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"
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 bool secrets_store_domain_sid(const char *domain
, const struct dom_sid
*sid
)
60 #ifdef _SAMBA_WAF_BUILD_
61 if (strequal(domain
, get_global_sam_name()) &&
62 (pdb_capabilities() & PDB_CAP_ADS
)) {
63 /* If we have a ADS-capable passdb backend, we
64 * must never make up our own SID, it will
65 * already be in the directory */
66 DEBUG(0, ("Refusing to store a Domain SID, this should be read from the directory not stored here\n"));
71 ret
= secrets_store(domain_sid_keystr(domain
), sid
, sizeof(struct dom_sid
));
73 /* Force a re-query, in case we modified our domain */
75 reset_global_sam_sid();
79 bool secrets_fetch_domain_sid(const char *domain
, struct dom_sid
*sid
)
81 struct dom_sid
*dyn_sid
;
84 #ifdef _SAMBA_WAF_BUILD_
85 if (strequal(domain
, get_global_sam_name()) &&
86 (pdb_capabilities() & PDB_CAP_ADS
)) {
87 struct pdb_domain_info
*domain_info
;
88 domain_info
= pdb_get_domain_info(talloc_tos());
90 /* If we have a ADS-capable passdb backend, we
91 * must never make up our own SID, it will
92 * already be in the directory */
93 DEBUG(0, ("Unable to fetch a Domain SID from the directory!\n"));
97 *sid
= domain_info
->sid
;
102 dyn_sid
= (struct dom_sid
*)secrets_fetch(domain_sid_keystr(domain
), &size
);
107 if (size
!= sizeof(struct dom_sid
)) {
117 bool secrets_store_domain_guid(const char *domain
, struct GUID
*guid
)
121 #ifdef _SAMBA_WAF_BUILD_
122 if (strequal(domain
, get_global_sam_name()) &&
123 (pdb_capabilities() & PDB_CAP_ADS
)) {
124 /* If we have a ADS-capable passdb backend, we
125 * must never make up our own GUID, it will
126 * already be in the directory */
127 DEBUG(0, ("Refusing to store a Domain GUID, this should be read from the directory not stored here\n"));
132 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
134 return secrets_store(key
, guid
, sizeof(struct GUID
));
137 bool secrets_fetch_domain_guid(const char *domain
, struct GUID
*guid
)
139 struct GUID
*dyn_guid
;
142 struct GUID new_guid
;
144 #ifdef _SAMBA_WAF_BUILD_
145 if (strequal(domain
, get_global_sam_name()) &&
146 (pdb_capabilities() & PDB_CAP_ADS
)) {
147 struct pdb_domain_info
*domain_info
;
148 domain_info
= pdb_get_domain_info(talloc_tos());
150 /* If we have a ADS-capable passdb backend, we
151 * must never make up our own SID, it will
152 * already be in the directory */
153 DEBUG(0, ("Unable to fetch a Domain GUID from the directory!\n"));
157 *guid
= domain_info
->guid
;
162 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
164 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
167 if (lp_server_role() == ROLE_DOMAIN_PDC
) {
168 new_guid
= GUID_random();
169 if (!secrets_store_domain_guid(domain
, &new_guid
))
171 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
173 if (dyn_guid
== NULL
) {
178 if (size
!= sizeof(struct GUID
)) {
179 DEBUG(1,("UUID size %d is wrong!\n", (int)size
));
190 * Form a key for fetching the machine trust account sec channel type
192 * @param domain domain name
196 static const char *machine_sec_channel_type_keystr(const char *domain
)
200 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
201 SECRETS_MACHINE_SEC_CHANNEL_TYPE
,
203 SMB_ASSERT(keystr
!= NULL
);
208 * Form a key for fetching the machine trust account last change time
210 * @param domain domain name
214 static const char *machine_last_change_time_keystr(const char *domain
)
218 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
219 SECRETS_MACHINE_LAST_CHANGE_TIME
,
221 SMB_ASSERT(keystr
!= NULL
);
227 * Form a key for fetching the machine previous trust account password
229 * @param domain domain name
233 static const char *machine_prev_password_keystr(const char *domain
)
237 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
238 SECRETS_MACHINE_PASSWORD_PREV
, domain
);
239 SMB_ASSERT(keystr
!= NULL
);
244 * Form a key for fetching the machine trust account password
246 * @param domain domain name
250 static const char *machine_password_keystr(const char *domain
)
254 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
255 SECRETS_MACHINE_PASSWORD
, domain
);
256 SMB_ASSERT(keystr
!= NULL
);
261 * Form a key for fetching the machine trust account password
263 * @param domain domain name
265 * @return stored password's key
267 static const char *trust_keystr(const char *domain
)
271 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
272 SECRETS_MACHINE_ACCT_PASS
, domain
);
273 SMB_ASSERT(keystr
!= NULL
);
277 /************************************************************************
278 Lock the trust password entry.
279 ************************************************************************/
281 void *secrets_get_trust_account_lock(TALLOC_CTX
*mem_ctx
, const char *domain
)
283 struct db_context
*db_ctx
;
284 if (!secrets_init()) {
288 db_ctx
= secrets_db_ctx();
290 return db_ctx
->fetch_locked(
291 db_ctx
, mem_ctx
, string_term_tdb_data(trust_keystr(domain
)));
294 /************************************************************************
295 Routine to get the default secure channel type for trust accounts
296 ************************************************************************/
298 enum netr_SchannelType
get_default_sec_channel(void)
300 if (lp_server_role() == ROLE_DOMAIN_BDC
||
301 lp_server_role() == ROLE_DOMAIN_PDC
) {
304 return SEC_CHAN_WKSTA
;
308 /************************************************************************
309 Routine to get the trust account password for a domain.
310 This only tries to get the legacy hashed version of the password.
311 The user of this function must have locked the trust password file using
312 the above secrets_lock_trust_account_password().
313 ************************************************************************/
315 bool secrets_fetch_trust_account_password_legacy(const char *domain
,
317 time_t *pass_last_set_time
,
318 enum netr_SchannelType
*channel
)
320 struct machine_acct_pass
*pass
;
323 if (!(pass
= (struct machine_acct_pass
*)secrets_fetch(
324 trust_keystr(domain
), &size
))) {
325 DEBUG(5, ("secrets_fetch failed!\n"));
329 if (size
!= sizeof(*pass
)) {
330 DEBUG(0, ("secrets were of incorrect size!\n"));
335 if (pass_last_set_time
) {
336 *pass_last_set_time
= pass
->mod_time
;
338 memcpy(ret_pwd
, pass
->hash
, 16);
341 *channel
= get_default_sec_channel();
344 /* Test if machine password has expired and needs to be changed */
345 if (lp_machine_password_timeout()) {
346 if (pass
->mod_time
> 0 && time(NULL
) > (pass
->mod_time
+
347 (time_t)lp_machine_password_timeout())) {
348 global_machine_password_needs_changing
= True
;
356 /************************************************************************
357 Routine to get the trust account password for a domain.
358 The user of this function must have locked the trust password file using
359 the above secrets_lock_trust_account_password().
360 ************************************************************************/
362 bool secrets_fetch_trust_account_password(const char *domain
, uint8 ret_pwd
[16],
363 time_t *pass_last_set_time
,
364 enum netr_SchannelType
*channel
)
368 plaintext
= secrets_fetch_machine_password(domain
, pass_last_set_time
,
371 DEBUG(4,("Using cleartext machine password\n"));
372 E_md4hash(plaintext
, ret_pwd
);
373 SAFE_FREE(plaintext
);
377 return secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
382 /************************************************************************
383 Routine to delete the old plaintext machine account password if any
384 ************************************************************************/
386 static bool secrets_delete_prev_machine_password(const char *domain
)
388 char *oldpass
= (char *)secrets_fetch(machine_prev_password_keystr(domain
), NULL
);
389 if (oldpass
== NULL
) {
393 return secrets_delete(machine_prev_password_keystr(domain
));
396 /************************************************************************
397 Routine to delete the plaintext machine account password and old
399 ************************************************************************/
401 bool secrets_delete_machine_password(const char *domain
)
403 if (!secrets_delete_prev_machine_password(domain
)) {
406 return secrets_delete(machine_password_keystr(domain
));
409 /************************************************************************
410 Routine to delete the plaintext machine account password, old password,
411 sec channel type and last change time from secrets database
412 ************************************************************************/
414 bool secrets_delete_machine_password_ex(const char *domain
)
416 if (!secrets_delete_prev_machine_password(domain
)) {
419 if (!secrets_delete(machine_password_keystr(domain
))) {
422 if (!secrets_delete(machine_sec_channel_type_keystr(domain
))) {
425 return secrets_delete(machine_last_change_time_keystr(domain
));
428 /************************************************************************
429 Routine to delete the domain sid
430 ************************************************************************/
432 bool secrets_delete_domain_sid(const char *domain
)
434 return secrets_delete(domain_sid_keystr(domain
));
437 /************************************************************************
438 Routine to store the previous machine password (by storing the current password
440 ************************************************************************/
442 static bool secrets_store_prev_machine_password(const char *domain
)
447 oldpass
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
448 if (oldpass
== NULL
) {
451 ret
= secrets_store(machine_prev_password_keystr(domain
), oldpass
, strlen(oldpass
)+1);
456 /************************************************************************
457 Routine to set the plaintext machine account password for a realm
458 the password is assumed to be a null terminated ascii string.
460 ************************************************************************/
462 bool secrets_store_machine_password(const char *pass
, const char *domain
,
463 enum netr_SchannelType sec_channel
)
466 uint32 last_change_time
;
467 uint32 sec_channel_type
;
469 if (!secrets_store_prev_machine_password(domain
)) {
473 ret
= secrets_store(machine_password_keystr(domain
), pass
, strlen(pass
)+1);
477 SIVAL(&last_change_time
, 0, time(NULL
));
478 ret
= secrets_store(machine_last_change_time_keystr(domain
), &last_change_time
, sizeof(last_change_time
));
480 SIVAL(&sec_channel_type
, 0, sec_channel
);
481 ret
= secrets_store(machine_sec_channel_type_keystr(domain
), &sec_channel_type
, sizeof(sec_channel_type
));
487 /************************************************************************
488 Routine to fetch the previous plaintext machine account password for a realm
489 the password is assumed to be a null terminated ascii string.
490 ************************************************************************/
492 char *secrets_fetch_prev_machine_password(const char *domain
)
494 return (char *)secrets_fetch(machine_prev_password_keystr(domain
), NULL
);
497 /************************************************************************
498 Routine to fetch the plaintext machine account password for a realm
499 the password is assumed to be a null terminated ascii string.
500 ************************************************************************/
502 char *secrets_fetch_machine_password(const char *domain
,
503 time_t *pass_last_set_time
,
504 enum netr_SchannelType
*channel
)
507 ret
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
509 if (pass_last_set_time
) {
511 uint32
*last_set_time
;
512 last_set_time
= (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain
), &size
);
514 *pass_last_set_time
= IVAL(last_set_time
,0);
515 SAFE_FREE(last_set_time
);
517 *pass_last_set_time
= 0;
523 uint32
*channel_type
;
524 channel_type
= (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain
), &size
);
526 *channel
= IVAL(channel_type
,0);
527 SAFE_FREE(channel_type
);
529 *channel
= get_default_sec_channel();