s3-libndr: add ../librpc/ndr/libndr.h include in some places.
[Samba.git] / source3 / passdb / machine_account_secrets.c
bloba51a99c9a2f0731587553ef717650fe005476cc6
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"
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_PASSDB
35 /* Urrrg. global.... */
36 bool global_machine_password_needs_changing;
38 /**
39 * Form a key for fetching the domain sid
41 * @param domain domain name
43 * @return keystring
44 **/
45 static const char *domain_sid_keystr(const char *domain)
47 char *keystr;
49 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
50 SECRETS_DOMAIN_SID, domain);
51 SMB_ASSERT(keystr != NULL);
52 return keystr;
55 bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
57 bool ret;
59 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
61 /* Force a re-query, in case we modified our domain */
62 if (ret)
63 reset_global_sam_sid();
64 return ret;
67 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
69 struct dom_sid *dyn_sid;
70 size_t size = 0;
72 dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
74 if (dyn_sid == NULL)
75 return False;
77 if (size != sizeof(struct dom_sid)) {
78 SAFE_FREE(dyn_sid);
79 return False;
82 *sid = *dyn_sid;
83 SAFE_FREE(dyn_sid);
84 return True;
87 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
89 fstring key;
91 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
92 strupper_m(key);
93 return secrets_store(key, guid, sizeof(struct GUID));
96 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
98 struct GUID *dyn_guid;
99 fstring key;
100 size_t size = 0;
101 struct GUID new_guid;
103 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
104 strupper_m(key);
105 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
107 if (!dyn_guid) {
108 if (lp_server_role() == ROLE_DOMAIN_PDC) {
109 new_guid = GUID_random();
110 if (!secrets_store_domain_guid(domain, &new_guid))
111 return False;
112 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
114 if (dyn_guid == NULL) {
115 return False;
119 if (size != sizeof(struct GUID)) {
120 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
121 SAFE_FREE(dyn_guid);
122 return False;
125 *guid = *dyn_guid;
126 SAFE_FREE(dyn_guid);
127 return True;
131 * Form a key for fetching the machine trust account sec channel type
133 * @param domain domain name
135 * @return keystring
137 static const char *machine_sec_channel_type_keystr(const char *domain)
139 char *keystr;
141 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
142 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
143 domain);
144 SMB_ASSERT(keystr != NULL);
145 return keystr;
149 * Form a key for fetching the machine trust account last change time
151 * @param domain domain name
153 * @return keystring
155 static const char *machine_last_change_time_keystr(const char *domain)
157 char *keystr;
159 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
160 SECRETS_MACHINE_LAST_CHANGE_TIME,
161 domain);
162 SMB_ASSERT(keystr != NULL);
163 return keystr;
168 * Form a key for fetching the machine previous trust account password
170 * @param domain domain name
172 * @return keystring
174 static const char *machine_prev_password_keystr(const char *domain)
176 char *keystr;
178 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
179 SECRETS_MACHINE_PASSWORD_PREV, domain);
180 SMB_ASSERT(keystr != NULL);
181 return keystr;
185 * Form a key for fetching the machine trust account password
187 * @param domain domain name
189 * @return keystring
191 static const char *machine_password_keystr(const char *domain)
193 char *keystr;
195 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
196 SECRETS_MACHINE_PASSWORD, domain);
197 SMB_ASSERT(keystr != NULL);
198 return keystr;
202 * Form a key for fetching the machine trust account password
204 * @param domain domain name
206 * @return stored password's key
208 static const char *trust_keystr(const char *domain)
210 char *keystr;
212 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
213 SECRETS_MACHINE_ACCT_PASS, domain);
214 SMB_ASSERT(keystr != NULL);
215 return keystr;
218 /************************************************************************
219 Lock the trust password entry.
220 ************************************************************************/
222 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
224 struct db_context *db_ctx;
225 if (!secrets_init()) {
226 return NULL;
229 db_ctx = secrets_db_ctx();
231 return db_ctx->fetch_locked(
232 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
235 /************************************************************************
236 Routine to get the default secure channel type for trust accounts
237 ************************************************************************/
239 enum netr_SchannelType get_default_sec_channel(void)
241 if (lp_server_role() == ROLE_DOMAIN_BDC ||
242 lp_server_role() == ROLE_DOMAIN_PDC) {
243 return SEC_CHAN_BDC;
244 } else {
245 return SEC_CHAN_WKSTA;
249 /************************************************************************
250 Routine to get the trust account password for a domain.
251 This only tries to get the legacy hashed version of the password.
252 The user of this function must have locked the trust password file using
253 the above secrets_lock_trust_account_password().
254 ************************************************************************/
256 bool secrets_fetch_trust_account_password_legacy(const char *domain,
257 uint8 ret_pwd[16],
258 time_t *pass_last_set_time,
259 enum netr_SchannelType *channel)
261 struct machine_acct_pass *pass;
262 size_t size = 0;
264 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
265 trust_keystr(domain), &size))) {
266 DEBUG(5, ("secrets_fetch failed!\n"));
267 return False;
270 if (size != sizeof(*pass)) {
271 DEBUG(0, ("secrets were of incorrect size!\n"));
272 SAFE_FREE(pass);
273 return False;
276 if (pass_last_set_time) {
277 *pass_last_set_time = pass->mod_time;
279 memcpy(ret_pwd, pass->hash, 16);
281 if (channel) {
282 *channel = get_default_sec_channel();
285 /* Test if machine password has expired and needs to be changed */
286 if (lp_machine_password_timeout()) {
287 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
288 (time_t)lp_machine_password_timeout())) {
289 global_machine_password_needs_changing = True;
293 SAFE_FREE(pass);
294 return True;
297 /************************************************************************
298 Routine to get the trust account password for a domain.
299 The user of this function must have locked the trust password file using
300 the above secrets_lock_trust_account_password().
301 ************************************************************************/
303 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
304 time_t *pass_last_set_time,
305 enum netr_SchannelType *channel)
307 char *plaintext;
309 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
310 channel);
311 if (plaintext) {
312 DEBUG(4,("Using cleartext machine password\n"));
313 E_md4hash(plaintext, ret_pwd);
314 SAFE_FREE(plaintext);
315 return True;
318 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
319 pass_last_set_time,
320 channel);
323 /************************************************************************
324 Routine to delete the old plaintext machine account password if any
325 ************************************************************************/
327 static bool secrets_delete_prev_machine_password(const char *domain)
329 char *oldpass = (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
330 if (oldpass == NULL) {
331 return true;
333 SAFE_FREE(oldpass);
334 return secrets_delete(machine_prev_password_keystr(domain));
337 /************************************************************************
338 Routine to delete the plaintext machine account password and old
339 password if any
340 ************************************************************************/
342 bool secrets_delete_machine_password(const char *domain)
344 if (!secrets_delete_prev_machine_password(domain)) {
345 return false;
347 return secrets_delete(machine_password_keystr(domain));
350 /************************************************************************
351 Routine to delete the plaintext machine account password, old password,
352 sec channel type and last change time from secrets database
353 ************************************************************************/
355 bool secrets_delete_machine_password_ex(const char *domain)
357 if (!secrets_delete_prev_machine_password(domain)) {
358 return false;
360 if (!secrets_delete(machine_password_keystr(domain))) {
361 return false;
363 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
364 return false;
366 return secrets_delete(machine_last_change_time_keystr(domain));
369 /************************************************************************
370 Routine to delete the domain sid
371 ************************************************************************/
373 bool secrets_delete_domain_sid(const char *domain)
375 return secrets_delete(domain_sid_keystr(domain));
378 /************************************************************************
379 Routine to store the previous machine password (by storing the current password
380 as the old)
381 ************************************************************************/
383 static bool secrets_store_prev_machine_password(const char *domain)
385 char *oldpass;
386 bool ret;
388 oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
389 if (oldpass == NULL) {
390 return true;
392 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
393 SAFE_FREE(oldpass);
394 return ret;
397 /************************************************************************
398 Routine to set the plaintext machine account password for a realm
399 the password is assumed to be a null terminated ascii string.
400 Before storing
401 ************************************************************************/
403 bool secrets_store_machine_password(const char *pass, const char *domain,
404 enum netr_SchannelType sec_channel)
406 bool ret;
407 uint32 last_change_time;
408 uint32 sec_channel_type;
410 if (!secrets_store_prev_machine_password(domain)) {
411 return false;
414 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
415 if (!ret)
416 return ret;
418 SIVAL(&last_change_time, 0, time(NULL));
419 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
421 SIVAL(&sec_channel_type, 0, sec_channel);
422 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
424 return ret;
428 /************************************************************************
429 Routine to fetch the previous plaintext machine account password for a realm
430 the password is assumed to be a null terminated ascii string.
431 ************************************************************************/
433 char *secrets_fetch_prev_machine_password(const char *domain)
435 return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
438 /************************************************************************
439 Routine to fetch the plaintext machine account password for a realm
440 the password is assumed to be a null terminated ascii string.
441 ************************************************************************/
443 char *secrets_fetch_machine_password(const char *domain,
444 time_t *pass_last_set_time,
445 enum netr_SchannelType *channel)
447 char *ret;
448 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
450 if (pass_last_set_time) {
451 size_t size;
452 uint32 *last_set_time;
453 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
454 if (last_set_time) {
455 *pass_last_set_time = IVAL(last_set_time,0);
456 SAFE_FREE(last_set_time);
457 } else {
458 *pass_last_set_time = 0;
462 if (channel) {
463 size_t size;
464 uint32 *channel_type;
465 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
466 if (channel_type) {
467 *channel = IVAL(channel_type,0);
468 SAFE_FREE(channel_type);
469 } else {
470 *channel = get_default_sec_channel();
474 return ret;