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