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