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 */
26 #include "../libcli/auth/libcli_auth.h"
31 #define DBGC_CLASS DBGC_PASSDB
33 /* Urrrg. global.... */
34 bool global_machine_password_needs_changing
;
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 bool secrets_store_domain_sid(const char *domain
, const struct dom_sid
*sid
)
57 ret
= secrets_store(domain_sid_keystr(domain
), sid
, sizeof(struct dom_sid
));
59 /* Force a re-query, in case we modified our domain */
61 reset_global_sam_sid();
65 bool secrets_fetch_domain_sid(const char *domain
, struct dom_sid
*sid
)
67 struct dom_sid
*dyn_sid
;
70 dyn_sid
= (struct dom_sid
*)secrets_fetch(domain_sid_keystr(domain
), &size
);
75 if (size
!= sizeof(struct dom_sid
)) {
85 bool secrets_store_domain_guid(const char *domain
, struct GUID
*guid
)
89 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
91 return secrets_store(key
, guid
, sizeof(struct GUID
));
94 bool secrets_fetch_domain_guid(const char *domain
, struct GUID
*guid
)
96 struct GUID
*dyn_guid
;
101 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
103 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
106 if (lp_server_role() == ROLE_DOMAIN_PDC
) {
107 new_guid
= GUID_random();
108 if (!secrets_store_domain_guid(domain
, &new_guid
))
110 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
112 if (dyn_guid
== NULL
) {
117 if (size
!= sizeof(struct GUID
)) {
118 DEBUG(1,("UUID size %d is wrong!\n", (int)size
));
129 * Form a key for fetching the machine trust account sec channel type
131 * @param domain domain name
135 static const char *machine_sec_channel_type_keystr(const char *domain
)
139 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
140 SECRETS_MACHINE_SEC_CHANNEL_TYPE
,
142 SMB_ASSERT(keystr
!= NULL
);
147 * Form a key for fetching the machine trust account last change time
149 * @param domain domain name
153 static const char *machine_last_change_time_keystr(const char *domain
)
157 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
158 SECRETS_MACHINE_LAST_CHANGE_TIME
,
160 SMB_ASSERT(keystr
!= NULL
);
166 * Form a key for fetching the machine previous trust account password
168 * @param domain domain name
172 static const char *machine_prev_password_keystr(const char *domain
)
176 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
177 SECRETS_MACHINE_PASSWORD_PREV
, domain
);
178 SMB_ASSERT(keystr
!= NULL
);
183 * Form a key for fetching the machine trust account password
185 * @param domain domain name
189 static const char *machine_password_keystr(const char *domain
)
193 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
194 SECRETS_MACHINE_PASSWORD
, domain
);
195 SMB_ASSERT(keystr
!= NULL
);
200 * Form a key for fetching the machine trust account password
202 * @param domain domain name
204 * @return stored password's key
206 static const char *trust_keystr(const char *domain
)
210 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
211 SECRETS_MACHINE_ACCT_PASS
, domain
);
212 SMB_ASSERT(keystr
!= NULL
);
216 /************************************************************************
217 Lock the trust password entry.
218 ************************************************************************/
220 void *secrets_get_trust_account_lock(TALLOC_CTX
*mem_ctx
, const char *domain
)
222 struct db_context
*db_ctx
;
223 if (!secrets_init()) {
227 db_ctx
= secrets_db_ctx();
229 return db_ctx
->fetch_locked(
230 db_ctx
, mem_ctx
, string_term_tdb_data(trust_keystr(domain
)));
233 /************************************************************************
234 Routine to get the default secure channel type for trust accounts
235 ************************************************************************/
237 enum netr_SchannelType
get_default_sec_channel(void)
239 if (lp_server_role() == ROLE_DOMAIN_BDC
||
240 lp_server_role() == ROLE_DOMAIN_PDC
) {
243 return SEC_CHAN_WKSTA
;
247 /************************************************************************
248 Routine to get the trust account password for a domain.
249 This only tries to get the legacy hashed version of the password.
250 The user of this function must have locked the trust password file using
251 the above secrets_lock_trust_account_password().
252 ************************************************************************/
254 bool secrets_fetch_trust_account_password_legacy(const char *domain
,
256 time_t *pass_last_set_time
,
257 enum netr_SchannelType
*channel
)
259 struct machine_acct_pass
*pass
;
262 if (!(pass
= (struct machine_acct_pass
*)secrets_fetch(
263 trust_keystr(domain
), &size
))) {
264 DEBUG(5, ("secrets_fetch failed!\n"));
268 if (size
!= sizeof(*pass
)) {
269 DEBUG(0, ("secrets were of incorrect size!\n"));
274 if (pass_last_set_time
) {
275 *pass_last_set_time
= pass
->mod_time
;
277 memcpy(ret_pwd
, pass
->hash
, 16);
280 *channel
= get_default_sec_channel();
283 /* Test if machine password has expired and needs to be changed */
284 if (lp_machine_password_timeout()) {
285 if (pass
->mod_time
> 0 && time(NULL
) > (pass
->mod_time
+
286 (time_t)lp_machine_password_timeout())) {
287 global_machine_password_needs_changing
= True
;
295 /************************************************************************
296 Routine to get the trust account password for a domain.
297 The user of this function must have locked the trust password file using
298 the above secrets_lock_trust_account_password().
299 ************************************************************************/
301 bool secrets_fetch_trust_account_password(const char *domain
, uint8 ret_pwd
[16],
302 time_t *pass_last_set_time
,
303 enum netr_SchannelType
*channel
)
307 plaintext
= secrets_fetch_machine_password(domain
, pass_last_set_time
,
310 DEBUG(4,("Using cleartext machine password\n"));
311 E_md4hash(plaintext
, ret_pwd
);
312 SAFE_FREE(plaintext
);
316 return secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
321 /************************************************************************
322 Routine to delete the old plaintext machine account password if any
323 ************************************************************************/
325 static bool secrets_delete_prev_machine_password(const char *domain
)
327 char *oldpass
= (char *)secrets_fetch(machine_prev_password_keystr(domain
), NULL
);
328 if (oldpass
== NULL
) {
332 return secrets_delete(machine_prev_password_keystr(domain
));
335 /************************************************************************
336 Routine to delete the plaintext machine account password and old
338 ************************************************************************/
340 bool secrets_delete_machine_password(const char *domain
)
342 if (!secrets_delete_prev_machine_password(domain
)) {
345 return secrets_delete(machine_password_keystr(domain
));
348 /************************************************************************
349 Routine to delete the plaintext machine account password, old password,
350 sec channel type and last change time from secrets database
351 ************************************************************************/
353 bool secrets_delete_machine_password_ex(const char *domain
)
355 if (!secrets_delete_prev_machine_password(domain
)) {
358 if (!secrets_delete(machine_password_keystr(domain
))) {
361 if (!secrets_delete(machine_sec_channel_type_keystr(domain
))) {
364 return secrets_delete(machine_last_change_time_keystr(domain
));
367 /************************************************************************
368 Routine to delete the domain sid
369 ************************************************************************/
371 bool secrets_delete_domain_sid(const char *domain
)
373 return secrets_delete(domain_sid_keystr(domain
));
376 /************************************************************************
377 Routine to store the previous machine password (by storing the current password
379 ************************************************************************/
381 static bool secrets_store_prev_machine_password(const char *domain
)
386 oldpass
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
387 if (oldpass
== NULL
) {
390 ret
= secrets_store(machine_prev_password_keystr(domain
), oldpass
, strlen(oldpass
)+1);
395 /************************************************************************
396 Routine to set the plaintext machine account password for a realm
397 the password is assumed to be a null terminated ascii string.
399 ************************************************************************/
401 bool secrets_store_machine_password(const char *pass
, const char *domain
,
402 enum netr_SchannelType sec_channel
)
405 uint32 last_change_time
;
406 uint32 sec_channel_type
;
408 if (!secrets_store_prev_machine_password(domain
)) {
412 ret
= secrets_store(machine_password_keystr(domain
), pass
, strlen(pass
)+1);
416 SIVAL(&last_change_time
, 0, time(NULL
));
417 ret
= secrets_store(machine_last_change_time_keystr(domain
), &last_change_time
, sizeof(last_change_time
));
419 SIVAL(&sec_channel_type
, 0, sec_channel
);
420 ret
= secrets_store(machine_sec_channel_type_keystr(domain
), &sec_channel_type
, sizeof(sec_channel_type
));
426 /************************************************************************
427 Routine to fetch the previous plaintext machine account password for a realm
428 the password is assumed to be a null terminated ascii string.
429 ************************************************************************/
431 char *secrets_fetch_prev_machine_password(const char *domain
)
433 return (char *)secrets_fetch(machine_prev_password_keystr(domain
), NULL
);
436 /************************************************************************
437 Routine to fetch the plaintext machine account password for a realm
438 the password is assumed to be a null terminated ascii string.
439 ************************************************************************/
441 char *secrets_fetch_machine_password(const char *domain
,
442 time_t *pass_last_set_time
,
443 enum netr_SchannelType
*channel
)
446 ret
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
448 if (pass_last_set_time
) {
450 uint32
*last_set_time
;
451 last_set_time
= (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain
), &size
);
453 *pass_last_set_time
= IVAL(last_set_time
,0);
454 SAFE_FREE(last_set_time
);
456 *pass_last_set_time
= 0;
462 uint32
*channel_type
;
463 channel_type
= (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain
), &size
);
465 *channel
= IVAL(channel_type
,0);
466 SAFE_FREE(channel_type
);
468 *channel
= get_default_sec_channel();