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