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"
35 #define DBGC_CLASS DBGC_PASSDB
37 static char *des_salt_key(const char *realm);
40 * Form a key for fetching the domain sid
42 * @param domain domain name
46 static const char *domain_sid_keystr(const char *domain)
50 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
51 SECRETS_DOMAIN_SID, domain);
52 SMB_ASSERT(keystr != NULL);
56 static const char *domain_guid_keystr(const char *domain)
60 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
61 SECRETS_DOMAIN_GUID, domain);
62 SMB_ASSERT(keystr != NULL);
66 static const char *protect_ids_keystr(const char *domain)
70 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
71 SECRETS_PROTECT_IDS, domain);
72 SMB_ASSERT(keystr != NULL);
76 /* N O T E: never use this outside of passdb modules that store the SID on their own */
77 bool secrets_mark_domain_protected(const char *domain)
81 ret = secrets_store(protect_ids_keystr(domain), "TRUE", 5);
83 DEBUG(0, ("Failed to protect the Domain IDs\n"));
88 bool secrets_clear_domain_protection(const char *domain)
91 void *protection = secrets_fetch(protect_ids_keystr(domain), NULL);
94 SAFE_FREE(protection);
95 ret = secrets_delete_entry(protect_ids_keystr(domain));
97 DEBUG(0, ("Failed to remove Domain IDs protection\n"));
104 bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
109 protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
111 if (strncmp(protect_ids, "TRUE", 4)) {
112 DEBUG(0, ("Refusing to store a Domain SID, "
113 "it has been marked as protected!\n"));
114 SAFE_FREE(protect_ids);
118 SAFE_FREE(protect_ids);
120 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
122 /* Force a re-query, in the case where we modified our domain */
124 if (dom_sid_equal(get_global_sam_sid(), sid) == false) {
125 reset_global_sam_sid();
131 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
133 struct dom_sid *dyn_sid;
136 dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
141 if (size != sizeof(struct dom_sid)) {
151 bool secrets_store_domain_guid(const char *domain, const struct GUID *guid)
156 protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
158 if (strncmp(protect_ids, "TRUE", 4)) {
159 DEBUG(0, ("Refusing to store a Domain SID, "
160 "it has been marked as protected!\n"));
161 SAFE_FREE(protect_ids);
165 SAFE_FREE(protect_ids);
167 key = domain_guid_keystr(domain);
168 return secrets_store(key, guid, sizeof(struct GUID));
171 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
173 struct GUID *dyn_guid;
176 struct GUID new_guid;
178 key = domain_guid_keystr(domain);
179 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
182 if (lp_server_role() == ROLE_DOMAIN_PDC) {
183 new_guid = GUID_random();
184 if (!secrets_store_domain_guid(domain, &new_guid))
186 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
188 if (dyn_guid == NULL) {
193 if (size != sizeof(struct GUID)) {
194 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
205 * Form a key for fetching the machine trust account sec channel type
207 * @param domain domain name
211 static const char *machine_sec_channel_type_keystr(const char *domain)
215 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
216 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
218 SMB_ASSERT(keystr != NULL);
223 * Form a key for fetching the machine trust account last change time
225 * @param domain domain name
229 static const char *machine_last_change_time_keystr(const char *domain)
233 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
234 SECRETS_MACHINE_LAST_CHANGE_TIME,
236 SMB_ASSERT(keystr != NULL);
242 * Form a key for fetching the machine previous trust account password
244 * @param domain domain name
248 static const char *machine_prev_password_keystr(const char *domain)
252 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
253 SECRETS_MACHINE_PASSWORD_PREV, domain);
254 SMB_ASSERT(keystr != NULL);
259 * Form a key for fetching the machine trust account password
261 * @param domain domain name
265 static const char *machine_password_keystr(const char *domain)
269 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
270 SECRETS_MACHINE_PASSWORD, domain);
271 SMB_ASSERT(keystr != NULL);
276 * Form a key for fetching the machine trust account password
278 * @param domain domain name
280 * @return stored password's key
282 static const char *trust_keystr(const char *domain)
286 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
287 SECRETS_MACHINE_ACCT_PASS, domain);
288 SMB_ASSERT(keystr != NULL);
292 /************************************************************************
293 Routine to get the default secure channel type for trust accounts
294 ************************************************************************/
296 enum netr_SchannelType get_default_sec_channel(void)
298 if (lp_server_role() == ROLE_DOMAIN_BDC ||
299 lp_server_role() == ROLE_DOMAIN_PDC ||
300 lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
303 return SEC_CHAN_WKSTA;
307 /************************************************************************
308 Routine to get the trust account password for a domain.
309 This only tries to get the legacy hashed version of the password.
310 The user of this function must have locked the trust password file using
311 the above secrets_lock_trust_account_password().
312 ************************************************************************/
314 bool secrets_fetch_trust_account_password_legacy(const char *domain,
316 time_t *pass_last_set_time,
317 enum netr_SchannelType *channel)
319 struct machine_acct_pass *pass;
322 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
323 trust_keystr(domain), &size))) {
324 DEBUG(5, ("secrets_fetch failed!\n"));
328 if (size != sizeof(*pass)) {
329 DEBUG(0, ("secrets were of incorrect size!\n"));
334 if (pass_last_set_time) {
335 *pass_last_set_time = pass->mod_time;
337 memcpy(ret_pwd, pass->hash, 16);
340 *channel = get_default_sec_channel();
347 /************************************************************************
348 Routine to get the trust account password for a domain.
349 The user of this function must have locked the trust password file using
350 the above secrets_lock_trust_account_password().
351 ************************************************************************/
353 bool secrets_fetch_trust_account_password(const char *domain, uint8_t ret_pwd[16],
354 time_t *pass_last_set_time,
355 enum netr_SchannelType *channel)
359 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
362 DEBUG(4,("Using cleartext machine password\n"));
363 E_md4hash(plaintext, ret_pwd);
364 SAFE_FREE(plaintext);
368 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
373 /************************************************************************
374 Routine to delete the plaintext machine account password, old password,
375 sec channel type and last change time from secrets database
376 ************************************************************************/
378 bool secrets_delete_machine_password_ex(const char *domain)
380 if (!secrets_delete(machine_prev_password_keystr(domain))) {
383 if (!secrets_delete_entry(machine_password_keystr(domain))) {
386 if (!secrets_delete_entry(machine_sec_channel_type_keystr(domain))) {
389 return secrets_delete_entry(machine_last_change_time_keystr(domain));
392 /************************************************************************
393 Routine to delete the domain sid
394 ************************************************************************/
396 bool secrets_delete_domain_sid(const char *domain)
398 return secrets_delete_entry(domain_sid_keystr(domain));
401 /************************************************************************
402 Routine to store the previous machine password (by storing the current password
404 ************************************************************************/
406 static bool secrets_store_prev_machine_password(const char *domain)
411 oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
412 if (oldpass == NULL) {
415 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
420 /************************************************************************
421 Routine to set the plaintext machine account password for a realm
422 the password is assumed to be a null terminated ascii string.
424 ************************************************************************/
426 bool secrets_store_machine_password(const char *pass, const char *domain,
427 enum netr_SchannelType sec_channel)
430 uint32_t last_change_time;
431 uint32_t sec_channel_type;
433 if (!secrets_store_prev_machine_password(domain)) {
437 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
441 SIVAL(&last_change_time, 0, time(NULL));
442 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
444 SIVAL(&sec_channel_type, 0, sec_channel);
445 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
450 /************************************************************************
451 Set the machine trust account password, the old pw and last change
452 time, domain SID and salting principals based on values passed in
453 (added to supprt the secrets_tdb_sync module on secrets.ldb)
454 ************************************************************************/
456 bool secrets_store_machine_pw_sync(const char *pass, const char *oldpass, const char *domain,
458 const char *salting_principal, uint32_t supported_enc_types,
459 const struct dom_sid *domain_sid, uint32_t last_change_time,
460 uint32_t secure_channel_type,
464 uint8_t last_change_time_store[4];
465 TALLOC_CTX *frame = talloc_stackframe();
466 uint8_t sec_channel_bytes[4];
469 secrets_delete_machine_password_ex(domain);
470 secrets_delete_domain_sid(domain);
475 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
482 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
484 ret = secrets_delete(machine_prev_password_keystr(domain));
491 if (secure_channel_type == 0) {
492 /* We delete this and instead have the read code fall back to
493 * a default based on server role, as our caller can't specify
494 * this with any more certainty */
495 ret = secrets_delete(machine_sec_channel_type_keystr(domain));
501 SIVAL(&sec_channel_bytes, 0, secure_channel_type);
502 ret = secrets_store(machine_sec_channel_type_keystr(domain),
503 &sec_channel_bytes, sizeof(sec_channel_bytes));
510 SIVAL(&last_change_time_store, 0, last_change_time);
511 ret = secrets_store(machine_last_change_time_keystr(domain),
512 &last_change_time_store, sizeof(last_change_time));
519 ret = secrets_store_domain_sid(domain, domain_sid);
527 char *key = des_salt_key(realm);
529 if (salting_principal != NULL) {
530 ret = secrets_store(key,
532 strlen(salting_principal)+1);
534 ret = secrets_delete(key);
542 /************************************************************************
543 Return the standard DES salt key
544 ************************************************************************/
546 char* kerberos_standard_des_salt( void )
550 fstr_sprintf( salt, "host/%s.%s@", lp_netbios_name(), lp_realm() );
551 (void)strlower_m( salt );
552 fstrcat( salt, lp_realm() );
554 return SMB_STRDUP( salt );
557 /************************************************************************
558 ************************************************************************/
560 static char *des_salt_key(const char *realm)
564 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/DES/%s",
565 SECRETS_SALTING_PRINCIPAL,
567 SMB_ASSERT(keystr != NULL);
571 /************************************************************************
572 ************************************************************************/
574 bool kerberos_secrets_store_des_salt( const char* salt )
579 key = des_salt_key(lp_realm());
581 DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n"));
586 DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n"));
587 secrets_delete_entry( key );
591 DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt));
593 ret = secrets_store( key, salt, strlen(salt)+1 );
600 /************************************************************************
601 ************************************************************************/
604 char* kerberos_secrets_fetch_des_salt( void )
608 key = des_salt_key(lp_realm());
610 DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
614 salt = (char*)secrets_fetch( key, NULL );
621 /************************************************************************
622 Routine to get the salting principal for this service.
623 Caller must free if return is not null.
624 ************************************************************************/
626 char *kerberos_secrets_fetch_salt_princ(void)
629 /* lookup new key first */
631 salt_princ_s = kerberos_secrets_fetch_des_salt();
632 if (salt_princ_s == NULL) {
633 /* fall back to host/machine.realm@REALM */
634 salt_princ_s = kerberos_standard_des_salt();
640 /************************************************************************
641 Routine to fetch the previous plaintext machine account password for a realm
642 the password is assumed to be a null terminated ascii string.
643 ************************************************************************/
645 char *secrets_fetch_prev_machine_password(const char *domain)
647 return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
650 /************************************************************************
651 Routine to fetch the last change time of the machine account password
653 ************************************************************************/
655 time_t secrets_fetch_pass_last_set_time(const char *domain)
657 uint32_t *last_set_time;
658 time_t pass_last_set_time;
660 last_set_time = secrets_fetch(machine_last_change_time_keystr(domain),
663 pass_last_set_time = IVAL(last_set_time,0);
664 SAFE_FREE(last_set_time);
666 pass_last_set_time = 0;
669 return pass_last_set_time;
672 /************************************************************************
673 Routine to fetch the plaintext machine account password for a realm
674 the password is assumed to be a null terminated ascii string.
675 ************************************************************************/
677 char *secrets_fetch_machine_password(const char *domain,
678 time_t *pass_last_set_time,
679 enum netr_SchannelType *channel)
682 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
684 if (pass_last_set_time) {
685 *pass_last_set_time = secrets_fetch_pass_last_set_time(domain);
690 uint32_t *channel_type;
691 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
693 *channel = IVAL(channel_type,0);
694 SAFE_FREE(channel_type);
696 *channel = get_default_sec_channel();