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"
29 #define DBGC_CLASS DBGC_PASSDB
31 /* Urrrg. global.... */
32 bool global_machine_password_needs_changing;
35 * Form a key for fetching the domain sid
37 * @param domain domain name
41 static const char *domain_sid_keystr(const char *domain)
45 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
46 SECRETS_DOMAIN_SID, domain);
47 SMB_ASSERT(keystr != NULL);
51 bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
55 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
57 /* Force a re-query, in case we modified our domain */
59 reset_global_sam_sid();
63 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
65 struct dom_sid *dyn_sid;
68 dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
73 if (size != sizeof(struct dom_sid)) {
83 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
87 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
89 return secrets_store(key, guid, sizeof(struct GUID));
92 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
94 struct GUID *dyn_guid;
99 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
101 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
104 if (lp_server_role() == ROLE_DOMAIN_PDC) {
105 new_guid = GUID_random();
106 if (!secrets_store_domain_guid(domain, &new_guid))
108 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
110 if (dyn_guid == NULL) {
115 if (size != sizeof(struct GUID)) {
116 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
127 * Form a key for fetching the machine trust account sec channel type
129 * @param domain domain name
133 static const char *machine_sec_channel_type_keystr(const char *domain)
137 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
138 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
140 SMB_ASSERT(keystr != NULL);
145 * Form a key for fetching the machine trust account last change time
147 * @param domain domain name
151 static const char *machine_last_change_time_keystr(const char *domain)
155 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
156 SECRETS_MACHINE_LAST_CHANGE_TIME,
158 SMB_ASSERT(keystr != NULL);
164 * Form a key for fetching the machine previous trust account password
166 * @param domain domain name
170 static const char *machine_prev_password_keystr(const char *domain)
174 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
175 SECRETS_MACHINE_PASSWORD_PREV, domain);
176 SMB_ASSERT(keystr != NULL);
181 * Form a key for fetching the machine trust account password
183 * @param domain domain name
187 static const char *machine_password_keystr(const char *domain)
191 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
192 SECRETS_MACHINE_PASSWORD, domain);
193 SMB_ASSERT(keystr != NULL);
198 * Form a key for fetching the machine trust account password
200 * @param domain domain name
202 * @return stored password's key
204 static const char *trust_keystr(const char *domain)
208 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
209 SECRETS_MACHINE_ACCT_PASS, domain);
210 SMB_ASSERT(keystr != NULL);
214 /************************************************************************
215 Lock the trust password entry.
216 ************************************************************************/
218 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
220 struct db_context *db_ctx;
221 if (!secrets_init()) {
225 db_ctx = secrets_db_ctx();
227 return db_ctx->fetch_locked(
228 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
231 /************************************************************************
232 Routine to get the default secure channel type for trust accounts
233 ************************************************************************/
235 enum netr_SchannelType get_default_sec_channel(void)
237 if (lp_server_role() == ROLE_DOMAIN_BDC ||
238 lp_server_role() == ROLE_DOMAIN_PDC) {
241 return SEC_CHAN_WKSTA;
245 /************************************************************************
246 Routine to get the trust account password for a domain.
247 This only tries to get the legacy hashed version of the password.
248 The user of this function must have locked the trust password file using
249 the above secrets_lock_trust_account_password().
250 ************************************************************************/
252 bool secrets_fetch_trust_account_password_legacy(const char *domain,
254 time_t *pass_last_set_time,
255 enum netr_SchannelType *channel)
257 struct machine_acct_pass *pass;
260 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
261 trust_keystr(domain), &size))) {
262 DEBUG(5, ("secrets_fetch failed!\n"));
266 if (size != sizeof(*pass)) {
267 DEBUG(0, ("secrets were of incorrect size!\n"));
272 if (pass_last_set_time) {
273 *pass_last_set_time = pass->mod_time;
275 memcpy(ret_pwd, pass->hash, 16);
278 *channel = get_default_sec_channel();
281 /* Test if machine password has expired and needs to be changed */
282 if (lp_machine_password_timeout()) {
283 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
284 (time_t)lp_machine_password_timeout())) {
285 global_machine_password_needs_changing = True;
293 /************************************************************************
294 Routine to get the trust account password for a domain.
295 The user of this function must have locked the trust password file using
296 the above secrets_lock_trust_account_password().
297 ************************************************************************/
299 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
300 time_t *pass_last_set_time,
301 enum netr_SchannelType *channel)
305 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
308 DEBUG(4,("Using cleartext machine password\n"));
309 E_md4hash(plaintext, ret_pwd);
310 SAFE_FREE(plaintext);
314 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
319 /************************************************************************
320 Routine to delete the old plaintext machine account password if any
321 ************************************************************************/
323 static bool secrets_delete_prev_machine_password(const char *domain)
325 char *oldpass = (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
326 if (oldpass == NULL) {
330 return secrets_delete(machine_prev_password_keystr(domain));
333 /************************************************************************
334 Routine to delete the plaintext machine account password and old
336 ************************************************************************/
338 bool secrets_delete_machine_password(const char *domain)
340 if (!secrets_delete_prev_machine_password(domain)) {
343 return secrets_delete(machine_password_keystr(domain));
346 /************************************************************************
347 Routine to delete the plaintext machine account password, old password,
348 sec channel type and last change time from secrets database
349 ************************************************************************/
351 bool secrets_delete_machine_password_ex(const char *domain)
353 if (!secrets_delete_prev_machine_password(domain)) {
356 if (!secrets_delete(machine_password_keystr(domain))) {
359 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
362 return secrets_delete(machine_last_change_time_keystr(domain));
365 /************************************************************************
366 Routine to delete the domain sid
367 ************************************************************************/
369 bool secrets_delete_domain_sid(const char *domain)
371 return secrets_delete(domain_sid_keystr(domain));
374 /************************************************************************
375 Routine to store the previous machine password (by storing the current password
377 ************************************************************************/
379 static bool secrets_store_prev_machine_password(const char *domain)
384 oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
385 if (oldpass == NULL) {
388 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
393 /************************************************************************
394 Routine to set the plaintext machine account password for a realm
395 the password is assumed to be a null terminated ascii string.
397 ************************************************************************/
399 bool secrets_store_machine_password(const char *pass, const char *domain,
400 enum netr_SchannelType sec_channel)
403 uint32 last_change_time;
404 uint32 sec_channel_type;
406 if (!secrets_store_prev_machine_password(domain)) {
410 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
414 SIVAL(&last_change_time, 0, time(NULL));
415 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
417 SIVAL(&sec_channel_type, 0, sec_channel);
418 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
424 /************************************************************************
425 Routine to fetch the previous plaintext machine account password for a realm
426 the password is assumed to be a null terminated ascii string.
427 ************************************************************************/
429 char *secrets_fetch_prev_machine_password(const char *domain)
431 return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
434 /************************************************************************
435 Routine to fetch the plaintext machine account password for a realm
436 the password is assumed to be a null terminated ascii string.
437 ************************************************************************/
439 char *secrets_fetch_machine_password(const char *domain,
440 time_t *pass_last_set_time,
441 enum netr_SchannelType *channel)
444 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
446 if (pass_last_set_time) {
448 uint32 *last_set_time;
449 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
451 *pass_last_set_time = IVAL(last_set_time,0);
452 SAFE_FREE(last_set_time);
454 *pass_last_set_time = 0;
460 uint32 *channel_type;
461 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
463 *channel = IVAL(channel_type,0);
464 SAFE_FREE(channel_type);
466 *channel = get_default_sec_channel();