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