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