libsmb: Fix destructor setup in unexpected.c
[Samba.git] / source3 / passdb / machine_account_secrets.c
blob40511f96a8b0ea941be10c2d1b39cc6a770a5520
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"
40 #undef DBGC_CLASS
41 #define DBGC_CLASS DBGC_PASSDB
43 static char *domain_info_keystr(const char *domain);
45 static char *des_salt_key(const char *realm);
47 /**
48 * Form a key for fetching the domain sid
50 * @param domain domain name
52 * @return keystring
53 **/
54 static const char *domain_sid_keystr(const char *domain)
56 char *keystr;
58 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
59 SECRETS_DOMAIN_SID, domain);
60 SMB_ASSERT(keystr != NULL);
61 return keystr;
64 static const char *domain_guid_keystr(const char *domain)
66 char *keystr;
68 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
69 SECRETS_DOMAIN_GUID, domain);
70 SMB_ASSERT(keystr != NULL);
71 return keystr;
74 static const char *protect_ids_keystr(const char *domain)
76 char *keystr;
78 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
79 SECRETS_PROTECT_IDS, domain);
80 SMB_ASSERT(keystr != NULL);
81 return keystr;
84 /* N O T E: never use this outside of passdb modules that store the SID on their own */
85 bool secrets_mark_domain_protected(const char *domain)
87 bool ret;
89 ret = secrets_store(protect_ids_keystr(domain), "TRUE", 5);
90 if (!ret) {
91 DEBUG(0, ("Failed to protect the Domain IDs\n"));
93 return ret;
96 bool secrets_clear_domain_protection(const char *domain)
98 bool ret;
99 void *protection = secrets_fetch(protect_ids_keystr(domain), NULL);
101 if (protection) {
102 SAFE_FREE(protection);
103 ret = secrets_delete_entry(protect_ids_keystr(domain));
104 if (!ret) {
105 DEBUG(0, ("Failed to remove Domain IDs protection\n"));
107 return ret;
109 return true;
112 bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
114 char *protect_ids;
115 bool ret;
117 protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
118 if (protect_ids) {
119 if (strncmp(protect_ids, "TRUE", 4)) {
120 DEBUG(0, ("Refusing to store a Domain SID, "
121 "it has been marked as protected!\n"));
122 SAFE_FREE(protect_ids);
123 return false;
126 SAFE_FREE(protect_ids);
128 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
130 /* Force a re-query, in the case where we modified our domain */
131 if (ret) {
132 if (dom_sid_equal(get_global_sam_sid(), sid) == false) {
133 reset_global_sam_sid();
136 return ret;
139 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
141 struct dom_sid *dyn_sid;
142 size_t size = 0;
144 dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
146 if (dyn_sid == NULL)
147 return False;
149 if (size != sizeof(struct dom_sid)) {
150 SAFE_FREE(dyn_sid);
151 return False;
154 *sid = *dyn_sid;
155 SAFE_FREE(dyn_sid);
156 return True;
159 bool secrets_store_domain_guid(const char *domain, const struct GUID *guid)
161 char *protect_ids;
162 const char *key;
164 protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
165 if (protect_ids) {
166 if (strncmp(protect_ids, "TRUE", 4)) {
167 DEBUG(0, ("Refusing to store a Domain SID, "
168 "it has been marked as protected!\n"));
169 SAFE_FREE(protect_ids);
170 return false;
173 SAFE_FREE(protect_ids);
175 key = domain_guid_keystr(domain);
176 return secrets_store(key, guid, sizeof(struct GUID));
179 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
181 struct GUID *dyn_guid;
182 const char *key;
183 size_t size = 0;
184 struct GUID new_guid;
186 key = domain_guid_keystr(domain);
187 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
189 if (!dyn_guid) {
190 if (lp_server_role() == ROLE_DOMAIN_PDC) {
191 new_guid = GUID_random();
192 if (!secrets_store_domain_guid(domain, &new_guid))
193 return False;
194 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
196 if (dyn_guid == NULL) {
197 return False;
201 if (size != sizeof(struct GUID)) {
202 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
203 SAFE_FREE(dyn_guid);
204 return False;
207 *guid = *dyn_guid;
208 SAFE_FREE(dyn_guid);
209 return True;
213 * Form a key for fetching the machine trust account sec channel type
215 * @param domain domain name
217 * @return keystring
219 static const char *machine_sec_channel_type_keystr(const char *domain)
221 char *keystr;
223 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
224 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
225 domain);
226 SMB_ASSERT(keystr != NULL);
227 return keystr;
231 * Form a key for fetching the machine trust account last change time
233 * @param domain domain name
235 * @return keystring
237 static const char *machine_last_change_time_keystr(const char *domain)
239 char *keystr;
241 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
242 SECRETS_MACHINE_LAST_CHANGE_TIME,
243 domain);
244 SMB_ASSERT(keystr != NULL);
245 return keystr;
250 * Form a key for fetching the machine previous trust account password
252 * @param domain domain name
254 * @return keystring
256 static const char *machine_prev_password_keystr(const char *domain)
258 char *keystr;
260 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
261 SECRETS_MACHINE_PASSWORD_PREV, domain);
262 SMB_ASSERT(keystr != NULL);
263 return keystr;
267 * Form a key for fetching the machine trust account password
269 * @param domain domain name
271 * @return keystring
273 static const char *machine_password_keystr(const char *domain)
275 char *keystr;
277 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
278 SECRETS_MACHINE_PASSWORD, domain);
279 SMB_ASSERT(keystr != NULL);
280 return keystr;
284 * Form a key for fetching the machine trust account password
286 * @param domain domain name
288 * @return stored password's key
290 static const char *trust_keystr(const char *domain)
292 char *keystr;
294 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
295 SECRETS_MACHINE_ACCT_PASS, domain);
296 SMB_ASSERT(keystr != NULL);
297 return keystr;
300 /************************************************************************
301 Routine to get the default secure channel type for trust accounts
302 ************************************************************************/
304 enum netr_SchannelType get_default_sec_channel(void)
306 if (lp_server_role() == ROLE_DOMAIN_BDC ||
307 lp_server_role() == ROLE_DOMAIN_PDC ||
308 lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
309 return SEC_CHAN_BDC;
310 } else {
311 return SEC_CHAN_WKSTA;
315 /************************************************************************
316 Routine to get the trust account password for a domain.
317 This only tries to get the legacy hashed version of the password.
318 The user of this function must have locked the trust password file using
319 the above secrets_lock_trust_account_password().
320 ************************************************************************/
322 bool secrets_fetch_trust_account_password_legacy(const char *domain,
323 uint8_t ret_pwd[16],
324 time_t *pass_last_set_time,
325 enum netr_SchannelType *channel)
327 struct machine_acct_pass *pass;
328 size_t size = 0;
330 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
331 trust_keystr(domain), &size))) {
332 DEBUG(5, ("secrets_fetch failed!\n"));
333 return False;
336 if (size != sizeof(*pass)) {
337 DEBUG(0, ("secrets were of incorrect size!\n"));
338 SAFE_FREE(pass);
339 return False;
342 if (pass_last_set_time) {
343 *pass_last_set_time = pass->mod_time;
345 memcpy(ret_pwd, pass->hash, 16);
347 if (channel) {
348 *channel = get_default_sec_channel();
351 SAFE_FREE(pass);
352 return True;
355 /************************************************************************
356 Routine to get the trust account password for a domain.
357 The user of this function must have locked the trust password file using
358 the above secrets_lock_trust_account_password().
359 ************************************************************************/
361 bool secrets_fetch_trust_account_password(const char *domain, uint8_t ret_pwd[16],
362 time_t *pass_last_set_time,
363 enum netr_SchannelType *channel)
365 char *plaintext;
367 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
368 channel);
369 if (plaintext) {
370 DEBUG(4,("Using cleartext machine password\n"));
371 E_md4hash(plaintext, ret_pwd);
372 SAFE_FREE(plaintext);
373 return True;
376 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
377 pass_last_set_time,
378 channel);
381 /************************************************************************
382 Routine to delete all information related to the domain joined machine.
383 ************************************************************************/
385 bool secrets_delete_machine_password_ex(const char *domain, const char *realm)
387 const char *tmpkey = NULL;
388 bool ok;
390 tmpkey = domain_info_keystr(domain);
391 ok = secrets_delete(tmpkey);
392 if (!ok) {
393 return false;
396 if (realm != NULL) {
397 tmpkey = des_salt_key(domain);
398 ok = secrets_delete(tmpkey);
399 if (!ok) {
400 return false;
404 tmpkey = domain_guid_keystr(domain);
405 ok = secrets_delete(tmpkey);
406 if (!ok) {
407 return false;
410 tmpkey = machine_prev_password_keystr(domain);
411 ok = secrets_delete(tmpkey);
412 if (!ok) {
413 return false;
416 tmpkey = machine_password_keystr(domain);
417 ok = secrets_delete(tmpkey);
418 if (!ok) {
419 return false;
422 tmpkey = machine_sec_channel_type_keystr(domain);
423 ok = secrets_delete(tmpkey);
424 if (!ok) {
425 return false;
428 tmpkey = machine_last_change_time_keystr(domain);
429 ok = secrets_delete(tmpkey);
430 if (!ok) {
431 return false;
434 tmpkey = domain_sid_keystr(domain);
435 ok = secrets_delete(tmpkey);
436 if (!ok) {
437 return false;
440 return true;
443 /************************************************************************
444 Routine to delete the domain sid
445 ************************************************************************/
447 bool secrets_delete_domain_sid(const char *domain)
449 return secrets_delete_entry(domain_sid_keystr(domain));
452 /************************************************************************
453 Set the machine trust account password, the old pw and last change
454 time, domain SID and salting principals based on values passed in
455 (added to supprt the secrets_tdb_sync module on secrets.ldb)
456 ************************************************************************/
458 bool secrets_store_machine_pw_sync(const char *pass, const char *oldpass, const char *domain,
459 const char *realm,
460 const char *salting_principal, uint32_t supported_enc_types,
461 const struct dom_sid *domain_sid, uint32_t last_change_time,
462 uint32_t secure_channel_type,
463 bool delete_join)
465 bool ret;
466 uint8_t last_change_time_store[4];
467 TALLOC_CTX *frame = talloc_stackframe();
468 uint8_t sec_channel_bytes[4];
470 if (delete_join) {
471 secrets_delete_machine_password_ex(domain, realm);
472 TALLOC_FREE(frame);
473 return true;
476 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
477 if (!ret) {
478 TALLOC_FREE(frame);
479 return ret;
482 if (oldpass) {
483 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
484 } else {
485 ret = secrets_delete(machine_prev_password_keystr(domain));
487 if (!ret) {
488 TALLOC_FREE(frame);
489 return ret;
492 if (secure_channel_type == 0) {
493 /* We delete this and instead have the read code fall back to
494 * a default based on server role, as our caller can't specify
495 * this with any more certainty */
496 ret = secrets_delete(machine_sec_channel_type_keystr(domain));
497 if (!ret) {
498 TALLOC_FREE(frame);
499 return ret;
501 } else {
502 SIVAL(&sec_channel_bytes, 0, secure_channel_type);
503 ret = secrets_store(machine_sec_channel_type_keystr(domain),
504 &sec_channel_bytes, sizeof(sec_channel_bytes));
505 if (!ret) {
506 TALLOC_FREE(frame);
507 return ret;
511 SIVAL(&last_change_time_store, 0, last_change_time);
512 ret = secrets_store(machine_last_change_time_keystr(domain),
513 &last_change_time_store, sizeof(last_change_time));
515 if (!ret) {
516 TALLOC_FREE(frame);
517 return ret;
520 ret = secrets_store_domain_sid(domain, domain_sid);
522 if (!ret) {
523 TALLOC_FREE(frame);
524 return ret;
527 if (realm != NULL) {
528 char *key = des_salt_key(realm);
530 if (salting_principal != NULL) {
531 ret = secrets_store(key,
532 salting_principal,
533 strlen(salting_principal)+1);
534 } else {
535 ret = secrets_delete(key);
539 TALLOC_FREE(frame);
540 return ret;
543 /************************************************************************
544 Return the standard DES salt key
545 ************************************************************************/
547 char* kerberos_standard_des_salt( void )
549 fstring salt;
551 fstr_sprintf( salt, "host/%s.%s@", lp_netbios_name(), lp_realm() );
552 (void)strlower_m( salt );
553 fstrcat( salt, lp_realm() );
555 return SMB_STRDUP( salt );
558 /************************************************************************
559 ************************************************************************/
561 static char *des_salt_key(const char *realm)
563 char *keystr;
565 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/DES/%s",
566 SECRETS_SALTING_PRINCIPAL,
567 realm);
568 SMB_ASSERT(keystr != NULL);
569 return keystr;
572 /************************************************************************
573 ************************************************************************/
575 bool kerberos_secrets_store_des_salt( const char* salt )
577 char* key;
578 bool ret;
580 key = des_salt_key(lp_realm());
581 if (key == NULL) {
582 DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n"));
583 return False;
586 if ( !salt ) {
587 DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n"));
588 secrets_delete_entry( key );
589 return True;
592 DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt));
594 ret = secrets_store( key, salt, strlen(salt)+1 );
596 TALLOC_FREE(key);
598 return ret;
601 /************************************************************************
602 ************************************************************************/
604 static
605 char* kerberos_secrets_fetch_des_salt( void )
607 char *salt, *key;
609 key = des_salt_key(lp_realm());
610 if (key == NULL) {
611 DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
612 return NULL;
615 salt = (char*)secrets_fetch( key, NULL );
617 TALLOC_FREE(key);
619 return salt;
622 /************************************************************************
623 Routine to get the salting principal for this service.
624 Caller must free if return is not null.
625 ************************************************************************/
627 char *kerberos_secrets_fetch_salt_princ(void)
629 char *salt_princ_s;
630 /* lookup new key first */
632 salt_princ_s = kerberos_secrets_fetch_des_salt();
633 if (salt_princ_s == NULL) {
634 /* fall back to host/machine.realm@REALM */
635 salt_princ_s = kerberos_standard_des_salt();
638 return salt_princ_s;
641 /************************************************************************
642 Routine to fetch the previous plaintext machine account password for a realm
643 the password is assumed to be a null terminated ascii string.
644 ************************************************************************/
646 char *secrets_fetch_prev_machine_password(const char *domain)
648 return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
651 /************************************************************************
652 Routine to fetch the last change time of the machine account password
653 for a realm
654 ************************************************************************/
656 time_t secrets_fetch_pass_last_set_time(const char *domain)
658 uint32_t *last_set_time;
659 time_t pass_last_set_time;
661 last_set_time = secrets_fetch(machine_last_change_time_keystr(domain),
662 NULL);
663 if (last_set_time) {
664 pass_last_set_time = IVAL(last_set_time,0);
665 SAFE_FREE(last_set_time);
666 } else {
667 pass_last_set_time = 0;
670 return pass_last_set_time;
673 /************************************************************************
674 Routine to fetch the plaintext machine account password for a realm
675 the password is assumed to be a null terminated ascii string.
676 ************************************************************************/
678 char *secrets_fetch_machine_password(const char *domain,
679 time_t *pass_last_set_time,
680 enum netr_SchannelType *channel)
682 char *ret;
683 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
685 if (pass_last_set_time) {
686 *pass_last_set_time = secrets_fetch_pass_last_set_time(domain);
689 if (channel) {
690 size_t size;
691 uint32_t *channel_type;
692 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
693 if (channel_type) {
694 *channel = IVAL(channel_type,0);
695 SAFE_FREE(channel_type);
696 } else {
697 *channel = get_default_sec_channel();
701 return ret;
704 static char *domain_info_keystr(const char *domain)
706 char *keystr;
708 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
709 SECRETS_MACHINE_DOMAIN_INFO,
710 domain);
711 SMB_ASSERT(keystr != NULL);
712 return keystr;
715 /************************************************************************
716 Routine to get account password to trusted domain
717 ************************************************************************/
719 static NTSTATUS secrets_fetch_domain_info1_by_key(const char *key,
720 TALLOC_CTX *mem_ctx,
721 struct secrets_domain_info1 **_info1)
723 struct secrets_domain_infoB sdib = { .version = 0, };
724 enum ndr_err_code ndr_err;
725 /* unpacking structures */
726 DATA_BLOB blob;
728 /* fetching trusted domain password structure */
729 blob.data = (uint8_t *)secrets_fetch(key, &blob.length);
730 if (blob.data == NULL) {
731 DBG_NOTICE("secrets_fetch failed!\n");
732 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
735 /* unpack trusted domain password */
736 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sdib,
737 (ndr_pull_flags_fn_t)ndr_pull_secrets_domain_infoB);
738 SAFE_FREE(blob.data);
739 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
740 DBG_ERR("ndr_pull_struct_blob failed - %s!\n",
741 ndr_errstr(ndr_err));
742 return NT_STATUS_INTERNAL_DB_CORRUPTION;
745 if (sdib.version != SECRETS_DOMAIN_INFO_VERSION_1) {
746 DBG_ERR("sdib.version = %u\n", (unsigned)sdib.version);
747 return NT_STATUS_INTERNAL_DB_CORRUPTION;
750 *_info1 = sdib.info.info1;
751 return NT_STATUS_OK;;
754 static NTSTATUS secrets_fetch_domain_info(const char *domain,
755 TALLOC_CTX *mem_ctx,
756 struct secrets_domain_info1 **pinfo)
758 char *key = domain_info_keystr(domain);
759 return secrets_fetch_domain_info1_by_key(key, mem_ctx, pinfo);
762 void secrets_debug_domain_info(int lvl, const struct secrets_domain_info1 *info1,
763 const char *name)
765 struct secrets_domain_infoB sdib = {
766 .version = SECRETS_DOMAIN_INFO_VERSION_1,
769 sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
771 ndr_print_debug((ndr_print_fn_t)ndr_print_secrets_domain_infoB,
772 name, &sdib);
775 char *secrets_domain_info_string(TALLOC_CTX *mem_ctx, const struct secrets_domain_info1 *info1,
776 const char *name, bool include_secrets)
778 TALLOC_CTX *frame = talloc_stackframe();
779 struct secrets_domain_infoB sdib = {
780 .version = SECRETS_DOMAIN_INFO_VERSION_1,
782 struct ndr_print *ndr = NULL;
783 char *ret = NULL;
785 sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
787 ndr = talloc_zero(frame, struct ndr_print);
788 if (ndr == NULL) {
789 TALLOC_FREE(frame);
790 return NULL;
792 ndr->private_data = talloc_strdup(ndr, "");
793 if (ndr->private_data == NULL) {
794 TALLOC_FREE(frame);
795 return NULL;
797 ndr->print = ndr_print_string_helper;
798 ndr->depth = 1;
799 ndr->print_secrets = include_secrets;
801 ndr_print_secrets_domain_infoB(ndr, name, &sdib);
802 ret = talloc_steal(mem_ctx, (char *)ndr->private_data);
803 TALLOC_FREE(frame);
804 return ret;
807 static NTSTATUS secrets_store_domain_info1_by_key(const char *key,
808 const struct secrets_domain_info1 *info1)
810 struct secrets_domain_infoB sdib = {
811 .version = SECRETS_DOMAIN_INFO_VERSION_1,
813 /* packing structures */
814 DATA_BLOB blob;
815 enum ndr_err_code ndr_err;
816 bool ok;
818 sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
820 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &sdib,
821 (ndr_push_flags_fn_t)ndr_push_secrets_domain_infoB);
822 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
823 return ndr_map_error2ntstatus(ndr_err);
826 ok = secrets_store(key, blob.data, blob.length);
827 data_blob_clear_free(&blob);
828 if (!ok) {
829 return NT_STATUS_INTERNAL_DB_ERROR;
832 return NT_STATUS_OK;
835 static NTSTATUS secrets_store_domain_info(const struct secrets_domain_info1 *info,
836 bool upgrade)
838 TALLOC_CTX *frame = talloc_stackframe();
839 const char *domain = info->domain_info.name.string;
840 const char *realm = info->domain_info.dns_domain.string;
841 char *key = domain_info_keystr(domain);
842 struct db_context *db = NULL;
843 struct timeval last_change_tv;
844 const DATA_BLOB *cleartext_blob = NULL;
845 DATA_BLOB pw_blob = data_blob_null;
846 DATA_BLOB old_pw_blob = data_blob_null;
847 const char *pw = NULL;
848 const char *old_pw = NULL;
849 bool ok;
850 NTSTATUS status;
851 int ret;
852 int role = lp_server_role();
854 switch (info->secure_channel_type) {
855 case SEC_CHAN_WKSTA:
856 case SEC_CHAN_BDC:
857 if (!upgrade && role >= ROLE_ACTIVE_DIRECTORY_DC) {
858 DBG_ERR("AD_DC not supported for %s\n",
859 domain);
860 TALLOC_FREE(frame);
861 return NT_STATUS_INTERNAL_ERROR;
864 break;
865 default:
866 DBG_ERR("SEC_CHAN_* not supported for %s\n",
867 domain);
868 TALLOC_FREE(frame);
869 return NT_STATUS_INTERNAL_ERROR;
872 db = secrets_db_ctx();
874 ret = dbwrap_transaction_start(db);
875 if (ret != 0) {
876 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
877 domain);
878 TALLOC_FREE(frame);
879 return NT_STATUS_INTERNAL_DB_ERROR;
882 ok = secrets_clear_domain_protection(domain);
883 if (!ok) {
884 DBG_ERR("secrets_clear_domain_protection(%s) failed\n",
885 domain);
886 dbwrap_transaction_cancel(db);
887 TALLOC_FREE(frame);
888 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
891 ok = secrets_delete_machine_password_ex(domain, realm);
892 if (!ok) {
893 DBG_ERR("secrets_delete_machine_password_ex(%s) failed\n",
894 domain);
895 dbwrap_transaction_cancel(db);
896 TALLOC_FREE(frame);
897 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
900 status = secrets_store_domain_info1_by_key(key, info);
901 if (!NT_STATUS_IS_OK(status)) {
902 DBG_ERR("secrets_store_domain_info1_by_key() failed "
903 "for %s - %s\n", domain, nt_errstr(status));
904 dbwrap_transaction_cancel(db);
905 TALLOC_FREE(frame);
906 return status;
910 * We use info->password_last_change instead
911 * of info->password.change_time because
912 * we may want to defer the next change approach
913 * if the server rejected the change the last time,
914 * e.g. due to RefusePasswordChange=1.
916 nttime_to_timeval(&last_change_tv, info->password_last_change);
918 cleartext_blob = &info->password->cleartext_blob;
919 ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
920 cleartext_blob->data,
921 cleartext_blob->length,
922 (void **)&pw_blob.data,
923 &pw_blob.length);
924 if (!ok) {
925 status = NT_STATUS_UNMAPPABLE_CHARACTER;
926 if (errno == ENOMEM) {
927 status = NT_STATUS_NO_MEMORY;
929 DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
930 "failed for pw of %s - %s\n",
931 domain, nt_errstr(status));
932 dbwrap_transaction_cancel(db);
933 TALLOC_FREE(frame);
934 return status;
936 pw = (const char *)pw_blob.data;
937 if (info->old_password != NULL) {
938 cleartext_blob = &info->old_password->cleartext_blob;
939 ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
940 cleartext_blob->data,
941 cleartext_blob->length,
942 (void **)&old_pw_blob.data,
943 &old_pw_blob.length);
944 if (!ok) {
945 status = NT_STATUS_UNMAPPABLE_CHARACTER;
946 if (errno == ENOMEM) {
947 status = NT_STATUS_NO_MEMORY;
949 DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
950 "failed for old_pw of %s - %s\n",
951 domain, nt_errstr(status));
952 dbwrap_transaction_cancel(db);
953 data_blob_clear_free(&pw_blob);
954 TALLOC_FREE(frame);
955 return status;
957 old_pw = (const char *)old_pw_blob.data;
960 ok = secrets_store_machine_pw_sync(pw, old_pw,
961 domain, realm,
962 info->salt_principal,
963 info->supported_enc_types,
964 info->domain_info.sid,
965 last_change_tv.tv_sec,
966 info->secure_channel_type,
967 false); /* delete_join */
968 data_blob_clear_free(&pw_blob);
969 data_blob_clear_free(&old_pw_blob);
970 if (!ok) {
971 DBG_ERR("secrets_store_machine_pw_sync(%s) failed\n",
972 domain);
973 dbwrap_transaction_cancel(db);
974 TALLOC_FREE(frame);
975 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
978 if (!GUID_all_zero(&info->domain_info.domain_guid)) {
979 ok = secrets_store_domain_guid(domain,
980 &info->domain_info.domain_guid);
981 if (!ok) {
982 DBG_ERR("secrets_store_domain_guid(%s) failed\n",
983 domain);
984 dbwrap_transaction_cancel(db);
985 TALLOC_FREE(frame);
986 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
990 ok = secrets_mark_domain_protected(domain);
991 if (!ok) {
992 DBG_ERR("secrets_mark_domain_protected(%s) failed\n",
993 domain);
994 dbwrap_transaction_cancel(db);
995 TALLOC_FREE(frame);
996 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
999 ret = dbwrap_transaction_commit(db);
1000 if (ret != 0) {
1001 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1002 domain);
1003 TALLOC_FREE(frame);
1004 return NT_STATUS_INTERNAL_DB_ERROR;
1007 TALLOC_FREE(frame);
1008 return NT_STATUS_OK;
1011 static int secrets_domain_info_kerberos_keys(struct secrets_domain_info1_password *p,
1012 const char *salt_principal)
1014 #ifdef HAVE_ADS
1015 krb5_error_code krb5_ret;
1016 krb5_context krb5_ctx = NULL;
1017 DATA_BLOB cleartext_utf8_b = data_blob_null;
1018 krb5_data cleartext_utf8;
1019 krb5_data salt;
1020 krb5_keyblock key;
1021 DATA_BLOB aes_256_b = data_blob_null;
1022 DATA_BLOB aes_128_b = data_blob_null;
1023 DATA_BLOB des_md5_b = data_blob_null;
1024 bool ok;
1025 #endif /* HAVE_ADS */
1026 DATA_BLOB arc4_b = data_blob_null;
1027 const uint16_t max_keys = 4;
1028 struct secrets_domain_info1_kerberos_key *keys = NULL;
1029 uint16_t idx = 0;
1030 char *salt_data = NULL;
1033 * We calculate:
1034 * ENCTYPE_AES256_CTS_HMAC_SHA1_96
1035 * ENCTYPE_AES128_CTS_HMAC_SHA1_96
1036 * ENCTYPE_ARCFOUR_HMAC
1037 * ENCTYPE_DES_CBC_MD5
1039 * We don't include ENCTYPE_DES_CBC_CRC
1040 * as W2008R2 also doesn't store it anymore.
1042 * Note we store all enctypes we support,
1043 * including the weak encryption types,
1044 * but that's no problem as we also
1045 * store the cleartext password anyway.
1047 * Which values are then used to construct
1048 * a keytab is configured at runtime and the
1049 * configuration of msDS-SupportedEncryptionTypes.
1051 * If we don't have kerberos support or no
1052 * salt, we only generate an entry for arcfour-hmac-md5.
1054 keys = talloc_zero_array(p,
1055 struct secrets_domain_info1_kerberos_key,
1056 max_keys);
1057 if (keys == NULL) {
1058 return ENOMEM;
1061 arc4_b = data_blob_talloc(keys,
1062 p->nt_hash.hash,
1063 sizeof(p->nt_hash.hash));
1064 if (arc4_b.data == NULL) {
1065 DBG_ERR("data_blob_talloc failed for arcfour-hmac-md5.\n");
1066 TALLOC_FREE(keys);
1067 return ENOMEM;
1070 #ifdef HAVE_ADS
1071 if (salt_principal == NULL) {
1072 goto no_kerberos;
1075 initialize_krb5_error_table();
1076 krb5_ret = krb5_init_context(&krb5_ctx);
1077 if (krb5_ret != 0) {
1078 TALLOC_FREE(keys);
1079 return krb5_ret;
1082 krb5_ret = smb_krb5_salt_principal2data(krb5_ctx, salt_principal,
1083 p, &salt_data);
1084 if (krb5_ret != 0) {
1085 DBG_ERR("smb_krb5_salt_principal2data(%s) failed: %s\n",
1086 salt_principal,
1087 smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1088 krb5_free_context(krb5_ctx);
1089 TALLOC_FREE(keys);
1090 return krb5_ret;
1093 salt = (krb5_data) {
1094 .data = discard_const(salt_data),
1095 .length = strlen(salt_data),
1098 ok = convert_string_talloc(keys, CH_UTF16MUNGED, CH_UTF8,
1099 p->cleartext_blob.data,
1100 p->cleartext_blob.length,
1101 (void **)&cleartext_utf8_b.data,
1102 &cleartext_utf8_b.length);
1103 if (!ok) {
1104 if (errno != 0) {
1105 krb5_ret = errno;
1106 } else {
1107 krb5_ret = EINVAL;
1109 krb5_free_context(krb5_ctx);
1110 TALLOC_FREE(keys);
1111 return krb5_ret;
1113 cleartext_utf8.data = (void *)cleartext_utf8_b.data;
1114 cleartext_utf8.length = cleartext_utf8_b.length;
1116 krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
1117 NULL,
1118 &salt,
1119 &cleartext_utf8,
1120 ENCTYPE_AES256_CTS_HMAC_SHA1_96,
1121 &key);
1122 if (krb5_ret != 0) {
1123 DBG_ERR("generation of a aes256-cts-hmac-sha1-96 key failed: %s\n",
1124 smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1125 krb5_free_context(krb5_ctx);
1126 TALLOC_FREE(keys);
1127 TALLOC_FREE(salt_data);
1128 return krb5_ret;
1130 aes_256_b = data_blob_talloc(keys,
1131 KRB5_KEY_DATA(&key),
1132 KRB5_KEY_LENGTH(&key));
1133 krb5_free_keyblock_contents(krb5_ctx, &key);
1134 if (aes_256_b.data == NULL) {
1135 DBG_ERR("data_blob_talloc failed for aes-256.\n");
1136 krb5_free_context(krb5_ctx);
1137 TALLOC_FREE(keys);
1138 TALLOC_FREE(salt_data);
1139 return ENOMEM;
1142 krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
1143 NULL,
1144 &salt,
1145 &cleartext_utf8,
1146 ENCTYPE_AES128_CTS_HMAC_SHA1_96,
1147 &key);
1148 if (krb5_ret != 0) {
1149 DBG_ERR("generation of a aes128-cts-hmac-sha1-96 key failed: %s\n",
1150 smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1151 krb5_free_context(krb5_ctx);
1152 TALLOC_FREE(keys);
1153 TALLOC_FREE(salt_data);
1154 return krb5_ret;
1156 aes_128_b = data_blob_talloc(keys,
1157 KRB5_KEY_DATA(&key),
1158 KRB5_KEY_LENGTH(&key));
1159 krb5_free_keyblock_contents(krb5_ctx, &key);
1160 if (aes_128_b.data == NULL) {
1161 DBG_ERR("data_blob_talloc failed for aes-128.\n");
1162 krb5_free_context(krb5_ctx);
1163 TALLOC_FREE(keys);
1164 TALLOC_FREE(salt_data);
1165 return ENOMEM;
1168 krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
1169 NULL,
1170 &salt,
1171 &cleartext_utf8,
1172 ENCTYPE_DES_CBC_MD5,
1173 &key);
1174 if (krb5_ret != 0) {
1175 DBG_ERR("generation of a des-cbc-md5 key failed: %s\n",
1176 smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1177 krb5_free_context(krb5_ctx);
1178 TALLOC_FREE(keys);
1179 TALLOC_FREE(salt_data);
1180 return krb5_ret;
1182 des_md5_b = data_blob_talloc(keys,
1183 KRB5_KEY_DATA(&key),
1184 KRB5_KEY_LENGTH(&key));
1185 krb5_free_keyblock_contents(krb5_ctx, &key);
1186 if (des_md5_b.data == NULL) {
1187 DBG_ERR("data_blob_talloc failed for des-cbc-md5.\n");
1188 krb5_free_context(krb5_ctx);
1189 TALLOC_FREE(keys);
1190 TALLOC_FREE(salt_data);
1191 return ENOMEM;
1194 krb5_free_context(krb5_ctx);
1195 no_kerberos:
1197 if (aes_256_b.length != 0) {
1198 keys[idx].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
1199 keys[idx].iteration_count = 4096;
1200 keys[idx].value = aes_256_b;
1201 idx += 1;
1204 if (aes_128_b.length != 0) {
1205 keys[idx].keytype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
1206 keys[idx].iteration_count = 4096;
1207 keys[idx].value = aes_128_b;
1208 idx += 1;
1211 #endif /* HAVE_ADS */
1213 keys[idx].keytype = ENCTYPE_ARCFOUR_HMAC;
1214 keys[idx].iteration_count = 4096;
1215 keys[idx].value = arc4_b;
1216 idx += 1;
1218 #ifdef HAVE_ADS
1219 if (des_md5_b.length != 0) {
1220 keys[idx].keytype = ENCTYPE_DES_CBC_MD5;
1221 keys[idx].iteration_count = 4096;
1222 keys[idx].value = des_md5_b;
1223 idx += 1;
1225 #endif /* HAVE_ADS */
1227 p->salt_data = salt_data;
1228 p->default_iteration_count = 4096;
1229 p->num_keys = idx;
1230 p->keys = keys;
1231 return 0;
1234 static NTSTATUS secrets_domain_info_password_create(TALLOC_CTX *mem_ctx,
1235 const char *cleartext_unix,
1236 const char *salt_principal,
1237 NTTIME change_time,
1238 const char *change_server,
1239 struct secrets_domain_info1_password **_p)
1241 struct secrets_domain_info1_password *p = NULL;
1242 bool ok;
1243 size_t len;
1244 int ret;
1246 if (change_server == NULL) {
1247 return NT_STATUS_INVALID_PARAMETER_MIX;
1250 p = talloc_zero(mem_ctx, struct secrets_domain_info1_password);
1251 if (p == NULL) {
1252 return NT_STATUS_NO_MEMORY;
1254 p->change_time = change_time;
1255 p->change_server = talloc_strdup(p, change_server);
1256 if (p->change_server == NULL) {
1257 TALLOC_FREE(p);
1258 return NT_STATUS_NO_MEMORY;
1260 len = strlen(cleartext_unix);
1261 ok = convert_string_talloc(p, CH_UNIX, CH_UTF16,
1262 cleartext_unix, len,
1263 (void **)&p->cleartext_blob.data,
1264 &p->cleartext_blob.length);
1265 if (!ok) {
1266 NTSTATUS status = NT_STATUS_UNMAPPABLE_CHARACTER;
1267 if (errno == ENOMEM) {
1268 status = NT_STATUS_NO_MEMORY;
1270 TALLOC_FREE(p);
1271 return status;
1273 mdfour(p->nt_hash.hash,
1274 p->cleartext_blob.data,
1275 p->cleartext_blob.length);
1277 ret = secrets_domain_info_kerberos_keys(p, salt_principal);
1278 if (ret != 0) {
1279 NTSTATUS status = krb5_to_nt_status(ret);
1280 TALLOC_FREE(p);
1281 return status;
1284 *_p = p;
1285 return NT_STATUS_OK;
1288 NTSTATUS secrets_fetch_or_upgrade_domain_info(const char *domain,
1289 TALLOC_CTX *mem_ctx,
1290 struct secrets_domain_info1 **pinfo)
1292 TALLOC_CTX *frame = NULL;
1293 struct secrets_domain_info1 *old = NULL;
1294 struct secrets_domain_info1 *info = NULL;
1295 const char *dns_domain = NULL;
1296 const char *server = NULL;
1297 struct db_context *db = NULL;
1298 time_t last_set_time;
1299 NTTIME last_set_nt;
1300 enum netr_SchannelType channel;
1301 char *pw = NULL;
1302 char *old_pw = NULL;
1303 struct dom_sid domain_sid;
1304 struct GUID domain_guid;
1305 bool ok;
1306 NTSTATUS status;
1307 int ret;
1309 ok = strequal(domain, lp_workgroup());
1310 if (ok) {
1311 dns_domain = lp_dnsdomain();
1313 if (dns_domain != NULL && dns_domain[0] == '\0') {
1314 dns_domain = NULL;
1318 last_set_time = secrets_fetch_pass_last_set_time(domain);
1319 if (last_set_time == 0) {
1320 return NT_STATUS_OK;
1322 unix_to_nt_time(&last_set_nt, last_set_time);
1324 frame = talloc_stackframe();
1326 status = secrets_fetch_domain_info(domain, frame, &old);
1327 if (NT_STATUS_IS_OK(status)) {
1328 if (old->password_last_change >= last_set_nt) {
1329 *pinfo = talloc_move(mem_ctx, &old);
1330 TALLOC_FREE(frame);
1331 return NT_STATUS_OK;
1333 TALLOC_FREE(old);
1336 info = talloc_zero(frame, struct secrets_domain_info1);
1337 if (info == NULL) {
1338 DBG_ERR("talloc_zero failed\n");
1339 TALLOC_FREE(frame);
1340 return NT_STATUS_NO_MEMORY;
1343 db = secrets_db_ctx();
1345 ret = dbwrap_transaction_start(db);
1346 if (ret != 0) {
1347 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1348 domain);
1349 TALLOC_FREE(frame);
1350 return NT_STATUS_INTERNAL_DB_ERROR;
1353 pw = secrets_fetch_machine_password(domain,
1354 &last_set_time,
1355 &channel);
1356 if (pw == NULL) {
1357 DBG_ERR("secrets_fetch_machine_password(%s) failed\n",
1358 domain);
1359 dbwrap_transaction_cancel(db);
1360 TALLOC_FREE(frame);
1361 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1363 unix_to_nt_time(&last_set_nt, last_set_time);
1365 old_pw = secrets_fetch_prev_machine_password(domain);
1367 ok = secrets_fetch_domain_sid(domain, &domain_sid);
1368 if (!ok) {
1369 DBG_ERR("secrets_fetch_domain_sid(%s) failed\n",
1370 domain);
1371 dbwrap_transaction_cancel(db);
1372 SAFE_FREE(old_pw);
1373 SAFE_FREE(pw);
1374 TALLOC_FREE(frame);
1375 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1378 ok = secrets_fetch_domain_guid(domain, &domain_guid);
1379 if (!ok) {
1380 domain_guid = GUID_zero();
1383 info->computer_name = lp_netbios_name();
1384 info->account_name = talloc_asprintf(frame, "%s$", info->computer_name);
1385 if (info->account_name == NULL) {
1386 DBG_ERR("talloc_asprintf(%s$) failed\n", info->computer_name);
1387 dbwrap_transaction_cancel(db);
1388 SAFE_FREE(old_pw);
1389 SAFE_FREE(pw);
1390 TALLOC_FREE(frame);
1391 return NT_STATUS_NO_MEMORY;
1393 info->secure_channel_type = channel;
1395 info->domain_info.name.string = domain;
1396 info->domain_info.dns_domain.string = dns_domain;
1397 info->domain_info.dns_forest.string = dns_domain;
1398 info->domain_info.domain_guid = domain_guid;
1399 info->domain_info.sid = &domain_sid;
1401 info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
1402 info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1404 if (dns_domain != NULL) {
1406 * We just assume all AD domains are
1407 * NETR_TRUST_FLAG_NATIVE these days.
1409 * This isn't used anyway for now.
1411 info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
1413 info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
1415 server = info->domain_info.dns_domain.string;
1416 } else {
1417 info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1419 server = talloc_asprintf(info,
1420 "%s#%02X",
1421 domain,
1422 NBT_NAME_PDC);
1423 if (server == NULL) {
1424 DBG_ERR("talloc_asprintf(%s#%02X) failed\n",
1425 domain, NBT_NAME_PDC);
1426 dbwrap_transaction_cancel(db);
1427 SAFE_FREE(pw);
1428 SAFE_FREE(old_pw);
1429 TALLOC_FREE(frame);
1430 return NT_STATUS_NO_MEMORY;
1433 info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
1435 info->join_time = 0;
1438 * We don't have enough information about the configured
1439 * enctypes.
1441 info->supported_enc_types = 0;
1442 info->salt_principal = NULL;
1443 if (info->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
1444 char *p = NULL;
1446 p = kerberos_secrets_fetch_salt_princ();
1447 if (p == NULL) {
1448 dbwrap_transaction_cancel(db);
1449 SAFE_FREE(old_pw);
1450 SAFE_FREE(pw);
1451 TALLOC_FREE(frame);
1452 return NT_STATUS_INTERNAL_ERROR;
1454 info->salt_principal = talloc_strdup(info, p);
1455 SAFE_FREE(p);
1456 if (info->salt_principal == NULL) {
1457 dbwrap_transaction_cancel(db);
1458 SAFE_FREE(pw);
1459 SAFE_FREE(old_pw);
1460 TALLOC_FREE(frame);
1461 return NT_STATUS_NO_MEMORY;
1465 info->password_last_change = last_set_nt;
1466 info->password_changes = 1;
1467 info->next_change = NULL;
1469 status = secrets_domain_info_password_create(info,
1471 info->salt_principal,
1472 last_set_nt, server,
1473 &info->password);
1474 SAFE_FREE(pw);
1475 if (!NT_STATUS_IS_OK(status)) {
1476 DBG_ERR("secrets_domain_info_password_create(pw) failed "
1477 "for %s - %s\n", domain, nt_errstr(status));
1478 dbwrap_transaction_cancel(db);
1479 SAFE_FREE(old_pw);
1480 TALLOC_FREE(frame);
1481 return status;
1485 * After a join we don't have old passwords.
1487 if (old_pw != NULL) {
1488 status = secrets_domain_info_password_create(info,
1489 old_pw,
1490 info->salt_principal,
1491 0, server,
1492 &info->old_password);
1493 SAFE_FREE(old_pw);
1494 if (!NT_STATUS_IS_OK(status)) {
1495 DBG_ERR("secrets_domain_info_password_create(old) failed "
1496 "for %s - %s\n", domain, nt_errstr(status));
1497 dbwrap_transaction_cancel(db);
1498 TALLOC_FREE(frame);
1499 return status;
1501 info->password_changes += 1;
1502 } else {
1503 info->old_password = NULL;
1505 info->older_password = NULL;
1507 secrets_debug_domain_info(DBGLVL_INFO, info, "upgrade");
1509 status = secrets_store_domain_info(info, true /* upgrade */);
1510 if (!NT_STATUS_IS_OK(status)) {
1511 DBG_ERR("secrets_store_domain_info() failed "
1512 "for %s - %s\n", domain, nt_errstr(status));
1513 dbwrap_transaction_cancel(db);
1514 TALLOC_FREE(frame);
1515 return status;
1519 * We now reparse it.
1521 status = secrets_fetch_domain_info(domain, frame, &info);
1522 if (!NT_STATUS_IS_OK(status)) {
1523 DBG_ERR("secrets_fetch_domain_info() failed "
1524 "for %s - %s\n", domain, nt_errstr(status));
1525 dbwrap_transaction_cancel(db);
1526 TALLOC_FREE(frame);
1527 return status;
1530 ret = dbwrap_transaction_commit(db);
1531 if (ret != 0) {
1532 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1533 domain);
1534 dbwrap_transaction_cancel(db);
1535 TALLOC_FREE(frame);
1536 return NT_STATUS_INTERNAL_DB_ERROR;
1539 *pinfo = talloc_move(mem_ctx, &info);
1540 TALLOC_FREE(frame);
1541 return NT_STATUS_OK;
1544 NTSTATUS secrets_store_JoinCtx(const struct libnet_JoinCtx *r)
1546 TALLOC_CTX *frame = talloc_stackframe();
1547 struct secrets_domain_info1 *old = NULL;
1548 struct secrets_domain_info1 *info = NULL;
1549 struct db_context *db = NULL;
1550 struct timeval tv = timeval_current();
1551 NTTIME now = timeval_to_nttime(&tv);
1552 const char *domain = r->out.netbios_domain_name;
1553 NTSTATUS status;
1554 int ret;
1556 info = talloc_zero(frame, struct secrets_domain_info1);
1557 if (info == NULL) {
1558 DBG_ERR("talloc_zero failed\n");
1559 TALLOC_FREE(frame);
1560 return NT_STATUS_NO_MEMORY;
1563 info->computer_name = r->in.machine_name;
1564 info->account_name = r->out.account_name;
1565 info->secure_channel_type = r->in.secure_channel_type;
1567 info->domain_info.name.string =
1568 r->out.netbios_domain_name;
1569 info->domain_info.dns_domain.string =
1570 r->out.dns_domain_name;
1571 info->domain_info.dns_forest.string =
1572 r->out.forest_name;
1573 info->domain_info.domain_guid = r->out.domain_guid;
1574 info->domain_info.sid = r->out.domain_sid;
1576 info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
1577 info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1578 if (r->out.domain_is_ad) {
1580 * We just assume all AD domains are
1581 * NETR_TRUST_FLAG_NATIVE these days.
1583 * This isn't used anyway for now.
1585 info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
1587 info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
1588 } else {
1589 info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1591 info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
1593 info->join_time = now;
1595 info->supported_enc_types = r->out.set_encryption_types;
1596 info->salt_principal = r->out.krb5_salt;
1598 if (info->salt_principal == NULL && r->out.domain_is_ad) {
1599 char *p = NULL;
1601 ret = smb_krb5_salt_principal(info->domain_info.dns_domain.string,
1602 info->account_name,
1603 NULL /* userPrincipalName */,
1604 true /* is_computer */,
1605 info, &p);
1606 if (ret != 0) {
1607 status = krb5_to_nt_status(ret);
1608 DBG_ERR("smb_krb5_salt_principal() failed "
1609 "for %s - %s\n", domain, nt_errstr(status));
1610 TALLOC_FREE(frame);
1611 return status;
1613 info->salt_principal = p;
1616 info->password_last_change = now;
1617 info->password_changes = 1;
1618 info->next_change = NULL;
1620 status = secrets_domain_info_password_create(info,
1621 r->in.machine_password,
1622 info->salt_principal,
1623 now, r->in.dc_name,
1624 &info->password);
1625 if (!NT_STATUS_IS_OK(status)) {
1626 DBG_ERR("secrets_domain_info_password_create(pw) failed "
1627 "for %s - %s\n", domain, nt_errstr(status));
1628 TALLOC_FREE(frame);
1629 return status;
1632 db = secrets_db_ctx();
1634 ret = dbwrap_transaction_start(db);
1635 if (ret != 0) {
1636 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1637 domain);
1638 TALLOC_FREE(frame);
1639 return NT_STATUS_INTERNAL_DB_ERROR;
1642 status = secrets_fetch_or_upgrade_domain_info(domain, frame, &old);
1643 if (NT_STATUS_EQUAL(status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
1644 DBG_DEBUG("no old join for domain(%s) available\n",
1645 domain);
1646 old = NULL;
1647 } else if (!NT_STATUS_IS_OK(status)) {
1648 DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
1649 domain);
1650 dbwrap_transaction_cancel(db);
1651 TALLOC_FREE(frame);
1652 return status;
1656 * We reuse values from an old join, so that
1657 * we still accept already granted kerberos tickets.
1659 if (old != NULL) {
1660 info->old_password = old->password;
1661 info->older_password = old->old_password;
1664 secrets_debug_domain_info(DBGLVL_INFO, info, "join");
1666 status = secrets_store_domain_info(info, false /* upgrade */);
1667 if (!NT_STATUS_IS_OK(status)) {
1668 DBG_ERR("secrets_store_domain_info() failed "
1669 "for %s - %s\n", domain, nt_errstr(status));
1670 dbwrap_transaction_cancel(db);
1671 TALLOC_FREE(frame);
1672 return status;
1675 ret = dbwrap_transaction_commit(db);
1676 if (ret != 0) {
1677 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1678 domain);
1679 TALLOC_FREE(frame);
1680 return NT_STATUS_INTERNAL_DB_ERROR;
1683 TALLOC_FREE(frame);
1684 return NT_STATUS_OK;
1687 NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname,
1688 const char *cleartext_unix,
1689 TALLOC_CTX *mem_ctx,
1690 struct secrets_domain_info1 **pinfo,
1691 struct secrets_domain_info1_change **pprev)
1693 TALLOC_CTX *frame = talloc_stackframe();
1694 struct db_context *db = NULL;
1695 struct secrets_domain_info1 *info = NULL;
1696 struct secrets_domain_info1_change *prev = NULL;
1697 struct secrets_domain_info1_change *next = NULL;
1698 struct timeval tv = timeval_current();
1699 NTTIME now = timeval_to_nttime(&tv);
1700 NTSTATUS status;
1701 int ret;
1703 db = secrets_db_ctx();
1705 ret = dbwrap_transaction_start(db);
1706 if (ret != 0) {
1707 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1708 domain);
1709 TALLOC_FREE(frame);
1710 return NT_STATUS_INTERNAL_DB_ERROR;
1713 status = secrets_fetch_or_upgrade_domain_info(domain, frame, &info);
1714 if (!NT_STATUS_IS_OK(status)) {
1715 DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
1716 domain);
1717 dbwrap_transaction_cancel(db);
1718 TALLOC_FREE(frame);
1719 return status;
1722 prev = info->next_change;
1723 info->next_change = NULL;
1725 next = talloc_zero(frame, struct secrets_domain_info1_change);
1726 if (next == NULL) {
1727 DBG_ERR("talloc_zero failed\n");
1728 TALLOC_FREE(frame);
1729 return NT_STATUS_NO_MEMORY;
1732 if (prev != NULL) {
1733 *next = *prev;
1734 } else {
1735 status = secrets_domain_info_password_create(next,
1736 cleartext_unix,
1737 info->salt_principal,
1738 now, dcname,
1739 &next->password);
1740 if (!NT_STATUS_IS_OK(status)) {
1741 DBG_ERR("secrets_domain_info_password_create(next) failed "
1742 "for %s - %s\n", domain, nt_errstr(status));
1743 dbwrap_transaction_cancel(db);
1744 TALLOC_FREE(frame);
1745 return status;
1749 next->local_status = NT_STATUS_OK;
1750 next->remote_status = NT_STATUS_NOT_COMMITTED;
1751 next->change_time = now;
1752 next->change_server = dcname;
1754 info->next_change = next;
1756 secrets_debug_domain_info(DBGLVL_INFO, info, "prepare_change");
1758 status = secrets_store_domain_info(info, false /* upgrade */);
1759 if (!NT_STATUS_IS_OK(status)) {
1760 DBG_ERR("secrets_store_domain_info() failed "
1761 "for %s - %s\n", domain, nt_errstr(status));
1762 dbwrap_transaction_cancel(db);
1763 TALLOC_FREE(frame);
1764 return status;
1768 * We now reparse it.
1770 status = secrets_fetch_domain_info(domain, frame, &info);
1771 if (!NT_STATUS_IS_OK(status)) {
1772 DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
1773 dbwrap_transaction_cancel(db);
1774 TALLOC_FREE(frame);
1775 return status;
1778 ret = dbwrap_transaction_commit(db);
1779 if (ret != 0) {
1780 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1781 domain);
1782 TALLOC_FREE(frame);
1783 return NT_STATUS_INTERNAL_DB_ERROR;
1786 *pinfo = talloc_move(mem_ctx, &info);
1787 if (prev != NULL) {
1788 *pprev = talloc_move(mem_ctx, &prev);
1789 } else {
1790 *pprev = NULL;
1793 TALLOC_FREE(frame);
1794 return NT_STATUS_OK;
1797 static NTSTATUS secrets_check_password_change(const struct secrets_domain_info1 *cookie,
1798 TALLOC_CTX *mem_ctx,
1799 struct secrets_domain_info1 **pstored)
1801 const char *domain = cookie->domain_info.name.string;
1802 struct secrets_domain_info1 *stored = NULL;
1803 struct secrets_domain_info1_change *sn = NULL;
1804 struct secrets_domain_info1_change *cn = NULL;
1805 NTSTATUS status;
1806 int cmp;
1808 if (cookie->next_change == NULL) {
1809 DBG_ERR("cookie->next_change == NULL for %s.\n", domain);
1810 return NT_STATUS_INTERNAL_ERROR;
1813 if (cookie->next_change->password == NULL) {
1814 DBG_ERR("cookie->next_change->password == NULL for %s.\n", domain);
1815 return NT_STATUS_INTERNAL_ERROR;
1818 if (cookie->password == NULL) {
1819 DBG_ERR("cookie->password == NULL for %s.\n", domain);
1820 return NT_STATUS_INTERNAL_ERROR;
1824 * Here we check that the given strucure still contains the
1825 * same secrets_domain_info1_change as currently stored.
1827 * There's always a gap between secrets_prepare_password_change()
1828 * and the callers of secrets_check_password_change().
1831 status = secrets_fetch_domain_info(domain, mem_ctx, &stored);
1832 if (!NT_STATUS_IS_OK(status)) {
1833 DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
1834 return status;
1837 if (stored->next_change == NULL) {
1839 * We hit a race..., the administrator
1840 * rejoined or something similar happened.
1842 DBG_ERR("stored->next_change == NULL for %s.\n", domain);
1843 TALLOC_FREE(stored);
1844 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1847 if (stored->password_last_change != cookie->password_last_change) {
1848 struct timeval store_tv;
1849 struct timeval_buf store_buf;
1850 struct timeval cookie_tv;
1851 struct timeval_buf cookie_buf;
1853 nttime_to_timeval(&store_tv, stored->password_last_change);
1854 nttime_to_timeval(&cookie_tv, cookie->password_last_change);
1856 DBG_ERR("password_last_change differs %s != %s for %s.\n",
1857 timeval_str_buf(&store_tv, false, false, &store_buf),
1858 timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1859 domain);
1860 TALLOC_FREE(stored);
1861 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1864 sn = stored->next_change;
1865 cn = cookie->next_change;
1867 if (sn->change_time != cn->change_time) {
1868 struct timeval store_tv;
1869 struct timeval_buf store_buf;
1870 struct timeval cookie_tv;
1871 struct timeval_buf cookie_buf;
1873 nttime_to_timeval(&store_tv, sn->change_time);
1874 nttime_to_timeval(&cookie_tv, cn->change_time);
1876 DBG_ERR("next change_time differs %s != %s for %s.\n",
1877 timeval_str_buf(&store_tv, false, false, &store_buf),
1878 timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1879 domain);
1880 TALLOC_FREE(stored);
1881 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1884 if (sn->password->change_time != cn->password->change_time) {
1885 struct timeval store_tv;
1886 struct timeval_buf store_buf;
1887 struct timeval cookie_tv;
1888 struct timeval_buf cookie_buf;
1890 nttime_to_timeval(&store_tv, sn->password->change_time);
1891 nttime_to_timeval(&cookie_tv, cn->password->change_time);
1893 DBG_ERR("next password.change_time differs %s != %s for %s.\n",
1894 timeval_str_buf(&store_tv, false, false, &store_buf),
1895 timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1896 domain);
1897 TALLOC_FREE(stored);
1898 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1901 cmp = memcmp(sn->password->nt_hash.hash,
1902 cn->password->nt_hash.hash,
1903 16);
1904 if (cmp != 0) {
1905 DBG_ERR("next password.nt_hash differs for %s.\n",
1906 domain);
1907 TALLOC_FREE(stored);
1908 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1911 cmp = memcmp(stored->password->nt_hash.hash,
1912 cookie->password->nt_hash.hash,
1913 16);
1914 if (cmp != 0) {
1915 DBG_ERR("password.nt_hash differs for %s.\n",
1916 domain);
1917 TALLOC_FREE(stored);
1918 return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1921 *pstored = stored;
1922 return NT_STATUS_OK;
1925 static NTSTATUS secrets_abort_password_change(const char *change_server,
1926 NTSTATUS local_status,
1927 NTSTATUS remote_status,
1928 const struct secrets_domain_info1 *cookie,
1929 bool defer)
1931 const char *domain = cookie->domain_info.name.string;
1932 TALLOC_CTX *frame = talloc_stackframe();
1933 struct db_context *db = NULL;
1934 struct secrets_domain_info1 *info = NULL;
1935 const char *reason = defer ? "defer_change" : "failed_change";
1936 struct timeval tv = timeval_current();
1937 NTTIME now = timeval_to_nttime(&tv);
1938 NTSTATUS status;
1939 int ret;
1941 db = secrets_db_ctx();
1943 ret = dbwrap_transaction_start(db);
1944 if (ret != 0) {
1945 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1946 domain);
1947 TALLOC_FREE(frame);
1948 return NT_STATUS_INTERNAL_DB_ERROR;
1952 * secrets_check_password_change()
1953 * checks that cookie->next_change
1954 * is valid and the same as store
1955 * in the database.
1957 status = secrets_check_password_change(cookie, frame, &info);
1958 if (!NT_STATUS_IS_OK(status)) {
1959 DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
1960 dbwrap_transaction_cancel(db);
1961 TALLOC_FREE(frame);
1962 return status;
1966 * Remember the last server and error.
1968 info->next_change->change_server = change_server;
1969 info->next_change->change_time = now;
1970 info->next_change->local_status = local_status;
1971 info->next_change->remote_status = remote_status;
1974 * Make sure the next automatic change is deferred.
1976 if (defer) {
1977 info->password_last_change = now;
1980 secrets_debug_domain_info(DBGLVL_WARNING, info, reason);
1982 status = secrets_store_domain_info(info, false /* upgrade */);
1983 if (!NT_STATUS_IS_OK(status)) {
1984 DBG_ERR("secrets_store_domain_info() failed "
1985 "for %s - %s\n", domain, nt_errstr(status));
1986 dbwrap_transaction_cancel(db);
1987 TALLOC_FREE(frame);
1988 return status;
1991 ret = dbwrap_transaction_commit(db);
1992 if (ret != 0) {
1993 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1994 domain);
1995 TALLOC_FREE(frame);
1996 return NT_STATUS_INTERNAL_DB_ERROR;
1999 TALLOC_FREE(frame);
2000 return NT_STATUS_OK;
2003 NTSTATUS secrets_failed_password_change(const char *change_server,
2004 NTSTATUS local_status,
2005 NTSTATUS remote_status,
2006 const struct secrets_domain_info1 *cookie)
2008 static const bool defer = false;
2009 return secrets_abort_password_change(change_server,
2010 local_status,
2011 remote_status,
2012 cookie, defer);
2015 NTSTATUS secrets_defer_password_change(const char *change_server,
2016 NTSTATUS local_status,
2017 NTSTATUS remote_status,
2018 const struct secrets_domain_info1 *cookie)
2020 static const bool defer = true;
2021 return secrets_abort_password_change(change_server,
2022 local_status,
2023 remote_status,
2024 cookie, defer);
2027 NTSTATUS secrets_finish_password_change(const char *change_server,
2028 NTTIME change_time,
2029 const struct secrets_domain_info1 *cookie)
2031 const char *domain = cookie->domain_info.name.string;
2032 TALLOC_CTX *frame = talloc_stackframe();
2033 struct db_context *db = NULL;
2034 struct secrets_domain_info1 *info = NULL;
2035 struct secrets_domain_info1_change *nc = NULL;
2036 NTSTATUS status;
2037 int ret;
2039 db = secrets_db_ctx();
2041 ret = dbwrap_transaction_start(db);
2042 if (ret != 0) {
2043 DBG_ERR("dbwrap_transaction_start() failed for %s\n",
2044 domain);
2045 TALLOC_FREE(frame);
2046 return NT_STATUS_INTERNAL_DB_ERROR;
2050 * secrets_check_password_change() checks that cookie->next_change is
2051 * valid and the same as store in the database.
2053 status = secrets_check_password_change(cookie, frame, &info);
2054 if (!NT_STATUS_IS_OK(status)) {
2055 DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
2056 dbwrap_transaction_cancel(db);
2057 TALLOC_FREE(frame);
2058 return status;
2061 nc = info->next_change;
2063 nc->password->change_server = change_server;
2064 nc->password->change_time = change_time;
2066 info->password_last_change = change_time;
2067 info->password_changes += 1;
2068 info->next_change = NULL;
2070 info->older_password = info->old_password;
2071 info->old_password = info->password;
2072 info->password = nc->password;
2074 secrets_debug_domain_info(DBGLVL_WARNING, info, "finish_change");
2076 status = secrets_store_domain_info(info, false /* upgrade */);
2077 if (!NT_STATUS_IS_OK(status)) {
2078 DBG_ERR("secrets_store_domain_info() failed "
2079 "for %s - %s\n", domain, nt_errstr(status));
2080 dbwrap_transaction_cancel(db);
2081 TALLOC_FREE(frame);
2082 return status;
2085 ret = dbwrap_transaction_commit(db);
2086 if (ret != 0) {
2087 DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
2088 domain);
2089 TALLOC_FREE(frame);
2090 return NT_STATUS_INTERNAL_DB_ERROR;
2093 TALLOC_FREE(frame);
2094 return NT_STATUS_OK;