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