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