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