Cleanup size_t return values in callers of convert_string_allocate
[ira/wip.git] / source3 / passdb / secrets.c
1 /*
2    Unix SMB/CIFS implementation.
3    Copyright (C) Andrew Tridgell 1992-2001
4    Copyright (C) Andrew Bartlett      2002
5    Copyright (C) Rafal Szczesniak     2002
6    Copyright (C) Tim Potter           2001
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 /* the Samba secrets database stores any generated, private information
23    such as the local SID and machine trust password */
24
25 #include "includes.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_PASSDB
29
30 static 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         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                 return False;
403         }
404
405         if (pass_last_set_time) {
406                 *pass_last_set_time = pass->mod_time;
407         }
408         memcpy(ret_pwd, pass->hash, 16);
409
410         if (channel) {
411                 *channel = get_default_sec_channel();
412         }
413
414         /* Test if machine password has expired and needs to be changed */
415         if (lp_machine_password_timeout()) {
416                 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
417                                 (time_t)lp_machine_password_timeout())) {
418                         global_machine_password_needs_changing = True;
419                 }
420         }
421
422         SAFE_FREE(pass);
423         return True;
424 }
425
426 /************************************************************************
427  Routine to get the trust account password for a domain.
428  The user of this function must have locked the trust password file using
429  the above secrets_lock_trust_account_password().
430 ************************************************************************/
431
432 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
433                                           time_t *pass_last_set_time,
434                                           uint32 *channel)
435 {
436         char *plaintext;
437
438         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
439                                                    channel);
440         if (plaintext) {
441                 DEBUG(4,("Using cleartext machine password\n"));
442                 E_md4hash(plaintext, ret_pwd);
443                 SAFE_FREE(plaintext);
444                 return True;
445         }
446
447         return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
448                                                            pass_last_set_time,
449                                                            channel);
450 }
451
452 /**
453  * Pack SID passed by pointer
454  *
455  * @param pack_buf pointer to buffer which is to be filled with packed data
456  * @param bufsize size of packing buffer
457  * @param sid pointer to sid to be packed
458  *
459  * @return length of the packed representation of the whole structure
460  **/
461 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
462 {
463         int idx;
464         size_t len = 0;
465         uint8 *p = pack_buf;
466         int remaining_space = pack_buf ? bufsize : 0;
467
468         if (!sid) {
469                 return -1;
470         }
471
472         len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
473                         sid->num_auths);
474         if (pack_buf) {
475                 p = pack_buf + len;
476                 remaining_space = bufsize - len;
477         }
478
479         for (idx = 0; idx < 6; idx++) {
480                 len += tdb_pack(p, remaining_space, "b",
481                                 sid->id_auth[idx]);
482                 if (pack_buf) {
483                         p = pack_buf + len;
484                         remaining_space = bufsize - len;
485                 }
486         }
487
488         for (idx = 0; idx < MAXSUBAUTHS; idx++) {
489                 len += tdb_pack(p, remaining_space, "d",
490                                 sid->sub_auths[idx]);
491                 if (pack_buf) {
492                         p = pack_buf + len;
493                         remaining_space = bufsize - len;
494                 }
495         }
496
497         return len;
498 }
499
500 /**
501  * Unpack SID into a pointer
502  *
503  * @param pack_buf pointer to buffer with packed representation
504  * @param bufsize size of the buffer
505  * @param sid pointer to sid structure to be filled with unpacked data
506  *
507  * @return size of structure unpacked from buffer
508  **/
509 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
510 {
511         int idx, len = 0;
512
513         if (!sid || !pack_buf) return -1;
514
515         len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
516                           &sid->sid_rev_num, &sid->num_auths);
517
518         for (idx = 0; idx < 6; idx++) {
519                 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
520                                   &sid->id_auth[idx]);
521         }
522
523         for (idx = 0; idx < MAXSUBAUTHS; idx++) {
524                 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
525                                   &sid->sub_auths[idx]);
526         }
527
528         return len;
529 }
530
531 /**
532  * Pack TRUSTED_DOM_PASS passed by pointer
533  *
534  * @param pack_buf pointer to buffer which is to be filled with packed data
535  * @param bufsize size of the buffer
536  * @param pass pointer to trusted domain password to be packed
537  *
538  * @return length of the packed representation of the whole structure
539  **/
540 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
541                                         TRUSTED_DOM_PASS* pass)
542 {
543         int idx, len = 0;
544         uint8 *p = pack_buf;
545         int remaining_space = pack_buf ? bufsize : 0;
546
547         if (!pass) {
548                 return -1;
549         }
550
551         /* packing unicode domain name and password */
552         len += tdb_pack(p, remaining_space, "d",
553                         pass->uni_name_len);
554         if (pack_buf) {
555                 p = pack_buf + len;
556                 remaining_space = bufsize - len;
557         }
558
559         for (idx = 0; idx < 32; idx++) {
560                 len += tdb_pack(p, remaining_space, "w",
561                                  pass->uni_name[idx]);
562                 if (pack_buf) {
563                         p = pack_buf + len;
564                         remaining_space = bufsize - len;
565                 }
566         }
567
568         len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
569                              pass->pass, pass->mod_time);
570         if (pack_buf) {
571                 p = pack_buf + len;
572                 remaining_space = bufsize - len;
573         }
574
575         /* packing SID structure */
576         len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
577         if (pack_buf) {
578                 p = pack_buf + len;
579                 remaining_space = bufsize - len;
580         }
581
582         return len;
583 }
584
585
586 /**
587  * Unpack TRUSTED_DOM_PASS passed by pointer
588  *
589  * @param pack_buf pointer to buffer with packed representation
590  * @param bufsize size of the buffer
591  * @param pass pointer to trusted domain password to be filled with unpacked data
592  *
593  * @return size of structure unpacked from buffer
594  **/
595 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
596                                           TRUSTED_DOM_PASS* pass)
597 {
598         int idx, len = 0;
599         char *passp = NULL;
600
601         if (!pack_buf || !pass) return -1;
602
603         /* unpack unicode domain name and plaintext password */
604         len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
605
606         for (idx = 0; idx < 32; idx++)
607                 len +=  tdb_unpack(pack_buf + len, bufsize - len, "w",
608                                    &pass->uni_name[idx]);
609
610         len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
611                           &pass->pass_len, &passp, &pass->mod_time);
612         if (passp) {
613                 fstrcpy(pass->pass, passp);
614         }
615         SAFE_FREE(passp);
616
617         /* unpack domain sid */
618         len += tdb_sid_unpack(pack_buf + len, bufsize - len,
619                               &pass->domain_sid);
620
621         return len;
622 }
623
624 /************************************************************************
625  Routine to get account password to trusted domain
626 ************************************************************************/
627
628 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
629                                            DOM_SID *sid, time_t *pass_last_set_time)
630 {
631         struct trusted_dom_pass pass;
632         size_t size = 0;
633
634         /* unpacking structures */
635         uint8 *pass_buf;
636         int pass_len = 0;
637
638         ZERO_STRUCT(pass);
639
640         /* fetching trusted domain password structure */
641         if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
642                                                &size))) {
643                 DEBUG(5, ("secrets_fetch failed!\n"));
644                 return False;
645         }
646
647         /* unpack trusted domain password */
648         pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
649         SAFE_FREE(pass_buf);
650
651         if (pass_len != size) {
652                 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
653                 return False;
654         }
655
656         /* the trust's password */
657         if (pwd) {
658                 *pwd = SMB_STRDUP(pass.pass);
659                 if (!*pwd) {
660                         return False;
661                 }
662         }
663
664         /* last change time */
665         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
666
667         /* domain sid */
668         if (sid != NULL) sid_copy(sid, &pass.domain_sid);
669
670         return True;
671 }
672
673 /**
674  * Routine to store the password for trusted domain
675  *
676  * @param domain remote domain name
677  * @param pwd plain text password of trust relationship
678  * @param sid remote domain sid
679  *
680  * @return true if succeeded
681  **/
682
683 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
684                                            const DOM_SID *sid)
685 {
686         smb_ucs2_t *uni_dom_name;
687         bool ret;
688         size_t converted_size;
689
690         /* packing structures */
691         uint8 *pass_buf = NULL;
692         int pass_len = 0;
693
694         struct trusted_dom_pass pass;
695         ZERO_STRUCT(pass);
696
697         if (!push_ucs2_allocate(&uni_dom_name, domain, &converted_size)) {
698                 DEBUG(0, ("Could not convert domain name %s to unicode\n",
699                           domain));
700                 return False;
701         }
702
703         strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
704         pass.uni_name_len = strlen_w(uni_dom_name)+1;
705         SAFE_FREE(uni_dom_name);
706
707         /* last change time */
708         pass.mod_time = time(NULL);
709
710         /* password of the trust */
711         pass.pass_len = strlen(pwd);
712         fstrcpy(pass.pass, pwd);
713
714         /* domain sid */
715         sid_copy(&pass.domain_sid, sid);
716
717         /* Calculate the length. */
718         pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
719         pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
720         if (!pass_buf) {
721                 return false;
722         }
723         pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
724         ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
725                         pass_len);
726         SAFE_FREE(pass_buf);
727         return ret;
728 }
729
730 /************************************************************************
731  Routine to delete the plaintext machine account password
732 ************************************************************************/
733
734 bool secrets_delete_machine_password(const char *domain)
735 {
736         return secrets_delete(machine_password_keystr(domain));
737 }
738
739 /************************************************************************
740  Routine to delete the plaintext machine account password, sec channel type and
741  last change time from secrets database
742 ************************************************************************/
743
744 bool secrets_delete_machine_password_ex(const char *domain)
745 {
746         if (!secrets_delete(machine_password_keystr(domain))) {
747                 return false;
748         }
749         if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
750                 return false;
751         }
752         return secrets_delete(machine_last_change_time_keystr(domain));
753 }
754
755 /************************************************************************
756  Routine to delete the domain sid
757 ************************************************************************/
758
759 bool secrets_delete_domain_sid(const char *domain)
760 {
761         return secrets_delete(domain_sid_keystr(domain));
762 }
763
764 /************************************************************************
765  Routine to set the plaintext machine account password for a realm
766 the password is assumed to be a null terminated ascii string
767 ************************************************************************/
768
769 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
770 {
771         bool ret;
772         uint32 last_change_time;
773         uint32 sec_channel_type;
774
775         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
776         if (!ret)
777                 return ret;
778
779         SIVAL(&last_change_time, 0, time(NULL));
780         ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
781
782         SIVAL(&sec_channel_type, 0, sec_channel);
783         ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
784
785         return ret;
786 }
787
788 /************************************************************************
789  Routine to fetch the plaintext machine account password for a realm
790  the password is assumed to be a null terminated ascii string.
791 ************************************************************************/
792
793 char *secrets_fetch_machine_password(const char *domain,
794                                      time_t *pass_last_set_time,
795                                      uint32 *channel)
796 {
797         char *ret;
798         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
799
800         if (pass_last_set_time) {
801                 size_t size;
802                 uint32 *last_set_time;
803                 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
804                 if (last_set_time) {
805                         *pass_last_set_time = IVAL(last_set_time,0);
806                         SAFE_FREE(last_set_time);
807                 } else {
808                         *pass_last_set_time = 0;
809                 }
810         }
811
812         if (channel) {
813                 size_t size;
814                 uint32 *channel_type;
815                 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
816                 if (channel_type) {
817                         *channel = IVAL(channel_type,0);
818                         SAFE_FREE(channel_type);
819                 } else {
820                         *channel = get_default_sec_channel();
821                 }
822         }
823
824         return ret;
825 }
826
827 /************************************************************************
828  Routine to delete the password for trusted domain
829 ************************************************************************/
830
831 bool trusted_domain_password_delete(const char *domain)
832 {
833         return secrets_delete(trustdom_keystr(domain));
834 }
835
836 bool secrets_store_ldap_pw(const char* dn, char* pw)
837 {
838         char *key = NULL;
839         bool ret;
840
841         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
842                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
843                 return False;
844         }
845
846         ret = secrets_store(key, pw, strlen(pw)+1);
847
848         SAFE_FREE(key);
849         return ret;
850 }
851
852 /*******************************************************************
853  Find the ldap password.
854 ******************************************************************/
855
856 bool fetch_ldap_pw(char **dn, char** pw)
857 {
858         char *key = NULL;
859         size_t size = 0;
860
861         *dn = smb_xstrdup(lp_ldap_admin_dn());
862
863         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
864                 SAFE_FREE(*dn);
865                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
866         }
867
868         *pw=(char *)secrets_fetch(key, &size);
869         SAFE_FREE(key);
870
871         if (!size) {
872                 /* Upgrade 2.2 style entry */
873                 char *p;
874                 char* old_style_key = SMB_STRDUP(*dn);
875                 char *data;
876                 fstring old_style_pw;
877
878                 if (!old_style_key) {
879                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
880                         return False;
881                 }
882
883                 for (p=old_style_key; *p; p++)
884                         if (*p == ',') *p = '/';
885
886                 data=(char *)secrets_fetch(old_style_key, &size);
887                 if (!size && size < sizeof(old_style_pw)) {
888                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
889                         SAFE_FREE(old_style_key);
890                         SAFE_FREE(*dn);
891                         return False;
892                 }
893
894                 size = MIN(size, sizeof(fstring)-1);
895                 strncpy(old_style_pw, data, size);
896                 old_style_pw[size] = 0;
897
898                 SAFE_FREE(data);
899
900                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
901                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
902                         SAFE_FREE(old_style_key);
903                         SAFE_FREE(*dn);
904                         return False;
905                 }
906                 if (!secrets_delete(old_style_key)) {
907                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
908                 }
909
910                 SAFE_FREE(old_style_key);
911
912                 *pw = smb_xstrdup(old_style_pw);
913         }
914
915         return True;
916 }
917
918 /**
919  * Get trusted domains info from secrets.tdb.
920  **/
921
922 struct list_trusted_domains_state {
923         uint32 num_domains;
924         struct trustdom_info **domains;
925 };
926
927 static int list_trusted_domain(struct db_record *rec, void *private_data)
928 {
929         const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
930         size_t converted_size, packed_size = 0;
931         struct trusted_dom_pass pass;
932         struct trustdom_info *dom_info;
933
934         struct list_trusted_domains_state *state =
935                 (struct list_trusted_domains_state *)private_data;
936
937         if ((rec->key.dsize < prefix_len)
938             || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
939                         prefix_len) != 0)) {
940                 return 0;
941         }
942
943         packed_size = tdb_trusted_dom_pass_unpack(
944                 rec->value.dptr, rec->value.dsize, &pass);
945
946         if (rec->value.dsize != packed_size) {
947                 DEBUG(2, ("Secrets record is invalid!\n"));
948                 return 0;
949         }
950
951         if (pass.domain_sid.num_auths != 4) {
952                 DEBUG(0, ("SID %s is not a domain sid, has %d "
953                           "auths instead of 4\n",
954                           sid_string_dbg(&pass.domain_sid),
955                           pass.domain_sid.num_auths));
956                 return 0;
957         }
958
959         if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
960                 DEBUG(0, ("talloc failed\n"));
961                 return 0;
962         }
963
964         if (!pull_ucs2_talloc(dom_info, &dom_info->name, pass.uni_name,
965                               &converted_size)) {
966                 DEBUG(2, ("pull_ucs2_talloc failed\n"));
967                 TALLOC_FREE(dom_info);
968                 return 0;
969         }
970
971         sid_copy(&dom_info->sid, &pass.domain_sid);
972
973         ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
974                      &state->domains, &state->num_domains);
975
976         if (state->domains == NULL) {
977                 state->num_domains = 0;
978                 return -1;
979         }
980         return 0;
981 }
982
983 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
984                                  struct trustdom_info ***domains)
985 {
986         struct list_trusted_domains_state state;
987
988         secrets_init();
989
990         if (db_ctx == NULL) {
991                 return NT_STATUS_ACCESS_DENIED;
992         }
993
994         state.num_domains = 0;
995
996         /*
997          * Make sure that a talloc context for the trustdom_info structs
998          * exists
999          */
1000
1001         if (!(state.domains = TALLOC_ARRAY(
1002                       mem_ctx, struct trustdom_info *, 1))) {
1003                 return NT_STATUS_NO_MEMORY;
1004         }
1005
1006         db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
1007
1008         *num_domains = state.num_domains;
1009         *domains = state.domains;
1010         return NT_STATUS_OK;
1011 }
1012
1013 /*******************************************************************************
1014  Store a complete AFS keyfile into secrets.tdb.
1015 *******************************************************************************/
1016
1017 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1018 {
1019         fstring key;
1020
1021         if ((cell == NULL) || (keyfile == NULL))
1022                 return False;
1023
1024         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1025                 return False;
1026
1027         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1028         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1029 }
1030
1031 /*******************************************************************************
1032  Fetch the current (highest) AFS key from secrets.tdb
1033 *******************************************************************************/
1034 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1035 {
1036         fstring key;
1037         struct afs_keyfile *keyfile;
1038         size_t size = 0;
1039         uint32 i;
1040
1041         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1042
1043         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1044
1045         if (keyfile == NULL)
1046                 return False;
1047
1048         if (size != sizeof(struct afs_keyfile)) {
1049                 SAFE_FREE(keyfile);
1050                 return False;
1051         }
1052
1053         i = ntohl(keyfile->nkeys);
1054
1055         if (i > SECRETS_AFS_MAXKEYS) {
1056                 SAFE_FREE(keyfile);
1057                 return False;
1058         }
1059
1060         *result = keyfile->entry[i-1];
1061
1062         result->kvno = ntohl(result->kvno);
1063
1064         return True;
1065 }
1066
1067 /******************************************************************************
1068   When kerberos is not available, choose between anonymous or
1069   authenticated connections.
1070
1071   We need to use an authenticated connection if DCs have the
1072   RestrictAnonymous registry entry set > 0, or the "Additional
1073   restrictions for anonymous connections" set in the win2k Local
1074   Security Policy.
1075
1076   Caller to free() result in domain, username, password
1077 *******************************************************************************/
1078 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1079 {
1080         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1081         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1082         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1083
1084         if (*username && **username) {
1085
1086                 if (!*domain || !**domain)
1087                         *domain = smb_xstrdup(lp_workgroup());
1088
1089                 if (!*password || !**password)
1090                         *password = smb_xstrdup("");
1091
1092                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1093                           *domain, *username));
1094
1095         } else {
1096                 DEBUG(3, ("IPC$ connections done anonymously\n"));
1097                 *username = smb_xstrdup("");
1098                 *domain = smb_xstrdup("");
1099                 *password = smb_xstrdup("");
1100         }
1101 }
1102
1103 /******************************************************************************
1104  Open or create the schannel session store tdb.
1105 *******************************************************************************/
1106
1107 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1108 {
1109         TDB_DATA vers;
1110         uint32 ver;
1111         TDB_CONTEXT *tdb_sc = NULL;
1112         char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1113
1114         if (!fname) {
1115                 return NULL;
1116         }
1117
1118         tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1119
1120         if (!tdb_sc) {
1121                 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1122                 TALLOC_FREE(fname);
1123                 return NULL;
1124         }
1125
1126         vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1127         if (vers.dptr == NULL) {
1128                 /* First opener, no version. */
1129                 SIVAL(&ver,0,1);
1130                 vers.dptr = (uint8 *)&ver;
1131                 vers.dsize = 4;
1132                 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1133                 vers.dptr = NULL;
1134         } else if (vers.dsize == 4) {
1135                 ver = IVAL(vers.dptr,0);
1136                 if (ver != 1) {
1137                         tdb_close(tdb_sc);
1138                         tdb_sc = NULL;
1139                         DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1140                                 (int)ver, fname ));
1141                 }
1142         } else {
1143                 tdb_close(tdb_sc);
1144                 tdb_sc = NULL;
1145                 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1146                         (int)vers.dsize, fname ));
1147         }
1148
1149         SAFE_FREE(vers.dptr);
1150         TALLOC_FREE(fname);
1151
1152         return tdb_sc;
1153 }
1154
1155 /******************************************************************************
1156  Store the schannel state after an AUTH2 call.
1157  Note we must be root here.
1158 *******************************************************************************/
1159
1160 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1161                                 const char *remote_machine,
1162                                 const struct dcinfo *pdc)
1163 {
1164         TDB_CONTEXT *tdb_sc = NULL;
1165         TDB_DATA value;
1166         bool ret;
1167         char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1168                                                   SECRETS_SCHANNEL_STATE,
1169                                                   remote_machine);
1170         if (!keystr) {
1171                 return False;
1172         }
1173
1174         /* Work out how large the record is. */
1175         value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1176                                 pdc->sequence,
1177                                 8, pdc->seed_chal.data,
1178                                 8, pdc->clnt_chal.data,
1179                                 8, pdc->srv_chal.data,
1180                                 16, pdc->sess_key,
1181                                 16, pdc->mach_pw,
1182                                 pdc->mach_acct,
1183                                 pdc->remote_machine,
1184                                 pdc->domain);
1185
1186         value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1187         if (!value.dptr) {
1188                 TALLOC_FREE(keystr);
1189                 return False;
1190         }
1191
1192         value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1193                                 pdc->sequence,
1194                                 8, pdc->seed_chal.data,
1195                                 8, pdc->clnt_chal.data,
1196                                 8, pdc->srv_chal.data,
1197                                 16, pdc->sess_key,
1198                                 16, pdc->mach_pw,
1199                                 pdc->mach_acct,
1200                                 pdc->remote_machine,
1201                                 pdc->domain);
1202
1203         tdb_sc = open_schannel_session_store(mem_ctx);
1204         if (!tdb_sc) {
1205                 TALLOC_FREE(keystr);
1206                 TALLOC_FREE(value.dptr);
1207                 return False;
1208         }
1209
1210         ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1211
1212         DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1213                 keystr ));
1214
1215         tdb_close(tdb_sc);
1216         TALLOC_FREE(keystr);
1217         TALLOC_FREE(value.dptr);
1218         return ret;
1219 }
1220
1221 /******************************************************************************
1222  Restore the schannel state on a client reconnect.
1223  Note we must be root here.
1224 *******************************************************************************/
1225
1226 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1227                                 const char *remote_machine,
1228                                 struct dcinfo **ppdc)
1229 {
1230         TDB_CONTEXT *tdb_sc = NULL;
1231         TDB_DATA value;
1232         unsigned char *pseed_chal = NULL;
1233         unsigned char *pclnt_chal = NULL;
1234         unsigned char *psrv_chal = NULL;
1235         unsigned char *psess_key = NULL;
1236         unsigned char *pmach_pw = NULL;
1237         uint32 l1, l2, l3, l4, l5;
1238         int ret;
1239         struct dcinfo *pdc = NULL;
1240         char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1241                                                   SECRETS_SCHANNEL_STATE,
1242                                                   remote_machine);
1243
1244         *ppdc = NULL;
1245
1246         if (!keystr) {
1247                 return False;
1248         }
1249
1250         tdb_sc = open_schannel_session_store(mem_ctx);
1251         if (!tdb_sc) {
1252                 TALLOC_FREE(keystr);
1253                 return False;
1254         }
1255
1256         value = tdb_fetch_bystring(tdb_sc, keystr);
1257         if (!value.dptr) {
1258                 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1259                         keystr ));
1260                 tdb_close(tdb_sc);
1261                 return False;
1262         }
1263
1264         pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1265
1266         /* Retrieve the record. */
1267         ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1268                                 &pdc->sequence,
1269                                 &l1, &pseed_chal,
1270                                 &l2, &pclnt_chal,
1271                                 &l3, &psrv_chal,
1272                                 &l4, &psess_key,
1273                                 &l5, &pmach_pw,
1274                                 &pdc->mach_acct,
1275                                 &pdc->remote_machine,
1276                                 &pdc->domain);
1277
1278         if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1279                 /* Bad record - delete it. */
1280                 tdb_delete_bystring(tdb_sc, keystr);
1281                 tdb_close(tdb_sc);
1282                 TALLOC_FREE(keystr);
1283                 TALLOC_FREE(pdc);
1284                 SAFE_FREE(pseed_chal);
1285                 SAFE_FREE(pclnt_chal);
1286                 SAFE_FREE(psrv_chal);
1287                 SAFE_FREE(psess_key);
1288                 SAFE_FREE(pmach_pw);
1289                 SAFE_FREE(value.dptr);
1290                 return False;
1291         }
1292
1293         tdb_close(tdb_sc);
1294
1295         memcpy(pdc->seed_chal.data, pseed_chal, 8);
1296         memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1297         memcpy(pdc->srv_chal.data, psrv_chal, 8);
1298         memcpy(pdc->sess_key, psess_key, 16);
1299         memcpy(pdc->mach_pw, pmach_pw, 16);
1300
1301         /* We know these are true so didn't bother to store them. */
1302         pdc->challenge_sent = True;
1303         pdc->authenticated = True;
1304
1305         DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1306                 keystr ));
1307
1308         SAFE_FREE(pseed_chal);
1309         SAFE_FREE(pclnt_chal);
1310         SAFE_FREE(psrv_chal);
1311         SAFE_FREE(psess_key);
1312         SAFE_FREE(pmach_pw);
1313
1314         TALLOC_FREE(keystr);
1315         SAFE_FREE(value.dptr);
1316
1317         *ppdc = pdc;
1318
1319         return True;
1320 }
1321
1322 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1323 {
1324         char *tdbkey = NULL;
1325         bool ret;
1326
1327         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1328                 DEBUG(0, ("asprintf failed!\n"));
1329                 return False;
1330         }
1331
1332         ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1333
1334         SAFE_FREE(tdbkey);
1335         return ret;
1336 }
1337
1338 /*******************************************************************
1339  Find the ldap password.
1340 ******************************************************************/
1341
1342 char *secrets_fetch_generic(const char *owner, const char *key)
1343 {
1344         char *secret = NULL;
1345         char *tdbkey = NULL;
1346
1347         if (( ! owner) || ( ! key)) {
1348                 DEBUG(1, ("Invalid Paramters"));
1349                 return NULL;
1350         }
1351
1352         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1353                 DEBUG(0, ("Out of memory!\n"));
1354                 return NULL;
1355         }
1356
1357         secret = (char *)secrets_fetch(tdbkey, NULL);
1358         SAFE_FREE(tdbkey);
1359
1360         return secret;
1361 }
1362