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