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 */
27 #include "../libcli/auth/libcli_auth.h"
29 #include "dbwrap/dbwrap.h"
30 #include "../librpc/ndr/libndr.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 "libads/krb5_errs.h"
43 #define DBGC_CLASS DBGC_PASSDB
45 static char *domain_info_keystr(const char *domain);
47 static char *des_salt_key(const char *realm);
50 * Form a key for fetching the domain sid
52 * @param domain domain name
56 static const char *domain_sid_keystr(const char *domain)
60 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
61 SECRETS_DOMAIN_SID, domain);
62 SMB_ASSERT(keystr != NULL);
66 static const char *domain_guid_keystr(const char *domain)
70 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
71 SECRETS_DOMAIN_GUID, domain);
72 SMB_ASSERT(keystr != NULL);
76 static const char *protect_ids_keystr(const char *domain)
80 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
81 SECRETS_PROTECT_IDS, domain);
82 SMB_ASSERT(keystr != NULL);
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)
91 ret = secrets_store(protect_ids_keystr(domain), "TRUE", 5);
93 DEBUG(0, ("Failed to protect the Domain IDs\n"));
98 bool secrets_clear_domain_protection(const char *domain)
101 void *protection = secrets_fetch(protect_ids_keystr(domain), NULL);
104 SAFE_FREE(protection);
105 ret = secrets_delete_entry(protect_ids_keystr(domain));
107 DEBUG(0, ("Failed to remove Domain IDs protection\n"));
114 bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
118 struct dom_sid clean_sid = { 0 };
120 protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
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);
129 SAFE_FREE(protect_ids);
132 * use a copy to prevent uninitialized memory from being carried over
135 sid_copy(&clean_sid, sid);
137 ret = secrets_store(domain_sid_keystr(domain),
139 sizeof(struct dom_sid));
141 /* Force a re-query, in the case where we modified our domain */
143 if (dom_sid_equal(get_global_sam_sid(), sid) == false) {
144 reset_global_sam_sid();
150 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
152 struct dom_sid *dyn_sid;
155 dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
160 if (size != sizeof(struct dom_sid)) {
170 bool secrets_store_domain_guid(const char *domain, const struct GUID *guid)
175 protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
177 if (strncmp(protect_ids, "TRUE", 4)) {
178 DEBUG(0, ("Refusing to store a Domain SID, "
179 "it has been marked as protected!\n"));
180 SAFE_FREE(protect_ids);
184 SAFE_FREE(protect_ids);
186 key = domain_guid_keystr(domain);
187 return secrets_store(key, guid, sizeof(struct GUID));
190 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
192 struct GUID *dyn_guid;
195 struct GUID new_guid;
197 key = domain_guid_keystr(domain);
198 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
201 if (lp_server_role() == ROLE_DOMAIN_PDC) {
202 new_guid = GUID_random();
203 if (!secrets_store_domain_guid(domain, &new_guid))
205 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
207 if (dyn_guid == NULL) {
212 if (size != sizeof(struct GUID)) {
213 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
224 * Form a key for fetching the machine trust account sec channel type
226 * @param domain domain name
230 static const char *machine_sec_channel_type_keystr(const char *domain)
234 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
235 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
237 SMB_ASSERT(keystr != NULL);
242 * Form a key for fetching the machine trust account last change time
244 * @param domain domain name
248 static const char *machine_last_change_time_keystr(const char *domain)
252 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
253 SECRETS_MACHINE_LAST_CHANGE_TIME,
255 SMB_ASSERT(keystr != NULL);
261 * Form a key for fetching the machine previous trust account password
263 * @param domain domain name
267 static const char *machine_prev_password_keystr(const char *domain)
271 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
272 SECRETS_MACHINE_PASSWORD_PREV, domain);
273 SMB_ASSERT(keystr != NULL);
278 * Form a key for fetching the machine trust account password
280 * @param domain domain name
284 static const char *machine_password_keystr(const char *domain)
288 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
289 SECRETS_MACHINE_PASSWORD, domain);
290 SMB_ASSERT(keystr != NULL);
295 * Form a key for fetching the machine trust account password
297 * @param domain domain name
299 * @return stored password's key
301 static const char *trust_keystr(const char *domain)
305 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
306 SECRETS_MACHINE_ACCT_PASS, domain);
307 SMB_ASSERT(keystr != NULL);
311 /************************************************************************
312 Routine to get the default secure channel type for trust accounts
313 ************************************************************************/
315 enum netr_SchannelType get_default_sec_channel(void)
317 if (lp_server_role() == ROLE_DOMAIN_BDC ||
318 lp_server_role() == ROLE_DOMAIN_PDC ||
319 lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
322 return SEC_CHAN_WKSTA;
326 /************************************************************************
327 Routine to get the trust account password for a domain.
328 This only tries to get the legacy hashed version of the password.
329 The user of this function must have locked the trust password file using
330 the above secrets_lock_trust_account_password().
331 ************************************************************************/
333 bool secrets_fetch_trust_account_password_legacy(const char *domain,
335 time_t *pass_last_set_time,
336 enum netr_SchannelType *channel)
338 struct machine_acct_pass *pass;
341 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
342 trust_keystr(domain), &size))) {
343 DEBUG(5, ("secrets_fetch failed!\n"));
347 if (size != sizeof(*pass)) {
348 DEBUG(0, ("secrets were of incorrect size!\n"));
353 if (pass_last_set_time) {
354 *pass_last_set_time = pass->mod_time;
356 memcpy(ret_pwd, pass->hash, 16);
359 *channel = get_default_sec_channel();
366 /************************************************************************
367 Routine to get the trust account password for a domain.
368 The user of this function must have locked the trust password file using
369 the above secrets_lock_trust_account_password().
370 ************************************************************************/
372 bool secrets_fetch_trust_account_password(const char *domain, uint8_t ret_pwd[16],
373 time_t *pass_last_set_time,
374 enum netr_SchannelType *channel)
378 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
381 DEBUG(4,("Using cleartext machine password\n"));
382 E_md4hash(plaintext, ret_pwd);
383 SAFE_FREE(plaintext);
387 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
392 /************************************************************************
393 Routine to delete all information related to the domain joined machine.
394 ************************************************************************/
396 bool secrets_delete_machine_password_ex(const char *domain, const char *realm)
398 const char *tmpkey = NULL;
401 tmpkey = domain_info_keystr(domain);
402 ok = secrets_delete(tmpkey);
408 tmpkey = des_salt_key(domain);
409 ok = secrets_delete(tmpkey);
415 tmpkey = domain_guid_keystr(domain);
416 ok = secrets_delete(tmpkey);
421 tmpkey = machine_prev_password_keystr(domain);
422 ok = secrets_delete(tmpkey);
427 tmpkey = machine_password_keystr(domain);
428 ok = secrets_delete(tmpkey);
433 tmpkey = machine_sec_channel_type_keystr(domain);
434 ok = secrets_delete(tmpkey);
439 tmpkey = machine_last_change_time_keystr(domain);
440 ok = secrets_delete(tmpkey);
445 tmpkey = domain_sid_keystr(domain);
446 ok = secrets_delete(tmpkey);
454 /************************************************************************
455 Routine to delete the domain sid
456 ************************************************************************/
458 bool secrets_delete_domain_sid(const char *domain)
460 return secrets_delete_entry(domain_sid_keystr(domain));
463 /************************************************************************
464 Set the machine trust account password, the old pw and last change
465 time, domain SID and salting principals based on values passed in
466 (added to supprt the secrets_tdb_sync module on secrets.ldb)
467 ************************************************************************/
469 bool secrets_store_machine_pw_sync(const char *pass, const char *oldpass, const char *domain,
471 const char *salting_principal, uint32_t supported_enc_types,
472 const struct dom_sid *domain_sid, uint32_t last_change_time,
473 uint32_t secure_channel_type,
477 uint8_t last_change_time_store[4];
478 TALLOC_CTX *frame = talloc_stackframe();
479 uint8_t sec_channel_bytes[4];
482 secrets_delete_machine_password_ex(domain, realm);
487 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
494 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
496 ret = secrets_delete(machine_prev_password_keystr(domain));
503 if (secure_channel_type == 0) {
504 /* We delete this and instead have the read code fall back to
505 * a default based on server role, as our caller can't specify
506 * this with any more certainty */
507 ret = secrets_delete(machine_sec_channel_type_keystr(domain));
513 SIVAL(&sec_channel_bytes, 0, secure_channel_type);
514 ret = secrets_store(machine_sec_channel_type_keystr(domain),
515 &sec_channel_bytes, sizeof(sec_channel_bytes));
522 SIVAL(&last_change_time_store, 0, last_change_time);
523 ret = secrets_store(machine_last_change_time_keystr(domain),
524 &last_change_time_store, sizeof(last_change_time));
531 ret = secrets_store_domain_sid(domain, domain_sid);
539 char *key = des_salt_key(realm);
541 if (salting_principal != NULL) {
542 ret = secrets_store(key,
544 strlen(salting_principal)+1);
546 ret = secrets_delete(key);
554 /************************************************************************
555 Return the standard DES salt key
556 ************************************************************************/
558 char* kerberos_standard_des_salt( void )
562 fstr_sprintf( salt, "host/%s.%s@", lp_netbios_name(), lp_realm() );
563 (void)strlower_m( salt );
564 fstrcat( salt, lp_realm() );
566 return SMB_STRDUP( salt );
569 /************************************************************************
570 ************************************************************************/
572 static char *des_salt_key(const char *realm)
576 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/DES/%s",
577 SECRETS_SALTING_PRINCIPAL,
579 SMB_ASSERT(keystr != NULL);
583 /************************************************************************
584 ************************************************************************/
586 bool kerberos_secrets_store_des_salt( const char* salt )
591 key = des_salt_key(lp_realm());
593 DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n"));
598 DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n"));
599 secrets_delete_entry( key );
603 DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt));
605 ret = secrets_store( key, salt, strlen(salt)+1 );
612 /************************************************************************
613 ************************************************************************/
616 char* kerberos_secrets_fetch_des_salt( void )
620 key = des_salt_key(lp_realm());
622 DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
626 salt = (char*)secrets_fetch( key, NULL );
633 /************************************************************************
634 Routine to get the salting principal for this service.
635 Caller must free if return is not null.
636 ************************************************************************/
638 char *kerberos_secrets_fetch_salt_princ(void)
641 /* lookup new key first */
643 salt_princ_s = kerberos_secrets_fetch_des_salt();
644 if (salt_princ_s == NULL) {
645 /* fall back to host/machine.realm@REALM */
646 salt_princ_s = kerberos_standard_des_salt();
652 /************************************************************************
653 Routine to fetch the previous plaintext machine account password for a realm
654 the password is assumed to be a null terminated ascii string.
655 ************************************************************************/
657 char *secrets_fetch_prev_machine_password(const char *domain)
659 return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
662 /************************************************************************
663 Routine to fetch the last change time of the machine account password
665 ************************************************************************/
667 time_t secrets_fetch_pass_last_set_time(const char *domain)
669 uint32_t *last_set_time;
670 time_t pass_last_set_time;
672 last_set_time = secrets_fetch(machine_last_change_time_keystr(domain),
675 pass_last_set_time = IVAL(last_set_time,0);
676 SAFE_FREE(last_set_time);
678 pass_last_set_time = 0;
681 return pass_last_set_time;
684 /************************************************************************
685 Routine to fetch the plaintext machine account password for a realm
686 the password is assumed to be a null terminated ascii string.
687 ************************************************************************/
689 char *secrets_fetch_machine_password(const char *domain,
690 time_t *pass_last_set_time,
691 enum netr_SchannelType *channel)
694 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
696 if (pass_last_set_time) {
697 *pass_last_set_time = secrets_fetch_pass_last_set_time(domain);
702 uint32_t *channel_type;
703 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
705 *channel = IVAL(channel_type,0);
706 SAFE_FREE(channel_type);
708 *channel = get_default_sec_channel();
715 static char *domain_info_keystr(const char *domain)
719 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
720 SECRETS_MACHINE_DOMAIN_INFO,
722 SMB_ASSERT(keystr != NULL);
726 /************************************************************************
727 Routine to get account password to trusted domain
728 ************************************************************************/
730 static NTSTATUS secrets_fetch_domain_info1_by_key(const char *key,
732 struct secrets_domain_info1 **_info1)
734 struct secrets_domain_infoB sdib = { .version = 0, };
735 enum ndr_err_code ndr_err;
736 /* unpacking structures */
739 /* fetching trusted domain password structure */
740 blob.data = (uint8_t *)secrets_fetch(key, &blob.length);
741 if (blob.data == NULL) {
742 DBG_NOTICE("secrets_fetch failed!\n");
743 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
746 /* unpack trusted domain password */
747 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sdib,
748 (ndr_pull_flags_fn_t)ndr_pull_secrets_domain_infoB);
749 SAFE_FREE(blob.data);
750 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
751 DBG_ERR("ndr_pull_struct_blob failed - %s!\n",
752 ndr_errstr(ndr_err));
753 return NT_STATUS_INTERNAL_DB_CORRUPTION;
756 if (sdib.version != SECRETS_DOMAIN_INFO_VERSION_1) {
757 DBG_ERR("sdib.version = %u\n", (unsigned)sdib.version);
758 return NT_STATUS_INTERNAL_DB_CORRUPTION;
761 *_info1 = sdib.info.info1;
762 return NT_STATUS_OK;;
765 static NTSTATUS secrets_fetch_domain_info(const char *domain,
767 struct secrets_domain_info1 **pinfo)
769 char *key = domain_info_keystr(domain);
770 return secrets_fetch_domain_info1_by_key(key, mem_ctx, pinfo);
773 void secrets_debug_domain_info(int lvl, const struct secrets_domain_info1 *info1,
776 struct secrets_domain_infoB sdib = {
777 .version = SECRETS_DOMAIN_INFO_VERSION_1,
780 sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
782 ndr_print_debug((ndr_print_fn_t)ndr_print_secrets_domain_infoB,
786 char *secrets_domain_info_string(TALLOC_CTX *mem_ctx, const struct secrets_domain_info1 *info1,
787 const char *name, bool include_secrets)
789 TALLOC_CTX *frame = talloc_stackframe();
790 struct secrets_domain_infoB sdib = {
791 .version = SECRETS_DOMAIN_INFO_VERSION_1,
793 struct ndr_print *ndr = NULL;
796 sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
798 ndr = talloc_zero(frame, struct ndr_print);
803 ndr->private_data = talloc_strdup(ndr, "");
804 if (ndr->private_data == NULL) {
808 ndr->print = ndr_print_string_helper;
810 ndr->print_secrets = include_secrets;
812 ndr_print_secrets_domain_infoB(ndr, name, &sdib);
813 ret = talloc_steal(mem_ctx, (char *)ndr->private_data);
818 static NTSTATUS secrets_store_domain_info1_by_key(const char *key,
819 const struct secrets_domain_info1 *info1)
821 struct secrets_domain_infoB sdib = {
822 .version = SECRETS_DOMAIN_INFO_VERSION_1,
824 /* packing structures */
826 enum ndr_err_code ndr_err;
829 sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
831 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &sdib,
832 (ndr_push_flags_fn_t)ndr_push_secrets_domain_infoB);
833 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
834 return ndr_map_error2ntstatus(ndr_err);
837 ok = secrets_store(key, blob.data, blob.length);
838 data_blob_clear_free(&blob);
840 return NT_STATUS_INTERNAL_DB_ERROR;
846 static NTSTATUS secrets_store_domain_info(const struct secrets_domain_info1 *info,
849 TALLOC_CTX *frame = talloc_stackframe();
850 const char *domain = info->domain_info.name.string;
851 const char *realm = info->domain_info.dns_domain.string;
852 char *key = domain_info_keystr(domain);
853 struct db_context *db = NULL;
854 struct timeval last_change_tv;
855 const DATA_BLOB *cleartext_blob = NULL;
856 DATA_BLOB pw_blob = data_blob_null;
857 DATA_BLOB old_pw_blob = data_blob_null;
858 const char *pw = NULL;
859 const char *old_pw = NULL;
863 int role = lp_server_role();
865 switch (info->secure_channel_type) {
868 if (!upgrade && role >= ROLE_ACTIVE_DIRECTORY_DC) {
869 DBG_ERR("AD_DC not supported for %s\n",
872 return NT_STATUS_INTERNAL_ERROR;
877 DBG_ERR("SEC_CHAN_* not supported for %s\n",
880 return NT_STATUS_INTERNAL_ERROR;
883 db = secrets_db_ctx();
885 ret = dbwrap_transaction_start(db);
887 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
890 return NT_STATUS_INTERNAL_DB_ERROR;
893 ok = secrets_clear_domain_protection(domain);
895 DBG_ERR("secrets_clear_domain_protection(%s) failed\n",
897 dbwrap_transaction_cancel(db);
899 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
902 ok = secrets_delete_machine_password_ex(domain, realm);
904 DBG_ERR("secrets_delete_machine_password_ex(%s) failed\n",
906 dbwrap_transaction_cancel(db);
908 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
911 status = secrets_store_domain_info1_by_key(key, info);
912 if (!NT_STATUS_IS_OK(status)) {
913 DBG_ERR("secrets_store_domain_info1_by_key() failed "
914 "for %s - %s\n", domain, nt_errstr(status));
915 dbwrap_transaction_cancel(db);
921 * We use info->password_last_change instead
922 * of info->password.change_time because
923 * we may want to defer the next change approach
924 * if the server rejected the change the last time,
925 * e.g. due to RefusePasswordChange=1.
927 nttime_to_timeval(&last_change_tv, info->password_last_change);
929 cleartext_blob = &info->password->cleartext_blob;
930 ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
931 cleartext_blob->data,
932 cleartext_blob->length,
933 (void **)&pw_blob.data,
936 status = NT_STATUS_UNMAPPABLE_CHARACTER;
937 if (errno == ENOMEM) {
938 status = NT_STATUS_NO_MEMORY;
940 DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
941 "failed for pw of %s - %s\n",
942 domain, nt_errstr(status));
943 dbwrap_transaction_cancel(db);
947 pw = (const char *)pw_blob.data;
948 if (info->old_password != NULL) {
949 cleartext_blob = &info->old_password->cleartext_blob;
950 ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
951 cleartext_blob->data,
952 cleartext_blob->length,
953 (void **)&old_pw_blob.data,
954 &old_pw_blob.length);
956 status = NT_STATUS_UNMAPPABLE_CHARACTER;
957 if (errno == ENOMEM) {
958 status = NT_STATUS_NO_MEMORY;
960 DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
961 "failed for old_pw of %s - %s\n",
962 domain, nt_errstr(status));
963 dbwrap_transaction_cancel(db);
964 data_blob_clear_free(&pw_blob);
968 old_pw = (const char *)old_pw_blob.data;
971 ok = secrets_store_machine_pw_sync(pw, old_pw,
973 info->salt_principal,
974 info->supported_enc_types,
975 info->domain_info.sid,
976 last_change_tv.tv_sec,
977 info->secure_channel_type,
978 false); /* delete_join */
979 data_blob_clear_free(&pw_blob);
980 data_blob_clear_free(&old_pw_blob);
982 DBG_ERR("secrets_store_machine_pw_sync(%s) failed\n",
984 dbwrap_transaction_cancel(db);
986 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
989 if (!GUID_all_zero(&info->domain_info.domain_guid)) {
990 ok = secrets_store_domain_guid(domain,
991 &info->domain_info.domain_guid);
993 DBG_ERR("secrets_store_domain_guid(%s) failed\n",
995 dbwrap_transaction_cancel(db);
997 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1001 ok = secrets_mark_domain_protected(domain);
1003 DBG_ERR("secrets_mark_domain_protected(%s) failed\n",
1005 dbwrap_transaction_cancel(db);
1007 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1010 ret = dbwrap_transaction_commit(db);
1012 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1015 return NT_STATUS_INTERNAL_DB_ERROR;
1019 return NT_STATUS_OK;
1022 static int secrets_domain_info_kerberos_keys(struct secrets_domain_info1_password *p,
1023 const char *salt_principal)
1026 krb5_error_code krb5_ret;
1027 krb5_context krb5_ctx = NULL;
1028 DATA_BLOB cleartext_utf8_b = data_blob_null;
1029 krb5_data cleartext_utf8;
1032 DATA_BLOB aes_256_b = data_blob_null;
1033 DATA_BLOB aes_128_b = data_blob_null;
1034 DATA_BLOB des_md5_b = data_blob_null;
1036 #endif /* HAVE_ADS */
1037 DATA_BLOB arc4_b = data_blob_null;
1038 const uint16_t max_keys = 4;
1039 struct secrets_domain_info1_kerberos_key *keys = NULL;
1041 char *salt_data = NULL;
1045 * ENCTYPE_AES256_CTS_HMAC_SHA1_96
1046 * ENCTYPE_AES128_CTS_HMAC_SHA1_96
1047 * ENCTYPE_ARCFOUR_HMAC
1048 * ENCTYPE_DES_CBC_MD5
1050 * We don't include ENCTYPE_DES_CBC_CRC
1051 * as W2008R2 also doesn't store it anymore.
1053 * Note we store all enctypes we support,
1054 * including the weak encryption types,
1055 * but that's no problem as we also
1056 * store the cleartext password anyway.
1058 * Which values are then used to construct
1059 * a keytab is configured at runtime and the
1060 * configuration of msDS-SupportedEncryptionTypes.
1062 * If we don't have kerberos support or no
1063 * salt, we only generate an entry for arcfour-hmac-md5.
1065 keys = talloc_zero_array(p,
1066 struct secrets_domain_info1_kerberos_key,
1072 arc4_b = data_blob_talloc(keys,
1074 sizeof(p->nt_hash.hash));
1075 if (arc4_b.data == NULL) {
1076 DBG_ERR("data_blob_talloc failed for arcfour-hmac-md5.\n");
1082 if (salt_principal == NULL) {
1086 initialize_krb5_error_table();
1087 krb5_ret = krb5_init_context(&krb5_ctx);
1088 if (krb5_ret != 0) {
1093 krb5_ret = smb_krb5_salt_principal2data(krb5_ctx, salt_principal,
1095 if (krb5_ret != 0) {
1096 DBG_ERR("smb_krb5_salt_principal2data(%s) failed: %s\n",
1098 smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1099 krb5_free_context(krb5_ctx);
1104 salt = (krb5_data) {
1105 .data = discard_const(salt_data),
1106 .length = strlen(salt_data),
1109 ok = convert_string_talloc(keys, CH_UTF16MUNGED, CH_UTF8,
1110 p->cleartext_blob.data,
1111 p->cleartext_blob.length,
1112 (void **)&cleartext_utf8_b.data,
1113 &cleartext_utf8_b.length);
1120 krb5_free_context(krb5_ctx);
1124 cleartext_utf8.data = (void *)cleartext_utf8_b.data;
1125 cleartext_utf8.length = cleartext_utf8_b.length;
1127 krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
1131 ENCTYPE_AES256_CTS_HMAC_SHA1_96,
1133 if (krb5_ret != 0) {
1134 DBG_ERR("generation of a aes256-cts-hmac-sha1-96 key failed: %s\n",
1135 smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1136 krb5_free_context(krb5_ctx);
1138 TALLOC_FREE(salt_data);
1141 aes_256_b = data_blob_talloc(keys,
1142 KRB5_KEY_DATA(&key),
1143 KRB5_KEY_LENGTH(&key));
1144 krb5_free_keyblock_contents(krb5_ctx, &key);
1145 if (aes_256_b.data == NULL) {
1146 DBG_ERR("data_blob_talloc failed for aes-256.\n");
1147 krb5_free_context(krb5_ctx);
1149 TALLOC_FREE(salt_data);
1153 krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
1157 ENCTYPE_AES128_CTS_HMAC_SHA1_96,
1159 if (krb5_ret != 0) {
1160 DBG_ERR("generation of a aes128-cts-hmac-sha1-96 key failed: %s\n",
1161 smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1162 krb5_free_context(krb5_ctx);
1164 TALLOC_FREE(salt_data);
1167 aes_128_b = data_blob_talloc(keys,
1168 KRB5_KEY_DATA(&key),
1169 KRB5_KEY_LENGTH(&key));
1170 krb5_free_keyblock_contents(krb5_ctx, &key);
1171 if (aes_128_b.data == NULL) {
1172 DBG_ERR("data_blob_talloc failed for aes-128.\n");
1173 krb5_free_context(krb5_ctx);
1175 TALLOC_FREE(salt_data);
1179 krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
1183 ENCTYPE_DES_CBC_MD5,
1185 if (krb5_ret != 0) {
1186 DBG_ERR("generation of a des-cbc-md5 key failed: %s\n",
1187 smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1188 krb5_free_context(krb5_ctx);
1190 TALLOC_FREE(salt_data);
1193 des_md5_b = data_blob_talloc(keys,
1194 KRB5_KEY_DATA(&key),
1195 KRB5_KEY_LENGTH(&key));
1196 krb5_free_keyblock_contents(krb5_ctx, &key);
1197 if (des_md5_b.data == NULL) {
1198 DBG_ERR("data_blob_talloc failed for des-cbc-md5.\n");
1199 krb5_free_context(krb5_ctx);
1201 TALLOC_FREE(salt_data);
1205 krb5_free_context(krb5_ctx);
1208 if (aes_256_b.length != 0) {
1209 keys[idx].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
1210 keys[idx].iteration_count = 4096;
1211 keys[idx].value = aes_256_b;
1215 if (aes_128_b.length != 0) {
1216 keys[idx].keytype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
1217 keys[idx].iteration_count = 4096;
1218 keys[idx].value = aes_128_b;
1222 #endif /* HAVE_ADS */
1224 keys[idx].keytype = ENCTYPE_ARCFOUR_HMAC;
1225 keys[idx].iteration_count = 4096;
1226 keys[idx].value = arc4_b;
1230 if (des_md5_b.length != 0) {
1231 keys[idx].keytype = ENCTYPE_DES_CBC_MD5;
1232 keys[idx].iteration_count = 4096;
1233 keys[idx].value = des_md5_b;
1236 #endif /* HAVE_ADS */
1238 p->salt_data = salt_data;
1239 p->default_iteration_count = 4096;
1245 static NTSTATUS secrets_domain_info_password_create(TALLOC_CTX *mem_ctx,
1246 const char *cleartext_unix,
1247 const char *salt_principal,
1249 const char *change_server,
1250 struct secrets_domain_info1_password **_p)
1252 struct secrets_domain_info1_password *p = NULL;
1257 if (change_server == NULL) {
1258 return NT_STATUS_INVALID_PARAMETER_MIX;
1261 p = talloc_zero(mem_ctx, struct secrets_domain_info1_password);
1263 return NT_STATUS_NO_MEMORY;
1265 p->change_time = change_time;
1266 p->change_server = talloc_strdup(p, change_server);
1267 if (p->change_server == NULL) {
1269 return NT_STATUS_NO_MEMORY;
1271 len = strlen(cleartext_unix);
1272 ok = convert_string_talloc(p, CH_UNIX, CH_UTF16,
1273 cleartext_unix, len,
1274 (void **)&p->cleartext_blob.data,
1275 &p->cleartext_blob.length);
1277 NTSTATUS status = NT_STATUS_UNMAPPABLE_CHARACTER;
1278 if (errno == ENOMEM) {
1279 status = NT_STATUS_NO_MEMORY;
1284 mdfour(p->nt_hash.hash,
1285 p->cleartext_blob.data,
1286 p->cleartext_blob.length);
1288 ret = secrets_domain_info_kerberos_keys(p, salt_principal);
1290 NTSTATUS status = krb5_to_nt_status(ret);
1296 return NT_STATUS_OK;
1299 NTSTATUS secrets_fetch_or_upgrade_domain_info(const char *domain,
1300 TALLOC_CTX *mem_ctx,
1301 struct secrets_domain_info1 **pinfo)
1303 TALLOC_CTX *frame = NULL;
1304 struct secrets_domain_info1 *old = NULL;
1305 struct secrets_domain_info1 *info = NULL;
1306 const char *dns_domain = NULL;
1307 const char *server = NULL;
1308 struct db_context *db = NULL;
1309 time_t last_set_time;
1311 enum netr_SchannelType channel;
1313 char *old_pw = NULL;
1314 struct dom_sid domain_sid;
1315 struct GUID domain_guid;
1320 ok = strequal(domain, lp_workgroup());
1322 dns_domain = lp_dnsdomain();
1324 if (dns_domain != NULL && dns_domain[0] == '\0') {
1329 last_set_time = secrets_fetch_pass_last_set_time(domain);
1330 if (last_set_time == 0) {
1331 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1333 unix_to_nt_time(&last_set_nt, last_set_time);
1335 frame = talloc_stackframe();
1337 status = secrets_fetch_domain_info(domain, frame, &old);
1338 if (NT_STATUS_IS_OK(status)) {
1339 if (old->password_last_change >= last_set_nt) {
1340 *pinfo = talloc_move(mem_ctx, &old);
1342 return NT_STATUS_OK;
1347 info = talloc_zero(frame, struct secrets_domain_info1);
1349 DBG_ERR("talloc_zero failed\n");
1351 return NT_STATUS_NO_MEMORY;
1354 db = secrets_db_ctx();
1356 ret = dbwrap_transaction_start(db);
1358 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1361 return NT_STATUS_INTERNAL_DB_ERROR;
1364 pw = secrets_fetch_machine_password(domain,
1368 DBG_ERR("secrets_fetch_machine_password(%s) failed\n",
1370 dbwrap_transaction_cancel(db);
1372 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1374 unix_to_nt_time(&last_set_nt, last_set_time);
1376 old_pw = secrets_fetch_prev_machine_password(domain);
1378 ok = secrets_fetch_domain_sid(domain, &domain_sid);
1380 DBG_ERR("secrets_fetch_domain_sid(%s) failed\n",
1382 dbwrap_transaction_cancel(db);
1386 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1389 ok = secrets_fetch_domain_guid(domain, &domain_guid);
1391 domain_guid = GUID_zero();
1394 info->computer_name = lp_netbios_name();
1395 info->account_name = talloc_asprintf(frame, "%s$", info->computer_name);
1396 if (info->account_name == NULL) {
1397 DBG_ERR("talloc_asprintf(%s$) failed\n", info->computer_name);
1398 dbwrap_transaction_cancel(db);
1402 return NT_STATUS_NO_MEMORY;
1404 info->secure_channel_type = channel;
1406 info->domain_info.name.string = domain;
1407 info->domain_info.dns_domain.string = dns_domain;
1408 info->domain_info.dns_forest.string = dns_domain;
1409 info->domain_info.domain_guid = domain_guid;
1410 info->domain_info.sid = &domain_sid;
1412 info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
1413 info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1415 if (dns_domain != NULL) {
1417 * We just assume all AD domains are
1418 * NETR_TRUST_FLAG_NATIVE these days.
1420 * This isn't used anyway for now.
1422 info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
1424 info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
1426 server = info->domain_info.dns_domain.string;
1428 info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1430 server = talloc_asprintf(info,
1434 if (server == NULL) {
1435 DBG_ERR("talloc_asprintf(%s#%02X) failed\n",
1436 domain, NBT_NAME_PDC);
1437 dbwrap_transaction_cancel(db);
1441 return NT_STATUS_NO_MEMORY;
1444 info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
1446 info->join_time = 0;
1449 * We don't have enough information about the configured
1452 info->supported_enc_types = 0;
1453 info->salt_principal = NULL;
1454 if (info->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
1457 p = kerberos_secrets_fetch_salt_princ();
1459 dbwrap_transaction_cancel(db);
1463 return NT_STATUS_INTERNAL_ERROR;
1465 info->salt_principal = talloc_strdup(info, p);
1467 if (info->salt_principal == NULL) {
1468 dbwrap_transaction_cancel(db);
1472 return NT_STATUS_NO_MEMORY;
1476 info->password_last_change = last_set_nt;
1477 info->password_changes = 1;
1478 info->next_change = NULL;
1480 status = secrets_domain_info_password_create(info,
1482 info->salt_principal,
1483 last_set_nt, server,
1486 if (!NT_STATUS_IS_OK(status)) {
1487 DBG_ERR("secrets_domain_info_password_create(pw) failed "
1488 "for %s - %s\n", domain, nt_errstr(status));
1489 dbwrap_transaction_cancel(db);
1496 * After a join we don't have old passwords.
1498 if (old_pw != NULL) {
1499 status = secrets_domain_info_password_create(info,
1501 info->salt_principal,
1503 &info->old_password);
1505 if (!NT_STATUS_IS_OK(status)) {
1506 DBG_ERR("secrets_domain_info_password_create(old) failed "
1507 "for %s - %s\n", domain, nt_errstr(status));
1508 dbwrap_transaction_cancel(db);
1512 info->password_changes += 1;
1514 info->old_password = NULL;
1516 info->older_password = NULL;
1518 secrets_debug_domain_info(DBGLVL_INFO, info, "upgrade");
1520 status = secrets_store_domain_info(info, true /* upgrade */);
1521 if (!NT_STATUS_IS_OK(status)) {
1522 DBG_ERR("secrets_store_domain_info() failed "
1523 "for %s - %s\n", domain, nt_errstr(status));
1524 dbwrap_transaction_cancel(db);
1530 * We now reparse it.
1532 status = secrets_fetch_domain_info(domain, frame, &info);
1533 if (!NT_STATUS_IS_OK(status)) {
1534 DBG_ERR("secrets_fetch_domain_info() failed "
1535 "for %s - %s\n", domain, nt_errstr(status));
1536 dbwrap_transaction_cancel(db);
1541 ret = dbwrap_transaction_commit(db);
1543 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1545 dbwrap_transaction_cancel(db);
1547 return NT_STATUS_INTERNAL_DB_ERROR;
1550 *pinfo = talloc_move(mem_ctx, &info);
1552 return NT_STATUS_OK;
1555 NTSTATUS secrets_store_JoinCtx(const struct libnet_JoinCtx *r)
1557 TALLOC_CTX *frame = talloc_stackframe();
1558 struct secrets_domain_info1 *old = NULL;
1559 struct secrets_domain_info1 *info = NULL;
1560 struct db_context *db = NULL;
1561 struct timeval tv = timeval_current();
1562 NTTIME now = timeval_to_nttime(&tv);
1563 const char *domain = r->out.netbios_domain_name;
1567 info = talloc_zero(frame, struct secrets_domain_info1);
1569 DBG_ERR("talloc_zero failed\n");
1571 return NT_STATUS_NO_MEMORY;
1574 info->computer_name = r->in.machine_name;
1575 info->account_name = r->out.account_name;
1576 info->secure_channel_type = r->in.secure_channel_type;
1578 info->domain_info.name.string =
1579 r->out.netbios_domain_name;
1580 info->domain_info.dns_domain.string =
1581 r->out.dns_domain_name;
1582 info->domain_info.dns_forest.string =
1584 info->domain_info.domain_guid = r->out.domain_guid;
1585 info->domain_info.sid = r->out.domain_sid;
1587 info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
1588 info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1589 if (r->out.domain_is_ad) {
1591 * We just assume all AD domains are
1592 * NETR_TRUST_FLAG_NATIVE these days.
1594 * This isn't used anyway for now.
1596 info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
1598 info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
1600 info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1602 info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
1604 info->join_time = now;
1606 info->supported_enc_types = r->out.set_encryption_types;
1607 info->salt_principal = r->out.krb5_salt;
1609 if (info->salt_principal == NULL && r->out.domain_is_ad) {
1612 ret = smb_krb5_salt_principal(info->domain_info.dns_domain.string,
1614 NULL /* userPrincipalName */,
1615 UF_WORKSTATION_TRUST_ACCOUNT,
1618 status = krb5_to_nt_status(ret);
1619 DBG_ERR("smb_krb5_salt_principal() failed "
1620 "for %s - %s\n", domain, nt_errstr(status));
1624 info->salt_principal = p;
1627 info->password_last_change = now;
1628 info->password_changes = 1;
1629 info->next_change = NULL;
1631 status = secrets_domain_info_password_create(info,
1632 r->in.machine_password,
1633 info->salt_principal,
1636 if (!NT_STATUS_IS_OK(status)) {
1637 DBG_ERR("secrets_domain_info_password_create(pw) failed "
1638 "for %s - %s\n", domain, nt_errstr(status));
1643 db = secrets_db_ctx();
1645 ret = dbwrap_transaction_start(db);
1647 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1650 return NT_STATUS_INTERNAL_DB_ERROR;
1653 status = secrets_fetch_or_upgrade_domain_info(domain, frame, &old);
1654 if (NT_STATUS_EQUAL(status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
1655 DBG_DEBUG("no old join for domain(%s) available\n",
1658 } else if (!NT_STATUS_IS_OK(status)) {
1659 DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
1661 dbwrap_transaction_cancel(db);
1667 * We reuse values from an old join, so that
1668 * we still accept already granted kerberos tickets.
1671 info->old_password = old->password;
1672 info->older_password = old->old_password;
1675 secrets_debug_domain_info(DBGLVL_INFO, info, "join");
1677 status = secrets_store_domain_info(info, false /* upgrade */);
1678 if (!NT_STATUS_IS_OK(status)) {
1679 DBG_ERR("secrets_store_domain_info() failed "
1680 "for %s - %s\n", domain, nt_errstr(status));
1681 dbwrap_transaction_cancel(db);
1686 ret = dbwrap_transaction_commit(db);
1688 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1691 return NT_STATUS_INTERNAL_DB_ERROR;
1695 return NT_STATUS_OK;
1698 NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname,
1699 const char *cleartext_unix,
1700 TALLOC_CTX *mem_ctx,
1701 struct secrets_domain_info1 **pinfo,
1702 struct secrets_domain_info1_change **pprev)
1704 TALLOC_CTX *frame = talloc_stackframe();
1705 struct db_context *db = NULL;
1706 struct secrets_domain_info1 *info = NULL;
1707 struct secrets_domain_info1_change *prev = NULL;
1708 struct secrets_domain_info1_change *next = NULL;
1709 struct timeval tv = timeval_current();
1710 NTTIME now = timeval_to_nttime(&tv);
1714 db = secrets_db_ctx();
1716 ret = dbwrap_transaction_start(db);
1718 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1721 return NT_STATUS_INTERNAL_DB_ERROR;
1724 status = secrets_fetch_or_upgrade_domain_info(domain, frame, &info);
1725 if (!NT_STATUS_IS_OK(status)) {
1726 DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
1728 dbwrap_transaction_cancel(db);
1733 prev = info->next_change;
1734 info->next_change = NULL;
1736 next = talloc_zero(frame, struct secrets_domain_info1_change);
1738 DBG_ERR("talloc_zero failed\n");
1740 return NT_STATUS_NO_MEMORY;
1746 status = secrets_domain_info_password_create(next,
1748 info->salt_principal,
1751 if (!NT_STATUS_IS_OK(status)) {
1752 DBG_ERR("secrets_domain_info_password_create(next) failed "
1753 "for %s - %s\n", domain, nt_errstr(status));
1754 dbwrap_transaction_cancel(db);
1760 next->local_status = NT_STATUS_OK;
1761 next->remote_status = NT_STATUS_NOT_COMMITTED;
1762 next->change_time = now;
1763 next->change_server = dcname;
1765 info->next_change = next;
1767 secrets_debug_domain_info(DBGLVL_INFO, info, "prepare_change");
1769 status = secrets_store_domain_info(info, false /* upgrade */);
1770 if (!NT_STATUS_IS_OK(status)) {
1771 DBG_ERR("secrets_store_domain_info() failed "
1772 "for %s - %s\n", domain, nt_errstr(status));
1773 dbwrap_transaction_cancel(db);
1779 * We now reparse it.
1781 status = secrets_fetch_domain_info(domain, frame, &info);
1782 if (!NT_STATUS_IS_OK(status)) {
1783 DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
1784 dbwrap_transaction_cancel(db);
1789 ret = dbwrap_transaction_commit(db);
1791 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1794 return NT_STATUS_INTERNAL_DB_ERROR;
1797 *pinfo = talloc_move(mem_ctx, &info);
1799 *pprev = talloc_move(mem_ctx, &prev);
1805 return NT_STATUS_OK;
1808 static NTSTATUS secrets_check_password_change(const struct secrets_domain_info1 *cookie,
1809 TALLOC_CTX *mem_ctx,
1810 struct secrets_domain_info1 **pstored)
1812 const char *domain = cookie->domain_info.name.string;
1813 struct secrets_domain_info1 *stored = NULL;
1814 struct secrets_domain_info1_change *sn = NULL;
1815 struct secrets_domain_info1_change *cn = NULL;
1819 if (cookie->next_change == NULL) {
1820 DBG_ERR("cookie->next_change == NULL for %s.\n", domain);
1821 return NT_STATUS_INTERNAL_ERROR;
1824 if (cookie->next_change->password == NULL) {
1825 DBG_ERR("cookie->next_change->password == NULL for %s.\n", domain);
1826 return NT_STATUS_INTERNAL_ERROR;
1829 if (cookie->password == NULL) {
1830 DBG_ERR("cookie->password == NULL for %s.\n", domain);
1831 return NT_STATUS_INTERNAL_ERROR;
1835 * Here we check that the given strucure still contains the
1836 * same secrets_domain_info1_change as currently stored.
1838 * There's always a gap between secrets_prepare_password_change()
1839 * and the callers of secrets_check_password_change().
1842 status = secrets_fetch_domain_info(domain, mem_ctx, &stored);
1843 if (!NT_STATUS_IS_OK(status)) {
1844 DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
1848 if (stored->next_change == NULL) {
1850 * We hit a race..., the administrator
1851 * rejoined or something similar happened.
1853 DBG_ERR("stored->next_change == NULL for %s.\n", domain);
1854 TALLOC_FREE(stored);
1855 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1858 if (stored->password_last_change != cookie->password_last_change) {
1859 struct timeval store_tv;
1860 struct timeval_buf store_buf;
1861 struct timeval cookie_tv;
1862 struct timeval_buf cookie_buf;
1864 nttime_to_timeval(&store_tv, stored->password_last_change);
1865 nttime_to_timeval(&cookie_tv, cookie->password_last_change);
1867 DBG_ERR("password_last_change 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),
1871 TALLOC_FREE(stored);
1872 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1875 sn = stored->next_change;
1876 cn = cookie->next_change;
1878 if (sn->change_time != cn->change_time) {
1879 struct timeval store_tv;
1880 struct timeval_buf store_buf;
1881 struct timeval cookie_tv;
1882 struct timeval_buf cookie_buf;
1884 nttime_to_timeval(&store_tv, sn->change_time);
1885 nttime_to_timeval(&cookie_tv, cn->change_time);
1887 DBG_ERR("next change_time differs %s != %s for %s.\n",
1888 timeval_str_buf(&store_tv, false, false, &store_buf),
1889 timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1891 TALLOC_FREE(stored);
1892 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1895 if (sn->password->change_time != cn->password->change_time) {
1896 struct timeval store_tv;
1897 struct timeval_buf store_buf;
1898 struct timeval cookie_tv;
1899 struct timeval_buf cookie_buf;
1901 nttime_to_timeval(&store_tv, sn->password->change_time);
1902 nttime_to_timeval(&cookie_tv, cn->password->change_time);
1904 DBG_ERR("next password.change_time differs %s != %s for %s.\n",
1905 timeval_str_buf(&store_tv, false, false, &store_buf),
1906 timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1908 TALLOC_FREE(stored);
1909 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1912 cmp = memcmp(sn->password->nt_hash.hash,
1913 cn->password->nt_hash.hash,
1916 DBG_ERR("next password.nt_hash differs for %s.\n",
1918 TALLOC_FREE(stored);
1919 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1922 cmp = memcmp(stored->password->nt_hash.hash,
1923 cookie->password->nt_hash.hash,
1926 DBG_ERR("password.nt_hash differs for %s.\n",
1928 TALLOC_FREE(stored);
1929 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1933 return NT_STATUS_OK;
1936 static NTSTATUS secrets_abort_password_change(const char *change_server,
1937 NTSTATUS local_status,
1938 NTSTATUS remote_status,
1939 const struct secrets_domain_info1 *cookie,
1942 const char *domain = cookie->domain_info.name.string;
1943 TALLOC_CTX *frame = talloc_stackframe();
1944 struct db_context *db = NULL;
1945 struct secrets_domain_info1 *info = NULL;
1946 const char *reason = defer ? "defer_change" : "failed_change";
1947 struct timeval tv = timeval_current();
1948 NTTIME now = timeval_to_nttime(&tv);
1952 db = secrets_db_ctx();
1954 ret = dbwrap_transaction_start(db);
1956 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1959 return NT_STATUS_INTERNAL_DB_ERROR;
1963 * secrets_check_password_change()
1964 * checks that cookie->next_change
1965 * is valid and the same as store
1968 status = secrets_check_password_change(cookie, frame, &info);
1969 if (!NT_STATUS_IS_OK(status)) {
1970 DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
1971 dbwrap_transaction_cancel(db);
1977 * Remember the last server and error.
1979 info->next_change->change_server = change_server;
1980 info->next_change->change_time = now;
1981 info->next_change->local_status = local_status;
1982 info->next_change->remote_status = remote_status;
1985 * Make sure the next automatic change is deferred.
1988 info->password_last_change = now;
1991 secrets_debug_domain_info(DBGLVL_WARNING, info, reason);
1993 status = secrets_store_domain_info(info, false /* upgrade */);
1994 if (!NT_STATUS_IS_OK(status)) {
1995 DBG_ERR("secrets_store_domain_info() failed "
1996 "for %s - %s\n", domain, nt_errstr(status));
1997 dbwrap_transaction_cancel(db);
2002 ret = dbwrap_transaction_commit(db);
2004 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
2007 return NT_STATUS_INTERNAL_DB_ERROR;
2011 return NT_STATUS_OK;
2014 NTSTATUS secrets_failed_password_change(const char *change_server,
2015 NTSTATUS local_status,
2016 NTSTATUS remote_status,
2017 const struct secrets_domain_info1 *cookie)
2019 static const bool defer = false;
2020 return secrets_abort_password_change(change_server,
2026 NTSTATUS secrets_defer_password_change(const char *change_server,
2027 NTSTATUS local_status,
2028 NTSTATUS remote_status,
2029 const struct secrets_domain_info1 *cookie)
2031 static const bool defer = true;
2032 return secrets_abort_password_change(change_server,
2038 NTSTATUS secrets_finish_password_change(const char *change_server,
2040 const struct secrets_domain_info1 *cookie)
2042 const char *domain = cookie->domain_info.name.string;
2043 TALLOC_CTX *frame = talloc_stackframe();
2044 struct db_context *db = NULL;
2045 struct secrets_domain_info1 *info = NULL;
2046 struct secrets_domain_info1_change *nc = NULL;
2050 db = secrets_db_ctx();
2052 ret = dbwrap_transaction_start(db);
2054 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
2057 return NT_STATUS_INTERNAL_DB_ERROR;
2061 * secrets_check_password_change() checks that cookie->next_change is
2062 * valid and the same as store in the database.
2064 status = secrets_check_password_change(cookie, frame, &info);
2065 if (!NT_STATUS_IS_OK(status)) {
2066 DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
2067 dbwrap_transaction_cancel(db);
2072 nc = info->next_change;
2074 nc->password->change_server = change_server;
2075 nc->password->change_time = change_time;
2077 info->password_last_change = change_time;
2078 info->password_changes += 1;
2079 info->next_change = NULL;
2081 info->older_password = info->old_password;
2082 info->old_password = info->password;
2083 info->password = nc->password;
2085 secrets_debug_domain_info(DBGLVL_WARNING, info, "finish_change");
2087 status = secrets_store_domain_info(info, false /* upgrade */);
2088 if (!NT_STATUS_IS_OK(status)) {
2089 DBG_ERR("secrets_store_domain_info() failed "
2090 "for %s - %s\n", domain, nt_errstr(status));
2091 dbwrap_transaction_cancel(db);
2096 ret = dbwrap_transaction_commit(db);
2098 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
2101 return NT_STATUS_INTERNAL_DB_ERROR;
2105 return NT_STATUS_OK;