r16197: Fix Klocwork id 1338
[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 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);
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                                 (time_t)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) == (size_t)-1) {
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         SAFE_FREE(uni_dom_name);
416
417         /* last change time */
418         pass.mod_time = time(NULL);
419
420         /* password of the trust */
421         pass.pass_len = strlen(pwd);
422         fstrcpy(pass.pass, pwd);
423
424         /* domain sid */
425         sid_copy(&pass.domain_sid, sid);
426         
427         pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_buf_len, &pass);
428
429         return secrets_store(trustdom_keystr(domain), (void *)&pass_buf, pass_len);
430 }
431
432 /************************************************************************
433  Routine to set the plaintext machine account password for a realm
434 the password is assumed to be a null terminated ascii string
435 ************************************************************************/
436
437 BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
438 {
439         char *key = NULL;
440         BOOL ret;
441         uint32 last_change_time;
442         uint32 sec_channel_type;
443
444         asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
445         if (!key) 
446                 return False;
447         strupper_m(key);
448
449         ret = secrets_store(key, pass, strlen(pass)+1);
450         SAFE_FREE(key);
451
452         if (!ret)
453                 return ret;
454         
455         asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
456         if (!key) 
457                 return False;
458         strupper_m(key);
459
460         SIVAL(&last_change_time, 0, time(NULL));
461         ret = secrets_store(key, &last_change_time, sizeof(last_change_time));
462         SAFE_FREE(key);
463
464         asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
465         if (!key) 
466                 return False;
467         strupper_m(key);
468
469         SIVAL(&sec_channel_type, 0, sec_channel);
470         ret = secrets_store(key, &sec_channel_type, sizeof(sec_channel_type));
471         SAFE_FREE(key);
472
473         return ret;
474 }
475
476 /************************************************************************
477  Routine to fetch the plaintext machine account password for a realm
478  the password is assumed to be a null terminated ascii string.
479 ************************************************************************/
480
481 char *secrets_fetch_machine_password(const char *domain, 
482                                      time_t *pass_last_set_time,
483                                      uint32 *channel)
484 {
485         char *key = NULL;
486         char *ret;
487         asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
488         strupper_m(key);
489         ret = (char *)secrets_fetch(key, NULL);
490         SAFE_FREE(key);
491         
492         if (pass_last_set_time) {
493                 size_t size;
494                 uint32 *last_set_time;
495                 asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
496                 strupper_m(key);
497                 last_set_time = secrets_fetch(key, &size);
498                 if (last_set_time) {
499                         *pass_last_set_time = IVAL(last_set_time,0);
500                         SAFE_FREE(last_set_time);
501                 } else {
502                         *pass_last_set_time = 0;
503                 }
504                 SAFE_FREE(key);
505         }
506         
507         if (channel) {
508                 size_t size;
509                 uint32 *channel_type;
510                 asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
511                 strupper_m(key);
512                 channel_type = secrets_fetch(key, &size);
513                 if (channel_type) {
514                         *channel = IVAL(channel_type,0);
515                         SAFE_FREE(channel_type);
516                 } else {
517                         *channel = get_default_sec_channel();
518                 }
519                 SAFE_FREE(key);
520         }
521         
522         return ret;
523 }
524
525 /*******************************************************************
526  Wrapper around retrieving the trust account password
527 *******************************************************************/
528                                                                                                                      
529 BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16], uint32 *channel)
530 {
531         DOM_SID sid;
532         char *pwd;
533         time_t last_set_time;
534                                                                                                                      
535         /* if we are a DC and this is not our domain, then lookup an account
536                 for the domain trust */
537                                                                                                                      
538         if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() ) {
539                 if (!secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
540                                                         &last_set_time)) {
541                         DEBUG(0, ("get_trust_pw: could not fetch trust "
542                                 "account password for trusted domain %s\n",
543                                 domain));
544                         return False;
545                 }
546                                                                                                                      
547                 *channel = SEC_CHAN_DOMAIN;
548                 E_md4hash(pwd, ret_pwd);
549                 SAFE_FREE(pwd);
550
551                 return True;
552         }
553                                                                                                                      
554         /* Just get the account for the requested domain. In the future this
555          * might also cover to be member of more than one domain. */
556                                                                                                                      
557         if (secrets_fetch_trust_account_password(domain, ret_pwd,
558                                                 &last_set_time, channel))
559                 return True;
560
561         DEBUG(5, ("get_trust_pw: could not fetch trust account "
562                 "password for domain %s\n", domain));
563         return False;
564 }
565
566 /************************************************************************
567  Routine to delete the machine trust account password file for a domain.
568 ************************************************************************/
569
570 BOOL trust_password_delete(const char *domain)
571 {
572         return secrets_delete(trust_keystr(domain));
573 }
574
575 /************************************************************************
576  Routine to delete the password for trusted domain
577 ************************************************************************/
578
579 BOOL trusted_domain_password_delete(const char *domain)
580 {
581         return secrets_delete(trustdom_keystr(domain));
582 }
583
584 BOOL secrets_store_ldap_pw(const char* dn, char* pw)
585 {
586         char *key = NULL;
587         BOOL ret;
588         
589         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
590                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
591                 return False;
592         }
593                 
594         ret = secrets_store(key, pw, strlen(pw)+1);
595         
596         SAFE_FREE(key);
597         return ret;
598 }
599
600 /*******************************************************************
601  Find the ldap password.
602 ******************************************************************/
603
604 BOOL fetch_ldap_pw(char **dn, char** pw)
605 {
606         char *key = NULL;
607         size_t size = 0;
608         
609         *dn = smb_xstrdup(lp_ldap_admin_dn());
610         
611         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
612                 SAFE_FREE(*dn);
613                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
614         }
615         
616         *pw=secrets_fetch(key, &size);
617         SAFE_FREE(key);
618
619         if (!size) {
620                 /* Upgrade 2.2 style entry */
621                 char *p;
622                 char* old_style_key = SMB_STRDUP(*dn);
623                 char *data;
624                 fstring old_style_pw;
625                 
626                 if (!old_style_key) {
627                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
628                         return False;
629                 }
630
631                 for (p=old_style_key; *p; p++)
632                         if (*p == ',') *p = '/';
633         
634                 data=secrets_fetch(old_style_key, &size);
635                 if (!size && size < sizeof(old_style_pw)) {
636                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
637                         SAFE_FREE(old_style_key);
638                         SAFE_FREE(*dn);
639                         return False;
640                 }
641
642                 size = MIN(size, sizeof(fstring)-1);
643                 strncpy(old_style_pw, data, size);
644                 old_style_pw[size] = 0;
645
646                 SAFE_FREE(data);
647
648                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
649                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
650                         SAFE_FREE(old_style_key);
651                         SAFE_FREE(*dn);
652                         return False;                   
653                 }
654                 if (!secrets_delete(old_style_key)) {
655                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
656                 }
657
658                 SAFE_FREE(old_style_key);
659
660                 *pw = smb_xstrdup(old_style_pw);                
661         }
662         
663         return True;
664 }
665
666 /**
667  * Get trusted domains info from secrets.tdb.
668  **/ 
669
670 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
671                                  struct trustdom_info ***domains)
672 {
673         TDB_LIST_NODE *keys, *k;
674         char *pattern;
675
676         if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
677         
678         /* generate searching pattern */
679         pattern = talloc_asprintf(mem_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
680         if (pattern == NULL) {
681                 DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
682                           "failed!\n"));
683                 return NT_STATUS_NO_MEMORY;
684         }
685
686         *domains = NULL;
687         *num_domains = 0;
688
689         /* fetching trusted domains' data and collecting them in a list */
690         keys = tdb_search_keys(tdb, pattern);
691
692         /* searching for keys in secrets db -- way to go ... */
693         for (k = keys; k; k = k->next) {
694                 char *packed_pass;
695                 size_t size = 0, packed_size = 0;
696                 struct trusted_dom_pass pass;
697                 char *secrets_key;
698                 struct trustdom_info *dom_info;
699                 
700                 /* important: ensure null-termination of the key string */
701                 secrets_key = talloc_strndup(mem_ctx,
702                                              k->node_key.dptr,
703                                              k->node_key.dsize);
704                 if (!secrets_key) {
705                         DEBUG(0, ("strndup failed!\n"));
706                         tdb_search_list_free(keys);
707                         return NT_STATUS_NO_MEMORY;
708                 }
709
710                 packed_pass = secrets_fetch(secrets_key, &size);
711                 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
712                                                           &pass);
713                 /* packed representation isn't needed anymore */
714                 SAFE_FREE(packed_pass);
715                 
716                 if (size != packed_size) {
717                         DEBUG(2, ("Secrets record %s is invalid!\n",
718                                   secrets_key));
719                         continue;
720                 }
721
722                 if (pass.domain_sid.num_auths != 4) {
723                         DEBUG(0, ("SID %s is not a domain sid, has %d "
724                                   "auths instead of 4\n",
725                                   sid_string_static(&pass.domain_sid),
726                                   pass.domain_sid.num_auths));
727                         continue;
728                 }
729
730                 dom_info = TALLOC_P(mem_ctx, struct trustdom_info);
731                 if (dom_info == NULL) {
732                         DEBUG(0, ("talloc failed\n"));
733                         tdb_search_list_free(keys);
734                         return NT_STATUS_NO_MEMORY;
735                 }
736
737                 if (pull_ucs2_talloc(mem_ctx, &dom_info->name,
738                                      pass.uni_name) == (size_t)-1) {
739                         DEBUG(2, ("pull_ucs2_talloc failed\n"));
740                         tdb_search_list_free(keys);
741                         return NT_STATUS_NO_MEMORY;
742                 }
743
744                 sid_copy(&dom_info->sid, &pass.domain_sid);
745
746                 ADD_TO_ARRAY(mem_ctx, struct trustdom_info *, dom_info,
747                              domains, num_domains);
748
749                 if (*domains == NULL) {
750                         tdb_search_list_free(keys);
751                         return NT_STATUS_NO_MEMORY;
752                 }
753                 talloc_steal(*domains, dom_info);
754         }
755         
756         DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
757                   *num_domains));
758
759         /* free the results of searching the keys */
760         tdb_search_list_free(keys);
761
762         return NT_STATUS_OK;
763 }
764
765 /*******************************************************************************
766  Lock the secrets tdb based on a string - this is used as a primitive form of mutex
767  between smbd instances.
768 *******************************************************************************/
769
770 BOOL secrets_named_mutex(const char *name, unsigned int timeout)
771 {
772         int ret = 0;
773
774         if (!secrets_init())
775                 return False;
776
777         ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
778         if (ret == 0)
779                 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
780
781         return (ret == 0);
782 }
783
784 /*******************************************************************************
785  Unlock a named mutex.
786 *******************************************************************************/
787
788 void secrets_named_mutex_release(const char *name)
789 {
790         tdb_unlock_bystring(tdb, name);
791         DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
792 }
793
794 /*******************************************************************************
795  Store a complete AFS keyfile into secrets.tdb.
796 *******************************************************************************/
797
798 BOOL secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
799 {
800         fstring key;
801
802         if ((cell == NULL) || (keyfile == NULL))
803                 return False;
804
805         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
806                 return False;
807
808         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
809         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
810 }
811
812 /*******************************************************************************
813  Fetch the current (highest) AFS key from secrets.tdb
814 *******************************************************************************/
815 BOOL secrets_fetch_afs_key(const char *cell, struct afs_key *result)
816 {
817         fstring key;
818         struct afs_keyfile *keyfile;
819         size_t size = 0;
820         uint32 i;
821
822         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
823
824         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
825
826         if (keyfile == NULL)
827                 return False;
828
829         if (size != sizeof(struct afs_keyfile)) {
830                 SAFE_FREE(keyfile);
831                 return False;
832         }
833
834         i = ntohl(keyfile->nkeys);
835
836         if (i > SECRETS_AFS_MAXKEYS) {
837                 SAFE_FREE(keyfile);
838                 return False;
839         }
840
841         *result = keyfile->entry[i-1];
842
843         result->kvno = ntohl(result->kvno);
844
845         return True;
846 }
847
848 /******************************************************************************
849   When kerberos is not available, choose between anonymous or
850   authenticated connections.  
851
852   We need to use an authenticated connection if DCs have the
853   RestrictAnonymous registry entry set > 0, or the "Additional
854   restrictions for anonymous connections" set in the win2k Local
855   Security Policy.
856
857   Caller to free() result in domain, username, password
858 *******************************************************************************/
859 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
860 {
861         *username = secrets_fetch(SECRETS_AUTH_USER, NULL);
862         *domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
863         *password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
864         
865         if (*username && **username) {
866
867                 if (!*domain || !**domain)
868                         *domain = smb_xstrdup(lp_workgroup());
869                 
870                 if (!*password || !**password)
871                         *password = smb_xstrdup("");
872
873                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n", 
874                           *domain, *username));
875
876         } else {
877                 DEBUG(3, ("IPC$ connections done anonymously\n"));
878                 *username = smb_xstrdup("");
879                 *domain = smb_xstrdup("");
880                 *password = smb_xstrdup("");
881         }
882 }
883
884 /******************************************************************************
885  Open or create the schannel session store tdb.
886 *******************************************************************************/
887
888 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
889 {
890         TDB_DATA vers;
891         uint32 ver;
892         TDB_CONTEXT *tdb_sc = NULL;
893         char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
894
895         if (!fname) {
896                 return NULL;
897         }
898
899         tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
900
901         if (!tdb_sc) {
902                 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
903                 TALLOC_FREE(fname);
904                 return NULL;
905         }
906
907         vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
908         if (vers.dptr == NULL) {
909                 /* First opener, no version. */
910                 SIVAL(&ver,0,1);
911                 vers.dptr = (char *)&ver;
912                 vers.dsize = 4;
913                 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
914                 vers.dptr = NULL;
915         } else if (vers.dsize == 4) {
916                 ver = IVAL(vers.dptr,0);
917                 if (ver != 1) {
918                         tdb_close(tdb_sc);
919                         tdb_sc = NULL;
920                         DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
921                                 (int)ver, fname ));
922                 }
923         } else {
924                 tdb_close(tdb_sc);
925                 tdb_sc = NULL;
926                 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
927                         (int)vers.dsize, fname ));
928         }
929
930         SAFE_FREE(vers.dptr);
931         TALLOC_FREE(fname);
932
933         return tdb_sc;
934 }
935
936 /******************************************************************************
937  Store the schannel state after an AUTH2 call.
938  Note we must be root here.
939 *******************************************************************************/
940
941 BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
942                                 const char *remote_machine,
943                                 const struct dcinfo *pdc)
944 {
945         TDB_CONTEXT *tdb_sc = NULL;
946         TDB_DATA value;
947         BOOL ret;
948         char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
949                                 remote_machine);
950         if (!keystr) {
951                 return False;
952         }
953
954         strupper_m(keystr);
955
956         /* Work out how large the record is. */
957         value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
958                                 pdc->sequence,
959                                 8, pdc->seed_chal.data,
960                                 8, pdc->clnt_chal.data,
961                                 8, pdc->srv_chal.data,
962                                 16, pdc->sess_key,
963                                 16, pdc->mach_pw,
964                                 pdc->mach_acct,
965                                 pdc->remote_machine,
966                                 pdc->domain);
967
968         value.dptr = TALLOC(mem_ctx, value.dsize);
969         if (!value.dptr) {
970                 TALLOC_FREE(keystr);
971                 return False;
972         }
973
974         value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
975                                 pdc->sequence,
976                                 8, pdc->seed_chal.data,
977                                 8, pdc->clnt_chal.data,
978                                 8, pdc->srv_chal.data,
979                                 16, pdc->sess_key,
980                                 16, pdc->mach_pw,
981                                 pdc->mach_acct,
982                                 pdc->remote_machine,
983                                 pdc->domain);
984
985         tdb_sc = open_schannel_session_store(mem_ctx);
986         if (!tdb_sc) {
987                 TALLOC_FREE(keystr);
988                 TALLOC_FREE(value.dptr);
989                 return False;
990         }
991
992         ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
993
994         DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
995                 keystr ));
996
997         tdb_close(tdb_sc);
998         TALLOC_FREE(keystr);
999         TALLOC_FREE(value.dptr);
1000         return ret;
1001 }
1002
1003 /******************************************************************************
1004  Restore the schannel state on a client reconnect.
1005  Note we must be root here.
1006 *******************************************************************************/
1007
1008 BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1009                                 const char *remote_machine,
1010                                 struct dcinfo **ppdc)
1011 {
1012         TDB_CONTEXT *tdb_sc = NULL;
1013         TDB_DATA value;
1014         unsigned char *pseed_chal = NULL;
1015         unsigned char *pclnt_chal = NULL;
1016         unsigned char *psrv_chal = NULL;
1017         unsigned char *psess_key = NULL;
1018         unsigned char *pmach_pw = NULL;
1019         uint32 l1, l2, l3, l4, l5;
1020         int ret;
1021         struct dcinfo *pdc = NULL;
1022         char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1023                                 remote_machine);
1024
1025         *ppdc = NULL;
1026
1027         if (!keystr) {
1028                 return False;
1029         }
1030
1031         strupper_m(keystr);
1032
1033         tdb_sc = open_schannel_session_store(mem_ctx);
1034         if (!tdb_sc) {
1035                 TALLOC_FREE(keystr);
1036                 return False;
1037         }
1038
1039         value = tdb_fetch_bystring(tdb_sc, keystr);
1040         if (!value.dptr) {
1041                 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1042                         keystr ));
1043                 tdb_close(tdb_sc);
1044                 return False;
1045         }
1046
1047         pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1048
1049         /* Retrieve the record. */
1050         ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1051                                 &pdc->sequence,
1052                                 &l1, &pseed_chal,
1053                                 &l2, &pclnt_chal,
1054                                 &l3, &psrv_chal,
1055                                 &l4, &psess_key,
1056                                 &l5, &pmach_pw,
1057                                 &pdc->mach_acct,
1058                                 &pdc->remote_machine,
1059                                 &pdc->domain);
1060
1061         if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1062                 /* Bad record - delete it. */
1063                 tdb_delete_bystring(tdb_sc, keystr);
1064                 tdb_close(tdb_sc);
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         tdb_close(tdb_sc);
1077
1078         memcpy(pdc->seed_chal.data, pseed_chal, 8);
1079         memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1080         memcpy(pdc->srv_chal.data, psrv_chal, 8);
1081         memcpy(pdc->sess_key, psess_key, 16);
1082         memcpy(pdc->mach_pw, pmach_pw, 16);
1083
1084         /* We know these are true so didn't bother to store them. */
1085         pdc->challenge_sent = True;
1086         pdc->authenticated = True;
1087
1088         DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1089                 keystr ));
1090
1091         SAFE_FREE(pseed_chal);
1092         SAFE_FREE(pclnt_chal);
1093         SAFE_FREE(psrv_chal);
1094         SAFE_FREE(psess_key);
1095         SAFE_FREE(pmach_pw);
1096
1097         TALLOC_FREE(keystr);
1098         SAFE_FREE(value.dptr);
1099
1100         *ppdc = pdc;
1101
1102         return True;
1103 }