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