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
36 /* Urrrg. global.... */
37 bool global_machine_password_needs_changing
;
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 *protect_ids_keystr(const char *domain
)
60 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
61 SECRETS_PROTECT_IDS
, domain
);
62 SMB_ASSERT(keystr
!= NULL
);
66 /* N O T E: never use this outside of passdb modules that store the SID on their own */
67 bool secrets_mark_domain_protected(const char *domain
)
71 ret
= secrets_store(protect_ids_keystr(domain
), "TRUE", 5);
73 DEBUG(0, ("Failed to protect the Domain IDs\n"));
78 bool secrets_clear_domain_protection(const char *domain
)
82 ret
= secrets_delete(protect_ids_keystr(domain
));
84 DEBUG(0, ("Failed to remove Domain IDs protection\n"));
89 bool secrets_store_domain_sid(const char *domain
, const struct dom_sid
*sid
)
91 #if _SAMBA_BUILD_ == 4
96 #if _SAMBA_BUILD_ == 4
97 protect_ids
= secrets_fetch(protect_ids_keystr(domain
), NULL
);
99 if (strncmp(protect_ids
, "TRUE", 4)) {
100 DEBUG(0, ("Refusing to store a Domain SID, "
101 "it has been marked as protected!\n"));
107 ret
= secrets_store(domain_sid_keystr(domain
), sid
, sizeof(struct dom_sid
));
109 /* Force a re-query, in case we modified our domain */
111 reset_global_sam_sid();
115 bool secrets_fetch_domain_sid(const char *domain
, struct dom_sid
*sid
)
117 struct dom_sid
*dyn_sid
;
120 dyn_sid
= (struct dom_sid
*)secrets_fetch(domain_sid_keystr(domain
), &size
);
125 if (size
!= sizeof(struct dom_sid
)) {
135 bool secrets_store_domain_guid(const char *domain
, struct GUID
*guid
)
137 #if _SAMBA_BUILD_ == 4
142 #if _SAMBA_BUILD_ == 4
143 protect_ids
= secrets_fetch(protect_ids_keystr(domain
), NULL
);
145 if (strncmp(protect_ids
, "TRUE", 4)) {
146 DEBUG(0, ("Refusing to store a Domain SID, "
147 "it has been marked as protected!\n"));
153 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
155 return secrets_store(key
, guid
, sizeof(struct GUID
));
158 bool secrets_fetch_domain_guid(const char *domain
, struct GUID
*guid
)
160 struct GUID
*dyn_guid
;
163 struct GUID new_guid
;
165 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
167 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
170 if (lp_server_role() == ROLE_DOMAIN_PDC
) {
171 new_guid
= GUID_random();
172 if (!secrets_store_domain_guid(domain
, &new_guid
))
174 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
176 if (dyn_guid
== NULL
) {
181 if (size
!= sizeof(struct GUID
)) {
182 DEBUG(1,("UUID size %d is wrong!\n", (int)size
));
193 * Form a key for fetching the machine trust account sec channel type
195 * @param domain domain name
199 static const char *machine_sec_channel_type_keystr(const char *domain
)
203 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
204 SECRETS_MACHINE_SEC_CHANNEL_TYPE
,
206 SMB_ASSERT(keystr
!= NULL
);
211 * Form a key for fetching the machine trust account last change time
213 * @param domain domain name
217 static const char *machine_last_change_time_keystr(const char *domain
)
221 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
222 SECRETS_MACHINE_LAST_CHANGE_TIME
,
224 SMB_ASSERT(keystr
!= NULL
);
230 * Form a key for fetching the machine previous trust account password
232 * @param domain domain name
236 static const char *machine_prev_password_keystr(const char *domain
)
240 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
241 SECRETS_MACHINE_PASSWORD_PREV
, domain
);
242 SMB_ASSERT(keystr
!= NULL
);
247 * Form a key for fetching the machine trust account password
249 * @param domain domain name
253 static const char *machine_password_keystr(const char *domain
)
257 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
258 SECRETS_MACHINE_PASSWORD
, domain
);
259 SMB_ASSERT(keystr
!= NULL
);
264 * Form a key for fetching the machine trust account password
266 * @param domain domain name
268 * @return stored password's key
270 static const char *trust_keystr(const char *domain
)
274 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
275 SECRETS_MACHINE_ACCT_PASS
, domain
);
276 SMB_ASSERT(keystr
!= NULL
);
280 /************************************************************************
281 Lock the trust password entry.
282 ************************************************************************/
284 void *secrets_get_trust_account_lock(TALLOC_CTX
*mem_ctx
, const char *domain
)
286 struct db_context
*db_ctx
;
287 if (!secrets_init()) {
291 db_ctx
= secrets_db_ctx();
293 return dbwrap_fetch_locked(
294 db_ctx
, mem_ctx
, string_term_tdb_data(trust_keystr(domain
)));
297 /************************************************************************
298 Routine to get the default secure channel type for trust accounts
299 ************************************************************************/
301 enum netr_SchannelType
get_default_sec_channel(void)
303 if (lp_server_role() == ROLE_DOMAIN_BDC
||
304 lp_server_role() == ROLE_DOMAIN_PDC
) {
307 return SEC_CHAN_WKSTA
;
311 /************************************************************************
312 Routine to get the trust account password for a domain.
313 This only tries to get the legacy hashed version of the password.
314 The user of this function must have locked the trust password file using
315 the above secrets_lock_trust_account_password().
316 ************************************************************************/
318 bool secrets_fetch_trust_account_password_legacy(const char *domain
,
320 time_t *pass_last_set_time
,
321 enum netr_SchannelType
*channel
)
323 struct machine_acct_pass
*pass
;
326 if (!(pass
= (struct machine_acct_pass
*)secrets_fetch(
327 trust_keystr(domain
), &size
))) {
328 DEBUG(5, ("secrets_fetch failed!\n"));
332 if (size
!= sizeof(*pass
)) {
333 DEBUG(0, ("secrets were of incorrect size!\n"));
338 if (pass_last_set_time
) {
339 *pass_last_set_time
= pass
->mod_time
;
341 memcpy(ret_pwd
, pass
->hash
, 16);
344 *channel
= get_default_sec_channel();
347 /* Test if machine password has expired and needs to be changed */
348 if (lp_machine_password_timeout()) {
349 if (pass
->mod_time
> 0 && time(NULL
) > (pass
->mod_time
+
350 (time_t)lp_machine_password_timeout())) {
351 global_machine_password_needs_changing
= True
;
359 /************************************************************************
360 Routine to get the trust account password for a domain.
361 The user of this function must have locked the trust password file using
362 the above secrets_lock_trust_account_password().
363 ************************************************************************/
365 bool secrets_fetch_trust_account_password(const char *domain
, uint8 ret_pwd
[16],
366 time_t *pass_last_set_time
,
367 enum netr_SchannelType
*channel
)
371 plaintext
= secrets_fetch_machine_password(domain
, pass_last_set_time
,
374 DEBUG(4,("Using cleartext machine password\n"));
375 E_md4hash(plaintext
, ret_pwd
);
376 SAFE_FREE(plaintext
);
380 return secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
385 /************************************************************************
386 Routine to delete the old plaintext machine account password if any
387 ************************************************************************/
389 static bool secrets_delete_prev_machine_password(const char *domain
)
391 char *oldpass
= (char *)secrets_fetch(machine_prev_password_keystr(domain
), NULL
);
392 if (oldpass
== NULL
) {
396 return secrets_delete(machine_prev_password_keystr(domain
));
399 /************************************************************************
400 Routine to delete the plaintext machine account password, old password,
401 sec channel type and last change time from secrets database
402 ************************************************************************/
404 bool secrets_delete_machine_password_ex(const char *domain
)
406 if (!secrets_delete_prev_machine_password(domain
)) {
409 if (!secrets_delete(machine_password_keystr(domain
))) {
412 if (!secrets_delete(machine_sec_channel_type_keystr(domain
))) {
415 return secrets_delete(machine_last_change_time_keystr(domain
));
418 /************************************************************************
419 Routine to delete the domain sid
420 ************************************************************************/
422 bool secrets_delete_domain_sid(const char *domain
)
424 return secrets_delete(domain_sid_keystr(domain
));
427 /************************************************************************
428 Routine to store the previous machine password (by storing the current password
430 ************************************************************************/
432 static bool secrets_store_prev_machine_password(const char *domain
)
437 oldpass
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
438 if (oldpass
== NULL
) {
441 ret
= secrets_store(machine_prev_password_keystr(domain
), oldpass
, strlen(oldpass
)+1);
446 /************************************************************************
447 Routine to set the plaintext machine account password for a realm
448 the password is assumed to be a null terminated ascii string.
450 ************************************************************************/
452 bool secrets_store_machine_password(const char *pass
, const char *domain
,
453 enum netr_SchannelType sec_channel
)
456 uint32 last_change_time
;
457 uint32 sec_channel_type
;
459 if (!secrets_store_prev_machine_password(domain
)) {
463 ret
= secrets_store(machine_password_keystr(domain
), pass
, strlen(pass
)+1);
467 SIVAL(&last_change_time
, 0, time(NULL
));
468 ret
= secrets_store(machine_last_change_time_keystr(domain
), &last_change_time
, sizeof(last_change_time
));
470 SIVAL(&sec_channel_type
, 0, sec_channel
);
471 ret
= secrets_store(machine_sec_channel_type_keystr(domain
), &sec_channel_type
, sizeof(sec_channel_type
));
477 /************************************************************************
478 Routine to fetch the previous plaintext machine account password for a realm
479 the password is assumed to be a null terminated ascii string.
480 ************************************************************************/
482 char *secrets_fetch_prev_machine_password(const char *domain
)
484 return (char *)secrets_fetch(machine_prev_password_keystr(domain
), NULL
);
487 /************************************************************************
488 Routine to fetch the plaintext machine account password for a realm
489 the password is assumed to be a null terminated ascii string.
490 ************************************************************************/
492 char *secrets_fetch_machine_password(const char *domain
,
493 time_t *pass_last_set_time
,
494 enum netr_SchannelType
*channel
)
497 ret
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
499 if (pass_last_set_time
) {
501 uint32
*last_set_time
;
502 last_set_time
= (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain
), &size
);
504 *pass_last_set_time
= IVAL(last_set_time
,0);
505 SAFE_FREE(last_set_time
);
507 *pass_last_set_time
= 0;
513 uint32
*channel_type
;
514 channel_type
= (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain
), &size
);
516 *channel
= IVAL(channel_type
,0);
517 SAFE_FREE(channel_type
);
519 *channel
= get_default_sec_channel();