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