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