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