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