d12045d8e1c1aa6953a6857db84d0c225bb3b565
[samba.git] / source4 / auth / ntlm / auth_sam.c
1 /*
2    Unix SMB/CIFS implementation.
3    Password and authentication handling
4    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2009
5    Copyright (C) Gerald Carter                             2003
6    Copyright (C) Stefan Metzmacher                         2005-2010
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "system/time.h"
24 #include <ldb.h>
25 #include "libcli/ldap/ldap_ndr.h"
26 #include "libcli/security/security.h"
27 #include "auth/auth.h"
28 #include "../libcli/auth/ntlm_check.h"
29 #include "auth/ntlm/auth_proto.h"
30 #include "auth/auth_sam.h"
31 #include "dsdb/samdb/samdb.h"
32 #include "dsdb/samdb/ldb_modules/util.h"
33 #include "dsdb/common/util.h"
34 #include "param/param.h"
35 #include "librpc/gen_ndr/ndr_irpc_c.h"
36 #include "librpc/gen_ndr/ndr_winbind_c.h"
37 #include "lib/messaging/irpc.h"
38 #include "libcli/auth/libcli_auth.h"
39 #include "libds/common/roles.h"
40 #include "lib/util/tevent_ntstatus.h"
41 #include "system/kerberos.h"
42 #include "auth/kerberos/kerberos.h"
43 #include "kdc/authn_policy_util.h"
44 #include "kdc/db-glue.h"
45
46 #undef DBGC_CLASS
47 #define DBGC_CLASS DBGC_AUTH
48
49 NTSTATUS auth_sam_init(void);
50
51 extern const char *user_attrs[];
52 extern const char *domain_ref_attrs[];
53
54 /****************************************************************************
55  Do a specific test for an smb password being correct, given a smb_password and
56  the lanman and NT responses.
57 ****************************************************************************/
58 static NTSTATUS authsam_password_ok(struct auth4_context *auth_context,
59                                     TALLOC_CTX *mem_ctx,
60                                     const struct samr_Password *nt_pwd,
61                                     struct smb_krb5_context *smb_krb5_context,
62                                     const DATA_BLOB *stored_aes_256_key,
63                                     const krb5_data *salt,
64                                     const struct auth_usersupplied_info *user_info,
65                                     DATA_BLOB *user_sess_key,
66                                     DATA_BLOB *lm_sess_key)
67 {
68         NTSTATUS status;
69
70         switch (user_info->password_state) {
71         case AUTH_PASSWORD_PLAIN:
72         {
73                 const struct auth_usersupplied_info *user_info_temp;
74
75                 if (nt_pwd == NULL && stored_aes_256_key != NULL && user_info->password.plaintext != NULL) {
76                         bool pw_equal;
77                         int krb5_ret;
78                         DATA_BLOB supplied_aes_256_key;
79                         krb5_keyblock key;
80                         krb5_data cleartext_data = {
81                                 .data = user_info->password.plaintext,
82                                 .length = strlen(user_info->password.plaintext)
83                         };
84
85                         *lm_sess_key = data_blob_null;
86                         *user_sess_key = data_blob_null;
87
88                         krb5_ret = smb_krb5_create_key_from_string(smb_krb5_context->krb5_context,
89                                                                    NULL,
90                                                                    salt,
91                                                                    &cleartext_data,
92                                                                    ENCTYPE_AES256_CTS_HMAC_SHA1_96,
93                                                                    &key);
94                         if (krb5_ret) {
95                                 DBG_ERR("generation of a aes256-cts-hmac-sha1-96 key for password comparison failed: %s\n",
96                                         smb_get_krb5_error_message(smb_krb5_context->krb5_context,
97                                                                    krb5_ret, mem_ctx));
98                                 return NT_STATUS_INTERNAL_ERROR;
99                         }
100
101                         supplied_aes_256_key = data_blob_const(KRB5_KEY_DATA(&key),
102                                                                KRB5_KEY_LENGTH(&key));
103
104                         pw_equal = data_blob_equal_const_time(&supplied_aes_256_key,
105                                                               stored_aes_256_key);
106
107                         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &key);
108                         if (!pw_equal) {
109                                 return NT_STATUS_WRONG_PASSWORD;
110                         }
111                         return NT_STATUS_OK;
112                 }
113
114                 status = encrypt_user_info(mem_ctx, auth_context,
115                                            AUTH_PASSWORD_HASH,
116                                            user_info, &user_info_temp);
117                 if (!NT_STATUS_IS_OK(status)) {
118                         DEBUG(1, ("Failed to convert plaintext password to password HASH: %s\n", nt_errstr(status)));
119                         return status;
120                 }
121                 user_info = user_info_temp;
122
123                 FALL_THROUGH;
124         }
125         case AUTH_PASSWORD_HASH:
126                 *lm_sess_key = data_blob(NULL, 0);
127                 *user_sess_key = data_blob(NULL, 0);
128                 status = hash_password_check(mem_ctx,
129                                              false,
130                                              lpcfg_ntlm_auth(auth_context->lp_ctx),
131                                              NULL,
132                                              user_info->password.hash.nt,
133                                              user_info->mapped.account_name,
134                                              NULL, nt_pwd);
135                 NT_STATUS_NOT_OK_RETURN(status);
136                 break;
137
138         case AUTH_PASSWORD_RESPONSE:
139                 status = ntlm_password_check(mem_ctx,
140                                              false,
141                                              lpcfg_ntlm_auth(auth_context->lp_ctx),
142                                              user_info->logon_parameters,
143                                              &auth_context->challenge.data,
144                                              &user_info->password.response.lanman,
145                                              &user_info->password.response.nt,
146                                              user_info->mapped.account_name,
147                                              user_info->client.account_name,
148                                              user_info->client.domain_name,
149                                              NULL, nt_pwd,
150                                              user_sess_key, lm_sess_key);
151                 NT_STATUS_NOT_OK_RETURN(status);
152                 break;
153         }
154
155         return NT_STATUS_OK;
156 }
157
158 static void auth_sam_trigger_zero_password(TALLOC_CTX *mem_ctx,
159                                            struct imessaging_context *msg_ctx,
160                                            struct tevent_context *event_ctx,
161                                            struct netr_SendToSamBase *send_to_sam)
162 {
163         struct dcerpc_binding_handle *irpc_handle;
164         struct winbind_SendToSam r;
165         struct tevent_req *req;
166         TALLOC_CTX *tmp_ctx;
167
168         tmp_ctx = talloc_new(mem_ctx);
169         if (tmp_ctx == NULL) {
170                 return;
171         }
172
173         irpc_handle = irpc_binding_handle_by_name(tmp_ctx, msg_ctx,
174                                                   "winbind_server",
175                                                   &ndr_table_winbind);
176         if (irpc_handle == NULL) {
177                 DEBUG(1,(__location__ ": Unable to get binding handle for winbind\n"));
178                 TALLOC_FREE(tmp_ctx);
179                 return;
180         }
181
182         r.in.message = *send_to_sam;
183
184         /*
185          * This seem to rely on the current IRPC implementation,
186          * which delivers the message in the _send function.
187          *
188          * TODO: we need a ONE_WAY IRPC handle and register
189          * a callback and wait for it to be triggered!
190          */
191         req = dcerpc_winbind_SendToSam_r_send(tmp_ctx,
192                                               event_ctx,
193                                               irpc_handle,
194                                               &r);
195
196         /* we aren't interested in a reply */
197         talloc_free(req);
198         TALLOC_FREE(tmp_ctx);
199
200 }
201
202 /*
203   send a message to the drepl server telling it to initiate a
204   REPL_SECRET getncchanges extended op to fetch the users secrets
205  */
206 static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx,
207                                          struct imessaging_context *msg_ctx,
208                                          struct tevent_context *event_ctx,
209                                          struct ldb_dn *user_dn)
210 {
211         struct dcerpc_binding_handle *irpc_handle;
212         struct drepl_trigger_repl_secret r;
213         struct tevent_req *req;
214         TALLOC_CTX *tmp_ctx;
215
216         tmp_ctx = talloc_new(mem_ctx);
217         if (tmp_ctx == NULL) {
218                 return;
219         }
220
221         irpc_handle = irpc_binding_handle_by_name(tmp_ctx, msg_ctx,
222                                                   "dreplsrv",
223                                                   &ndr_table_irpc);
224         if (irpc_handle == NULL) {
225                 DEBUG(1,(__location__ ": Unable to get binding handle for dreplsrv\n"));
226                 TALLOC_FREE(tmp_ctx);
227                 return;
228         }
229
230         r.in.user_dn = ldb_dn_get_linearized(user_dn);
231
232         /*
233          * This seem to rely on the current IRPC implementation,
234          * which delivers the message in the _send function.
235          *
236          * TODO: we need a ONE_WAY IRPC handle and register
237          * a callback and wait for it to be triggered!
238          */
239         req = dcerpc_drepl_trigger_repl_secret_r_send(tmp_ctx,
240                                                       event_ctx,
241                                                       irpc_handle,
242                                                       &r);
243
244         /* we aren't interested in a reply */
245         talloc_free(req);
246         TALLOC_FREE(tmp_ctx);
247 }
248
249 static const struct samr_Password *hide_invalid_nthash(const struct samr_Password *in)
250 {
251         /*
252          * This is the result of:
253          *
254          * E_md4hash("", zero_string_hash.hash);
255          */
256         static const struct samr_Password zero_string_hash = {
257                 .hash = {
258                         0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
259                         0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0,
260                 }
261         };
262
263         if (in == NULL) {
264                 return NULL;
265         }
266
267         /*
268          * Skip over any all-zero hashes in the history.  No known software
269          * stores these but just to be sure
270          */
271         if (all_zero(in->hash, sizeof(in->hash))) {
272                 return NULL;
273         }
274
275         /*
276          * This looks odd, but the password_hash module in the past has written
277          * this in the rare situation where (somehow) we didn't have an old NT
278          * hash (one of the old LM-only set paths)
279          *
280          * mem_equal_const_time() is used to avoid a timing attack
281          * when comparing secret data in the server with this constant
282          * value.
283          */
284         if (mem_equal_const_time(in->hash, zero_string_hash.hash, 16)) {
285                 in = NULL;
286         }
287
288         return in;
289 }
290
291 /*
292  * Check that a password is OK, and update badPwdCount if required.
293  */
294
295 static NTSTATUS authsam_password_check_and_record(struct auth4_context *auth_context,
296                                                   TALLOC_CTX *mem_ctx,
297                                                   struct ldb_dn *domain_dn,
298                                                   struct ldb_message *msg,
299                                                   const struct auth_usersupplied_info *user_info,
300                                                   DATA_BLOB *user_sess_key,
301                                                   DATA_BLOB *lm_sess_key,
302                                                   bool *authoritative)
303 {
304         NTSTATUS nt_status;
305         NTSTATUS auth_status;
306         TALLOC_CTX *tmp_ctx;
307         int i, ret;
308         int history_len = 0;
309         struct ldb_context *sam_ctx = auth_context->sam_ctx;
310         const char * const attrs[] = { "pwdHistoryLength", NULL };
311         struct ldb_message *dom_msg;
312         struct samr_Password *nt_pwd;
313         DATA_BLOB _aes_256_key = data_blob_null;
314         DATA_BLOB *aes_256_key = NULL;
315         krb5_data _salt = { .data = NULL, .length = 0 };
316         krb5_data *salt = NULL;
317         DATA_BLOB salt_data = data_blob_null;
318         struct smb_krb5_context *smb_krb5_context = NULL;
319         const struct ldb_val *sc_val;
320         uint32_t userAccountControl = 0;
321         uint32_t current_kvno = 0;
322         bool am_rodc;
323
324         tmp_ctx = talloc_new(mem_ctx);
325         if (tmp_ctx == NULL) {
326                 return NT_STATUS_NO_MEMORY;
327         }
328
329         /*
330          * This call does more than what it appears to do, it also
331          * checks for the account lockout.
332          *
333          * It is done here so that all parts of Samba that read the
334          * password refuse to even operate on it if the account is
335          * locked out, to avoid mistakes like CVE-2013-4496.
336          */
337         nt_status = samdb_result_passwords(tmp_ctx, auth_context->lp_ctx,
338                                            msg, &nt_pwd);
339         if (!NT_STATUS_IS_OK(nt_status)) {
340                 TALLOC_FREE(tmp_ctx);
341                 return nt_status;
342         }
343
344         userAccountControl = ldb_msg_find_attr_as_uint(msg,
345                                                        "userAccountControl",
346                                                        0);
347
348         sc_val = ldb_msg_find_ldb_val(msg, "supplementalCredentials");
349
350         if (nt_pwd == NULL && sc_val == NULL) {
351                 if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) {
352                         /*
353                          * we don't have passwords for this
354                          * account. We are an RODC, and this account
355                          * may be one for which we either are denied
356                          * REPL_SECRET replication or we haven't yet
357                          * done the replication. We return
358                          * NT_STATUS_NOT_IMPLEMENTED which tells the
359                          * auth code to try the next authentication
360                          * mechanism. We also send a message to our
361                          * drepl server to tell it to try and
362                          * replicate the secrets for this account.
363                          *
364                          * TODO: Should we only trigger this is detected
365                          * there's a chance that the password might be
366                          * replicated, we should be able to detect this
367                          * based on msDS-NeverRevealGroup.
368                          */
369                         auth_sam_trigger_repl_secret(auth_context,
370                                                      auth_context->msg_ctx,
371                                                      auth_context->event_ctx,
372                                                      msg->dn);
373                         TALLOC_FREE(tmp_ctx);
374                         return NT_STATUS_NOT_IMPLEMENTED;
375                 }
376         }
377
378         /*
379          * If we don't have an NT password, pull a kerberos key
380          * instead for plaintext.
381          */
382         if (nt_pwd == NULL &&
383             sc_val != NULL &&
384             user_info->password_state == AUTH_PASSWORD_PLAIN)
385         {
386                 krb5_error_code krb5_ret;
387
388                 krb5_ret = smb_krb5_init_context(tmp_ctx,
389                                                  auth_context->lp_ctx,
390                                                  &smb_krb5_context);
391                 if (krb5_ret != 0) {
392                         DBG_ERR("Failed to setup krb5_context: %s!\n",
393                                 error_message(krb5_ret));
394                         return NT_STATUS_INTERNAL_ERROR;
395                 }
396
397                 /*
398                  * Get the current salt from the record
399                  */
400
401                 krb5_ret = dsdb_extract_aes_256_key(smb_krb5_context->krb5_context,
402                                                     tmp_ctx,
403                                                     msg,
404                                                     userAccountControl,
405                                                     NULL, /* kvno */
406                                                     &current_kvno, /* kvno_out */
407                                                     &_aes_256_key,
408                                                     &salt_data);
409                 if (krb5_ret == 0) {
410                         aes_256_key = &_aes_256_key;
411
412                         _salt.data = (char *)salt_data.data;
413                         _salt.length = salt_data.length;
414                         salt = &_salt;
415                 }
416         }
417
418         auth_status = authsam_password_ok(auth_context,
419                                           tmp_ctx,
420                                           nt_pwd,
421                                           smb_krb5_context,
422                                           aes_256_key,
423                                           salt,
424                                           user_info,
425                                           user_sess_key, lm_sess_key);
426
427         if (NT_STATUS_IS_OK(auth_status)) {
428                 if (user_sess_key->data) {
429                         talloc_steal(mem_ctx, user_sess_key->data);
430                 }
431                 if (lm_sess_key->data) {
432                         talloc_steal(mem_ctx, lm_sess_key->data);
433                 }
434                 TALLOC_FREE(tmp_ctx);
435                 return NT_STATUS_OK;
436         }
437         *user_sess_key = data_blob_null;
438         *lm_sess_key = data_blob_null;
439
440         if (!NT_STATUS_EQUAL(auth_status, NT_STATUS_WRONG_PASSWORD)) {
441                 TALLOC_FREE(tmp_ctx);
442                 return auth_status;
443         }
444
445         /*
446          * We only continue if this was a wrong password
447          * and we'll always return NT_STATUS_WRONG_PASSWORD
448          * no matter what error happens.
449          */
450
451         /* pull the domain password property attributes */
452         ret = dsdb_search_one(sam_ctx, tmp_ctx, &dom_msg, domain_dn, LDB_SCOPE_BASE,
453                               attrs, 0, "objectClass=domain");
454         if (ret == LDB_SUCCESS) {
455                 history_len = ldb_msg_find_attr_as_uint(dom_msg, "pwdHistoryLength", 0);
456         } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
457                 DEBUG(3,("Couldn't find domain %s: %s!\n",
458                          ldb_dn_get_linearized(domain_dn),
459                          ldb_errstring(sam_ctx)));
460         } else {
461                 DEBUG(3,("error finding domain %s: %s!\n",
462                          ldb_dn_get_linearized(domain_dn),
463                          ldb_errstring(sam_ctx)));
464         }
465
466         for (i = 1; i < MIN(history_len, 3); i++) {
467                 const struct samr_Password *nt_history_pwd = NULL;
468                 NTTIME pwdLastSet;
469                 struct timeval tv_now;
470                 NTTIME now;
471                 int allowed_period_mins;
472                 NTTIME allowed_period;
473
474                 /* Reset these variables back to starting as empty */
475                 aes_256_key = NULL;
476                 salt = NULL;
477
478                 /*
479                  * Obtain the i'th old password from the NT password
480                  * history for this user.
481                  *
482                  * We avoid issues with salts (which are not
483                  * recorded for historical AES256 keys) by using the
484                  * ntPwdHistory in preference.
485                  */
486                 nt_status = samdb_result_passwords_from_history(tmp_ctx,
487                                                         auth_context->lp_ctx,
488                                                         msg, i,
489                                                         NULL,
490                                                         &nt_history_pwd);
491
492                 /*
493                  * Belts and braces: note that
494                  * samdb_result_passwords_from_history() currently
495                  * does not fail for missing attributes, it only sets
496                  * nt_history_pwd = NULL, so "break" and fall down to
497                  * the bad password count update if this happens
498                  */
499                 if (!NT_STATUS_IS_OK(nt_status)) {
500                         break;
501                 }
502
503                 nt_history_pwd = hide_invalid_nthash(nt_history_pwd);
504
505                 /*
506                  * We don't have an NT hash from the
507                  * ntPwdHistory, but we can still perform the
508                  * password check with the AES256
509                  * key.
510                  *
511                  * However, this is the second preference as
512                  * it will fail if the account was renamed
513                  * prior to a password change (as we won't
514                  * have the correct salt available to
515                  * calculate the AES256 key).
516                  */
517
518                 if (nt_history_pwd == NULL && sc_val != NULL &&
519                     user_info->password_state == AUTH_PASSWORD_PLAIN &&
520                     current_kvno >= i)
521                 {
522                         krb5_error_code krb5_ret;
523                         const uint32_t request_kvno = current_kvno - i;
524
525                         /*
526                          * Confirm we have a krb5_context set up
527                          */
528                         if (smb_krb5_context == NULL) {
529                                 /*
530                                  * We get here if we had a unicodePwd
531                                  * for the current password, no
532                                  * ntPwdHistory, a valid previous
533                                  * Kerberos history AND are processing
534                                  * a simple bind.
535                                  *
536                                  * This really is a corner case so
537                                  * favour cleaner code over trying to
538                                  * allow for an old password.  It is
539                                  * more likely this is just a new
540                                  * account.
541                                  *
542                                  * "break" out of the loop and fall down
543                                  * to the bad password update
544                                  */
545                                 break;
546                         }
547
548                         /*
549                          * Get the current salt from the record
550                          */
551
552                         krb5_ret = dsdb_extract_aes_256_key(smb_krb5_context->krb5_context,
553                                                             tmp_ctx,
554                                                             msg,
555                                                             userAccountControl,
556                                                             &request_kvno, /* kvno */
557                                                             NULL, /* kvno_out */
558                                                             &_aes_256_key,
559                                                             &salt_data);
560                         if (krb5_ret != 0) {
561                                 break;
562                         }
563
564                         aes_256_key = &_aes_256_key;
565
566                         _salt.data = (char *)salt_data.data;
567                         _salt.length = salt_data.length;
568                         salt = &_salt;
569
570                 } else if (nt_history_pwd == NULL) {
571                         /*
572                          * If we don't find element 'i' in the
573                          * ntPwdHistory and can not fall back to the
574                          * kerberos hash, we won't find 'i+1' ...
575                          */
576                         break;
577                 }
578
579                 auth_status = authsam_password_ok(auth_context, tmp_ctx,
580                                                   nt_history_pwd,
581                                                   smb_krb5_context,
582                                                   aes_256_key,
583                                                   salt,
584                                                   user_info,
585                                                   user_sess_key,
586                                                   lm_sess_key);
587
588                 if (!NT_STATUS_IS_OK(auth_status)) {
589                         /*
590                          * If this was not a correct password, try the next
591                          * one from the history
592                          */
593                         *user_sess_key = data_blob_null;
594                         *lm_sess_key = data_blob_null;
595                         continue;
596                 }
597
598                 if (i != 1) {
599                         /*
600                          * The authentication was OK, but not against
601                          * the previous password, which is stored at index 1.
602                          *
603                          * We just return the original wrong password.
604                          * This skips the update of the bad pwd count,
605                          * because this is almost certainly user error
606                          * (or automatic login on a computer using a cached
607                          * password from before the password change),
608                          * not an attack.
609                          */
610                         TALLOC_FREE(tmp_ctx);
611                         return NT_STATUS_WRONG_PASSWORD;
612                 }
613
614                 if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) {
615                         /*
616                          * The authentication was OK against the previous password,
617                          * but it's not a NTLM network authentication,
618                          * LDAP simple bind or something similar.
619                          *
620                          * We just return the original wrong password.
621                          * This skips the update of the bad pwd count,
622                          * because this is almost certainly user error
623                          * (or automatic login on a computer using a cached
624                          * password from before the password change),
625                          * not an attack.
626                          */
627                         TALLOC_FREE(tmp_ctx);
628                         return NT_STATUS_WRONG_PASSWORD;
629                 }
630
631                 /*
632                  * If the password was OK, it's a NTLM network authentication
633                  * and it was the previous password.
634                  *
635                  * Now we see if it is within the grace period,
636                  * so that we don't break cached sessions on other computers
637                  * before the user can lock and unlock their other screens
638                  * (resetting their cached password).
639                  *
640                  * See http://support.microsoft.com/kb/906305
641                  * OldPasswordAllowedPeriod ("old password allowed period")
642                  * is specified in minutes. The default is 60.
643                  */
644                 allowed_period_mins = lpcfg_old_password_allowed_period(auth_context->lp_ctx);
645                 /*
646                  * NTTIME uses 100ns units
647                  */
648                 allowed_period = (NTTIME) allowed_period_mins *
649                                  60 * 1000*1000*10;
650                 pwdLastSet = samdb_result_nttime(msg, "pwdLastSet", 0);
651                 tv_now = timeval_current();
652                 now = timeval_to_nttime(&tv_now);
653
654                 if (now < pwdLastSet) {
655                         /*
656                          * time jump?
657                          *
658                          * We just return the original wrong password.
659                          * This skips the update of the bad pwd count,
660                          * because this is almost certainly user error
661                          * (or automatic login on a computer using a cached
662                          * password from before the password change),
663                          * not an attack.
664                          */
665                         TALLOC_FREE(tmp_ctx);
666                         return NT_STATUS_WRONG_PASSWORD;
667                 }
668
669                 if ((now - pwdLastSet) >= allowed_period) {
670                         /*
671                          * The allowed period is over.
672                          *
673                          * We just return the original wrong password.
674                          * This skips the update of the bad pwd count,
675                          * because this is almost certainly user error
676                          * (or automatic login on a computer using a cached
677                          * password from before the password change),
678                          * not an attack.
679                          */
680                         TALLOC_FREE(tmp_ctx);
681                         return NT_STATUS_WRONG_PASSWORD;
682                 }
683
684                 /*
685                  * We finally allow the authentication with the
686                  * previous password within the allowed period.
687                  */
688                 if (user_sess_key->data) {
689                         talloc_steal(mem_ctx, user_sess_key->data);
690                 }
691                 if (lm_sess_key->data) {
692                         talloc_steal(mem_ctx, lm_sess_key->data);
693                 }
694
695                 TALLOC_FREE(tmp_ctx);
696                 return auth_status;
697         }
698
699         /*
700          * If we are not in the allowed period or match an old password,
701          * we didn't return early. Now update the badPwdCount et al.
702          */
703         nt_status = authsam_update_bad_pwd_count(auth_context->sam_ctx,
704                                                  msg, domain_dn);
705         if (!NT_STATUS_IS_OK(nt_status)) {
706                 /*
707                  * We need to return the original
708                  * NT_STATUS_WRONG_PASSWORD error, so there isn't
709                  * anything more we can do than write something into
710                  * the log
711                  */
712                 DEBUG(0, ("Failed to note bad password for user [%s]: %s\n",
713                           user_info->mapped.account_name,
714                           nt_errstr(nt_status)));
715         }
716
717         if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) {
718                 *authoritative = false;
719         }
720
721         TALLOC_FREE(tmp_ctx);
722
723         if (NT_STATUS_IS_OK(nt_status)) {
724                 nt_status = NT_STATUS_WRONG_PASSWORD;
725         }
726         return nt_status;
727 }
728
729 static NTSTATUS authsam_check_netlogon_trust(TALLOC_CTX *mem_ctx,
730                                              struct ldb_context *sam_ctx,
731                                              struct loadparm_context *lp_ctx,
732                                              const struct auth_usersupplied_info *user_info,
733                                              const struct auth_user_info_dc *user_info_dc,
734                                              struct authn_audit_info **server_audit_info_out)
735 {
736         TALLOC_CTX *tmp_ctx = NULL;
737
738         static const char *authn_policy_silo_attrs[] = {
739                 "msDS-AssignedAuthNPolicy",
740                 "msDS-AssignedAuthNPolicySilo",
741                 "objectClass", /* used to determine which set of policy
742                                 * attributes apply. */
743                 NULL,
744         };
745
746         const struct authn_server_policy *authn_server_policy = NULL;
747
748         struct dom_sid_buf netlogon_trust_sid_buf;
749         const char *netlogon_trust_sid_str = NULL;
750         struct ldb_dn *netlogon_trust_dn = NULL;
751         struct ldb_message *netlogon_trust_msg = NULL;
752
753         int ret;
754
755         /* Have we established a secure channel? */
756         if (user_info->netlogon_trust_account.secure_channel_type == SEC_CHAN_NULL) {
757                 return NT_STATUS_OK;
758         }
759
760         if (!authn_policy_silos_and_policies_in_effect(sam_ctx)) {
761                 return NT_STATUS_OK;
762         }
763
764         /*
765          * We have established a secure channel, and we should have the machine
766          * account’s SID.
767          */
768         SMB_ASSERT(user_info->netlogon_trust_account.sid != NULL);
769
770         tmp_ctx = talloc_new(mem_ctx);
771         if (tmp_ctx == NULL) {
772                 return NT_STATUS_NO_MEMORY;
773         }
774
775         netlogon_trust_sid_str = dom_sid_str_buf(user_info->netlogon_trust_account.sid,
776                                                  &netlogon_trust_sid_buf);
777
778         netlogon_trust_dn = ldb_dn_new_fmt(tmp_ctx, sam_ctx,
779                                            "<SID=%s>",
780                                            netlogon_trust_sid_str);
781         if (netlogon_trust_dn == NULL) {
782                 talloc_free(tmp_ctx);
783                 return NT_STATUS_NO_MEMORY;
784         }
785
786         /*
787          * Look up the machine account to see if it has an applicable
788          * authentication policy.
789          */
790         ret = dsdb_search_one(sam_ctx,
791                               tmp_ctx,
792                               &netlogon_trust_msg,
793                               netlogon_trust_dn,
794                               LDB_SCOPE_BASE,
795                               authn_policy_silo_attrs,
796                               0,
797                               NULL);
798         if (ret) {
799                 talloc_free(tmp_ctx);
800                 return dsdb_ldb_err_to_ntstatus(ret);
801         }
802
803         ret = authn_policy_server(sam_ctx,
804                                   tmp_ctx,
805                                   netlogon_trust_msg,
806                                   &authn_server_policy);
807         if (ret) {
808                 talloc_free(tmp_ctx);
809                 return NT_STATUS_INTERNAL_ERROR;
810         }
811
812         if (authn_server_policy != NULL) {
813                 struct authn_audit_info *server_audit_info = NULL;
814                 NTSTATUS status;
815
816                 /*
817                  * An authentication policy applies to the machine
818                  * account. Carry out the access check.
819                  */
820                 status = authn_policy_authenticate_to_service(tmp_ctx,
821                                                               sam_ctx,
822                                                               lp_ctx,
823                                                               AUTHN_POLICY_AUTH_TYPE_NTLM,
824                                                               user_info_dc,
825                                                               NULL /* device_info */,
826                                                               /*
827                                                                * It seems that claims go ignored for
828                                                                * SamLogon (see SamLogonTests â€”
829                                                                * test_samlogon_allowed_to_computer_silo).
830                                                                */
831                                                               (struct auth_claims) {},
832                                                               authn_server_policy,
833                                                               (struct authn_policy_flags) {},
834                                                               &server_audit_info);
835                 if (server_audit_info != NULL) {
836                         *server_audit_info_out = talloc_move(mem_ctx, &server_audit_info);
837                 }
838                 if (!NT_STATUS_IS_OK(status)) {
839                         talloc_free(tmp_ctx);
840                         return status;
841                 }
842         }
843
844         return NT_STATUS_OK;
845 }
846
847 static NTSTATUS authsam_authenticate(struct auth4_context *auth_context,
848                                      TALLOC_CTX *mem_ctx,
849                                      struct ldb_dn *domain_dn,
850                                      struct ldb_message *msg,
851                                      const struct auth_usersupplied_info *user_info,
852                                      const struct auth_user_info_dc *user_info_dc,
853                                      DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key,
854                                      struct authn_audit_info **client_audit_info_out,
855                                      struct authn_audit_info **server_audit_info_out,
856                                      bool *authoritative)
857 {
858         NTSTATUS nt_status;
859         int ret;
860         bool interactive = (user_info->password_state == AUTH_PASSWORD_HASH);
861         uint32_t acct_flags = samdb_result_acct_flags(msg, NULL);
862         struct netr_SendToSamBase *send_to_sam = NULL;
863         const struct authn_ntlm_client_policy *authn_client_policy = NULL;
864         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
865         if (!tmp_ctx) {
866                 return NT_STATUS_NO_MEMORY;
867         }
868
869         /* You can only do an interactive login to normal accounts */
870         if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) {
871                 if (!(acct_flags & ACB_NORMAL)) {
872                         TALLOC_FREE(tmp_ctx);
873                         return NT_STATUS_NO_SUCH_USER;
874                 }
875                 if (acct_flags & ACB_SMARTCARD_REQUIRED) {
876                         if (acct_flags & ACB_DISABLED) {
877                                 DEBUG(2,("authsam_authenticate: Account for user '%s' "
878                                          "was disabled.\n",
879                                          user_info->mapped.account_name));
880                                 TALLOC_FREE(tmp_ctx);
881                                 return NT_STATUS_ACCOUNT_DISABLED;
882                         }
883                         DEBUG(2,("authsam_authenticate: Account for user '%s' "
884                                  "requires interactive smartcard logon.\n",
885                                  user_info->mapped.account_name));
886                         TALLOC_FREE(tmp_ctx);
887                         return NT_STATUS_SMARTCARD_LOGON_REQUIRED;
888                 }
889         }
890
891         /* See whether an authentication policy applies to the client. */
892         ret = authn_policy_ntlm_client(auth_context->sam_ctx,
893                                        tmp_ctx,
894                                        msg,
895                                        &authn_client_policy);
896         if (ret) {
897                 TALLOC_FREE(tmp_ctx);
898                 return NT_STATUS_INTERNAL_ERROR;
899         }
900
901         nt_status = authn_policy_ntlm_apply_device_restriction(mem_ctx,
902                                                                authn_client_policy,
903                                                                client_audit_info_out);
904         if (!NT_STATUS_IS_OK(nt_status)) {
905                 /*
906                  * As we didn’t get far enough to check the server policy, only
907                  * the client policy will be referenced in the authentication
908                  * log message.
909                  */
910                 TALLOC_FREE(tmp_ctx);
911                 return nt_status;
912         }
913
914         nt_status = authsam_password_check_and_record(auth_context, tmp_ctx,
915                                                       domain_dn, msg,
916                                                       user_info,
917                                                       user_sess_key, lm_sess_key,
918                                                       authoritative);
919         if (!NT_STATUS_IS_OK(nt_status)) {
920                 TALLOC_FREE(tmp_ctx);
921                 return nt_status;
922         }
923
924         nt_status = authsam_check_netlogon_trust(mem_ctx,
925                                                  auth_context->sam_ctx,
926                                                  auth_context->lp_ctx,
927                                                  user_info,
928                                                  user_info_dc,
929                                                  server_audit_info_out);
930         if (!NT_STATUS_IS_OK(nt_status)) {
931                 TALLOC_FREE(tmp_ctx);
932                 return nt_status;
933         }
934
935         nt_status = authsam_account_ok(tmp_ctx, auth_context->sam_ctx,
936                                        user_info->logon_parameters,
937                                        domain_dn,
938                                        msg,
939                                        user_info->workstation_name,
940                                        user_info->mapped.account_name,
941                                        false, false);
942         if (!NT_STATUS_IS_OK(nt_status)) {
943                 TALLOC_FREE(tmp_ctx);
944                 return nt_status;
945         }
946
947         nt_status = authsam_logon_success_accounting(auth_context->sam_ctx,
948                                                      msg, domain_dn,
949                                                      interactive,
950                                                      tmp_ctx,
951                                                      &send_to_sam);
952
953         if (send_to_sam != NULL) {
954                 auth_sam_trigger_zero_password(tmp_ctx,
955                                                auth_context->msg_ctx,
956                                                auth_context->event_ctx,
957                                                send_to_sam);
958         }
959
960         if (!NT_STATUS_IS_OK(nt_status)) {
961                 TALLOC_FREE(tmp_ctx);
962                 return nt_status;
963         }
964
965         if (user_sess_key && user_sess_key->data) {
966                 talloc_steal(mem_ctx, user_sess_key->data);
967         }
968         if (lm_sess_key && lm_sess_key->data) {
969                 talloc_steal(mem_ctx, lm_sess_key->data);
970         }
971
972         TALLOC_FREE(tmp_ctx);
973         return nt_status;
974 }
975
976
977
978 static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx,
979                                                  TALLOC_CTX *mem_ctx,
980                                                  const struct auth_usersupplied_info *user_info,
981                                                  struct auth_user_info_dc **user_info_dc,
982                                                  struct authn_audit_info **client_audit_info_out,
983                                                  struct authn_audit_info **server_audit_info_out,
984                                                  bool *authoritative)
985 {
986         NTSTATUS nt_status;
987         int result;
988         const char *account_name = user_info->mapped.account_name;
989         struct ldb_message *msg;
990         struct ldb_dn *domain_dn;
991         DATA_BLOB user_sess_key, lm_sess_key;
992         TALLOC_CTX *tmp_ctx;
993         const char *p = NULL;
994         struct auth_user_info_dc *reparented = NULL;
995         struct authn_audit_info *client_audit_info = NULL;
996         struct authn_audit_info *server_audit_info = NULL;
997
998         if (ctx->auth_ctx->sam_ctx == NULL) {
999                 DEBUG(0, ("No SAM available, cannot log in users\n"));
1000                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1001         }
1002
1003         if (!account_name || !*account_name) {
1004                 /* 'not for me' */
1005                 return NT_STATUS_NOT_IMPLEMENTED;
1006         }
1007
1008         tmp_ctx = talloc_new(mem_ctx);
1009         if (!tmp_ctx) {
1010                 return NT_STATUS_NO_MEMORY;
1011         }
1012
1013         domain_dn = ldb_get_default_basedn(ctx->auth_ctx->sam_ctx);
1014         if (domain_dn == NULL) {
1015                 talloc_free(tmp_ctx);
1016                 return NT_STATUS_NO_SUCH_DOMAIN;
1017         }
1018
1019         /*
1020          * If we have not already mapped this user, then now is a good
1021          * time to do so, before we look it up.  We used to do this
1022          * earlier, but in a multi-forest environment we want to do
1023          * this mapping at the final domain.
1024          *
1025          * However, on the flip side we may have already mapped the
1026          * user if this was an LDAP simple bind, in which case we
1027          * really, really want to get back to exactly the same account
1028          * we got the DN for.
1029          */
1030         if (!user_info->cracknames_called) {
1031                 p = strchr_m(account_name, '@');
1032         } else {
1033                 /*
1034                  * This is slightly nicer than double-indenting the
1035                  * block below
1036                  */
1037                 p = NULL;
1038         }
1039
1040         if (p != NULL) {
1041                 const char *nt4_domain = NULL;
1042                 const char *nt4_account = NULL;
1043                 bool is_my_domain = false;
1044
1045                 nt_status = crack_name_to_nt4_name(mem_ctx,
1046                                                    ctx->auth_ctx->sam_ctx,
1047                                                    /*
1048                                                     * DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON ?
1049                                                     */
1050                                                    DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
1051                                                    account_name,
1052                                                    &nt4_domain, &nt4_account);
1053                 if (!NT_STATUS_IS_OK(nt_status)) {
1054                         talloc_free(tmp_ctx);
1055                         return NT_STATUS_NO_SUCH_USER;
1056                 }
1057
1058                 is_my_domain = lpcfg_is_mydomain(ctx->auth_ctx->lp_ctx, nt4_domain);
1059                 if (!is_my_domain) {
1060                         /*
1061                          * This is a user within our forest,
1062                          * but in a different domain,
1063                          * we're not authoritative
1064                          */
1065                         talloc_free(tmp_ctx);
1066                         return NT_STATUS_NOT_IMPLEMENTED;
1067                 }
1068
1069                 /*
1070                  * Let's use the NT4 account name for the lookup.
1071                  */
1072                 account_name = nt4_account;
1073         }
1074
1075         nt_status = authsam_search_account(tmp_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg);
1076         if (!NT_STATUS_IS_OK(nt_status)) {
1077                 talloc_free(tmp_ctx);
1078                 return nt_status;
1079         }
1080
1081         nt_status = authsam_make_user_info_dc(tmp_ctx, ctx->auth_ctx->sam_ctx,
1082                                              lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
1083                                              lpcfg_sam_name(ctx->auth_ctx->lp_ctx),
1084                                              lpcfg_sam_dnsname(ctx->auth_ctx->lp_ctx),
1085                                              domain_dn,
1086                                              msg,
1087                                              data_blob_null, data_blob_null,
1088                                              user_info_dc);
1089         if (!NT_STATUS_IS_OK(nt_status)) {
1090                 talloc_free(tmp_ctx);
1091                 return nt_status;
1092         }
1093
1094         result = dsdb_is_protected_user(ctx->auth_ctx->sam_ctx,
1095                                         (*user_info_dc)->sids,
1096                                         (*user_info_dc)->num_sids);
1097         /*
1098          * We also consider an error result (a negative value) as denying the
1099          * authentication.
1100          */
1101         if (result != 0) {
1102                 talloc_free(tmp_ctx);
1103                 return NT_STATUS_ACCOUNT_RESTRICTION;
1104         }
1105
1106         nt_status = authsam_authenticate(ctx->auth_ctx,
1107                                          tmp_ctx,
1108                                          domain_dn,
1109                                          msg,
1110                                          user_info,
1111                                          *user_info_dc,
1112                                          &user_sess_key,
1113                                          &lm_sess_key,
1114                                          &client_audit_info,
1115                                          &server_audit_info,
1116                                          authoritative);
1117         if (client_audit_info != NULL) {
1118                 *client_audit_info_out = talloc_move(mem_ctx, &client_audit_info);
1119         }
1120         if (server_audit_info != NULL) {
1121                 *server_audit_info_out = talloc_move(mem_ctx, &server_audit_info);
1122         }
1123         if (!NT_STATUS_IS_OK(nt_status)) {
1124                 talloc_free(tmp_ctx);
1125                 return nt_status;
1126         }
1127
1128         (*user_info_dc)->user_session_key = data_blob_talloc(*user_info_dc,
1129                                                              user_sess_key.data,
1130                                                              user_sess_key.length);
1131         if (user_sess_key.data) {
1132                 if ((*user_info_dc)->user_session_key.data == NULL) {
1133                         TALLOC_FREE(tmp_ctx);
1134                         return NT_STATUS_NO_MEMORY;
1135                 }
1136         }
1137
1138         (*user_info_dc)->lm_session_key = data_blob_talloc(*user_info_dc,
1139                                                            lm_sess_key.data,
1140                                                            lm_sess_key.length);
1141         if (lm_sess_key.data) {
1142                 if ((*user_info_dc)->lm_session_key.data == NULL) {
1143                         TALLOC_FREE(tmp_ctx);
1144                         return NT_STATUS_NO_MEMORY;
1145                 }
1146         }
1147
1148         /*
1149          * Release our handle to *user_info_dc. {client,server}_audit_info_out,
1150          * if non-NULL, becomes the new parent.
1151          */
1152         reparented = talloc_reparent(tmp_ctx, mem_ctx, *user_info_dc);
1153         if (reparented == NULL) {
1154                 talloc_free(tmp_ctx);
1155                 return NT_STATUS_INTERNAL_ERROR;
1156         }
1157
1158         talloc_free(tmp_ctx);
1159
1160         return NT_STATUS_OK;
1161 }
1162
1163 struct authsam_check_password_state {
1164         struct auth_user_info_dc *user_info_dc;
1165         struct authn_audit_info *client_audit_info;
1166         struct authn_audit_info *server_audit_info;
1167         bool authoritative;
1168 };
1169
1170 static struct tevent_req *authsam_check_password_send(
1171         TALLOC_CTX *mem_ctx,
1172         struct tevent_context *ev,
1173         struct auth_method_context *ctx,
1174         const struct auth_usersupplied_info *user_info)
1175 {
1176         struct tevent_req *req = NULL;
1177         struct authsam_check_password_state *state = NULL;
1178         NTSTATUS status;
1179
1180         req = tevent_req_create(
1181                 mem_ctx, &state, struct authsam_check_password_state);
1182         if (req == NULL) {
1183                 return NULL;
1184         }
1185         /*
1186          * authsam_check_password_internals() sets this to false in
1187          * the rodc case, otherwise it leaves it untouched. Default to
1188          * "we're authoritative".
1189          */
1190         state->authoritative = true;
1191
1192         status = authsam_check_password_internals(
1193                 ctx,
1194                 state,
1195                 user_info,
1196                 &state->user_info_dc,
1197                 &state->client_audit_info,
1198                 &state->server_audit_info,
1199                 &state->authoritative);
1200         if (tevent_req_nterror(req, status)) {
1201                 return tevent_req_post(req, ev);
1202         }
1203
1204         tevent_req_done(req);
1205         return tevent_req_post(req, ev);
1206 }
1207
1208 static NTSTATUS authsam_check_password_recv(
1209         struct tevent_req *req,
1210         TALLOC_CTX *mem_ctx,
1211         struct auth_user_info_dc **interim_info,
1212         const struct authn_audit_info **client_audit_info,
1213         const struct authn_audit_info **server_audit_info,
1214         bool *authoritative)
1215 {
1216         struct authsam_check_password_state *state = tevent_req_data(
1217                 req, struct authsam_check_password_state);
1218         NTSTATUS status;
1219
1220         *authoritative = state->authoritative;
1221
1222         *client_audit_info = talloc_reparent(state, mem_ctx, state->client_audit_info);
1223         state->client_audit_info = NULL;
1224
1225         *server_audit_info = talloc_reparent(state, mem_ctx, state->server_audit_info);
1226         state->server_audit_info = NULL;
1227
1228         if (tevent_req_is_nterror(req, &status)) {
1229                 tevent_req_received(req);
1230                 return status;
1231         }
1232         /*
1233          * Release our handle to state->user_info_dc.
1234          * {client,server}_audit_info, if non-NULL, becomes the new parent.
1235          */
1236         *interim_info = talloc_reparent(state, mem_ctx, state->user_info_dc);
1237         state->user_info_dc = NULL;
1238
1239         tevent_req_received(req);
1240         return NT_STATUS_OK;
1241 }
1242
1243 static NTSTATUS authsam_ignoredomain_want_check(struct auth_method_context *ctx,
1244                                                 TALLOC_CTX *mem_ctx,
1245                                                 const struct auth_usersupplied_info *user_info)
1246 {
1247         if (!user_info->mapped.account_name || !*user_info->mapped.account_name) {
1248                 return NT_STATUS_NOT_IMPLEMENTED;
1249         }
1250
1251         return NT_STATUS_OK;
1252 }
1253
1254 /****************************************************************************
1255 Check SAM security (above) but with a few extra checks.
1256 ****************************************************************************/
1257 static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
1258                                    TALLOC_CTX *mem_ctx,
1259                                    const struct auth_usersupplied_info *user_info)
1260 {
1261         const char *effective_domain = user_info->mapped.domain_name;
1262         bool is_local_name = false;
1263         bool is_my_domain = false;
1264         const char *p = NULL;
1265         struct dsdb_trust_routing_table *trt = NULL;
1266         const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
1267         NTSTATUS status;
1268
1269         if (!user_info->mapped.account_name || !*user_info->mapped.account_name) {
1270                 return NT_STATUS_NOT_IMPLEMENTED;
1271         }
1272
1273         if (effective_domain == NULL) {
1274                 effective_domain = "";
1275         }
1276
1277         is_local_name = lpcfg_is_myname(ctx->auth_ctx->lp_ctx,
1278                                         effective_domain);
1279
1280         /* check whether or not we service this domain/workgroup name */
1281         switch (lpcfg_server_role(ctx->auth_ctx->lp_ctx)) {
1282         case ROLE_STANDALONE:
1283                 return NT_STATUS_OK;
1284
1285         case ROLE_DOMAIN_MEMBER:
1286                 if (is_local_name) {
1287                         return NT_STATUS_OK;
1288                 }
1289
1290                 DBG_DEBUG("%s is not one of my local names (DOMAIN_MEMBER)\n",
1291                           effective_domain);
1292                 return NT_STATUS_NOT_IMPLEMENTED;
1293
1294         case ROLE_ACTIVE_DIRECTORY_DC:
1295                 /* handled later */
1296                 break;
1297
1298         default:
1299                 DBG_ERR("lpcfg_server_role() has an undefined value\n");
1300                 return NT_STATUS_INVALID_SERVER_STATE;
1301         }
1302
1303         /*
1304          * Now we handle the AD DC case...
1305          */
1306
1307         is_my_domain = lpcfg_is_my_domain_or_realm(ctx->auth_ctx->lp_ctx,
1308                                                    effective_domain);
1309         if (is_my_domain) {
1310                 return NT_STATUS_OK;
1311         }
1312
1313         if (user_info->cracknames_called) {
1314                 /*
1315                  * The caller already did a cracknames call.
1316                  */
1317                 DBG_DEBUG("%s is not own domain name (DC)\n",
1318                           effective_domain);
1319                 return NT_STATUS_NOT_IMPLEMENTED;
1320         }
1321
1322         if (!strequal(effective_domain, "")) {
1323                 DBG_DEBUG("%s is not own domain name (DC)\n",
1324                           effective_domain);
1325                 return NT_STATUS_NOT_IMPLEMENTED;
1326         }
1327
1328         p = strchr_m(user_info->mapped.account_name, '@');
1329         if (p == NULL) {
1330                 /*
1331                  * An empty to domain name should be handled
1332                  * as the local domain name.
1333                  */
1334                 return NT_STATUS_OK;
1335         }
1336
1337         effective_domain = p + 1;
1338         is_my_domain = lpcfg_is_my_domain_or_realm(ctx->auth_ctx->lp_ctx,
1339                                                    effective_domain);
1340         if (is_my_domain) {
1341                 return NT_STATUS_OK;
1342         }
1343
1344         if (strequal(effective_domain, "")) {
1345                 DBG_DEBUG("authsam_check_password: upn without realm (DC)\n");
1346                 return NT_STATUS_NOT_IMPLEMENTED;
1347         }
1348
1349         /*
1350          * as last option we check the routing table if the
1351          * domain is within our forest.
1352          */
1353         status = dsdb_trust_routing_table_load(ctx->auth_ctx->sam_ctx,
1354                                                mem_ctx, &trt);
1355         if (!NT_STATUS_IS_OK(status)) {
1356                 DBG_ERR("authsam_check_password: dsdb_trust_routing_table_load() %s\n",
1357                          nt_errstr(status));
1358                 return status;
1359         }
1360
1361         tdo = dsdb_trust_routing_by_name(trt, effective_domain);
1362         if (tdo == NULL) {
1363                 DBG_DEBUG("%s is not a known TLN (DC)\n",
1364                           effective_domain);
1365                 TALLOC_FREE(trt);
1366                 return NT_STATUS_NOT_IMPLEMENTED;
1367         }
1368
1369         if (!(tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
1370                 DBG_DEBUG("%s is not a TLN in our forest (DC)\n",
1371                           effective_domain);
1372                 TALLOC_FREE(trt);
1373                 return NT_STATUS_NOT_IMPLEMENTED;
1374         }
1375
1376         /*
1377          * This principal is within our forest.
1378          * we'll later do a crack_name_to_nt4_name()
1379          * to check if it's in our domain.
1380          */
1381         TALLOC_FREE(trt);
1382         return NT_STATUS_OK;
1383 }
1384
1385 static const struct auth_operations sam_ignoredomain_ops = {
1386         .name                      = "sam_ignoredomain",
1387         .want_check                = authsam_ignoredomain_want_check,
1388         .check_password_send       = authsam_check_password_send,
1389         .check_password_recv       = authsam_check_password_recv,
1390 };
1391
1392 static const struct auth_operations sam_ops = {
1393         .name                      = "sam",
1394         .want_check                = authsam_want_check,
1395         .check_password_send       = authsam_check_password_send,
1396         .check_password_recv       = authsam_check_password_recv,
1397 };
1398
1399 _PUBLIC_ NTSTATUS auth4_sam_init(TALLOC_CTX *);
1400 _PUBLIC_ NTSTATUS auth4_sam_init(TALLOC_CTX *ctx)
1401 {
1402         NTSTATUS ret;
1403
1404         ret = auth_register(ctx, &sam_ops);
1405         if (!NT_STATUS_IS_OK(ret)) {
1406                 DEBUG(0,("Failed to register 'sam' auth backend!\n"));
1407                 return ret;
1408         }
1409
1410         ret = auth_register(ctx, &sam_ignoredomain_ops);
1411         if (!NT_STATUS_IS_OK(ret)) {
1412                 DEBUG(0,("Failed to register 'sam_ignoredomain' auth backend!\n"));
1413                 return ret;
1414         }
1415
1416         return ret;
1417 }