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