s3:passdb: Fix memory leak caused by recursion of get_global_sam_sid()
[Samba.git] / source3 / passdb / machine_account_secrets.c
blobc97b35e7e5239f7dc38ab6e859d4bf50a82a5388
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
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.
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.
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/>.
22 /* the Samba secrets database stores any generated, private information
23 such as the local SID and machine trust password */
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"
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"
42 #undef DBGC_CLASS
43 #define DBGC_CLASS DBGC_PASSDB
45 static char *domain_info_keystr(const char *domain);
47 static char *des_salt_key(const char *realm);
49 /**
50 * Form a key for fetching the domain sid
52 * @param domain domain name
54 * @return keystring
55 **/
56 static const char *domain_sid_keystr(const char *domain)
58 char *keystr;
60 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
61 SECRETS_DOMAIN_SID, domain);
62 SMB_ASSERT(keystr != NULL);
63 return keystr;
66 static const char *domain_guid_keystr(const char *domain)
68 char *keystr;
70 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
71 SECRETS_DOMAIN_GUID, domain);
72 SMB_ASSERT(keystr != NULL);
73 return keystr;
76 static const char *protect_ids_keystr(const char *domain)
78 char *keystr;
80 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
81 SECRETS_PROTECT_IDS, domain);
82 SMB_ASSERT(keystr != NULL);
83 return keystr;
86 /* N O T E: never use this outside of passdb modules that store the SID on their own */
87 bool secrets_mark_domain_protected(const char *domain)
89 bool ret;
91 ret = secrets_store(protect_ids_keystr(domain), "TRUE", 5);
92 if (!ret) {
93 DEBUG(0, ("Failed to protect the Domain IDs\n"));
95 return ret;
98 bool secrets_clear_domain_protection(const char *domain)
100 bool ret;
101 void *protection = secrets_fetch(protect_ids_keystr(domain), NULL);
103 if (protection) {
104 SAFE_FREE(protection);
105 ret = secrets_delete_entry(protect_ids_keystr(domain));
106 if (!ret) {
107 DEBUG(0, ("Failed to remove Domain IDs protection\n"));
109 return ret;
111 return true;
114 bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
116 char *protect_ids;
117 bool ret;
118 struct dom_sid clean_sid = { 0 };
120 protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
121 if (protect_ids) {
122 if (strncmp(protect_ids, "TRUE", 4)) {
123 DEBUG(0, ("Refusing to store a Domain SID, "
124 "it has been marked as protected!\n"));
125 SAFE_FREE(protect_ids);
126 return false;
129 SAFE_FREE(protect_ids);
132 * use a copy to prevent uninitialized memory from being carried over
133 * to the tdb
135 sid_copy(&clean_sid, sid);
137 ret = secrets_store(domain_sid_keystr(domain),
138 &clean_sid,
139 sizeof(struct dom_sid));
141 /* Force a re-query */
142 if (ret) {
144 * Do not call get_global_domain_sid() here, or we will call it
145 * recursively.
147 reset_global_sam_sid();
149 return ret;
152 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
154 struct dom_sid *dyn_sid;
155 size_t size = 0;
157 dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
159 if (dyn_sid == NULL)
160 return False;
162 if (size != sizeof(struct dom_sid)) {
163 SAFE_FREE(dyn_sid);
164 return False;
167 *sid = *dyn_sid;
168 SAFE_FREE(dyn_sid);
169 return True;
172 bool secrets_store_domain_guid(const char *domain, const struct GUID *guid)
174 char *protect_ids;
175 const char *key;
177 protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
178 if (protect_ids) {
179 if (strncmp(protect_ids, "TRUE", 4)) {
180 DEBUG(0, ("Refusing to store a Domain SID, "
181 "it has been marked as protected!\n"));
182 SAFE_FREE(protect_ids);
183 return false;
186 SAFE_FREE(protect_ids);
188 key = domain_guid_keystr(domain);
189 return secrets_store(key, guid, sizeof(struct GUID));
192 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
194 struct GUID *dyn_guid;
195 const char *key;
196 size_t size = 0;
197 struct GUID new_guid;
199 key = domain_guid_keystr(domain);
200 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
202 if (!dyn_guid) {
203 if (lp_server_role() == ROLE_DOMAIN_PDC ||
204 lp_server_role() == ROLE_IPA_DC) {
205 new_guid = GUID_random();
206 if (!secrets_store_domain_guid(domain, &new_guid))
207 return False;
208 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
210 if (dyn_guid == NULL) {
211 return False;
215 if (size != sizeof(struct GUID)) {
216 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
217 SAFE_FREE(dyn_guid);
218 return False;
221 *guid = *dyn_guid;
222 SAFE_FREE(dyn_guid);
223 return True;
227 * Form a key for fetching the machine trust account sec channel type
229 * @param domain domain name
231 * @return keystring
233 static const char *machine_sec_channel_type_keystr(const char *domain)
235 char *keystr;
237 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
238 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
239 domain);
240 SMB_ASSERT(keystr != NULL);
241 return keystr;
245 * Form a key for fetching the machine trust account last change time
247 * @param domain domain name
249 * @return keystring
251 static const char *machine_last_change_time_keystr(const char *domain)
253 char *keystr;
255 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
256 SECRETS_MACHINE_LAST_CHANGE_TIME,
257 domain);
258 SMB_ASSERT(keystr != NULL);
259 return keystr;
264 * Form a key for fetching the machine previous trust account password
266 * @param domain domain name
268 * @return keystring
270 static const char *machine_prev_password_keystr(const char *domain)
272 char *keystr;
274 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
275 SECRETS_MACHINE_PASSWORD_PREV, domain);
276 SMB_ASSERT(keystr != NULL);
277 return keystr;
281 * Form a key for fetching the machine trust account password
283 * @param domain domain name
285 * @return keystring
287 static const char *machine_password_keystr(const char *domain)
289 char *keystr;
291 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
292 SECRETS_MACHINE_PASSWORD, domain);
293 SMB_ASSERT(keystr != NULL);
294 return keystr;
298 * Form a key for fetching the machine trust account password
300 * @param domain domain name
302 * @return stored password's key
304 static const char *trust_keystr(const char *domain)
306 char *keystr;
308 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
309 SECRETS_MACHINE_ACCT_PASS, domain);
310 SMB_ASSERT(keystr != NULL);
311 return keystr;
314 /************************************************************************
315 Routine to get the default secure channel type for trust accounts
316 ************************************************************************/
318 enum netr_SchannelType get_default_sec_channel(void)
320 if (IS_DC) {
321 return SEC_CHAN_BDC;
322 } else {
323 return SEC_CHAN_WKSTA;
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 ************************************************************************/
334 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)
339 struct machine_acct_pass *pass;
340 size_t size = 0;
342 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
343 trust_keystr(domain), &size))) {
344 DEBUG(5, ("secrets_fetch failed!\n"));
345 return False;
348 if (size != sizeof(*pass)) {
349 DEBUG(0, ("secrets were of incorrect size!\n"));
350 BURN_FREE(pass, size);
351 return False;
354 if (pass_last_set_time) {
355 *pass_last_set_time = pass->mod_time;
357 memcpy(ret_pwd, pass->hash, 16);
359 if (channel) {
360 *channel = get_default_sec_channel();
363 BURN_FREE(pass, size);
364 return True;
367 /************************************************************************
368 Routine to delete all information related to the domain joined machine.
369 ************************************************************************/
371 bool secrets_delete_machine_password_ex(const char *domain, const char *realm)
373 const char *tmpkey = NULL;
374 bool ok;
376 tmpkey = domain_info_keystr(domain);
377 ok = secrets_delete(tmpkey);
378 if (!ok) {
379 return false;
382 if (realm != NULL) {
383 tmpkey = des_salt_key(domain);
384 ok = secrets_delete(tmpkey);
385 if (!ok) {
386 return false;
390 tmpkey = domain_guid_keystr(domain);
391 ok = secrets_delete(tmpkey);
392 if (!ok) {
393 return false;
396 tmpkey = machine_prev_password_keystr(domain);
397 ok = secrets_delete(tmpkey);
398 if (!ok) {
399 return false;
402 tmpkey = machine_password_keystr(domain);
403 ok = secrets_delete(tmpkey);
404 if (!ok) {
405 return false;
408 tmpkey = machine_sec_channel_type_keystr(domain);
409 ok = secrets_delete(tmpkey);
410 if (!ok) {
411 return false;
414 tmpkey = machine_last_change_time_keystr(domain);
415 ok = secrets_delete(tmpkey);
416 if (!ok) {
417 return false;
420 tmpkey = domain_sid_keystr(domain);
421 ok = secrets_delete(tmpkey);
422 if (!ok) {
423 return false;
426 return true;
429 /************************************************************************
430 Routine to delete the domain sid
431 ************************************************************************/
433 bool secrets_delete_domain_sid(const char *domain)
435 return secrets_delete_entry(domain_sid_keystr(domain));
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 ************************************************************************/
444 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)
451 bool ret;
452 uint8_t last_change_time_store[4];
453 TALLOC_CTX *frame = talloc_stackframe();
454 uint8_t sec_channel_bytes[4];
456 if (delete_join) {
457 secrets_delete_machine_password_ex(domain, realm);
458 TALLOC_FREE(frame);
459 return true;
462 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
463 if (!ret) {
464 TALLOC_FREE(frame);
465 return ret;
468 if (oldpass) {
469 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
470 } else {
471 ret = secrets_delete(machine_prev_password_keystr(domain));
473 if (!ret) {
474 TALLOC_FREE(frame);
475 return ret;
478 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 ret = secrets_delete(machine_sec_channel_type_keystr(domain));
483 if (!ret) {
484 TALLOC_FREE(frame);
485 return ret;
487 } else {
488 SIVAL(&sec_channel_bytes, 0, secure_channel_type);
489 ret = secrets_store(machine_sec_channel_type_keystr(domain),
490 &sec_channel_bytes, sizeof(sec_channel_bytes));
491 if (!ret) {
492 TALLOC_FREE(frame);
493 return ret;
497 SIVAL(&last_change_time_store, 0, last_change_time);
498 ret = secrets_store(machine_last_change_time_keystr(domain),
499 &last_change_time_store, sizeof(last_change_time));
501 if (!ret) {
502 TALLOC_FREE(frame);
503 return ret;
506 ret = secrets_store_domain_sid(domain, domain_sid);
508 if (!ret) {
509 TALLOC_FREE(frame);
510 return ret;
513 if (realm != NULL) {
514 char *key = des_salt_key(realm);
516 if (salting_principal != NULL) {
517 ret = secrets_store(key,
518 salting_principal,
519 strlen(salting_principal)+1);
520 } else {
521 ret = secrets_delete(key);
525 TALLOC_FREE(frame);
526 return ret;
529 /************************************************************************
530 Return the standard DES salt key
531 ************************************************************************/
533 char* kerberos_standard_des_salt( void )
535 fstring salt;
537 fstr_sprintf( salt, "host/%s.%s@", lp_netbios_name(), lp_realm() );
538 (void)strlower_m( salt );
539 fstrcat( salt, lp_realm() );
541 return SMB_STRDUP( salt );
544 /************************************************************************
545 ************************************************************************/
547 static char *des_salt_key(const char *realm)
549 char *keystr;
551 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/DES/%s",
552 SECRETS_SALTING_PRINCIPAL,
553 realm);
554 SMB_ASSERT(keystr != NULL);
555 return keystr;
558 /************************************************************************
559 ************************************************************************/
561 bool kerberos_secrets_store_des_salt( const char* salt )
563 char* key;
564 bool ret;
566 key = des_salt_key(lp_realm());
567 if (key == NULL) {
568 DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n"));
569 return False;
572 if ( !salt ) {
573 DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n"));
574 secrets_delete_entry( key );
575 return True;
578 DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt));
580 ret = secrets_store( key, salt, strlen(salt)+1 );
582 TALLOC_FREE(key);
584 return ret;
587 /************************************************************************
588 ************************************************************************/
590 static
591 char* kerberos_secrets_fetch_des_salt( void )
593 char *salt, *key;
595 key = des_salt_key(lp_realm());
596 if (key == NULL) {
597 DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
598 return NULL;
601 salt = (char*)secrets_fetch( key, NULL );
603 TALLOC_FREE(key);
605 return salt;
608 /************************************************************************
609 Routine to get the salting principal for this service.
610 Caller must free if return is not null.
611 ************************************************************************/
613 char *kerberos_secrets_fetch_salt_princ(void)
615 char *salt_princ_s;
616 /* lookup new key first */
618 salt_princ_s = kerberos_secrets_fetch_des_salt();
619 if (salt_princ_s == NULL) {
620 /* fall back to host/machine.realm@REALM */
621 salt_princ_s = kerberos_standard_des_salt();
624 return salt_princ_s;
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 ************************************************************************/
632 char *secrets_fetch_prev_machine_password(const char *domain)
634 return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
637 /************************************************************************
638 Routine to fetch the last change time of the machine account password
639 for a realm
640 ************************************************************************/
642 time_t secrets_fetch_pass_last_set_time(const char *domain)
644 uint32_t *last_set_time;
645 time_t pass_last_set_time;
647 last_set_time = secrets_fetch(machine_last_change_time_keystr(domain),
648 NULL);
649 if (last_set_time) {
650 pass_last_set_time = IVAL(last_set_time,0);
651 SAFE_FREE(last_set_time);
652 } else {
653 pass_last_set_time = 0;
656 return pass_last_set_time;
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 ************************************************************************/
664 char *secrets_fetch_machine_password(const char *domain,
665 time_t *pass_last_set_time,
666 enum netr_SchannelType *channel)
668 char *ret;
669 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
671 if (pass_last_set_time) {
672 *pass_last_set_time = secrets_fetch_pass_last_set_time(domain);
675 if (channel) {
676 size_t size;
677 uint32_t *channel_type;
678 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
679 if (channel_type) {
680 *channel = IVAL(channel_type,0);
681 SAFE_FREE(channel_type);
682 } else {
683 *channel = get_default_sec_channel();
687 return ret;
690 static int password_nt_hash_destructor(struct secrets_domain_info1_password *pw)
692 ZERO_STRUCT(pw->nt_hash);
694 return 0;
697 static int setup_password_zeroing(struct secrets_domain_info1_password *pw)
699 if (pw != NULL) {
700 size_t i;
702 talloc_keep_secret(pw->cleartext_blob.data);
703 talloc_set_destructor(pw, password_nt_hash_destructor);
704 for (i = 0; i < pw->num_keys; i++) {
705 talloc_keep_secret(pw->keys[i].value.data);
709 return 0;
712 static char *domain_info_keystr(const char *domain)
714 char *keystr;
716 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
717 SECRETS_MACHINE_DOMAIN_INFO,
718 domain);
719 SMB_ASSERT(keystr != NULL);
720 return keystr;
723 /************************************************************************
724 Routine to get account password to trusted domain
725 ************************************************************************/
727 static NTSTATUS secrets_fetch_domain_info1_by_key(const char *key,
728 TALLOC_CTX *mem_ctx,
729 struct secrets_domain_info1 **_info1)
731 struct secrets_domain_infoB sdib = { .version = 0, };
732 enum ndr_err_code ndr_err;
733 /* unpacking structures */
734 DATA_BLOB blob;
736 /* fetching trusted domain password structure */
737 blob.data = (uint8_t *)secrets_fetch(key, &blob.length);
738 if (blob.data == NULL) {
739 DBG_NOTICE("secrets_fetch failed!\n");
740 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
743 /* unpack trusted domain password */
744 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sdib,
745 (ndr_pull_flags_fn_t)ndr_pull_secrets_domain_infoB);
746 BURN_FREE(blob.data, blob.length);
747 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
748 DBG_ERR("ndr_pull_struct_blob failed - %s!\n",
749 ndr_errstr(ndr_err));
750 return NT_STATUS_INTERNAL_DB_CORRUPTION;
753 if (sdib.info.info1->next_change != NULL) {
754 setup_password_zeroing(sdib.info.info1->next_change->password);
756 setup_password_zeroing(sdib.info.info1->password);
757 setup_password_zeroing(sdib.info.info1->old_password);
758 setup_password_zeroing(sdib.info.info1->older_password);
760 if (sdib.version != SECRETS_DOMAIN_INFO_VERSION_1) {
761 DBG_ERR("sdib.version = %u\n", (unsigned)sdib.version);
762 return NT_STATUS_INTERNAL_DB_CORRUPTION;
765 *_info1 = sdib.info.info1;
766 return NT_STATUS_OK;;
769 static NTSTATUS secrets_fetch_domain_info(const char *domain,
770 TALLOC_CTX *mem_ctx,
771 struct secrets_domain_info1 **pinfo)
773 char *key = domain_info_keystr(domain);
774 return secrets_fetch_domain_info1_by_key(key, mem_ctx, pinfo);
777 void secrets_debug_domain_info(int lvl, const struct secrets_domain_info1 *info1,
778 const char *name)
780 struct secrets_domain_infoB sdib = {
781 .version = SECRETS_DOMAIN_INFO_VERSION_1,
784 sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
786 NDR_PRINT_DEBUG_LEVEL(lvl, secrets_domain_infoB, &sdib);
789 char *secrets_domain_info_string(TALLOC_CTX *mem_ctx, const struct secrets_domain_info1 *info1,
790 const char *name, bool include_secrets)
792 TALLOC_CTX *frame = talloc_stackframe();
793 struct secrets_domain_infoB sdib = {
794 .version = SECRETS_DOMAIN_INFO_VERSION_1,
796 struct ndr_print *ndr = NULL;
797 char *ret = NULL;
799 sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
801 ndr = talloc_zero(frame, struct ndr_print);
802 if (ndr == NULL) {
803 TALLOC_FREE(frame);
804 return NULL;
806 ndr->private_data = talloc_strdup(ndr, "");
807 if (ndr->private_data == NULL) {
808 TALLOC_FREE(frame);
809 return NULL;
811 ndr->print = ndr_print_string_helper;
812 ndr->depth = 1;
813 ndr->print_secrets = include_secrets;
815 ndr_print_secrets_domain_infoB(ndr, name, &sdib);
816 ret = talloc_steal(mem_ctx, (char *)ndr->private_data);
817 TALLOC_FREE(frame);
818 return ret;
821 static NTSTATUS secrets_store_domain_info1_by_key(const char *key,
822 const struct secrets_domain_info1 *info1)
824 struct secrets_domain_infoB sdib = {
825 .version = SECRETS_DOMAIN_INFO_VERSION_1,
827 /* packing structures */
828 DATA_BLOB blob;
829 enum ndr_err_code ndr_err;
830 bool ok;
832 sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
834 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &sdib,
835 (ndr_push_flags_fn_t)ndr_push_secrets_domain_infoB);
836 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
837 return ndr_map_error2ntstatus(ndr_err);
840 ok = secrets_store(key, blob.data, blob.length);
841 data_blob_clear_free(&blob);
842 if (!ok) {
843 return NT_STATUS_INTERNAL_DB_ERROR;
846 return NT_STATUS_OK;
849 static NTSTATUS secrets_store_domain_info(const struct secrets_domain_info1 *info,
850 bool upgrade)
852 TALLOC_CTX *frame = talloc_stackframe();
853 const char *domain = info->domain_info.name.string;
854 const char *realm = info->domain_info.dns_domain.string;
855 char *key = domain_info_keystr(domain);
856 struct db_context *db = NULL;
857 struct timeval last_change_tv;
858 const DATA_BLOB *cleartext_blob = NULL;
859 DATA_BLOB pw_blob = data_blob_null;
860 DATA_BLOB old_pw_blob = data_blob_null;
861 const char *pw = NULL;
862 const char *old_pw = NULL;
863 bool ok;
864 NTSTATUS status;
865 int ret;
866 int role = lp_server_role();
868 switch (info->secure_channel_type) {
869 case SEC_CHAN_WKSTA:
870 case SEC_CHAN_BDC:
871 if (!upgrade && role >= ROLE_ACTIVE_DIRECTORY_DC) {
872 DBG_ERR("AD_DC not supported for %s\n",
873 domain);
874 TALLOC_FREE(frame);
875 return NT_STATUS_INTERNAL_ERROR;
878 break;
879 default:
880 DBG_ERR("SEC_CHAN_* not supported for %s\n",
881 domain);
882 TALLOC_FREE(frame);
883 return NT_STATUS_INTERNAL_ERROR;
886 db = secrets_db_ctx();
888 ret = dbwrap_transaction_start(db);
889 if (ret != 0) {
890 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
891 domain);
892 TALLOC_FREE(frame);
893 return NT_STATUS_INTERNAL_DB_ERROR;
896 ok = secrets_clear_domain_protection(domain);
897 if (!ok) {
898 DBG_ERR("secrets_clear_domain_protection(%s) failed\n",
899 domain);
900 dbwrap_transaction_cancel(db);
901 TALLOC_FREE(frame);
902 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
905 ok = secrets_delete_machine_password_ex(domain, realm);
906 if (!ok) {
907 DBG_ERR("secrets_delete_machine_password_ex(%s) failed\n",
908 domain);
909 dbwrap_transaction_cancel(db);
910 TALLOC_FREE(frame);
911 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
914 status = secrets_store_domain_info1_by_key(key, info);
915 if (!NT_STATUS_IS_OK(status)) {
916 DBG_ERR("secrets_store_domain_info1_by_key() failed "
917 "for %s - %s\n", domain, nt_errstr(status));
918 dbwrap_transaction_cancel(db);
919 TALLOC_FREE(frame);
920 return status;
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.
930 nttime_to_timeval(&last_change_tv, info->password_last_change);
932 cleartext_blob = &info->password->cleartext_blob;
933 ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
934 cleartext_blob->data,
935 cleartext_blob->length,
936 (void **)&pw_blob.data,
937 &pw_blob.length);
938 if (!ok) {
939 status = NT_STATUS_UNMAPPABLE_CHARACTER;
940 if (errno == ENOMEM) {
941 status = NT_STATUS_NO_MEMORY;
943 DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
944 "failed for pw of %s - %s\n",
945 domain, nt_errstr(status));
946 dbwrap_transaction_cancel(db);
947 TALLOC_FREE(frame);
948 return status;
950 pw = (const char *)pw_blob.data;
951 if (info->old_password != NULL) {
952 cleartext_blob = &info->old_password->cleartext_blob;
953 ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
954 cleartext_blob->data,
955 cleartext_blob->length,
956 (void **)&old_pw_blob.data,
957 &old_pw_blob.length);
958 if (!ok) {
959 status = NT_STATUS_UNMAPPABLE_CHARACTER;
960 if (errno == ENOMEM) {
961 status = NT_STATUS_NO_MEMORY;
963 DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
964 "failed for old_pw of %s - %s\n",
965 domain, nt_errstr(status));
966 dbwrap_transaction_cancel(db);
967 data_blob_clear_free(&pw_blob);
968 TALLOC_FREE(frame);
969 return status;
971 old_pw = (const char *)old_pw_blob.data;
974 ok = secrets_store_machine_pw_sync(pw, old_pw,
975 domain, realm,
976 info->salt_principal,
977 info->supported_enc_types,
978 info->domain_info.sid,
979 last_change_tv.tv_sec,
980 info->secure_channel_type,
981 false); /* delete_join */
982 data_blob_clear_free(&pw_blob);
983 data_blob_clear_free(&old_pw_blob);
984 if (!ok) {
985 DBG_ERR("secrets_store_machine_pw_sync(%s) failed\n",
986 domain);
987 dbwrap_transaction_cancel(db);
988 TALLOC_FREE(frame);
989 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
992 if (!GUID_all_zero(&info->domain_info.domain_guid)) {
993 ok = secrets_store_domain_guid(domain,
994 &info->domain_info.domain_guid);
995 if (!ok) {
996 DBG_ERR("secrets_store_domain_guid(%s) failed\n",
997 domain);
998 dbwrap_transaction_cancel(db);
999 TALLOC_FREE(frame);
1000 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1004 ok = secrets_mark_domain_protected(domain);
1005 if (!ok) {
1006 DBG_ERR("secrets_mark_domain_protected(%s) failed\n",
1007 domain);
1008 dbwrap_transaction_cancel(db);
1009 TALLOC_FREE(frame);
1010 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1013 ret = dbwrap_transaction_commit(db);
1014 if (ret != 0) {
1015 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1016 domain);
1017 TALLOC_FREE(frame);
1018 return NT_STATUS_INTERNAL_DB_ERROR;
1021 TALLOC_FREE(frame);
1022 return NT_STATUS_OK;
1025 static int secrets_domain_info_kerberos_keys(struct secrets_domain_info1_password *p,
1026 const char *salt_principal)
1028 #ifdef HAVE_ADS
1029 krb5_error_code krb5_ret;
1030 krb5_context krb5_ctx = NULL;
1031 DATA_BLOB cleartext_utf8_b = data_blob_null;
1032 krb5_data cleartext_utf8;
1033 krb5_data salt;
1034 krb5_keyblock key;
1035 DATA_BLOB aes_256_b = data_blob_null;
1036 DATA_BLOB aes_128_b = data_blob_null;
1037 bool ok;
1038 #endif /* HAVE_ADS */
1039 DATA_BLOB arc4_b = data_blob_null;
1040 const uint16_t max_keys = 4;
1041 struct secrets_domain_info1_kerberos_key *keys = NULL;
1042 uint16_t idx = 0;
1043 char *salt_data = NULL;
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
1052 * We don't include ENCTYPE_DES_CBC_CRC
1053 * as W2008R2 also doesn't store it anymore.
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.
1060 * Which values are then used to construct
1061 * a keytab is configured at runtime and the
1062 * configuration of msDS-SupportedEncryptionTypes.
1064 * If we don't have kerberos support or no
1065 * salt, we only generate an entry for arcfour-hmac-md5.
1067 keys = talloc_zero_array(p,
1068 struct secrets_domain_info1_kerberos_key,
1069 max_keys);
1070 if (keys == NULL) {
1071 return ENOMEM;
1074 arc4_b = data_blob_talloc(keys,
1075 p->nt_hash.hash,
1076 sizeof(p->nt_hash.hash));
1077 if (arc4_b.data == NULL) {
1078 DBG_ERR("data_blob_talloc failed for arcfour-hmac-md5.\n");
1079 TALLOC_FREE(keys);
1080 return ENOMEM;
1082 talloc_keep_secret(arc4_b.data);
1084 #ifdef HAVE_ADS
1085 if (salt_principal == NULL) {
1086 goto no_kerberos;
1089 krb5_ret = smb_krb5_init_context_common(&krb5_ctx);
1090 if (krb5_ret != 0) {
1091 DBG_ERR("kerberos init context failed (%s)\n",
1092 error_message(krb5_ret));
1093 TALLOC_FREE(keys);
1094 return krb5_ret;
1097 krb5_ret = smb_krb5_salt_principal2data(krb5_ctx, salt_principal,
1098 p, &salt_data);
1099 if (krb5_ret != 0) {
1100 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 krb5_free_context(krb5_ctx);
1104 TALLOC_FREE(keys);
1105 return krb5_ret;
1108 salt = (krb5_data) {
1109 .data = discard_const(salt_data),
1110 .length = strlen(salt_data),
1113 ok = convert_string_talloc(keys, CH_UTF16MUNGED, CH_UTF8,
1114 p->cleartext_blob.data,
1115 p->cleartext_blob.length,
1116 (void **)&cleartext_utf8_b.data,
1117 &cleartext_utf8_b.length);
1118 if (!ok) {
1119 if (errno != 0) {
1120 krb5_ret = errno;
1121 } else {
1122 krb5_ret = EINVAL;
1124 krb5_free_context(krb5_ctx);
1125 TALLOC_FREE(keys);
1126 return krb5_ret;
1128 talloc_keep_secret(cleartext_utf8_b.data);
1129 cleartext_utf8.data = (void *)cleartext_utf8_b.data;
1130 cleartext_utf8.length = cleartext_utf8_b.length;
1132 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 if (krb5_ret != 0) {
1139 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 krb5_free_context(krb5_ctx);
1142 TALLOC_FREE(keys);
1143 TALLOC_FREE(salt_data);
1144 return krb5_ret;
1146 aes_256_b = data_blob_talloc(keys,
1147 KRB5_KEY_DATA(&key),
1148 KRB5_KEY_LENGTH(&key));
1149 krb5_free_keyblock_contents(krb5_ctx, &key);
1150 if (aes_256_b.data == NULL) {
1151 DBG_ERR("data_blob_talloc failed for aes-256.\n");
1152 krb5_free_context(krb5_ctx);
1153 TALLOC_FREE(keys);
1154 TALLOC_FREE(salt_data);
1155 return ENOMEM;
1157 talloc_keep_secret(aes_256_b.data);
1159 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 if (krb5_ret != 0) {
1166 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 krb5_free_context(krb5_ctx);
1169 TALLOC_FREE(keys);
1170 TALLOC_FREE(salt_data);
1171 return krb5_ret;
1173 aes_128_b = data_blob_talloc(keys,
1174 KRB5_KEY_DATA(&key),
1175 KRB5_KEY_LENGTH(&key));
1176 krb5_free_keyblock_contents(krb5_ctx, &key);
1177 if (aes_128_b.data == NULL) {
1178 DBG_ERR("data_blob_talloc failed for aes-128.\n");
1179 krb5_free_context(krb5_ctx);
1180 TALLOC_FREE(keys);
1181 TALLOC_FREE(salt_data);
1182 return ENOMEM;
1184 talloc_keep_secret(aes_128_b.data);
1186 krb5_free_context(krb5_ctx);
1187 no_kerberos:
1189 if (aes_256_b.length != 0) {
1190 keys[idx].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
1191 keys[idx].iteration_count = 4096;
1192 keys[idx].value = aes_256_b;
1193 idx += 1;
1196 if (aes_128_b.length != 0) {
1197 keys[idx].keytype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
1198 keys[idx].iteration_count = 4096;
1199 keys[idx].value = aes_128_b;
1200 idx += 1;
1203 #endif /* HAVE_ADS */
1205 keys[idx].keytype = ENCTYPE_ARCFOUR_HMAC;
1206 keys[idx].iteration_count = 4096;
1207 keys[idx].value = arc4_b;
1208 idx += 1;
1210 p->salt_data = salt_data;
1211 p->default_iteration_count = 4096;
1212 p->num_keys = idx;
1213 p->keys = keys;
1214 return 0;
1217 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)
1224 struct secrets_domain_info1_password *p = NULL;
1225 bool ok;
1226 size_t len;
1227 int ret;
1229 if (change_server == NULL) {
1230 return NT_STATUS_INVALID_PARAMETER_MIX;
1233 p = talloc_zero(mem_ctx, struct secrets_domain_info1_password);
1234 if (p == NULL) {
1235 return NT_STATUS_NO_MEMORY;
1237 p->change_time = change_time;
1238 p->change_server = talloc_strdup(p, change_server);
1239 if (p->change_server == NULL) {
1240 TALLOC_FREE(p);
1241 return NT_STATUS_NO_MEMORY;
1243 len = strlen(cleartext_unix);
1244 ok = convert_string_talloc(p, CH_UNIX, CH_UTF16,
1245 cleartext_unix, len,
1246 (void **)&p->cleartext_blob.data,
1247 &p->cleartext_blob.length);
1248 if (!ok) {
1249 NTSTATUS status = NT_STATUS_UNMAPPABLE_CHARACTER;
1250 if (errno == ENOMEM) {
1251 status = NT_STATUS_NO_MEMORY;
1253 TALLOC_FREE(p);
1254 return status;
1256 talloc_keep_secret(p->cleartext_blob.data);
1257 mdfour(p->nt_hash.hash,
1258 p->cleartext_blob.data,
1259 p->cleartext_blob.length);
1261 talloc_set_destructor(p, password_nt_hash_destructor);
1262 ret = secrets_domain_info_kerberos_keys(p, salt_principal);
1263 if (ret != 0) {
1264 NTSTATUS status = krb5_to_nt_status(ret);
1265 TALLOC_FREE(p);
1266 return status;
1269 *_p = p;
1270 return NT_STATUS_OK;
1273 NTSTATUS secrets_fetch_or_upgrade_domain_info(const char *domain,
1274 TALLOC_CTX *mem_ctx,
1275 struct secrets_domain_info1 **pinfo)
1277 TALLOC_CTX *frame = NULL;
1278 struct secrets_domain_info1 *old = NULL;
1279 struct secrets_domain_info1 *info = NULL;
1280 const char *dns_domain = NULL;
1281 const char *server = NULL;
1282 struct db_context *db = NULL;
1283 time_t last_set_time;
1284 NTTIME last_set_nt;
1285 enum netr_SchannelType channel;
1286 char *pw = NULL;
1287 char *old_pw = NULL;
1288 struct dom_sid domain_sid;
1289 struct GUID domain_guid;
1290 bool ok;
1291 NTSTATUS status;
1292 int ret;
1294 ok = strequal(domain, lp_workgroup());
1295 if (ok) {
1296 dns_domain = lp_dnsdomain();
1298 if (dns_domain != NULL && dns_domain[0] == '\0') {
1299 dns_domain = NULL;
1303 last_set_time = secrets_fetch_pass_last_set_time(domain);
1304 if (last_set_time == 0) {
1305 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1307 unix_to_nt_time(&last_set_nt, last_set_time);
1309 frame = talloc_stackframe();
1311 status = secrets_fetch_domain_info(domain, frame, &old);
1312 if (NT_STATUS_IS_OK(status)) {
1313 if (old->password_last_change >= last_set_nt) {
1314 *pinfo = talloc_move(mem_ctx, &old);
1315 TALLOC_FREE(frame);
1316 return NT_STATUS_OK;
1318 TALLOC_FREE(old);
1321 info = talloc_zero(frame, struct secrets_domain_info1);
1322 if (info == NULL) {
1323 DBG_ERR("talloc_zero failed\n");
1324 TALLOC_FREE(frame);
1325 return NT_STATUS_NO_MEMORY;
1328 db = secrets_db_ctx();
1330 ret = dbwrap_transaction_start(db);
1331 if (ret != 0) {
1332 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1333 domain);
1334 TALLOC_FREE(frame);
1335 return NT_STATUS_INTERNAL_DB_ERROR;
1338 pw = secrets_fetch_machine_password(domain,
1339 &last_set_time,
1340 &channel);
1341 if (pw == NULL) {
1342 DBG_ERR("secrets_fetch_machine_password(%s) failed\n",
1343 domain);
1344 dbwrap_transaction_cancel(db);
1345 TALLOC_FREE(frame);
1346 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1348 unix_to_nt_time(&last_set_nt, last_set_time);
1350 old_pw = secrets_fetch_prev_machine_password(domain);
1352 ok = secrets_fetch_domain_sid(domain, &domain_sid);
1353 if (!ok) {
1354 DBG_ERR("secrets_fetch_domain_sid(%s) failed\n",
1355 domain);
1356 dbwrap_transaction_cancel(db);
1357 BURN_FREE_STR(old_pw);
1358 BURN_FREE_STR(pw);
1359 TALLOC_FREE(frame);
1360 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1363 ok = secrets_fetch_domain_guid(domain, &domain_guid);
1364 if (!ok) {
1365 domain_guid = GUID_zero();
1368 info->computer_name = lp_netbios_name();
1369 info->account_name = talloc_asprintf(frame, "%s$", info->computer_name);
1370 if (info->account_name == NULL) {
1371 DBG_ERR("talloc_asprintf(%s$) failed\n", info->computer_name);
1372 dbwrap_transaction_cancel(db);
1373 BURN_FREE_STR(old_pw);
1374 BURN_FREE_STR(pw);
1375 TALLOC_FREE(frame);
1376 return NT_STATUS_NO_MEMORY;
1378 info->secure_channel_type = channel;
1380 info->domain_info.name.string = domain;
1381 info->domain_info.dns_domain.string = dns_domain;
1382 info->domain_info.dns_forest.string = dns_domain;
1383 info->domain_info.domain_guid = domain_guid;
1384 info->domain_info.sid = &domain_sid;
1386 info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
1387 info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1389 if (dns_domain != NULL) {
1391 * We just assume all AD domains are
1392 * NETR_TRUST_FLAG_NATIVE these days.
1394 * This isn't used anyway for now.
1396 info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
1398 info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
1400 server = info->domain_info.dns_domain.string;
1401 } else {
1402 info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1404 server = talloc_asprintf(info,
1405 "%s#%02X",
1406 domain,
1407 NBT_NAME_PDC);
1408 if (server == NULL) {
1409 DBG_ERR("talloc_asprintf(%s#%02X) failed\n",
1410 domain, NBT_NAME_PDC);
1411 dbwrap_transaction_cancel(db);
1412 BURN_FREE_STR(pw);
1413 BURN_FREE_STR(old_pw);
1414 TALLOC_FREE(frame);
1415 return NT_STATUS_NO_MEMORY;
1418 info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
1420 info->join_time = 0;
1423 * We don't have enough information about the configured
1424 * enctypes.
1426 info->supported_enc_types = 0;
1427 info->salt_principal = NULL;
1428 if (info->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
1429 char *p = NULL;
1431 p = kerberos_secrets_fetch_salt_princ();
1432 if (p == NULL) {
1433 dbwrap_transaction_cancel(db);
1434 BURN_FREE_STR(old_pw);
1435 BURN_FREE_STR(pw);
1436 TALLOC_FREE(frame);
1437 return NT_STATUS_INTERNAL_ERROR;
1439 info->salt_principal = talloc_strdup(info, p);
1440 SAFE_FREE(p);
1441 if (info->salt_principal == NULL) {
1442 dbwrap_transaction_cancel(db);
1443 BURN_FREE_STR(pw);
1444 BURN_FREE_STR(old_pw);
1445 TALLOC_FREE(frame);
1446 return NT_STATUS_NO_MEMORY;
1450 info->password_last_change = last_set_nt;
1451 info->password_changes = 1;
1452 info->next_change = NULL;
1454 status = secrets_domain_info_password_create(info,
1456 info->salt_principal,
1457 last_set_nt, server,
1458 &info->password);
1459 BURN_FREE_STR(pw);
1460 if (!NT_STATUS_IS_OK(status)) {
1461 DBG_ERR("secrets_domain_info_password_create(pw) failed "
1462 "for %s - %s\n", domain, nt_errstr(status));
1463 dbwrap_transaction_cancel(db);
1464 BURN_FREE_STR(old_pw);
1465 TALLOC_FREE(frame);
1466 return status;
1470 * After a join we don't have old passwords.
1472 if (old_pw != NULL) {
1473 status = secrets_domain_info_password_create(info,
1474 old_pw,
1475 info->salt_principal,
1476 0, server,
1477 &info->old_password);
1478 BURN_FREE_STR(old_pw);
1479 if (!NT_STATUS_IS_OK(status)) {
1480 DBG_ERR("secrets_domain_info_password_create(old) failed "
1481 "for %s - %s\n", domain, nt_errstr(status));
1482 dbwrap_transaction_cancel(db);
1483 TALLOC_FREE(frame);
1484 return status;
1486 info->password_changes += 1;
1487 } else {
1488 info->old_password = NULL;
1490 info->older_password = NULL;
1492 secrets_debug_domain_info(DBGLVL_INFO, info, "upgrade");
1494 status = secrets_store_domain_info(info, true /* upgrade */);
1495 if (!NT_STATUS_IS_OK(status)) {
1496 DBG_ERR("secrets_store_domain_info() failed "
1497 "for %s - %s\n", domain, nt_errstr(status));
1498 dbwrap_transaction_cancel(db);
1499 TALLOC_FREE(frame);
1500 return status;
1504 * We now reparse it.
1506 status = secrets_fetch_domain_info(domain, frame, &info);
1507 if (!NT_STATUS_IS_OK(status)) {
1508 DBG_ERR("secrets_fetch_domain_info() failed "
1509 "for %s - %s\n", domain, nt_errstr(status));
1510 dbwrap_transaction_cancel(db);
1511 TALLOC_FREE(frame);
1512 return status;
1515 ret = dbwrap_transaction_commit(db);
1516 if (ret != 0) {
1517 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1518 domain);
1519 dbwrap_transaction_cancel(db);
1520 TALLOC_FREE(frame);
1521 return NT_STATUS_INTERNAL_DB_ERROR;
1524 *pinfo = talloc_move(mem_ctx, &info);
1525 TALLOC_FREE(frame);
1526 return NT_STATUS_OK;
1529 NTSTATUS secrets_store_JoinCtx(const struct libnet_JoinCtx *r)
1531 TALLOC_CTX *frame = talloc_stackframe();
1532 struct secrets_domain_info1 *old = NULL;
1533 struct secrets_domain_info1 *info = NULL;
1534 struct db_context *db = NULL;
1535 struct timeval tv = timeval_current();
1536 NTTIME now = timeval_to_nttime(&tv);
1537 const char *domain = r->out.netbios_domain_name;
1538 NTSTATUS status;
1539 int ret;
1541 info = talloc_zero(frame, struct secrets_domain_info1);
1542 if (info == NULL) {
1543 DBG_ERR("talloc_zero failed\n");
1544 TALLOC_FREE(frame);
1545 return NT_STATUS_NO_MEMORY;
1548 info->computer_name = r->in.machine_name;
1549 info->account_name = r->out.account_name;
1550 info->secure_channel_type = r->in.secure_channel_type;
1552 info->domain_info.name.string =
1553 r->out.netbios_domain_name;
1554 info->domain_info.dns_domain.string =
1555 r->out.dns_domain_name;
1556 info->domain_info.dns_forest.string =
1557 r->out.forest_name;
1558 info->domain_info.domain_guid = r->out.domain_guid;
1559 info->domain_info.sid = r->out.domain_sid;
1561 info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
1562 info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1563 if (r->out.domain_is_ad) {
1565 * We just assume all AD domains are
1566 * NETR_TRUST_FLAG_NATIVE these days.
1568 * This isn't used anyway for now.
1570 info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
1572 info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
1573 } else {
1574 info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1576 info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
1578 info->join_time = now;
1580 info->supported_enc_types = r->out.set_encryption_types;
1581 info->salt_principal = r->out.krb5_salt;
1583 if (info->salt_principal == NULL && r->out.domain_is_ad) {
1584 char *p = NULL;
1586 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 if (ret != 0) {
1592 status = krb5_to_nt_status(ret);
1593 DBG_ERR("smb_krb5_salt_principal() failed "
1594 "for %s - %s\n", domain, nt_errstr(status));
1595 TALLOC_FREE(frame);
1596 return status;
1598 info->salt_principal = p;
1601 info->password_last_change = now;
1602 info->password_changes = 1;
1603 info->next_change = NULL;
1605 status = secrets_domain_info_password_create(info,
1606 r->in.machine_password,
1607 info->salt_principal,
1608 now, r->in.dc_name,
1609 &info->password);
1610 if (!NT_STATUS_IS_OK(status)) {
1611 DBG_ERR("secrets_domain_info_password_create(pw) failed "
1612 "for %s - %s\n", domain, nt_errstr(status));
1613 TALLOC_FREE(frame);
1614 return status;
1617 db = secrets_db_ctx();
1619 ret = dbwrap_transaction_start(db);
1620 if (ret != 0) {
1621 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1622 domain);
1623 TALLOC_FREE(frame);
1624 return NT_STATUS_INTERNAL_DB_ERROR;
1627 status = secrets_fetch_or_upgrade_domain_info(domain, frame, &old);
1628 if (NT_STATUS_EQUAL(status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
1629 DBG_DEBUG("no old join for domain(%s) available\n",
1630 domain);
1631 old = NULL;
1632 } else if (!NT_STATUS_IS_OK(status)) {
1633 DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
1634 domain);
1635 dbwrap_transaction_cancel(db);
1636 TALLOC_FREE(frame);
1637 return status;
1641 * We reuse values from an old join, so that
1642 * we still accept already granted kerberos tickets.
1644 if (old != NULL) {
1645 info->old_password = old->password;
1646 info->older_password = old->old_password;
1649 secrets_debug_domain_info(DBGLVL_INFO, info, "join");
1651 status = secrets_store_domain_info(info, false /* upgrade */);
1652 if (!NT_STATUS_IS_OK(status)) {
1653 DBG_ERR("secrets_store_domain_info() failed "
1654 "for %s - %s\n", domain, nt_errstr(status));
1655 dbwrap_transaction_cancel(db);
1656 TALLOC_FREE(frame);
1657 return status;
1660 ret = dbwrap_transaction_commit(db);
1661 if (ret != 0) {
1662 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1663 domain);
1664 TALLOC_FREE(frame);
1665 return NT_STATUS_INTERNAL_DB_ERROR;
1668 TALLOC_FREE(frame);
1669 return NT_STATUS_OK;
1672 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)
1678 TALLOC_CTX *frame = talloc_stackframe();
1679 struct db_context *db = NULL;
1680 struct secrets_domain_info1 *info = NULL;
1681 struct secrets_domain_info1_change *prev = NULL;
1682 struct secrets_domain_info1_change *next = NULL;
1683 struct timeval tv = timeval_current();
1684 NTTIME now = timeval_to_nttime(&tv);
1685 NTSTATUS status;
1686 int ret;
1688 db = secrets_db_ctx();
1690 ret = dbwrap_transaction_start(db);
1691 if (ret != 0) {
1692 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1693 domain);
1694 TALLOC_FREE(frame);
1695 return NT_STATUS_INTERNAL_DB_ERROR;
1698 status = secrets_fetch_or_upgrade_domain_info(domain, frame, &info);
1699 if (!NT_STATUS_IS_OK(status)) {
1700 DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
1701 domain);
1702 dbwrap_transaction_cancel(db);
1703 TALLOC_FREE(frame);
1704 return status;
1707 prev = info->next_change;
1708 info->next_change = NULL;
1710 next = talloc_zero(frame, struct secrets_domain_info1_change);
1711 if (next == NULL) {
1712 DBG_ERR("talloc_zero failed\n");
1713 TALLOC_FREE(frame);
1714 return NT_STATUS_NO_MEMORY;
1717 if (prev != NULL) {
1718 *next = *prev;
1719 } else {
1720 status = secrets_domain_info_password_create(next,
1721 cleartext_unix,
1722 info->salt_principal,
1723 now, dcname,
1724 &next->password);
1725 if (!NT_STATUS_IS_OK(status)) {
1726 DBG_ERR("secrets_domain_info_password_create(next) failed "
1727 "for %s - %s\n", domain, nt_errstr(status));
1728 dbwrap_transaction_cancel(db);
1729 TALLOC_FREE(frame);
1730 return status;
1734 next->local_status = NT_STATUS_OK;
1735 next->remote_status = NT_STATUS_NOT_COMMITTED;
1736 next->change_time = now;
1737 next->change_server = dcname;
1739 info->next_change = next;
1741 secrets_debug_domain_info(DBGLVL_INFO, info, "prepare_change");
1743 status = secrets_store_domain_info(info, false /* upgrade */);
1744 if (!NT_STATUS_IS_OK(status)) {
1745 DBG_ERR("secrets_store_domain_info() failed "
1746 "for %s - %s\n", domain, nt_errstr(status));
1747 dbwrap_transaction_cancel(db);
1748 TALLOC_FREE(frame);
1749 return status;
1753 * We now reparse it.
1755 status = secrets_fetch_domain_info(domain, frame, &info);
1756 if (!NT_STATUS_IS_OK(status)) {
1757 DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
1758 dbwrap_transaction_cancel(db);
1759 TALLOC_FREE(frame);
1760 return status;
1763 ret = dbwrap_transaction_commit(db);
1764 if (ret != 0) {
1765 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1766 domain);
1767 TALLOC_FREE(frame);
1768 return NT_STATUS_INTERNAL_DB_ERROR;
1771 *pinfo = talloc_move(mem_ctx, &info);
1772 if (prev != NULL) {
1773 *pprev = talloc_move(mem_ctx, &prev);
1774 } else {
1775 *pprev = NULL;
1778 TALLOC_FREE(frame);
1779 return NT_STATUS_OK;
1782 static NTSTATUS secrets_check_password_change(const struct secrets_domain_info1 *cookie,
1783 TALLOC_CTX *mem_ctx,
1784 struct secrets_domain_info1 **pstored)
1786 const char *domain = cookie->domain_info.name.string;
1787 struct secrets_domain_info1 *stored = NULL;
1788 struct secrets_domain_info1_change *sn = NULL;
1789 struct secrets_domain_info1_change *cn = NULL;
1790 NTSTATUS status;
1791 bool cmp;
1793 if (cookie->next_change == NULL) {
1794 DBG_ERR("cookie->next_change == NULL for %s.\n", domain);
1795 return NT_STATUS_INTERNAL_ERROR;
1798 if (cookie->next_change->password == NULL) {
1799 DBG_ERR("cookie->next_change->password == NULL for %s.\n", domain);
1800 return NT_STATUS_INTERNAL_ERROR;
1803 if (cookie->password == NULL) {
1804 DBG_ERR("cookie->password == NULL for %s.\n", domain);
1805 return NT_STATUS_INTERNAL_ERROR;
1809 * Here we check that the given structure still contains the
1810 * same secrets_domain_info1_change as currently stored.
1812 * There's always a gap between secrets_prepare_password_change()
1813 * and the callers of secrets_check_password_change().
1816 status = secrets_fetch_domain_info(domain, mem_ctx, &stored);
1817 if (!NT_STATUS_IS_OK(status)) {
1818 DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
1819 return status;
1822 if (stored->next_change == NULL) {
1824 * We hit a race..., the administrator
1825 * rejoined or something similar happened.
1827 DBG_ERR("stored->next_change == NULL for %s.\n", domain);
1828 TALLOC_FREE(stored);
1829 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1832 if (stored->password_last_change != cookie->password_last_change) {
1833 struct timeval store_tv;
1834 struct timeval_buf store_buf;
1835 struct timeval cookie_tv;
1836 struct timeval_buf cookie_buf;
1838 nttime_to_timeval(&store_tv, stored->password_last_change);
1839 nttime_to_timeval(&cookie_tv, cookie->password_last_change);
1841 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 TALLOC_FREE(stored);
1846 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1849 sn = stored->next_change;
1850 cn = cookie->next_change;
1852 if (sn->change_time != cn->change_time) {
1853 struct timeval store_tv;
1854 struct timeval_buf store_buf;
1855 struct timeval cookie_tv;
1856 struct timeval_buf cookie_buf;
1858 nttime_to_timeval(&store_tv, sn->change_time);
1859 nttime_to_timeval(&cookie_tv, cn->change_time);
1861 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 TALLOC_FREE(stored);
1866 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1869 if (sn->password->change_time != cn->password->change_time) {
1870 struct timeval store_tv;
1871 struct timeval_buf store_buf;
1872 struct timeval cookie_tv;
1873 struct timeval_buf cookie_buf;
1875 nttime_to_timeval(&store_tv, sn->password->change_time);
1876 nttime_to_timeval(&cookie_tv, cn->password->change_time);
1878 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 TALLOC_FREE(stored);
1883 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1886 cmp = mem_equal_const_time(sn->password->nt_hash.hash,
1887 cn->password->nt_hash.hash,
1888 16);
1889 if (!cmp) {
1890 DBG_ERR("next password.nt_hash differs for %s.\n",
1891 domain);
1892 TALLOC_FREE(stored);
1893 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1896 cmp = mem_equal_const_time(stored->password->nt_hash.hash,
1897 cookie->password->nt_hash.hash,
1898 16);
1899 if (!cmp) {
1900 DBG_ERR("password.nt_hash differs for %s.\n",
1901 domain);
1902 TALLOC_FREE(stored);
1903 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1906 *pstored = stored;
1907 return NT_STATUS_OK;
1910 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)
1916 const char *domain = cookie->domain_info.name.string;
1917 TALLOC_CTX *frame = talloc_stackframe();
1918 struct db_context *db = NULL;
1919 struct secrets_domain_info1 *info = NULL;
1920 const char *reason = defer ? "defer_change" : "failed_change";
1921 struct timeval tv = timeval_current();
1922 NTTIME now = timeval_to_nttime(&tv);
1923 NTSTATUS status;
1924 int ret;
1926 db = secrets_db_ctx();
1928 ret = dbwrap_transaction_start(db);
1929 if (ret != 0) {
1930 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1931 domain);
1932 TALLOC_FREE(frame);
1933 return NT_STATUS_INTERNAL_DB_ERROR;
1937 * secrets_check_password_change()
1938 * checks that cookie->next_change
1939 * is valid and the same as store
1940 * in the database.
1942 status = secrets_check_password_change(cookie, frame, &info);
1943 if (!NT_STATUS_IS_OK(status)) {
1944 DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
1945 dbwrap_transaction_cancel(db);
1946 TALLOC_FREE(frame);
1947 return status;
1951 * Remember the last server and error.
1953 info->next_change->change_server = change_server;
1954 info->next_change->change_time = now;
1955 info->next_change->local_status = local_status;
1956 info->next_change->remote_status = remote_status;
1959 * Make sure the next automatic change is deferred.
1961 if (defer) {
1962 info->password_last_change = now;
1965 secrets_debug_domain_info(DBGLVL_WARNING, info, reason);
1967 status = secrets_store_domain_info(info, false /* upgrade */);
1968 if (!NT_STATUS_IS_OK(status)) {
1969 DBG_ERR("secrets_store_domain_info() failed "
1970 "for %s - %s\n", domain, nt_errstr(status));
1971 dbwrap_transaction_cancel(db);
1972 TALLOC_FREE(frame);
1973 return status;
1976 ret = dbwrap_transaction_commit(db);
1977 if (ret != 0) {
1978 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1979 domain);
1980 TALLOC_FREE(frame);
1981 return NT_STATUS_INTERNAL_DB_ERROR;
1984 TALLOC_FREE(frame);
1985 return NT_STATUS_OK;
1988 NTSTATUS secrets_failed_password_change(const char *change_server,
1989 NTSTATUS local_status,
1990 NTSTATUS remote_status,
1991 const struct secrets_domain_info1 *cookie)
1993 static const bool defer = false;
1994 return secrets_abort_password_change(change_server,
1995 local_status,
1996 remote_status,
1997 cookie, defer);
2000 NTSTATUS secrets_defer_password_change(const char *change_server,
2001 NTSTATUS local_status,
2002 NTSTATUS remote_status,
2003 const struct secrets_domain_info1 *cookie)
2005 static const bool defer = true;
2006 return secrets_abort_password_change(change_server,
2007 local_status,
2008 remote_status,
2009 cookie, defer);
2012 NTSTATUS secrets_finish_password_change(const char *change_server,
2013 NTTIME change_time,
2014 const struct secrets_domain_info1 *cookie)
2016 const char *domain = cookie->domain_info.name.string;
2017 TALLOC_CTX *frame = talloc_stackframe();
2018 struct db_context *db = NULL;
2019 struct secrets_domain_info1 *info = NULL;
2020 struct secrets_domain_info1_change *nc = NULL;
2021 NTSTATUS status;
2022 int ret;
2024 db = secrets_db_ctx();
2026 ret = dbwrap_transaction_start(db);
2027 if (ret != 0) {
2028 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
2029 domain);
2030 TALLOC_FREE(frame);
2031 return NT_STATUS_INTERNAL_DB_ERROR;
2035 * secrets_check_password_change() checks that cookie->next_change is
2036 * valid and the same as store in the database.
2038 status = secrets_check_password_change(cookie, frame, &info);
2039 if (!NT_STATUS_IS_OK(status)) {
2040 DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
2041 dbwrap_transaction_cancel(db);
2042 TALLOC_FREE(frame);
2043 return status;
2046 nc = info->next_change;
2048 nc->password->change_server = change_server;
2049 nc->password->change_time = change_time;
2051 info->password_last_change = change_time;
2052 info->password_changes += 1;
2053 info->next_change = NULL;
2055 info->older_password = info->old_password;
2056 info->old_password = info->password;
2057 info->password = nc->password;
2059 secrets_debug_domain_info(DBGLVL_WARNING, info, "finish_change");
2061 status = secrets_store_domain_info(info, false /* upgrade */);
2062 if (!NT_STATUS_IS_OK(status)) {
2063 DBG_ERR("secrets_store_domain_info() failed "
2064 "for %s - %s\n", domain, nt_errstr(status));
2065 dbwrap_transaction_cancel(db);
2066 TALLOC_FREE(frame);
2067 return status;
2070 ret = dbwrap_transaction_commit(db);
2071 if (ret != 0) {
2072 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
2073 domain);
2074 TALLOC_FREE(frame);
2075 return NT_STATUS_INTERNAL_DB_ERROR;
2078 TALLOC_FREE(frame);
2079 return NT_STATUS_OK;