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