s3:secrets: rename secrets_delete() to secrets_delete_entry()
[sfrench/samba-autobuild/.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/dbwrap.h"
30 #include "../librpc/ndr/libndr.h"
31 #include "util_tdb.h"
32 #include "libcli/security/security.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_PASSDB
36
37 static char *des_salt_key(const char *realm);
38
39 /**
40  * Form a key for fetching the domain sid
41  *
42  * @param domain domain name
43  *
44  * @return keystring
45  **/
46 static const char *domain_sid_keystr(const char *domain)
47 {
48         char *keystr;
49
50         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
51                                             SECRETS_DOMAIN_SID, domain);
52         SMB_ASSERT(keystr != NULL);
53         return keystr;
54 }
55
56 static const char *domain_guid_keystr(const char *domain)
57 {
58         char *keystr;
59
60         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
61                                             SECRETS_DOMAIN_GUID, domain);
62         SMB_ASSERT(keystr != NULL);
63         return keystr;
64 }
65
66 static const char *protect_ids_keystr(const char *domain)
67 {
68         char *keystr;
69
70         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
71                                             SECRETS_PROTECT_IDS, domain);
72         SMB_ASSERT(keystr != NULL);
73         return keystr;
74 }
75
76 /* N O T E: never use this outside of passdb modules that store the SID on their own */
77 bool secrets_mark_domain_protected(const char *domain)
78 {
79         bool ret;
80
81         ret = secrets_store(protect_ids_keystr(domain), "TRUE", 5);
82         if (!ret) {
83                 DEBUG(0, ("Failed to protect the Domain IDs\n"));
84         }
85         return ret;
86 }
87
88 bool secrets_clear_domain_protection(const char *domain)
89 {
90         bool ret;
91         void *protection = secrets_fetch(protect_ids_keystr(domain), NULL);
92         
93         if (protection) {
94                 SAFE_FREE(protection);
95                 ret = secrets_delete_entry(protect_ids_keystr(domain));
96                 if (!ret) {
97                         DEBUG(0, ("Failed to remove Domain IDs protection\n"));
98                 }
99                 return ret;
100         }
101         return true;
102 }
103
104 bool secrets_store_domain_sid(const char *domain, const struct dom_sid  *sid)
105 {
106         char *protect_ids;
107         bool ret;
108
109         protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
110         if (protect_ids) {
111                 if (strncmp(protect_ids, "TRUE", 4)) {
112                         DEBUG(0, ("Refusing to store a Domain SID, "
113                                   "it has been marked as protected!\n"));
114                         SAFE_FREE(protect_ids);
115                         return false;
116                 }
117         }
118         SAFE_FREE(protect_ids);
119
120         ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid ));
121
122         /* Force a re-query, in the case where we modified our domain */
123         if (ret) {
124                 if (dom_sid_equal(get_global_sam_sid(), sid) == false) {
125                         reset_global_sam_sid();
126                 }
127         }
128         return ret;
129 }
130
131 bool secrets_fetch_domain_sid(const char *domain, struct dom_sid  *sid)
132 {
133         struct dom_sid  *dyn_sid;
134         size_t size = 0;
135
136         dyn_sid = (struct dom_sid  *)secrets_fetch(domain_sid_keystr(domain), &size);
137
138         if (dyn_sid == NULL)
139                 return False;
140
141         if (size != sizeof(struct dom_sid)) {
142                 SAFE_FREE(dyn_sid);
143                 return False;
144         }
145
146         *sid = *dyn_sid;
147         SAFE_FREE(dyn_sid);
148         return True;
149 }
150
151 bool secrets_store_domain_guid(const char *domain, const struct GUID *guid)
152 {
153         char *protect_ids;
154         const char *key;
155
156         protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
157         if (protect_ids) {
158                 if (strncmp(protect_ids, "TRUE", 4)) {
159                         DEBUG(0, ("Refusing to store a Domain SID, "
160                                   "it has been marked as protected!\n"));
161                         SAFE_FREE(protect_ids);
162                         return false;
163                 }
164         }
165         SAFE_FREE(protect_ids);
166
167         key = domain_guid_keystr(domain);
168         return secrets_store(key, guid, sizeof(struct GUID));
169 }
170
171 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
172 {
173         struct GUID *dyn_guid;
174         const char *key;
175         size_t size = 0;
176         struct GUID new_guid;
177
178         key = domain_guid_keystr(domain);
179         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
180
181         if (!dyn_guid) {
182                 if (lp_server_role() == ROLE_DOMAIN_PDC) {
183                         new_guid = GUID_random();
184                         if (!secrets_store_domain_guid(domain, &new_guid))
185                                 return False;
186                         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
187                 }
188                 if (dyn_guid == NULL) {
189                         return False;
190                 }
191         }
192
193         if (size != sizeof(struct GUID)) {
194                 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
195                 SAFE_FREE(dyn_guid);
196                 return False;
197         }
198
199         *guid = *dyn_guid;
200         SAFE_FREE(dyn_guid);
201         return True;
202 }
203
204 /**
205  * Form a key for fetching the machine trust account sec channel type
206  *
207  * @param domain domain name
208  *
209  * @return keystring
210  **/
211 static const char *machine_sec_channel_type_keystr(const char *domain)
212 {
213         char *keystr;
214
215         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
216                                             SECRETS_MACHINE_SEC_CHANNEL_TYPE,
217                                             domain);
218         SMB_ASSERT(keystr != NULL);
219         return keystr;
220 }
221
222 /**
223  * Form a key for fetching the machine trust account last change time
224  *
225  * @param domain domain name
226  *
227  * @return keystring
228  **/
229 static const char *machine_last_change_time_keystr(const char *domain)
230 {
231         char *keystr;
232
233         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
234                                             SECRETS_MACHINE_LAST_CHANGE_TIME,
235                                             domain);
236         SMB_ASSERT(keystr != NULL);
237         return keystr;
238 }
239
240
241 /**
242  * Form a key for fetching the machine previous trust account password
243  *
244  * @param domain domain name
245  *
246  * @return keystring
247  **/
248 static const char *machine_prev_password_keystr(const char *domain)
249 {
250         char *keystr;
251
252         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
253                                             SECRETS_MACHINE_PASSWORD_PREV, domain);
254         SMB_ASSERT(keystr != NULL);
255         return keystr;
256 }
257
258 /**
259  * Form a key for fetching the machine trust account password
260  *
261  * @param domain domain name
262  *
263  * @return keystring
264  **/
265 static const char *machine_password_keystr(const char *domain)
266 {
267         char *keystr;
268
269         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
270                                             SECRETS_MACHINE_PASSWORD, domain);
271         SMB_ASSERT(keystr != NULL);
272         return keystr;
273 }
274
275 /**
276  * Form a key for fetching the machine trust account password
277  *
278  * @param domain domain name
279  *
280  * @return stored password's key
281  **/
282 static const char *trust_keystr(const char *domain)
283 {
284         char *keystr;
285
286         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
287                                             SECRETS_MACHINE_ACCT_PASS, domain);
288         SMB_ASSERT(keystr != NULL);
289         return keystr;
290 }
291
292 /************************************************************************
293  Routine to get the default secure channel type for trust accounts
294 ************************************************************************/
295
296 enum netr_SchannelType get_default_sec_channel(void)
297 {
298         if (lp_server_role() == ROLE_DOMAIN_BDC ||
299             lp_server_role() == ROLE_DOMAIN_PDC ||
300             lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
301                 return SEC_CHAN_BDC;
302         } else {
303                 return SEC_CHAN_WKSTA;
304         }
305 }
306
307 /************************************************************************
308  Routine to get the trust account password for a domain.
309  This only tries to get the legacy hashed version of the password.
310  The user of this function must have locked the trust password file using
311  the above secrets_lock_trust_account_password().
312 ************************************************************************/
313
314 bool secrets_fetch_trust_account_password_legacy(const char *domain,
315                                                  uint8_t ret_pwd[16],
316                                                  time_t *pass_last_set_time,
317                                                  enum netr_SchannelType *channel)
318 {
319         struct machine_acct_pass *pass;
320         size_t size = 0;
321
322         if (!(pass = (struct machine_acct_pass *)secrets_fetch(
323                       trust_keystr(domain), &size))) {
324                 DEBUG(5, ("secrets_fetch failed!\n"));
325                 return False;
326         }
327
328         if (size != sizeof(*pass)) {
329                 DEBUG(0, ("secrets were of incorrect size!\n"));
330                 SAFE_FREE(pass);
331                 return False;
332         }
333
334         if (pass_last_set_time) {
335                 *pass_last_set_time = pass->mod_time;
336         }
337         memcpy(ret_pwd, pass->hash, 16);
338
339         if (channel) {
340                 *channel = get_default_sec_channel();
341         }
342
343         SAFE_FREE(pass);
344         return True;
345 }
346
347 /************************************************************************
348  Routine to get the trust account password for a domain.
349  The user of this function must have locked the trust password file using
350  the above secrets_lock_trust_account_password().
351 ************************************************************************/
352
353 bool secrets_fetch_trust_account_password(const char *domain, uint8_t ret_pwd[16],
354                                           time_t *pass_last_set_time,
355                                           enum netr_SchannelType *channel)
356 {
357         char *plaintext;
358
359         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
360                                                    channel);
361         if (plaintext) {
362                 DEBUG(4,("Using cleartext machine password\n"));
363                 E_md4hash(plaintext, ret_pwd);
364                 SAFE_FREE(plaintext);
365                 return True;
366         }
367
368         return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
369                                                            pass_last_set_time,
370                                                            channel);
371 }
372
373 /************************************************************************
374  Routine to delete the old plaintext machine account password if any
375 ************************************************************************/
376
377 static bool secrets_delete_prev_machine_password(const char *domain)
378 {
379         char *oldpass = (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
380         if (oldpass == NULL) {
381                 return true;
382         }
383         SAFE_FREE(oldpass);
384         return secrets_delete_entry(machine_prev_password_keystr(domain));
385 }
386
387 /************************************************************************
388  Routine to delete the plaintext machine account password, old password,
389  sec channel type and last change time from secrets database
390 ************************************************************************/
391
392 bool secrets_delete_machine_password_ex(const char *domain)
393 {
394         if (!secrets_delete_prev_machine_password(domain)) {
395                 return false;
396         }
397         if (!secrets_delete_entry(machine_password_keystr(domain))) {
398                 return false;
399         }
400         if (!secrets_delete_entry(machine_sec_channel_type_keystr(domain))) {
401                 return false;
402         }
403         return secrets_delete_entry(machine_last_change_time_keystr(domain));
404 }
405
406 /************************************************************************
407  Routine to delete the domain sid
408 ************************************************************************/
409
410 bool secrets_delete_domain_sid(const char *domain)
411 {
412         return secrets_delete_entry(domain_sid_keystr(domain));
413 }
414
415 /************************************************************************
416  Routine to store the previous machine password (by storing the current password
417  as the old)
418 ************************************************************************/
419
420 static bool secrets_store_prev_machine_password(const char *domain)
421 {
422         char *oldpass;
423         bool ret;
424
425         oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
426         if (oldpass == NULL) {
427                 return true;
428         }
429         ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
430         SAFE_FREE(oldpass);
431         return ret;
432 }
433
434 /************************************************************************
435  Routine to set the plaintext machine account password for a realm
436  the password is assumed to be a null terminated ascii string.
437  Before storing
438 ************************************************************************/
439
440 bool secrets_store_machine_password(const char *pass, const char *domain,
441                                     enum netr_SchannelType sec_channel)
442 {
443         bool ret;
444         uint32_t last_change_time;
445         uint32_t sec_channel_type;
446
447         if (!secrets_store_prev_machine_password(domain)) {
448                 return false;
449         }
450
451         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
452         if (!ret)
453                 return ret;
454
455         SIVAL(&last_change_time, 0, time(NULL));
456         ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
457
458         SIVAL(&sec_channel_type, 0, sec_channel);
459         ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
460
461         return ret;
462 }
463
464 /************************************************************************
465  Set the machine trust account password, the old pw and last change
466  time, domain SID and salting principals based on values passed in
467  (added to supprt the secrets_tdb_sync module on secrets.ldb)
468 ************************************************************************/
469
470 bool secrets_store_machine_pw_sync(const char *pass, const char *oldpass, const char *domain,
471                                    const char *realm,
472                                    const char *salting_principal, uint32_t supported_enc_types,
473                                    const struct dom_sid *domain_sid, uint32_t last_change_time,
474                                    uint32_t secure_channel_type,
475                                    bool delete_join)
476 {
477         bool ret;
478         uint8_t last_change_time_store[4];
479         TALLOC_CTX *frame = talloc_stackframe();
480         uint8_t sec_channel_bytes[4];
481         void *value;
482
483         if (delete_join) {
484                 secrets_delete_machine_password_ex(domain);
485                 secrets_delete_domain_sid(domain);
486                 TALLOC_FREE(frame);
487                 return true;
488         }
489
490         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
491         if (!ret) {
492                 TALLOC_FREE(frame);
493                 return ret;
494         }
495
496         if (oldpass) {
497                 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
498         } else {
499                 value = secrets_fetch_prev_machine_password(domain);
500                 if (value) {
501                         SAFE_FREE(value);
502                         ret = secrets_delete_prev_machine_password(domain);
503                 }
504         }
505         if (!ret) {
506                 TALLOC_FREE(frame);
507                 return ret;
508         }
509
510         if (secure_channel_type == 0) {
511                 /* We delete this and instead have the read code fall back to
512                  * a default based on server role, as our caller can't specify
513                  * this with any more certainty */
514                 value = secrets_fetch(machine_sec_channel_type_keystr(domain), NULL);
515                 if (value) {
516                         SAFE_FREE(value);
517                         ret = secrets_delete_entry(machine_sec_channel_type_keystr(domain));
518                         if (!ret) {
519                                 TALLOC_FREE(frame);
520                                 return ret;
521                         }
522                 }
523         } else {
524                 SIVAL(&sec_channel_bytes, 0, secure_channel_type);
525                 ret = secrets_store(machine_sec_channel_type_keystr(domain), 
526                                     &sec_channel_bytes, sizeof(sec_channel_bytes));
527                 if (!ret) {
528                         TALLOC_FREE(frame);
529                         return ret;
530                 }
531         }
532
533         SIVAL(&last_change_time_store, 0, last_change_time);
534         ret = secrets_store(machine_last_change_time_keystr(domain),
535                             &last_change_time_store, sizeof(last_change_time));
536
537         if (!ret) {
538                 TALLOC_FREE(frame);
539                 return ret;
540         }
541
542         ret = secrets_store_domain_sid(domain, domain_sid);
543
544         if (!ret) {
545                 TALLOC_FREE(frame);
546                 return ret;
547         }
548
549         if (realm && salting_principal) {
550                 char *key = des_salt_key(realm);
551                 ret = secrets_store(key, salting_principal, strlen(salting_principal)+1 );
552         }
553
554         TALLOC_FREE(frame);
555         return ret;
556 }
557
558 /************************************************************************
559  Return the standard DES salt key
560 ************************************************************************/
561
562 char* kerberos_standard_des_salt( void )
563 {
564         fstring salt;
565
566         fstr_sprintf( salt, "host/%s.%s@", lp_netbios_name(), lp_realm() );
567         (void)strlower_m( salt );
568         fstrcat( salt, lp_realm() );
569
570         return SMB_STRDUP( salt );
571 }
572
573 /************************************************************************
574 ************************************************************************/
575
576 static char *des_salt_key(const char *realm)
577 {
578         char *keystr;
579
580         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/DES/%s",
581                                             SECRETS_SALTING_PRINCIPAL,
582                                             realm);
583         SMB_ASSERT(keystr != NULL);
584         return keystr;
585 }
586
587 /************************************************************************
588 ************************************************************************/
589
590 bool kerberos_secrets_store_des_salt( const char* salt )
591 {
592         char* key;
593         bool ret;
594
595         key = des_salt_key(lp_realm());
596         if (key == NULL) {
597                 DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n"));
598                 return False;
599         }
600
601         if ( !salt ) {
602                 DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n"));
603                 secrets_delete_entry( key );
604                 return True;
605         }
606
607         DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt));
608
609         ret = secrets_store( key, salt, strlen(salt)+1 );
610
611         TALLOC_FREE(key);
612
613         return ret;
614 }
615
616 /************************************************************************
617 ************************************************************************/
618
619 static
620 char* kerberos_secrets_fetch_des_salt( void )
621 {
622         char *salt, *key;
623
624         key = des_salt_key(lp_realm());
625         if (key == NULL) {
626                 DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
627                 return NULL;
628         }
629
630         salt = (char*)secrets_fetch( key, NULL );
631
632         TALLOC_FREE(key);
633
634         return salt;
635 }
636
637 /************************************************************************
638  Routine to get the salting principal for this service.
639  Caller must free if return is not null.
640  ************************************************************************/
641
642 char *kerberos_secrets_fetch_salt_princ(void)
643 {
644         char *salt_princ_s;
645         /* lookup new key first */
646
647         salt_princ_s = kerberos_secrets_fetch_des_salt();
648         if (salt_princ_s == NULL) {
649                 /* fall back to host/machine.realm@REALM */
650                 salt_princ_s = kerberos_standard_des_salt();
651         }
652
653         return salt_princ_s;
654 }
655
656 /************************************************************************
657  Routine to fetch the previous plaintext machine account password for a realm
658  the password is assumed to be a null terminated ascii string.
659 ************************************************************************/
660
661 char *secrets_fetch_prev_machine_password(const char *domain)
662 {
663         return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
664 }
665
666 /************************************************************************
667  Routine to fetch the last change time of the machine account password
668   for a realm
669 ************************************************************************/
670
671 time_t secrets_fetch_pass_last_set_time(const char *domain)
672 {
673         uint32_t *last_set_time;
674         time_t pass_last_set_time;
675
676         last_set_time = secrets_fetch(machine_last_change_time_keystr(domain),
677                                       NULL);
678         if (last_set_time) {
679                 pass_last_set_time = IVAL(last_set_time,0);
680                 SAFE_FREE(last_set_time);
681         } else {
682                 pass_last_set_time = 0;
683         }
684
685         return pass_last_set_time;
686 }
687
688 /************************************************************************
689  Routine to fetch the plaintext machine account password for a realm
690  the password is assumed to be a null terminated ascii string.
691 ************************************************************************/
692
693 char *secrets_fetch_machine_password(const char *domain,
694                                      time_t *pass_last_set_time,
695                                      enum netr_SchannelType *channel)
696 {
697         char *ret;
698         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
699
700         if (pass_last_set_time) {
701                 *pass_last_set_time = secrets_fetch_pass_last_set_time(domain);
702         }
703
704         if (channel) {
705                 size_t size;
706                 uint32_t *channel_type;
707                 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
708                 if (channel_type) {
709                         *channel = IVAL(channel_type,0);
710                         SAFE_FREE(channel_type);
711                 } else {
712                         *channel = get_default_sec_channel();
713                 }
714         }
715
716         return ret;
717 }