s3-libndr: add ../librpc/ndr/libndr.h include in some places.
[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 "passdb.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "secrets.h"
29 #include "dbwrap.h"
30 #include "../librpc/ndr/libndr.h"
31
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_PASSDB
34
35 /* Urrrg. global.... */
36 bool global_machine_password_needs_changing;
37
38 /**
39  * Form a key for fetching the domain sid
40  *
41  * @param domain domain name
42  *
43  * @return keystring
44  **/
45 static const char *domain_sid_keystr(const char *domain)
46 {
47         char *keystr;
48
49         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
50                                             SECRETS_DOMAIN_SID, domain);
51         SMB_ASSERT(keystr != NULL);
52         return keystr;
53 }
54
55 bool secrets_store_domain_sid(const char *domain, const struct dom_sid  *sid)
56 {
57         bool ret;
58
59         ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
60
61         /* Force a re-query, in case we modified our domain */
62         if (ret)
63                 reset_global_sam_sid();
64         return ret;
65 }
66
67 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid  *sid)
68 {
69         struct dom_sid  *dyn_sid;
70         size_t size = 0;
71
72         dyn_sid = (struct dom_sid  *)secrets_fetch(domain_sid_keystr(domain), &size);
73
74         if (dyn_sid == NULL)
75                 return False;
76
77         if (size != sizeof(struct dom_sid)) {
78                 SAFE_FREE(dyn_sid);
79                 return False;
80         }
81
82         *sid = *dyn_sid;
83         SAFE_FREE(dyn_sid);
84         return True;
85 }
86
87 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
88 {
89         fstring key;
90
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));
94 }
95
96 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
97 {
98         struct GUID *dyn_guid;
99         fstring key;
100         size_t size = 0;
101         struct GUID new_guid;
102
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);
106
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);
113                 }
114                 if (dyn_guid == NULL) {
115                         return False;
116                 }
117         }
118
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;
123         }
124
125         *guid = *dyn_guid;
126         SAFE_FREE(dyn_guid);
127         return True;
128 }
129
130 /**
131  * Form a key for fetching the machine trust account sec channel type
132  *
133  * @param domain domain name
134  *
135  * @return keystring
136  **/
137 static const char *machine_sec_channel_type_keystr(const char *domain)
138 {
139         char *keystr;
140
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;
146 }
147
148 /**
149  * Form a key for fetching the machine trust account last change time
150  *
151  * @param domain domain name
152  *
153  * @return keystring
154  **/
155 static const char *machine_last_change_time_keystr(const char *domain)
156 {
157         char *keystr;
158
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;
164 }
165
166
167 /**
168  * Form a key for fetching the machine previous trust account password
169  *
170  * @param domain domain name
171  *
172  * @return keystring
173  **/
174 static const char *machine_prev_password_keystr(const char *domain)
175 {
176         char *keystr;
177
178         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
179                                             SECRETS_MACHINE_PASSWORD_PREV, domain);
180         SMB_ASSERT(keystr != NULL);
181         return keystr;
182 }
183
184 /**
185  * Form a key for fetching the machine trust account password
186  *
187  * @param domain domain name
188  *
189  * @return keystring
190  **/
191 static const char *machine_password_keystr(const char *domain)
192 {
193         char *keystr;
194
195         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
196                                             SECRETS_MACHINE_PASSWORD, domain);
197         SMB_ASSERT(keystr != NULL);
198         return keystr;
199 }
200
201 /**
202  * Form a key for fetching the machine trust account password
203  *
204  * @param domain domain name
205  *
206  * @return stored password's key
207  **/
208 static const char *trust_keystr(const char *domain)
209 {
210         char *keystr;
211
212         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
213                                             SECRETS_MACHINE_ACCT_PASS, domain);
214         SMB_ASSERT(keystr != NULL);
215         return keystr;
216 }
217
218 /************************************************************************
219  Lock the trust password entry.
220 ************************************************************************/
221
222 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
223 {
224         struct db_context *db_ctx;
225         if (!secrets_init()) {
226                 return NULL;
227         }
228
229         db_ctx = secrets_db_ctx();
230
231         return db_ctx->fetch_locked(
232                 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
233 }
234
235 /************************************************************************
236  Routine to get the default secure channel type for trust accounts
237 ************************************************************************/
238
239 enum netr_SchannelType get_default_sec_channel(void)
240 {
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;
246         }
247 }
248
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 ************************************************************************/
255
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)
260 {
261         struct machine_acct_pass *pass;
262         size_t size = 0;
263
264         if (!(pass = (struct machine_acct_pass *)secrets_fetch(
265                       trust_keystr(domain), &size))) {
266                 DEBUG(5, ("secrets_fetch failed!\n"));
267                 return False;
268         }
269
270         if (size != sizeof(*pass)) {
271                 DEBUG(0, ("secrets were of incorrect size!\n"));
272                 SAFE_FREE(pass);
273                 return False;
274         }
275
276         if (pass_last_set_time) {
277                 *pass_last_set_time = pass->mod_time;
278         }
279         memcpy(ret_pwd, pass->hash, 16);
280
281         if (channel) {
282                 *channel = get_default_sec_channel();
283         }
284
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;
290                 }
291         }
292
293         SAFE_FREE(pass);
294         return True;
295 }
296
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 ************************************************************************/
302
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)
306 {
307         char *plaintext;
308
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;
316         }
317
318         return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
319                                                            pass_last_set_time,
320                                                            channel);
321 }
322
323 /************************************************************************
324  Routine to delete the old plaintext machine account password if any
325 ************************************************************************/
326
327 static bool secrets_delete_prev_machine_password(const char *domain)
328 {
329         char *oldpass = (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
330         if (oldpass == NULL) {
331                 return true;
332         }
333         SAFE_FREE(oldpass);
334         return secrets_delete(machine_prev_password_keystr(domain));
335 }
336
337 /************************************************************************
338  Routine to delete the plaintext machine account password and old
339  password if any
340 ************************************************************************/
341
342 bool secrets_delete_machine_password(const char *domain)
343 {
344         if (!secrets_delete_prev_machine_password(domain)) {
345                 return false;
346         }
347         return secrets_delete(machine_password_keystr(domain));
348 }
349
350 /************************************************************************
351  Routine to delete the plaintext machine account password, old password,
352  sec channel type and last change time from secrets database
353 ************************************************************************/
354
355 bool secrets_delete_machine_password_ex(const char *domain)
356 {
357         if (!secrets_delete_prev_machine_password(domain)) {
358                 return false;
359         }
360         if (!secrets_delete(machine_password_keystr(domain))) {
361                 return false;
362         }
363         if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
364                 return false;
365         }
366         return secrets_delete(machine_last_change_time_keystr(domain));
367 }
368
369 /************************************************************************
370  Routine to delete the domain sid
371 ************************************************************************/
372
373 bool secrets_delete_domain_sid(const char *domain)
374 {
375         return secrets_delete(domain_sid_keystr(domain));
376 }
377
378 /************************************************************************
379  Routine to store the previous machine password (by storing the current password
380  as the old)
381 ************************************************************************/
382
383 static bool secrets_store_prev_machine_password(const char *domain)
384 {
385         char *oldpass;
386         bool ret;
387
388         oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
389         if (oldpass == NULL) {
390                 return true;
391         }
392         ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
393         SAFE_FREE(oldpass);
394         return ret;
395 }
396
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 ************************************************************************/
402
403 bool secrets_store_machine_password(const char *pass, const char *domain,
404                                     enum netr_SchannelType sec_channel)
405 {
406         bool ret;
407         uint32 last_change_time;
408         uint32 sec_channel_type;
409
410         if (!secrets_store_prev_machine_password(domain)) {
411                 return false;
412         }
413
414         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
415         if (!ret)
416                 return ret;
417
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));
420
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));
423
424         return ret;
425 }
426
427
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 ************************************************************************/
432
433 char *secrets_fetch_prev_machine_password(const char *domain)
434 {
435         return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
436 }
437
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 ************************************************************************/
442
443 char *secrets_fetch_machine_password(const char *domain,
444                                      time_t *pass_last_set_time,
445                                      enum netr_SchannelType *channel)
446 {
447         char *ret;
448         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
449
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;
459                 }
460         }
461
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();
471                 }
472         }
473
474         return ret;
475 }