Line data Source code
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 28212 : 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 1404 : NTSTATUS status;
69 :
70 28212 : switch (user_info->password_state) {
71 508 : case AUTH_PASSWORD_PLAIN:
72 : {
73 0 : const struct auth_usersupplied_info *user_info_temp;
74 :
75 508 : if (nt_pwd == NULL && stored_aes_256_key != NULL && user_info->password.plaintext != NULL) {
76 0 : bool pw_equal;
77 0 : int krb5_ret;
78 0 : DATA_BLOB supplied_aes_256_key;
79 0 : krb5_keyblock key;
80 64 : krb5_data cleartext_data = {
81 64 : .data = user_info->password.plaintext,
82 64 : .length = strlen(user_info->password.plaintext)
83 : };
84 :
85 64 : *lm_sess_key = data_blob_null;
86 64 : *user_sess_key = data_blob_null;
87 :
88 64 : 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 64 : if (krb5_ret) {
95 0 : 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 0 : return NT_STATUS_INTERNAL_ERROR;
99 : }
100 :
101 64 : supplied_aes_256_key = data_blob_const(KRB5_KEY_DATA(&key),
102 32 : KRB5_KEY_LENGTH(&key));
103 :
104 64 : pw_equal = data_blob_equal_const_time(&supplied_aes_256_key,
105 : stored_aes_256_key);
106 :
107 64 : krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &key);
108 64 : if (!pw_equal) {
109 34 : return NT_STATUS_WRONG_PASSWORD;
110 : }
111 30 : return NT_STATUS_OK;
112 : }
113 :
114 444 : status = encrypt_user_info(mem_ctx, auth_context,
115 : AUTH_PASSWORD_HASH,
116 : user_info, &user_info_temp);
117 444 : if (!NT_STATUS_IS_OK(status)) {
118 0 : DEBUG(1, ("Failed to convert plaintext password to password HASH: %s\n", nt_errstr(status)));
119 0 : return status;
120 : }
121 444 : user_info = user_info_temp;
122 :
123 0 : FALL_THROUGH;
124 : }
125 : case AUTH_PASSWORD_HASH:
126 1036 : *lm_sess_key = data_blob(NULL, 0);
127 1036 : *user_sess_key = data_blob(NULL, 0);
128 1036 : status = hash_password_check(mem_ctx,
129 : false,
130 1036 : lpcfg_ntlm_auth(auth_context->lp_ctx),
131 : NULL,
132 1036 : user_info->password.hash.nt,
133 1036 : user_info->mapped.account_name,
134 : NULL, nt_pwd);
135 1036 : NT_STATUS_NOT_OK_RETURN(status);
136 696 : break;
137 :
138 27112 : case AUTH_PASSWORD_RESPONSE:
139 27112 : status = ntlm_password_check(mem_ctx,
140 : false,
141 27112 : lpcfg_ntlm_auth(auth_context->lp_ctx),
142 27112 : user_info->logon_parameters,
143 27112 : &auth_context->challenge.data,
144 : &user_info->password.response.lanman,
145 : &user_info->password.response.nt,
146 27112 : user_info->mapped.account_name,
147 27112 : user_info->client.account_name,
148 27112 : user_info->client.domain_name,
149 : NULL, nt_pwd,
150 : user_sess_key, lm_sess_key);
151 27112 : NT_STATUS_NOT_OK_RETURN(status);
152 21923 : break;
153 : }
154 :
155 24022 : return NT_STATUS_OK;
156 : }
157 :
158 9 : 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 0 : struct dcerpc_binding_handle *irpc_handle;
164 0 : struct winbind_SendToSam r;
165 0 : struct tevent_req *req;
166 0 : TALLOC_CTX *tmp_ctx;
167 :
168 9 : tmp_ctx = talloc_new(mem_ctx);
169 9 : if (tmp_ctx == NULL) {
170 0 : return;
171 : }
172 :
173 9 : irpc_handle = irpc_binding_handle_by_name(tmp_ctx, msg_ctx,
174 : "winbind_server",
175 : &ndr_table_winbind);
176 9 : if (irpc_handle == NULL) {
177 0 : DEBUG(1,(__location__ ": Unable to get binding handle for winbind\n"));
178 0 : TALLOC_FREE(tmp_ctx);
179 0 : return;
180 : }
181 :
182 9 : 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 9 : 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 9 : talloc_free(req);
198 9 : 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 125 : 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 0 : struct dcerpc_binding_handle *irpc_handle;
212 0 : struct drepl_trigger_repl_secret r;
213 0 : struct tevent_req *req;
214 0 : TALLOC_CTX *tmp_ctx;
215 :
216 125 : tmp_ctx = talloc_new(mem_ctx);
217 125 : if (tmp_ctx == NULL) {
218 0 : return;
219 : }
220 :
221 125 : irpc_handle = irpc_binding_handle_by_name(tmp_ctx, msg_ctx,
222 : "dreplsrv",
223 : &ndr_table_irpc);
224 125 : if (irpc_handle == NULL) {
225 0 : DEBUG(1,(__location__ ": Unable to get binding handle for dreplsrv\n"));
226 0 : TALLOC_FREE(tmp_ctx);
227 0 : return;
228 : }
229 :
230 125 : 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 125 : 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 125 : talloc_free(req);
246 125 : TALLOC_FREE(tmp_ctx);
247 : }
248 :
249 3737 : 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 1 : 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 3737 : if (in == NULL) {
264 2463 : 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 1273 : if (all_zero(in->hash, sizeof(in->hash))) {
272 0 : 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 1273 : if (mem_equal_const_time(in->hash, zero_string_hash.hash, 16)) {
285 0 : in = NULL;
286 : }
287 :
288 1273 : return in;
289 : }
290 :
291 : /*
292 : * Check that a password is OK, and update badPwdCount if required.
293 : */
294 :
295 27092 : 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 1404 : NTSTATUS nt_status;
305 1404 : NTSTATUS auth_status;
306 1404 : TALLOC_CTX *tmp_ctx;
307 1404 : int i, ret;
308 27092 : int history_len = 0;
309 27092 : struct ldb_context *sam_ctx = auth_context->sam_ctx;
310 27092 : const char * const attrs[] = { "pwdHistoryLength", NULL };
311 1404 : struct ldb_message *dom_msg;
312 1404 : struct samr_Password *nt_pwd;
313 27092 : DATA_BLOB _aes_256_key = data_blob_null;
314 27092 : DATA_BLOB *aes_256_key = NULL;
315 27092 : krb5_data _salt = { .data = NULL, .length = 0 };
316 27092 : krb5_data *salt = NULL;
317 27092 : DATA_BLOB salt_data = data_blob_null;
318 27092 : struct smb_krb5_context *smb_krb5_context = NULL;
319 1404 : const struct ldb_val *sc_val;
320 27092 : uint32_t userAccountControl = 0;
321 27092 : uint32_t current_kvno = 0;
322 1404 : bool am_rodc;
323 :
324 27092 : tmp_ctx = talloc_new(mem_ctx);
325 27092 : if (tmp_ctx == NULL) {
326 0 : 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 27092 : nt_status = samdb_result_passwords(tmp_ctx, auth_context->lp_ctx,
338 : msg, &nt_pwd);
339 27092 : if (!NT_STATUS_IS_OK(nt_status)) {
340 50 : TALLOC_FREE(tmp_ctx);
341 50 : return nt_status;
342 : }
343 :
344 27042 : userAccountControl = ldb_msg_find_attr_as_uint(msg,
345 : "userAccountControl",
346 : 0);
347 :
348 27042 : sc_val = ldb_msg_find_ldb_val(msg, "supplementalCredentials");
349 :
350 27042 : if (nt_pwd == NULL && sc_val == NULL) {
351 127 : 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 125 : auth_sam_trigger_repl_secret(auth_context,
370 : auth_context->msg_ctx,
371 : auth_context->event_ctx,
372 : msg->dn);
373 125 : TALLOC_FREE(tmp_ctx);
374 125 : 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 26917 : if (nt_pwd == NULL &&
383 50 : sc_val != NULL &&
384 50 : user_info->password_state == AUTH_PASSWORD_PLAIN)
385 : {
386 0 : krb5_error_code krb5_ret;
387 :
388 42 : krb5_ret = smb_krb5_init_context(tmp_ctx,
389 : auth_context->lp_ctx,
390 : &smb_krb5_context);
391 42 : if (krb5_ret != 0) {
392 0 : DBG_ERR("Failed to setup krb5_context: %s!\n",
393 : error_message(krb5_ret));
394 0 : return NT_STATUS_INTERNAL_ERROR;
395 : }
396 :
397 : /*
398 : * Get the current salt from the record
399 : */
400 :
401 42 : krb5_ret = dsdb_extract_aes_256_key(smb_krb5_context->krb5_context,
402 : tmp_ctx,
403 : msg,
404 : userAccountControl,
405 : NULL, /* kvno */
406 : ¤t_kvno, /* kvno_out */
407 : &_aes_256_key,
408 : &salt_data);
409 42 : if (krb5_ret == 0) {
410 42 : aes_256_key = &_aes_256_key;
411 :
412 42 : _salt.data = (char *)salt_data.data;
413 42 : _salt.length = salt_data.length;
414 42 : salt = &_salt;
415 : }
416 : }
417 :
418 26917 : 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 26917 : if (NT_STATUS_IS_OK(auth_status)) {
428 23636 : if (user_sess_key->data) {
429 22221 : talloc_steal(mem_ctx, user_sess_key->data);
430 : }
431 23636 : if (lm_sess_key->data) {
432 20595 : talloc_steal(mem_ctx, lm_sess_key->data);
433 : }
434 23636 : TALLOC_FREE(tmp_ctx);
435 23636 : return NT_STATUS_OK;
436 : }
437 3281 : *user_sess_key = data_blob_null;
438 3281 : *lm_sess_key = data_blob_null;
439 :
440 3281 : if (!NT_STATUS_EQUAL(auth_status, NT_STATUS_WRONG_PASSWORD)) {
441 224 : TALLOC_FREE(tmp_ctx);
442 224 : 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 3057 : ret = dsdb_search_one(sam_ctx, tmp_ctx, &dom_msg, domain_dn, LDB_SCOPE_BASE,
453 : attrs, 0, "objectClass=domain");
454 3057 : if (ret == LDB_SUCCESS) {
455 3057 : history_len = ldb_msg_find_attr_as_uint(dom_msg, "pwdHistoryLength", 0);
456 0 : } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
457 0 : DEBUG(3,("Couldn't find domain %s: %s!\n",
458 : ldb_dn_get_linearized(domain_dn),
459 : ldb_errstring(sam_ctx)));
460 : } else {
461 0 : DEBUG(3,("error finding domain %s: %s!\n",
462 : ldb_dn_get_linearized(domain_dn),
463 : ldb_errstring(sam_ctx)));
464 : }
465 :
466 3936 : for (i = 1; i < MIN(history_len, 3); i++) {
467 3737 : const struct samr_Password *nt_history_pwd = NULL;
468 1 : NTTIME pwdLastSet;
469 1 : struct timeval tv_now;
470 1 : NTTIME now;
471 1 : int allowed_period_mins;
472 1 : NTTIME allowed_period;
473 :
474 : /* Reset these variables back to starting as empty */
475 3737 : aes_256_key = NULL;
476 3737 : 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 3737 : 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 3737 : if (!NT_STATUS_IS_OK(nt_status)) {
500 2441 : break;
501 : }
502 :
503 3737 : 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 3737 : if (nt_history_pwd == NULL && sc_val != NULL &&
519 2462 : user_info->password_state == AUTH_PASSWORD_PLAIN &&
520 103 : current_kvno >= i)
521 22 : {
522 0 : krb5_error_code krb5_ret;
523 32 : const uint32_t request_kvno = current_kvno - i;
524 :
525 : /*
526 : * Confirm we have a krb5_context set up
527 : */
528 32 : 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 10 : break;
546 : }
547 :
548 : /*
549 : * Get the current salt from the record
550 : */
551 :
552 32 : 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 32 : if (krb5_ret != 0) {
561 10 : break;
562 : }
563 :
564 22 : aes_256_key = &_aes_256_key;
565 :
566 22 : _salt.data = (char *)salt_data.data;
567 22 : _salt.length = salt_data.length;
568 22 : salt = &_salt;
569 :
570 3705 : } 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 2431 : break;
577 : }
578 :
579 1295 : 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 1295 : 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 879 : *user_sess_key = data_blob_null;
594 879 : *lm_sess_key = data_blob_null;
595 879 : continue;
596 : }
597 :
598 416 : 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 25 : TALLOC_FREE(tmp_ctx);
611 25 : return NT_STATUS_WRONG_PASSWORD;
612 : }
613 :
614 391 : 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 5 : TALLOC_FREE(tmp_ctx);
628 5 : 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 386 : allowed_period_mins = lpcfg_old_password_allowed_period(auth_context->lp_ctx);
645 : /*
646 : * NTTIME uses 100ns units
647 : */
648 386 : allowed_period = (NTTIME) allowed_period_mins *
649 : 60 * 1000*1000*10;
650 386 : pwdLastSet = samdb_result_nttime(msg, "pwdLastSet", 0);
651 386 : tv_now = timeval_current();
652 386 : now = timeval_to_nttime(&tv_now);
653 :
654 386 : 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 0 : TALLOC_FREE(tmp_ctx);
666 0 : return NT_STATUS_WRONG_PASSWORD;
667 : }
668 :
669 386 : 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 0 : TALLOC_FREE(tmp_ctx);
681 0 : 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 386 : if (user_sess_key->data) {
689 281 : talloc_steal(mem_ctx, user_sess_key->data);
690 : }
691 386 : if (lm_sess_key->data) {
692 155 : talloc_steal(mem_ctx, lm_sess_key->data);
693 : }
694 :
695 386 : TALLOC_FREE(tmp_ctx);
696 386 : 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 2641 : nt_status = authsam_update_bad_pwd_count(auth_context->sam_ctx,
704 : msg, domain_dn);
705 2641 : 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 2 : 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 2641 : if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) {
718 18 : *authoritative = false;
719 : }
720 :
721 2641 : TALLOC_FREE(tmp_ctx);
722 :
723 2641 : if (NT_STATUS_IS_OK(nt_status)) {
724 2639 : nt_status = NT_STATUS_WRONG_PASSWORD;
725 : }
726 2641 : return nt_status;
727 : }
728 :
729 24022 : 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 24022 : TALLOC_CTX *tmp_ctx = NULL;
737 :
738 1403 : 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 24022 : const struct authn_server_policy *authn_server_policy = NULL;
747 :
748 1403 : struct dom_sid_buf netlogon_trust_sid_buf;
749 24022 : const char *netlogon_trust_sid_str = NULL;
750 24022 : struct ldb_dn *netlogon_trust_dn = NULL;
751 24022 : struct ldb_message *netlogon_trust_msg = NULL;
752 :
753 1403 : int ret;
754 :
755 : /* Have we established a secure channel? */
756 24022 : if (user_info->netlogon_trust_account.secure_channel_type == SEC_CHAN_NULL) {
757 12092 : return NT_STATUS_OK;
758 : }
759 :
760 11930 : if (!authn_policy_silos_and_policies_in_effect(sam_ctx)) {
761 428 : 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 11502 : SMB_ASSERT(user_info->netlogon_trust_account.sid != NULL);
769 :
770 11502 : tmp_ctx = talloc_new(mem_ctx);
771 11502 : if (tmp_ctx == NULL) {
772 0 : return NT_STATUS_NO_MEMORY;
773 : }
774 :
775 11502 : netlogon_trust_sid_str = dom_sid_str_buf(user_info->netlogon_trust_account.sid,
776 : &netlogon_trust_sid_buf);
777 :
778 11502 : netlogon_trust_dn = ldb_dn_new_fmt(tmp_ctx, sam_ctx,
779 : "<SID=%s>",
780 : netlogon_trust_sid_str);
781 11502 : if (netlogon_trust_dn == NULL) {
782 0 : talloc_free(tmp_ctx);
783 0 : 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 11502 : 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 11502 : if (ret) {
799 0 : talloc_free(tmp_ctx);
800 0 : return dsdb_ldb_err_to_ntstatus(ret);
801 : }
802 :
803 11502 : ret = authn_policy_server(sam_ctx,
804 : tmp_ctx,
805 : netlogon_trust_msg,
806 : &authn_server_policy);
807 11502 : if (ret) {
808 0 : talloc_free(tmp_ctx);
809 0 : return NT_STATUS_INTERNAL_ERROR;
810 : }
811 :
812 11502 : if (authn_server_policy != NULL) {
813 104 : struct authn_audit_info *server_audit_info = NULL;
814 0 : NTSTATUS status;
815 :
816 : /*
817 : * An authentication policy applies to the machine
818 : * account. Carry out the access check.
819 : */
820 104 : 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 104 : (struct auth_claims) {},
832 : authn_server_policy,
833 104 : (struct authn_policy_flags) {},
834 : &server_audit_info);
835 104 : if (server_audit_info != NULL) {
836 104 : *server_audit_info_out = talloc_move(mem_ctx, &server_audit_info);
837 : }
838 104 : if (!NT_STATUS_IS_OK(status)) {
839 52 : talloc_free(tmp_ctx);
840 52 : return status;
841 : }
842 : }
843 :
844 11450 : return NT_STATUS_OK;
845 : }
846 :
847 27137 : 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 1404 : NTSTATUS nt_status;
859 1404 : int ret;
860 27137 : bool interactive = (user_info->password_state == AUTH_PASSWORD_HASH);
861 27137 : uint32_t acct_flags = samdb_result_acct_flags(msg, NULL);
862 27137 : struct netr_SendToSamBase *send_to_sam = NULL;
863 27137 : const struct authn_ntlm_client_policy *authn_client_policy = NULL;
864 27137 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
865 27137 : if (!tmp_ctx) {
866 0 : return NT_STATUS_NO_MEMORY;
867 : }
868 :
869 : /* You can only do an interactive login to normal accounts */
870 27137 : if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) {
871 530 : if (!(acct_flags & ACB_NORMAL)) {
872 5 : TALLOC_FREE(tmp_ctx);
873 5 : return NT_STATUS_NO_SUCH_USER;
874 : }
875 525 : if (acct_flags & ACB_SMARTCARD_REQUIRED) {
876 2 : if (acct_flags & ACB_DISABLED) {
877 0 : DEBUG(2,("authsam_authenticate: Account for user '%s' "
878 : "was disabled.\n",
879 : user_info->mapped.account_name));
880 0 : TALLOC_FREE(tmp_ctx);
881 0 : return NT_STATUS_ACCOUNT_DISABLED;
882 : }
883 2 : DEBUG(2,("authsam_authenticate: Account for user '%s' "
884 : "requires interactive smartcard logon.\n",
885 : user_info->mapped.account_name));
886 2 : TALLOC_FREE(tmp_ctx);
887 2 : return NT_STATUS_SMARTCARD_LOGON_REQUIRED;
888 : }
889 : }
890 :
891 : /* See whether an authentication policy applies to the client. */
892 27130 : ret = authn_policy_ntlm_client(auth_context->sam_ctx,
893 : tmp_ctx,
894 : msg,
895 : &authn_client_policy);
896 27130 : if (ret) {
897 0 : TALLOC_FREE(tmp_ctx);
898 0 : return NT_STATUS_INTERNAL_ERROR;
899 : }
900 :
901 27130 : nt_status = authn_policy_ntlm_apply_device_restriction(mem_ctx,
902 : authn_client_policy,
903 : client_audit_info_out);
904 27130 : 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 38 : TALLOC_FREE(tmp_ctx);
911 38 : return nt_status;
912 : }
913 :
914 27092 : 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 27092 : if (!NT_STATUS_IS_OK(nt_status)) {
920 3070 : TALLOC_FREE(tmp_ctx);
921 3070 : return nt_status;
922 : }
923 :
924 24022 : 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 24022 : if (!NT_STATUS_IS_OK(nt_status)) {
931 52 : TALLOC_FREE(tmp_ctx);
932 52 : return nt_status;
933 : }
934 :
935 25373 : nt_status = authsam_account_ok(tmp_ctx, auth_context->sam_ctx,
936 23970 : user_info->logon_parameters,
937 : domain_dn,
938 : msg,
939 23970 : user_info->workstation_name,
940 23970 : user_info->mapped.account_name,
941 : false, false);
942 23970 : if (!NT_STATUS_IS_OK(nt_status)) {
943 966 : TALLOC_FREE(tmp_ctx);
944 966 : return nt_status;
945 : }
946 :
947 23004 : 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 23004 : if (send_to_sam != NULL) {
954 9 : auth_sam_trigger_zero_password(tmp_ctx,
955 : auth_context->msg_ctx,
956 : auth_context->event_ctx,
957 : send_to_sam);
958 : }
959 :
960 23004 : if (!NT_STATUS_IS_OK(nt_status)) {
961 0 : TALLOC_FREE(tmp_ctx);
962 0 : return nt_status;
963 : }
964 :
965 23004 : if (user_sess_key && user_sess_key->data) {
966 21691 : talloc_steal(mem_ctx, user_sess_key->data);
967 : }
968 23004 : if (lm_sess_key && lm_sess_key->data) {
969 20219 : talloc_steal(mem_ctx, lm_sess_key->data);
970 : }
971 :
972 23004 : TALLOC_FREE(tmp_ctx);
973 23004 : return nt_status;
974 : }
975 :
976 :
977 :
978 28335 : 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 1410 : NTSTATUS nt_status;
987 1410 : int result;
988 28335 : const char *account_name = user_info->mapped.account_name;
989 1410 : struct ldb_message *msg;
990 1410 : struct ldb_dn *domain_dn;
991 1410 : DATA_BLOB user_sess_key, lm_sess_key;
992 1410 : TALLOC_CTX *tmp_ctx;
993 28335 : const char *p = NULL;
994 28335 : struct auth_user_info_dc *reparented = NULL;
995 28335 : struct authn_audit_info *client_audit_info = NULL;
996 28335 : struct authn_audit_info *server_audit_info = NULL;
997 :
998 28335 : if (ctx->auth_ctx->sam_ctx == NULL) {
999 0 : DEBUG(0, ("No SAM available, cannot log in users\n"));
1000 0 : return NT_STATUS_INVALID_SYSTEM_SERVICE;
1001 : }
1002 :
1003 28335 : if (!account_name || !*account_name) {
1004 : /* 'not for me' */
1005 0 : return NT_STATUS_NOT_IMPLEMENTED;
1006 : }
1007 :
1008 28335 : tmp_ctx = talloc_new(mem_ctx);
1009 28335 : if (!tmp_ctx) {
1010 0 : return NT_STATUS_NO_MEMORY;
1011 : }
1012 :
1013 28335 : domain_dn = ldb_get_default_basedn(ctx->auth_ctx->sam_ctx);
1014 28335 : if (domain_dn == NULL) {
1015 0 : talloc_free(tmp_ctx);
1016 0 : 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 28335 : if (!user_info->cracknames_called) {
1031 27894 : p = strchr_m(account_name, '@');
1032 : } else {
1033 : /*
1034 : * This is slightly nicer than double-indenting the
1035 : * block below
1036 : */
1037 441 : p = NULL;
1038 : }
1039 :
1040 28335 : if (p != NULL) {
1041 7894 : const char *nt4_domain = NULL;
1042 7894 : const char *nt4_account = NULL;
1043 7894 : bool is_my_domain = false;
1044 :
1045 8854 : nt_status = crack_name_to_nt4_name(mem_ctx,
1046 7894 : 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 7894 : if (!NT_STATUS_IS_OK(nt_status)) {
1054 0 : talloc_free(tmp_ctx);
1055 0 : return NT_STATUS_NO_SUCH_USER;
1056 : }
1057 :
1058 7894 : is_my_domain = lpcfg_is_mydomain(ctx->auth_ctx->lp_ctx, nt4_domain);
1059 7894 : 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 0 : talloc_free(tmp_ctx);
1066 0 : return NT_STATUS_NOT_IMPLEMENTED;
1067 : }
1068 :
1069 : /*
1070 : * Let's use the NT4 account name for the lookup.
1071 : */
1072 7894 : account_name = nt4_account;
1073 : }
1074 :
1075 28335 : nt_status = authsam_search_account(tmp_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg);
1076 28335 : if (!NT_STATUS_IS_OK(nt_status)) {
1077 1181 : talloc_free(tmp_ctx);
1078 1181 : return nt_status;
1079 : }
1080 :
1081 27154 : nt_status = authsam_make_user_info_dc(tmp_ctx, ctx->auth_ctx->sam_ctx,
1082 27154 : lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
1083 27154 : lpcfg_sam_name(ctx->auth_ctx->lp_ctx),
1084 27154 : 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 27154 : if (!NT_STATUS_IS_OK(nt_status)) {
1090 0 : talloc_free(tmp_ctx);
1091 0 : return nt_status;
1092 : }
1093 :
1094 28558 : result = dsdb_is_protected_user(ctx->auth_ctx->sam_ctx,
1095 27154 : (*user_info_dc)->sids,
1096 27154 : (*user_info_dc)->num_sids);
1097 : /*
1098 : * We also consider an error result (a negative value) as denying the
1099 : * authentication.
1100 : */
1101 27154 : if (result != 0) {
1102 17 : talloc_free(tmp_ctx);
1103 17 : return NT_STATUS_ACCOUNT_RESTRICTION;
1104 : }
1105 :
1106 27137 : 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 27137 : if (client_audit_info != NULL) {
1118 100 : *client_audit_info_out = talloc_move(mem_ctx, &client_audit_info);
1119 : }
1120 27137 : if (server_audit_info != NULL) {
1121 104 : *server_audit_info_out = talloc_move(mem_ctx, &server_audit_info);
1122 : }
1123 27137 : if (!NT_STATUS_IS_OK(nt_status)) {
1124 4133 : talloc_free(tmp_ctx);
1125 4133 : return nt_status;
1126 : }
1127 :
1128 23004 : (*user_info_dc)->user_session_key = data_blob_talloc(*user_info_dc,
1129 : user_sess_key.data,
1130 : user_sess_key.length);
1131 23004 : if (user_sess_key.data) {
1132 21691 : if ((*user_info_dc)->user_session_key.data == NULL) {
1133 0 : TALLOC_FREE(tmp_ctx);
1134 0 : return NT_STATUS_NO_MEMORY;
1135 : }
1136 : }
1137 :
1138 23004 : (*user_info_dc)->lm_session_key = data_blob_talloc(*user_info_dc,
1139 : lm_sess_key.data,
1140 : lm_sess_key.length);
1141 23004 : if (lm_sess_key.data) {
1142 20219 : if ((*user_info_dc)->lm_session_key.data == NULL) {
1143 0 : TALLOC_FREE(tmp_ctx);
1144 0 : 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 23004 : reparented = talloc_reparent(tmp_ctx, mem_ctx, *user_info_dc);
1153 23004 : if (reparented == NULL) {
1154 0 : talloc_free(tmp_ctx);
1155 0 : return NT_STATUS_INTERNAL_ERROR;
1156 : }
1157 :
1158 23004 : talloc_free(tmp_ctx);
1159 :
1160 23004 : 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 28335 : 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 28335 : struct tevent_req *req = NULL;
1177 28335 : struct authsam_check_password_state *state = NULL;
1178 1410 : NTSTATUS status;
1179 :
1180 28335 : req = tevent_req_create(
1181 : mem_ctx, &state, struct authsam_check_password_state);
1182 28335 : if (req == NULL) {
1183 0 : 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 28335 : state->authoritative = true;
1191 :
1192 28335 : status = authsam_check_password_internals(
1193 : ctx,
1194 : state,
1195 : user_info,
1196 26925 : &state->user_info_dc,
1197 26925 : &state->client_audit_info,
1198 26925 : &state->server_audit_info,
1199 26925 : &state->authoritative);
1200 28335 : if (tevent_req_nterror(req, status)) {
1201 5331 : return tevent_req_post(req, ev);
1202 : }
1203 :
1204 23004 : tevent_req_done(req);
1205 23004 : return tevent_req_post(req, ev);
1206 : }
1207 :
1208 28335 : 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 28335 : struct authsam_check_password_state *state = tevent_req_data(
1217 : req, struct authsam_check_password_state);
1218 1410 : NTSTATUS status;
1219 :
1220 28335 : *authoritative = state->authoritative;
1221 :
1222 28335 : *client_audit_info = talloc_reparent(state, mem_ctx, state->client_audit_info);
1223 28335 : state->client_audit_info = NULL;
1224 :
1225 28335 : *server_audit_info = talloc_reparent(state, mem_ctx, state->server_audit_info);
1226 28335 : state->server_audit_info = NULL;
1227 :
1228 28335 : if (tevent_req_is_nterror(req, &status)) {
1229 5331 : tevent_req_received(req);
1230 5331 : 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 23004 : *interim_info = talloc_reparent(state, mem_ctx, state->user_info_dc);
1237 23004 : state->user_info_dc = NULL;
1238 :
1239 23004 : tevent_req_received(req);
1240 23004 : return NT_STATUS_OK;
1241 : }
1242 :
1243 1187 : 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 1187 : if (!user_info->mapped.account_name || !*user_info->mapped.account_name) {
1248 12 : return NT_STATUS_NOT_IMPLEMENTED;
1249 : }
1250 :
1251 1175 : return NT_STATUS_OK;
1252 : }
1253 :
1254 : /****************************************************************************
1255 : Check SAM security (above) but with a few extra checks.
1256 : ****************************************************************************/
1257 28603 : 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 28603 : const char *effective_domain = user_info->mapped.domain_name;
1262 28603 : bool is_local_name = false;
1263 28603 : bool is_my_domain = false;
1264 28603 : const char *p = NULL;
1265 28603 : struct dsdb_trust_routing_table *trt = NULL;
1266 28603 : const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
1267 1410 : NTSTATUS status;
1268 :
1269 28603 : if (!user_info->mapped.account_name || !*user_info->mapped.account_name) {
1270 14 : return NT_STATUS_NOT_IMPLEMENTED;
1271 : }
1272 :
1273 28589 : if (effective_domain == NULL) {
1274 1644 : effective_domain = "";
1275 : }
1276 :
1277 28589 : 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 28589 : switch (lpcfg_server_role(ctx->auth_ctx->lp_ctx)) {
1282 0 : case ROLE_STANDALONE:
1283 103 : return NT_STATUS_OK;
1284 :
1285 103 : case ROLE_DOMAIN_MEMBER:
1286 103 : if (is_local_name) {
1287 98 : return NT_STATUS_OK;
1288 : }
1289 :
1290 5 : DBG_DEBUG("%s is not one of my local names (DOMAIN_MEMBER)\n",
1291 : effective_domain);
1292 5 : return NT_STATUS_NOT_IMPLEMENTED;
1293 :
1294 27076 : case ROLE_ACTIVE_DIRECTORY_DC:
1295 : /* handled later */
1296 28486 : break;
1297 :
1298 0 : default:
1299 0 : DBG_ERR("lpcfg_server_role() has an undefined value\n");
1300 0 : return NT_STATUS_INVALID_SERVER_STATE;
1301 : }
1302 :
1303 : /*
1304 : * Now we handle the AD DC case...
1305 : */
1306 :
1307 28486 : is_my_domain = lpcfg_is_my_domain_or_realm(ctx->auth_ctx->lp_ctx,
1308 : effective_domain);
1309 28486 : if (is_my_domain) {
1310 19231 : return NT_STATUS_OK;
1311 : }
1312 :
1313 9255 : if (user_info->cracknames_called) {
1314 : /*
1315 : * The caller already did a cracknames call.
1316 : */
1317 0 : DBG_DEBUG("%s is not own domain name (DC)\n",
1318 : effective_domain);
1319 0 : return NT_STATUS_NOT_IMPLEMENTED;
1320 : }
1321 :
1322 9255 : if (!strequal(effective_domain, "")) {
1323 1392 : DBG_DEBUG("%s is not own domain name (DC)\n",
1324 : effective_domain);
1325 1392 : return NT_STATUS_NOT_IMPLEMENTED;
1326 : }
1327 :
1328 7863 : p = strchr_m(user_info->mapped.account_name, '@');
1329 7863 : if (p == NULL) {
1330 : /*
1331 : * An empty to domain name should be handled
1332 : * as the local domain name.
1333 : */
1334 9 : return NT_STATUS_OK;
1335 : }
1336 :
1337 7854 : effective_domain = p + 1;
1338 7854 : is_my_domain = lpcfg_is_my_domain_or_realm(ctx->auth_ctx->lp_ctx,
1339 : effective_domain);
1340 7854 : if (is_my_domain) {
1341 7822 : return NT_STATUS_OK;
1342 : }
1343 :
1344 32 : if (strequal(effective_domain, "")) {
1345 2 : DBG_DEBUG("authsam_check_password: upn without realm (DC)\n");
1346 2 : 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 30 : status = dsdb_trust_routing_table_load(ctx->auth_ctx->sam_ctx,
1354 : mem_ctx, &trt);
1355 30 : if (!NT_STATUS_IS_OK(status)) {
1356 0 : DBG_ERR("authsam_check_password: dsdb_trust_routing_table_load() %s\n",
1357 : nt_errstr(status));
1358 0 : return status;
1359 : }
1360 :
1361 30 : tdo = dsdb_trust_routing_by_name(trt, effective_domain);
1362 30 : if (tdo == NULL) {
1363 18 : DBG_DEBUG("%s is not a known TLN (DC)\n",
1364 : effective_domain);
1365 18 : TALLOC_FREE(trt);
1366 18 : return NT_STATUS_NOT_IMPLEMENTED;
1367 : }
1368 :
1369 12 : if (!(tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
1370 12 : DBG_DEBUG("%s is not a TLN in our forest (DC)\n",
1371 : effective_domain);
1372 12 : TALLOC_FREE(trt);
1373 12 : 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 0 : TALLOC_FREE(trt);
1382 0 : 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 9681 : _PUBLIC_ NTSTATUS auth4_sam_init(TALLOC_CTX *ctx)
1401 : {
1402 837 : NTSTATUS ret;
1403 :
1404 9681 : ret = auth_register(ctx, &sam_ops);
1405 9681 : if (!NT_STATUS_IS_OK(ret)) {
1406 0 : DEBUG(0,("Failed to register 'sam' auth backend!\n"));
1407 0 : return ret;
1408 : }
1409 :
1410 9681 : ret = auth_register(ctx, &sam_ignoredomain_ops);
1411 9681 : if (!NT_STATUS_IS_OK(ret)) {
1412 0 : DEBUG(0,("Failed to register 'sam_ignoredomain' auth backend!\n"));
1413 0 : return ret;
1414 : }
1415 :
1416 9681 : return ret;
1417 : }
|