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 trust account password
166 * @param domain domain name
170 static const char *machine_password_keystr(const char *domain)
174 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
175 SECRETS_MACHINE_PASSWORD, domain);
176 SMB_ASSERT(keystr != NULL);
181 * Form a key for fetching the machine trust account password
183 * @param domain domain name
185 * @return stored password's key
187 static const char *trust_keystr(const char *domain)
191 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
192 SECRETS_MACHINE_ACCT_PASS, domain);
193 SMB_ASSERT(keystr != NULL);
197 /************************************************************************
198 Lock the trust password entry.
199 ************************************************************************/
201 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
203 struct db_context *db_ctx;
204 if (!secrets_init()) {
208 db_ctx = secrets_db_ctx();
210 return db_ctx->fetch_locked(
211 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
214 /************************************************************************
215 Routine to get the default secure channel type for trust accounts
216 ************************************************************************/
218 enum netr_SchannelType get_default_sec_channel(void)
220 if (lp_server_role() == ROLE_DOMAIN_BDC ||
221 lp_server_role() == ROLE_DOMAIN_PDC) {
224 return SEC_CHAN_WKSTA;
228 /************************************************************************
229 Routine to get the trust account password for a domain.
230 This only tries to get the legacy hashed version of the password.
231 The user of this function must have locked the trust password file using
232 the above secrets_lock_trust_account_password().
233 ************************************************************************/
235 bool secrets_fetch_trust_account_password_legacy(const char *domain,
237 time_t *pass_last_set_time,
238 enum netr_SchannelType *channel)
240 struct machine_acct_pass *pass;
243 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
244 trust_keystr(domain), &size))) {
245 DEBUG(5, ("secrets_fetch failed!\n"));
249 if (size != sizeof(*pass)) {
250 DEBUG(0, ("secrets were of incorrect size!\n"));
255 if (pass_last_set_time) {
256 *pass_last_set_time = pass->mod_time;
258 memcpy(ret_pwd, pass->hash, 16);
261 *channel = get_default_sec_channel();
264 /* Test if machine password has expired and needs to be changed */
265 if (lp_machine_password_timeout()) {
266 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
267 (time_t)lp_machine_password_timeout())) {
268 global_machine_password_needs_changing = True;
276 /************************************************************************
277 Routine to get the trust account password for a domain.
278 The user of this function must have locked the trust password file using
279 the above secrets_lock_trust_account_password().
280 ************************************************************************/
282 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
283 time_t *pass_last_set_time,
284 enum netr_SchannelType *channel)
288 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
291 DEBUG(4,("Using cleartext machine password\n"));
292 E_md4hash(plaintext, ret_pwd);
293 SAFE_FREE(plaintext);
297 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
302 /************************************************************************
303 Routine to delete the plaintext machine account password
304 ************************************************************************/
306 bool secrets_delete_machine_password(const char *domain)
308 return secrets_delete(machine_password_keystr(domain));
311 /************************************************************************
312 Routine to delete the plaintext machine account password, sec channel type and
313 last change time from secrets database
314 ************************************************************************/
316 bool secrets_delete_machine_password_ex(const char *domain)
318 if (!secrets_delete(machine_password_keystr(domain))) {
321 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
324 return secrets_delete(machine_last_change_time_keystr(domain));
327 /************************************************************************
328 Routine to delete the domain sid
329 ************************************************************************/
331 bool secrets_delete_domain_sid(const char *domain)
333 return secrets_delete(domain_sid_keystr(domain));
336 /************************************************************************
337 Routine to set the plaintext machine account password for a realm
338 the password is assumed to be a null terminated ascii string
339 ************************************************************************/
341 bool secrets_store_machine_password(const char *pass, const char *domain,
342 enum netr_SchannelType sec_channel)
345 uint32 last_change_time;
346 uint32 sec_channel_type;
348 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
352 SIVAL(&last_change_time, 0, time(NULL));
353 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
355 SIVAL(&sec_channel_type, 0, sec_channel);
356 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
361 /************************************************************************
362 Routine to fetch the plaintext machine account password for a realm
363 the password is assumed to be a null terminated ascii string.
364 ************************************************************************/
366 char *secrets_fetch_machine_password(const char *domain,
367 time_t *pass_last_set_time,
368 enum netr_SchannelType *channel)
371 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
373 if (pass_last_set_time) {
375 uint32 *last_set_time;
376 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
378 *pass_last_set_time = IVAL(last_set_time,0);
379 SAFE_FREE(last_set_time);
381 *pass_last_set_time = 0;
387 uint32 *channel_type;
388 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
390 *channel = IVAL(channel_type,0);
391 SAFE_FREE(channel_type);
393 *channel = get_default_sec_channel();