s3-passdb: move open_schannel_session_store() to passdb/secrets_schannel.c.
[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 enum netr_SchannelType 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                                                  enum netr_SchannelType *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                                           enum netr_SchannelType *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,
797                                     enum netr_SchannelType sec_channel)
798 {
799         bool ret;
800         uint32 last_change_time;
801         uint32 sec_channel_type;
802
803         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
804         if (!ret)
805                 return ret;
806
807         SIVAL(&last_change_time, 0, time(NULL));
808         ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
809
810         SIVAL(&sec_channel_type, 0, sec_channel);
811         ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
812
813         return ret;
814 }
815
816 /************************************************************************
817  Routine to fetch the plaintext machine account password for a realm
818  the password is assumed to be a null terminated ascii string.
819 ************************************************************************/
820
821 char *secrets_fetch_machine_password(const char *domain,
822                                      time_t *pass_last_set_time,
823                                      enum netr_SchannelType *channel)
824 {
825         char *ret;
826         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
827
828         if (pass_last_set_time) {
829                 size_t size;
830                 uint32 *last_set_time;
831                 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
832                 if (last_set_time) {
833                         *pass_last_set_time = IVAL(last_set_time,0);
834                         SAFE_FREE(last_set_time);
835                 } else {
836                         *pass_last_set_time = 0;
837                 }
838         }
839
840         if (channel) {
841                 size_t size;
842                 uint32 *channel_type;
843                 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
844                 if (channel_type) {
845                         *channel = IVAL(channel_type,0);
846                         SAFE_FREE(channel_type);
847                 } else {
848                         *channel = get_default_sec_channel();
849                 }
850         }
851
852         return ret;
853 }
854
855 /************************************************************************
856  Routine to delete the password for trusted domain
857 ************************************************************************/
858
859 bool trusted_domain_password_delete(const char *domain)
860 {
861         return secrets_delete(trustdom_keystr(domain));
862 }
863
864 bool secrets_store_ldap_pw(const char* dn, char* pw)
865 {
866         char *key = NULL;
867         bool ret;
868
869         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
870                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
871                 return False;
872         }
873
874         ret = secrets_store(key, pw, strlen(pw)+1);
875
876         SAFE_FREE(key);
877         return ret;
878 }
879
880 /*******************************************************************
881  Find the ldap password.
882 ******************************************************************/
883
884 bool fetch_ldap_pw(char **dn, char** pw)
885 {
886         char *key = NULL;
887         size_t size = 0;
888
889         *dn = smb_xstrdup(lp_ldap_admin_dn());
890
891         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
892                 SAFE_FREE(*dn);
893                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
894                 return false;
895         }
896
897         *pw=(char *)secrets_fetch(key, &size);
898         SAFE_FREE(key);
899
900         if (!size) {
901                 /* Upgrade 2.2 style entry */
902                 char *p;
903                 char* old_style_key = SMB_STRDUP(*dn);
904                 char *data;
905                 fstring old_style_pw;
906
907                 if (!old_style_key) {
908                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
909                         return False;
910                 }
911
912                 for (p=old_style_key; *p; p++)
913                         if (*p == ',') *p = '/';
914
915                 data=(char *)secrets_fetch(old_style_key, &size);
916                 if ((data == NULL) || (size < sizeof(old_style_pw))) {
917                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
918                         SAFE_FREE(old_style_key);
919                         SAFE_FREE(*dn);
920                         SAFE_FREE(data);
921                         return False;
922                 }
923
924                 size = MIN(size, sizeof(fstring)-1);
925                 strncpy(old_style_pw, data, size);
926                 old_style_pw[size] = 0;
927
928                 SAFE_FREE(data);
929
930                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
931                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
932                         SAFE_FREE(old_style_key);
933                         SAFE_FREE(*dn);
934                         return False;
935                 }
936                 if (!secrets_delete(old_style_key)) {
937                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
938                 }
939
940                 SAFE_FREE(old_style_key);
941
942                 *pw = smb_xstrdup(old_style_pw);
943         }
944
945         return True;
946 }
947
948 /**
949  * Get trusted domains info from secrets.tdb.
950  **/
951
952 struct list_trusted_domains_state {
953         uint32 num_domains;
954         struct trustdom_info **domains;
955 };
956
957 static int list_trusted_domain(struct db_record *rec, void *private_data)
958 {
959         const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
960         size_t converted_size, packed_size = 0;
961         struct trusted_dom_pass pass;
962         struct trustdom_info *dom_info;
963
964         struct list_trusted_domains_state *state =
965                 (struct list_trusted_domains_state *)private_data;
966
967         if ((rec->key.dsize < prefix_len)
968             || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
969                         prefix_len) != 0)) {
970                 return 0;
971         }
972
973         packed_size = tdb_trusted_dom_pass_unpack(
974                 rec->value.dptr, rec->value.dsize, &pass);
975
976         if (rec->value.dsize != packed_size) {
977                 DEBUG(2, ("Secrets record is invalid!\n"));
978                 return 0;
979         }
980
981         if (pass.domain_sid.num_auths != 4) {
982                 DEBUG(0, ("SID %s is not a domain sid, has %d "
983                           "auths instead of 4\n",
984                           sid_string_dbg(&pass.domain_sid),
985                           pass.domain_sid.num_auths));
986                 return 0;
987         }
988
989         if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
990                 DEBUG(0, ("talloc failed\n"));
991                 return 0;
992         }
993
994         if (!pull_ucs2_talloc(dom_info, &dom_info->name, pass.uni_name,
995                               &converted_size)) {
996                 DEBUG(2, ("pull_ucs2_talloc failed\n"));
997                 TALLOC_FREE(dom_info);
998                 return 0;
999         }
1000
1001         sid_copy(&dom_info->sid, &pass.domain_sid);
1002
1003         ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
1004                      &state->domains, &state->num_domains);
1005
1006         if (state->domains == NULL) {
1007                 state->num_domains = 0;
1008                 return -1;
1009         }
1010         return 0;
1011 }
1012
1013 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
1014                                  struct trustdom_info ***domains)
1015 {
1016         struct list_trusted_domains_state state;
1017
1018         secrets_init();
1019
1020         if (db_ctx == NULL) {
1021                 return NT_STATUS_ACCESS_DENIED;
1022         }
1023
1024         state.num_domains = 0;
1025
1026         /*
1027          * Make sure that a talloc context for the trustdom_info structs
1028          * exists
1029          */
1030
1031         if (!(state.domains = TALLOC_ARRAY(
1032                       mem_ctx, struct trustdom_info *, 1))) {
1033                 return NT_STATUS_NO_MEMORY;
1034         }
1035
1036         db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
1037
1038         *num_domains = state.num_domains;
1039         *domains = state.domains;
1040         return NT_STATUS_OK;
1041 }
1042
1043 /*******************************************************************************
1044  Store a complete AFS keyfile into secrets.tdb.
1045 *******************************************************************************/
1046
1047 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1048 {
1049         fstring key;
1050
1051         if ((cell == NULL) || (keyfile == NULL))
1052                 return False;
1053
1054         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1055                 return False;
1056
1057         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1058         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1059 }
1060
1061 /*******************************************************************************
1062  Fetch the current (highest) AFS key from secrets.tdb
1063 *******************************************************************************/
1064 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1065 {
1066         fstring key;
1067         struct afs_keyfile *keyfile;
1068         size_t size = 0;
1069         uint32 i;
1070
1071         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1072
1073         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1074
1075         if (keyfile == NULL)
1076                 return False;
1077
1078         if (size != sizeof(struct afs_keyfile)) {
1079                 SAFE_FREE(keyfile);
1080                 return False;
1081         }
1082
1083         i = ntohl(keyfile->nkeys);
1084
1085         if (i > SECRETS_AFS_MAXKEYS) {
1086                 SAFE_FREE(keyfile);
1087                 return False;
1088         }
1089
1090         *result = keyfile->entry[i-1];
1091
1092         result->kvno = ntohl(result->kvno);
1093
1094         SAFE_FREE(keyfile);
1095
1096         return True;
1097 }
1098
1099 /******************************************************************************
1100   When kerberos is not available, choose between anonymous or
1101   authenticated connections.
1102
1103   We need to use an authenticated connection if DCs have the
1104   RestrictAnonymous registry entry set > 0, or the "Additional
1105   restrictions for anonymous connections" set in the win2k Local
1106   Security Policy.
1107
1108   Caller to free() result in domain, username, password
1109 *******************************************************************************/
1110 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1111 {
1112         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1113         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1114         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1115
1116         if (*username && **username) {
1117
1118                 if (!*domain || !**domain)
1119                         *domain = smb_xstrdup(lp_workgroup());
1120
1121                 if (!*password || !**password)
1122                         *password = smb_xstrdup("");
1123
1124                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1125                           *domain, *username));
1126
1127         } else {
1128                 DEBUG(3, ("IPC$ connections done anonymously\n"));
1129                 *username = smb_xstrdup("");
1130                 *domain = smb_xstrdup("");
1131                 *password = smb_xstrdup("");
1132         }
1133 }
1134
1135 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1136 {
1137         char *tdbkey = NULL;
1138         bool ret;
1139
1140         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1141                 DEBUG(0, ("asprintf failed!\n"));
1142                 return False;
1143         }
1144
1145         ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1146
1147         SAFE_FREE(tdbkey);
1148         return ret;
1149 }
1150
1151 bool secrets_delete_generic(const char *owner, const char *key)
1152 {
1153         char *tdbkey = NULL;
1154         bool ret;
1155
1156         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1157                 DEBUG(0, ("asprintf failed!\n"));
1158                 return False;
1159         }
1160
1161         ret = secrets_delete(tdbkey);
1162
1163         SAFE_FREE(tdbkey);
1164         return ret;
1165 }
1166
1167 /*******************************************************************
1168  Find the ldap password.
1169 ******************************************************************/
1170
1171 char *secrets_fetch_generic(const char *owner, const char *key)
1172 {
1173         char *secret = NULL;
1174         char *tdbkey = NULL;
1175
1176         if (( ! owner) || ( ! key)) {
1177                 DEBUG(1, ("Invalid Paramters"));
1178                 return NULL;
1179         }
1180
1181         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1182                 DEBUG(0, ("Out of memory!\n"));
1183                 return NULL;
1184         }
1185
1186         secret = (char *)secrets_fetch(tdbkey, NULL);
1187         SAFE_FREE(tdbkey);
1188
1189         return secret;
1190 }
1191