Add secrets_shutdown().
[metze/samba/wip.git] / source3 / passdb / 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
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_PASSDB
29
30 static TDB_CONTEXT *tdb;
31
32 /* Urrrg. global.... */
33 bool global_machine_password_needs_changing;
34
35 /**
36  * Use a TDB to store an incrementing random seed.
37  *
38  * Initialised to the current pid, the very first time Samba starts,
39  * and incremented by one each time it is needed.
40  *
41  * @note Not called by systems with a working /dev/urandom.
42  */
43 static void get_rand_seed(int *new_seed)
44 {
45         *new_seed = sys_getpid();
46         if (tdb) {
47                 tdb_change_int32_atomic(tdb, "INFO/random_seed", new_seed, 1);
48         }
49 }
50
51 /* open up the secrets database */
52 bool secrets_init(void)
53 {
54         TALLOC_CTX *ctx;
55         char *fname = NULL;
56         unsigned char dummy;
57
58         if (tdb)
59                 return True;
60
61         ctx = talloc_init("secrets_init");
62         if (!ctx) {
63                 return false;
64         }
65         fname = talloc_asprintf(ctx,
66                         "%s/secrets.tdb",
67                         lp_private_dir());
68         if (!fname) {
69                 TALLOC_FREE(ctx);
70                 return false;
71         }
72
73         tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
74
75         if (!tdb) {
76                 DEBUG(0,("Failed to open %s\n", fname));
77                 TALLOC_FREE(ctx);
78                 return False;
79         }
80
81         TALLOC_FREE(ctx);
82
83         /**
84          * Set a reseed function for the crypto random generator
85          *
86          * This avoids a problem where systems without /dev/urandom
87          * could send the same challenge to multiple clients
88          */
89         set_rand_reseed_callback(get_rand_seed);
90
91         /* Ensure that the reseed is done now, while we are root, etc */
92         generate_random_buffer(&dummy, sizeof(dummy));
93
94         return True;
95 }
96
97 /*
98  * close secrets.tdb
99  */
100 void secrets_shutdown(void)
101 {
102         if (!tdb) {
103                 return;
104         }
105
106         tdb_close(tdb);
107         tdb = NULL;
108 }
109
110 /* read a entry from the secrets database - the caller must free the result
111    if size is non-null then the size of the entry is put in there
112  */
113 void *secrets_fetch(const char *key, size_t *size)
114 {
115         TDB_DATA dbuf;
116         secrets_init();
117         if (!tdb)
118                 return NULL;
119         dbuf = tdb_fetch(tdb, string_tdb_data(key));
120         if (size)
121                 *size = dbuf.dsize;
122         return dbuf.dptr;
123 }
124
125 /* store a secrets entry
126  */
127 bool secrets_store(const char *key, const void *data, size_t size)
128 {
129         secrets_init();
130         if (!tdb)
131                 return False;
132         return tdb_trans_store(tdb, string_tdb_data(key),
133                                make_tdb_data((const uint8 *)data, size),
134                                TDB_REPLACE) == 0;
135 }
136
137
138 /* delete a secets database entry
139  */
140 bool secrets_delete(const char *key)
141 {
142         secrets_init();
143         if (!tdb)
144                 return False;
145         return tdb_trans_delete(tdb, string_tdb_data(key)) == 0;
146 }
147
148 /**
149  * Form a key for fetching the domain sid
150  *
151  * @param domain domain name
152  *
153  * @return keystring
154  **/
155 static const char *domain_sid_keystr(const char *domain)
156 {
157         char *keystr;
158
159         keystr = talloc_asprintf(talloc_tos(), "%s/%s",
160                                  SECRETS_DOMAIN_SID, domain);
161         SMB_ASSERT(keystr != NULL);
162
163         strupper_m(keystr);
164
165         return keystr;
166 }
167
168 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
169 {
170         bool ret;
171
172         ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
173
174         /* Force a re-query, in case we modified our domain */
175         if (ret)
176                 reset_global_sam_sid();
177         return ret;
178 }
179
180 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
181 {
182         DOM_SID *dyn_sid;
183         size_t size = 0;
184
185         dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
186
187         if (dyn_sid == NULL)
188                 return False;
189
190         if (size != sizeof(DOM_SID)) {
191                 SAFE_FREE(dyn_sid);
192                 return False;
193         }
194
195         *sid = *dyn_sid;
196         SAFE_FREE(dyn_sid);
197         return True;
198 }
199
200 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
201 {
202         fstring key;
203
204         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
205         strupper_m(key);
206         return secrets_store(key, guid, sizeof(struct GUID));
207 }
208
209 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
210 {
211         struct GUID *dyn_guid;
212         fstring key;
213         size_t size = 0;
214         struct GUID new_guid;
215
216         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
217         strupper_m(key);
218         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
219
220         if (!dyn_guid) {
221                 if (lp_server_role() == ROLE_DOMAIN_PDC) {
222                         smb_uuid_generate_random(&new_guid);
223                         if (!secrets_store_domain_guid(domain, &new_guid))
224                                 return False;
225                         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
226                 }
227                 if (dyn_guid == NULL) {
228                         return False;
229                 }
230         }
231
232         if (size != sizeof(struct GUID)) {
233                 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
234                 SAFE_FREE(dyn_guid);
235                 return False;
236         }
237
238         *guid = *dyn_guid;
239         SAFE_FREE(dyn_guid);
240         return True;
241 }
242
243 /**
244  * Form a key for fetching the machine trust account sec channel type
245  *
246  * @param domain domain name
247  *
248  * @return keystring
249  **/
250 static const char *machine_sec_channel_type_keystr(const char *domain)
251 {
252         char *keystr;
253
254         keystr = talloc_asprintf(talloc_tos(), "%s/%s",
255                                  SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
256         SMB_ASSERT(keystr != NULL);
257
258         strupper_m(keystr);
259
260         return keystr;
261 }
262
263 /**
264  * Form a key for fetching the machine trust account last change time
265  *
266  * @param domain domain name
267  *
268  * @return keystring
269  **/
270 static const char *machine_last_change_time_keystr(const char *domain)
271 {
272         char *keystr;
273
274         keystr = talloc_asprintf(talloc_tos(), "%s/%s",
275                                  SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
276         SMB_ASSERT(keystr != NULL);
277
278         strupper_m(keystr);
279
280         return keystr;
281 }
282
283
284 /**
285  * Form a key for fetching the machine trust account password
286  *
287  * @param domain domain name
288  *
289  * @return keystring
290  **/
291 static const char *machine_password_keystr(const char *domain)
292 {
293         char *keystr;
294
295         keystr = talloc_asprintf(talloc_tos(), "%s/%s",
296                                  SECRETS_MACHINE_PASSWORD, domain);
297         SMB_ASSERT(keystr != NULL);
298
299         strupper_m(keystr);
300
301         return keystr;
302 }
303
304 /**
305  * Form a key for fetching the machine trust account password
306  *
307  * @param domain domain name
308  *
309  * @return stored password's key
310  **/
311 static const char *trust_keystr(const char *domain)
312 {
313         char *keystr;
314
315         keystr = talloc_asprintf(talloc_tos(), "%s/%s",
316                                  SECRETS_MACHINE_ACCT_PASS, domain);
317         SMB_ASSERT(keystr != NULL);
318
319         strupper_m(keystr);
320
321         return keystr;
322 }
323
324 /**
325  * Form a key for fetching a trusted domain password
326  *
327  * @param domain trusted domain name
328  *
329  * @return stored password's key
330  **/
331 static char *trustdom_keystr(const char *domain)
332 {
333         char *keystr;
334
335         keystr = talloc_asprintf(talloc_tos(), "%s/%s",
336                                  SECRETS_DOMTRUST_ACCT_PASS, domain);
337         SMB_ASSERT(keystr != NULL);
338         strupper_m(keystr);
339
340         return keystr;
341 }
342
343 /************************************************************************
344  Lock the trust password entry.
345 ************************************************************************/
346
347 bool secrets_lock_trust_account_password(const char *domain, bool dolock)
348 {
349         if (!tdb)
350                 return False;
351
352         if (dolock)
353                 return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
354         else
355                 tdb_unlock_bystring(tdb, trust_keystr(domain));
356         return True;
357 }
358
359 /************************************************************************
360  Routine to get the default secure channel type for trust accounts
361 ************************************************************************/
362
363 uint32 get_default_sec_channel(void)
364 {
365         if (lp_server_role() == ROLE_DOMAIN_BDC ||
366             lp_server_role() == ROLE_DOMAIN_PDC) {
367                 return SEC_CHAN_BDC;
368         } else {
369                 return SEC_CHAN_WKSTA;
370         }
371 }
372
373 /************************************************************************
374  Routine to get the trust account password for a domain.
375  This only tries to get the legacy hashed version of the password.
376  The user of this function must have locked the trust password file using
377  the above secrets_lock_trust_account_password().
378 ************************************************************************/
379
380 bool secrets_fetch_trust_account_password_legacy(const char *domain,
381                                                  uint8 ret_pwd[16],
382                                                  time_t *pass_last_set_time,
383                                                  uint32 *channel)
384 {
385         struct machine_acct_pass *pass;
386         size_t size = 0;
387
388         if (!(pass = (struct machine_acct_pass *)secrets_fetch(
389                       trust_keystr(domain), &size))) {
390                 DEBUG(5, ("secrets_fetch failed!\n"));
391                 return False;
392         }
393
394         if (size != sizeof(*pass)) {
395                 DEBUG(0, ("secrets were of incorrect size!\n"));
396                 return False;
397         }
398
399         if (pass_last_set_time) {
400                 *pass_last_set_time = pass->mod_time;
401         }
402         memcpy(ret_pwd, pass->hash, 16);
403
404         if (channel) {
405                 *channel = get_default_sec_channel();
406         }
407
408         /* Test if machine password has expired and needs to be changed */
409         if (lp_machine_password_timeout()) {
410                 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
411                                 (time_t)lp_machine_password_timeout())) {
412                         global_machine_password_needs_changing = True;
413                 }
414         }
415
416         SAFE_FREE(pass);
417         return True;
418 }
419
420 /************************************************************************
421  Routine to get the trust account password for a domain.
422  The user of this function must have locked the trust password file using
423  the above secrets_lock_trust_account_password().
424 ************************************************************************/
425
426 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
427                                           time_t *pass_last_set_time,
428                                           uint32 *channel)
429 {
430         char *plaintext;
431
432         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
433                                                    channel);
434         if (plaintext) {
435                 DEBUG(4,("Using cleartext machine password\n"));
436                 E_md4hash(plaintext, ret_pwd);
437                 SAFE_FREE(plaintext);
438                 return True;
439         }
440
441         return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
442                                                            pass_last_set_time,
443                                                            channel);
444 }
445
446 /**
447  * Pack SID passed by pointer
448  *
449  * @param pack_buf pointer to buffer which is to be filled with packed data
450  * @param bufsize size of packing buffer
451  * @param sid pointer to sid to be packed
452  *
453  * @return length of the packed representation of the whole structure
454  **/
455 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
456 {
457         int idx;
458         size_t len = 0;
459         uint8 *p = pack_buf;
460         int remaining_space = pack_buf ? bufsize : 0;
461
462         if (!sid) {
463                 return -1;
464         }
465
466         len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
467                         sid->num_auths);
468         if (pack_buf) {
469                 p = pack_buf + len;
470                 remaining_space = bufsize - len;
471         }
472
473         for (idx = 0; idx < 6; idx++) {
474                 len += tdb_pack(p, remaining_space, "b",
475                                 sid->id_auth[idx]);
476                 if (pack_buf) {
477                         p = pack_buf + len;
478                         remaining_space = bufsize - len;
479                 }
480         }
481
482         for (idx = 0; idx < MAXSUBAUTHS; idx++) {
483                 len += tdb_pack(p, remaining_space, "d",
484                                 sid->sub_auths[idx]);
485                 if (pack_buf) {
486                         p = pack_buf + len;
487                         remaining_space = bufsize - len;
488                 }
489         }
490
491         return len;
492 }
493
494 /**
495  * Unpack SID into a pointer
496  *
497  * @param pack_buf pointer to buffer with packed representation
498  * @param bufsize size of the buffer
499  * @param sid pointer to sid structure to be filled with unpacked data
500  *
501  * @return size of structure unpacked from buffer
502  **/
503 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
504 {
505         int idx, len = 0;
506
507         if (!sid || !pack_buf) return -1;
508
509         len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
510                           &sid->sid_rev_num, &sid->num_auths);
511
512         for (idx = 0; idx < 6; idx++) {
513                 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
514                                   &sid->id_auth[idx]);
515         }
516
517         for (idx = 0; idx < MAXSUBAUTHS; idx++) {
518                 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
519                                   &sid->sub_auths[idx]);
520         }
521
522         return len;
523 }
524
525 /**
526  * Pack TRUSTED_DOM_PASS passed by pointer
527  *
528  * @param pack_buf pointer to buffer which is to be filled with packed data
529  * @param bufsize size of the buffer
530  * @param pass pointer to trusted domain password to be packed
531  *
532  * @return length of the packed representation of the whole structure
533  **/
534 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
535                                         TRUSTED_DOM_PASS* pass)
536 {
537         int idx, len = 0;
538         uint8 *p = pack_buf;
539         int remaining_space = pack_buf ? bufsize : 0;
540
541         if (!pass) {
542                 return -1;
543         }
544
545         /* packing unicode domain name and password */
546         len += tdb_pack(p, remaining_space, "d",
547                         pass->uni_name_len);
548         if (pack_buf) {
549                 p = pack_buf + len;
550                 remaining_space = bufsize - len;
551         }
552
553         for (idx = 0; idx < 32; idx++) {
554                 len += tdb_pack(p, remaining_space, "w",
555                                  pass->uni_name[idx]);
556                 if (pack_buf) {
557                         p = pack_buf + len;
558                         remaining_space = bufsize - len;
559                 }
560         }
561
562         len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
563                              pass->pass, pass->mod_time);
564         if (pack_buf) {
565                 p = pack_buf + len;
566                 remaining_space = bufsize - len;
567         }
568
569         /* packing SID structure */
570         len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
571         if (pack_buf) {
572                 p = pack_buf + len;
573                 remaining_space = bufsize - len;
574         }
575
576         return len;
577 }
578
579
580 /**
581  * Unpack TRUSTED_DOM_PASS passed by pointer
582  *
583  * @param pack_buf pointer to buffer with packed representation
584  * @param bufsize size of the buffer
585  * @param pass pointer to trusted domain password to be filled with unpacked data
586  *
587  * @return size of structure unpacked from buffer
588  **/
589 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
590                                           TRUSTED_DOM_PASS* pass)
591 {
592         int idx, len = 0;
593         char *passp = NULL;
594
595         if (!pack_buf || !pass) return -1;
596
597         /* unpack unicode domain name and plaintext password */
598         len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
599
600         for (idx = 0; idx < 32; idx++)
601                 len +=  tdb_unpack(pack_buf + len, bufsize - len, "w",
602                                    &pass->uni_name[idx]);
603
604         len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
605                           &pass->pass_len, &passp, &pass->mod_time);
606         if (passp) {
607                 fstrcpy(pass->pass, passp);
608         }
609         SAFE_FREE(passp);
610
611         /* unpack domain sid */
612         len += tdb_sid_unpack(pack_buf + len, bufsize - len,
613                               &pass->domain_sid);
614
615         return len;
616 }
617
618 /************************************************************************
619  Routine to get account password to trusted domain
620 ************************************************************************/
621
622 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
623                                            DOM_SID *sid, time_t *pass_last_set_time)
624 {
625         struct trusted_dom_pass pass;
626         size_t size = 0;
627
628         /* unpacking structures */
629         uint8 *pass_buf;
630         int pass_len = 0;
631
632         ZERO_STRUCT(pass);
633
634         /* fetching trusted domain password structure */
635         if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
636                                                &size))) {
637                 DEBUG(5, ("secrets_fetch failed!\n"));
638                 return False;
639         }
640
641         /* unpack trusted domain password */
642         pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
643         SAFE_FREE(pass_buf);
644
645         if (pass_len != size) {
646                 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
647                 return False;
648         }
649
650         /* the trust's password */
651         if (pwd) {
652                 *pwd = SMB_STRDUP(pass.pass);
653                 if (!*pwd) {
654                         return False;
655                 }
656         }
657
658         /* last change time */
659         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
660
661         /* domain sid */
662         if (sid != NULL) sid_copy(sid, &pass.domain_sid);
663
664         return True;
665 }
666
667 /**
668  * Routine to store the password for trusted domain
669  *
670  * @param domain remote domain name
671  * @param pwd plain text password of trust relationship
672  * @param sid remote domain sid
673  *
674  * @return true if succeeded
675  **/
676
677 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
678                                            const DOM_SID *sid)
679 {
680         smb_ucs2_t *uni_dom_name;
681         bool ret;
682
683         /* packing structures */
684         uint8 *pass_buf = NULL;
685         int pass_len = 0;
686
687         struct trusted_dom_pass pass;
688         ZERO_STRUCT(pass);
689
690         if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
691                 DEBUG(0, ("Could not convert domain name %s to unicode\n",
692                           domain));
693                 return False;
694         }
695
696         strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
697         pass.uni_name_len = strlen_w(uni_dom_name)+1;
698         SAFE_FREE(uni_dom_name);
699
700         /* last change time */
701         pass.mod_time = time(NULL);
702
703         /* password of the trust */
704         pass.pass_len = strlen(pwd);
705         fstrcpy(pass.pass, pwd);
706
707         /* domain sid */
708         sid_copy(&pass.domain_sid, sid);
709
710         /* Calculate the length. */
711         pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
712         pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
713         if (!pass_buf) {
714                 return false;
715         }
716         pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
717         ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
718                         pass_len);
719         SAFE_FREE(pass_buf);
720         return ret;
721 }
722
723 /************************************************************************
724  Routine to delete the plaintext machine account password
725 ************************************************************************/
726
727 bool secrets_delete_machine_password(const char *domain)
728 {
729         return secrets_delete(machine_password_keystr(domain));
730 }
731
732 /************************************************************************
733  Routine to delete the plaintext machine account password, sec channel type and
734  last change time from secrets database
735 ************************************************************************/
736
737 bool secrets_delete_machine_password_ex(const char *domain)
738 {
739         if (!secrets_delete(machine_password_keystr(domain))) {
740                 return false;
741         }
742         if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
743                 return false;
744         }
745         return secrets_delete(machine_last_change_time_keystr(domain));
746 }
747
748 /************************************************************************
749  Routine to delete the domain sid
750 ************************************************************************/
751
752 bool secrets_delete_domain_sid(const char *domain)
753 {
754         return secrets_delete(domain_sid_keystr(domain));
755 }
756
757 /************************************************************************
758  Routine to set the plaintext machine account password for a realm
759 the password is assumed to be a null terminated ascii string
760 ************************************************************************/
761
762 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
763 {
764         bool ret;
765         uint32 last_change_time;
766         uint32 sec_channel_type;
767
768         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
769         if (!ret)
770                 return ret;
771
772         SIVAL(&last_change_time, 0, time(NULL));
773         ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
774
775         SIVAL(&sec_channel_type, 0, sec_channel);
776         ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
777
778         return ret;
779 }
780
781 /************************************************************************
782  Routine to fetch the plaintext machine account password for a realm
783  the password is assumed to be a null terminated ascii string.
784 ************************************************************************/
785
786 char *secrets_fetch_machine_password(const char *domain,
787                                      time_t *pass_last_set_time,
788                                      uint32 *channel)
789 {
790         char *ret;
791         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
792
793         if (pass_last_set_time) {
794                 size_t size;
795                 uint32 *last_set_time;
796                 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
797                 if (last_set_time) {
798                         *pass_last_set_time = IVAL(last_set_time,0);
799                         SAFE_FREE(last_set_time);
800                 } else {
801                         *pass_last_set_time = 0;
802                 }
803         }
804
805         if (channel) {
806                 size_t size;
807                 uint32 *channel_type;
808                 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
809                 if (channel_type) {
810                         *channel = IVAL(channel_type,0);
811                         SAFE_FREE(channel_type);
812                 } else {
813                         *channel = get_default_sec_channel();
814                 }
815         }
816
817         return ret;
818 }
819
820 /************************************************************************
821  Routine to delete the password for trusted domain
822 ************************************************************************/
823
824 bool trusted_domain_password_delete(const char *domain)
825 {
826         return secrets_delete(trustdom_keystr(domain));
827 }
828
829 bool secrets_store_ldap_pw(const char* dn, char* pw)
830 {
831         char *key = NULL;
832         bool ret;
833
834         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
835                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
836                 return False;
837         }
838
839         ret = secrets_store(key, pw, strlen(pw)+1);
840
841         SAFE_FREE(key);
842         return ret;
843 }
844
845 /*******************************************************************
846  Find the ldap password.
847 ******************************************************************/
848
849 bool fetch_ldap_pw(char **dn, char** pw)
850 {
851         char *key = NULL;
852         size_t size = 0;
853
854         *dn = smb_xstrdup(lp_ldap_admin_dn());
855
856         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
857                 SAFE_FREE(*dn);
858                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
859         }
860
861         *pw=(char *)secrets_fetch(key, &size);
862         SAFE_FREE(key);
863
864         if (!size) {
865                 /* Upgrade 2.2 style entry */
866                 char *p;
867                 char* old_style_key = SMB_STRDUP(*dn);
868                 char *data;
869                 fstring old_style_pw;
870
871                 if (!old_style_key) {
872                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
873                         return False;
874                 }
875
876                 for (p=old_style_key; *p; p++)
877                         if (*p == ',') *p = '/';
878
879                 data=(char *)secrets_fetch(old_style_key, &size);
880                 if (!size && size < sizeof(old_style_pw)) {
881                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
882                         SAFE_FREE(old_style_key);
883                         SAFE_FREE(*dn);
884                         return False;
885                 }
886
887                 size = MIN(size, sizeof(fstring)-1);
888                 strncpy(old_style_pw, data, size);
889                 old_style_pw[size] = 0;
890
891                 SAFE_FREE(data);
892
893                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
894                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
895                         SAFE_FREE(old_style_key);
896                         SAFE_FREE(*dn);
897                         return False;
898                 }
899                 if (!secrets_delete(old_style_key)) {
900                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
901                 }
902
903                 SAFE_FREE(old_style_key);
904
905                 *pw = smb_xstrdup(old_style_pw);
906         }
907
908         return True;
909 }
910
911 /**
912  * Get trusted domains info from secrets.tdb.
913  **/
914
915 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
916                                  struct trustdom_info ***domains)
917 {
918         TDB_LIST_NODE *keys, *k;
919         char *pattern;
920         TALLOC_CTX *tmp_ctx;
921
922         if (!(tmp_ctx = talloc_new(mem_ctx))) {
923                 return NT_STATUS_NO_MEMORY;
924         }
925
926         if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
927
928         /* generate searching pattern */
929         pattern = talloc_asprintf(tmp_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
930         if (pattern == NULL) {
931                 DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
932                           "failed!\n"));
933                 TALLOC_FREE(tmp_ctx);
934                 return NT_STATUS_NO_MEMORY;
935         }
936
937         *num_domains = 0;
938
939         /*
940          * Make sure that a talloc context for the trustdom_info structs
941          * exists
942          */
943
944         if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
945                 TALLOC_FREE(tmp_ctx);
946                 return NT_STATUS_NO_MEMORY;
947         }
948
949         /* fetching trusted domains' data and collecting them in a list */
950         keys = tdb_search_keys(tdb, pattern);
951
952         /* searching for keys in secrets db -- way to go ... */
953         for (k = keys; k; k = k->next) {
954                 uint8 *packed_pass;
955                 size_t size = 0, packed_size = 0;
956                 struct trusted_dom_pass pass;
957                 char *secrets_key;
958                 struct trustdom_info *dom_info;
959
960                 /* important: ensure null-termination of the key string */
961                 secrets_key = talloc_strndup(tmp_ctx,
962                                              (const char *)k->node_key.dptr,
963                                              k->node_key.dsize);
964                 if (!secrets_key) {
965                         DEBUG(0, ("strndup failed!\n"));
966                         tdb_search_list_free(keys);
967                         TALLOC_FREE(tmp_ctx);
968                         return NT_STATUS_NO_MEMORY;
969                 }
970
971                 packed_pass = (uint8 *)secrets_fetch(secrets_key, &size);
972                 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
973                                                           &pass);
974                 /* packed representation isn't needed anymore */
975                 SAFE_FREE(packed_pass);
976
977                 if (size != packed_size) {
978                         DEBUG(2, ("Secrets record %s is invalid!\n",
979                                   secrets_key));
980                         continue;
981                 }
982
983                 if (pass.domain_sid.num_auths != 4) {
984                         DEBUG(0, ("SID %s is not a domain sid, has %d "
985                                   "auths instead of 4\n",
986                                   sid_string_dbg(&pass.domain_sid),
987                                   pass.domain_sid.num_auths));
988                         continue;
989                 }
990
991                 if (!(dom_info = TALLOC_P(*domains, struct trustdom_info))) {
992                         DEBUG(0, ("talloc failed\n"));
993                         tdb_search_list_free(keys);
994                         TALLOC_FREE(tmp_ctx);
995                         return NT_STATUS_NO_MEMORY;
996                 }
997
998                 if (pull_ucs2_talloc(dom_info, &dom_info->name,
999                                      pass.uni_name) == (size_t)-1) {
1000                         DEBUG(2, ("pull_ucs2_talloc failed\n"));
1001                         tdb_search_list_free(keys);
1002                         TALLOC_FREE(tmp_ctx);
1003                         return NT_STATUS_NO_MEMORY;
1004                 }
1005
1006                 sid_copy(&dom_info->sid, &pass.domain_sid);
1007
1008                 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
1009                              domains, num_domains);
1010
1011                 if (*domains == NULL) {
1012                         tdb_search_list_free(keys);
1013                         TALLOC_FREE(tmp_ctx);
1014                         return NT_STATUS_NO_MEMORY;
1015                 }
1016         }
1017
1018         DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
1019                   *num_domains));
1020
1021         /* free the results of searching the keys */
1022         tdb_search_list_free(keys);
1023         TALLOC_FREE(tmp_ctx);
1024
1025         return NT_STATUS_OK;
1026 }
1027
1028 /*******************************************************************************
1029  Lock the secrets tdb based on a string - this is used as a primitive form of mutex
1030  between smbd instances.
1031 *******************************************************************************/
1032
1033 bool secrets_named_mutex(const char *name, unsigned int timeout)
1034 {
1035         int ret = 0;
1036
1037         if (!secrets_init())
1038                 return False;
1039
1040         ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
1041         if (ret == 0)
1042                 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
1043
1044         return (ret == 0);
1045 }
1046
1047 /*******************************************************************************
1048  Unlock a named mutex.
1049 *******************************************************************************/
1050
1051 void secrets_named_mutex_release(const char *name)
1052 {
1053         tdb_unlock_bystring(tdb, name);
1054         DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
1055 }
1056
1057 /*******************************************************************************
1058  Store a complete AFS keyfile into secrets.tdb.
1059 *******************************************************************************/
1060
1061 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1062 {
1063         fstring key;
1064
1065         if ((cell == NULL) || (keyfile == NULL))
1066                 return False;
1067
1068         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1069                 return False;
1070
1071         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1072         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1073 }
1074
1075 /*******************************************************************************
1076  Fetch the current (highest) AFS key from secrets.tdb
1077 *******************************************************************************/
1078 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1079 {
1080         fstring key;
1081         struct afs_keyfile *keyfile;
1082         size_t size = 0;
1083         uint32 i;
1084
1085         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1086
1087         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1088
1089         if (keyfile == NULL)
1090                 return False;
1091
1092         if (size != sizeof(struct afs_keyfile)) {
1093                 SAFE_FREE(keyfile);
1094                 return False;
1095         }
1096
1097         i = ntohl(keyfile->nkeys);
1098
1099         if (i > SECRETS_AFS_MAXKEYS) {
1100                 SAFE_FREE(keyfile);
1101                 return False;
1102         }
1103
1104         *result = keyfile->entry[i-1];
1105
1106         result->kvno = ntohl(result->kvno);
1107
1108         return True;
1109 }
1110
1111 /******************************************************************************
1112   When kerberos is not available, choose between anonymous or
1113   authenticated connections.
1114
1115   We need to use an authenticated connection if DCs have the
1116   RestrictAnonymous registry entry set > 0, or the "Additional
1117   restrictions for anonymous connections" set in the win2k Local
1118   Security Policy.
1119
1120   Caller to free() result in domain, username, password
1121 *******************************************************************************/
1122 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1123 {
1124         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1125         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1126         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1127
1128         if (*username && **username) {
1129
1130                 if (!*domain || !**domain)
1131                         *domain = smb_xstrdup(lp_workgroup());
1132
1133                 if (!*password || !**password)
1134                         *password = smb_xstrdup("");
1135
1136                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1137                           *domain, *username));
1138
1139         } else {
1140                 DEBUG(3, ("IPC$ connections done anonymously\n"));
1141                 *username = smb_xstrdup("");
1142                 *domain = smb_xstrdup("");
1143                 *password = smb_xstrdup("");
1144         }
1145 }
1146
1147 /******************************************************************************
1148  Open or create the schannel session store tdb.
1149 *******************************************************************************/
1150
1151 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1152 {
1153         TDB_DATA vers;
1154         uint32 ver;
1155         TDB_CONTEXT *tdb_sc = NULL;
1156         char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1157
1158         if (!fname) {
1159                 return NULL;
1160         }
1161
1162         tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1163
1164         if (!tdb_sc) {
1165                 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1166                 TALLOC_FREE(fname);
1167                 return NULL;
1168         }
1169
1170         vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1171         if (vers.dptr == NULL) {
1172                 /* First opener, no version. */
1173                 SIVAL(&ver,0,1);
1174                 vers.dptr = (uint8 *)&ver;
1175                 vers.dsize = 4;
1176                 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1177                 vers.dptr = NULL;
1178         } else if (vers.dsize == 4) {
1179                 ver = IVAL(vers.dptr,0);
1180                 if (ver != 1) {
1181                         tdb_close(tdb_sc);
1182                         tdb_sc = NULL;
1183                         DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1184                                 (int)ver, fname ));
1185                 }
1186         } else {
1187                 tdb_close(tdb_sc);
1188                 tdb_sc = NULL;
1189                 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1190                         (int)vers.dsize, fname ));
1191         }
1192
1193         SAFE_FREE(vers.dptr);
1194         TALLOC_FREE(fname);
1195
1196         return tdb_sc;
1197 }
1198
1199 /******************************************************************************
1200  Store the schannel state after an AUTH2 call.
1201  Note we must be root here.
1202 *******************************************************************************/
1203
1204 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1205                                 const char *remote_machine,
1206                                 const struct dcinfo *pdc)
1207 {
1208         TDB_CONTEXT *tdb_sc = NULL;
1209         TDB_DATA value;
1210         bool ret;
1211         char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1212                                 remote_machine);
1213         if (!keystr) {
1214                 return False;
1215         }
1216
1217         strupper_m(keystr);
1218
1219         /* Work out how large the record is. */
1220         value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1221                                 pdc->sequence,
1222                                 8, pdc->seed_chal.data,
1223                                 8, pdc->clnt_chal.data,
1224                                 8, pdc->srv_chal.data,
1225                                 16, pdc->sess_key,
1226                                 16, pdc->mach_pw,
1227                                 pdc->mach_acct,
1228                                 pdc->remote_machine,
1229                                 pdc->domain);
1230
1231         value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1232         if (!value.dptr) {
1233                 TALLOC_FREE(keystr);
1234                 return False;
1235         }
1236
1237         value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1238                                 pdc->sequence,
1239                                 8, pdc->seed_chal.data,
1240                                 8, pdc->clnt_chal.data,
1241                                 8, pdc->srv_chal.data,
1242                                 16, pdc->sess_key,
1243                                 16, pdc->mach_pw,
1244                                 pdc->mach_acct,
1245                                 pdc->remote_machine,
1246                                 pdc->domain);
1247
1248         tdb_sc = open_schannel_session_store(mem_ctx);
1249         if (!tdb_sc) {
1250                 TALLOC_FREE(keystr);
1251                 TALLOC_FREE(value.dptr);
1252                 return False;
1253         }
1254
1255         ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1256
1257         DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1258                 keystr ));
1259
1260         tdb_close(tdb_sc);
1261         TALLOC_FREE(keystr);
1262         TALLOC_FREE(value.dptr);
1263         return ret;
1264 }
1265
1266 /******************************************************************************
1267  Restore the schannel state on a client reconnect.
1268  Note we must be root here.
1269 *******************************************************************************/
1270
1271 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1272                                 const char *remote_machine,
1273                                 struct dcinfo **ppdc)
1274 {
1275         TDB_CONTEXT *tdb_sc = NULL;
1276         TDB_DATA value;
1277         unsigned char *pseed_chal = NULL;
1278         unsigned char *pclnt_chal = NULL;
1279         unsigned char *psrv_chal = NULL;
1280         unsigned char *psess_key = NULL;
1281         unsigned char *pmach_pw = NULL;
1282         uint32 l1, l2, l3, l4, l5;
1283         int ret;
1284         struct dcinfo *pdc = NULL;
1285         char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1286                                 remote_machine);
1287
1288         *ppdc = NULL;
1289
1290         if (!keystr) {
1291                 return False;
1292         }
1293
1294         strupper_m(keystr);
1295
1296         tdb_sc = open_schannel_session_store(mem_ctx);
1297         if (!tdb_sc) {
1298                 TALLOC_FREE(keystr);
1299                 return False;
1300         }
1301
1302         value = tdb_fetch_bystring(tdb_sc, keystr);
1303         if (!value.dptr) {
1304                 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1305                         keystr ));
1306                 tdb_close(tdb_sc);
1307                 return False;
1308         }
1309
1310         pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1311
1312         /* Retrieve the record. */
1313         ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1314                                 &pdc->sequence,
1315                                 &l1, &pseed_chal,
1316                                 &l2, &pclnt_chal,
1317                                 &l3, &psrv_chal,
1318                                 &l4, &psess_key,
1319                                 &l5, &pmach_pw,
1320                                 &pdc->mach_acct,
1321                                 &pdc->remote_machine,
1322                                 &pdc->domain);
1323
1324         if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1325                 /* Bad record - delete it. */
1326                 tdb_delete_bystring(tdb_sc, keystr);
1327                 tdb_close(tdb_sc);
1328                 TALLOC_FREE(keystr);
1329                 TALLOC_FREE(pdc);
1330                 SAFE_FREE(pseed_chal);
1331                 SAFE_FREE(pclnt_chal);
1332                 SAFE_FREE(psrv_chal);
1333                 SAFE_FREE(psess_key);
1334                 SAFE_FREE(pmach_pw);
1335                 SAFE_FREE(value.dptr);
1336                 return False;
1337         }
1338
1339         tdb_close(tdb_sc);
1340
1341         memcpy(pdc->seed_chal.data, pseed_chal, 8);
1342         memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1343         memcpy(pdc->srv_chal.data, psrv_chal, 8);
1344         memcpy(pdc->sess_key, psess_key, 16);
1345         memcpy(pdc->mach_pw, pmach_pw, 16);
1346
1347         /* We know these are true so didn't bother to store them. */
1348         pdc->challenge_sent = True;
1349         pdc->authenticated = True;
1350
1351         DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1352                 keystr ));
1353
1354         SAFE_FREE(pseed_chal);
1355         SAFE_FREE(pclnt_chal);
1356         SAFE_FREE(psrv_chal);
1357         SAFE_FREE(psess_key);
1358         SAFE_FREE(pmach_pw);
1359
1360         TALLOC_FREE(keystr);
1361         SAFE_FREE(value.dptr);
1362
1363         *ppdc = pdc;
1364
1365         return True;
1366 }
1367
1368 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1369 {
1370         char *tdbkey = NULL;
1371         bool ret;
1372
1373         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1374                 DEBUG(0, ("asprintf failed!\n"));
1375                 return False;
1376         }
1377
1378         ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1379
1380         SAFE_FREE(tdbkey);
1381         return ret;
1382 }
1383
1384 /*******************************************************************
1385  Find the ldap password.
1386 ******************************************************************/
1387
1388 char *secrets_fetch_generic(const char *owner, const char *key)
1389 {
1390         char *secret = NULL;
1391         char *tdbkey = NULL;
1392
1393         if (( ! owner) || ( ! key)) {
1394                 DEBUG(1, ("Invalid Paramters"));
1395                 return NULL;
1396         }
1397
1398         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1399                 DEBUG(0, ("Out of memory!\n"));
1400                 return NULL;
1401         }
1402
1403         secret = (char *)secrets_fetch(tdbkey, NULL);
1404         SAFE_FREE(tdbkey);
1405
1406         return secret;
1407 }
1408