s3-torture: introduce test_cli_read()
[Samba/gebeck_regimport.git] / source3 / passdb / machine_account_secrets.c
blob665e2f89a4535d8eb7798ade6aed3be025792074
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 "passdb.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "secrets.h"
29 #include "dbwrap.h"
30 #include "../librpc/ndr/libndr.h"
31 #include "util_tdb.h"
33 #undef DBGC_CLASS
34 #define DBGC_CLASS DBGC_PASSDB
36 /* Urrrg. global.... */
37 bool global_machine_password_needs_changing;
39 /**
40 * Form a key for fetching the domain sid
42 * @param domain domain name
44 * @return keystring
45 **/
46 static const char *domain_sid_keystr(const char *domain)
48 char *keystr;
50 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
51 SECRETS_DOMAIN_SID, domain);
52 SMB_ASSERT(keystr != NULL);
53 return keystr;
56 bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
58 bool ret;
60 #ifdef _SAMBA_WAF_BUILD_
61 if (strequal(domain, get_global_sam_name()) &&
62 (pdb_capabilities() & PDB_CAP_ADS)) {
63 /* If we have a ADS-capable passdb backend, we
64 * must never make up our own SID, it will
65 * already be in the directory */
66 DEBUG(0, ("Refusing to store a Domain SID, this should be read from the directory not stored here\n"));
67 return false;
69 #endif
71 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
73 /* Force a re-query, in case we modified our domain */
74 if (ret)
75 reset_global_sam_sid();
76 return ret;
79 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
81 struct dom_sid *dyn_sid;
82 size_t size = 0;
84 #ifdef _SAMBA_WAF_BUILD_
85 if (strequal(domain, get_global_sam_name()) &&
86 (pdb_capabilities() & PDB_CAP_ADS)) {
87 struct pdb_domain_info *domain_info;
88 domain_info = pdb_get_domain_info(talloc_tos());
89 if (!domain_info) {
90 /* If we have a ADS-capable passdb backend, we
91 * must never make up our own SID, it will
92 * already be in the directory */
93 DEBUG(0, ("Unable to fetch a Domain SID from the directory!\n"));
94 return false;
97 *sid = domain_info->sid;
98 return true;
100 #endif
102 dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
104 if (dyn_sid == NULL)
105 return False;
107 if (size != sizeof(struct dom_sid)) {
108 SAFE_FREE(dyn_sid);
109 return False;
112 *sid = *dyn_sid;
113 SAFE_FREE(dyn_sid);
114 return True;
117 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
119 fstring key;
121 #ifdef _SAMBA_WAF_BUILD_
122 if (strequal(domain, get_global_sam_name()) &&
123 (pdb_capabilities() & PDB_CAP_ADS)) {
124 /* If we have a ADS-capable passdb backend, we
125 * must never make up our own GUID, it will
126 * already be in the directory */
127 DEBUG(0, ("Refusing to store a Domain GUID, this should be read from the directory not stored here\n"));
128 return false;
130 #endif
132 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
133 strupper_m(key);
134 return secrets_store(key, guid, sizeof(struct GUID));
137 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
139 struct GUID *dyn_guid;
140 fstring key;
141 size_t size = 0;
142 struct GUID new_guid;
144 #ifdef _SAMBA_WAF_BUILD_
145 if (strequal(domain, get_global_sam_name()) &&
146 (pdb_capabilities() & PDB_CAP_ADS)) {
147 struct pdb_domain_info *domain_info;
148 domain_info = pdb_get_domain_info(talloc_tos());
149 if (!domain_info) {
150 /* If we have a ADS-capable passdb backend, we
151 * must never make up our own SID, it will
152 * already be in the directory */
153 DEBUG(0, ("Unable to fetch a Domain GUID from the directory!\n"));
154 return false;
157 *guid = domain_info->guid;
158 return true;
160 #endif
162 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
163 strupper_m(key);
164 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
166 if (!dyn_guid) {
167 if (lp_server_role() == ROLE_DOMAIN_PDC) {
168 new_guid = GUID_random();
169 if (!secrets_store_domain_guid(domain, &new_guid))
170 return False;
171 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
173 if (dyn_guid == NULL) {
174 return False;
178 if (size != sizeof(struct GUID)) {
179 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
180 SAFE_FREE(dyn_guid);
181 return False;
184 *guid = *dyn_guid;
185 SAFE_FREE(dyn_guid);
186 return True;
190 * Form a key for fetching the machine trust account sec channel type
192 * @param domain domain name
194 * @return keystring
196 static const char *machine_sec_channel_type_keystr(const char *domain)
198 char *keystr;
200 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
201 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
202 domain);
203 SMB_ASSERT(keystr != NULL);
204 return keystr;
208 * Form a key for fetching the machine trust account last change time
210 * @param domain domain name
212 * @return keystring
214 static const char *machine_last_change_time_keystr(const char *domain)
216 char *keystr;
218 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
219 SECRETS_MACHINE_LAST_CHANGE_TIME,
220 domain);
221 SMB_ASSERT(keystr != NULL);
222 return keystr;
227 * Form a key for fetching the machine previous trust account password
229 * @param domain domain name
231 * @return keystring
233 static const char *machine_prev_password_keystr(const char *domain)
235 char *keystr;
237 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
238 SECRETS_MACHINE_PASSWORD_PREV, domain);
239 SMB_ASSERT(keystr != NULL);
240 return keystr;
244 * Form a key for fetching the machine trust account password
246 * @param domain domain name
248 * @return keystring
250 static const char *machine_password_keystr(const char *domain)
252 char *keystr;
254 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
255 SECRETS_MACHINE_PASSWORD, domain);
256 SMB_ASSERT(keystr != NULL);
257 return keystr;
261 * Form a key for fetching the machine trust account password
263 * @param domain domain name
265 * @return stored password's key
267 static const char *trust_keystr(const char *domain)
269 char *keystr;
271 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
272 SECRETS_MACHINE_ACCT_PASS, domain);
273 SMB_ASSERT(keystr != NULL);
274 return keystr;
277 /************************************************************************
278 Lock the trust password entry.
279 ************************************************************************/
281 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
283 struct db_context *db_ctx;
284 if (!secrets_init()) {
285 return NULL;
288 db_ctx = secrets_db_ctx();
290 return db_ctx->fetch_locked(
291 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
294 /************************************************************************
295 Routine to get the default secure channel type for trust accounts
296 ************************************************************************/
298 enum netr_SchannelType get_default_sec_channel(void)
300 if (lp_server_role() == ROLE_DOMAIN_BDC ||
301 lp_server_role() == ROLE_DOMAIN_PDC) {
302 return SEC_CHAN_BDC;
303 } else {
304 return SEC_CHAN_WKSTA;
308 /************************************************************************
309 Routine to get the trust account password for a domain.
310 This only tries to get the legacy hashed version of the password.
311 The user of this function must have locked the trust password file using
312 the above secrets_lock_trust_account_password().
313 ************************************************************************/
315 bool secrets_fetch_trust_account_password_legacy(const char *domain,
316 uint8 ret_pwd[16],
317 time_t *pass_last_set_time,
318 enum netr_SchannelType *channel)
320 struct machine_acct_pass *pass;
321 size_t size = 0;
323 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
324 trust_keystr(domain), &size))) {
325 DEBUG(5, ("secrets_fetch failed!\n"));
326 return False;
329 if (size != sizeof(*pass)) {
330 DEBUG(0, ("secrets were of incorrect size!\n"));
331 SAFE_FREE(pass);
332 return False;
335 if (pass_last_set_time) {
336 *pass_last_set_time = pass->mod_time;
338 memcpy(ret_pwd, pass->hash, 16);
340 if (channel) {
341 *channel = get_default_sec_channel();
344 /* Test if machine password has expired and needs to be changed */
345 if (lp_machine_password_timeout()) {
346 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
347 (time_t)lp_machine_password_timeout())) {
348 global_machine_password_needs_changing = True;
352 SAFE_FREE(pass);
353 return True;
356 /************************************************************************
357 Routine to get the trust account password for a domain.
358 The user of this function must have locked the trust password file using
359 the above secrets_lock_trust_account_password().
360 ************************************************************************/
362 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
363 time_t *pass_last_set_time,
364 enum netr_SchannelType *channel)
366 char *plaintext;
368 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
369 channel);
370 if (plaintext) {
371 DEBUG(4,("Using cleartext machine password\n"));
372 E_md4hash(plaintext, ret_pwd);
373 SAFE_FREE(plaintext);
374 return True;
377 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
378 pass_last_set_time,
379 channel);
382 /************************************************************************
383 Routine to delete the old plaintext machine account password if any
384 ************************************************************************/
386 static bool secrets_delete_prev_machine_password(const char *domain)
388 char *oldpass = (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
389 if (oldpass == NULL) {
390 return true;
392 SAFE_FREE(oldpass);
393 return secrets_delete(machine_prev_password_keystr(domain));
396 /************************************************************************
397 Routine to delete the plaintext machine account password and old
398 password if any
399 ************************************************************************/
401 bool secrets_delete_machine_password(const char *domain)
403 if (!secrets_delete_prev_machine_password(domain)) {
404 return false;
406 return secrets_delete(machine_password_keystr(domain));
409 /************************************************************************
410 Routine to delete the plaintext machine account password, old password,
411 sec channel type and last change time from secrets database
412 ************************************************************************/
414 bool secrets_delete_machine_password_ex(const char *domain)
416 if (!secrets_delete_prev_machine_password(domain)) {
417 return false;
419 if (!secrets_delete(machine_password_keystr(domain))) {
420 return false;
422 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
423 return false;
425 return secrets_delete(machine_last_change_time_keystr(domain));
428 /************************************************************************
429 Routine to delete the domain sid
430 ************************************************************************/
432 bool secrets_delete_domain_sid(const char *domain)
434 return secrets_delete(domain_sid_keystr(domain));
437 /************************************************************************
438 Routine to store the previous machine password (by storing the current password
439 as the old)
440 ************************************************************************/
442 static bool secrets_store_prev_machine_password(const char *domain)
444 char *oldpass;
445 bool ret;
447 oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
448 if (oldpass == NULL) {
449 return true;
451 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
452 SAFE_FREE(oldpass);
453 return ret;
456 /************************************************************************
457 Routine to set the plaintext machine account password for a realm
458 the password is assumed to be a null terminated ascii string.
459 Before storing
460 ************************************************************************/
462 bool secrets_store_machine_password(const char *pass, const char *domain,
463 enum netr_SchannelType sec_channel)
465 bool ret;
466 uint32 last_change_time;
467 uint32 sec_channel_type;
469 if (!secrets_store_prev_machine_password(domain)) {
470 return false;
473 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
474 if (!ret)
475 return ret;
477 SIVAL(&last_change_time, 0, time(NULL));
478 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
480 SIVAL(&sec_channel_type, 0, sec_channel);
481 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
483 return ret;
487 /************************************************************************
488 Routine to fetch the previous plaintext machine account password for a realm
489 the password is assumed to be a null terminated ascii string.
490 ************************************************************************/
492 char *secrets_fetch_prev_machine_password(const char *domain)
494 return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
497 /************************************************************************
498 Routine to fetch the plaintext machine account password for a realm
499 the password is assumed to be a null terminated ascii string.
500 ************************************************************************/
502 char *secrets_fetch_machine_password(const char *domain,
503 time_t *pass_last_set_time,
504 enum netr_SchannelType *channel)
506 char *ret;
507 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
509 if (pass_last_set_time) {
510 size_t size;
511 uint32 *last_set_time;
512 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
513 if (last_set_time) {
514 *pass_last_set_time = IVAL(last_set_time,0);
515 SAFE_FREE(last_set_time);
516 } else {
517 *pass_last_set_time = 0;
521 if (channel) {
522 size_t size;
523 uint32 *channel_type;
524 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
525 if (channel_type) {
526 *channel = IVAL(channel_type,0);
527 SAFE_FREE(channel_type);
528 } else {
529 *channel = get_default_sec_channel();
533 return ret;