Use pidl for _PNP_HwProfFlags().
[Samba/gebeck_regimport.git] / source3 / passdb / secrets.c
blob6c5375e7de8baa0007379df7ca82e483e1e282dc
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 TALLOC_CTX *ctx;
55 char *fname = NULL;
56 unsigned char dummy;
58 if (tdb)
59 return True;
61 ctx = talloc_init("secrets_init");
62 if (!ctx) {
63 return false;
65 fname = talloc_asprintf(ctx,
66 "%s/secrets.tdb",
67 lp_private_dir());
68 if (!fname) {
69 TALLOC_FREE(ctx);
70 return false;
73 tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
75 if (!tdb) {
76 DEBUG(0,("Failed to open %s\n", fname));
77 TALLOC_FREE(ctx);
78 return False;
81 TALLOC_FREE(ctx);
83 /**
84 * Set a reseed function for the crypto random generator
86 * This avoids a problem where systems without /dev/urandom
87 * could send the same challenge to multiple clients
89 set_rand_reseed_callback(get_rand_seed);
91 /* Ensure that the reseed is done now, while we are root, etc */
92 generate_random_buffer(&dummy, sizeof(dummy));
94 return True;
98 * close secrets.tdb
100 void secrets_shutdown(void)
102 if (!tdb) {
103 return;
106 tdb_close(tdb);
107 tdb = NULL;
110 /* read a entry from the secrets database - the caller must free the result
111 if size is non-null then the size of the entry is put in there
113 void *secrets_fetch(const char *key, size_t *size)
115 TDB_DATA dbuf;
117 if (!secrets_init()) {
118 return NULL;
121 if (!tdb) {
122 return NULL;
125 dbuf = tdb_fetch(tdb, string_tdb_data(key));
126 if (size) {
127 *size = dbuf.dsize;
130 return dbuf.dptr;
133 /* store a secrets entry
135 bool secrets_store(const char *key, const void *data, size_t size)
137 if (!secrets_init()) {
138 return false;
141 if (!tdb) {
142 return false;
145 return tdb_trans_store(tdb, string_tdb_data(key),
146 make_tdb_data((const uint8 *)data, size),
147 TDB_REPLACE) == 0;
151 /* delete a secets database entry
153 bool secrets_delete(const char *key)
155 if (!secrets_init()) {
156 return false;
159 if (!tdb) {
160 return false;
163 return tdb_trans_delete(tdb, string_tdb_data(key)) == 0;
167 * Form a key for fetching the domain sid
169 * @param domain domain name
171 * @return keystring
173 static const char *domain_sid_keystr(const char *domain)
175 char *keystr;
177 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
178 SECRETS_DOMAIN_SID, domain);
179 SMB_ASSERT(keystr != NULL);
181 strupper_m(keystr);
183 return keystr;
186 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
188 bool ret;
190 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
192 /* Force a re-query, in case we modified our domain */
193 if (ret)
194 reset_global_sam_sid();
195 return ret;
198 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
200 DOM_SID *dyn_sid;
201 size_t size = 0;
203 dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
205 if (dyn_sid == NULL)
206 return False;
208 if (size != sizeof(DOM_SID)) {
209 SAFE_FREE(dyn_sid);
210 return False;
213 *sid = *dyn_sid;
214 SAFE_FREE(dyn_sid);
215 return True;
218 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
220 fstring key;
222 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
223 strupper_m(key);
224 return secrets_store(key, guid, sizeof(struct GUID));
227 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
229 struct GUID *dyn_guid;
230 fstring key;
231 size_t size = 0;
232 struct GUID new_guid;
234 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
235 strupper_m(key);
236 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
238 if (!dyn_guid) {
239 if (lp_server_role() == ROLE_DOMAIN_PDC) {
240 smb_uuid_generate_random(&new_guid);
241 if (!secrets_store_domain_guid(domain, &new_guid))
242 return False;
243 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
245 if (dyn_guid == NULL) {
246 return False;
250 if (size != sizeof(struct GUID)) {
251 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
252 SAFE_FREE(dyn_guid);
253 return False;
256 *guid = *dyn_guid;
257 SAFE_FREE(dyn_guid);
258 return True;
262 * Form a key for fetching the machine trust account sec channel type
264 * @param domain domain name
266 * @return keystring
268 static const char *machine_sec_channel_type_keystr(const char *domain)
270 char *keystr;
272 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
273 SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
274 SMB_ASSERT(keystr != NULL);
276 strupper_m(keystr);
278 return keystr;
282 * Form a key for fetching the machine trust account last change time
284 * @param domain domain name
286 * @return keystring
288 static const char *machine_last_change_time_keystr(const char *domain)
290 char *keystr;
292 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
293 SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
294 SMB_ASSERT(keystr != NULL);
296 strupper_m(keystr);
298 return keystr;
303 * Form a key for fetching the machine trust account password
305 * @param domain domain name
307 * @return keystring
309 static const char *machine_password_keystr(const char *domain)
311 char *keystr;
313 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
314 SECRETS_MACHINE_PASSWORD, domain);
315 SMB_ASSERT(keystr != NULL);
317 strupper_m(keystr);
319 return keystr;
323 * Form a key for fetching the machine trust account password
325 * @param domain domain name
327 * @return stored password's key
329 static const char *trust_keystr(const char *domain)
331 char *keystr;
333 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
334 SECRETS_MACHINE_ACCT_PASS, domain);
335 SMB_ASSERT(keystr != NULL);
337 strupper_m(keystr);
339 return keystr;
343 * Form a key for fetching a trusted domain password
345 * @param domain trusted domain name
347 * @return stored password's key
349 static char *trustdom_keystr(const char *domain)
351 char *keystr;
353 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
354 SECRETS_DOMTRUST_ACCT_PASS, domain);
355 SMB_ASSERT(keystr != NULL);
356 strupper_m(keystr);
358 return keystr;
361 /************************************************************************
362 Lock the trust password entry.
363 ************************************************************************/
365 bool secrets_lock_trust_account_password(const char *domain, bool dolock)
367 if (!tdb)
368 return False;
370 if (dolock)
371 return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
372 else
373 tdb_unlock_bystring(tdb, trust_keystr(domain));
374 return True;
377 /************************************************************************
378 Routine to get the default secure channel type for trust accounts
379 ************************************************************************/
381 uint32 get_default_sec_channel(void)
383 if (lp_server_role() == ROLE_DOMAIN_BDC ||
384 lp_server_role() == ROLE_DOMAIN_PDC) {
385 return SEC_CHAN_BDC;
386 } else {
387 return SEC_CHAN_WKSTA;
391 /************************************************************************
392 Routine to get the trust account password for a domain.
393 This only tries to get the legacy hashed version of the password.
394 The user of this function must have locked the trust password file using
395 the above secrets_lock_trust_account_password().
396 ************************************************************************/
398 bool secrets_fetch_trust_account_password_legacy(const char *domain,
399 uint8 ret_pwd[16],
400 time_t *pass_last_set_time,
401 uint32 *channel)
403 struct machine_acct_pass *pass;
404 size_t size = 0;
406 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
407 trust_keystr(domain), &size))) {
408 DEBUG(5, ("secrets_fetch failed!\n"));
409 return False;
412 if (size != sizeof(*pass)) {
413 DEBUG(0, ("secrets were of incorrect size!\n"));
414 return False;
417 if (pass_last_set_time) {
418 *pass_last_set_time = pass->mod_time;
420 memcpy(ret_pwd, pass->hash, 16);
422 if (channel) {
423 *channel = get_default_sec_channel();
426 /* Test if machine password has expired and needs to be changed */
427 if (lp_machine_password_timeout()) {
428 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
429 (time_t)lp_machine_password_timeout())) {
430 global_machine_password_needs_changing = True;
434 SAFE_FREE(pass);
435 return True;
438 /************************************************************************
439 Routine to get the trust account password for a domain.
440 The user of this function must have locked the trust password file using
441 the above secrets_lock_trust_account_password().
442 ************************************************************************/
444 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
445 time_t *pass_last_set_time,
446 uint32 *channel)
448 char *plaintext;
450 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
451 channel);
452 if (plaintext) {
453 DEBUG(4,("Using cleartext machine password\n"));
454 E_md4hash(plaintext, ret_pwd);
455 SAFE_FREE(plaintext);
456 return True;
459 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
460 pass_last_set_time,
461 channel);
465 * Pack SID passed by pointer
467 * @param pack_buf pointer to buffer which is to be filled with packed data
468 * @param bufsize size of packing buffer
469 * @param sid pointer to sid to be packed
471 * @return length of the packed representation of the whole structure
473 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
475 int idx;
476 size_t len = 0;
477 uint8 *p = pack_buf;
478 int remaining_space = pack_buf ? bufsize : 0;
480 if (!sid) {
481 return -1;
484 len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
485 sid->num_auths);
486 if (pack_buf) {
487 p = pack_buf + len;
488 remaining_space = bufsize - len;
491 for (idx = 0; idx < 6; idx++) {
492 len += tdb_pack(p, remaining_space, "b",
493 sid->id_auth[idx]);
494 if (pack_buf) {
495 p = pack_buf + len;
496 remaining_space = bufsize - len;
500 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
501 len += tdb_pack(p, remaining_space, "d",
502 sid->sub_auths[idx]);
503 if (pack_buf) {
504 p = pack_buf + len;
505 remaining_space = bufsize - len;
509 return len;
513 * Unpack SID into a pointer
515 * @param pack_buf pointer to buffer with packed representation
516 * @param bufsize size of the buffer
517 * @param sid pointer to sid structure to be filled with unpacked data
519 * @return size of structure unpacked from buffer
521 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
523 int idx, len = 0;
525 if (!sid || !pack_buf) return -1;
527 len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
528 &sid->sid_rev_num, &sid->num_auths);
530 for (idx = 0; idx < 6; idx++) {
531 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
532 &sid->id_auth[idx]);
535 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
536 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
537 &sid->sub_auths[idx]);
540 return len;
544 * Pack TRUSTED_DOM_PASS passed by pointer
546 * @param pack_buf pointer to buffer which is to be filled with packed data
547 * @param bufsize size of the buffer
548 * @param pass pointer to trusted domain password to be packed
550 * @return length of the packed representation of the whole structure
552 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
553 TRUSTED_DOM_PASS* pass)
555 int idx, len = 0;
556 uint8 *p = pack_buf;
557 int remaining_space = pack_buf ? bufsize : 0;
559 if (!pass) {
560 return -1;
563 /* packing unicode domain name and password */
564 len += tdb_pack(p, remaining_space, "d",
565 pass->uni_name_len);
566 if (pack_buf) {
567 p = pack_buf + len;
568 remaining_space = bufsize - len;
571 for (idx = 0; idx < 32; idx++) {
572 len += tdb_pack(p, remaining_space, "w",
573 pass->uni_name[idx]);
574 if (pack_buf) {
575 p = pack_buf + len;
576 remaining_space = bufsize - len;
580 len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
581 pass->pass, pass->mod_time);
582 if (pack_buf) {
583 p = pack_buf + len;
584 remaining_space = bufsize - len;
587 /* packing SID structure */
588 len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
589 if (pack_buf) {
590 p = pack_buf + len;
591 remaining_space = bufsize - len;
594 return len;
599 * Unpack TRUSTED_DOM_PASS passed by pointer
601 * @param pack_buf pointer to buffer with packed representation
602 * @param bufsize size of the buffer
603 * @param pass pointer to trusted domain password to be filled with unpacked data
605 * @return size of structure unpacked from buffer
607 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
608 TRUSTED_DOM_PASS* pass)
610 int idx, len = 0;
611 char *passp = NULL;
613 if (!pack_buf || !pass) return -1;
615 /* unpack unicode domain name and plaintext password */
616 len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
618 for (idx = 0; idx < 32; idx++)
619 len += tdb_unpack(pack_buf + len, bufsize - len, "w",
620 &pass->uni_name[idx]);
622 len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
623 &pass->pass_len, &passp, &pass->mod_time);
624 if (passp) {
625 fstrcpy(pass->pass, passp);
627 SAFE_FREE(passp);
629 /* unpack domain sid */
630 len += tdb_sid_unpack(pack_buf + len, bufsize - len,
631 &pass->domain_sid);
633 return len;
636 /************************************************************************
637 Routine to get account password to trusted domain
638 ************************************************************************/
640 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
641 DOM_SID *sid, time_t *pass_last_set_time)
643 struct trusted_dom_pass pass;
644 size_t size = 0;
646 /* unpacking structures */
647 uint8 *pass_buf;
648 int pass_len = 0;
650 ZERO_STRUCT(pass);
652 /* fetching trusted domain password structure */
653 if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
654 &size))) {
655 DEBUG(5, ("secrets_fetch failed!\n"));
656 return False;
659 /* unpack trusted domain password */
660 pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
661 SAFE_FREE(pass_buf);
663 if (pass_len != size) {
664 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
665 return False;
668 /* the trust's password */
669 if (pwd) {
670 *pwd = SMB_STRDUP(pass.pass);
671 if (!*pwd) {
672 return False;
676 /* last change time */
677 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
679 /* domain sid */
680 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
682 return True;
686 * Routine to store the password for trusted domain
688 * @param domain remote domain name
689 * @param pwd plain text password of trust relationship
690 * @param sid remote domain sid
692 * @return true if succeeded
695 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
696 const DOM_SID *sid)
698 smb_ucs2_t *uni_dom_name;
699 bool ret;
701 /* packing structures */
702 uint8 *pass_buf = NULL;
703 int pass_len = 0;
705 struct trusted_dom_pass pass;
706 ZERO_STRUCT(pass);
708 if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
709 DEBUG(0, ("Could not convert domain name %s to unicode\n",
710 domain));
711 return False;
714 strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
715 pass.uni_name_len = strlen_w(uni_dom_name)+1;
716 SAFE_FREE(uni_dom_name);
718 /* last change time */
719 pass.mod_time = time(NULL);
721 /* password of the trust */
722 pass.pass_len = strlen(pwd);
723 fstrcpy(pass.pass, pwd);
725 /* domain sid */
726 sid_copy(&pass.domain_sid, sid);
728 /* Calculate the length. */
729 pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
730 pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
731 if (!pass_buf) {
732 return false;
734 pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
735 ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
736 pass_len);
737 SAFE_FREE(pass_buf);
738 return ret;
741 /************************************************************************
742 Routine to delete the plaintext machine account password
743 ************************************************************************/
745 bool secrets_delete_machine_password(const char *domain)
747 return secrets_delete(machine_password_keystr(domain));
750 /************************************************************************
751 Routine to delete the plaintext machine account password, sec channel type and
752 last change time from secrets database
753 ************************************************************************/
755 bool secrets_delete_machine_password_ex(const char *domain)
757 if (!secrets_delete(machine_password_keystr(domain))) {
758 return false;
760 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
761 return false;
763 return secrets_delete(machine_last_change_time_keystr(domain));
766 /************************************************************************
767 Routine to delete the domain sid
768 ************************************************************************/
770 bool secrets_delete_domain_sid(const char *domain)
772 return secrets_delete(domain_sid_keystr(domain));
775 /************************************************************************
776 Routine to set the plaintext machine account password for a realm
777 the password is assumed to be a null terminated ascii string
778 ************************************************************************/
780 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
782 bool ret;
783 uint32 last_change_time;
784 uint32 sec_channel_type;
786 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
787 if (!ret)
788 return ret;
790 SIVAL(&last_change_time, 0, time(NULL));
791 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
793 SIVAL(&sec_channel_type, 0, sec_channel);
794 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
796 return ret;
799 /************************************************************************
800 Routine to fetch the plaintext machine account password for a realm
801 the password is assumed to be a null terminated ascii string.
802 ************************************************************************/
804 char *secrets_fetch_machine_password(const char *domain,
805 time_t *pass_last_set_time,
806 uint32 *channel)
808 char *ret;
809 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
811 if (pass_last_set_time) {
812 size_t size;
813 uint32 *last_set_time;
814 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
815 if (last_set_time) {
816 *pass_last_set_time = IVAL(last_set_time,0);
817 SAFE_FREE(last_set_time);
818 } else {
819 *pass_last_set_time = 0;
823 if (channel) {
824 size_t size;
825 uint32 *channel_type;
826 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
827 if (channel_type) {
828 *channel = IVAL(channel_type,0);
829 SAFE_FREE(channel_type);
830 } else {
831 *channel = get_default_sec_channel();
835 return ret;
838 /************************************************************************
839 Routine to delete the password for trusted domain
840 ************************************************************************/
842 bool trusted_domain_password_delete(const char *domain)
844 return secrets_delete(trustdom_keystr(domain));
847 bool secrets_store_ldap_pw(const char* dn, char* pw)
849 char *key = NULL;
850 bool ret;
852 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
853 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
854 return False;
857 ret = secrets_store(key, pw, strlen(pw)+1);
859 SAFE_FREE(key);
860 return ret;
863 /*******************************************************************
864 Find the ldap password.
865 ******************************************************************/
867 bool fetch_ldap_pw(char **dn, char** pw)
869 char *key = NULL;
870 size_t size = 0;
872 *dn = smb_xstrdup(lp_ldap_admin_dn());
874 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
875 SAFE_FREE(*dn);
876 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
879 *pw=(char *)secrets_fetch(key, &size);
880 SAFE_FREE(key);
882 if (!size) {
883 /* Upgrade 2.2 style entry */
884 char *p;
885 char* old_style_key = SMB_STRDUP(*dn);
886 char *data;
887 fstring old_style_pw;
889 if (!old_style_key) {
890 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
891 return False;
894 for (p=old_style_key; *p; p++)
895 if (*p == ',') *p = '/';
897 data=(char *)secrets_fetch(old_style_key, &size);
898 if (!size && size < sizeof(old_style_pw)) {
899 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
900 SAFE_FREE(old_style_key);
901 SAFE_FREE(*dn);
902 return False;
905 size = MIN(size, sizeof(fstring)-1);
906 strncpy(old_style_pw, data, size);
907 old_style_pw[size] = 0;
909 SAFE_FREE(data);
911 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
912 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
913 SAFE_FREE(old_style_key);
914 SAFE_FREE(*dn);
915 return False;
917 if (!secrets_delete(old_style_key)) {
918 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
921 SAFE_FREE(old_style_key);
923 *pw = smb_xstrdup(old_style_pw);
926 return True;
930 * Get trusted domains info from secrets.tdb.
933 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
934 struct trustdom_info ***domains)
936 TDB_LIST_NODE *keys, *k;
937 char *pattern;
938 TALLOC_CTX *tmp_ctx;
940 if (!(tmp_ctx = talloc_new(mem_ctx))) {
941 return NT_STATUS_NO_MEMORY;
944 if (!secrets_init()) {
945 return NT_STATUS_ACCESS_DENIED;
948 /* generate searching pattern */
949 pattern = talloc_asprintf(tmp_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
950 if (pattern == NULL) {
951 DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
952 "failed!\n"));
953 TALLOC_FREE(tmp_ctx);
954 return NT_STATUS_NO_MEMORY;
957 *num_domains = 0;
960 * Make sure that a talloc context for the trustdom_info structs
961 * exists
964 if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
965 TALLOC_FREE(tmp_ctx);
966 return NT_STATUS_NO_MEMORY;
969 /* fetching trusted domains' data and collecting them in a list */
970 keys = tdb_search_keys(tdb, pattern);
972 /* searching for keys in secrets db -- way to go ... */
973 for (k = keys; k; k = k->next) {
974 uint8 *packed_pass;
975 size_t size = 0, packed_size = 0;
976 struct trusted_dom_pass pass;
977 char *secrets_key;
978 struct trustdom_info *dom_info;
980 /* important: ensure null-termination of the key string */
981 secrets_key = talloc_strndup(tmp_ctx,
982 (const char *)k->node_key.dptr,
983 k->node_key.dsize);
984 if (!secrets_key) {
985 DEBUG(0, ("strndup failed!\n"));
986 tdb_search_list_free(keys);
987 TALLOC_FREE(tmp_ctx);
988 return NT_STATUS_NO_MEMORY;
991 packed_pass = (uint8 *)secrets_fetch(secrets_key, &size);
992 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
993 &pass);
994 /* packed representation isn't needed anymore */
995 SAFE_FREE(packed_pass);
997 if (size != packed_size) {
998 DEBUG(2, ("Secrets record %s is invalid!\n",
999 secrets_key));
1000 continue;
1003 if (pass.domain_sid.num_auths != 4) {
1004 DEBUG(0, ("SID %s is not a domain sid, has %d "
1005 "auths instead of 4\n",
1006 sid_string_dbg(&pass.domain_sid),
1007 pass.domain_sid.num_auths));
1008 continue;
1011 if (!(dom_info = TALLOC_P(*domains, struct trustdom_info))) {
1012 DEBUG(0, ("talloc failed\n"));
1013 tdb_search_list_free(keys);
1014 TALLOC_FREE(tmp_ctx);
1015 return NT_STATUS_NO_MEMORY;
1018 if (pull_ucs2_talloc(dom_info, &dom_info->name,
1019 pass.uni_name) == (size_t)-1) {
1020 DEBUG(2, ("pull_ucs2_talloc failed\n"));
1021 tdb_search_list_free(keys);
1022 TALLOC_FREE(tmp_ctx);
1023 return NT_STATUS_NO_MEMORY;
1026 sid_copy(&dom_info->sid, &pass.domain_sid);
1028 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
1029 domains, num_domains);
1031 if (*domains == NULL) {
1032 tdb_search_list_free(keys);
1033 TALLOC_FREE(tmp_ctx);
1034 return NT_STATUS_NO_MEMORY;
1038 DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
1039 *num_domains));
1041 /* free the results of searching the keys */
1042 tdb_search_list_free(keys);
1043 TALLOC_FREE(tmp_ctx);
1045 return NT_STATUS_OK;
1048 /*******************************************************************************
1049 Lock the secrets tdb based on a string - this is used as a primitive form of mutex
1050 between smbd instances.
1051 *******************************************************************************/
1053 bool secrets_named_mutex(const char *name, unsigned int timeout)
1055 int ret = 0;
1057 if (!secrets_init()) {
1058 return false;
1061 ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
1062 if (ret == 0) {
1063 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
1066 return (ret == 0);
1069 /*******************************************************************************
1070 Unlock a named mutex.
1071 *******************************************************************************/
1073 void secrets_named_mutex_release(const char *name)
1075 tdb_unlock_bystring(tdb, name);
1076 DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
1079 /*******************************************************************************
1080 Store a complete AFS keyfile into secrets.tdb.
1081 *******************************************************************************/
1083 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1085 fstring key;
1087 if ((cell == NULL) || (keyfile == NULL))
1088 return False;
1090 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1091 return False;
1093 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1094 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1097 /*******************************************************************************
1098 Fetch the current (highest) AFS key from secrets.tdb
1099 *******************************************************************************/
1100 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1102 fstring key;
1103 struct afs_keyfile *keyfile;
1104 size_t size = 0;
1105 uint32 i;
1107 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1109 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1111 if (keyfile == NULL)
1112 return False;
1114 if (size != sizeof(struct afs_keyfile)) {
1115 SAFE_FREE(keyfile);
1116 return False;
1119 i = ntohl(keyfile->nkeys);
1121 if (i > SECRETS_AFS_MAXKEYS) {
1122 SAFE_FREE(keyfile);
1123 return False;
1126 *result = keyfile->entry[i-1];
1128 result->kvno = ntohl(result->kvno);
1130 return True;
1133 /******************************************************************************
1134 When kerberos is not available, choose between anonymous or
1135 authenticated connections.
1137 We need to use an authenticated connection if DCs have the
1138 RestrictAnonymous registry entry set > 0, or the "Additional
1139 restrictions for anonymous connections" set in the win2k Local
1140 Security Policy.
1142 Caller to free() result in domain, username, password
1143 *******************************************************************************/
1144 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1146 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1147 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1148 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1150 if (*username && **username) {
1152 if (!*domain || !**domain)
1153 *domain = smb_xstrdup(lp_workgroup());
1155 if (!*password || !**password)
1156 *password = smb_xstrdup("");
1158 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1159 *domain, *username));
1161 } else {
1162 DEBUG(3, ("IPC$ connections done anonymously\n"));
1163 *username = smb_xstrdup("");
1164 *domain = smb_xstrdup("");
1165 *password = smb_xstrdup("");
1169 /******************************************************************************
1170 Open or create the schannel session store tdb.
1171 *******************************************************************************/
1173 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1175 TDB_DATA vers;
1176 uint32 ver;
1177 TDB_CONTEXT *tdb_sc = NULL;
1178 char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1180 if (!fname) {
1181 return NULL;
1184 tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1186 if (!tdb_sc) {
1187 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1188 TALLOC_FREE(fname);
1189 return NULL;
1192 vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1193 if (vers.dptr == NULL) {
1194 /* First opener, no version. */
1195 SIVAL(&ver,0,1);
1196 vers.dptr = (uint8 *)&ver;
1197 vers.dsize = 4;
1198 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1199 vers.dptr = NULL;
1200 } else if (vers.dsize == 4) {
1201 ver = IVAL(vers.dptr,0);
1202 if (ver != 1) {
1203 tdb_close(tdb_sc);
1204 tdb_sc = NULL;
1205 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1206 (int)ver, fname ));
1208 } else {
1209 tdb_close(tdb_sc);
1210 tdb_sc = NULL;
1211 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1212 (int)vers.dsize, fname ));
1215 SAFE_FREE(vers.dptr);
1216 TALLOC_FREE(fname);
1218 return tdb_sc;
1221 /******************************************************************************
1222 Store the schannel state after an AUTH2 call.
1223 Note we must be root here.
1224 *******************************************************************************/
1226 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1227 const char *remote_machine,
1228 const struct dcinfo *pdc)
1230 TDB_CONTEXT *tdb_sc = NULL;
1231 TDB_DATA value;
1232 bool ret;
1233 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1234 remote_machine);
1235 if (!keystr) {
1236 return False;
1239 strupper_m(keystr);
1241 /* Work out how large the record is. */
1242 value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1243 pdc->sequence,
1244 8, pdc->seed_chal.data,
1245 8, pdc->clnt_chal.data,
1246 8, pdc->srv_chal.data,
1247 16, pdc->sess_key,
1248 16, pdc->mach_pw,
1249 pdc->mach_acct,
1250 pdc->remote_machine,
1251 pdc->domain);
1253 value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1254 if (!value.dptr) {
1255 TALLOC_FREE(keystr);
1256 return False;
1259 value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1260 pdc->sequence,
1261 8, pdc->seed_chal.data,
1262 8, pdc->clnt_chal.data,
1263 8, pdc->srv_chal.data,
1264 16, pdc->sess_key,
1265 16, pdc->mach_pw,
1266 pdc->mach_acct,
1267 pdc->remote_machine,
1268 pdc->domain);
1270 tdb_sc = open_schannel_session_store(mem_ctx);
1271 if (!tdb_sc) {
1272 TALLOC_FREE(keystr);
1273 TALLOC_FREE(value.dptr);
1274 return False;
1277 ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1279 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1280 keystr ));
1282 tdb_close(tdb_sc);
1283 TALLOC_FREE(keystr);
1284 TALLOC_FREE(value.dptr);
1285 return ret;
1288 /******************************************************************************
1289 Restore the schannel state on a client reconnect.
1290 Note we must be root here.
1291 *******************************************************************************/
1293 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1294 const char *remote_machine,
1295 struct dcinfo **ppdc)
1297 TDB_CONTEXT *tdb_sc = NULL;
1298 TDB_DATA value;
1299 unsigned char *pseed_chal = NULL;
1300 unsigned char *pclnt_chal = NULL;
1301 unsigned char *psrv_chal = NULL;
1302 unsigned char *psess_key = NULL;
1303 unsigned char *pmach_pw = NULL;
1304 uint32 l1, l2, l3, l4, l5;
1305 int ret;
1306 struct dcinfo *pdc = NULL;
1307 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1308 remote_machine);
1310 *ppdc = NULL;
1312 if (!keystr) {
1313 return False;
1316 strupper_m(keystr);
1318 tdb_sc = open_schannel_session_store(mem_ctx);
1319 if (!tdb_sc) {
1320 TALLOC_FREE(keystr);
1321 return False;
1324 value = tdb_fetch_bystring(tdb_sc, keystr);
1325 if (!value.dptr) {
1326 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1327 keystr ));
1328 tdb_close(tdb_sc);
1329 return False;
1332 pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1334 /* Retrieve the record. */
1335 ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1336 &pdc->sequence,
1337 &l1, &pseed_chal,
1338 &l2, &pclnt_chal,
1339 &l3, &psrv_chal,
1340 &l4, &psess_key,
1341 &l5, &pmach_pw,
1342 &pdc->mach_acct,
1343 &pdc->remote_machine,
1344 &pdc->domain);
1346 if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1347 /* Bad record - delete it. */
1348 tdb_delete_bystring(tdb_sc, keystr);
1349 tdb_close(tdb_sc);
1350 TALLOC_FREE(keystr);
1351 TALLOC_FREE(pdc);
1352 SAFE_FREE(pseed_chal);
1353 SAFE_FREE(pclnt_chal);
1354 SAFE_FREE(psrv_chal);
1355 SAFE_FREE(psess_key);
1356 SAFE_FREE(pmach_pw);
1357 SAFE_FREE(value.dptr);
1358 return False;
1361 tdb_close(tdb_sc);
1363 memcpy(pdc->seed_chal.data, pseed_chal, 8);
1364 memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1365 memcpy(pdc->srv_chal.data, psrv_chal, 8);
1366 memcpy(pdc->sess_key, psess_key, 16);
1367 memcpy(pdc->mach_pw, pmach_pw, 16);
1369 /* We know these are true so didn't bother to store them. */
1370 pdc->challenge_sent = True;
1371 pdc->authenticated = True;
1373 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1374 keystr ));
1376 SAFE_FREE(pseed_chal);
1377 SAFE_FREE(pclnt_chal);
1378 SAFE_FREE(psrv_chal);
1379 SAFE_FREE(psess_key);
1380 SAFE_FREE(pmach_pw);
1382 TALLOC_FREE(keystr);
1383 SAFE_FREE(value.dptr);
1385 *ppdc = pdc;
1387 return True;
1390 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1392 char *tdbkey = NULL;
1393 bool ret;
1395 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1396 DEBUG(0, ("asprintf failed!\n"));
1397 return False;
1400 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1402 SAFE_FREE(tdbkey);
1403 return ret;
1406 /*******************************************************************
1407 Find the ldap password.
1408 ******************************************************************/
1410 char *secrets_fetch_generic(const char *owner, const char *key)
1412 char *secret = NULL;
1413 char *tdbkey = NULL;
1415 if (( ! owner) || ( ! key)) {
1416 DEBUG(1, ("Invalid Paramters"));
1417 return NULL;
1420 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1421 DEBUG(0, ("Out of memory!\n"));
1422 return NULL;
1425 secret = (char *)secrets_fetch(tdbkey, NULL);
1426 SAFE_FREE(tdbkey);
1428 return secret;