s3: Lift the server_messaging_context from notify_job_status
[Samba/gbeck.git] / source3 / passdb / machine_account_secrets.c
blobc5a8faf694dd137ea62e4e6a5dfb74df1443eeda
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"
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_PASSDB
32 /* Urrrg. global.... */
33 bool global_machine_password_needs_changing;
35 /**
36 * Form a key for fetching the domain sid
38 * @param domain domain name
40 * @return keystring
41 **/
42 static const char *domain_sid_keystr(const char *domain)
44 char *keystr;
46 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
47 SECRETS_DOMAIN_SID, domain);
48 SMB_ASSERT(keystr != NULL);
49 return keystr;
52 bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid)
54 bool ret;
56 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
58 /* Force a re-query, in case we modified our domain */
59 if (ret)
60 reset_global_sam_sid();
61 return ret;
64 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid)
66 struct dom_sid *dyn_sid;
67 size_t size = 0;
69 dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size);
71 if (dyn_sid == NULL)
72 return False;
74 if (size != sizeof(struct dom_sid)) {
75 SAFE_FREE(dyn_sid);
76 return False;
79 *sid = *dyn_sid;
80 SAFE_FREE(dyn_sid);
81 return True;
84 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
86 fstring key;
88 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
89 strupper_m(key);
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;
96 fstring key;
97 size_t size = 0;
98 struct GUID new_guid;
100 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
101 strupper_m(key);
102 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
104 if (!dyn_guid) {
105 if (lp_server_role() == ROLE_DOMAIN_PDC) {
106 new_guid = GUID_random();
107 if (!secrets_store_domain_guid(domain, &new_guid))
108 return False;
109 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
111 if (dyn_guid == NULL) {
112 return False;
116 if (size != sizeof(struct GUID)) {
117 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
118 SAFE_FREE(dyn_guid);
119 return False;
122 *guid = *dyn_guid;
123 SAFE_FREE(dyn_guid);
124 return True;
128 * Form a key for fetching the machine trust account sec channel type
130 * @param domain domain name
132 * @return keystring
134 static const char *machine_sec_channel_type_keystr(const char *domain)
136 char *keystr;
138 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
139 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
140 domain);
141 SMB_ASSERT(keystr != NULL);
142 return keystr;
146 * Form a key for fetching the machine trust account last change time
148 * @param domain domain name
150 * @return keystring
152 static const char *machine_last_change_time_keystr(const char *domain)
154 char *keystr;
156 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
157 SECRETS_MACHINE_LAST_CHANGE_TIME,
158 domain);
159 SMB_ASSERT(keystr != NULL);
160 return keystr;
165 * Form a key for fetching the machine previous trust account password
167 * @param domain domain name
169 * @return keystring
171 static const char *machine_prev_password_keystr(const char *domain)
173 char *keystr;
175 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
176 SECRETS_MACHINE_PASSWORD_PREV, domain);
177 SMB_ASSERT(keystr != NULL);
178 return keystr;
182 * Form a key for fetching the machine trust account password
184 * @param domain domain name
186 * @return keystring
188 static const char *machine_password_keystr(const char *domain)
190 char *keystr;
192 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
193 SECRETS_MACHINE_PASSWORD, domain);
194 SMB_ASSERT(keystr != NULL);
195 return keystr;
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)
207 char *keystr;
209 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
210 SECRETS_MACHINE_ACCT_PASS, domain);
211 SMB_ASSERT(keystr != NULL);
212 return keystr;
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()) {
223 return NULL;
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) {
240 return SEC_CHAN_BDC;
241 } else {
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,
254 uint8 ret_pwd[16],
255 time_t *pass_last_set_time,
256 enum netr_SchannelType *channel)
258 struct machine_acct_pass *pass;
259 size_t size = 0;
261 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
262 trust_keystr(domain), &size))) {
263 DEBUG(5, ("secrets_fetch failed!\n"));
264 return False;
267 if (size != sizeof(*pass)) {
268 DEBUG(0, ("secrets were of incorrect size!\n"));
269 SAFE_FREE(pass);
270 return False;
273 if (pass_last_set_time) {
274 *pass_last_set_time = pass->mod_time;
276 memcpy(ret_pwd, pass->hash, 16);
278 if (channel) {
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;
290 SAFE_FREE(pass);
291 return 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)
304 char *plaintext;
306 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
307 channel);
308 if (plaintext) {
309 DEBUG(4,("Using cleartext machine password\n"));
310 E_md4hash(plaintext, ret_pwd);
311 SAFE_FREE(plaintext);
312 return True;
315 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
316 pass_last_set_time,
317 channel);
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) {
328 return true;
330 SAFE_FREE(oldpass);
331 return secrets_delete(machine_prev_password_keystr(domain));
334 /************************************************************************
335 Routine to delete the plaintext machine account password and old
336 password if any
337 ************************************************************************/
339 bool secrets_delete_machine_password(const char *domain)
341 if (!secrets_delete_prev_machine_password(domain)) {
342 return false;
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)) {
355 return false;
357 if (!secrets_delete(machine_password_keystr(domain))) {
358 return false;
360 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
361 return false;
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
377 as the old)
378 ************************************************************************/
380 static bool secrets_store_prev_machine_password(const char *domain)
382 char *oldpass;
383 bool ret;
385 oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
386 if (oldpass == NULL) {
387 return true;
389 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
390 SAFE_FREE(oldpass);
391 return ret;
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.
397 Before storing
398 ************************************************************************/
400 bool secrets_store_machine_password(const char *pass, const char *domain,
401 enum netr_SchannelType sec_channel)
403 bool ret;
404 uint32 last_change_time;
405 uint32 sec_channel_type;
407 if (!secrets_store_prev_machine_password(domain)) {
408 return false;
411 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
412 if (!ret)
413 return ret;
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));
421 return ret;
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)
444 char *ret;
445 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
447 if (pass_last_set_time) {
448 size_t size;
449 uint32 *last_set_time;
450 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
451 if (last_set_time) {
452 *pass_last_set_time = IVAL(last_set_time,0);
453 SAFE_FREE(last_set_time);
454 } else {
455 *pass_last_set_time = 0;
459 if (channel) {
460 size_t size;
461 uint32 *channel_type;
462 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
463 if (channel_type) {
464 *channel = IVAL(channel_type,0);
465 SAFE_FREE(channel_type);
466 } else {
467 *channel = get_default_sec_channel();
471 return ret;