db99d010ec4ddc38606249f9d1f45a02cc0c438a
[kai/samba.git] / source3 / passdb / machine_account_secrets.c
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
7
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.
12
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.
17
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/>.
20 */
21
22 /* the Samba secrets database stores any generated, private information
23    such as the local SID and machine trust password */
24
25 #include "includes.h"
26 #include "../libcli/auth/libcli_auth.h"
27
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_PASSDB
30
31 /* Urrrg. global.... */
32 bool global_machine_password_needs_changing;
33
34 /**
35  * Form a key for fetching the domain sid
36  *
37  * @param domain domain name
38  *
39  * @return keystring
40  **/
41 static const char *domain_sid_keystr(const char *domain)
42 {
43         char *keystr;
44
45         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
46                                             SECRETS_DOMAIN_SID, domain);
47         SMB_ASSERT(keystr != NULL);
48         return keystr;
49 }
50
51 bool secrets_store_domain_sid(const char *domain, const struct dom_sid  *sid)
52 {
53         bool ret;
54
55         ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
56
57         /* Force a re-query, in case we modified our domain */
58         if (ret)
59                 reset_global_sam_sid();
60         return ret;
61 }
62
63 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid  *sid)
64 {
65         struct dom_sid  *dyn_sid;
66         size_t size = 0;
67
68         dyn_sid = (struct dom_sid  *)secrets_fetch(domain_sid_keystr(domain), &size);
69
70         if (dyn_sid == NULL)
71                 return False;
72
73         if (size != sizeof(struct dom_sid)) {
74                 SAFE_FREE(dyn_sid);
75                 return False;
76         }
77
78         *sid = *dyn_sid;
79         SAFE_FREE(dyn_sid);
80         return True;
81 }
82
83 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
84 {
85         fstring key;
86
87         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
88         strupper_m(key);
89         return secrets_store(key, guid, sizeof(struct GUID));
90 }
91
92 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
93 {
94         struct GUID *dyn_guid;
95         fstring key;
96         size_t size = 0;
97         struct GUID new_guid;
98
99         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
100         strupper_m(key);
101         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
102
103         if (!dyn_guid) {
104                 if (lp_server_role() == ROLE_DOMAIN_PDC) {
105                         new_guid = GUID_random();
106                         if (!secrets_store_domain_guid(domain, &new_guid))
107                                 return False;
108                         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
109                 }
110                 if (dyn_guid == NULL) {
111                         return False;
112                 }
113         }
114
115         if (size != sizeof(struct GUID)) {
116                 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
117                 SAFE_FREE(dyn_guid);
118                 return False;
119         }
120
121         *guid = *dyn_guid;
122         SAFE_FREE(dyn_guid);
123         return True;
124 }
125
126 /**
127  * Form a key for fetching the machine trust account sec channel type
128  *
129  * @param domain domain name
130  *
131  * @return keystring
132  **/
133 static const char *machine_sec_channel_type_keystr(const char *domain)
134 {
135         char *keystr;
136
137         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
138                                             SECRETS_MACHINE_SEC_CHANNEL_TYPE,
139                                             domain);
140         SMB_ASSERT(keystr != NULL);
141         return keystr;
142 }
143
144 /**
145  * Form a key for fetching the machine trust account last change time
146  *
147  * @param domain domain name
148  *
149  * @return keystring
150  **/
151 static const char *machine_last_change_time_keystr(const char *domain)
152 {
153         char *keystr;
154
155         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
156                                             SECRETS_MACHINE_LAST_CHANGE_TIME,
157                                             domain);
158         SMB_ASSERT(keystr != NULL);
159         return keystr;
160 }
161
162
163 /**
164  * Form a key for fetching the machine previous trust account password
165  *
166  * @param domain domain name
167  *
168  * @return keystring
169  **/
170 static const char *machine_prev_password_keystr(const char *domain)
171 {
172         char *keystr;
173
174         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
175                                             SECRETS_MACHINE_PASSWORD_PREV, domain);
176         SMB_ASSERT(keystr != NULL);
177         return keystr;
178 }
179
180 /**
181  * Form a key for fetching the machine trust account password
182  *
183  * @param domain domain name
184  *
185  * @return keystring
186  **/
187 static const char *machine_password_keystr(const char *domain)
188 {
189         char *keystr;
190
191         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
192                                             SECRETS_MACHINE_PASSWORD, domain);
193         SMB_ASSERT(keystr != NULL);
194         return keystr;
195 }
196
197 /**
198  * Form a key for fetching the machine trust account password
199  *
200  * @param domain domain name
201  *
202  * @return stored password's key
203  **/
204 static const char *trust_keystr(const char *domain)
205 {
206         char *keystr;
207
208         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
209                                             SECRETS_MACHINE_ACCT_PASS, domain);
210         SMB_ASSERT(keystr != NULL);
211         return keystr;
212 }
213
214 /************************************************************************
215  Lock the trust password entry.
216 ************************************************************************/
217
218 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
219 {
220         struct db_context *db_ctx;
221         if (!secrets_init()) {
222                 return NULL;
223         }
224
225         db_ctx = secrets_db_ctx();
226
227         return db_ctx->fetch_locked(
228                 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
229 }
230
231 /************************************************************************
232  Routine to get the default secure channel type for trust accounts
233 ************************************************************************/
234
235 enum netr_SchannelType get_default_sec_channel(void)
236 {
237         if (lp_server_role() == ROLE_DOMAIN_BDC ||
238             lp_server_role() == ROLE_DOMAIN_PDC) {
239                 return SEC_CHAN_BDC;
240         } else {
241                 return SEC_CHAN_WKSTA;
242         }
243 }
244
245 /************************************************************************
246  Routine to get the trust account password for a domain.
247  This only tries to get the legacy hashed version of the password.
248  The user of this function must have locked the trust password file using
249  the above secrets_lock_trust_account_password().
250 ************************************************************************/
251
252 bool secrets_fetch_trust_account_password_legacy(const char *domain,
253                                                  uint8 ret_pwd[16],
254                                                  time_t *pass_last_set_time,
255                                                  enum netr_SchannelType *channel)
256 {
257         struct machine_acct_pass *pass;
258         size_t size = 0;
259
260         if (!(pass = (struct machine_acct_pass *)secrets_fetch(
261                       trust_keystr(domain), &size))) {
262                 DEBUG(5, ("secrets_fetch failed!\n"));
263                 return False;
264         }
265
266         if (size != sizeof(*pass)) {
267                 DEBUG(0, ("secrets were of incorrect size!\n"));
268                 SAFE_FREE(pass);
269                 return False;
270         }
271
272         if (pass_last_set_time) {
273                 *pass_last_set_time = pass->mod_time;
274         }
275         memcpy(ret_pwd, pass->hash, 16);
276
277         if (channel) {
278                 *channel = get_default_sec_channel();
279         }
280
281         /* Test if machine password has expired and needs to be changed */
282         if (lp_machine_password_timeout()) {
283                 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
284                                 (time_t)lp_machine_password_timeout())) {
285                         global_machine_password_needs_changing = True;
286                 }
287         }
288
289         SAFE_FREE(pass);
290         return True;
291 }
292
293 /************************************************************************
294  Routine to get the trust account password for a domain.
295  The user of this function must have locked the trust password file using
296  the above secrets_lock_trust_account_password().
297 ************************************************************************/
298
299 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
300                                           time_t *pass_last_set_time,
301                                           enum netr_SchannelType *channel)
302 {
303         char *plaintext;
304
305         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
306                                                    channel);
307         if (plaintext) {
308                 DEBUG(4,("Using cleartext machine password\n"));
309                 E_md4hash(plaintext, ret_pwd);
310                 SAFE_FREE(plaintext);
311                 return True;
312         }
313
314         return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
315                                                            pass_last_set_time,
316                                                            channel);
317 }
318
319 /************************************************************************
320  Routine to delete the old plaintext machine account password if any
321 ************************************************************************/
322
323 static bool secrets_delete_prev_machine_password(const char *domain)
324 {
325         char *oldpass = (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
326         if (oldpass == NULL) {
327                 return true;
328         }
329         SAFE_FREE(oldpass);
330         return secrets_delete(machine_prev_password_keystr(domain));
331 }
332
333 /************************************************************************
334  Routine to delete the plaintext machine account password and old
335  password if any
336 ************************************************************************/
337
338 bool secrets_delete_machine_password(const char *domain)
339 {
340         if (!secrets_delete_prev_machine_password(domain)) {
341                 return false;
342         }
343         return secrets_delete(machine_password_keystr(domain));
344 }
345
346 /************************************************************************
347  Routine to delete the plaintext machine account password, old password,
348  sec channel type and last change time from secrets database
349 ************************************************************************/
350
351 bool secrets_delete_machine_password_ex(const char *domain)
352 {
353         if (!secrets_delete_prev_machine_password(domain)) {
354                 return false;
355         }
356         if (!secrets_delete(machine_password_keystr(domain))) {
357                 return false;
358         }
359         if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
360                 return false;
361         }
362         return secrets_delete(machine_last_change_time_keystr(domain));
363 }
364
365 /************************************************************************
366  Routine to delete the domain sid
367 ************************************************************************/
368
369 bool secrets_delete_domain_sid(const char *domain)
370 {
371         return secrets_delete(domain_sid_keystr(domain));
372 }
373
374 /************************************************************************
375  Routine to store the previous machine password (by storing the current password
376  as the old)
377 ************************************************************************/
378
379 static bool secrets_store_prev_machine_password(const char *domain)
380 {
381         char *oldpass;
382         bool ret;
383
384         oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
385         if (oldpass == NULL) {
386                 return true;
387         }
388         ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
389         SAFE_FREE(oldpass);
390         return ret;
391 }
392
393 /************************************************************************
394  Routine to set the plaintext machine account password for a realm
395  the password is assumed to be a null terminated ascii string.
396  Before storing
397 ************************************************************************/
398
399 bool secrets_store_machine_password(const char *pass, const char *domain,
400                                     enum netr_SchannelType sec_channel)
401 {
402         bool ret;
403         uint32 last_change_time;
404         uint32 sec_channel_type;
405
406         if (!secrets_store_prev_machine_password(domain)) {
407                 return false;
408         }
409
410         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
411         if (!ret)
412                 return ret;
413
414         SIVAL(&last_change_time, 0, time(NULL));
415         ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
416
417         SIVAL(&sec_channel_type, 0, sec_channel);
418         ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
419
420         return ret;
421 }
422
423
424 /************************************************************************
425  Routine to fetch the previous plaintext machine account password for a realm
426  the password is assumed to be a null terminated ascii string.
427 ************************************************************************/
428
429 char *secrets_fetch_prev_machine_password(const char *domain)
430 {
431         return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
432 }
433
434 /************************************************************************
435  Routine to fetch the plaintext machine account password for a realm
436  the password is assumed to be a null terminated ascii string.
437 ************************************************************************/
438
439 char *secrets_fetch_machine_password(const char *domain,
440                                      time_t *pass_last_set_time,
441                                      enum netr_SchannelType *channel)
442 {
443         char *ret;
444         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
445
446         if (pass_last_set_time) {
447                 size_t size;
448                 uint32 *last_set_time;
449                 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
450                 if (last_set_time) {
451                         *pass_last_set_time = IVAL(last_set_time,0);
452                         SAFE_FREE(last_set_time);
453                 } else {
454                         *pass_last_set_time = 0;
455                 }
456         }
457
458         if (channel) {
459                 size_t size;
460                 uint32 *channel_type;
461                 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
462                 if (channel_type) {
463                         *channel = IVAL(channel_type,0);
464                         SAFE_FREE(channel_type);
465                 } else {
466                         *channel = get_default_sec_channel();
467                 }
468         }
469
470         return ret;
471 }