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"
30 #define DBGC_CLASS DBGC_PASSDB
32 /* Urrrg. global.... */
33 bool global_machine_password_needs_changing;
36 * Form a key for fetching the domain sid
38 * @param domain domain name
42 static const char *domain_sid_keystr(const char *domain)
46 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
47 SECRETS_DOMAIN_SID, domain);
48 SMB_ASSERT(keystr != NULL);
52 bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
56 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
58 /* Force a re-query, in case we modified our domain */
60 reset_global_sam_sid();
64 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
66 struct dom_sid *dyn_sid;
69 dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
74 if (size != sizeof(struct dom_sid)) {
84 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
88 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
90 return secrets_store(key, guid, sizeof(struct GUID));
93 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
95 struct GUID *dyn_guid;
100 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
102 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
105 if (lp_server_role() == ROLE_DOMAIN_PDC) {
106 new_guid = GUID_random();
107 if (!secrets_store_domain_guid(domain, &new_guid))
109 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
111 if (dyn_guid == NULL) {
116 if (size != sizeof(struct GUID)) {
117 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
128 * Form a key for fetching the machine trust account sec channel type
130 * @param domain domain name
134 static const char *machine_sec_channel_type_keystr(const char *domain)
138 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
139 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
141 SMB_ASSERT(keystr != NULL);
146 * Form a key for fetching the machine trust account last change time
148 * @param domain domain name
152 static const char *machine_last_change_time_keystr(const char *domain)
156 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
157 SECRETS_MACHINE_LAST_CHANGE_TIME,
159 SMB_ASSERT(keystr != NULL);
165 * Form a key for fetching the machine previous trust account password
167 * @param domain domain name
171 static const char *machine_prev_password_keystr(const char *domain)
175 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
176 SECRETS_MACHINE_PASSWORD_PREV, domain);
177 SMB_ASSERT(keystr != NULL);
182 * Form a key for fetching the machine trust account password
184 * @param domain domain name
188 static const char *machine_password_keystr(const char *domain)
192 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
193 SECRETS_MACHINE_PASSWORD, domain);
194 SMB_ASSERT(keystr != NULL);
199 * Form a key for fetching the machine trust account password
201 * @param domain domain name
203 * @return stored password's key
205 static const char *trust_keystr(const char *domain)
209 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
210 SECRETS_MACHINE_ACCT_PASS, domain);
211 SMB_ASSERT(keystr != NULL);
215 /************************************************************************
216 Lock the trust password entry.
217 ************************************************************************/
219 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
221 struct db_context *db_ctx;
222 if (!secrets_init()) {
226 db_ctx = secrets_db_ctx();
228 return db_ctx->fetch_locked(
229 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
232 /************************************************************************
233 Routine to get the default secure channel type for trust accounts
234 ************************************************************************/
236 enum netr_SchannelType get_default_sec_channel(void)
238 if (lp_server_role() == ROLE_DOMAIN_BDC ||
239 lp_server_role() == ROLE_DOMAIN_PDC) {
242 return SEC_CHAN_WKSTA;
246 /************************************************************************
247 Routine to get the trust account password for a domain.
248 This only tries to get the legacy hashed version of the password.
249 The user of this function must have locked the trust password file using
250 the above secrets_lock_trust_account_password().
251 ************************************************************************/
253 bool secrets_fetch_trust_account_password_legacy(const char *domain,
255 time_t *pass_last_set_time,
256 enum netr_SchannelType *channel)
258 struct machine_acct_pass *pass;
261 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
262 trust_keystr(domain), &size))) {
263 DEBUG(5, ("secrets_fetch failed!\n"));
267 if (size != sizeof(*pass)) {
268 DEBUG(0, ("secrets were of incorrect size!\n"));
273 if (pass_last_set_time) {
274 *pass_last_set_time = pass->mod_time;
276 memcpy(ret_pwd, pass->hash, 16);
279 *channel = get_default_sec_channel();
282 /* Test if machine password has expired and needs to be changed */
283 if (lp_machine_password_timeout()) {
284 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
285 (time_t)lp_machine_password_timeout())) {
286 global_machine_password_needs_changing = True;
294 /************************************************************************
295 Routine to get the trust account password for a domain.
296 The user of this function must have locked the trust password file using
297 the above secrets_lock_trust_account_password().
298 ************************************************************************/
300 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
301 time_t *pass_last_set_time,
302 enum netr_SchannelType *channel)
306 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
309 DEBUG(4,("Using cleartext machine password\n"));
310 E_md4hash(plaintext, ret_pwd);
311 SAFE_FREE(plaintext);
315 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
320 /************************************************************************
321 Routine to delete the old plaintext machine account password if any
322 ************************************************************************/
324 static bool secrets_delete_prev_machine_password(const char *domain)
326 char *oldpass = (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
327 if (oldpass == NULL) {
331 return secrets_delete(machine_prev_password_keystr(domain));
334 /************************************************************************
335 Routine to delete the plaintext machine account password and old
337 ************************************************************************/
339 bool secrets_delete_machine_password(const char *domain)
341 if (!secrets_delete_prev_machine_password(domain)) {
344 return secrets_delete(machine_password_keystr(domain));
347 /************************************************************************
348 Routine to delete the plaintext machine account password, old password,
349 sec channel type and last change time from secrets database
350 ************************************************************************/
352 bool secrets_delete_machine_password_ex(const char *domain)
354 if (!secrets_delete_prev_machine_password(domain)) {
357 if (!secrets_delete(machine_password_keystr(domain))) {
360 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
363 return secrets_delete(machine_last_change_time_keystr(domain));
366 /************************************************************************
367 Routine to delete the domain sid
368 ************************************************************************/
370 bool secrets_delete_domain_sid(const char *domain)
372 return secrets_delete(domain_sid_keystr(domain));
375 /************************************************************************
376 Routine to store the previous machine password (by storing the current password
378 ************************************************************************/
380 static bool secrets_store_prev_machine_password(const char *domain)
385 oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
386 if (oldpass == NULL) {
389 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
394 /************************************************************************
395 Routine to set the plaintext machine account password for a realm
396 the password is assumed to be a null terminated ascii string.
398 ************************************************************************/
400 bool secrets_store_machine_password(const char *pass, const char *domain,
401 enum netr_SchannelType sec_channel)
404 uint32 last_change_time;
405 uint32 sec_channel_type;
407 if (!secrets_store_prev_machine_password(domain)) {
411 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
415 SIVAL(&last_change_time, 0, time(NULL));
416 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
418 SIVAL(&sec_channel_type, 0, sec_channel);
419 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
425 /************************************************************************
426 Routine to fetch the previous plaintext machine account password for a realm
427 the password is assumed to be a null terminated ascii string.
428 ************************************************************************/
430 char *secrets_fetch_prev_machine_password(const char *domain)
432 return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
435 /************************************************************************
436 Routine to fetch the plaintext machine account password for a realm
437 the password is assumed to be a null terminated ascii string.
438 ************************************************************************/
440 char *secrets_fetch_machine_password(const char *domain,
441 time_t *pass_last_set_time,
442 enum netr_SchannelType *channel)
445 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
447 if (pass_last_set_time) {
449 uint32 *last_set_time;
450 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
452 *pass_last_set_time = IVAL(last_set_time,0);
453 SAFE_FREE(last_set_time);
455 *pass_last_set_time = 0;
461 uint32 *channel_type;
462 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
464 *channel = IVAL(channel_type,0);
465 SAFE_FREE(channel_type);
467 *channel = get_default_sec_channel();