Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Copyright (C) Andrew Tridgell 1992-2001
4 : Copyright (C) Andrew Bartlett 2002
5 : Copyright (C) Rafal Szczesniak 2002
6 : Copyright (C) Tim Potter 2001
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 : /* the Samba secrets database stores any generated, private information
23 : such as the local SID and machine trust password */
24 :
25 : #include "includes.h"
26 : #include "passdb.h"
27 : #include "../libcli/auth/libcli_auth.h"
28 : #include "secrets.h"
29 : #include "dbwrap/dbwrap.h"
30 : #include "../librpc/ndr/libndr.h"
31 : #include "util_tdb.h"
32 : #include "libcli/security/security.h"
33 :
34 : #include "librpc/gen_ndr/libnet_join.h"
35 : #include "librpc/gen_ndr/ndr_secrets.h"
36 : #include "lib/crypto/crypto.h"
37 : #include "lib/krb5_wrap/krb5_samba.h"
38 : #include "lib/util/time_basic.h"
39 : #include "../libds/common/flags.h"
40 : #include "lib/util/string_wrappers.h"
41 :
42 : #undef DBGC_CLASS
43 : #define DBGC_CLASS DBGC_PASSDB
44 :
45 : static char *domain_info_keystr(const char *domain);
46 :
47 : static char *des_salt_key(const char *realm);
48 :
49 : /**
50 : * Form a key for fetching the domain sid
51 : *
52 : * @param domain domain name
53 : *
54 : * @return keystring
55 : **/
56 36255 : static const char *domain_sid_keystr(const char *domain)
57 : {
58 967 : char *keystr;
59 :
60 36255 : keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
61 : SECRETS_DOMAIN_SID, domain);
62 36255 : SMB_ASSERT(keystr != NULL);
63 36255 : return keystr;
64 : }
65 :
66 10421 : static const char *domain_guid_keystr(const char *domain)
67 : {
68 871 : char *keystr;
69 :
70 10421 : keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
71 : SECRETS_DOMAIN_GUID, domain);
72 10421 : SMB_ASSERT(keystr != NULL);
73 10421 : return keystr;
74 : }
75 :
76 1367 : static const char *protect_ids_keystr(const char *domain)
77 : {
78 108 : char *keystr;
79 :
80 1367 : keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
81 : SECRETS_PROTECT_IDS, domain);
82 1367 : SMB_ASSERT(keystr != NULL);
83 1367 : return keystr;
84 : }
85 :
86 : /* N O T E: never use this outside of passdb modules that store the SID on their own */
87 246 : bool secrets_mark_domain_protected(const char *domain)
88 : {
89 19 : bool ret;
90 :
91 246 : ret = secrets_store(protect_ids_keystr(domain), "TRUE", 5);
92 246 : if (!ret) {
93 0 : DEBUG(0, ("Failed to protect the Domain IDs\n"));
94 : }
95 246 : return ret;
96 : }
97 :
98 246 : bool secrets_clear_domain_protection(const char *domain)
99 : {
100 19 : bool ret;
101 246 : void *protection = secrets_fetch(protect_ids_keystr(domain), NULL);
102 :
103 246 : if (protection) {
104 116 : SAFE_FREE(protection);
105 116 : ret = secrets_delete_entry(protect_ids_keystr(domain));
106 116 : if (!ret) {
107 0 : DEBUG(0, ("Failed to remove Domain IDs protection\n"));
108 : }
109 116 : return ret;
110 : }
111 120 : return true;
112 : }
113 :
114 599 : bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
115 : {
116 50 : char *protect_ids;
117 50 : bool ret;
118 599 : struct dom_sid clean_sid = { 0 };
119 :
120 599 : protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
121 599 : if (protect_ids) {
122 85 : if (strncmp(protect_ids, "TRUE", 4)) {
123 0 : DEBUG(0, ("Refusing to store a Domain SID, "
124 : "it has been marked as protected!\n"));
125 0 : SAFE_FREE(protect_ids);
126 0 : return false;
127 : }
128 : }
129 599 : SAFE_FREE(protect_ids);
130 :
131 : /*
132 : * use a copy to prevent uninitialized memory from being carried over
133 : * to the tdb
134 : */
135 599 : sid_copy(&clean_sid, sid);
136 :
137 599 : ret = secrets_store(domain_sid_keystr(domain),
138 : &clean_sid,
139 : sizeof(struct dom_sid));
140 :
141 : /* Force a re-query, in the case where we modified our domain */
142 599 : if (ret) {
143 599 : if (dom_sid_equal(get_global_sam_sid(), sid) == false) {
144 269 : reset_global_sam_sid();
145 : }
146 : }
147 549 : return ret;
148 : }
149 :
150 35522 : bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
151 : {
152 917 : struct dom_sid *dyn_sid;
153 35522 : size_t size = 0;
154 :
155 35522 : dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
156 :
157 35522 : if (dyn_sid == NULL)
158 11313 : return False;
159 :
160 24183 : if (size != sizeof(struct dom_sid)) {
161 0 : SAFE_FREE(dyn_sid);
162 0 : return False;
163 : }
164 :
165 24183 : *sid = *dyn_sid;
166 24183 : SAFE_FREE(dyn_sid);
167 24183 : return True;
168 : }
169 :
170 160 : bool secrets_store_domain_guid(const char *domain, const struct GUID *guid)
171 : {
172 11 : char *protect_ids;
173 11 : const char *key;
174 :
175 160 : protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
176 160 : if (protect_ids) {
177 0 : if (strncmp(protect_ids, "TRUE", 4)) {
178 0 : DEBUG(0, ("Refusing to store a Domain SID, "
179 : "it has been marked as protected!\n"));
180 0 : SAFE_FREE(protect_ids);
181 0 : return false;
182 : }
183 : }
184 160 : SAFE_FREE(protect_ids);
185 :
186 160 : key = domain_guid_keystr(domain);
187 160 : return secrets_store(key, guid, sizeof(struct GUID));
188 : }
189 :
190 10127 : bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
191 : {
192 860 : struct GUID *dyn_guid;
193 860 : const char *key;
194 10127 : size_t size = 0;
195 860 : struct GUID new_guid;
196 :
197 10127 : key = domain_guid_keystr(domain);
198 10127 : dyn_guid = (struct GUID *)secrets_fetch(key, &size);
199 :
200 10127 : if (!dyn_guid) {
201 194 : if (lp_server_role() == ROLE_DOMAIN_PDC ||
202 97 : lp_server_role() == ROLE_IPA_DC) {
203 0 : new_guid = GUID_random();
204 0 : if (!secrets_store_domain_guid(domain, &new_guid))
205 0 : return False;
206 0 : dyn_guid = (struct GUID *)secrets_fetch(key, &size);
207 : }
208 97 : if (dyn_guid == NULL) {
209 87 : return False;
210 : }
211 : }
212 :
213 10030 : if (size != sizeof(struct GUID)) {
214 0 : DEBUG(1,("UUID size %d is wrong!\n", (int)size));
215 0 : SAFE_FREE(dyn_guid);
216 0 : return False;
217 : }
218 :
219 10030 : *guid = *dyn_guid;
220 10030 : SAFE_FREE(dyn_guid);
221 10030 : return True;
222 : }
223 :
224 : /**
225 : * Form a key for fetching the machine trust account sec channel type
226 : *
227 : * @param domain domain name
228 : *
229 : * @return keystring
230 : **/
231 485 : static const char *machine_sec_channel_type_keystr(const char *domain)
232 : {
233 25 : char *keystr;
234 :
235 485 : keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
236 : SECRETS_MACHINE_SEC_CHANNEL_TYPE,
237 : domain);
238 485 : SMB_ASSERT(keystr != NULL);
239 485 : return keystr;
240 : }
241 :
242 : /**
243 : * Form a key for fetching the machine trust account last change time
244 : *
245 : * @param domain domain name
246 : *
247 : * @return keystring
248 : **/
249 4975 : static const char *machine_last_change_time_keystr(const char *domain)
250 : {
251 25 : char *keystr;
252 :
253 4975 : keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
254 : SECRETS_MACHINE_LAST_CHANGE_TIME,
255 : domain);
256 4975 : SMB_ASSERT(keystr != NULL);
257 4975 : return keystr;
258 : }
259 :
260 :
261 : /**
262 : * Form a key for fetching the machine previous trust account password
263 : *
264 : * @param domain domain name
265 : *
266 : * @return keystring
267 : **/
268 485 : static const char *machine_prev_password_keystr(const char *domain)
269 : {
270 25 : char *keystr;
271 :
272 485 : keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
273 : SECRETS_MACHINE_PASSWORD_PREV, domain);
274 485 : SMB_ASSERT(keystr != NULL);
275 485 : return keystr;
276 : }
277 :
278 : /**
279 : * Form a key for fetching the machine trust account password
280 : *
281 : * @param domain domain name
282 : *
283 : * @return keystring
284 : **/
285 641 : static const char *machine_password_keystr(const char *domain)
286 : {
287 25 : char *keystr;
288 :
289 641 : keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
290 : SECRETS_MACHINE_PASSWORD, domain);
291 641 : SMB_ASSERT(keystr != NULL);
292 641 : return keystr;
293 : }
294 :
295 : /**
296 : * Form a key for fetching the machine trust account password
297 : *
298 : * @param domain domain name
299 : *
300 : * @return stored password's key
301 : **/
302 0 : static const char *trust_keystr(const char *domain)
303 : {
304 0 : char *keystr;
305 :
306 0 : keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
307 : SECRETS_MACHINE_ACCT_PASS, domain);
308 0 : SMB_ASSERT(keystr != NULL);
309 0 : return keystr;
310 : }
311 :
312 : /************************************************************************
313 : Routine to get the default secure channel type for trust accounts
314 : ************************************************************************/
315 :
316 16 : enum netr_SchannelType get_default_sec_channel(void)
317 : {
318 16 : if (IS_DC) {
319 8 : return SEC_CHAN_BDC;
320 : } else {
321 8 : return SEC_CHAN_WKSTA;
322 : }
323 : }
324 :
325 : /************************************************************************
326 : Routine to get the trust account password for a domain.
327 : This only tries to get the legacy hashed version of the password.
328 : The user of this function must have locked the trust password file using
329 : the above secrets_lock_trust_account_password().
330 : ************************************************************************/
331 :
332 0 : bool secrets_fetch_trust_account_password_legacy(const char *domain,
333 : uint8_t ret_pwd[16],
334 : time_t *pass_last_set_time,
335 : enum netr_SchannelType *channel)
336 : {
337 0 : struct machine_acct_pass *pass;
338 0 : size_t size = 0;
339 :
340 0 : if (!(pass = (struct machine_acct_pass *)secrets_fetch(
341 : trust_keystr(domain), &size))) {
342 0 : DEBUG(5, ("secrets_fetch failed!\n"));
343 0 : return False;
344 : }
345 :
346 0 : if (size != sizeof(*pass)) {
347 0 : DEBUG(0, ("secrets were of incorrect size!\n"));
348 0 : BURN_FREE(pass, size);
349 0 : return False;
350 : }
351 :
352 0 : if (pass_last_set_time) {
353 0 : *pass_last_set_time = pass->mod_time;
354 : }
355 0 : memcpy(ret_pwd, pass->hash, 16);
356 :
357 0 : if (channel) {
358 0 : *channel = get_default_sec_channel();
359 : }
360 :
361 0 : BURN_FREE(pass, size);
362 0 : return True;
363 : }
364 :
365 : /************************************************************************
366 : Routine to delete all information related to the domain joined machine.
367 : ************************************************************************/
368 :
369 134 : bool secrets_delete_machine_password_ex(const char *domain, const char *realm)
370 : {
371 134 : const char *tmpkey = NULL;
372 0 : bool ok;
373 :
374 134 : tmpkey = domain_info_keystr(domain);
375 134 : ok = secrets_delete(tmpkey);
376 134 : if (!ok) {
377 0 : return false;
378 : }
379 :
380 134 : if (realm != NULL) {
381 113 : tmpkey = des_salt_key(domain);
382 113 : ok = secrets_delete(tmpkey);
383 113 : if (!ok) {
384 0 : return false;
385 : }
386 : }
387 :
388 134 : tmpkey = domain_guid_keystr(domain);
389 134 : ok = secrets_delete(tmpkey);
390 134 : if (!ok) {
391 0 : return false;
392 : }
393 :
394 134 : tmpkey = machine_prev_password_keystr(domain);
395 134 : ok = secrets_delete(tmpkey);
396 134 : if (!ok) {
397 0 : return false;
398 : }
399 :
400 134 : tmpkey = machine_password_keystr(domain);
401 134 : ok = secrets_delete(tmpkey);
402 134 : if (!ok) {
403 0 : return false;
404 : }
405 :
406 134 : tmpkey = machine_sec_channel_type_keystr(domain);
407 134 : ok = secrets_delete(tmpkey);
408 134 : if (!ok) {
409 0 : return false;
410 : }
411 :
412 134 : tmpkey = machine_last_change_time_keystr(domain);
413 134 : ok = secrets_delete(tmpkey);
414 134 : if (!ok) {
415 0 : return false;
416 : }
417 :
418 134 : tmpkey = domain_sid_keystr(domain);
419 134 : ok = secrets_delete(tmpkey);
420 134 : if (!ok) {
421 0 : return false;
422 : }
423 :
424 134 : return true;
425 : }
426 :
427 : /************************************************************************
428 : Routine to delete the domain sid
429 : ************************************************************************/
430 :
431 0 : bool secrets_delete_domain_sid(const char *domain)
432 : {
433 0 : return secrets_delete_entry(domain_sid_keystr(domain));
434 : }
435 :
436 : /************************************************************************
437 : Set the machine trust account password, the old pw and last change
438 : time, domain SID and salting principals based on values passed in
439 : (added to support the secrets_tdb_sync module on secrets.ldb)
440 : ************************************************************************/
441 :
442 342 : bool secrets_store_machine_pw_sync(const char *pass, const char *oldpass, const char *domain,
443 : const char *realm,
444 : const char *salting_principal, uint32_t supported_enc_types,
445 : const struct dom_sid *domain_sid, uint32_t last_change_time,
446 : uint32_t secure_channel_type,
447 : bool delete_join)
448 : {
449 25 : bool ret;
450 25 : uint8_t last_change_time_store[4];
451 342 : TALLOC_CTX *frame = talloc_stackframe();
452 25 : uint8_t sec_channel_bytes[4];
453 :
454 342 : if (delete_join) {
455 0 : secrets_delete_machine_password_ex(domain, realm);
456 0 : TALLOC_FREE(frame);
457 0 : return true;
458 : }
459 :
460 342 : ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
461 342 : if (!ret) {
462 0 : TALLOC_FREE(frame);
463 0 : return ret;
464 : }
465 :
466 342 : if (oldpass) {
467 70 : ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
468 : } else {
469 272 : ret = secrets_delete(machine_prev_password_keystr(domain));
470 : }
471 342 : if (!ret) {
472 0 : TALLOC_FREE(frame);
473 0 : return ret;
474 : }
475 :
476 342 : if (secure_channel_type == 0) {
477 : /* We delete this and instead have the read code fall back to
478 : * a default based on server role, as our caller can't specify
479 : * this with any more certainty */
480 0 : ret = secrets_delete(machine_sec_channel_type_keystr(domain));
481 0 : if (!ret) {
482 0 : TALLOC_FREE(frame);
483 0 : return ret;
484 : }
485 : } else {
486 342 : SIVAL(&sec_channel_bytes, 0, secure_channel_type);
487 342 : ret = secrets_store(machine_sec_channel_type_keystr(domain),
488 : &sec_channel_bytes, sizeof(sec_channel_bytes));
489 342 : if (!ret) {
490 0 : TALLOC_FREE(frame);
491 0 : return ret;
492 : }
493 : }
494 :
495 342 : SIVAL(&last_change_time_store, 0, last_change_time);
496 342 : ret = secrets_store(machine_last_change_time_keystr(domain),
497 : &last_change_time_store, sizeof(last_change_time));
498 :
499 342 : if (!ret) {
500 0 : TALLOC_FREE(frame);
501 0 : return ret;
502 : }
503 :
504 342 : ret = secrets_store_domain_sid(domain, domain_sid);
505 :
506 342 : if (!ret) {
507 0 : TALLOC_FREE(frame);
508 0 : return ret;
509 : }
510 :
511 342 : if (realm != NULL) {
512 321 : char *key = des_salt_key(realm);
513 :
514 321 : if (salting_principal != NULL) {
515 321 : ret = secrets_store(key,
516 : salting_principal,
517 321 : strlen(salting_principal)+1);
518 : } else {
519 0 : ret = secrets_delete(key);
520 : }
521 : }
522 :
523 342 : TALLOC_FREE(frame);
524 317 : return ret;
525 : }
526 :
527 : /************************************************************************
528 : Return the standard DES salt key
529 : ************************************************************************/
530 :
531 60 : char* kerberos_standard_des_salt( void )
532 : {
533 0 : fstring salt;
534 :
535 60 : fstr_sprintf( salt, "host/%s.%s@", lp_netbios_name(), lp_realm() );
536 60 : (void)strlower_m( salt );
537 60 : fstrcat( salt, lp_realm() );
538 :
539 60 : return SMB_STRDUP( salt );
540 : }
541 :
542 : /************************************************************************
543 : ************************************************************************/
544 :
545 509 : static char *des_salt_key(const char *realm)
546 : {
547 25 : char *keystr;
548 :
549 509 : keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/DES/%s",
550 : SECRETS_SALTING_PRINCIPAL,
551 : realm);
552 509 : SMB_ASSERT(keystr != NULL);
553 509 : return keystr;
554 : }
555 :
556 : /************************************************************************
557 : ************************************************************************/
558 :
559 0 : bool kerberos_secrets_store_des_salt( const char* salt )
560 : {
561 0 : char* key;
562 0 : bool ret;
563 :
564 0 : key = des_salt_key(lp_realm());
565 0 : if (key == NULL) {
566 0 : DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n"));
567 0 : return False;
568 : }
569 :
570 0 : if ( !salt ) {
571 0 : DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n"));
572 0 : secrets_delete_entry( key );
573 0 : return True;
574 : }
575 :
576 0 : DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt));
577 :
578 0 : ret = secrets_store( key, salt, strlen(salt)+1 );
579 :
580 0 : TALLOC_FREE(key);
581 :
582 0 : return ret;
583 : }
584 :
585 : /************************************************************************
586 : ************************************************************************/
587 :
588 : static
589 75 : char* kerberos_secrets_fetch_des_salt( void )
590 : {
591 0 : char *salt, *key;
592 :
593 75 : key = des_salt_key(lp_realm());
594 75 : if (key == NULL) {
595 0 : DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
596 0 : return NULL;
597 : }
598 :
599 75 : salt = (char*)secrets_fetch( key, NULL );
600 :
601 75 : TALLOC_FREE(key);
602 :
603 75 : return salt;
604 : }
605 :
606 : /************************************************************************
607 : Routine to get the salting principal for this service.
608 : Caller must free if return is not null.
609 : ************************************************************************/
610 :
611 75 : char *kerberos_secrets_fetch_salt_princ(void)
612 : {
613 0 : char *salt_princ_s;
614 : /* lookup new key first */
615 :
616 75 : salt_princ_s = kerberos_secrets_fetch_des_salt();
617 75 : if (salt_princ_s == NULL) {
618 : /* fall back to host/machine.realm@REALM */
619 0 : salt_princ_s = kerberos_standard_des_salt();
620 : }
621 :
622 75 : return salt_princ_s;
623 : }
624 :
625 : /************************************************************************
626 : Routine to fetch the previous plaintext machine account password for a realm
627 : the password is assumed to be a null terminated ascii string.
628 : ************************************************************************/
629 :
630 9 : char *secrets_fetch_prev_machine_password(const char *domain)
631 : {
632 9 : return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
633 : }
634 :
635 : /************************************************************************
636 : Routine to fetch the last change time of the machine account password
637 : for a realm
638 : ************************************************************************/
639 :
640 4499 : time_t secrets_fetch_pass_last_set_time(const char *domain)
641 : {
642 0 : uint32_t *last_set_time;
643 0 : time_t pass_last_set_time;
644 :
645 4499 : last_set_time = secrets_fetch(machine_last_change_time_keystr(domain),
646 : NULL);
647 4499 : if (last_set_time) {
648 4426 : pass_last_set_time = IVAL(last_set_time,0);
649 4426 : SAFE_FREE(last_set_time);
650 : } else {
651 73 : pass_last_set_time = 0;
652 : }
653 :
654 4499 : return pass_last_set_time;
655 : }
656 :
657 : /************************************************************************
658 : Routine to fetch the plaintext machine account password for a realm
659 : the password is assumed to be a null terminated ascii string.
660 : ************************************************************************/
661 :
662 165 : char *secrets_fetch_machine_password(const char *domain,
663 : time_t *pass_last_set_time,
664 : enum netr_SchannelType *channel)
665 : {
666 0 : char *ret;
667 165 : ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
668 :
669 165 : if (pass_last_set_time) {
670 9 : *pass_last_set_time = secrets_fetch_pass_last_set_time(domain);
671 : }
672 :
673 165 : if (channel) {
674 0 : size_t size;
675 0 : uint32_t *channel_type;
676 9 : channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
677 9 : if (channel_type) {
678 9 : *channel = IVAL(channel_type,0);
679 9 : SAFE_FREE(channel_type);
680 : } else {
681 0 : *channel = get_default_sec_channel();
682 : }
683 : }
684 :
685 165 : return ret;
686 : }
687 :
688 9478 : static int password_nt_hash_destructor(struct secrets_domain_info1_password *pw)
689 : {
690 9478 : ZERO_STRUCT(pw->nt_hash);
691 :
692 9478 : return 0;
693 : }
694 :
695 13283 : static int setup_password_zeroing(struct secrets_domain_info1_password *pw)
696 : {
697 13283 : if (pw != NULL) {
698 0 : size_t i;
699 :
700 9379 : talloc_keep_secret(pw->cleartext_blob.data);
701 9379 : talloc_set_destructor(pw, password_nt_hash_destructor);
702 37450 : for (i = 0; i < pw->num_keys; i++) {
703 28071 : talloc_keep_secret(pw->keys[i].value.data);
704 : }
705 : }
706 :
707 13283 : return 0;
708 : }
709 :
710 4668 : static char *domain_info_keystr(const char *domain)
711 : {
712 0 : char *keystr;
713 :
714 4668 : keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
715 : SECRETS_MACHINE_DOMAIN_INFO,
716 : domain);
717 4668 : SMB_ASSERT(keystr != NULL);
718 4668 : return keystr;
719 : }
720 :
721 : /************************************************************************
722 : Routine to get account password to trusted domain
723 : ************************************************************************/
724 :
725 4430 : static NTSTATUS secrets_fetch_domain_info1_by_key(const char *key,
726 : TALLOC_CTX *mem_ctx,
727 : struct secrets_domain_info1 **_info1)
728 : {
729 4430 : struct secrets_domain_infoB sdib = { .version = 0, };
730 0 : enum ndr_err_code ndr_err;
731 : /* unpacking structures */
732 0 : DATA_BLOB blob;
733 :
734 : /* fetching trusted domain password structure */
735 4430 : blob.data = (uint8_t *)secrets_fetch(key, &blob.length);
736 4430 : if (blob.data == NULL) {
737 9 : DBG_NOTICE("secrets_fetch failed!\n");
738 9 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
739 : }
740 :
741 : /* unpack trusted domain password */
742 4421 : ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sdib,
743 : (ndr_pull_flags_fn_t)ndr_pull_secrets_domain_infoB);
744 4421 : BURN_FREE(blob.data, blob.length);
745 4421 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
746 0 : DBG_ERR("ndr_pull_struct_blob failed - %s!\n",
747 : ndr_errstr(ndr_err));
748 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
749 : }
750 :
751 4421 : if (sdib.info.info1->next_change != NULL) {
752 20 : setup_password_zeroing(sdib.info.info1->next_change->password);
753 : }
754 4421 : setup_password_zeroing(sdib.info.info1->password);
755 4421 : setup_password_zeroing(sdib.info.info1->old_password);
756 4421 : setup_password_zeroing(sdib.info.info1->older_password);
757 :
758 4421 : if (sdib.version != SECRETS_DOMAIN_INFO_VERSION_1) {
759 0 : DBG_ERR("sdib.version = %u\n", (unsigned)sdib.version);
760 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
761 : }
762 :
763 4421 : *_info1 = sdib.info.info1;
764 4421 : return NT_STATUS_OK;;
765 : }
766 :
767 4430 : static NTSTATUS secrets_fetch_domain_info(const char *domain,
768 : TALLOC_CTX *mem_ctx,
769 : struct secrets_domain_info1 **pinfo)
770 : {
771 4430 : char *key = domain_info_keystr(domain);
772 4430 : return secrets_fetch_domain_info1_by_key(key, mem_ctx, pinfo);
773 : }
774 :
775 104 : void secrets_debug_domain_info(int lvl, const struct secrets_domain_info1 *info1,
776 : const char *name)
777 : {
778 104 : struct secrets_domain_infoB sdib = {
779 : .version = SECRETS_DOMAIN_INFO_VERSION_1,
780 : };
781 :
782 104 : sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
783 :
784 104 : NDR_PRINT_DEBUG_LEVEL(lvl, secrets_domain_infoB, &sdib);
785 104 : }
786 :
787 3 : char *secrets_domain_info_string(TALLOC_CTX *mem_ctx, const struct secrets_domain_info1 *info1,
788 : const char *name, bool include_secrets)
789 : {
790 3 : TALLOC_CTX *frame = talloc_stackframe();
791 3 : struct secrets_domain_infoB sdib = {
792 : .version = SECRETS_DOMAIN_INFO_VERSION_1,
793 : };
794 3 : struct ndr_print *ndr = NULL;
795 3 : char *ret = NULL;
796 :
797 3 : sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
798 :
799 3 : ndr = talloc_zero(frame, struct ndr_print);
800 3 : if (ndr == NULL) {
801 0 : TALLOC_FREE(frame);
802 0 : return NULL;
803 : }
804 3 : ndr->private_data = talloc_strdup(ndr, "");
805 3 : if (ndr->private_data == NULL) {
806 0 : TALLOC_FREE(frame);
807 0 : return NULL;
808 : }
809 3 : ndr->print = ndr_print_string_helper;
810 3 : ndr->depth = 1;
811 3 : ndr->print_secrets = include_secrets;
812 :
813 3 : ndr_print_secrets_domain_infoB(ndr, name, &sdib);
814 3 : ret = talloc_steal(mem_ctx, (char *)ndr->private_data);
815 3 : TALLOC_FREE(frame);
816 3 : return ret;
817 : }
818 :
819 100 : static NTSTATUS secrets_store_domain_info1_by_key(const char *key,
820 : const struct secrets_domain_info1 *info1)
821 : {
822 100 : struct secrets_domain_infoB sdib = {
823 : .version = SECRETS_DOMAIN_INFO_VERSION_1,
824 : };
825 : /* packing structures */
826 0 : DATA_BLOB blob;
827 0 : enum ndr_err_code ndr_err;
828 0 : bool ok;
829 :
830 100 : sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
831 :
832 100 : ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &sdib,
833 : (ndr_push_flags_fn_t)ndr_push_secrets_domain_infoB);
834 100 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
835 0 : return ndr_map_error2ntstatus(ndr_err);
836 : }
837 :
838 100 : ok = secrets_store(key, blob.data, blob.length);
839 100 : data_blob_clear_free(&blob);
840 100 : if (!ok) {
841 0 : return NT_STATUS_INTERNAL_DB_ERROR;
842 : }
843 :
844 100 : return NT_STATUS_OK;
845 : }
846 :
847 104 : static NTSTATUS secrets_store_domain_info(const struct secrets_domain_info1 *info,
848 : bool upgrade)
849 : {
850 104 : TALLOC_CTX *frame = talloc_stackframe();
851 104 : const char *domain = info->domain_info.name.string;
852 104 : const char *realm = info->domain_info.dns_domain.string;
853 104 : char *key = domain_info_keystr(domain);
854 104 : struct db_context *db = NULL;
855 0 : struct timeval last_change_tv;
856 104 : const DATA_BLOB *cleartext_blob = NULL;
857 104 : DATA_BLOB pw_blob = data_blob_null;
858 104 : DATA_BLOB old_pw_blob = data_blob_null;
859 104 : const char *pw = NULL;
860 104 : const char *old_pw = NULL;
861 0 : bool ok;
862 0 : NTSTATUS status;
863 0 : int ret;
864 104 : int role = lp_server_role();
865 :
866 104 : switch (info->secure_channel_type) {
867 100 : case SEC_CHAN_WKSTA:
868 : case SEC_CHAN_BDC:
869 100 : if (!upgrade && role >= ROLE_ACTIVE_DIRECTORY_DC) {
870 0 : DBG_ERR("AD_DC not supported for %s\n",
871 : domain);
872 0 : TALLOC_FREE(frame);
873 0 : return NT_STATUS_INTERNAL_ERROR;
874 : }
875 :
876 100 : break;
877 4 : default:
878 4 : DBG_ERR("SEC_CHAN_* not supported for %s\n",
879 : domain);
880 4 : TALLOC_FREE(frame);
881 4 : return NT_STATUS_INTERNAL_ERROR;
882 : }
883 :
884 100 : db = secrets_db_ctx();
885 :
886 100 : ret = dbwrap_transaction_start(db);
887 100 : if (ret != 0) {
888 0 : DBG_ERR("dbwrap_transaction_start() failed for %s\n",
889 : domain);
890 0 : TALLOC_FREE(frame);
891 0 : return NT_STATUS_INTERNAL_DB_ERROR;
892 : }
893 :
894 100 : ok = secrets_clear_domain_protection(domain);
895 100 : if (!ok) {
896 0 : DBG_ERR("secrets_clear_domain_protection(%s) failed\n",
897 : domain);
898 0 : dbwrap_transaction_cancel(db);
899 0 : TALLOC_FREE(frame);
900 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
901 : }
902 :
903 100 : ok = secrets_delete_machine_password_ex(domain, realm);
904 100 : if (!ok) {
905 0 : DBG_ERR("secrets_delete_machine_password_ex(%s) failed\n",
906 : domain);
907 0 : dbwrap_transaction_cancel(db);
908 0 : TALLOC_FREE(frame);
909 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
910 : }
911 :
912 100 : status = secrets_store_domain_info1_by_key(key, info);
913 100 : if (!NT_STATUS_IS_OK(status)) {
914 0 : DBG_ERR("secrets_store_domain_info1_by_key() failed "
915 : "for %s - %s\n", domain, nt_errstr(status));
916 0 : dbwrap_transaction_cancel(db);
917 0 : TALLOC_FREE(frame);
918 0 : return status;
919 : }
920 :
921 : /*
922 : * We use info->password_last_change instead
923 : * of info->password.change_time because
924 : * we may want to defer the next change approach
925 : * if the server rejected the change the last time,
926 : * e.g. due to RefusePasswordChange=1.
927 : */
928 100 : nttime_to_timeval(&last_change_tv, info->password_last_change);
929 :
930 100 : cleartext_blob = &info->password->cleartext_blob;
931 100 : ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
932 100 : cleartext_blob->data,
933 100 : cleartext_blob->length,
934 : (void **)&pw_blob.data,
935 : &pw_blob.length);
936 100 : if (!ok) {
937 0 : status = NT_STATUS_UNMAPPABLE_CHARACTER;
938 0 : if (errno == ENOMEM) {
939 0 : status = NT_STATUS_NO_MEMORY;
940 : }
941 0 : DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
942 : "failed for pw of %s - %s\n",
943 : domain, nt_errstr(status));
944 0 : dbwrap_transaction_cancel(db);
945 0 : TALLOC_FREE(frame);
946 0 : return status;
947 : }
948 100 : pw = (const char *)pw_blob.data;
949 100 : if (info->old_password != NULL) {
950 20 : cleartext_blob = &info->old_password->cleartext_blob;
951 20 : ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
952 20 : cleartext_blob->data,
953 20 : cleartext_blob->length,
954 : (void **)&old_pw_blob.data,
955 : &old_pw_blob.length);
956 20 : if (!ok) {
957 0 : status = NT_STATUS_UNMAPPABLE_CHARACTER;
958 0 : if (errno == ENOMEM) {
959 0 : status = NT_STATUS_NO_MEMORY;
960 : }
961 0 : DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
962 : "failed for old_pw of %s - %s\n",
963 : domain, nt_errstr(status));
964 0 : dbwrap_transaction_cancel(db);
965 0 : data_blob_clear_free(&pw_blob);
966 0 : TALLOC_FREE(frame);
967 0 : return status;
968 : }
969 20 : old_pw = (const char *)old_pw_blob.data;
970 : }
971 :
972 100 : ok = secrets_store_machine_pw_sync(pw, old_pw,
973 : domain, realm,
974 100 : info->salt_principal,
975 100 : info->supported_enc_types,
976 100 : info->domain_info.sid,
977 100 : last_change_tv.tv_sec,
978 100 : info->secure_channel_type,
979 : false); /* delete_join */
980 100 : data_blob_clear_free(&pw_blob);
981 100 : data_blob_clear_free(&old_pw_blob);
982 100 : if (!ok) {
983 0 : DBG_ERR("secrets_store_machine_pw_sync(%s) failed\n",
984 : domain);
985 0 : dbwrap_transaction_cancel(db);
986 0 : TALLOC_FREE(frame);
987 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
988 : }
989 :
990 100 : if (!GUID_all_zero(&info->domain_info.domain_guid)) {
991 75 : ok = secrets_store_domain_guid(domain,
992 : &info->domain_info.domain_guid);
993 75 : if (!ok) {
994 0 : DBG_ERR("secrets_store_domain_guid(%s) failed\n",
995 : domain);
996 0 : dbwrap_transaction_cancel(db);
997 0 : TALLOC_FREE(frame);
998 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
999 : }
1000 : }
1001 :
1002 100 : ok = secrets_mark_domain_protected(domain);
1003 100 : if (!ok) {
1004 0 : DBG_ERR("secrets_mark_domain_protected(%s) failed\n",
1005 : domain);
1006 0 : dbwrap_transaction_cancel(db);
1007 0 : TALLOC_FREE(frame);
1008 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1009 : }
1010 :
1011 100 : ret = dbwrap_transaction_commit(db);
1012 100 : if (ret != 0) {
1013 0 : DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1014 : domain);
1015 0 : TALLOC_FREE(frame);
1016 0 : return NT_STATUS_INTERNAL_DB_ERROR;
1017 : }
1018 :
1019 100 : TALLOC_FREE(frame);
1020 100 : return NT_STATUS_OK;
1021 : }
1022 :
1023 99 : static int secrets_domain_info_kerberos_keys(struct secrets_domain_info1_password *p,
1024 : const char *salt_principal)
1025 : {
1026 : #ifdef HAVE_ADS
1027 0 : krb5_error_code krb5_ret;
1028 92 : krb5_context krb5_ctx = NULL;
1029 92 : DATA_BLOB cleartext_utf8_b = data_blob_null;
1030 0 : krb5_data cleartext_utf8;
1031 0 : krb5_data salt;
1032 0 : krb5_keyblock key;
1033 92 : DATA_BLOB aes_256_b = data_blob_null;
1034 92 : DATA_BLOB aes_128_b = data_blob_null;
1035 0 : bool ok;
1036 : #endif /* HAVE_ADS */
1037 99 : DATA_BLOB arc4_b = data_blob_null;
1038 99 : const uint16_t max_keys = 4;
1039 99 : struct secrets_domain_info1_kerberos_key *keys = NULL;
1040 99 : uint16_t idx = 0;
1041 99 : char *salt_data = NULL;
1042 :
1043 : /*
1044 : * We calculate:
1045 : * ENCTYPE_AES256_CTS_HMAC_SHA1_96
1046 : * ENCTYPE_AES128_CTS_HMAC_SHA1_96
1047 : * ENCTYPE_ARCFOUR_HMAC
1048 : * ENCTYPE_DES_CBC_MD5
1049 : *
1050 : * We don't include ENCTYPE_DES_CBC_CRC
1051 : * as W2008R2 also doesn't store it anymore.
1052 : *
1053 : * Note we store all enctypes we support,
1054 : * including the weak encryption types,
1055 : * but that's no problem as we also
1056 : * store the cleartext password anyway.
1057 : *
1058 : * Which values are then used to construct
1059 : * a keytab is configured at runtime and the
1060 : * configuration of msDS-SupportedEncryptionTypes.
1061 : *
1062 : * If we don't have kerberos support or no
1063 : * salt, we only generate an entry for arcfour-hmac-md5.
1064 : */
1065 99 : keys = talloc_zero_array(p,
1066 : struct secrets_domain_info1_kerberos_key,
1067 : max_keys);
1068 99 : if (keys == NULL) {
1069 0 : return ENOMEM;
1070 : }
1071 :
1072 99 : arc4_b = data_blob_talloc(keys,
1073 : p->nt_hash.hash,
1074 : sizeof(p->nt_hash.hash));
1075 99 : if (arc4_b.data == NULL) {
1076 0 : DBG_ERR("data_blob_talloc failed for arcfour-hmac-md5.\n");
1077 0 : TALLOC_FREE(keys);
1078 0 : return ENOMEM;
1079 : }
1080 99 : talloc_keep_secret(arc4_b.data);
1081 :
1082 : #ifdef HAVE_ADS
1083 92 : if (salt_principal == NULL) {
1084 8 : goto no_kerberos;
1085 : }
1086 :
1087 84 : krb5_ret = smb_krb5_init_context_common(&krb5_ctx);
1088 84 : if (krb5_ret != 0) {
1089 0 : DBG_ERR("kerberos init context failed (%s)\n",
1090 : error_message(krb5_ret));
1091 0 : TALLOC_FREE(keys);
1092 0 : return krb5_ret;
1093 : }
1094 :
1095 84 : krb5_ret = smb_krb5_salt_principal2data(krb5_ctx, salt_principal,
1096 : p, &salt_data);
1097 84 : if (krb5_ret != 0) {
1098 0 : DBG_ERR("smb_krb5_salt_principal2data(%s) failed: %s\n",
1099 : salt_principal,
1100 : smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1101 0 : krb5_free_context(krb5_ctx);
1102 0 : TALLOC_FREE(keys);
1103 0 : return krb5_ret;
1104 : }
1105 :
1106 84 : salt = (krb5_data) {
1107 49 : .data = discard_const(salt_data),
1108 84 : .length = strlen(salt_data),
1109 : };
1110 :
1111 84 : ok = convert_string_talloc(keys, CH_UTF16MUNGED, CH_UTF8,
1112 84 : p->cleartext_blob.data,
1113 : p->cleartext_blob.length,
1114 : (void **)&cleartext_utf8_b.data,
1115 : &cleartext_utf8_b.length);
1116 84 : if (!ok) {
1117 0 : if (errno != 0) {
1118 0 : krb5_ret = errno;
1119 : } else {
1120 0 : krb5_ret = EINVAL;
1121 : }
1122 0 : krb5_free_context(krb5_ctx);
1123 0 : TALLOC_FREE(keys);
1124 0 : return krb5_ret;
1125 : }
1126 84 : talloc_keep_secret(cleartext_utf8_b.data);
1127 84 : cleartext_utf8.data = (void *)cleartext_utf8_b.data;
1128 84 : cleartext_utf8.length = cleartext_utf8_b.length;
1129 :
1130 84 : krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
1131 : NULL,
1132 : &salt,
1133 : &cleartext_utf8,
1134 : ENCTYPE_AES256_CTS_HMAC_SHA1_96,
1135 : &key);
1136 84 : if (krb5_ret != 0) {
1137 0 : DBG_ERR("generation of a aes256-cts-hmac-sha1-96 key failed: %s\n",
1138 : smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1139 0 : krb5_free_context(krb5_ctx);
1140 0 : TALLOC_FREE(keys);
1141 0 : TALLOC_FREE(salt_data);
1142 0 : return krb5_ret;
1143 : }
1144 84 : aes_256_b = data_blob_talloc(keys,
1145 : KRB5_KEY_DATA(&key),
1146 : KRB5_KEY_LENGTH(&key));
1147 84 : krb5_free_keyblock_contents(krb5_ctx, &key);
1148 84 : if (aes_256_b.data == NULL) {
1149 0 : DBG_ERR("data_blob_talloc failed for aes-256.\n");
1150 0 : krb5_free_context(krb5_ctx);
1151 0 : TALLOC_FREE(keys);
1152 0 : TALLOC_FREE(salt_data);
1153 0 : return ENOMEM;
1154 : }
1155 84 : talloc_keep_secret(aes_256_b.data);
1156 :
1157 84 : krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
1158 : NULL,
1159 : &salt,
1160 : &cleartext_utf8,
1161 : ENCTYPE_AES128_CTS_HMAC_SHA1_96,
1162 : &key);
1163 84 : if (krb5_ret != 0) {
1164 0 : DBG_ERR("generation of a aes128-cts-hmac-sha1-96 key failed: %s\n",
1165 : smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1166 0 : krb5_free_context(krb5_ctx);
1167 0 : TALLOC_FREE(keys);
1168 0 : TALLOC_FREE(salt_data);
1169 0 : return krb5_ret;
1170 : }
1171 84 : aes_128_b = data_blob_talloc(keys,
1172 : KRB5_KEY_DATA(&key),
1173 : KRB5_KEY_LENGTH(&key));
1174 84 : krb5_free_keyblock_contents(krb5_ctx, &key);
1175 84 : if (aes_128_b.data == NULL) {
1176 0 : DBG_ERR("data_blob_talloc failed for aes-128.\n");
1177 0 : krb5_free_context(krb5_ctx);
1178 0 : TALLOC_FREE(keys);
1179 0 : TALLOC_FREE(salt_data);
1180 0 : return ENOMEM;
1181 : }
1182 84 : talloc_keep_secret(aes_128_b.data);
1183 :
1184 84 : krb5_free_context(krb5_ctx);
1185 92 : no_kerberos:
1186 :
1187 92 : if (aes_256_b.length != 0) {
1188 84 : keys[idx].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
1189 84 : keys[idx].iteration_count = 4096;
1190 84 : keys[idx].value = aes_256_b;
1191 84 : idx += 1;
1192 : }
1193 :
1194 92 : if (aes_128_b.length != 0) {
1195 84 : keys[idx].keytype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
1196 84 : keys[idx].iteration_count = 4096;
1197 84 : keys[idx].value = aes_128_b;
1198 84 : idx += 1;
1199 : }
1200 :
1201 : #endif /* HAVE_ADS */
1202 :
1203 99 : keys[idx].keytype = ENCTYPE_ARCFOUR_HMAC;
1204 99 : keys[idx].iteration_count = 4096;
1205 99 : keys[idx].value = arc4_b;
1206 99 : idx += 1;
1207 :
1208 99 : p->salt_data = salt_data;
1209 99 : p->default_iteration_count = 4096;
1210 99 : p->num_keys = idx;
1211 99 : p->keys = keys;
1212 99 : return 0;
1213 : }
1214 :
1215 99 : static NTSTATUS secrets_domain_info_password_create(TALLOC_CTX *mem_ctx,
1216 : const char *cleartext_unix,
1217 : const char *salt_principal,
1218 : NTTIME change_time,
1219 : const char *change_server,
1220 : struct secrets_domain_info1_password **_p)
1221 : {
1222 99 : struct secrets_domain_info1_password *p = NULL;
1223 0 : bool ok;
1224 0 : size_t len;
1225 0 : int ret;
1226 :
1227 99 : if (change_server == NULL) {
1228 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1229 : }
1230 :
1231 99 : p = talloc_zero(mem_ctx, struct secrets_domain_info1_password);
1232 99 : if (p == NULL) {
1233 0 : return NT_STATUS_NO_MEMORY;
1234 : }
1235 99 : p->change_time = change_time;
1236 99 : p->change_server = talloc_strdup(p, change_server);
1237 99 : if (p->change_server == NULL) {
1238 0 : TALLOC_FREE(p);
1239 0 : return NT_STATUS_NO_MEMORY;
1240 : }
1241 99 : len = strlen(cleartext_unix);
1242 99 : ok = convert_string_talloc(p, CH_UNIX, CH_UTF16,
1243 : cleartext_unix, len,
1244 99 : (void **)&p->cleartext_blob.data,
1245 : &p->cleartext_blob.length);
1246 99 : if (!ok) {
1247 0 : NTSTATUS status = NT_STATUS_UNMAPPABLE_CHARACTER;
1248 0 : if (errno == ENOMEM) {
1249 0 : status = NT_STATUS_NO_MEMORY;
1250 : }
1251 0 : TALLOC_FREE(p);
1252 0 : return status;
1253 : }
1254 99 : talloc_keep_secret(p->cleartext_blob.data);
1255 99 : mdfour(p->nt_hash.hash,
1256 99 : p->cleartext_blob.data,
1257 99 : p->cleartext_blob.length);
1258 :
1259 99 : talloc_set_destructor(p, password_nt_hash_destructor);
1260 99 : ret = secrets_domain_info_kerberos_keys(p, salt_principal);
1261 99 : if (ret != 0) {
1262 0 : NTSTATUS status = krb5_to_nt_status(ret);
1263 0 : TALLOC_FREE(p);
1264 0 : return status;
1265 : }
1266 :
1267 99 : *_p = p;
1268 99 : return NT_STATUS_OK;
1269 : }
1270 :
1271 4475 : NTSTATUS secrets_fetch_or_upgrade_domain_info(const char *domain,
1272 : TALLOC_CTX *mem_ctx,
1273 : struct secrets_domain_info1 **pinfo)
1274 : {
1275 4475 : TALLOC_CTX *frame = NULL;
1276 4475 : struct secrets_domain_info1 *old = NULL;
1277 4475 : struct secrets_domain_info1 *info = NULL;
1278 4475 : const char *dns_domain = NULL;
1279 4475 : const char *server = NULL;
1280 4475 : struct db_context *db = NULL;
1281 0 : time_t last_set_time;
1282 0 : NTTIME last_set_nt;
1283 0 : enum netr_SchannelType channel;
1284 4475 : char *pw = NULL;
1285 4475 : char *old_pw = NULL;
1286 0 : struct dom_sid domain_sid;
1287 0 : struct GUID domain_guid;
1288 0 : bool ok;
1289 0 : NTSTATUS status;
1290 0 : int ret;
1291 :
1292 4475 : ok = strequal(domain, lp_workgroup());
1293 4475 : if (ok) {
1294 4475 : dns_domain = lp_dnsdomain();
1295 :
1296 4475 : if (dns_domain != NULL && dns_domain[0] == '\0') {
1297 18 : dns_domain = NULL;
1298 : }
1299 : }
1300 :
1301 4475 : last_set_time = secrets_fetch_pass_last_set_time(domain);
1302 4475 : if (last_set_time == 0) {
1303 70 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1304 : }
1305 4405 : unix_to_nt_time(&last_set_nt, last_set_time);
1306 :
1307 4405 : frame = talloc_stackframe();
1308 :
1309 4405 : status = secrets_fetch_domain_info(domain, frame, &old);
1310 4405 : if (NT_STATUS_IS_OK(status)) {
1311 4396 : if (old->password_last_change >= last_set_nt) {
1312 4396 : *pinfo = talloc_move(mem_ctx, &old);
1313 4396 : TALLOC_FREE(frame);
1314 4396 : return NT_STATUS_OK;
1315 : }
1316 0 : TALLOC_FREE(old);
1317 : }
1318 :
1319 9 : info = talloc_zero(frame, struct secrets_domain_info1);
1320 9 : if (info == NULL) {
1321 0 : DBG_ERR("talloc_zero failed\n");
1322 0 : TALLOC_FREE(frame);
1323 0 : return NT_STATUS_NO_MEMORY;
1324 : }
1325 :
1326 9 : db = secrets_db_ctx();
1327 :
1328 9 : ret = dbwrap_transaction_start(db);
1329 9 : if (ret != 0) {
1330 0 : DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1331 : domain);
1332 0 : TALLOC_FREE(frame);
1333 0 : return NT_STATUS_INTERNAL_DB_ERROR;
1334 : }
1335 :
1336 9 : pw = secrets_fetch_machine_password(domain,
1337 : &last_set_time,
1338 : &channel);
1339 9 : if (pw == NULL) {
1340 0 : DBG_ERR("secrets_fetch_machine_password(%s) failed\n",
1341 : domain);
1342 0 : dbwrap_transaction_cancel(db);
1343 0 : TALLOC_FREE(frame);
1344 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1345 : }
1346 9 : unix_to_nt_time(&last_set_nt, last_set_time);
1347 :
1348 9 : old_pw = secrets_fetch_prev_machine_password(domain);
1349 :
1350 9 : ok = secrets_fetch_domain_sid(domain, &domain_sid);
1351 9 : if (!ok) {
1352 0 : DBG_ERR("secrets_fetch_domain_sid(%s) failed\n",
1353 : domain);
1354 0 : dbwrap_transaction_cancel(db);
1355 0 : BURN_FREE_STR(old_pw);
1356 0 : BURN_FREE_STR(pw);
1357 0 : TALLOC_FREE(frame);
1358 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1359 : }
1360 :
1361 9 : ok = secrets_fetch_domain_guid(domain, &domain_guid);
1362 9 : if (!ok) {
1363 4 : domain_guid = GUID_zero();
1364 : }
1365 :
1366 9 : info->computer_name = lp_netbios_name();
1367 9 : info->account_name = talloc_asprintf(frame, "%s$", info->computer_name);
1368 9 : if (info->account_name == NULL) {
1369 0 : DBG_ERR("talloc_asprintf(%s$) failed\n", info->computer_name);
1370 0 : dbwrap_transaction_cancel(db);
1371 0 : BURN_FREE_STR(old_pw);
1372 0 : BURN_FREE_STR(pw);
1373 0 : TALLOC_FREE(frame);
1374 0 : return NT_STATUS_NO_MEMORY;
1375 : }
1376 9 : info->secure_channel_type = channel;
1377 :
1378 9 : info->domain_info.name.string = domain;
1379 9 : info->domain_info.dns_domain.string = dns_domain;
1380 9 : info->domain_info.dns_forest.string = dns_domain;
1381 9 : info->domain_info.domain_guid = domain_guid;
1382 9 : info->domain_info.sid = &domain_sid;
1383 :
1384 9 : info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
1385 9 : info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1386 :
1387 9 : if (dns_domain != NULL) {
1388 : /*
1389 : * We just assume all AD domains are
1390 : * NETR_TRUST_FLAG_NATIVE these days.
1391 : *
1392 : * This isn't used anyway for now.
1393 : */
1394 9 : info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
1395 :
1396 9 : info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
1397 :
1398 9 : server = info->domain_info.dns_domain.string;
1399 : } else {
1400 0 : info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1401 :
1402 0 : server = talloc_asprintf(info,
1403 : "%s#%02X",
1404 : domain,
1405 : NBT_NAME_PDC);
1406 0 : if (server == NULL) {
1407 0 : DBG_ERR("talloc_asprintf(%s#%02X) failed\n",
1408 : domain, NBT_NAME_PDC);
1409 0 : dbwrap_transaction_cancel(db);
1410 0 : BURN_FREE_STR(pw);
1411 0 : BURN_FREE_STR(old_pw);
1412 0 : TALLOC_FREE(frame);
1413 0 : return NT_STATUS_NO_MEMORY;
1414 : }
1415 : }
1416 9 : info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
1417 :
1418 9 : info->join_time = 0;
1419 :
1420 : /*
1421 : * We don't have enough information about the configured
1422 : * enctypes.
1423 : */
1424 9 : info->supported_enc_types = 0;
1425 9 : info->salt_principal = NULL;
1426 9 : if (info->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
1427 9 : char *p = NULL;
1428 :
1429 9 : p = kerberos_secrets_fetch_salt_princ();
1430 9 : if (p == NULL) {
1431 0 : dbwrap_transaction_cancel(db);
1432 0 : BURN_FREE_STR(old_pw);
1433 0 : BURN_FREE_STR(pw);
1434 0 : TALLOC_FREE(frame);
1435 0 : return NT_STATUS_INTERNAL_ERROR;
1436 : }
1437 9 : info->salt_principal = talloc_strdup(info, p);
1438 9 : SAFE_FREE(p);
1439 9 : if (info->salt_principal == NULL) {
1440 0 : dbwrap_transaction_cancel(db);
1441 0 : BURN_FREE_STR(pw);
1442 0 : BURN_FREE_STR(old_pw);
1443 0 : TALLOC_FREE(frame);
1444 0 : return NT_STATUS_NO_MEMORY;
1445 : }
1446 : }
1447 :
1448 9 : info->password_last_change = last_set_nt;
1449 9 : info->password_changes = 1;
1450 9 : info->next_change = NULL;
1451 :
1452 9 : status = secrets_domain_info_password_create(info,
1453 : pw,
1454 9 : info->salt_principal,
1455 : last_set_nt, server,
1456 9 : &info->password);
1457 9 : BURN_FREE_STR(pw);
1458 9 : if (!NT_STATUS_IS_OK(status)) {
1459 0 : DBG_ERR("secrets_domain_info_password_create(pw) failed "
1460 : "for %s - %s\n", domain, nt_errstr(status));
1461 0 : dbwrap_transaction_cancel(db);
1462 0 : BURN_FREE_STR(old_pw);
1463 0 : TALLOC_FREE(frame);
1464 0 : return status;
1465 : }
1466 :
1467 : /*
1468 : * After a join we don't have old passwords.
1469 : */
1470 9 : if (old_pw != NULL) {
1471 5 : status = secrets_domain_info_password_create(info,
1472 : old_pw,
1473 5 : info->salt_principal,
1474 : 0, server,
1475 5 : &info->old_password);
1476 5 : BURN_FREE_STR(old_pw);
1477 5 : if (!NT_STATUS_IS_OK(status)) {
1478 0 : DBG_ERR("secrets_domain_info_password_create(old) failed "
1479 : "for %s - %s\n", domain, nt_errstr(status));
1480 0 : dbwrap_transaction_cancel(db);
1481 0 : TALLOC_FREE(frame);
1482 0 : return status;
1483 : }
1484 5 : info->password_changes += 1;
1485 : } else {
1486 4 : info->old_password = NULL;
1487 : }
1488 9 : info->older_password = NULL;
1489 :
1490 9 : secrets_debug_domain_info(DBGLVL_INFO, info, "upgrade");
1491 :
1492 9 : status = secrets_store_domain_info(info, true /* upgrade */);
1493 9 : if (!NT_STATUS_IS_OK(status)) {
1494 4 : DBG_ERR("secrets_store_domain_info() failed "
1495 : "for %s - %s\n", domain, nt_errstr(status));
1496 4 : dbwrap_transaction_cancel(db);
1497 4 : TALLOC_FREE(frame);
1498 4 : return status;
1499 : }
1500 :
1501 : /*
1502 : * We now reparse it.
1503 : */
1504 5 : status = secrets_fetch_domain_info(domain, frame, &info);
1505 5 : if (!NT_STATUS_IS_OK(status)) {
1506 0 : DBG_ERR("secrets_fetch_domain_info() failed "
1507 : "for %s - %s\n", domain, nt_errstr(status));
1508 0 : dbwrap_transaction_cancel(db);
1509 0 : TALLOC_FREE(frame);
1510 0 : return status;
1511 : }
1512 :
1513 5 : ret = dbwrap_transaction_commit(db);
1514 5 : if (ret != 0) {
1515 0 : DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1516 : domain);
1517 0 : dbwrap_transaction_cancel(db);
1518 0 : TALLOC_FREE(frame);
1519 0 : return NT_STATUS_INTERNAL_DB_ERROR;
1520 : }
1521 :
1522 5 : *pinfo = talloc_move(mem_ctx, &info);
1523 5 : TALLOC_FREE(frame);
1524 5 : return NT_STATUS_OK;
1525 : }
1526 :
1527 75 : NTSTATUS secrets_store_JoinCtx(const struct libnet_JoinCtx *r)
1528 : {
1529 75 : TALLOC_CTX *frame = talloc_stackframe();
1530 75 : struct secrets_domain_info1 *old = NULL;
1531 75 : struct secrets_domain_info1 *info = NULL;
1532 75 : struct db_context *db = NULL;
1533 75 : struct timeval tv = timeval_current();
1534 75 : NTTIME now = timeval_to_nttime(&tv);
1535 75 : const char *domain = r->out.netbios_domain_name;
1536 0 : NTSTATUS status;
1537 0 : int ret;
1538 :
1539 75 : info = talloc_zero(frame, struct secrets_domain_info1);
1540 75 : if (info == NULL) {
1541 0 : DBG_ERR("talloc_zero failed\n");
1542 0 : TALLOC_FREE(frame);
1543 0 : return NT_STATUS_NO_MEMORY;
1544 : }
1545 :
1546 75 : info->computer_name = r->in.machine_name;
1547 75 : info->account_name = r->out.account_name;
1548 75 : info->secure_channel_type = r->in.secure_channel_type;
1549 :
1550 75 : info->domain_info.name.string =
1551 75 : r->out.netbios_domain_name;
1552 75 : info->domain_info.dns_domain.string =
1553 75 : r->out.dns_domain_name;
1554 75 : info->domain_info.dns_forest.string =
1555 75 : r->out.forest_name;
1556 75 : info->domain_info.domain_guid = r->out.domain_guid;
1557 75 : info->domain_info.sid = r->out.domain_sid;
1558 :
1559 75 : info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
1560 75 : info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1561 75 : if (r->out.domain_is_ad) {
1562 : /*
1563 : * We just assume all AD domains are
1564 : * NETR_TRUST_FLAG_NATIVE these days.
1565 : *
1566 : * This isn't used anyway for now.
1567 : */
1568 66 : info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
1569 :
1570 66 : info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
1571 : } else {
1572 9 : info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1573 : }
1574 75 : info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
1575 :
1576 75 : info->join_time = now;
1577 :
1578 75 : info->supported_enc_types = r->out.set_encryption_types;
1579 75 : info->salt_principal = r->out.krb5_salt;
1580 :
1581 75 : if (info->salt_principal == NULL && r->out.domain_is_ad) {
1582 18 : char *p = NULL;
1583 :
1584 18 : ret = smb_krb5_salt_principal_str(info->domain_info.dns_domain.string,
1585 : info->account_name,
1586 : NULL /* userPrincipalName */,
1587 : UF_WORKSTATION_TRUST_ACCOUNT,
1588 : info, &p);
1589 18 : if (ret != 0) {
1590 0 : status = krb5_to_nt_status(ret);
1591 0 : DBG_ERR("smb_krb5_salt_principal() failed "
1592 : "for %s - %s\n", domain, nt_errstr(status));
1593 0 : TALLOC_FREE(frame);
1594 0 : return status;
1595 : }
1596 18 : info->salt_principal = p;
1597 : }
1598 :
1599 75 : info->password_last_change = now;
1600 75 : info->password_changes = 1;
1601 75 : info->next_change = NULL;
1602 :
1603 75 : status = secrets_domain_info_password_create(info,
1604 75 : r->in.machine_password,
1605 : info->salt_principal,
1606 75 : now, r->in.dc_name,
1607 : &info->password);
1608 75 : if (!NT_STATUS_IS_OK(status)) {
1609 0 : DBG_ERR("secrets_domain_info_password_create(pw) failed "
1610 : "for %s - %s\n", domain, nt_errstr(status));
1611 0 : TALLOC_FREE(frame);
1612 0 : return status;
1613 : }
1614 :
1615 75 : db = secrets_db_ctx();
1616 :
1617 75 : ret = dbwrap_transaction_start(db);
1618 75 : if (ret != 0) {
1619 0 : DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1620 : domain);
1621 0 : TALLOC_FREE(frame);
1622 0 : return NT_STATUS_INTERNAL_DB_ERROR;
1623 : }
1624 :
1625 75 : status = secrets_fetch_or_upgrade_domain_info(domain, frame, &old);
1626 75 : if (NT_STATUS_EQUAL(status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
1627 70 : DBG_DEBUG("no old join for domain(%s) available\n",
1628 : domain);
1629 70 : old = NULL;
1630 5 : } else if (!NT_STATUS_IS_OK(status)) {
1631 0 : DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
1632 : domain);
1633 0 : dbwrap_transaction_cancel(db);
1634 0 : TALLOC_FREE(frame);
1635 0 : return status;
1636 : }
1637 :
1638 : /*
1639 : * We reuse values from an old join, so that
1640 : * we still accept already granted kerberos tickets.
1641 : */
1642 75 : if (old != NULL) {
1643 5 : info->old_password = old->password;
1644 5 : info->older_password = old->old_password;
1645 : }
1646 :
1647 75 : secrets_debug_domain_info(DBGLVL_INFO, info, "join");
1648 :
1649 75 : status = secrets_store_domain_info(info, false /* upgrade */);
1650 75 : if (!NT_STATUS_IS_OK(status)) {
1651 0 : DBG_ERR("secrets_store_domain_info() failed "
1652 : "for %s - %s\n", domain, nt_errstr(status));
1653 0 : dbwrap_transaction_cancel(db);
1654 0 : TALLOC_FREE(frame);
1655 0 : return status;
1656 : }
1657 :
1658 75 : ret = dbwrap_transaction_commit(db);
1659 75 : if (ret != 0) {
1660 0 : DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1661 : domain);
1662 0 : TALLOC_FREE(frame);
1663 0 : return NT_STATUS_INTERNAL_DB_ERROR;
1664 : }
1665 :
1666 75 : TALLOC_FREE(frame);
1667 75 : return NT_STATUS_OK;
1668 : }
1669 :
1670 10 : NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname,
1671 : const char *cleartext_unix,
1672 : TALLOC_CTX *mem_ctx,
1673 : struct secrets_domain_info1 **pinfo,
1674 : struct secrets_domain_info1_change **pprev)
1675 : {
1676 10 : TALLOC_CTX *frame = talloc_stackframe();
1677 10 : struct db_context *db = NULL;
1678 10 : struct secrets_domain_info1 *info = NULL;
1679 10 : struct secrets_domain_info1_change *prev = NULL;
1680 10 : struct secrets_domain_info1_change *next = NULL;
1681 10 : struct timeval tv = timeval_current();
1682 10 : NTTIME now = timeval_to_nttime(&tv);
1683 0 : NTSTATUS status;
1684 0 : int ret;
1685 :
1686 10 : db = secrets_db_ctx();
1687 :
1688 10 : ret = dbwrap_transaction_start(db);
1689 10 : if (ret != 0) {
1690 0 : DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1691 : domain);
1692 0 : TALLOC_FREE(frame);
1693 0 : return NT_STATUS_INTERNAL_DB_ERROR;
1694 : }
1695 :
1696 10 : status = secrets_fetch_or_upgrade_domain_info(domain, frame, &info);
1697 10 : if (!NT_STATUS_IS_OK(status)) {
1698 0 : DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
1699 : domain);
1700 0 : dbwrap_transaction_cancel(db);
1701 0 : TALLOC_FREE(frame);
1702 0 : return status;
1703 : }
1704 :
1705 10 : prev = info->next_change;
1706 10 : info->next_change = NULL;
1707 :
1708 10 : next = talloc_zero(frame, struct secrets_domain_info1_change);
1709 10 : if (next == NULL) {
1710 0 : DBG_ERR("talloc_zero failed\n");
1711 0 : TALLOC_FREE(frame);
1712 0 : return NT_STATUS_NO_MEMORY;
1713 : }
1714 :
1715 10 : if (prev != NULL) {
1716 0 : *next = *prev;
1717 : } else {
1718 10 : status = secrets_domain_info_password_create(next,
1719 : cleartext_unix,
1720 10 : info->salt_principal,
1721 : now, dcname,
1722 : &next->password);
1723 10 : if (!NT_STATUS_IS_OK(status)) {
1724 0 : DBG_ERR("secrets_domain_info_password_create(next) failed "
1725 : "for %s - %s\n", domain, nt_errstr(status));
1726 0 : dbwrap_transaction_cancel(db);
1727 0 : TALLOC_FREE(frame);
1728 0 : return status;
1729 : }
1730 : }
1731 :
1732 10 : next->local_status = NT_STATUS_OK;
1733 10 : next->remote_status = NT_STATUS_NOT_COMMITTED;
1734 10 : next->change_time = now;
1735 10 : next->change_server = dcname;
1736 :
1737 10 : info->next_change = next;
1738 :
1739 10 : secrets_debug_domain_info(DBGLVL_INFO, info, "prepare_change");
1740 :
1741 10 : status = secrets_store_domain_info(info, false /* upgrade */);
1742 10 : if (!NT_STATUS_IS_OK(status)) {
1743 0 : DBG_ERR("secrets_store_domain_info() failed "
1744 : "for %s - %s\n", domain, nt_errstr(status));
1745 0 : dbwrap_transaction_cancel(db);
1746 0 : TALLOC_FREE(frame);
1747 0 : return status;
1748 : }
1749 :
1750 : /*
1751 : * We now reparse it.
1752 : */
1753 10 : status = secrets_fetch_domain_info(domain, frame, &info);
1754 10 : if (!NT_STATUS_IS_OK(status)) {
1755 0 : DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
1756 0 : dbwrap_transaction_cancel(db);
1757 0 : TALLOC_FREE(frame);
1758 0 : return status;
1759 : }
1760 :
1761 10 : ret = dbwrap_transaction_commit(db);
1762 10 : if (ret != 0) {
1763 0 : DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1764 : domain);
1765 0 : TALLOC_FREE(frame);
1766 0 : return NT_STATUS_INTERNAL_DB_ERROR;
1767 : }
1768 :
1769 10 : *pinfo = talloc_move(mem_ctx, &info);
1770 10 : if (prev != NULL) {
1771 0 : *pprev = talloc_move(mem_ctx, &prev);
1772 : } else {
1773 10 : *pprev = NULL;
1774 : }
1775 :
1776 10 : TALLOC_FREE(frame);
1777 10 : return NT_STATUS_OK;
1778 : }
1779 :
1780 10 : static NTSTATUS secrets_check_password_change(const struct secrets_domain_info1 *cookie,
1781 : TALLOC_CTX *mem_ctx,
1782 : struct secrets_domain_info1 **pstored)
1783 : {
1784 10 : const char *domain = cookie->domain_info.name.string;
1785 10 : struct secrets_domain_info1 *stored = NULL;
1786 10 : struct secrets_domain_info1_change *sn = NULL;
1787 10 : struct secrets_domain_info1_change *cn = NULL;
1788 0 : NTSTATUS status;
1789 0 : bool cmp;
1790 :
1791 10 : if (cookie->next_change == NULL) {
1792 0 : DBG_ERR("cookie->next_change == NULL for %s.\n", domain);
1793 0 : return NT_STATUS_INTERNAL_ERROR;
1794 : }
1795 :
1796 10 : if (cookie->next_change->password == NULL) {
1797 0 : DBG_ERR("cookie->next_change->password == NULL for %s.\n", domain);
1798 0 : return NT_STATUS_INTERNAL_ERROR;
1799 : }
1800 :
1801 10 : if (cookie->password == NULL) {
1802 0 : DBG_ERR("cookie->password == NULL for %s.\n", domain);
1803 0 : return NT_STATUS_INTERNAL_ERROR;
1804 : }
1805 :
1806 : /*
1807 : * Here we check that the given structure still contains the
1808 : * same secrets_domain_info1_change as currently stored.
1809 : *
1810 : * There's always a gap between secrets_prepare_password_change()
1811 : * and the callers of secrets_check_password_change().
1812 : */
1813 :
1814 10 : status = secrets_fetch_domain_info(domain, mem_ctx, &stored);
1815 10 : if (!NT_STATUS_IS_OK(status)) {
1816 0 : DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
1817 0 : return status;
1818 : }
1819 :
1820 10 : if (stored->next_change == NULL) {
1821 : /*
1822 : * We hit a race..., the administrator
1823 : * rejoined or something similar happened.
1824 : */
1825 0 : DBG_ERR("stored->next_change == NULL for %s.\n", domain);
1826 0 : TALLOC_FREE(stored);
1827 0 : return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1828 : }
1829 :
1830 10 : if (stored->password_last_change != cookie->password_last_change) {
1831 0 : struct timeval store_tv;
1832 0 : struct timeval_buf store_buf;
1833 0 : struct timeval cookie_tv;
1834 0 : struct timeval_buf cookie_buf;
1835 :
1836 0 : nttime_to_timeval(&store_tv, stored->password_last_change);
1837 0 : nttime_to_timeval(&cookie_tv, cookie->password_last_change);
1838 :
1839 0 : DBG_ERR("password_last_change differs %s != %s for %s.\n",
1840 : timeval_str_buf(&store_tv, false, false, &store_buf),
1841 : timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1842 : domain);
1843 0 : TALLOC_FREE(stored);
1844 0 : return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1845 : }
1846 :
1847 10 : sn = stored->next_change;
1848 10 : cn = cookie->next_change;
1849 :
1850 10 : if (sn->change_time != cn->change_time) {
1851 0 : struct timeval store_tv;
1852 0 : struct timeval_buf store_buf;
1853 0 : struct timeval cookie_tv;
1854 0 : struct timeval_buf cookie_buf;
1855 :
1856 0 : nttime_to_timeval(&store_tv, sn->change_time);
1857 0 : nttime_to_timeval(&cookie_tv, cn->change_time);
1858 :
1859 0 : DBG_ERR("next change_time differs %s != %s for %s.\n",
1860 : timeval_str_buf(&store_tv, false, false, &store_buf),
1861 : timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1862 : domain);
1863 0 : TALLOC_FREE(stored);
1864 0 : return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1865 : }
1866 :
1867 10 : if (sn->password->change_time != cn->password->change_time) {
1868 0 : struct timeval store_tv;
1869 0 : struct timeval_buf store_buf;
1870 0 : struct timeval cookie_tv;
1871 0 : struct timeval_buf cookie_buf;
1872 :
1873 0 : nttime_to_timeval(&store_tv, sn->password->change_time);
1874 0 : nttime_to_timeval(&cookie_tv, cn->password->change_time);
1875 :
1876 0 : DBG_ERR("next password.change_time differs %s != %s for %s.\n",
1877 : timeval_str_buf(&store_tv, false, false, &store_buf),
1878 : timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1879 : domain);
1880 0 : TALLOC_FREE(stored);
1881 0 : return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1882 : }
1883 :
1884 10 : cmp = mem_equal_const_time(sn->password->nt_hash.hash,
1885 10 : cn->password->nt_hash.hash,
1886 : 16);
1887 10 : if (!cmp) {
1888 0 : DBG_ERR("next password.nt_hash differs for %s.\n",
1889 : domain);
1890 0 : TALLOC_FREE(stored);
1891 0 : return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1892 : }
1893 :
1894 10 : cmp = mem_equal_const_time(stored->password->nt_hash.hash,
1895 10 : cookie->password->nt_hash.hash,
1896 : 16);
1897 10 : if (!cmp) {
1898 0 : DBG_ERR("password.nt_hash differs for %s.\n",
1899 : domain);
1900 0 : TALLOC_FREE(stored);
1901 0 : return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1902 : }
1903 :
1904 10 : *pstored = stored;
1905 10 : return NT_STATUS_OK;
1906 : }
1907 :
1908 0 : static NTSTATUS secrets_abort_password_change(const char *change_server,
1909 : NTSTATUS local_status,
1910 : NTSTATUS remote_status,
1911 : const struct secrets_domain_info1 *cookie,
1912 : bool defer)
1913 : {
1914 0 : const char *domain = cookie->domain_info.name.string;
1915 0 : TALLOC_CTX *frame = talloc_stackframe();
1916 0 : struct db_context *db = NULL;
1917 0 : struct secrets_domain_info1 *info = NULL;
1918 0 : const char *reason = defer ? "defer_change" : "failed_change";
1919 0 : struct timeval tv = timeval_current();
1920 0 : NTTIME now = timeval_to_nttime(&tv);
1921 0 : NTSTATUS status;
1922 0 : int ret;
1923 :
1924 0 : db = secrets_db_ctx();
1925 :
1926 0 : ret = dbwrap_transaction_start(db);
1927 0 : if (ret != 0) {
1928 0 : DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1929 : domain);
1930 0 : TALLOC_FREE(frame);
1931 0 : return NT_STATUS_INTERNAL_DB_ERROR;
1932 : }
1933 :
1934 : /*
1935 : * secrets_check_password_change()
1936 : * checks that cookie->next_change
1937 : * is valid and the same as store
1938 : * in the database.
1939 : */
1940 0 : status = secrets_check_password_change(cookie, frame, &info);
1941 0 : if (!NT_STATUS_IS_OK(status)) {
1942 0 : DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
1943 0 : dbwrap_transaction_cancel(db);
1944 0 : TALLOC_FREE(frame);
1945 0 : return status;
1946 : }
1947 :
1948 : /*
1949 : * Remember the last server and error.
1950 : */
1951 0 : info->next_change->change_server = change_server;
1952 0 : info->next_change->change_time = now;
1953 0 : info->next_change->local_status = local_status;
1954 0 : info->next_change->remote_status = remote_status;
1955 :
1956 : /*
1957 : * Make sure the next automatic change is deferred.
1958 : */
1959 0 : if (defer) {
1960 0 : info->password_last_change = now;
1961 : }
1962 :
1963 0 : secrets_debug_domain_info(DBGLVL_WARNING, info, reason);
1964 :
1965 0 : status = secrets_store_domain_info(info, false /* upgrade */);
1966 0 : if (!NT_STATUS_IS_OK(status)) {
1967 0 : DBG_ERR("secrets_store_domain_info() failed "
1968 : "for %s - %s\n", domain, nt_errstr(status));
1969 0 : dbwrap_transaction_cancel(db);
1970 0 : TALLOC_FREE(frame);
1971 0 : return status;
1972 : }
1973 :
1974 0 : ret = dbwrap_transaction_commit(db);
1975 0 : if (ret != 0) {
1976 0 : DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1977 : domain);
1978 0 : TALLOC_FREE(frame);
1979 0 : return NT_STATUS_INTERNAL_DB_ERROR;
1980 : }
1981 :
1982 0 : TALLOC_FREE(frame);
1983 0 : return NT_STATUS_OK;
1984 : }
1985 :
1986 0 : NTSTATUS secrets_failed_password_change(const char *change_server,
1987 : NTSTATUS local_status,
1988 : NTSTATUS remote_status,
1989 : const struct secrets_domain_info1 *cookie)
1990 : {
1991 0 : static const bool defer = false;
1992 0 : return secrets_abort_password_change(change_server,
1993 : local_status,
1994 : remote_status,
1995 : cookie, defer);
1996 : }
1997 :
1998 0 : NTSTATUS secrets_defer_password_change(const char *change_server,
1999 : NTSTATUS local_status,
2000 : NTSTATUS remote_status,
2001 : const struct secrets_domain_info1 *cookie)
2002 : {
2003 0 : static const bool defer = true;
2004 0 : return secrets_abort_password_change(change_server,
2005 : local_status,
2006 : remote_status,
2007 : cookie, defer);
2008 : }
2009 :
2010 10 : NTSTATUS secrets_finish_password_change(const char *change_server,
2011 : NTTIME change_time,
2012 : const struct secrets_domain_info1 *cookie)
2013 : {
2014 10 : const char *domain = cookie->domain_info.name.string;
2015 10 : TALLOC_CTX *frame = talloc_stackframe();
2016 10 : struct db_context *db = NULL;
2017 10 : struct secrets_domain_info1 *info = NULL;
2018 10 : struct secrets_domain_info1_change *nc = NULL;
2019 0 : NTSTATUS status;
2020 0 : int ret;
2021 :
2022 10 : db = secrets_db_ctx();
2023 :
2024 10 : ret = dbwrap_transaction_start(db);
2025 10 : if (ret != 0) {
2026 0 : DBG_ERR("dbwrap_transaction_start() failed for %s\n",
2027 : domain);
2028 0 : TALLOC_FREE(frame);
2029 0 : return NT_STATUS_INTERNAL_DB_ERROR;
2030 : }
2031 :
2032 : /*
2033 : * secrets_check_password_change() checks that cookie->next_change is
2034 : * valid and the same as store in the database.
2035 : */
2036 10 : status = secrets_check_password_change(cookie, frame, &info);
2037 10 : if (!NT_STATUS_IS_OK(status)) {
2038 0 : DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
2039 0 : dbwrap_transaction_cancel(db);
2040 0 : TALLOC_FREE(frame);
2041 0 : return status;
2042 : }
2043 :
2044 10 : nc = info->next_change;
2045 :
2046 10 : nc->password->change_server = change_server;
2047 10 : nc->password->change_time = change_time;
2048 :
2049 10 : info->password_last_change = change_time;
2050 10 : info->password_changes += 1;
2051 10 : info->next_change = NULL;
2052 :
2053 10 : info->older_password = info->old_password;
2054 10 : info->old_password = info->password;
2055 10 : info->password = nc->password;
2056 :
2057 10 : secrets_debug_domain_info(DBGLVL_WARNING, info, "finish_change");
2058 :
2059 10 : status = secrets_store_domain_info(info, false /* upgrade */);
2060 10 : if (!NT_STATUS_IS_OK(status)) {
2061 0 : DBG_ERR("secrets_store_domain_info() failed "
2062 : "for %s - %s\n", domain, nt_errstr(status));
2063 0 : dbwrap_transaction_cancel(db);
2064 0 : TALLOC_FREE(frame);
2065 0 : return status;
2066 : }
2067 :
2068 10 : ret = dbwrap_transaction_commit(db);
2069 10 : if (ret != 0) {
2070 0 : DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
2071 : domain);
2072 0 : TALLOC_FREE(frame);
2073 0 : return NT_STATUS_INTERNAL_DB_ERROR;
2074 : }
2075 :
2076 10 : TALLOC_FREE(frame);
2077 10 : return NT_STATUS_OK;
2078 : }
|