Avoid some pointless checks
[Samba.git] / source / passdb / secrets.c
blobd88c53897d05e56d589c50b725a71874f69ce235
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 TDB_CONTEXT *tdb;
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 (tdb) {
47 tdb_change_int32_atomic(tdb, "INFO/random_seed", new_seed, 1);
51 /* open up the secrets database */
52 bool secrets_init(void)
54 char *fname = NULL;
55 unsigned char dummy;
57 if (tdb)
58 return True;
60 fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
61 lp_private_dir());
62 if (fname == NULL) {
63 return false;
66 tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
68 if (!tdb) {
69 DEBUG(0,("Failed to open %s\n", fname));
70 TALLOC_FREE(fname);
71 return False;
74 TALLOC_FREE(fname);
76 /**
77 * Set a reseed function for the crypto random generator
79 * This avoids a problem where systems without /dev/urandom
80 * could send the same challenge to multiple clients
82 set_rand_reseed_callback(get_rand_seed);
84 /* Ensure that the reseed is done now, while we are root, etc */
85 generate_random_buffer(&dummy, sizeof(dummy));
87 return True;
91 * close secrets.tdb
93 void secrets_shutdown(void)
95 if (!tdb) {
96 return;
99 tdb_close(tdb);
100 tdb = NULL;
103 /* read a entry from the secrets database - the caller must free the result
104 if size is non-null then the size of the entry is put in there
106 void *secrets_fetch(const char *key, size_t *size)
108 TDB_DATA dbuf;
110 if (!secrets_init()) {
111 return NULL;
114 dbuf = tdb_fetch(tdb, string_tdb_data(key));
115 if (size) {
116 *size = dbuf.dsize;
119 return dbuf.dptr;
122 /* store a secrets entry
124 bool secrets_store(const char *key, const void *data, size_t size)
126 if (!secrets_init()) {
127 return false;
130 return tdb_trans_store(tdb, string_tdb_data(key),
131 make_tdb_data((const uint8 *)data, size),
132 TDB_REPLACE) == 0;
136 /* delete a secets database entry
138 bool secrets_delete(const char *key)
140 if (!secrets_init()) {
141 return false;
144 return tdb_trans_delete(tdb, string_tdb_data(key)) == 0;
148 * Form a key for fetching the domain sid
150 * @param domain domain name
152 * @return keystring
154 static const char *domain_sid_keystr(const char *domain)
156 char *keystr;
158 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
159 SECRETS_DOMAIN_SID, domain);
160 SMB_ASSERT(keystr != NULL);
162 strupper_m(keystr);
164 return keystr;
167 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
169 bool ret;
171 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
173 /* Force a re-query, in case we modified our domain */
174 if (ret)
175 reset_global_sam_sid();
176 return ret;
179 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
181 DOM_SID *dyn_sid;
182 size_t size = 0;
184 dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
186 if (dyn_sid == NULL)
187 return False;
189 if (size != sizeof(DOM_SID)) {
190 SAFE_FREE(dyn_sid);
191 return False;
194 *sid = *dyn_sid;
195 SAFE_FREE(dyn_sid);
196 return True;
199 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
201 fstring key;
203 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
204 strupper_m(key);
205 return secrets_store(key, guid, sizeof(struct GUID));
208 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
210 struct GUID *dyn_guid;
211 fstring key;
212 size_t size = 0;
213 struct GUID new_guid;
215 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
216 strupper_m(key);
217 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
219 if (!dyn_guid) {
220 if (lp_server_role() == ROLE_DOMAIN_PDC) {
221 smb_uuid_generate_random(&new_guid);
222 if (!secrets_store_domain_guid(domain, &new_guid))
223 return False;
224 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
226 if (dyn_guid == NULL) {
227 return False;
231 if (size != sizeof(struct GUID)) {
232 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
233 SAFE_FREE(dyn_guid);
234 return False;
237 *guid = *dyn_guid;
238 SAFE_FREE(dyn_guid);
239 return True;
243 * Form a key for fetching the machine trust account sec channel type
245 * @param domain domain name
247 * @return keystring
249 static const char *machine_sec_channel_type_keystr(const char *domain)
251 char *keystr;
253 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
254 SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
255 SMB_ASSERT(keystr != NULL);
257 strupper_m(keystr);
259 return keystr;
263 * Form a key for fetching the machine trust account last change time
265 * @param domain domain name
267 * @return keystring
269 static const char *machine_last_change_time_keystr(const char *domain)
271 char *keystr;
273 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
274 SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
275 SMB_ASSERT(keystr != NULL);
277 strupper_m(keystr);
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(talloc_tos(), "%s/%s",
295 SECRETS_MACHINE_PASSWORD, domain);
296 SMB_ASSERT(keystr != NULL);
298 strupper_m(keystr);
300 return keystr;
304 * Form a key for fetching the machine trust account password
306 * @param domain domain name
308 * @return stored password's key
310 static const char *trust_keystr(const char *domain)
312 char *keystr;
314 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
315 SECRETS_MACHINE_ACCT_PASS, domain);
316 SMB_ASSERT(keystr != NULL);
318 strupper_m(keystr);
320 return keystr;
324 * Form a key for fetching a trusted domain password
326 * @param domain trusted domain name
328 * @return stored password's key
330 static char *trustdom_keystr(const char *domain)
332 char *keystr;
334 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
335 SECRETS_DOMTRUST_ACCT_PASS, domain);
336 SMB_ASSERT(keystr != NULL);
337 strupper_m(keystr);
339 return keystr;
342 /************************************************************************
343 Lock the trust password entry.
344 ************************************************************************/
346 bool secrets_lock_trust_account_password(const char *domain, bool dolock)
348 if (!tdb)
349 return False;
351 if (dolock)
352 return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
353 else
354 tdb_unlock_bystring(tdb, trust_keystr(domain));
355 return True;
358 /************************************************************************
359 Routine to get the default secure channel type for trust accounts
360 ************************************************************************/
362 uint32 get_default_sec_channel(void)
364 if (lp_server_role() == ROLE_DOMAIN_BDC ||
365 lp_server_role() == ROLE_DOMAIN_PDC) {
366 return SEC_CHAN_BDC;
367 } else {
368 return SEC_CHAN_WKSTA;
372 /************************************************************************
373 Routine to get the trust account password for a domain.
374 This only tries to get the legacy hashed version of the password.
375 The user of this function must have locked the trust password file using
376 the above secrets_lock_trust_account_password().
377 ************************************************************************/
379 bool secrets_fetch_trust_account_password_legacy(const char *domain,
380 uint8 ret_pwd[16],
381 time_t *pass_last_set_time,
382 uint32 *channel)
384 struct machine_acct_pass *pass;
385 size_t size = 0;
387 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
388 trust_keystr(domain), &size))) {
389 DEBUG(5, ("secrets_fetch failed!\n"));
390 return False;
393 if (size != sizeof(*pass)) {
394 DEBUG(0, ("secrets were of incorrect size!\n"));
395 return False;
398 if (pass_last_set_time) {
399 *pass_last_set_time = pass->mod_time;
401 memcpy(ret_pwd, pass->hash, 16);
403 if (channel) {
404 *channel = get_default_sec_channel();
407 /* Test if machine password has expired and needs to be changed */
408 if (lp_machine_password_timeout()) {
409 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
410 (time_t)lp_machine_password_timeout())) {
411 global_machine_password_needs_changing = True;
415 SAFE_FREE(pass);
416 return True;
419 /************************************************************************
420 Routine to get the trust account password for a domain.
421 The user of this function must have locked the trust password file using
422 the above secrets_lock_trust_account_password().
423 ************************************************************************/
425 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
426 time_t *pass_last_set_time,
427 uint32 *channel)
429 char *plaintext;
431 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
432 channel);
433 if (plaintext) {
434 DEBUG(4,("Using cleartext machine password\n"));
435 E_md4hash(plaintext, ret_pwd);
436 SAFE_FREE(plaintext);
437 return True;
440 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
441 pass_last_set_time,
442 channel);
446 * Pack SID passed by pointer
448 * @param pack_buf pointer to buffer which is to be filled with packed data
449 * @param bufsize size of packing buffer
450 * @param sid pointer to sid to be packed
452 * @return length of the packed representation of the whole structure
454 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
456 int idx;
457 size_t len = 0;
458 uint8 *p = pack_buf;
459 int remaining_space = pack_buf ? bufsize : 0;
461 if (!sid) {
462 return -1;
465 len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
466 sid->num_auths);
467 if (pack_buf) {
468 p = pack_buf + len;
469 remaining_space = bufsize - len;
472 for (idx = 0; idx < 6; idx++) {
473 len += tdb_pack(p, remaining_space, "b",
474 sid->id_auth[idx]);
475 if (pack_buf) {
476 p = pack_buf + len;
477 remaining_space = bufsize - len;
481 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
482 len += tdb_pack(p, remaining_space, "d",
483 sid->sub_auths[idx]);
484 if (pack_buf) {
485 p = pack_buf + len;
486 remaining_space = bufsize - len;
490 return len;
494 * Unpack SID into a pointer
496 * @param pack_buf pointer to buffer with packed representation
497 * @param bufsize size of the buffer
498 * @param sid pointer to sid structure to be filled with unpacked data
500 * @return size of structure unpacked from buffer
502 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
504 int idx, len = 0;
506 if (!sid || !pack_buf) return -1;
508 len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
509 &sid->sid_rev_num, &sid->num_auths);
511 for (idx = 0; idx < 6; idx++) {
512 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
513 &sid->id_auth[idx]);
516 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
517 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
518 &sid->sub_auths[idx]);
521 return len;
525 * Pack TRUSTED_DOM_PASS passed by pointer
527 * @param pack_buf pointer to buffer which is to be filled with packed data
528 * @param bufsize size of the buffer
529 * @param pass pointer to trusted domain password to be packed
531 * @return length of the packed representation of the whole structure
533 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
534 TRUSTED_DOM_PASS* pass)
536 int idx, len = 0;
537 uint8 *p = pack_buf;
538 int remaining_space = pack_buf ? bufsize : 0;
540 if (!pass) {
541 return -1;
544 /* packing unicode domain name and password */
545 len += tdb_pack(p, remaining_space, "d",
546 pass->uni_name_len);
547 if (pack_buf) {
548 p = pack_buf + len;
549 remaining_space = bufsize - len;
552 for (idx = 0; idx < 32; idx++) {
553 len += tdb_pack(p, remaining_space, "w",
554 pass->uni_name[idx]);
555 if (pack_buf) {
556 p = pack_buf + len;
557 remaining_space = bufsize - len;
561 len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
562 pass->pass, pass->mod_time);
563 if (pack_buf) {
564 p = pack_buf + len;
565 remaining_space = bufsize - len;
568 /* packing SID structure */
569 len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
570 if (pack_buf) {
571 p = pack_buf + len;
572 remaining_space = bufsize - len;
575 return len;
580 * Unpack TRUSTED_DOM_PASS passed by pointer
582 * @param pack_buf pointer to buffer with packed representation
583 * @param bufsize size of the buffer
584 * @param pass pointer to trusted domain password to be filled with unpacked data
586 * @return size of structure unpacked from buffer
588 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
589 TRUSTED_DOM_PASS* pass)
591 int idx, len = 0;
592 char *passp = NULL;
594 if (!pack_buf || !pass) return -1;
596 /* unpack unicode domain name and plaintext password */
597 len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
599 for (idx = 0; idx < 32; idx++)
600 len += tdb_unpack(pack_buf + len, bufsize - len, "w",
601 &pass->uni_name[idx]);
603 len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
604 &pass->pass_len, &passp, &pass->mod_time);
605 if (passp) {
606 fstrcpy(pass->pass, passp);
608 SAFE_FREE(passp);
610 /* unpack domain sid */
611 len += tdb_sid_unpack(pack_buf + len, bufsize - len,
612 &pass->domain_sid);
614 return len;
617 /************************************************************************
618 Routine to get account password to trusted domain
619 ************************************************************************/
621 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
622 DOM_SID *sid, time_t *pass_last_set_time)
624 struct trusted_dom_pass pass;
625 size_t size = 0;
627 /* unpacking structures */
628 uint8 *pass_buf;
629 int pass_len = 0;
631 ZERO_STRUCT(pass);
633 /* fetching trusted domain password structure */
634 if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
635 &size))) {
636 DEBUG(5, ("secrets_fetch failed!\n"));
637 return False;
640 /* unpack trusted domain password */
641 pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
642 SAFE_FREE(pass_buf);
644 if (pass_len != size) {
645 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
646 return False;
649 /* the trust's password */
650 if (pwd) {
651 *pwd = SMB_STRDUP(pass.pass);
652 if (!*pwd) {
653 return False;
657 /* last change time */
658 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
660 /* domain sid */
661 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
663 return True;
667 * Routine to store the password for trusted domain
669 * @param domain remote domain name
670 * @param pwd plain text password of trust relationship
671 * @param sid remote domain sid
673 * @return true if succeeded
676 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
677 const DOM_SID *sid)
679 smb_ucs2_t *uni_dom_name;
680 bool ret;
682 /* packing structures */
683 uint8 *pass_buf = NULL;
684 int pass_len = 0;
686 struct trusted_dom_pass pass;
687 ZERO_STRUCT(pass);
689 if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
690 DEBUG(0, ("Could not convert domain name %s to unicode\n",
691 domain));
692 return False;
695 strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
696 pass.uni_name_len = strlen_w(uni_dom_name)+1;
697 SAFE_FREE(uni_dom_name);
699 /* last change time */
700 pass.mod_time = time(NULL);
702 /* password of the trust */
703 pass.pass_len = strlen(pwd);
704 fstrcpy(pass.pass, pwd);
706 /* domain sid */
707 sid_copy(&pass.domain_sid, sid);
709 /* Calculate the length. */
710 pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
711 pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
712 if (!pass_buf) {
713 return false;
715 pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
716 ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
717 pass_len);
718 SAFE_FREE(pass_buf);
719 return ret;
722 /************************************************************************
723 Routine to delete the plaintext machine account password
724 ************************************************************************/
726 bool secrets_delete_machine_password(const char *domain)
728 return secrets_delete(machine_password_keystr(domain));
731 /************************************************************************
732 Routine to delete the plaintext machine account password, sec channel type and
733 last change time from secrets database
734 ************************************************************************/
736 bool secrets_delete_machine_password_ex(const char *domain)
738 if (!secrets_delete(machine_password_keystr(domain))) {
739 return false;
741 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
742 return false;
744 return secrets_delete(machine_last_change_time_keystr(domain));
747 /************************************************************************
748 Routine to delete the domain sid
749 ************************************************************************/
751 bool secrets_delete_domain_sid(const char *domain)
753 return secrets_delete(domain_sid_keystr(domain));
756 /************************************************************************
757 Routine to set the plaintext machine account password for a realm
758 the password is assumed to be a null terminated ascii string
759 ************************************************************************/
761 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
763 bool ret;
764 uint32 last_change_time;
765 uint32 sec_channel_type;
767 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
768 if (!ret)
769 return ret;
771 SIVAL(&last_change_time, 0, time(NULL));
772 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
774 SIVAL(&sec_channel_type, 0, sec_channel);
775 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
777 return ret;
780 /************************************************************************
781 Routine to fetch the plaintext machine account password for a realm
782 the password is assumed to be a null terminated ascii string.
783 ************************************************************************/
785 char *secrets_fetch_machine_password(const char *domain,
786 time_t *pass_last_set_time,
787 uint32 *channel)
789 char *ret;
790 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
792 if (pass_last_set_time) {
793 size_t size;
794 uint32 *last_set_time;
795 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
796 if (last_set_time) {
797 *pass_last_set_time = IVAL(last_set_time,0);
798 SAFE_FREE(last_set_time);
799 } else {
800 *pass_last_set_time = 0;
804 if (channel) {
805 size_t size;
806 uint32 *channel_type;
807 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
808 if (channel_type) {
809 *channel = IVAL(channel_type,0);
810 SAFE_FREE(channel_type);
811 } else {
812 *channel = get_default_sec_channel();
816 return ret;
819 /************************************************************************
820 Routine to delete the password for trusted domain
821 ************************************************************************/
823 bool trusted_domain_password_delete(const char *domain)
825 return secrets_delete(trustdom_keystr(domain));
828 bool secrets_store_ldap_pw(const char* dn, char* pw)
830 char *key = NULL;
831 bool ret;
833 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
834 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
835 return False;
838 ret = secrets_store(key, pw, strlen(pw)+1);
840 SAFE_FREE(key);
841 return ret;
844 /*******************************************************************
845 Find the ldap password.
846 ******************************************************************/
848 bool fetch_ldap_pw(char **dn, char** pw)
850 char *key = NULL;
851 size_t size = 0;
853 *dn = smb_xstrdup(lp_ldap_admin_dn());
855 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
856 SAFE_FREE(*dn);
857 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
860 *pw=(char *)secrets_fetch(key, &size);
861 SAFE_FREE(key);
863 if (!size) {
864 /* Upgrade 2.2 style entry */
865 char *p;
866 char* old_style_key = SMB_STRDUP(*dn);
867 char *data;
868 fstring old_style_pw;
870 if (!old_style_key) {
871 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
872 return False;
875 for (p=old_style_key; *p; p++)
876 if (*p == ',') *p = '/';
878 data=(char *)secrets_fetch(old_style_key, &size);
879 if (!size && size < sizeof(old_style_pw)) {
880 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
881 SAFE_FREE(old_style_key);
882 SAFE_FREE(*dn);
883 return False;
886 size = MIN(size, sizeof(fstring)-1);
887 strncpy(old_style_pw, data, size);
888 old_style_pw[size] = 0;
890 SAFE_FREE(data);
892 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
893 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
894 SAFE_FREE(old_style_key);
895 SAFE_FREE(*dn);
896 return False;
898 if (!secrets_delete(old_style_key)) {
899 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
902 SAFE_FREE(old_style_key);
904 *pw = smb_xstrdup(old_style_pw);
907 return True;
911 * Get trusted domains info from secrets.tdb.
914 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
915 struct trustdom_info ***domains)
917 TDB_LIST_NODE *keys, *k;
918 char *pattern;
919 TALLOC_CTX *tmp_ctx;
921 if (!(tmp_ctx = talloc_new(mem_ctx))) {
922 return NT_STATUS_NO_MEMORY;
925 if (!secrets_init()) {
926 return NT_STATUS_ACCESS_DENIED;
929 /* generate searching pattern */
930 pattern = talloc_asprintf(tmp_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
931 if (pattern == NULL) {
932 DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
933 "failed!\n"));
934 TALLOC_FREE(tmp_ctx);
935 return NT_STATUS_NO_MEMORY;
938 *num_domains = 0;
941 * Make sure that a talloc context for the trustdom_info structs
942 * exists
945 if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
946 TALLOC_FREE(tmp_ctx);
947 return NT_STATUS_NO_MEMORY;
950 /* fetching trusted domains' data and collecting them in a list */
951 keys = tdb_search_keys(tdb, pattern);
953 /* searching for keys in secrets db -- way to go ... */
954 for (k = keys; k; k = k->next) {
955 uint8 *packed_pass;
956 size_t size = 0, packed_size = 0;
957 struct trusted_dom_pass pass;
958 char *secrets_key;
959 struct trustdom_info *dom_info;
961 /* important: ensure null-termination of the key string */
962 secrets_key = talloc_strndup(tmp_ctx,
963 (const char *)k->node_key.dptr,
964 k->node_key.dsize);
965 if (!secrets_key) {
966 DEBUG(0, ("strndup failed!\n"));
967 tdb_search_list_free(keys);
968 TALLOC_FREE(tmp_ctx);
969 return NT_STATUS_NO_MEMORY;
972 packed_pass = (uint8 *)secrets_fetch(secrets_key, &size);
973 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
974 &pass);
975 /* packed representation isn't needed anymore */
976 SAFE_FREE(packed_pass);
978 if (size != packed_size) {
979 DEBUG(2, ("Secrets record %s is invalid!\n",
980 secrets_key));
981 continue;
984 if (pass.domain_sid.num_auths != 4) {
985 DEBUG(0, ("SID %s is not a domain sid, has %d "
986 "auths instead of 4\n",
987 sid_string_dbg(&pass.domain_sid),
988 pass.domain_sid.num_auths));
989 continue;
992 if (!(dom_info = TALLOC_P(*domains, struct trustdom_info))) {
993 DEBUG(0, ("talloc failed\n"));
994 tdb_search_list_free(keys);
995 TALLOC_FREE(tmp_ctx);
996 return NT_STATUS_NO_MEMORY;
999 if (pull_ucs2_talloc(dom_info, &dom_info->name,
1000 pass.uni_name) == (size_t)-1) {
1001 DEBUG(2, ("pull_ucs2_talloc failed\n"));
1002 tdb_search_list_free(keys);
1003 TALLOC_FREE(tmp_ctx);
1004 return NT_STATUS_NO_MEMORY;
1007 sid_copy(&dom_info->sid, &pass.domain_sid);
1009 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
1010 domains, num_domains);
1012 if (*domains == NULL) {
1013 tdb_search_list_free(keys);
1014 TALLOC_FREE(tmp_ctx);
1015 return NT_STATUS_NO_MEMORY;
1019 DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
1020 *num_domains));
1022 /* free the results of searching the keys */
1023 tdb_search_list_free(keys);
1024 TALLOC_FREE(tmp_ctx);
1026 return NT_STATUS_OK;
1029 /*******************************************************************************
1030 Lock the secrets tdb based on a string - this is used as a primitive form of mutex
1031 between smbd instances.
1032 *******************************************************************************/
1034 bool secrets_named_mutex(const char *name, unsigned int timeout)
1036 int ret = 0;
1038 if (!secrets_init()) {
1039 return false;
1042 ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
1043 if (ret == 0) {
1044 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
1047 return (ret == 0);
1050 /*******************************************************************************
1051 Unlock a named mutex.
1052 *******************************************************************************/
1054 void secrets_named_mutex_release(const char *name)
1056 tdb_unlock_bystring(tdb, name);
1057 DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
1060 /*******************************************************************************
1061 Store a complete AFS keyfile into secrets.tdb.
1062 *******************************************************************************/
1064 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1066 fstring key;
1068 if ((cell == NULL) || (keyfile == NULL))
1069 return False;
1071 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1072 return False;
1074 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1075 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1078 /*******************************************************************************
1079 Fetch the current (highest) AFS key from secrets.tdb
1080 *******************************************************************************/
1081 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1083 fstring key;
1084 struct afs_keyfile *keyfile;
1085 size_t size = 0;
1086 uint32 i;
1088 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1090 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1092 if (keyfile == NULL)
1093 return False;
1095 if (size != sizeof(struct afs_keyfile)) {
1096 SAFE_FREE(keyfile);
1097 return False;
1100 i = ntohl(keyfile->nkeys);
1102 if (i > SECRETS_AFS_MAXKEYS) {
1103 SAFE_FREE(keyfile);
1104 return False;
1107 *result = keyfile->entry[i-1];
1109 result->kvno = ntohl(result->kvno);
1111 return True;
1114 /******************************************************************************
1115 When kerberos is not available, choose between anonymous or
1116 authenticated connections.
1118 We need to use an authenticated connection if DCs have the
1119 RestrictAnonymous registry entry set > 0, or the "Additional
1120 restrictions for anonymous connections" set in the win2k Local
1121 Security Policy.
1123 Caller to free() result in domain, username, password
1124 *******************************************************************************/
1125 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1127 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1128 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1129 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1131 if (*username && **username) {
1133 if (!*domain || !**domain)
1134 *domain = smb_xstrdup(lp_workgroup());
1136 if (!*password || !**password)
1137 *password = smb_xstrdup("");
1139 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1140 *domain, *username));
1142 } else {
1143 DEBUG(3, ("IPC$ connections done anonymously\n"));
1144 *username = smb_xstrdup("");
1145 *domain = smb_xstrdup("");
1146 *password = smb_xstrdup("");
1150 /******************************************************************************
1151 Open or create the schannel session store tdb.
1152 *******************************************************************************/
1154 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1156 TDB_DATA vers;
1157 uint32 ver;
1158 TDB_CONTEXT *tdb_sc = NULL;
1159 char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1161 if (!fname) {
1162 return NULL;
1165 tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1167 if (!tdb_sc) {
1168 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1169 TALLOC_FREE(fname);
1170 return NULL;
1173 vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1174 if (vers.dptr == NULL) {
1175 /* First opener, no version. */
1176 SIVAL(&ver,0,1);
1177 vers.dptr = (uint8 *)&ver;
1178 vers.dsize = 4;
1179 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1180 vers.dptr = NULL;
1181 } else if (vers.dsize == 4) {
1182 ver = IVAL(vers.dptr,0);
1183 if (ver != 1) {
1184 tdb_close(tdb_sc);
1185 tdb_sc = NULL;
1186 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1187 (int)ver, fname ));
1189 } else {
1190 tdb_close(tdb_sc);
1191 tdb_sc = NULL;
1192 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1193 (int)vers.dsize, fname ));
1196 SAFE_FREE(vers.dptr);
1197 TALLOC_FREE(fname);
1199 return tdb_sc;
1202 /******************************************************************************
1203 Store the schannel state after an AUTH2 call.
1204 Note we must be root here.
1205 *******************************************************************************/
1207 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1208 const char *remote_machine,
1209 const struct dcinfo *pdc)
1211 TDB_CONTEXT *tdb_sc = NULL;
1212 TDB_DATA value;
1213 bool ret;
1214 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1215 remote_machine);
1216 if (!keystr) {
1217 return False;
1220 strupper_m(keystr);
1222 /* Work out how large the record is. */
1223 value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1224 pdc->sequence,
1225 8, pdc->seed_chal.data,
1226 8, pdc->clnt_chal.data,
1227 8, pdc->srv_chal.data,
1228 16, pdc->sess_key,
1229 16, pdc->mach_pw,
1230 pdc->mach_acct,
1231 pdc->remote_machine,
1232 pdc->domain);
1234 value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1235 if (!value.dptr) {
1236 TALLOC_FREE(keystr);
1237 return False;
1240 value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1241 pdc->sequence,
1242 8, pdc->seed_chal.data,
1243 8, pdc->clnt_chal.data,
1244 8, pdc->srv_chal.data,
1245 16, pdc->sess_key,
1246 16, pdc->mach_pw,
1247 pdc->mach_acct,
1248 pdc->remote_machine,
1249 pdc->domain);
1251 tdb_sc = open_schannel_session_store(mem_ctx);
1252 if (!tdb_sc) {
1253 TALLOC_FREE(keystr);
1254 TALLOC_FREE(value.dptr);
1255 return False;
1258 ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1260 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1261 keystr ));
1263 tdb_close(tdb_sc);
1264 TALLOC_FREE(keystr);
1265 TALLOC_FREE(value.dptr);
1266 return ret;
1269 /******************************************************************************
1270 Restore the schannel state on a client reconnect.
1271 Note we must be root here.
1272 *******************************************************************************/
1274 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1275 const char *remote_machine,
1276 struct dcinfo **ppdc)
1278 TDB_CONTEXT *tdb_sc = NULL;
1279 TDB_DATA value;
1280 unsigned char *pseed_chal = NULL;
1281 unsigned char *pclnt_chal = NULL;
1282 unsigned char *psrv_chal = NULL;
1283 unsigned char *psess_key = NULL;
1284 unsigned char *pmach_pw = NULL;
1285 uint32 l1, l2, l3, l4, l5;
1286 int ret;
1287 struct dcinfo *pdc = NULL;
1288 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1289 remote_machine);
1291 *ppdc = NULL;
1293 if (!keystr) {
1294 return False;
1297 strupper_m(keystr);
1299 tdb_sc = open_schannel_session_store(mem_ctx);
1300 if (!tdb_sc) {
1301 TALLOC_FREE(keystr);
1302 return False;
1305 value = tdb_fetch_bystring(tdb_sc, keystr);
1306 if (!value.dptr) {
1307 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1308 keystr ));
1309 tdb_close(tdb_sc);
1310 return False;
1313 pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1315 /* Retrieve the record. */
1316 ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1317 &pdc->sequence,
1318 &l1, &pseed_chal,
1319 &l2, &pclnt_chal,
1320 &l3, &psrv_chal,
1321 &l4, &psess_key,
1322 &l5, &pmach_pw,
1323 &pdc->mach_acct,
1324 &pdc->remote_machine,
1325 &pdc->domain);
1327 if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1328 /* Bad record - delete it. */
1329 tdb_delete_bystring(tdb_sc, keystr);
1330 tdb_close(tdb_sc);
1331 TALLOC_FREE(keystr);
1332 TALLOC_FREE(pdc);
1333 SAFE_FREE(pseed_chal);
1334 SAFE_FREE(pclnt_chal);
1335 SAFE_FREE(psrv_chal);
1336 SAFE_FREE(psess_key);
1337 SAFE_FREE(pmach_pw);
1338 SAFE_FREE(value.dptr);
1339 return False;
1342 tdb_close(tdb_sc);
1344 memcpy(pdc->seed_chal.data, pseed_chal, 8);
1345 memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1346 memcpy(pdc->srv_chal.data, psrv_chal, 8);
1347 memcpy(pdc->sess_key, psess_key, 16);
1348 memcpy(pdc->mach_pw, pmach_pw, 16);
1350 /* We know these are true so didn't bother to store them. */
1351 pdc->challenge_sent = True;
1352 pdc->authenticated = True;
1354 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1355 keystr ));
1357 SAFE_FREE(pseed_chal);
1358 SAFE_FREE(pclnt_chal);
1359 SAFE_FREE(psrv_chal);
1360 SAFE_FREE(psess_key);
1361 SAFE_FREE(pmach_pw);
1363 TALLOC_FREE(keystr);
1364 SAFE_FREE(value.dptr);
1366 *ppdc = pdc;
1368 return True;
1371 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1373 char *tdbkey = NULL;
1374 bool ret;
1376 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1377 DEBUG(0, ("asprintf failed!\n"));
1378 return False;
1381 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1383 SAFE_FREE(tdbkey);
1384 return ret;
1387 /*******************************************************************
1388 Find the ldap password.
1389 ******************************************************************/
1391 char *secrets_fetch_generic(const char *owner, const char *key)
1393 char *secret = NULL;
1394 char *tdbkey = NULL;
1396 if (( ! owner) || ( ! key)) {
1397 DEBUG(1, ("Invalid Paramters"));
1398 return NULL;
1401 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1402 DEBUG(0, ("Out of memory!\n"));
1403 return NULL;
1406 secret = (char *)secrets_fetch(tdbkey, NULL);
1407 SAFE_FREE(tdbkey);
1409 return secret;