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