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