s4-test/repl_schema: Remote global ldb connections
[Samba.git] / source3 / passdb / machine_account_secrets.c
blobf3206d4eb8e11c7b756c0ae8a786a266fc54696b
1 /*
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 */
25 #include "includes.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "secrets.h"
28 #include "dbwrap.h"
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_PASSDB
33 /* Urrrg. global.... */
34 bool global_machine_password_needs_changing;
36 /**
37 * Form a key for fetching the domain sid
39 * @param domain domain name
41 * @return keystring
42 **/
43 static const char *domain_sid_keystr(const char *domain)
45 char *keystr;
47 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
48 SECRETS_DOMAIN_SID, domain);
49 SMB_ASSERT(keystr != NULL);
50 return keystr;
53 bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
55 bool ret;
57 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
59 /* Force a re-query, in case we modified our domain */
60 if (ret)
61 reset_global_sam_sid();
62 return ret;
65 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
67 struct dom_sid *dyn_sid;
68 size_t size = 0;
70 dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
72 if (dyn_sid == NULL)
73 return False;
75 if (size != sizeof(struct dom_sid)) {
76 SAFE_FREE(dyn_sid);
77 return False;
80 *sid = *dyn_sid;
81 SAFE_FREE(dyn_sid);
82 return True;
85 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
87 fstring key;
89 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
90 strupper_m(key);
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;
97 fstring key;
98 size_t size = 0;
99 struct GUID new_guid;
101 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
102 strupper_m(key);
103 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
105 if (!dyn_guid) {
106 if (lp_server_role() == ROLE_DOMAIN_PDC) {
107 new_guid = GUID_random();
108 if (!secrets_store_domain_guid(domain, &new_guid))
109 return False;
110 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
112 if (dyn_guid == NULL) {
113 return False;
117 if (size != sizeof(struct GUID)) {
118 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
119 SAFE_FREE(dyn_guid);
120 return False;
123 *guid = *dyn_guid;
124 SAFE_FREE(dyn_guid);
125 return True;
129 * Form a key for fetching the machine trust account sec channel type
131 * @param domain domain name
133 * @return keystring
135 static const char *machine_sec_channel_type_keystr(const char *domain)
137 char *keystr;
139 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
140 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
141 domain);
142 SMB_ASSERT(keystr != NULL);
143 return keystr;
147 * Form a key for fetching the machine trust account last change time
149 * @param domain domain name
151 * @return keystring
153 static const char *machine_last_change_time_keystr(const char *domain)
155 char *keystr;
157 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
158 SECRETS_MACHINE_LAST_CHANGE_TIME,
159 domain);
160 SMB_ASSERT(keystr != NULL);
161 return keystr;
166 * Form a key for fetching the machine previous trust account password
168 * @param domain domain name
170 * @return keystring
172 static const char *machine_prev_password_keystr(const char *domain)
174 char *keystr;
176 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
177 SECRETS_MACHINE_PASSWORD_PREV, domain);
178 SMB_ASSERT(keystr != NULL);
179 return keystr;
183 * Form a key for fetching the machine trust account password
185 * @param domain domain name
187 * @return keystring
189 static const char *machine_password_keystr(const char *domain)
191 char *keystr;
193 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
194 SECRETS_MACHINE_PASSWORD, domain);
195 SMB_ASSERT(keystr != NULL);
196 return keystr;
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)
208 char *keystr;
210 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
211 SECRETS_MACHINE_ACCT_PASS, domain);
212 SMB_ASSERT(keystr != NULL);
213 return keystr;
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()) {
224 return NULL;
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) {
241 return SEC_CHAN_BDC;
242 } else {
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,
255 uint8 ret_pwd[16],
256 time_t *pass_last_set_time,
257 enum netr_SchannelType *channel)
259 struct machine_acct_pass *pass;
260 size_t size = 0;
262 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
263 trust_keystr(domain), &size))) {
264 DEBUG(5, ("secrets_fetch failed!\n"));
265 return False;
268 if (size != sizeof(*pass)) {
269 DEBUG(0, ("secrets were of incorrect size!\n"));
270 SAFE_FREE(pass);
271 return False;
274 if (pass_last_set_time) {
275 *pass_last_set_time = pass->mod_time;
277 memcpy(ret_pwd, pass->hash, 16);
279 if (channel) {
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;
291 SAFE_FREE(pass);
292 return 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)
305 char *plaintext;
307 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
308 channel);
309 if (plaintext) {
310 DEBUG(4,("Using cleartext machine password\n"));
311 E_md4hash(plaintext, ret_pwd);
312 SAFE_FREE(plaintext);
313 return True;
316 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
317 pass_last_set_time,
318 channel);
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) {
329 return true;
331 SAFE_FREE(oldpass);
332 return secrets_delete(machine_prev_password_keystr(domain));
335 /************************************************************************
336 Routine to delete the plaintext machine account password and old
337 password if any
338 ************************************************************************/
340 bool secrets_delete_machine_password(const char *domain)
342 if (!secrets_delete_prev_machine_password(domain)) {
343 return false;
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)) {
356 return false;
358 if (!secrets_delete(machine_password_keystr(domain))) {
359 return false;
361 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
362 return false;
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
378 as the old)
379 ************************************************************************/
381 static bool secrets_store_prev_machine_password(const char *domain)
383 char *oldpass;
384 bool ret;
386 oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
387 if (oldpass == NULL) {
388 return true;
390 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
391 SAFE_FREE(oldpass);
392 return ret;
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.
398 Before storing
399 ************************************************************************/
401 bool secrets_store_machine_password(const char *pass, const char *domain,
402 enum netr_SchannelType sec_channel)
404 bool ret;
405 uint32 last_change_time;
406 uint32 sec_channel_type;
408 if (!secrets_store_prev_machine_password(domain)) {
409 return false;
412 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
413 if (!ret)
414 return ret;
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));
422 return ret;
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)
445 char *ret;
446 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
448 if (pass_last_set_time) {
449 size_t size;
450 uint32 *last_set_time;
451 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
452 if (last_set_time) {
453 *pass_last_set_time = IVAL(last_set_time,0);
454 SAFE_FREE(last_set_time);
455 } else {
456 *pass_last_set_time = 0;
460 if (channel) {
461 size_t size;
462 uint32 *channel_type;
463 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
464 if (channel_type) {
465 *channel = IVAL(channel_type,0);
466 SAFE_FREE(channel_type);
467 } else {
468 *channel = get_default_sec_channel();
472 return ret;