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 ret
= secrets_store(domain_sid_keystr(domain
), sid
, sizeof(struct dom_sid
));
62 /* Force a re-query, in case we modified our domain */
64 reset_global_sam_sid();
68 bool secrets_fetch_domain_sid(const char *domain
, struct dom_sid
*sid
)
70 struct dom_sid
*dyn_sid
;
73 dyn_sid
= (struct dom_sid
*)secrets_fetch(domain_sid_keystr(domain
), &size
);
78 if (size
!= sizeof(struct dom_sid
)) {
88 bool secrets_store_domain_guid(const char *domain
, struct GUID
*guid
)
92 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
94 return secrets_store(key
, guid
, sizeof(struct GUID
));
97 bool secrets_fetch_domain_guid(const char *domain
, struct GUID
*guid
)
99 struct GUID
*dyn_guid
;
102 struct GUID new_guid
;
104 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
106 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
109 if (lp_server_role() == ROLE_DOMAIN_PDC
) {
110 new_guid
= GUID_random();
111 if (!secrets_store_domain_guid(domain
, &new_guid
))
113 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
115 if (dyn_guid
== NULL
) {
120 if (size
!= sizeof(struct GUID
)) {
121 DEBUG(1,("UUID size %d is wrong!\n", (int)size
));
132 * Form a key for fetching the machine trust account sec channel type
134 * @param domain domain name
138 static const char *machine_sec_channel_type_keystr(const char *domain
)
142 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
143 SECRETS_MACHINE_SEC_CHANNEL_TYPE
,
145 SMB_ASSERT(keystr
!= NULL
);
150 * Form a key for fetching the machine trust account last change time
152 * @param domain domain name
156 static const char *machine_last_change_time_keystr(const char *domain
)
160 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
161 SECRETS_MACHINE_LAST_CHANGE_TIME
,
163 SMB_ASSERT(keystr
!= NULL
);
169 * Form a key for fetching the machine previous trust account password
171 * @param domain domain name
175 static const char *machine_prev_password_keystr(const char *domain
)
179 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
180 SECRETS_MACHINE_PASSWORD_PREV
, domain
);
181 SMB_ASSERT(keystr
!= NULL
);
186 * Form a key for fetching the machine trust account password
188 * @param domain domain name
192 static const char *machine_password_keystr(const char *domain
)
196 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
197 SECRETS_MACHINE_PASSWORD
, domain
);
198 SMB_ASSERT(keystr
!= NULL
);
203 * Form a key for fetching the machine trust account password
205 * @param domain domain name
207 * @return stored password's key
209 static const char *trust_keystr(const char *domain
)
213 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
214 SECRETS_MACHINE_ACCT_PASS
, domain
);
215 SMB_ASSERT(keystr
!= NULL
);
219 /************************************************************************
220 Lock the trust password entry.
221 ************************************************************************/
223 void *secrets_get_trust_account_lock(TALLOC_CTX
*mem_ctx
, const char *domain
)
225 struct db_context
*db_ctx
;
226 if (!secrets_init()) {
230 db_ctx
= secrets_db_ctx();
232 return db_ctx
->fetch_locked(
233 db_ctx
, mem_ctx
, string_term_tdb_data(trust_keystr(domain
)));
236 /************************************************************************
237 Routine to get the default secure channel type for trust accounts
238 ************************************************************************/
240 enum netr_SchannelType
get_default_sec_channel(void)
242 if (lp_server_role() == ROLE_DOMAIN_BDC
||
243 lp_server_role() == ROLE_DOMAIN_PDC
) {
246 return SEC_CHAN_WKSTA
;
250 /************************************************************************
251 Routine to get the trust account password for a domain.
252 This only tries to get the legacy hashed version of the password.
253 The user of this function must have locked the trust password file using
254 the above secrets_lock_trust_account_password().
255 ************************************************************************/
257 bool secrets_fetch_trust_account_password_legacy(const char *domain
,
259 time_t *pass_last_set_time
,
260 enum netr_SchannelType
*channel
)
262 struct machine_acct_pass
*pass
;
265 if (!(pass
= (struct machine_acct_pass
*)secrets_fetch(
266 trust_keystr(domain
), &size
))) {
267 DEBUG(5, ("secrets_fetch failed!\n"));
271 if (size
!= sizeof(*pass
)) {
272 DEBUG(0, ("secrets were of incorrect size!\n"));
277 if (pass_last_set_time
) {
278 *pass_last_set_time
= pass
->mod_time
;
280 memcpy(ret_pwd
, pass
->hash
, 16);
283 *channel
= get_default_sec_channel();
286 /* Test if machine password has expired and needs to be changed */
287 if (lp_machine_password_timeout()) {
288 if (pass
->mod_time
> 0 && time(NULL
) > (pass
->mod_time
+
289 (time_t)lp_machine_password_timeout())) {
290 global_machine_password_needs_changing
= True
;
298 /************************************************************************
299 Routine to get the trust account password for a domain.
300 The user of this function must have locked the trust password file using
301 the above secrets_lock_trust_account_password().
302 ************************************************************************/
304 bool secrets_fetch_trust_account_password(const char *domain
, uint8 ret_pwd
[16],
305 time_t *pass_last_set_time
,
306 enum netr_SchannelType
*channel
)
310 plaintext
= secrets_fetch_machine_password(domain
, pass_last_set_time
,
313 DEBUG(4,("Using cleartext machine password\n"));
314 E_md4hash(plaintext
, ret_pwd
);
315 SAFE_FREE(plaintext
);
319 return secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
324 /************************************************************************
325 Routine to delete the old plaintext machine account password if any
326 ************************************************************************/
328 static bool secrets_delete_prev_machine_password(const char *domain
)
330 char *oldpass
= (char *)secrets_fetch(machine_prev_password_keystr(domain
), NULL
);
331 if (oldpass
== NULL
) {
335 return secrets_delete(machine_prev_password_keystr(domain
));
338 /************************************************************************
339 Routine to delete the plaintext machine account password and old
341 ************************************************************************/
343 bool secrets_delete_machine_password(const char *domain
)
345 if (!secrets_delete_prev_machine_password(domain
)) {
348 return secrets_delete(machine_password_keystr(domain
));
351 /************************************************************************
352 Routine to delete the plaintext machine account password, old password,
353 sec channel type and last change time from secrets database
354 ************************************************************************/
356 bool secrets_delete_machine_password_ex(const char *domain
)
358 if (!secrets_delete_prev_machine_password(domain
)) {
361 if (!secrets_delete(machine_password_keystr(domain
))) {
364 if (!secrets_delete(machine_sec_channel_type_keystr(domain
))) {
367 return secrets_delete(machine_last_change_time_keystr(domain
));
370 /************************************************************************
371 Routine to delete the domain sid
372 ************************************************************************/
374 bool secrets_delete_domain_sid(const char *domain
)
376 return secrets_delete(domain_sid_keystr(domain
));
379 /************************************************************************
380 Routine to store the previous machine password (by storing the current password
382 ************************************************************************/
384 static bool secrets_store_prev_machine_password(const char *domain
)
389 oldpass
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
390 if (oldpass
== NULL
) {
393 ret
= secrets_store(machine_prev_password_keystr(domain
), oldpass
, strlen(oldpass
)+1);
398 /************************************************************************
399 Routine to set the plaintext machine account password for a realm
400 the password is assumed to be a null terminated ascii string.
402 ************************************************************************/
404 bool secrets_store_machine_password(const char *pass
, const char *domain
,
405 enum netr_SchannelType sec_channel
)
408 uint32 last_change_time
;
409 uint32 sec_channel_type
;
411 if (!secrets_store_prev_machine_password(domain
)) {
415 ret
= secrets_store(machine_password_keystr(domain
), pass
, strlen(pass
)+1);
419 SIVAL(&last_change_time
, 0, time(NULL
));
420 ret
= secrets_store(machine_last_change_time_keystr(domain
), &last_change_time
, sizeof(last_change_time
));
422 SIVAL(&sec_channel_type
, 0, sec_channel
);
423 ret
= secrets_store(machine_sec_channel_type_keystr(domain
), &sec_channel_type
, sizeof(sec_channel_type
));
429 /************************************************************************
430 Routine to fetch the previous plaintext machine account password for a realm
431 the password is assumed to be a null terminated ascii string.
432 ************************************************************************/
434 char *secrets_fetch_prev_machine_password(const char *domain
)
436 return (char *)secrets_fetch(machine_prev_password_keystr(domain
), NULL
);
439 /************************************************************************
440 Routine to fetch the plaintext machine account password for a realm
441 the password is assumed to be a null terminated ascii string.
442 ************************************************************************/
444 char *secrets_fetch_machine_password(const char *domain
,
445 time_t *pass_last_set_time
,
446 enum netr_SchannelType
*channel
)
449 ret
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
451 if (pass_last_set_time
) {
453 uint32
*last_set_time
;
454 last_set_time
= (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain
), &size
);
456 *pass_last_set_time
= IVAL(last_set_time
,0);
457 SAFE_FREE(last_set_time
);
459 *pass_last_set_time
= 0;
465 uint32
*channel_type
;
466 channel_type
= (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain
), &size
);
468 *channel
= IVAL(channel_type
,0);
469 SAFE_FREE(channel_type
);
471 *channel
= get_default_sec_channel();