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