s3:secrets: let secrets_delete_machine_password_ex() also remove the des_salt key
[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/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 all information related to the domain joined machine.
375 ************************************************************************/
376
377 bool secrets_delete_machine_password_ex(const char *domain, const char *realm)
378 {
379         const char *tmpkey = NULL;
380         bool ok;
381
382         if (realm != NULL) {
383                 tmpkey = des_salt_key(domain);
384                 ok = secrets_delete(tmpkey);
385                 if (!ok) {
386                         return false;
387                 }
388         }
389
390         tmpkey = domain_guid_keystr(domain);
391         ok = secrets_delete(tmpkey);
392         if (!ok) {
393                 return false;
394         }
395
396         tmpkey = machine_prev_password_keystr(domain);
397         ok = secrets_delete(tmpkey);
398         if (!ok) {
399                 return false;
400         }
401
402         tmpkey = machine_password_keystr(domain);
403         ok = secrets_delete_entry(tmpkey);
404         if (!ok) {
405                 return false;
406         }
407
408         tmpkey = machine_sec_channel_type_keystr(domain);
409         ok = secrets_delete_entry(tmpkey);
410         if (!ok) {
411                 return false;
412         }
413
414         tmpkey = machine_last_change_time_keystr(domain);
415         ok = secrets_delete_entry(tmpkey);
416         if (!ok) {
417                 return false;
418         }
419
420         tmpkey = domain_sid_keystr(domain);
421         ok = secrets_delete_entry(tmpkey);
422         if (!ok) {
423                 return false;
424         }
425
426         return true;
427 }
428
429 /************************************************************************
430  Routine to delete the domain sid
431 ************************************************************************/
432
433 bool secrets_delete_domain_sid(const char *domain)
434 {
435         return secrets_delete_entry(domain_sid_keystr(domain));
436 }
437
438 /************************************************************************
439  Routine to store the previous machine password (by storing the current password
440  as the old)
441 ************************************************************************/
442
443 static bool secrets_store_prev_machine_password(const char *domain)
444 {
445         char *oldpass;
446         bool ret;
447
448         oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
449         if (oldpass == NULL) {
450                 return true;
451         }
452         ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
453         SAFE_FREE(oldpass);
454         return ret;
455 }
456
457 /************************************************************************
458  Routine to set the plaintext machine account password for a realm
459  the password is assumed to be a null terminated ascii string.
460  Before storing
461 ************************************************************************/
462
463 bool secrets_store_machine_password(const char *pass, const char *domain,
464                                     enum netr_SchannelType sec_channel)
465 {
466         bool ret;
467         uint32_t last_change_time;
468         uint32_t sec_channel_type;
469
470         if (!secrets_store_prev_machine_password(domain)) {
471                 return false;
472         }
473
474         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
475         if (!ret)
476                 return ret;
477
478         SIVAL(&last_change_time, 0, time(NULL));
479         ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
480
481         SIVAL(&sec_channel_type, 0, sec_channel);
482         ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
483
484         return ret;
485 }
486
487 /************************************************************************
488  Set the machine trust account password, the old pw and last change
489  time, domain SID and salting principals based on values passed in
490  (added to supprt the secrets_tdb_sync module on secrets.ldb)
491 ************************************************************************/
492
493 bool secrets_store_machine_pw_sync(const char *pass, const char *oldpass, const char *domain,
494                                    const char *realm,
495                                    const char *salting_principal, uint32_t supported_enc_types,
496                                    const struct dom_sid *domain_sid, uint32_t last_change_time,
497                                    uint32_t secure_channel_type,
498                                    bool delete_join)
499 {
500         bool ret;
501         uint8_t last_change_time_store[4];
502         TALLOC_CTX *frame = talloc_stackframe();
503         uint8_t sec_channel_bytes[4];
504
505         if (delete_join) {
506                 secrets_delete_machine_password_ex(domain, realm);
507                 TALLOC_FREE(frame);
508                 return true;
509         }
510
511         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
512         if (!ret) {
513                 TALLOC_FREE(frame);
514                 return ret;
515         }
516
517         if (oldpass) {
518                 ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
519         } else {
520                 ret = secrets_delete(machine_prev_password_keystr(domain));
521         }
522         if (!ret) {
523                 TALLOC_FREE(frame);
524                 return ret;
525         }
526
527         if (secure_channel_type == 0) {
528                 /* We delete this and instead have the read code fall back to
529                  * a default based on server role, as our caller can't specify
530                  * this with any more certainty */
531                 ret = secrets_delete(machine_sec_channel_type_keystr(domain));
532                 if (!ret) {
533                         TALLOC_FREE(frame);
534                         return ret;
535                 }
536         } else {
537                 SIVAL(&sec_channel_bytes, 0, secure_channel_type);
538                 ret = secrets_store(machine_sec_channel_type_keystr(domain), 
539                                     &sec_channel_bytes, sizeof(sec_channel_bytes));
540                 if (!ret) {
541                         TALLOC_FREE(frame);
542                         return ret;
543                 }
544         }
545
546         SIVAL(&last_change_time_store, 0, last_change_time);
547         ret = secrets_store(machine_last_change_time_keystr(domain),
548                             &last_change_time_store, sizeof(last_change_time));
549
550         if (!ret) {
551                 TALLOC_FREE(frame);
552                 return ret;
553         }
554
555         ret = secrets_store_domain_sid(domain, domain_sid);
556
557         if (!ret) {
558                 TALLOC_FREE(frame);
559                 return ret;
560         }
561
562         if (realm != NULL) {
563                 char *key = des_salt_key(realm);
564
565                 if (salting_principal != NULL) {
566                         ret = secrets_store(key,
567                                             salting_principal,
568                                             strlen(salting_principal)+1);
569                 } else {
570                         ret = secrets_delete(key);
571                 }
572         }
573
574         TALLOC_FREE(frame);
575         return ret;
576 }
577
578 /************************************************************************
579  Return the standard DES salt key
580 ************************************************************************/
581
582 char* kerberos_standard_des_salt( void )
583 {
584         fstring salt;
585
586         fstr_sprintf( salt, "host/%s.%s@", lp_netbios_name(), lp_realm() );
587         (void)strlower_m( salt );
588         fstrcat( salt, lp_realm() );
589
590         return SMB_STRDUP( salt );
591 }
592
593 /************************************************************************
594 ************************************************************************/
595
596 static char *des_salt_key(const char *realm)
597 {
598         char *keystr;
599
600         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/DES/%s",
601                                             SECRETS_SALTING_PRINCIPAL,
602                                             realm);
603         SMB_ASSERT(keystr != NULL);
604         return keystr;
605 }
606
607 /************************************************************************
608 ************************************************************************/
609
610 bool kerberos_secrets_store_des_salt( const char* salt )
611 {
612         char* key;
613         bool ret;
614
615         key = des_salt_key(lp_realm());
616         if (key == NULL) {
617                 DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n"));
618                 return False;
619         }
620
621         if ( !salt ) {
622                 DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n"));
623                 secrets_delete_entry( key );
624                 return True;
625         }
626
627         DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt));
628
629         ret = secrets_store( key, salt, strlen(salt)+1 );
630
631         TALLOC_FREE(key);
632
633         return ret;
634 }
635
636 /************************************************************************
637 ************************************************************************/
638
639 static
640 char* kerberos_secrets_fetch_des_salt( void )
641 {
642         char *salt, *key;
643
644         key = des_salt_key(lp_realm());
645         if (key == NULL) {
646                 DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
647                 return NULL;
648         }
649
650         salt = (char*)secrets_fetch( key, NULL );
651
652         TALLOC_FREE(key);
653
654         return salt;
655 }
656
657 /************************************************************************
658  Routine to get the salting principal for this service.
659  Caller must free if return is not null.
660  ************************************************************************/
661
662 char *kerberos_secrets_fetch_salt_princ(void)
663 {
664         char *salt_princ_s;
665         /* lookup new key first */
666
667         salt_princ_s = kerberos_secrets_fetch_des_salt();
668         if (salt_princ_s == NULL) {
669                 /* fall back to host/machine.realm@REALM */
670                 salt_princ_s = kerberos_standard_des_salt();
671         }
672
673         return salt_princ_s;
674 }
675
676 /************************************************************************
677  Routine to fetch the previous plaintext machine account password for a realm
678  the password is assumed to be a null terminated ascii string.
679 ************************************************************************/
680
681 char *secrets_fetch_prev_machine_password(const char *domain)
682 {
683         return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
684 }
685
686 /************************************************************************
687  Routine to fetch the last change time of the machine account password
688   for a realm
689 ************************************************************************/
690
691 time_t secrets_fetch_pass_last_set_time(const char *domain)
692 {
693         uint32_t *last_set_time;
694         time_t pass_last_set_time;
695
696         last_set_time = secrets_fetch(machine_last_change_time_keystr(domain),
697                                       NULL);
698         if (last_set_time) {
699                 pass_last_set_time = IVAL(last_set_time,0);
700                 SAFE_FREE(last_set_time);
701         } else {
702                 pass_last_set_time = 0;
703         }
704
705         return pass_last_set_time;
706 }
707
708 /************************************************************************
709  Routine to fetch the plaintext machine account password for a realm
710  the password is assumed to be a null terminated ascii string.
711 ************************************************************************/
712
713 char *secrets_fetch_machine_password(const char *domain,
714                                      time_t *pass_last_set_time,
715                                      enum netr_SchannelType *channel)
716 {
717         char *ret;
718         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
719
720         if (pass_last_set_time) {
721                 *pass_last_set_time = secrets_fetch_pass_last_set_time(domain);
722         }
723
724         if (channel) {
725                 size_t size;
726                 uint32_t *channel_type;
727                 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
728                 if (channel_type) {
729                         *channel = IVAL(channel_type,0);
730                         SAFE_FREE(channel_type);
731                 } else {
732                         *channel = get_default_sec_channel();
733                 }
734         }
735
736         return ret;
737 }