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 28115 : 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 28115 : 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 1023 : *lm_sess_key = data_blob(NULL, 0);
127 1023 : *user_sess_key = data_blob(NULL, 0);
128 1023 : status = hash_password_check(mem_ctx,
129 : false,
130 1023 : lpcfg_ntlm_auth(auth_context->lp_ctx),
131 : NULL,
132 1023 : user_info->password.hash.nt,
133 1023 : user_info->mapped.account_name,
134 : NULL, nt_pwd);
135 1023 : NT_STATUS_NOT_OK_RETURN(status);
136 683 : break;
137 :
138 27028 : case AUTH_PASSWORD_RESPONSE:
139 27028 : status = ntlm_password_check(mem_ctx,
140 : false,
141 27028 : lpcfg_ntlm_auth(auth_context->lp_ctx),
142 27028 : user_info->logon_parameters,
143 27028 : &auth_context->challenge.data,
144 : &user_info->password.response.lanman,
145 : &user_info->password.response.nt,
146 27028 : user_info->mapped.account_name,
147 27028 : user_info->client.account_name,
148 27028 : user_info->client.domain_name,
149 : NULL, nt_pwd,
150 : user_sess_key, lm_sess_key);
151 27028 : NT_STATUS_NOT_OK_RETURN(status);
152 21841 : break;
153 : }
154 :
155 23927 : 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 3735 : 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 3735 : if (in == NULL) {
264 2461 : 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 26995 : 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 26995 : int history_len = 0;
309 26995 : struct ldb_context *sam_ctx = auth_context->sam_ctx;
310 26995 : const char * const attrs[] = { "pwdHistoryLength", NULL };
311 1404 : struct ldb_message *dom_msg;
312 1404 : struct samr_Password *nt_pwd;
313 26995 : DATA_BLOB _aes_256_key = data_blob_null;
314 26995 : DATA_BLOB *aes_256_key = NULL;
315 26995 : krb5_data _salt = { .data = NULL, .length = 0 };
316 26995 : krb5_data *salt = NULL;
317 26995 : DATA_BLOB salt_data = data_blob_null;
318 26995 : struct smb_krb5_context *smb_krb5_context = NULL;
319 1404 : const struct ldb_val *sc_val;
320 26995 : uint32_t userAccountControl = 0;
321 26995 : uint32_t current_kvno = 0;
322 1404 : bool am_rodc;
323 :
324 26995 : tmp_ctx = talloc_new(mem_ctx);
325 26995 : 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 26995 : nt_status = samdb_result_passwords(tmp_ctx, auth_context->lp_ctx,
338 : msg, &nt_pwd);
339 26995 : if (!NT_STATUS_IS_OK(nt_status)) {
340 50 : TALLOC_FREE(tmp_ctx);
341 50 : return nt_status;
342 : }
343 :
344 26945 : userAccountControl = ldb_msg_find_attr_as_uint(msg,
345 : "userAccountControl",
346 : 0);
347 :
348 26945 : sc_val = ldb_msg_find_ldb_val(msg, "supplementalCredentials");
349 :
350 26945 : 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 26820 : 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 26820 : 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 26820 : if (NT_STATUS_IS_OK(auth_status)) {
428 23541 : if (user_sess_key->data) {
429 22139 : talloc_steal(mem_ctx, user_sess_key->data);
430 : }
431 23541 : if (lm_sess_key->data) {
432 20528 : talloc_steal(mem_ctx, lm_sess_key->data);
433 : }
434 23541 : TALLOC_FREE(tmp_ctx);
435 23541 : return NT_STATUS_OK;
436 : }
437 3279 : *user_sess_key = data_blob_null;
438 3279 : *lm_sess_key = data_blob_null;
439 :
440 3279 : 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 3055 : ret = dsdb_search_one(sam_ctx, tmp_ctx, &dom_msg, domain_dn, LDB_SCOPE_BASE,
453 : attrs, 0, "objectClass=domain");
454 3055 : if (ret == LDB_SUCCESS) {
455 3055 : 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 3934 : for (i = 1; i < MIN(history_len, 3); i++) {
467 3735 : 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 3735 : aes_256_key = NULL;
476 3735 : 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 3735 : 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 3735 : if (!NT_STATUS_IS_OK(nt_status)) {
500 2439 : break;
501 : }
502 :
503 3735 : 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 3735 : if (nt_history_pwd == NULL && sc_val != NULL &&
519 2460 : 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 3703 : } 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 2429 : 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 2639 : nt_status = authsam_update_bad_pwd_count(auth_context->sam_ctx,
704 : msg, domain_dn);
705 2639 : 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 2639 : if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) {
718 18 : *authoritative = false;
719 : }
720 :
721 2639 : TALLOC_FREE(tmp_ctx);
722 :
723 2639 : if (NT_STATUS_IS_OK(nt_status)) {
724 2637 : nt_status = NT_STATUS_WRONG_PASSWORD;
725 : }
726 2639 : return nt_status;
727 : }
728 :
729 23927 : 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 23927 : 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 23927 : const struct authn_server_policy *authn_server_policy = NULL;
747 :
748 1403 : struct dom_sid_buf netlogon_trust_sid_buf;
749 23927 : const char *netlogon_trust_sid_str = NULL;
750 23927 : struct ldb_dn *netlogon_trust_dn = NULL;
751 23927 : struct ldb_message *netlogon_trust_msg = NULL;
752 :
753 1403 : int ret;
754 :
755 : /* Have we established a secure channel? */
756 23927 : if (user_info->netlogon_trust_account.secure_channel_type == SEC_CHAN_NULL) {
757 12032 : return NT_STATUS_OK;
758 : }
759 :
760 11895 : if (!authn_policy_silos_and_policies_in_effect(sam_ctx)) {
761 427 : 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 11468 : SMB_ASSERT(user_info->netlogon_trust_account.sid != NULL);
769 :
770 11468 : tmp_ctx = talloc_new(mem_ctx);
771 11468 : if (tmp_ctx == NULL) {
772 0 : return NT_STATUS_NO_MEMORY;
773 : }
774 :
775 11468 : netlogon_trust_sid_str = dom_sid_str_buf(user_info->netlogon_trust_account.sid,
776 : &netlogon_trust_sid_buf);
777 :
778 11468 : netlogon_trust_dn = ldb_dn_new_fmt(tmp_ctx, sam_ctx,
779 : "<SID=%s>",
780 : netlogon_trust_sid_str);
781 11468 : 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 11468 : 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 11468 : if (ret) {
799 0 : talloc_free(tmp_ctx);
800 0 : return dsdb_ldb_err_to_ntstatus(ret);
801 : }
802 :
803 11468 : ret = authn_policy_server(sam_ctx,
804 : tmp_ctx,
805 : netlogon_trust_msg,
806 : &authn_server_policy);
807 11468 : if (ret) {
808 0 : talloc_free(tmp_ctx);
809 0 : return NT_STATUS_INTERNAL_ERROR;
810 : }
811 :
812 11468 : if (authn_server_policy != NULL) {
813 80 : 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 80 : 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 80 : (struct auth_claims) {},
827 : authn_server_policy,
828 80 : (struct authn_policy_flags) {},
829 : &server_audit_info);
830 80 : if (server_audit_info != NULL) {
831 80 : *server_audit_info_out = talloc_move(mem_ctx, &server_audit_info);
832 : }
833 80 : if (!NT_STATUS_IS_OK(status)) {
834 36 : talloc_free(tmp_ctx);
835 36 : return status;
836 : }
837 : }
838 :
839 11432 : return NT_STATUS_OK;
840 : }
841 :
842 27038 : static NTSTATUS authsam_authenticate(struct auth4_context *auth_context,
843 : TALLOC_CTX *mem_ctx,
844 : struct ldb_dn *domain_dn,
845 : struct ldb_message *msg,
846 : const struct auth_usersupplied_info *user_info,
847 : const struct auth_user_info_dc *user_info_dc,
848 : DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key,
849 : struct authn_audit_info **client_audit_info_out,
850 : struct authn_audit_info **server_audit_info_out,
851 : bool *authoritative)
852 : {
853 1404 : NTSTATUS nt_status;
854 1404 : int ret;
855 27038 : bool interactive = (user_info->password_state == AUTH_PASSWORD_HASH);
856 27038 : uint32_t acct_flags = samdb_result_acct_flags(msg, NULL);
857 27038 : struct netr_SendToSamBase *send_to_sam = NULL;
858 27038 : const struct authn_ntlm_client_policy *authn_client_policy = NULL;
859 27038 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
860 27038 : if (!tmp_ctx) {
861 0 : return NT_STATUS_NO_MEMORY;
862 : }
863 :
864 : /* You can only do an interactive login to normal accounts */
865 27038 : if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) {
866 515 : if (!(acct_flags & ACB_NORMAL)) {
867 5 : TALLOC_FREE(tmp_ctx);
868 5 : return NT_STATUS_NO_SUCH_USER;
869 : }
870 510 : if (acct_flags & ACB_SMARTCARD_REQUIRED) {
871 0 : if (acct_flags & ACB_DISABLED) {
872 0 : DEBUG(2,("authsam_authenticate: Account for user '%s' "
873 : "was disabled.\n",
874 : user_info->mapped.account_name));
875 0 : TALLOC_FREE(tmp_ctx);
876 0 : return NT_STATUS_ACCOUNT_DISABLED;
877 : }
878 0 : DEBUG(2,("authsam_authenticate: Account for user '%s' "
879 : "requires interactive smartcard logon.\n",
880 : user_info->mapped.account_name));
881 0 : TALLOC_FREE(tmp_ctx);
882 0 : return NT_STATUS_SMARTCARD_LOGON_REQUIRED;
883 : }
884 : }
885 :
886 : /* See whether an authentication policy applies to the client. */
887 27033 : ret = authn_policy_ntlm_client(auth_context->sam_ctx,
888 : tmp_ctx,
889 : msg,
890 : &authn_client_policy);
891 27033 : if (ret) {
892 0 : TALLOC_FREE(tmp_ctx);
893 0 : return NT_STATUS_INTERNAL_ERROR;
894 : }
895 :
896 27033 : nt_status = authn_policy_ntlm_apply_device_restriction(mem_ctx,
897 : authn_client_policy,
898 : client_audit_info_out);
899 27033 : if (!NT_STATUS_IS_OK(nt_status)) {
900 : /*
901 : * As we didn’t get far enough to check the server policy, only
902 : * the client policy will be referenced in the authentication
903 : * log message.
904 : */
905 38 : TALLOC_FREE(tmp_ctx);
906 38 : return nt_status;
907 : }
908 :
909 26995 : nt_status = authsam_password_check_and_record(auth_context, tmp_ctx,
910 : domain_dn, msg,
911 : user_info,
912 : user_sess_key, lm_sess_key,
913 : authoritative);
914 26995 : if (!NT_STATUS_IS_OK(nt_status)) {
915 3068 : TALLOC_FREE(tmp_ctx);
916 3068 : return nt_status;
917 : }
918 :
919 23927 : nt_status = authsam_check_netlogon_trust(mem_ctx,
920 : auth_context->sam_ctx,
921 : auth_context->lp_ctx,
922 : user_info,
923 : user_info_dc,
924 : server_audit_info_out);
925 23927 : if (!NT_STATUS_IS_OK(nt_status)) {
926 36 : TALLOC_FREE(tmp_ctx);
927 36 : return nt_status;
928 : }
929 :
930 25294 : nt_status = authsam_account_ok(tmp_ctx, auth_context->sam_ctx,
931 23891 : user_info->logon_parameters,
932 : domain_dn,
933 : msg,
934 23891 : user_info->workstation_name,
935 23891 : user_info->mapped.account_name,
936 : false, false);
937 23891 : if (!NT_STATUS_IS_OK(nt_status)) {
938 960 : TALLOC_FREE(tmp_ctx);
939 960 : return nt_status;
940 : }
941 :
942 22931 : nt_status = authsam_logon_success_accounting(auth_context->sam_ctx,
943 : msg, domain_dn,
944 : interactive,
945 : tmp_ctx,
946 : &send_to_sam);
947 :
948 22931 : if (send_to_sam != NULL) {
949 9 : auth_sam_trigger_zero_password(tmp_ctx,
950 : auth_context->msg_ctx,
951 : auth_context->event_ctx,
952 : send_to_sam);
953 : }
954 :
955 22931 : if (!NT_STATUS_IS_OK(nt_status)) {
956 0 : TALLOC_FREE(tmp_ctx);
957 0 : return nt_status;
958 : }
959 :
960 22931 : if (user_sess_key && user_sess_key->data) {
961 21623 : talloc_steal(mem_ctx, user_sess_key->data);
962 : }
963 22931 : if (lm_sess_key && lm_sess_key->data) {
964 20158 : talloc_steal(mem_ctx, lm_sess_key->data);
965 : }
966 :
967 22931 : TALLOC_FREE(tmp_ctx);
968 22931 : return nt_status;
969 : }
970 :
971 :
972 :
973 27778 : static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx,
974 : TALLOC_CTX *mem_ctx,
975 : const struct auth_usersupplied_info *user_info,
976 : struct auth_user_info_dc **user_info_dc,
977 : struct authn_audit_info **client_audit_info_out,
978 : struct authn_audit_info **server_audit_info_out,
979 : bool *authoritative)
980 : {
981 1410 : NTSTATUS nt_status;
982 1410 : int result;
983 27778 : const char *account_name = user_info->mapped.account_name;
984 1410 : struct ldb_message *msg;
985 1410 : struct ldb_dn *domain_dn;
986 1410 : DATA_BLOB user_sess_key, lm_sess_key;
987 1410 : TALLOC_CTX *tmp_ctx;
988 27778 : const char *p = NULL;
989 27778 : struct auth_user_info_dc *reparented = NULL;
990 27778 : struct authn_audit_info *client_audit_info = NULL;
991 27778 : struct authn_audit_info *server_audit_info = NULL;
992 :
993 27778 : if (ctx->auth_ctx->sam_ctx == NULL) {
994 0 : DEBUG(0, ("No SAM available, cannot log in users\n"));
995 0 : return NT_STATUS_INVALID_SYSTEM_SERVICE;
996 : }
997 :
998 27778 : if (!account_name || !*account_name) {
999 : /* 'not for me' */
1000 0 : return NT_STATUS_NOT_IMPLEMENTED;
1001 : }
1002 :
1003 27778 : tmp_ctx = talloc_new(mem_ctx);
1004 27778 : if (!tmp_ctx) {
1005 0 : return NT_STATUS_NO_MEMORY;
1006 : }
1007 :
1008 27778 : domain_dn = ldb_get_default_basedn(ctx->auth_ctx->sam_ctx);
1009 27778 : if (domain_dn == NULL) {
1010 0 : talloc_free(tmp_ctx);
1011 0 : return NT_STATUS_NO_SUCH_DOMAIN;
1012 : }
1013 :
1014 : /*
1015 : * If we have not already mapped this user, then now is a good
1016 : * time to do so, before we look it up. We used to do this
1017 : * earlier, but in a multi-forest environment we want to do
1018 : * this mapping at the final domain.
1019 : *
1020 : * However, on the flip side we may have already mapped the
1021 : * user if this was an LDAP simple bind, in which case we
1022 : * really, really want to get back to exactly the same account
1023 : * we got the DN for.
1024 : */
1025 27778 : if (!user_info->cracknames_called) {
1026 27337 : p = strchr_m(account_name, '@');
1027 : } else {
1028 : /*
1029 : * This is slightly nicer than double-indenting the
1030 : * block below
1031 : */
1032 441 : p = NULL;
1033 : }
1034 :
1035 27778 : if (p != NULL) {
1036 7895 : const char *nt4_domain = NULL;
1037 7895 : const char *nt4_account = NULL;
1038 7895 : bool is_my_domain = false;
1039 :
1040 8855 : nt_status = crack_name_to_nt4_name(mem_ctx,
1041 7895 : ctx->auth_ctx->sam_ctx,
1042 : /*
1043 : * DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON ?
1044 : */
1045 : DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
1046 : account_name,
1047 : &nt4_domain, &nt4_account);
1048 7895 : if (!NT_STATUS_IS_OK(nt_status)) {
1049 0 : talloc_free(tmp_ctx);
1050 0 : return NT_STATUS_NO_SUCH_USER;
1051 : }
1052 :
1053 7895 : is_my_domain = lpcfg_is_mydomain(ctx->auth_ctx->lp_ctx, nt4_domain);
1054 7895 : if (!is_my_domain) {
1055 : /*
1056 : * This is a user within our forest,
1057 : * but in a different domain,
1058 : * we're not authoritative
1059 : */
1060 0 : talloc_free(tmp_ctx);
1061 0 : return NT_STATUS_NOT_IMPLEMENTED;
1062 : }
1063 :
1064 : /*
1065 : * Let's use the NT4 account name for the lookup.
1066 : */
1067 7895 : account_name = nt4_account;
1068 : }
1069 :
1070 27778 : nt_status = authsam_search_account(tmp_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg);
1071 27778 : if (!NT_STATUS_IS_OK(nt_status)) {
1072 723 : talloc_free(tmp_ctx);
1073 723 : return nt_status;
1074 : }
1075 :
1076 27055 : nt_status = authsam_make_user_info_dc(tmp_ctx, ctx->auth_ctx->sam_ctx,
1077 27055 : lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
1078 27055 : lpcfg_sam_name(ctx->auth_ctx->lp_ctx),
1079 27055 : lpcfg_sam_dnsname(ctx->auth_ctx->lp_ctx),
1080 : domain_dn,
1081 : msg,
1082 : data_blob_null, data_blob_null,
1083 : user_info_dc);
1084 27055 : if (!NT_STATUS_IS_OK(nt_status)) {
1085 0 : talloc_free(tmp_ctx);
1086 0 : return nt_status;
1087 : }
1088 :
1089 28459 : result = dsdb_is_protected_user(ctx->auth_ctx->sam_ctx,
1090 27055 : (*user_info_dc)->sids,
1091 27055 : (*user_info_dc)->num_sids);
1092 : /*
1093 : * We also consider an error result (a negative value) as denying the
1094 : * authentication.
1095 : */
1096 27055 : if (result != 0) {
1097 17 : talloc_free(tmp_ctx);
1098 17 : return NT_STATUS_ACCOUNT_RESTRICTION;
1099 : }
1100 :
1101 27038 : nt_status = authsam_authenticate(ctx->auth_ctx,
1102 : tmp_ctx,
1103 : domain_dn,
1104 : msg,
1105 : user_info,
1106 : *user_info_dc,
1107 : &user_sess_key,
1108 : &lm_sess_key,
1109 : &client_audit_info,
1110 : &server_audit_info,
1111 : authoritative);
1112 27038 : if (client_audit_info != NULL) {
1113 100 : *client_audit_info_out = talloc_move(mem_ctx, &client_audit_info);
1114 : }
1115 27038 : if (server_audit_info != NULL) {
1116 80 : *server_audit_info_out = talloc_move(mem_ctx, &server_audit_info);
1117 : }
1118 27038 : if (!NT_STATUS_IS_OK(nt_status)) {
1119 4107 : talloc_free(tmp_ctx);
1120 4107 : return nt_status;
1121 : }
1122 :
1123 22931 : (*user_info_dc)->user_session_key = data_blob_talloc(*user_info_dc,
1124 : user_sess_key.data,
1125 : user_sess_key.length);
1126 22931 : if (user_sess_key.data) {
1127 21623 : if ((*user_info_dc)->user_session_key.data == NULL) {
1128 0 : TALLOC_FREE(tmp_ctx);
1129 0 : return NT_STATUS_NO_MEMORY;
1130 : }
1131 : }
1132 :
1133 22931 : (*user_info_dc)->lm_session_key = data_blob_talloc(*user_info_dc,
1134 : lm_sess_key.data,
1135 : lm_sess_key.length);
1136 22931 : if (lm_sess_key.data) {
1137 20158 : if ((*user_info_dc)->lm_session_key.data == NULL) {
1138 0 : TALLOC_FREE(tmp_ctx);
1139 0 : return NT_STATUS_NO_MEMORY;
1140 : }
1141 : }
1142 :
1143 : /*
1144 : * Release our handle to *user_info_dc. {client,server}_audit_info_out,
1145 : * if non-NULL, becomes the new parent.
1146 : */
1147 22931 : reparented = talloc_reparent(tmp_ctx, mem_ctx, *user_info_dc);
1148 22931 : if (reparented == NULL) {
1149 0 : talloc_free(tmp_ctx);
1150 0 : return NT_STATUS_INTERNAL_ERROR;
1151 : }
1152 :
1153 22931 : talloc_free(tmp_ctx);
1154 :
1155 22931 : return NT_STATUS_OK;
1156 : }
1157 :
1158 : struct authsam_check_password_state {
1159 : struct auth_user_info_dc *user_info_dc;
1160 : struct authn_audit_info *client_audit_info;
1161 : struct authn_audit_info *server_audit_info;
1162 : bool authoritative;
1163 : };
1164 :
1165 27778 : static struct tevent_req *authsam_check_password_send(
1166 : TALLOC_CTX *mem_ctx,
1167 : struct tevent_context *ev,
1168 : struct auth_method_context *ctx,
1169 : const struct auth_usersupplied_info *user_info)
1170 : {
1171 27778 : struct tevent_req *req = NULL;
1172 27778 : struct authsam_check_password_state *state = NULL;
1173 1410 : NTSTATUS status;
1174 :
1175 27778 : req = tevent_req_create(
1176 : mem_ctx, &state, struct authsam_check_password_state);
1177 27778 : if (req == NULL) {
1178 0 : return NULL;
1179 : }
1180 : /*
1181 : * authsam_check_password_internals() sets this to false in
1182 : * the rodc case, otherwise it leaves it untouched. Default to
1183 : * "we're authoritative".
1184 : */
1185 27778 : state->authoritative = true;
1186 :
1187 27778 : status = authsam_check_password_internals(
1188 : ctx,
1189 : state,
1190 : user_info,
1191 26368 : &state->user_info_dc,
1192 26368 : &state->client_audit_info,
1193 26368 : &state->server_audit_info,
1194 26368 : &state->authoritative);
1195 27778 : if (tevent_req_nterror(req, status)) {
1196 4847 : return tevent_req_post(req, ev);
1197 : }
1198 :
1199 22931 : tevent_req_done(req);
1200 22931 : return tevent_req_post(req, ev);
1201 : }
1202 :
1203 27778 : static NTSTATUS authsam_check_password_recv(
1204 : struct tevent_req *req,
1205 : TALLOC_CTX *mem_ctx,
1206 : struct auth_user_info_dc **interim_info,
1207 : const struct authn_audit_info **client_audit_info,
1208 : const struct authn_audit_info **server_audit_info,
1209 : bool *authoritative)
1210 : {
1211 27778 : struct authsam_check_password_state *state = tevent_req_data(
1212 : req, struct authsam_check_password_state);
1213 1410 : NTSTATUS status;
1214 :
1215 27778 : *authoritative = state->authoritative;
1216 :
1217 27778 : *client_audit_info = talloc_reparent(state, mem_ctx, state->client_audit_info);
1218 27778 : state->client_audit_info = NULL;
1219 :
1220 27778 : *server_audit_info = talloc_reparent(state, mem_ctx, state->server_audit_info);
1221 27778 : state->server_audit_info = NULL;
1222 :
1223 27778 : if (tevent_req_is_nterror(req, &status)) {
1224 4847 : tevent_req_received(req);
1225 4847 : return status;
1226 : }
1227 : /*
1228 : * Release our handle to state->user_info_dc.
1229 : * {client,server}_audit_info, if non-NULL, becomes the new parent.
1230 : */
1231 22931 : *interim_info = talloc_reparent(state, mem_ctx, state->user_info_dc);
1232 22931 : state->user_info_dc = NULL;
1233 :
1234 22931 : tevent_req_received(req);
1235 22931 : return NT_STATUS_OK;
1236 : }
1237 :
1238 703 : static NTSTATUS authsam_ignoredomain_want_check(struct auth_method_context *ctx,
1239 : TALLOC_CTX *mem_ctx,
1240 : const struct auth_usersupplied_info *user_info)
1241 : {
1242 703 : if (!user_info->mapped.account_name || !*user_info->mapped.account_name) {
1243 12 : return NT_STATUS_NOT_IMPLEMENTED;
1244 : }
1245 :
1246 691 : return NT_STATUS_OK;
1247 : }
1248 :
1249 : /****************************************************************************
1250 : Check SAM security (above) but with a few extra checks.
1251 : ****************************************************************************/
1252 28047 : static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
1253 : TALLOC_CTX *mem_ctx,
1254 : const struct auth_usersupplied_info *user_info)
1255 : {
1256 28047 : const char *effective_domain = user_info->mapped.domain_name;
1257 28047 : bool is_local_name = false;
1258 28047 : bool is_my_domain = false;
1259 28047 : const char *p = NULL;
1260 28047 : struct dsdb_trust_routing_table *trt = NULL;
1261 28047 : const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
1262 1410 : NTSTATUS status;
1263 :
1264 28047 : if (!user_info->mapped.account_name || !*user_info->mapped.account_name) {
1265 14 : return NT_STATUS_NOT_IMPLEMENTED;
1266 : }
1267 :
1268 28033 : if (effective_domain == NULL) {
1269 1644 : effective_domain = "";
1270 : }
1271 :
1272 28033 : is_local_name = lpcfg_is_myname(ctx->auth_ctx->lp_ctx,
1273 : effective_domain);
1274 :
1275 : /* check whether or not we service this domain/workgroup name */
1276 28033 : switch (lpcfg_server_role(ctx->auth_ctx->lp_ctx)) {
1277 0 : case ROLE_STANDALONE:
1278 103 : return NT_STATUS_OK;
1279 :
1280 103 : case ROLE_DOMAIN_MEMBER:
1281 103 : if (is_local_name) {
1282 98 : return NT_STATUS_OK;
1283 : }
1284 :
1285 5 : DBG_DEBUG("%s is not one of my local names (DOMAIN_MEMBER)\n",
1286 : effective_domain);
1287 5 : return NT_STATUS_NOT_IMPLEMENTED;
1288 :
1289 26520 : case ROLE_ACTIVE_DIRECTORY_DC:
1290 : /* handled later */
1291 27930 : break;
1292 :
1293 0 : default:
1294 0 : DBG_ERR("lpcfg_server_role() has an undefined value\n");
1295 0 : return NT_STATUS_INVALID_SERVER_STATE;
1296 : }
1297 :
1298 : /*
1299 : * Now we handle the AD DC case...
1300 : */
1301 :
1302 27930 : is_my_domain = lpcfg_is_my_domain_or_realm(ctx->auth_ctx->lp_ctx,
1303 : effective_domain);
1304 27930 : if (is_my_domain) {
1305 19161 : return NT_STATUS_OK;
1306 : }
1307 :
1308 8769 : if (user_info->cracknames_called) {
1309 : /*
1310 : * The caller already did a cracknames call.
1311 : */
1312 0 : DBG_DEBUG("%s is not own domain name (DC)\n",
1313 : effective_domain);
1314 0 : return NT_STATUS_NOT_IMPLEMENTED;
1315 : }
1316 :
1317 8769 : if (!strequal(effective_domain, "")) {
1318 908 : DBG_DEBUG("%s is not own domain name (DC)\n",
1319 : effective_domain);
1320 908 : return NT_STATUS_NOT_IMPLEMENTED;
1321 : }
1322 :
1323 7861 : p = strchr_m(user_info->mapped.account_name, '@');
1324 7861 : if (p == NULL) {
1325 : /*
1326 : * An empty to domain name should be handled
1327 : * as the local domain name.
1328 : */
1329 5 : return NT_STATUS_OK;
1330 : }
1331 :
1332 7856 : effective_domain = p + 1;
1333 7856 : is_my_domain = lpcfg_is_my_domain_or_realm(ctx->auth_ctx->lp_ctx,
1334 : effective_domain);
1335 7856 : if (is_my_domain) {
1336 7823 : return NT_STATUS_OK;
1337 : }
1338 :
1339 33 : if (strequal(effective_domain, "")) {
1340 2 : DBG_DEBUG("authsam_check_password: upn without realm (DC)\n");
1341 2 : return NT_STATUS_NOT_IMPLEMENTED;
1342 : }
1343 :
1344 : /*
1345 : * as last option we check the routing table if the
1346 : * domain is within our forest.
1347 : */
1348 31 : status = dsdb_trust_routing_table_load(ctx->auth_ctx->sam_ctx,
1349 : mem_ctx, &trt);
1350 31 : if (!NT_STATUS_IS_OK(status)) {
1351 0 : DBG_ERR("authsam_check_password: dsdb_trust_routing_table_load() %s\n",
1352 : nt_errstr(status));
1353 0 : return status;
1354 : }
1355 :
1356 31 : tdo = dsdb_trust_routing_by_name(trt, effective_domain);
1357 31 : if (tdo == NULL) {
1358 18 : DBG_DEBUG("%s is not a known TLN (DC)\n",
1359 : effective_domain);
1360 18 : TALLOC_FREE(trt);
1361 18 : return NT_STATUS_NOT_IMPLEMENTED;
1362 : }
1363 :
1364 13 : if (!(tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
1365 13 : DBG_DEBUG("%s is not a TLN in our forest (DC)\n",
1366 : effective_domain);
1367 13 : TALLOC_FREE(trt);
1368 13 : return NT_STATUS_NOT_IMPLEMENTED;
1369 : }
1370 :
1371 : /*
1372 : * This principal is within our forest.
1373 : * we'll later do a crack_name_to_nt4_name()
1374 : * to check if it's in our domain.
1375 : */
1376 0 : TALLOC_FREE(trt);
1377 0 : return NT_STATUS_OK;
1378 : }
1379 :
1380 : static const struct auth_operations sam_ignoredomain_ops = {
1381 : .name = "sam_ignoredomain",
1382 : .want_check = authsam_ignoredomain_want_check,
1383 : .check_password_send = authsam_check_password_send,
1384 : .check_password_recv = authsam_check_password_recv,
1385 : };
1386 :
1387 : static const struct auth_operations sam_ops = {
1388 : .name = "sam",
1389 : .want_check = authsam_want_check,
1390 : .check_password_send = authsam_check_password_send,
1391 : .check_password_recv = authsam_check_password_recv,
1392 : };
1393 :
1394 : _PUBLIC_ NTSTATUS auth4_sam_init(TALLOC_CTX *);
1395 9620 : _PUBLIC_ NTSTATUS auth4_sam_init(TALLOC_CTX *ctx)
1396 : {
1397 837 : NTSTATUS ret;
1398 :
1399 9620 : ret = auth_register(ctx, &sam_ops);
1400 9620 : if (!NT_STATUS_IS_OK(ret)) {
1401 0 : DEBUG(0,("Failed to register 'sam' auth backend!\n"));
1402 0 : return ret;
1403 : }
1404 :
1405 9620 : ret = auth_register(ctx, &sam_ignoredomain_ops);
1406 9620 : if (!NT_STATUS_IS_OK(ret)) {
1407 0 : DEBUG(0,("Failed to register 'sam_ignoredomain' auth backend!\n"));
1408 0 : return ret;
1409 : }
1410 :
1411 9620 : return ret;
1412 : }
|