r14102: Fix Coverity bug # 70
[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 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_store(tdb, string_tdb_data(key), make_tdb_data(data, size),
108                          TDB_REPLACE) == 0;
109 }
110
111
112 /* delete a secets database entry
113  */
114 BOOL secrets_delete(const char *key)
115 {
116         secrets_init();
117         if (!tdb)
118                 return False;
119         return tdb_delete(tdb, string_tdb_data(key)) == 0;
120 }
121
122 BOOL secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
123 {
124         fstring key;
125         BOOL ret;
126
127         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
128         strupper_m(key);
129         ret = secrets_store(key, sid, sizeof(DOM_SID));
130
131         /* Force a re-query, in case we modified our domain */
132         if (ret)
133                 reset_global_sam_sid();
134         return ret;
135 }
136
137 BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
138 {
139         DOM_SID *dyn_sid;
140         fstring key;
141         size_t size = 0;
142
143         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
144         strupper_m(key);
145         dyn_sid = (DOM_SID *)secrets_fetch(key, &size);
146
147         if (dyn_sid == NULL)
148                 return False;
149
150         if (size != sizeof(DOM_SID)) { 
151                 SAFE_FREE(dyn_sid);
152                 return False;
153         }
154
155         *sid = *dyn_sid;
156         SAFE_FREE(dyn_sid);
157         return True;
158 }
159
160 BOOL secrets_store_domain_guid(const char *domain, struct uuid *guid)
161 {
162         fstring key;
163
164         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
165         strupper_m(key);
166         return secrets_store(key, guid, sizeof(struct uuid));
167 }
168
169 BOOL secrets_fetch_domain_guid(const char *domain, struct uuid *guid)
170 {
171         struct uuid *dyn_guid;
172         fstring key;
173         size_t size = 0;
174         struct uuid new_guid;
175
176         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
177         strupper_m(key);
178         dyn_guid = (struct uuid *)secrets_fetch(key, &size);
179
180         if (!dyn_guid) {
181                 if (lp_server_role() == ROLE_DOMAIN_PDC) {
182                         smb_uuid_generate_random(&new_guid);
183                         if (!secrets_store_domain_guid(domain, &new_guid))
184                                 return False;
185                         dyn_guid = (struct uuid *)secrets_fetch(key, &size);
186                 }
187                 if (dyn_guid == NULL) {
188                         return False;
189                 }
190         }
191
192         if (size != sizeof(struct uuid)) { 
193                 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
194                 SAFE_FREE(dyn_guid);
195                 return False;
196         }
197
198         *guid = *dyn_guid;
199         SAFE_FREE(dyn_guid);
200         return True;
201 }
202
203 /**
204  * Form a key for fetching the machine trust account password
205  *
206  * @param domain domain name
207  *
208  * @return stored password's key
209  **/
210 const char *trust_keystr(const char *domain)
211 {
212         static fstring keystr;
213
214         slprintf(keystr,sizeof(keystr)-1,"%s/%s", 
215                  SECRETS_MACHINE_ACCT_PASS, domain);
216         strupper_m(keystr);
217
218         return keystr;
219 }
220
221 /**
222  * Form a key for fetching a trusted domain password
223  *
224  * @param domain trusted domain name
225  *
226  * @return stored password's key
227  **/
228 static char *trustdom_keystr(const char *domain)
229 {
230         static pstring keystr;
231
232         pstr_sprintf(keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain);
233         strupper_m(keystr);
234                 
235         return keystr;
236 }
237
238 /************************************************************************
239  Lock the trust password entry.
240 ************************************************************************/
241
242 BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock)
243 {
244         if (!tdb)
245                 return False;
246
247         if (dolock)
248                 return (tdb_lock_bystring(tdb, trust_keystr(domain),0) == 0);
249         else
250                 tdb_unlock_bystring(tdb, trust_keystr(domain));
251         return True;
252 }
253
254 /************************************************************************
255  Routine to get the default secure channel type for trust accounts
256 ************************************************************************/
257
258 uint32 get_default_sec_channel(void) 
259 {
260         if (lp_server_role() == ROLE_DOMAIN_BDC || 
261             lp_server_role() == ROLE_DOMAIN_PDC) {
262                 return SEC_CHAN_BDC;
263         } else {
264                 return SEC_CHAN_WKSTA;
265         }
266 }
267
268 /************************************************************************
269  Routine to get the trust account password for a domain.
270  The user of this function must have locked the trust password file using
271  the above secrets_lock_trust_account_password().
272 ************************************************************************/
273
274 BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
275                                           time_t *pass_last_set_time,
276                                           uint32 *channel)
277 {
278         struct machine_acct_pass *pass;
279         char *plaintext;
280         size_t size = 0;
281
282         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time, 
283                                                    channel);
284         if (plaintext) {
285                 DEBUG(4,("Using cleartext machine password\n"));
286                 E_md4hash(plaintext, ret_pwd);
287                 SAFE_FREE(plaintext);
288                 return True;
289         }
290
291         if (!(pass = secrets_fetch(trust_keystr(domain), &size))) {
292                 DEBUG(5, ("secrets_fetch failed!\n"));
293                 return False;
294         }
295         
296         if (size != sizeof(*pass)) {
297                 DEBUG(0, ("secrets were of incorrect size!\n"));
298                 return False;
299         }
300
301         if (pass_last_set_time) {
302                 *pass_last_set_time = pass->mod_time;
303         }
304         memcpy(ret_pwd, pass->hash, 16);
305
306         if (channel) {
307                 *channel = get_default_sec_channel();
308         }
309
310         /* Test if machine password has expired and needs to be changed */
311         if (lp_machine_password_timeout()) {
312                 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
313                                 lp_machine_password_timeout())) {
314                         global_machine_password_needs_changing = True;
315                 }
316         }
317
318         SAFE_FREE(pass);
319         return True;
320 }
321
322 /************************************************************************
323  Routine to get account password to trusted domain
324 ************************************************************************/
325
326 BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
327                                            DOM_SID *sid, time_t *pass_last_set_time)
328 {
329         struct trusted_dom_pass pass;
330         size_t size = 0;
331         
332         /* unpacking structures */
333         char* pass_buf;
334         int pass_len = 0;
335
336         ZERO_STRUCT(pass);
337
338         /* fetching trusted domain password structure */
339         if (!(pass_buf = secrets_fetch(trustdom_keystr(domain), &size))) {
340                 DEBUG(5, ("secrets_fetch failed!\n"));
341                 return False;
342         }
343
344         /* unpack trusted domain password */
345         pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
346         SAFE_FREE(pass_buf);
347
348         if (pass_len != size) {
349                 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
350                 return False;
351         }
352                         
353         /* the trust's password */      
354         if (pwd) {
355                 *pwd = SMB_STRDUP(pass.pass);
356                 if (!*pwd) {
357                         return False;
358                 }
359         }
360
361         /* last change time */
362         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
363
364         /* domain sid */
365         if (sid != NULL) sid_copy(sid, &pass.domain_sid);
366                 
367         return True;
368 }
369
370 /************************************************************************
371  Routine to set the trust account password for a domain.
372 ************************************************************************/
373
374 BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16])
375 {
376         struct machine_acct_pass pass;
377
378         pass.mod_time = time(NULL);
379         memcpy(pass.hash, new_pwd, 16);
380
381         return secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass));
382 }
383
384 /**
385  * Routine to store the password for trusted domain
386  *
387  * @param domain remote domain name
388  * @param pwd plain text password of trust relationship
389  * @param sid remote domain sid
390  *
391  * @return true if succeeded
392  **/
393
394 BOOL secrets_store_trusted_domain_password(const char* domain, const char* pwd,
395                                            const DOM_SID *sid)
396 {
397         smb_ucs2_t *uni_dom_name;
398
399         /* packing structures */
400         pstring pass_buf;
401         int pass_len = 0;
402         int pass_buf_len = sizeof(pass_buf);
403         
404         struct trusted_dom_pass pass;
405         ZERO_STRUCT(pass);
406
407         if (push_ucs2_allocate(&uni_dom_name, domain) < 0) {
408                 DEBUG(0, ("Could not convert domain name %s to unicode\n",
409                           domain));
410                 return False;
411         }
412         
413         strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
414         pass.uni_name_len = strlen_w(uni_dom_name)+1;
415
416         /* last change time */
417         pass.mod_time = time(NULL);
418
419         /* password of the trust */
420         pass.pass_len = strlen(pwd);
421         fstrcpy(pass.pass, pwd);
422
423         /* domain sid */
424         sid_copy(&pass.domain_sid, sid);
425         
426         pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_buf_len, &pass);
427
428         return secrets_store(trustdom_keystr(domain), (void *)&pass_buf, pass_len);
429 }
430
431 /************************************************************************
432  Routine to set the plaintext machine account password for a realm
433 the password is assumed to be a null terminated ascii string
434 ************************************************************************/
435
436 BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
437 {
438         char *key = NULL;
439         BOOL ret;
440         uint32 last_change_time;
441         uint32 sec_channel_type;
442
443         asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
444         if (!key) 
445                 return False;
446         strupper_m(key);
447
448         ret = secrets_store(key, pass, strlen(pass)+1);
449         SAFE_FREE(key);
450
451         if (!ret)
452                 return ret;
453         
454         asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
455         if (!key) 
456                 return False;
457         strupper_m(key);
458
459         SIVAL(&last_change_time, 0, time(NULL));
460         ret = secrets_store(key, &last_change_time, sizeof(last_change_time));
461         SAFE_FREE(key);
462
463         asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
464         if (!key) 
465                 return False;
466         strupper_m(key);
467
468         SIVAL(&sec_channel_type, 0, sec_channel);
469         ret = secrets_store(key, &sec_channel_type, sizeof(sec_channel_type));
470         SAFE_FREE(key);
471
472         return ret;
473 }
474
475 /************************************************************************
476  Routine to fetch the plaintext machine account password for a realm
477  the password is assumed to be a null terminated ascii string.
478 ************************************************************************/
479
480 char *secrets_fetch_machine_password(const char *domain, 
481                                      time_t *pass_last_set_time,
482                                      uint32 *channel)
483 {
484         char *key = NULL;
485         char *ret;
486         asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
487         strupper_m(key);
488         ret = (char *)secrets_fetch(key, NULL);
489         SAFE_FREE(key);
490         
491         if (pass_last_set_time) {
492                 size_t size;
493                 uint32 *last_set_time;
494                 asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
495                 strupper_m(key);
496                 last_set_time = secrets_fetch(key, &size);
497                 if (last_set_time) {
498                         *pass_last_set_time = IVAL(last_set_time,0);
499                         SAFE_FREE(last_set_time);
500                 } else {
501                         *pass_last_set_time = 0;
502                 }
503                 SAFE_FREE(key);
504         }
505         
506         if (channel) {
507                 size_t size;
508                 uint32 *channel_type;
509                 asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
510                 strupper_m(key);
511                 channel_type = secrets_fetch(key, &size);
512                 if (channel_type) {
513                         *channel = IVAL(channel_type,0);
514                         SAFE_FREE(channel_type);
515                 } else {
516                         *channel = get_default_sec_channel();
517                 }
518                 SAFE_FREE(key);
519         }
520         
521         return ret;
522 }
523
524 /*******************************************************************
525  Wrapper around retrieving the trust account password
526 *******************************************************************/
527                                                                                                                      
528 BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16], uint32 *channel)
529 {
530         DOM_SID sid;
531         char *pwd;
532         time_t last_set_time;
533                                                                                                                      
534         /* if we are a DC and this is not our domain, then lookup an account
535                 for the domain trust */
536                                                                                                                      
537         if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() ) {
538                 if (!secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
539                                                         &last_set_time)) {
540                         DEBUG(0, ("get_trust_pw: could not fetch trust "
541                                 "account password for trusted domain %s\n",
542                                 domain));
543                         return False;
544                 }
545                                                                                                                      
546                 *channel = SEC_CHAN_DOMAIN;
547                 E_md4hash(pwd, ret_pwd);
548                 SAFE_FREE(pwd);
549
550                 return True;
551         }
552                                                                                                                      
553         /* Just get the account for the requested domain. In the future this
554          * might also cover to be member of more than one domain. */
555                                                                                                                      
556         if (secrets_fetch_trust_account_password(domain, ret_pwd,
557                                                 &last_set_time, channel))
558                 return True;
559
560         DEBUG(5, ("get_trust_pw: could not fetch trust account "
561                 "password for domain %s\n", domain));
562         return False;
563 }
564
565 /************************************************************************
566  Routine to delete the machine trust account password file for a domain.
567 ************************************************************************/
568
569 BOOL trust_password_delete(const char *domain)
570 {
571         return secrets_delete(trust_keystr(domain));
572 }
573
574 /************************************************************************
575  Routine to delete the password for trusted domain
576 ************************************************************************/
577
578 BOOL trusted_domain_password_delete(const char *domain)
579 {
580         return secrets_delete(trustdom_keystr(domain));
581 }
582
583 BOOL secrets_store_ldap_pw(const char* dn, char* pw)
584 {
585         char *key = NULL;
586         BOOL ret;
587         
588         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
589                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
590                 return False;
591         }
592                 
593         ret = secrets_store(key, pw, strlen(pw)+1);
594         
595         SAFE_FREE(key);
596         return ret;
597 }
598
599 /*******************************************************************
600  Find the ldap password.
601 ******************************************************************/
602
603 BOOL fetch_ldap_pw(char **dn, char** pw)
604 {
605         char *key = NULL;
606         size_t size = 0;
607         
608         *dn = smb_xstrdup(lp_ldap_admin_dn());
609         
610         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
611                 SAFE_FREE(*dn);
612                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
613         }
614         
615         *pw=secrets_fetch(key, &size);
616         SAFE_FREE(key);
617
618         if (!size) {
619                 /* Upgrade 2.2 style entry */
620                 char *p;
621                 char* old_style_key = SMB_STRDUP(*dn);
622                 char *data;
623                 fstring old_style_pw;
624                 
625                 if (!old_style_key) {
626                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
627                         return False;
628                 }
629
630                 for (p=old_style_key; *p; p++)
631                         if (*p == ',') *p = '/';
632         
633                 data=secrets_fetch(old_style_key, &size);
634                 if (!size && size < sizeof(old_style_pw)) {
635                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
636                         SAFE_FREE(old_style_key);
637                         SAFE_FREE(*dn);
638                         return False;
639                 }
640
641                 size = MIN(size, sizeof(fstring)-1);
642                 strncpy(old_style_pw, data, size);
643                 old_style_pw[size] = 0;
644
645                 SAFE_FREE(data);
646
647                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
648                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
649                         SAFE_FREE(old_style_key);
650                         SAFE_FREE(*dn);
651                         return False;                   
652                 }
653                 if (!secrets_delete(old_style_key)) {
654                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
655                 }
656
657                 SAFE_FREE(old_style_key);
658
659                 *pw = smb_xstrdup(old_style_pw);                
660         }
661         
662         return True;
663 }
664
665 /**
666  * Get trusted domains info from secrets.tdb.
667  **/ 
668
669 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
670                                  struct trustdom_info ***domains)
671 {
672         TDB_LIST_NODE *keys, *k;
673         char *pattern;
674
675         if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
676         
677         /* generate searching pattern */
678         pattern = talloc_asprintf(mem_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
679         if (pattern == NULL) {
680                 DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
681                           "failed!\n"));
682                 return NT_STATUS_NO_MEMORY;
683         }
684
685         *domains = NULL;
686         *num_domains = 0;
687
688         /* fetching trusted domains' data and collecting them in a list */
689         keys = tdb_search_keys(tdb, pattern);
690
691         /* searching for keys in secrets db -- way to go ... */
692         for (k = keys; k; k = k->next) {
693                 char *packed_pass;
694                 size_t size = 0, packed_size = 0;
695                 struct trusted_dom_pass pass;
696                 char *secrets_key;
697                 struct trustdom_info *dom_info;
698                 
699                 /* important: ensure null-termination of the key string */
700                 secrets_key = talloc_strndup(mem_ctx,
701                                              k->node_key.dptr,
702                                              k->node_key.dsize);
703                 if (!secrets_key) {
704                         DEBUG(0, ("strndup failed!\n"));
705                         tdb_search_list_free(keys);
706                         return NT_STATUS_NO_MEMORY;
707                 }
708
709                 packed_pass = secrets_fetch(secrets_key, &size);
710                 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
711                                                           &pass);
712                 /* packed representation isn't needed anymore */
713                 SAFE_FREE(packed_pass);
714                 
715                 if (size != packed_size) {
716                         DEBUG(2, ("Secrets record %s is invalid!\n",
717                                   secrets_key));
718                         continue;
719                 }
720
721                 if (pass.domain_sid.num_auths != 4) {
722                         DEBUG(0, ("SID %s is not a domain sid, has %d "
723                                   "auths instead of 4\n",
724                                   sid_string_static(&pass.domain_sid),
725                                   pass.domain_sid.num_auths));
726                         continue;
727                 }
728
729                 dom_info = TALLOC_P(mem_ctx, struct trustdom_info);
730                 if (dom_info == NULL) {
731                         DEBUG(0, ("talloc failed\n"));
732                         tdb_search_list_free(keys);
733                         return NT_STATUS_NO_MEMORY;
734                 }
735
736                 if (pull_ucs2_talloc(mem_ctx, &dom_info->name,
737                                      pass.uni_name) < 0) {
738                         DEBUG(2, ("pull_ucs2_talloc failed\n"));
739                         tdb_search_list_free(keys);
740                         return NT_STATUS_NO_MEMORY;
741                 }
742
743                 sid_copy(&dom_info->sid, &pass.domain_sid);
744
745                 ADD_TO_ARRAY(mem_ctx, struct trustdom_info *, dom_info,
746                              domains, num_domains);
747
748                 if (*domains == NULL) {
749                         tdb_search_list_free(keys);
750                         return NT_STATUS_NO_MEMORY;
751                 }
752                 talloc_steal(*domains, dom_info);
753         }
754         
755         DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
756                   *num_domains));
757
758         /* free the results of searching the keys */
759         tdb_search_list_free(keys);
760
761         return NT_STATUS_OK;
762 }
763
764 /*******************************************************************************
765  Lock the secrets tdb based on a string - this is used as a primitive form of mutex
766  between smbd instances.
767 *******************************************************************************/
768
769 BOOL secrets_named_mutex(const char *name, unsigned int timeout)
770 {
771         int ret = 0;
772
773         if (!secrets_init())
774                 return False;
775
776         ret = tdb_lock_bystring(tdb, name, timeout);
777         if (ret == 0)
778                 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
779
780         return (ret == 0);
781 }
782
783 /*******************************************************************************
784  Unlock a named mutex.
785 *******************************************************************************/
786
787 void secrets_named_mutex_release(const char *name)
788 {
789         tdb_unlock_bystring(tdb, name);
790         DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
791 }
792
793 /*******************************************************************************
794  Store a complete AFS keyfile into secrets.tdb.
795 *******************************************************************************/
796
797 BOOL secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
798 {
799         fstring key;
800
801         if ((cell == NULL) || (keyfile == NULL))
802                 return False;
803
804         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
805                 return False;
806
807         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
808         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
809 }
810
811 /*******************************************************************************
812  Fetch the current (highest) AFS key from secrets.tdb
813 *******************************************************************************/
814 BOOL secrets_fetch_afs_key(const char *cell, struct afs_key *result)
815 {
816         fstring key;
817         struct afs_keyfile *keyfile;
818         size_t size = 0;
819         uint32 i;
820
821         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
822
823         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
824
825         if (keyfile == NULL)
826                 return False;
827
828         if (size != sizeof(struct afs_keyfile)) {
829                 SAFE_FREE(keyfile);
830                 return False;
831         }
832
833         i = ntohl(keyfile->nkeys);
834
835         if (i > SECRETS_AFS_MAXKEYS) {
836                 SAFE_FREE(keyfile);
837                 return False;
838         }
839
840         *result = keyfile->entry[i-1];
841
842         result->kvno = ntohl(result->kvno);
843
844         return True;
845 }
846
847 /******************************************************************************
848   When kerberos is not available, choose between anonymous or
849   authenticated connections.  
850
851   We need to use an authenticated connection if DCs have the
852   RestrictAnonymous registry entry set > 0, or the "Additional
853   restrictions for anonymous connections" set in the win2k Local
854   Security Policy.
855
856   Caller to free() result in domain, username, password
857 *******************************************************************************/
858 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
859 {
860         *username = secrets_fetch(SECRETS_AUTH_USER, NULL);
861         *domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
862         *password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
863         
864         if (*username && **username) {
865
866                 if (!*domain || !**domain)
867                         *domain = smb_xstrdup(lp_workgroup());
868                 
869                 if (!*password || !**password)
870                         *password = smb_xstrdup("");
871
872                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n", 
873                           *domain, *username));
874
875         } else {
876                 DEBUG(3, ("IPC$ connections done anonymously\n"));
877                 *username = smb_xstrdup("");
878                 *domain = smb_xstrdup("");
879                 *password = smb_xstrdup("");
880         }
881 }
882
883 /******************************************************************************
884  Open or create the schannel session store tdb.
885 *******************************************************************************/
886
887 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
888 {
889         TDB_DATA vers;
890         uint32 ver;
891         TDB_CONTEXT *tdb_sc = NULL;
892         char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
893
894         if (!fname) {
895                 return NULL;
896         }
897
898         tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
899
900         if (!tdb_sc) {
901                 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
902                 TALLOC_FREE(fname);
903                 return NULL;
904         }
905
906         vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
907         if (vers.dptr == NULL) {
908                 /* First opener, no version. */
909                 SIVAL(&ver,0,1);
910                 vers.dptr = (char *)&ver;
911                 vers.dsize = 4;
912                 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
913                 vers.dptr = NULL;
914         } else if (vers.dsize == 4) {
915                 ver = IVAL(vers.dptr,0);
916                 if (ver != 1) {
917                         tdb_close(tdb_sc);
918                         tdb_sc = NULL;
919                         DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
920                                 (int)ver, fname ));
921                 }
922         } else {
923                 tdb_close(tdb_sc);
924                 tdb_sc = NULL;
925                 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
926                         (int)vers.dsize, fname ));
927         }
928
929         SAFE_FREE(vers.dptr);
930         TALLOC_FREE(fname);
931
932         return tdb_sc;
933 }
934
935 /******************************************************************************
936  Store the schannel state after an AUTH2 call.
937  Note we must be root here.
938 *******************************************************************************/
939
940 BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
941                                 const char *remote_machine,
942                                 const struct dcinfo *pdc)
943 {
944         TDB_CONTEXT *tdb_sc = NULL;
945         TDB_DATA value;
946         BOOL ret;
947         char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
948                                 remote_machine);
949         if (!keystr) {
950                 return False;
951         }
952
953         strupper_m(keystr);
954
955         /* Work out how large the record is. */
956         value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
957                                 pdc->sequence,
958                                 8, pdc->seed_chal.data,
959                                 8, pdc->clnt_chal.data,
960                                 8, pdc->srv_chal.data,
961                                 16, pdc->sess_key,
962                                 16, pdc->mach_pw,
963                                 pdc->mach_acct,
964                                 pdc->remote_machine,
965                                 pdc->domain);
966
967         value.dptr = TALLOC(mem_ctx, value.dsize);
968         if (!value.dptr) {
969                 TALLOC_FREE(keystr);
970                 return False;
971         }
972
973         value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
974                                 pdc->sequence,
975                                 8, pdc->seed_chal.data,
976                                 8, pdc->clnt_chal.data,
977                                 8, pdc->srv_chal.data,
978                                 16, pdc->sess_key,
979                                 16, pdc->mach_pw,
980                                 pdc->mach_acct,
981                                 pdc->remote_machine,
982                                 pdc->domain);
983
984         tdb_sc = open_schannel_session_store(mem_ctx);
985         if (!tdb_sc) {
986                 TALLOC_FREE(keystr);
987                 TALLOC_FREE(value.dptr);
988                 return False;
989         }
990
991         ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
992
993         DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
994                 keystr ));
995
996         tdb_close(tdb_sc);
997         TALLOC_FREE(keystr);
998         TALLOC_FREE(value.dptr);
999         return ret;
1000 }
1001
1002 /******************************************************************************
1003  Restore the schannel state on a client reconnect.
1004  Note we must be root here.
1005 *******************************************************************************/
1006
1007 BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1008                                 const char *remote_machine,
1009                                 struct dcinfo **ppdc)
1010 {
1011         TDB_CONTEXT *tdb_sc = NULL;
1012         TDB_DATA value;
1013         unsigned char *pseed_chal = NULL;
1014         unsigned char *pclnt_chal = NULL;
1015         unsigned char *psrv_chal = NULL;
1016         unsigned char *psess_key = NULL;
1017         unsigned char *pmach_pw = NULL;
1018         uint32 l1, l2, l3, l4, l5;
1019         int ret;
1020         struct dcinfo *pdc = NULL;
1021         char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1022                                 remote_machine);
1023
1024         *ppdc = NULL;
1025
1026         if (!keystr) {
1027                 return False;
1028         }
1029
1030         strupper_m(keystr);
1031
1032         tdb_sc = open_schannel_session_store(mem_ctx);
1033         if (!tdb_sc) {
1034                 TALLOC_FREE(keystr);
1035                 return False;
1036         }
1037
1038         value = tdb_fetch_bystring(tdb_sc, keystr);
1039         if (!value.dptr) {
1040                 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1041                         keystr ));
1042                 tdb_close(tdb_sc);
1043                 return False;
1044         }
1045
1046         tdb_close(tdb_sc);
1047
1048         pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1049
1050         /* Retrieve the record. */
1051         ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1052                                 &pdc->sequence,
1053                                 &l1, &pseed_chal,
1054                                 &l2, &pclnt_chal,
1055                                 &l3, &psrv_chal,
1056                                 &l4, &psess_key,
1057                                 &l5, &pmach_pw,
1058                                 &pdc->mach_acct,
1059                                 &pdc->remote_machine,
1060                                 &pdc->domain);
1061
1062         if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1063                 /* Bad record - delete it. */
1064                 tdb_delete_bystring(tdb_sc, keystr);
1065                 TALLOC_FREE(keystr);
1066                 TALLOC_FREE(pdc);
1067                 SAFE_FREE(pseed_chal);
1068                 SAFE_FREE(pclnt_chal);
1069                 SAFE_FREE(psrv_chal);
1070                 SAFE_FREE(psess_key);
1071                 SAFE_FREE(pmach_pw);
1072                 SAFE_FREE(value.dptr);
1073                 return False;
1074         }
1075
1076         memcpy(pdc->seed_chal.data, pseed_chal, 8);
1077         memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1078         memcpy(pdc->srv_chal.data, psrv_chal, 8);
1079         memcpy(pdc->sess_key, psess_key, 16);
1080         memcpy(pdc->mach_pw, pmach_pw, 16);
1081
1082         /* We know these are true so didn't bother to store them. */
1083         pdc->challenge_sent = True;
1084         pdc->authenticated = True;
1085
1086         DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1087                 keystr ));
1088
1089         SAFE_FREE(pseed_chal);
1090         SAFE_FREE(pclnt_chal);
1091         SAFE_FREE(psrv_chal);
1092         SAFE_FREE(psess_key);
1093         SAFE_FREE(pmach_pw);
1094
1095         TALLOC_FREE(keystr);
1096         SAFE_FREE(value.dptr);
1097
1098         *ppdc = pdc;
1099
1100         return True;
1101 }