Fix bug 5334
[Samba.git] / source / passdb / secrets.c
blob1e90f61558847f10ef501daa30d81baaafebc2e4
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
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.
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.
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/>.
22 /* the Samba secrets database stores any generated, private information
23 such as the local SID and machine trust password */
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_PASSDB
30 static struct db_context *db_ctx;
32 /* Urrrg. global.... */
33 bool global_machine_password_needs_changing;
35 /**
36 * Use a TDB to store an incrementing random seed.
38 * Initialised to the current pid, the very first time Samba starts,
39 * and incremented by one each time it is needed.
41 * @note Not called by systems with a working /dev/urandom.
43 static void get_rand_seed(int *new_seed)
45 *new_seed = sys_getpid();
46 if (db_ctx) {
47 dbwrap_change_int32_atomic(db_ctx, "INFO/random_seed",
48 new_seed, 1);
52 /* open up the secrets database */
53 bool secrets_init(void)
55 char *fname = NULL;
56 unsigned char dummy;
58 if (db_ctx != NULL)
59 return True;
61 fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
62 lp_private_dir());
63 if (fname == NULL) {
64 return false;
67 db_ctx = db_open(NULL, fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
69 if (db_ctx == NULL) {
70 DEBUG(0,("Failed to open %s\n", fname));
71 TALLOC_FREE(fname);
72 return False;
75 TALLOC_FREE(fname);
77 /**
78 * Set a reseed function for the crypto random generator
80 * This avoids a problem where systems without /dev/urandom
81 * could send the same challenge to multiple clients
83 set_rand_reseed_callback(get_rand_seed);
85 /* Ensure that the reseed is done now, while we are root, etc */
86 generate_random_buffer(&dummy, sizeof(dummy));
88 return True;
92 * close secrets.tdb
94 void secrets_shutdown(void)
96 TALLOC_FREE(db_ctx);
99 /* read a entry from the secrets database - the caller must free the result
100 if size is non-null then the size of the entry is put in there
102 void *secrets_fetch(const char *key, size_t *size)
104 TDB_DATA dbuf;
105 void *result;
107 if (!secrets_init()) {
108 return NULL;
111 if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
112 &dbuf) != 0) {
113 return NULL;
116 result = memdup(dbuf.dptr, dbuf.dsize);
117 if (result == NULL) {
118 return NULL;
120 TALLOC_FREE(dbuf.dptr);
122 if (size) {
123 *size = dbuf.dsize;
126 return result;
129 /* store a secrets entry
131 bool secrets_store(const char *key, const void *data, size_t size)
133 if (!secrets_init()) {
134 return false;
137 return dbwrap_trans_store(db_ctx, string_tdb_data(key),
138 make_tdb_data((const uint8 *)data, size),
139 TDB_REPLACE) == 0;
143 /* delete a secets database entry
145 bool secrets_delete(const char *key)
147 if (!secrets_init()) {
148 return false;
151 return dbwrap_trans_delete(db_ctx, string_tdb_data(key)) == 0;
155 * Form a key for fetching the domain sid
157 * @param domain domain name
159 * @return keystring
161 static const char *domain_sid_keystr(const char *domain)
163 char *keystr;
165 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
166 SECRETS_DOMAIN_SID, domain);
167 SMB_ASSERT(keystr != NULL);
168 return keystr;
171 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
173 bool ret;
175 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
177 /* Force a re-query, in case we modified our domain */
178 if (ret)
179 reset_global_sam_sid();
180 return ret;
183 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
185 DOM_SID *dyn_sid;
186 size_t size = 0;
188 dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
190 if (dyn_sid == NULL)
191 return False;
193 if (size != sizeof(DOM_SID)) {
194 SAFE_FREE(dyn_sid);
195 return False;
198 *sid = *dyn_sid;
199 SAFE_FREE(dyn_sid);
200 return True;
203 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
205 fstring key;
207 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
208 strupper_m(key);
209 return secrets_store(key, guid, sizeof(struct GUID));
212 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
214 struct GUID *dyn_guid;
215 fstring key;
216 size_t size = 0;
217 struct GUID new_guid;
219 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
220 strupper_m(key);
221 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
223 if (!dyn_guid) {
224 if (lp_server_role() == ROLE_DOMAIN_PDC) {
225 smb_uuid_generate_random(&new_guid);
226 if (!secrets_store_domain_guid(domain, &new_guid))
227 return False;
228 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
230 if (dyn_guid == NULL) {
231 return False;
235 if (size != sizeof(struct GUID)) {
236 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
237 SAFE_FREE(dyn_guid);
238 return False;
241 *guid = *dyn_guid;
242 SAFE_FREE(dyn_guid);
243 return True;
247 * Form a key for fetching the machine trust account sec channel type
249 * @param domain domain name
251 * @return keystring
253 static const char *machine_sec_channel_type_keystr(const char *domain)
255 char *keystr;
257 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
258 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
259 domain);
260 SMB_ASSERT(keystr != NULL);
261 return keystr;
265 * Form a key for fetching the machine trust account last change time
267 * @param domain domain name
269 * @return keystring
271 static const char *machine_last_change_time_keystr(const char *domain)
273 char *keystr;
275 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
276 SECRETS_MACHINE_LAST_CHANGE_TIME,
277 domain);
278 SMB_ASSERT(keystr != NULL);
279 return keystr;
284 * Form a key for fetching the machine trust account password
286 * @param domain domain name
288 * @return keystring
290 static const char *machine_password_keystr(const char *domain)
292 char *keystr;
294 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
295 SECRETS_MACHINE_PASSWORD, domain);
296 SMB_ASSERT(keystr != NULL);
297 return keystr;
301 * Form a key for fetching the machine trust account password
303 * @param domain domain name
305 * @return stored password's key
307 static const char *trust_keystr(const char *domain)
309 char *keystr;
311 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
312 SECRETS_MACHINE_ACCT_PASS, domain);
313 SMB_ASSERT(keystr != NULL);
314 return keystr;
318 * Form a key for fetching a trusted domain password
320 * @param domain trusted domain name
322 * @return stored password's key
324 static char *trustdom_keystr(const char *domain)
326 char *keystr;
328 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
329 SECRETS_DOMTRUST_ACCT_PASS,
330 domain);
331 SMB_ASSERT(keystr != NULL);
332 return keystr;
335 /************************************************************************
336 Lock the trust password entry.
337 ************************************************************************/
339 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
341 if (!secrets_init()) {
342 return NULL;
345 return db_ctx->fetch_locked(
346 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
349 /************************************************************************
350 Routine to get the default secure channel type for trust accounts
351 ************************************************************************/
353 uint32 get_default_sec_channel(void)
355 if (lp_server_role() == ROLE_DOMAIN_BDC ||
356 lp_server_role() == ROLE_DOMAIN_PDC) {
357 return SEC_CHAN_BDC;
358 } else {
359 return SEC_CHAN_WKSTA;
363 /************************************************************************
364 Routine to get the trust account password for a domain.
365 This only tries to get the legacy hashed version of the password.
366 The user of this function must have locked the trust password file using
367 the above secrets_lock_trust_account_password().
368 ************************************************************************/
370 bool secrets_fetch_trust_account_password_legacy(const char *domain,
371 uint8 ret_pwd[16],
372 time_t *pass_last_set_time,
373 uint32 *channel)
375 struct machine_acct_pass *pass;
376 size_t size = 0;
378 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
379 trust_keystr(domain), &size))) {
380 DEBUG(5, ("secrets_fetch failed!\n"));
381 return False;
384 if (size != sizeof(*pass)) {
385 DEBUG(0, ("secrets were of incorrect size!\n"));
386 return False;
389 if (pass_last_set_time) {
390 *pass_last_set_time = pass->mod_time;
392 memcpy(ret_pwd, pass->hash, 16);
394 if (channel) {
395 *channel = get_default_sec_channel();
398 /* Test if machine password has expired and needs to be changed */
399 if (lp_machine_password_timeout()) {
400 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
401 (time_t)lp_machine_password_timeout())) {
402 global_machine_password_needs_changing = True;
406 SAFE_FREE(pass);
407 return True;
410 /************************************************************************
411 Routine to get the trust account password for a domain.
412 The user of this function must have locked the trust password file using
413 the above secrets_lock_trust_account_password().
414 ************************************************************************/
416 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
417 time_t *pass_last_set_time,
418 uint32 *channel)
420 char *plaintext;
422 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
423 channel);
424 if (plaintext) {
425 DEBUG(4,("Using cleartext machine password\n"));
426 E_md4hash(plaintext, ret_pwd);
427 SAFE_FREE(plaintext);
428 return True;
431 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
432 pass_last_set_time,
433 channel);
437 * Pack SID passed by pointer
439 * @param pack_buf pointer to buffer which is to be filled with packed data
440 * @param bufsize size of packing buffer
441 * @param sid pointer to sid to be packed
443 * @return length of the packed representation of the whole structure
445 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
447 int idx;
448 size_t len = 0;
449 uint8 *p = pack_buf;
450 int remaining_space = pack_buf ? bufsize : 0;
452 if (!sid) {
453 return -1;
456 len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
457 sid->num_auths);
458 if (pack_buf) {
459 p = pack_buf + len;
460 remaining_space = bufsize - len;
463 for (idx = 0; idx < 6; idx++) {
464 len += tdb_pack(p, remaining_space, "b",
465 sid->id_auth[idx]);
466 if (pack_buf) {
467 p = pack_buf + len;
468 remaining_space = bufsize - len;
472 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
473 len += tdb_pack(p, remaining_space, "d",
474 sid->sub_auths[idx]);
475 if (pack_buf) {
476 p = pack_buf + len;
477 remaining_space = bufsize - len;
481 return len;
485 * Unpack SID into a pointer
487 * @param pack_buf pointer to buffer with packed representation
488 * @param bufsize size of the buffer
489 * @param sid pointer to sid structure to be filled with unpacked data
491 * @return size of structure unpacked from buffer
493 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
495 int idx, len = 0;
497 if (!sid || !pack_buf) return -1;
499 len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
500 &sid->sid_rev_num, &sid->num_auths);
502 for (idx = 0; idx < 6; idx++) {
503 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
504 &sid->id_auth[idx]);
507 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
508 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
509 &sid->sub_auths[idx]);
512 return len;
516 * Pack TRUSTED_DOM_PASS passed by pointer
518 * @param pack_buf pointer to buffer which is to be filled with packed data
519 * @param bufsize size of the buffer
520 * @param pass pointer to trusted domain password to be packed
522 * @return length of the packed representation of the whole structure
524 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
525 TRUSTED_DOM_PASS* pass)
527 int idx, len = 0;
528 uint8 *p = pack_buf;
529 int remaining_space = pack_buf ? bufsize : 0;
531 if (!pass) {
532 return -1;
535 /* packing unicode domain name and password */
536 len += tdb_pack(p, remaining_space, "d",
537 pass->uni_name_len);
538 if (pack_buf) {
539 p = pack_buf + len;
540 remaining_space = bufsize - len;
543 for (idx = 0; idx < 32; idx++) {
544 len += tdb_pack(p, remaining_space, "w",
545 pass->uni_name[idx]);
546 if (pack_buf) {
547 p = pack_buf + len;
548 remaining_space = bufsize - len;
552 len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
553 pass->pass, pass->mod_time);
554 if (pack_buf) {
555 p = pack_buf + len;
556 remaining_space = bufsize - len;
559 /* packing SID structure */
560 len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
561 if (pack_buf) {
562 p = pack_buf + len;
563 remaining_space = bufsize - len;
566 return len;
571 * Unpack TRUSTED_DOM_PASS passed by pointer
573 * @param pack_buf pointer to buffer with packed representation
574 * @param bufsize size of the buffer
575 * @param pass pointer to trusted domain password to be filled with unpacked data
577 * @return size of structure unpacked from buffer
579 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
580 TRUSTED_DOM_PASS* pass)
582 int idx, len = 0;
583 char *passp = NULL;
585 if (!pack_buf || !pass) return -1;
587 /* unpack unicode domain name and plaintext password */
588 len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
590 for (idx = 0; idx < 32; idx++)
591 len += tdb_unpack(pack_buf + len, bufsize - len, "w",
592 &pass->uni_name[idx]);
594 len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
595 &pass->pass_len, &passp, &pass->mod_time);
596 if (passp) {
597 fstrcpy(pass->pass, passp);
599 SAFE_FREE(passp);
601 /* unpack domain sid */
602 len += tdb_sid_unpack(pack_buf + len, bufsize - len,
603 &pass->domain_sid);
605 return len;
608 /************************************************************************
609 Routine to get account password to trusted domain
610 ************************************************************************/
612 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
613 DOM_SID *sid, time_t *pass_last_set_time)
615 struct trusted_dom_pass pass;
616 size_t size = 0;
618 /* unpacking structures */
619 uint8 *pass_buf;
620 int pass_len = 0;
622 ZERO_STRUCT(pass);
624 /* fetching trusted domain password structure */
625 if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
626 &size))) {
627 DEBUG(5, ("secrets_fetch failed!\n"));
628 return False;
631 /* unpack trusted domain password */
632 pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
633 SAFE_FREE(pass_buf);
635 if (pass_len != size) {
636 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
637 return False;
640 /* the trust's password */
641 if (pwd) {
642 *pwd = SMB_STRDUP(pass.pass);
643 if (!*pwd) {
644 return False;
648 /* last change time */
649 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
651 /* domain sid */
652 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
654 return True;
658 * Routine to store the password for trusted domain
660 * @param domain remote domain name
661 * @param pwd plain text password of trust relationship
662 * @param sid remote domain sid
664 * @return true if succeeded
667 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
668 const DOM_SID *sid)
670 smb_ucs2_t *uni_dom_name;
671 bool ret;
673 /* packing structures */
674 uint8 *pass_buf = NULL;
675 int pass_len = 0;
677 struct trusted_dom_pass pass;
678 ZERO_STRUCT(pass);
680 if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
681 DEBUG(0, ("Could not convert domain name %s to unicode\n",
682 domain));
683 return False;
686 strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
687 pass.uni_name_len = strlen_w(uni_dom_name)+1;
688 SAFE_FREE(uni_dom_name);
690 /* last change time */
691 pass.mod_time = time(NULL);
693 /* password of the trust */
694 pass.pass_len = strlen(pwd);
695 fstrcpy(pass.pass, pwd);
697 /* domain sid */
698 sid_copy(&pass.domain_sid, sid);
700 /* Calculate the length. */
701 pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
702 pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
703 if (!pass_buf) {
704 return false;
706 pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
707 ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
708 pass_len);
709 SAFE_FREE(pass_buf);
710 return ret;
713 /************************************************************************
714 Routine to delete the plaintext machine account password
715 ************************************************************************/
717 bool secrets_delete_machine_password(const char *domain)
719 return secrets_delete(machine_password_keystr(domain));
722 /************************************************************************
723 Routine to delete the plaintext machine account password, sec channel type and
724 last change time from secrets database
725 ************************************************************************/
727 bool secrets_delete_machine_password_ex(const char *domain)
729 if (!secrets_delete(machine_password_keystr(domain))) {
730 return false;
732 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
733 return false;
735 return secrets_delete(machine_last_change_time_keystr(domain));
738 /************************************************************************
739 Routine to delete the domain sid
740 ************************************************************************/
742 bool secrets_delete_domain_sid(const char *domain)
744 return secrets_delete(domain_sid_keystr(domain));
747 /************************************************************************
748 Routine to set the plaintext machine account password for a realm
749 the password is assumed to be a null terminated ascii string
750 ************************************************************************/
752 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
754 bool ret;
755 uint32 last_change_time;
756 uint32 sec_channel_type;
758 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
759 if (!ret)
760 return ret;
762 SIVAL(&last_change_time, 0, time(NULL));
763 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
765 SIVAL(&sec_channel_type, 0, sec_channel);
766 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
768 return ret;
771 /************************************************************************
772 Routine to fetch the plaintext machine account password for a realm
773 the password is assumed to be a null terminated ascii string.
774 ************************************************************************/
776 char *secrets_fetch_machine_password(const char *domain,
777 time_t *pass_last_set_time,
778 uint32 *channel)
780 char *ret;
781 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
783 if (pass_last_set_time) {
784 size_t size;
785 uint32 *last_set_time;
786 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
787 if (last_set_time) {
788 *pass_last_set_time = IVAL(last_set_time,0);
789 SAFE_FREE(last_set_time);
790 } else {
791 *pass_last_set_time = 0;
795 if (channel) {
796 size_t size;
797 uint32 *channel_type;
798 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
799 if (channel_type) {
800 *channel = IVAL(channel_type,0);
801 SAFE_FREE(channel_type);
802 } else {
803 *channel = get_default_sec_channel();
807 return ret;
810 /************************************************************************
811 Routine to delete the password for trusted domain
812 ************************************************************************/
814 bool trusted_domain_password_delete(const char *domain)
816 return secrets_delete(trustdom_keystr(domain));
819 bool secrets_store_ldap_pw(const char* dn, char* pw)
821 char *key = NULL;
822 bool ret;
824 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
825 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
826 return False;
829 ret = secrets_store(key, pw, strlen(pw)+1);
831 SAFE_FREE(key);
832 return ret;
835 /*******************************************************************
836 Find the ldap password.
837 ******************************************************************/
839 bool fetch_ldap_pw(char **dn, char** pw)
841 char *key = NULL;
842 size_t size = 0;
844 *dn = smb_xstrdup(lp_ldap_admin_dn());
846 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
847 SAFE_FREE(*dn);
848 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
851 *pw=(char *)secrets_fetch(key, &size);
852 SAFE_FREE(key);
854 if (!size) {
855 /* Upgrade 2.2 style entry */
856 char *p;
857 char* old_style_key = SMB_STRDUP(*dn);
858 char *data;
859 fstring old_style_pw;
861 if (!old_style_key) {
862 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
863 return False;
866 for (p=old_style_key; *p; p++)
867 if (*p == ',') *p = '/';
869 data=(char *)secrets_fetch(old_style_key, &size);
870 if (!size && size < sizeof(old_style_pw)) {
871 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
872 SAFE_FREE(old_style_key);
873 SAFE_FREE(*dn);
874 return False;
877 size = MIN(size, sizeof(fstring)-1);
878 strncpy(old_style_pw, data, size);
879 old_style_pw[size] = 0;
881 SAFE_FREE(data);
883 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
884 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
885 SAFE_FREE(old_style_key);
886 SAFE_FREE(*dn);
887 return False;
889 if (!secrets_delete(old_style_key)) {
890 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
893 SAFE_FREE(old_style_key);
895 *pw = smb_xstrdup(old_style_pw);
898 return True;
902 * Get trusted domains info from secrets.tdb.
905 struct list_trusted_domains_state {
906 uint32 num_domains;
907 struct trustdom_info **domains;
910 static int list_trusted_domain(struct db_record *rec, void *private_data)
912 const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
913 size_t packed_size = 0;
914 struct trusted_dom_pass pass;
915 struct trustdom_info *dom_info;
917 struct list_trusted_domains_state *state =
918 (struct list_trusted_domains_state *)private_data;
920 if ((rec->key.dsize < prefix_len)
921 || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
922 prefix_len) != 0)) {
923 return 0;
926 packed_size = tdb_trusted_dom_pass_unpack(
927 rec->value.dptr, rec->value.dsize, &pass);
929 if (rec->value.dsize != packed_size) {
930 DEBUG(2, ("Secrets record is invalid!\n"));
931 return 0;
934 if (pass.domain_sid.num_auths != 4) {
935 DEBUG(0, ("SID %s is not a domain sid, has %d "
936 "auths instead of 4\n",
937 sid_string_dbg(&pass.domain_sid),
938 pass.domain_sid.num_auths));
939 return 0;
942 if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
943 DEBUG(0, ("talloc failed\n"));
944 return 0;
947 if (pull_ucs2_talloc(dom_info, &dom_info->name,
948 pass.uni_name) == (size_t)-1) {
949 DEBUG(2, ("pull_ucs2_talloc failed\n"));
950 TALLOC_FREE(dom_info);
951 return 0;
954 sid_copy(&dom_info->sid, &pass.domain_sid);
956 ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
957 &state->domains, &state->num_domains);
959 if (state->domains == NULL) {
960 state->num_domains = 0;
961 return -1;
963 return 0;
966 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
967 struct trustdom_info ***domains)
969 struct list_trusted_domains_state state;
971 secrets_init();
973 if (db_ctx == NULL) {
974 return NT_STATUS_ACCESS_DENIED;
977 state.num_domains = 0;
980 * Make sure that a talloc context for the trustdom_info structs
981 * exists
984 if (!(state.domains = TALLOC_ARRAY(
985 mem_ctx, struct trustdom_info *, 1))) {
986 return NT_STATUS_NO_MEMORY;
989 db_ctx->traverse(db_ctx, list_trusted_domain, (void *)&state);
991 *num_domains = state.num_domains;
992 *domains = state.domains;
993 return NT_STATUS_OK;
996 /*******************************************************************************
997 Store a complete AFS keyfile into secrets.tdb.
998 *******************************************************************************/
1000 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1002 fstring key;
1004 if ((cell == NULL) || (keyfile == NULL))
1005 return False;
1007 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1008 return False;
1010 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1011 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1014 /*******************************************************************************
1015 Fetch the current (highest) AFS key from secrets.tdb
1016 *******************************************************************************/
1017 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1019 fstring key;
1020 struct afs_keyfile *keyfile;
1021 size_t size = 0;
1022 uint32 i;
1024 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1026 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1028 if (keyfile == NULL)
1029 return False;
1031 if (size != sizeof(struct afs_keyfile)) {
1032 SAFE_FREE(keyfile);
1033 return False;
1036 i = ntohl(keyfile->nkeys);
1038 if (i > SECRETS_AFS_MAXKEYS) {
1039 SAFE_FREE(keyfile);
1040 return False;
1043 *result = keyfile->entry[i-1];
1045 result->kvno = ntohl(result->kvno);
1047 return True;
1050 /******************************************************************************
1051 When kerberos is not available, choose between anonymous or
1052 authenticated connections.
1054 We need to use an authenticated connection if DCs have the
1055 RestrictAnonymous registry entry set > 0, or the "Additional
1056 restrictions for anonymous connections" set in the win2k Local
1057 Security Policy.
1059 Caller to free() result in domain, username, password
1060 *******************************************************************************/
1061 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1063 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1064 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1065 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1067 if (*username && **username) {
1069 if (!*domain || !**domain)
1070 *domain = smb_xstrdup(lp_workgroup());
1072 if (!*password || !**password)
1073 *password = smb_xstrdup("");
1075 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1076 *domain, *username));
1078 } else {
1079 DEBUG(3, ("IPC$ connections done anonymously\n"));
1080 *username = smb_xstrdup("");
1081 *domain = smb_xstrdup("");
1082 *password = smb_xstrdup("");
1086 /******************************************************************************
1087 Open or create the schannel session store tdb.
1088 *******************************************************************************/
1090 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1092 TDB_DATA vers;
1093 uint32 ver;
1094 TDB_CONTEXT *tdb_sc = NULL;
1095 char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1097 if (!fname) {
1098 return NULL;
1101 tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1103 if (!tdb_sc) {
1104 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1105 TALLOC_FREE(fname);
1106 return NULL;
1109 vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1110 if (vers.dptr == NULL) {
1111 /* First opener, no version. */
1112 SIVAL(&ver,0,1);
1113 vers.dptr = (uint8 *)&ver;
1114 vers.dsize = 4;
1115 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1116 vers.dptr = NULL;
1117 } else if (vers.dsize == 4) {
1118 ver = IVAL(vers.dptr,0);
1119 if (ver != 1) {
1120 tdb_close(tdb_sc);
1121 tdb_sc = NULL;
1122 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1123 (int)ver, fname ));
1125 } else {
1126 tdb_close(tdb_sc);
1127 tdb_sc = NULL;
1128 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1129 (int)vers.dsize, fname ));
1132 SAFE_FREE(vers.dptr);
1133 TALLOC_FREE(fname);
1135 return tdb_sc;
1138 /******************************************************************************
1139 Store the schannel state after an AUTH2 call.
1140 Note we must be root here.
1141 *******************************************************************************/
1143 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1144 const char *remote_machine,
1145 const struct dcinfo *pdc)
1147 TDB_CONTEXT *tdb_sc = NULL;
1148 TDB_DATA value;
1149 bool ret;
1150 char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1151 SECRETS_SCHANNEL_STATE,
1152 remote_machine);
1153 if (!keystr) {
1154 return False;
1157 /* Work out how large the record is. */
1158 value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1159 pdc->sequence,
1160 8, pdc->seed_chal.data,
1161 8, pdc->clnt_chal.data,
1162 8, pdc->srv_chal.data,
1163 16, pdc->sess_key,
1164 16, pdc->mach_pw,
1165 pdc->mach_acct,
1166 pdc->remote_machine,
1167 pdc->domain);
1169 value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1170 if (!value.dptr) {
1171 TALLOC_FREE(keystr);
1172 return False;
1175 value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1176 pdc->sequence,
1177 8, pdc->seed_chal.data,
1178 8, pdc->clnt_chal.data,
1179 8, pdc->srv_chal.data,
1180 16, pdc->sess_key,
1181 16, pdc->mach_pw,
1182 pdc->mach_acct,
1183 pdc->remote_machine,
1184 pdc->domain);
1186 tdb_sc = open_schannel_session_store(mem_ctx);
1187 if (!tdb_sc) {
1188 TALLOC_FREE(keystr);
1189 TALLOC_FREE(value.dptr);
1190 return False;
1193 ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1195 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1196 keystr ));
1198 tdb_close(tdb_sc);
1199 TALLOC_FREE(keystr);
1200 TALLOC_FREE(value.dptr);
1201 return ret;
1204 /******************************************************************************
1205 Restore the schannel state on a client reconnect.
1206 Note we must be root here.
1207 *******************************************************************************/
1209 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1210 const char *remote_machine,
1211 struct dcinfo **ppdc)
1213 TDB_CONTEXT *tdb_sc = NULL;
1214 TDB_DATA value;
1215 unsigned char *pseed_chal = NULL;
1216 unsigned char *pclnt_chal = NULL;
1217 unsigned char *psrv_chal = NULL;
1218 unsigned char *psess_key = NULL;
1219 unsigned char *pmach_pw = NULL;
1220 uint32 l1, l2, l3, l4, l5;
1221 int ret;
1222 struct dcinfo *pdc = NULL;
1223 char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1224 SECRETS_SCHANNEL_STATE,
1225 remote_machine);
1227 *ppdc = NULL;
1229 if (!keystr) {
1230 return False;
1233 tdb_sc = open_schannel_session_store(mem_ctx);
1234 if (!tdb_sc) {
1235 TALLOC_FREE(keystr);
1236 return False;
1239 value = tdb_fetch_bystring(tdb_sc, keystr);
1240 if (!value.dptr) {
1241 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1242 keystr ));
1243 tdb_close(tdb_sc);
1244 return False;
1247 pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1249 /* Retrieve the record. */
1250 ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1251 &pdc->sequence,
1252 &l1, &pseed_chal,
1253 &l2, &pclnt_chal,
1254 &l3, &psrv_chal,
1255 &l4, &psess_key,
1256 &l5, &pmach_pw,
1257 &pdc->mach_acct,
1258 &pdc->remote_machine,
1259 &pdc->domain);
1261 if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1262 /* Bad record - delete it. */
1263 tdb_delete_bystring(tdb_sc, keystr);
1264 tdb_close(tdb_sc);
1265 TALLOC_FREE(keystr);
1266 TALLOC_FREE(pdc);
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 SAFE_FREE(value.dptr);
1273 return False;
1276 tdb_close(tdb_sc);
1278 memcpy(pdc->seed_chal.data, pseed_chal, 8);
1279 memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1280 memcpy(pdc->srv_chal.data, psrv_chal, 8);
1281 memcpy(pdc->sess_key, psess_key, 16);
1282 memcpy(pdc->mach_pw, pmach_pw, 16);
1284 /* We know these are true so didn't bother to store them. */
1285 pdc->challenge_sent = True;
1286 pdc->authenticated = True;
1288 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1289 keystr ));
1291 SAFE_FREE(pseed_chal);
1292 SAFE_FREE(pclnt_chal);
1293 SAFE_FREE(psrv_chal);
1294 SAFE_FREE(psess_key);
1295 SAFE_FREE(pmach_pw);
1297 TALLOC_FREE(keystr);
1298 SAFE_FREE(value.dptr);
1300 *ppdc = pdc;
1302 return True;
1305 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1307 char *tdbkey = NULL;
1308 bool ret;
1310 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1311 DEBUG(0, ("asprintf failed!\n"));
1312 return False;
1315 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1317 SAFE_FREE(tdbkey);
1318 return ret;
1321 /*******************************************************************
1322 Find the ldap password.
1323 ******************************************************************/
1325 char *secrets_fetch_generic(const char *owner, const char *key)
1327 char *secret = NULL;
1328 char *tdbkey = NULL;
1330 if (( ! owner) || ( ! key)) {
1331 DEBUG(1, ("Invalid Paramters"));
1332 return NULL;
1335 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1336 DEBUG(0, ("Out of memory!\n"));
1337 return NULL;
1340 secret = (char *)secrets_fetch(tdbkey, NULL);
1341 SAFE_FREE(tdbkey);
1343 return secret;