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