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"
34 #define DBGC_CLASS DBGC_PASSDB
37 * Form a key for fetching the domain sid
39 * @param domain domain name
43 static const char *domain_sid_keystr(const char *domain
)
47 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
48 SECRETS_DOMAIN_SID
, domain
);
49 SMB_ASSERT(keystr
!= NULL
);
53 static const char *protect_ids_keystr(const char *domain
)
57 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
58 SECRETS_PROTECT_IDS
, domain
);
59 SMB_ASSERT(keystr
!= NULL
);
63 /* N O T E: never use this outside of passdb modules that store the SID on their own */
64 bool secrets_mark_domain_protected(const char *domain
)
68 ret
= secrets_store(protect_ids_keystr(domain
), "TRUE", 5);
70 DEBUG(0, ("Failed to protect the Domain IDs\n"));
75 bool secrets_clear_domain_protection(const char *domain
)
78 void *protection
= secrets_fetch(protect_ids_keystr(domain
), NULL
);
81 SAFE_FREE(protection
);
82 ret
= secrets_delete(protect_ids_keystr(domain
));
84 DEBUG(0, ("Failed to remove Domain IDs protection\n"));
91 bool secrets_store_domain_sid(const char *domain
, const struct dom_sid
*sid
)
93 #if _SAMBA_BUILD_ == 4
98 #if _SAMBA_BUILD_ == 4
99 protect_ids
= secrets_fetch(protect_ids_keystr(domain
), NULL
);
101 if (strncmp(protect_ids
, "TRUE", 4)) {
102 DEBUG(0, ("Refusing to store a Domain SID, "
103 "it has been marked as protected!\n"));
109 ret
= secrets_store(domain_sid_keystr(domain
), sid
, sizeof(struct dom_sid
));
111 /* Force a re-query, in case we modified our domain */
113 reset_global_sam_sid();
117 bool secrets_fetch_domain_sid(const char *domain
, struct dom_sid
*sid
)
119 struct dom_sid
*dyn_sid
;
122 dyn_sid
= (struct dom_sid
*)secrets_fetch(domain_sid_keystr(domain
), &size
);
127 if (size
!= sizeof(struct dom_sid
)) {
137 bool secrets_store_domain_guid(const char *domain
, struct GUID
*guid
)
139 #if _SAMBA_BUILD_ == 4
144 #if _SAMBA_BUILD_ == 4
145 protect_ids
= secrets_fetch(protect_ids_keystr(domain
), NULL
);
147 if (strncmp(protect_ids
, "TRUE", 4)) {
148 DEBUG(0, ("Refusing to store a Domain SID, "
149 "it has been marked as protected!\n"));
155 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
156 if (!strupper_m(key
)) {
159 return secrets_store(key
, guid
, sizeof(struct GUID
));
162 bool secrets_fetch_domain_guid(const char *domain
, struct GUID
*guid
)
164 struct GUID
*dyn_guid
;
167 struct GUID new_guid
;
169 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
170 if (!strupper_m(key
)) {
173 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
176 if (lp_server_role() == ROLE_DOMAIN_PDC
) {
177 new_guid
= GUID_random();
178 if (!secrets_store_domain_guid(domain
, &new_guid
))
180 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
182 if (dyn_guid
== NULL
) {
187 if (size
!= sizeof(struct GUID
)) {
188 DEBUG(1,("UUID size %d is wrong!\n", (int)size
));
199 * Form a key for fetching the machine trust account sec channel type
201 * @param domain domain name
205 static const char *machine_sec_channel_type_keystr(const char *domain
)
209 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
210 SECRETS_MACHINE_SEC_CHANNEL_TYPE
,
212 SMB_ASSERT(keystr
!= NULL
);
217 * Form a key for fetching the machine trust account last change time
219 * @param domain domain name
223 static const char *machine_last_change_time_keystr(const char *domain
)
227 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
228 SECRETS_MACHINE_LAST_CHANGE_TIME
,
230 SMB_ASSERT(keystr
!= NULL
);
236 * Form a key for fetching the machine previous trust account password
238 * @param domain domain name
242 static const char *machine_prev_password_keystr(const char *domain
)
246 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
247 SECRETS_MACHINE_PASSWORD_PREV
, domain
);
248 SMB_ASSERT(keystr
!= NULL
);
253 * Form a key for fetching the machine trust account password
255 * @param domain domain name
259 static const char *machine_password_keystr(const char *domain
)
263 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
264 SECRETS_MACHINE_PASSWORD
, domain
);
265 SMB_ASSERT(keystr
!= NULL
);
270 * Form a key for fetching the machine trust account password
272 * @param domain domain name
274 * @return stored password's key
276 static const char *trust_keystr(const char *domain
)
280 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
281 SECRETS_MACHINE_ACCT_PASS
, domain
);
282 SMB_ASSERT(keystr
!= NULL
);
286 /************************************************************************
287 Lock the trust password entry.
288 ************************************************************************/
290 void *secrets_get_trust_account_lock(TALLOC_CTX
*mem_ctx
, const char *domain
)
292 struct db_context
*db_ctx
;
293 if (!secrets_init()) {
297 db_ctx
= secrets_db_ctx();
299 return dbwrap_fetch_locked(
300 db_ctx
, mem_ctx
, string_term_tdb_data(trust_keystr(domain
)));
303 /************************************************************************
304 Routine to get the default secure channel type for trust accounts
305 ************************************************************************/
307 enum netr_SchannelType
get_default_sec_channel(void)
309 if (lp_server_role() == ROLE_DOMAIN_BDC
||
310 lp_server_role() == ROLE_DOMAIN_PDC
) {
313 return SEC_CHAN_WKSTA
;
317 /************************************************************************
318 Routine to get the trust account password for a domain.
319 This only tries to get the legacy hashed version of the password.
320 The user of this function must have locked the trust password file using
321 the above secrets_lock_trust_account_password().
322 ************************************************************************/
324 bool secrets_fetch_trust_account_password_legacy(const char *domain
,
326 time_t *pass_last_set_time
,
327 enum netr_SchannelType
*channel
)
329 struct machine_acct_pass
*pass
;
332 if (!(pass
= (struct machine_acct_pass
*)secrets_fetch(
333 trust_keystr(domain
), &size
))) {
334 DEBUG(5, ("secrets_fetch failed!\n"));
338 if (size
!= sizeof(*pass
)) {
339 DEBUG(0, ("secrets were of incorrect size!\n"));
344 if (pass_last_set_time
) {
345 *pass_last_set_time
= pass
->mod_time
;
347 memcpy(ret_pwd
, pass
->hash
, 16);
350 *channel
= get_default_sec_channel();
357 /************************************************************************
358 Routine to get the trust account password for a domain.
359 The user of this function must have locked the trust password file using
360 the above secrets_lock_trust_account_password().
361 ************************************************************************/
363 bool secrets_fetch_trust_account_password(const char *domain
, uint8_t ret_pwd
[16],
364 time_t *pass_last_set_time
,
365 enum netr_SchannelType
*channel
)
369 plaintext
= secrets_fetch_machine_password(domain
, pass_last_set_time
,
372 DEBUG(4,("Using cleartext machine password\n"));
373 E_md4hash(plaintext
, ret_pwd
);
374 SAFE_FREE(plaintext
);
378 return secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
383 /************************************************************************
384 Routine to delete the old plaintext machine account password if any
385 ************************************************************************/
387 static bool secrets_delete_prev_machine_password(const char *domain
)
389 char *oldpass
= (char *)secrets_fetch(machine_prev_password_keystr(domain
), NULL
);
390 if (oldpass
== NULL
) {
394 return secrets_delete(machine_prev_password_keystr(domain
));
397 /************************************************************************
398 Routine to delete the plaintext machine account password, old password,
399 sec channel type and last change time from secrets database
400 ************************************************************************/
402 bool secrets_delete_machine_password_ex(const char *domain
)
404 if (!secrets_delete_prev_machine_password(domain
)) {
407 if (!secrets_delete(machine_password_keystr(domain
))) {
410 if (!secrets_delete(machine_sec_channel_type_keystr(domain
))) {
413 return secrets_delete(machine_last_change_time_keystr(domain
));
416 /************************************************************************
417 Routine to delete the domain sid
418 ************************************************************************/
420 bool secrets_delete_domain_sid(const char *domain
)
422 return secrets_delete(domain_sid_keystr(domain
));
425 /************************************************************************
426 Routine to store the previous machine password (by storing the current password
428 ************************************************************************/
430 static bool secrets_store_prev_machine_password(const char *domain
)
435 oldpass
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
436 if (oldpass
== NULL
) {
439 ret
= secrets_store(machine_prev_password_keystr(domain
), oldpass
, strlen(oldpass
)+1);
444 /************************************************************************
445 Routine to set the plaintext machine account password for a realm
446 the password is assumed to be a null terminated ascii string.
448 ************************************************************************/
450 bool secrets_store_machine_password(const char *pass
, const char *domain
,
451 enum netr_SchannelType sec_channel
)
454 uint32_t last_change_time
;
455 uint32_t sec_channel_type
;
457 if (!secrets_store_prev_machine_password(domain
)) {
461 ret
= secrets_store(machine_password_keystr(domain
), pass
, strlen(pass
)+1);
465 SIVAL(&last_change_time
, 0, time(NULL
));
466 ret
= secrets_store(machine_last_change_time_keystr(domain
), &last_change_time
, sizeof(last_change_time
));
468 SIVAL(&sec_channel_type
, 0, sec_channel
);
469 ret
= secrets_store(machine_sec_channel_type_keystr(domain
), &sec_channel_type
, sizeof(sec_channel_type
));
475 /************************************************************************
476 Routine to fetch the previous plaintext machine account password for a realm
477 the password is assumed to be a null terminated ascii string.
478 ************************************************************************/
480 char *secrets_fetch_prev_machine_password(const char *domain
)
482 return (char *)secrets_fetch(machine_prev_password_keystr(domain
), NULL
);
485 /************************************************************************
486 Routine to fetch the plaintext machine account password for a realm
487 the password is assumed to be a null terminated ascii string.
488 ************************************************************************/
490 char *secrets_fetch_machine_password(const char *domain
,
491 time_t *pass_last_set_time
,
492 enum netr_SchannelType
*channel
)
495 ret
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
497 if (pass_last_set_time
) {
499 uint32_t *last_set_time
;
500 last_set_time
= (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain
), &size
);
502 *pass_last_set_time
= IVAL(last_set_time
,0);
503 SAFE_FREE(last_set_time
);
505 *pass_last_set_time
= 0;
511 uint32_t *channel_type
;
512 channel_type
= (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain
), &size
);
514 *channel
= IVAL(channel_type
,0);
515 SAFE_FREE(channel_type
);
517 *channel
= get_default_sec_channel();