Make use of talloc_asprintf_strupper_m in secrets.c
[Samba/bjacke.git] / source / passdb / secrets.c
blob2ef8f439884be464b2be06901ad92116bec0aba5
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_strupper_m(talloc_tos(), "%s/%s",
159 SECRETS_DOMAIN_SID, domain);
160 SMB_ASSERT(keystr != NULL);
161 return keystr;
164 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
166 bool ret;
168 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
170 /* Force a re-query, in case we modified our domain */
171 if (ret)
172 reset_global_sam_sid();
173 return ret;
176 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
178 DOM_SID *dyn_sid;
179 size_t size = 0;
181 dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
183 if (dyn_sid == NULL)
184 return False;
186 if (size != sizeof(DOM_SID)) {
187 SAFE_FREE(dyn_sid);
188 return False;
191 *sid = *dyn_sid;
192 SAFE_FREE(dyn_sid);
193 return True;
196 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
198 fstring key;
200 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
201 strupper_m(key);
202 return secrets_store(key, guid, sizeof(struct GUID));
205 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
207 struct GUID *dyn_guid;
208 fstring key;
209 size_t size = 0;
210 struct GUID new_guid;
212 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
213 strupper_m(key);
214 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
216 if (!dyn_guid) {
217 if (lp_server_role() == ROLE_DOMAIN_PDC) {
218 smb_uuid_generate_random(&new_guid);
219 if (!secrets_store_domain_guid(domain, &new_guid))
220 return False;
221 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
223 if (dyn_guid == NULL) {
224 return False;
228 if (size != sizeof(struct GUID)) {
229 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
230 SAFE_FREE(dyn_guid);
231 return False;
234 *guid = *dyn_guid;
235 SAFE_FREE(dyn_guid);
236 return True;
240 * Form a key for fetching the machine trust account sec channel type
242 * @param domain domain name
244 * @return keystring
246 static const char *machine_sec_channel_type_keystr(const char *domain)
248 char *keystr;
250 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
251 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
252 domain);
253 SMB_ASSERT(keystr != NULL);
254 return keystr;
258 * Form a key for fetching the machine trust account last change time
260 * @param domain domain name
262 * @return keystring
264 static const char *machine_last_change_time_keystr(const char *domain)
266 char *keystr;
268 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
269 SECRETS_MACHINE_LAST_CHANGE_TIME,
270 domain);
271 SMB_ASSERT(keystr != NULL);
272 return keystr;
277 * Form a key for fetching the machine trust account password
279 * @param domain domain name
281 * @return keystring
283 static const char *machine_password_keystr(const char *domain)
285 char *keystr;
287 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
288 SECRETS_MACHINE_PASSWORD, domain);
289 SMB_ASSERT(keystr != NULL);
290 return keystr;
294 * Form a key for fetching the machine trust account password
296 * @param domain domain name
298 * @return stored password's key
300 static const char *trust_keystr(const char *domain)
302 char *keystr;
304 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
305 SECRETS_MACHINE_ACCT_PASS, domain);
306 SMB_ASSERT(keystr != NULL);
307 return keystr;
311 * Form a key for fetching a trusted domain password
313 * @param domain trusted domain name
315 * @return stored password's key
317 static char *trustdom_keystr(const char *domain)
319 char *keystr;
321 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
322 SECRETS_DOMTRUST_ACCT_PASS,
323 domain);
324 SMB_ASSERT(keystr != NULL);
325 return keystr;
328 /************************************************************************
329 Lock the trust password entry.
330 ************************************************************************/
332 bool secrets_lock_trust_account_password(const char *domain, bool dolock)
334 if (!tdb)
335 return False;
337 if (dolock)
338 return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
339 else
340 tdb_unlock_bystring(tdb, trust_keystr(domain));
341 return True;
344 /************************************************************************
345 Routine to get the default secure channel type for trust accounts
346 ************************************************************************/
348 uint32 get_default_sec_channel(void)
350 if (lp_server_role() == ROLE_DOMAIN_BDC ||
351 lp_server_role() == ROLE_DOMAIN_PDC) {
352 return SEC_CHAN_BDC;
353 } else {
354 return SEC_CHAN_WKSTA;
358 /************************************************************************
359 Routine to get the trust account password for a domain.
360 This only tries to get the legacy hashed version of the password.
361 The user of this function must have locked the trust password file using
362 the above secrets_lock_trust_account_password().
363 ************************************************************************/
365 bool secrets_fetch_trust_account_password_legacy(const char *domain,
366 uint8 ret_pwd[16],
367 time_t *pass_last_set_time,
368 uint32 *channel)
370 struct machine_acct_pass *pass;
371 size_t size = 0;
373 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
374 trust_keystr(domain), &size))) {
375 DEBUG(5, ("secrets_fetch failed!\n"));
376 return False;
379 if (size != sizeof(*pass)) {
380 DEBUG(0, ("secrets were of incorrect size!\n"));
381 return False;
384 if (pass_last_set_time) {
385 *pass_last_set_time = pass->mod_time;
387 memcpy(ret_pwd, pass->hash, 16);
389 if (channel) {
390 *channel = get_default_sec_channel();
393 /* Test if machine password has expired and needs to be changed */
394 if (lp_machine_password_timeout()) {
395 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
396 (time_t)lp_machine_password_timeout())) {
397 global_machine_password_needs_changing = True;
401 SAFE_FREE(pass);
402 return True;
405 /************************************************************************
406 Routine to get the trust account password for a domain.
407 The user of this function must have locked the trust password file using
408 the above secrets_lock_trust_account_password().
409 ************************************************************************/
411 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
412 time_t *pass_last_set_time,
413 uint32 *channel)
415 char *plaintext;
417 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
418 channel);
419 if (plaintext) {
420 DEBUG(4,("Using cleartext machine password\n"));
421 E_md4hash(plaintext, ret_pwd);
422 SAFE_FREE(plaintext);
423 return True;
426 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
427 pass_last_set_time,
428 channel);
432 * Pack SID passed by pointer
434 * @param pack_buf pointer to buffer which is to be filled with packed data
435 * @param bufsize size of packing buffer
436 * @param sid pointer to sid to be packed
438 * @return length of the packed representation of the whole structure
440 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
442 int idx;
443 size_t len = 0;
444 uint8 *p = pack_buf;
445 int remaining_space = pack_buf ? bufsize : 0;
447 if (!sid) {
448 return -1;
451 len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
452 sid->num_auths);
453 if (pack_buf) {
454 p = pack_buf + len;
455 remaining_space = bufsize - len;
458 for (idx = 0; idx < 6; idx++) {
459 len += tdb_pack(p, remaining_space, "b",
460 sid->id_auth[idx]);
461 if (pack_buf) {
462 p = pack_buf + len;
463 remaining_space = bufsize - len;
467 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
468 len += tdb_pack(p, remaining_space, "d",
469 sid->sub_auths[idx]);
470 if (pack_buf) {
471 p = pack_buf + len;
472 remaining_space = bufsize - len;
476 return len;
480 * Unpack SID into a pointer
482 * @param pack_buf pointer to buffer with packed representation
483 * @param bufsize size of the buffer
484 * @param sid pointer to sid structure to be filled with unpacked data
486 * @return size of structure unpacked from buffer
488 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
490 int idx, len = 0;
492 if (!sid || !pack_buf) return -1;
494 len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
495 &sid->sid_rev_num, &sid->num_auths);
497 for (idx = 0; idx < 6; idx++) {
498 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
499 &sid->id_auth[idx]);
502 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
503 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
504 &sid->sub_auths[idx]);
507 return len;
511 * Pack TRUSTED_DOM_PASS passed by pointer
513 * @param pack_buf pointer to buffer which is to be filled with packed data
514 * @param bufsize size of the buffer
515 * @param pass pointer to trusted domain password to be packed
517 * @return length of the packed representation of the whole structure
519 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
520 TRUSTED_DOM_PASS* pass)
522 int idx, len = 0;
523 uint8 *p = pack_buf;
524 int remaining_space = pack_buf ? bufsize : 0;
526 if (!pass) {
527 return -1;
530 /* packing unicode domain name and password */
531 len += tdb_pack(p, remaining_space, "d",
532 pass->uni_name_len);
533 if (pack_buf) {
534 p = pack_buf + len;
535 remaining_space = bufsize - len;
538 for (idx = 0; idx < 32; idx++) {
539 len += tdb_pack(p, remaining_space, "w",
540 pass->uni_name[idx]);
541 if (pack_buf) {
542 p = pack_buf + len;
543 remaining_space = bufsize - len;
547 len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
548 pass->pass, pass->mod_time);
549 if (pack_buf) {
550 p = pack_buf + len;
551 remaining_space = bufsize - len;
554 /* packing SID structure */
555 len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
556 if (pack_buf) {
557 p = pack_buf + len;
558 remaining_space = bufsize - len;
561 return len;
566 * Unpack TRUSTED_DOM_PASS passed by pointer
568 * @param pack_buf pointer to buffer with packed representation
569 * @param bufsize size of the buffer
570 * @param pass pointer to trusted domain password to be filled with unpacked data
572 * @return size of structure unpacked from buffer
574 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
575 TRUSTED_DOM_PASS* pass)
577 int idx, len = 0;
578 char *passp = NULL;
580 if (!pack_buf || !pass) return -1;
582 /* unpack unicode domain name and plaintext password */
583 len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
585 for (idx = 0; idx < 32; idx++)
586 len += tdb_unpack(pack_buf + len, bufsize - len, "w",
587 &pass->uni_name[idx]);
589 len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
590 &pass->pass_len, &passp, &pass->mod_time);
591 if (passp) {
592 fstrcpy(pass->pass, passp);
594 SAFE_FREE(passp);
596 /* unpack domain sid */
597 len += tdb_sid_unpack(pack_buf + len, bufsize - len,
598 &pass->domain_sid);
600 return len;
603 /************************************************************************
604 Routine to get account password to trusted domain
605 ************************************************************************/
607 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
608 DOM_SID *sid, time_t *pass_last_set_time)
610 struct trusted_dom_pass pass;
611 size_t size = 0;
613 /* unpacking structures */
614 uint8 *pass_buf;
615 int pass_len = 0;
617 ZERO_STRUCT(pass);
619 /* fetching trusted domain password structure */
620 if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
621 &size))) {
622 DEBUG(5, ("secrets_fetch failed!\n"));
623 return False;
626 /* unpack trusted domain password */
627 pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
628 SAFE_FREE(pass_buf);
630 if (pass_len != size) {
631 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
632 return False;
635 /* the trust's password */
636 if (pwd) {
637 *pwd = SMB_STRDUP(pass.pass);
638 if (!*pwd) {
639 return False;
643 /* last change time */
644 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
646 /* domain sid */
647 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
649 return True;
653 * Routine to store the password for trusted domain
655 * @param domain remote domain name
656 * @param pwd plain text password of trust relationship
657 * @param sid remote domain sid
659 * @return true if succeeded
662 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
663 const DOM_SID *sid)
665 smb_ucs2_t *uni_dom_name;
666 bool ret;
668 /* packing structures */
669 uint8 *pass_buf = NULL;
670 int pass_len = 0;
672 struct trusted_dom_pass pass;
673 ZERO_STRUCT(pass);
675 if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
676 DEBUG(0, ("Could not convert domain name %s to unicode\n",
677 domain));
678 return False;
681 strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
682 pass.uni_name_len = strlen_w(uni_dom_name)+1;
683 SAFE_FREE(uni_dom_name);
685 /* last change time */
686 pass.mod_time = time(NULL);
688 /* password of the trust */
689 pass.pass_len = strlen(pwd);
690 fstrcpy(pass.pass, pwd);
692 /* domain sid */
693 sid_copy(&pass.domain_sid, sid);
695 /* Calculate the length. */
696 pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
697 pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
698 if (!pass_buf) {
699 return false;
701 pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
702 ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
703 pass_len);
704 SAFE_FREE(pass_buf);
705 return ret;
708 /************************************************************************
709 Routine to delete the plaintext machine account password
710 ************************************************************************/
712 bool secrets_delete_machine_password(const char *domain)
714 return secrets_delete(machine_password_keystr(domain));
717 /************************************************************************
718 Routine to delete the plaintext machine account password, sec channel type and
719 last change time from secrets database
720 ************************************************************************/
722 bool secrets_delete_machine_password_ex(const char *domain)
724 if (!secrets_delete(machine_password_keystr(domain))) {
725 return false;
727 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
728 return false;
730 return secrets_delete(machine_last_change_time_keystr(domain));
733 /************************************************************************
734 Routine to delete the domain sid
735 ************************************************************************/
737 bool secrets_delete_domain_sid(const char *domain)
739 return secrets_delete(domain_sid_keystr(domain));
742 /************************************************************************
743 Routine to set the plaintext machine account password for a realm
744 the password is assumed to be a null terminated ascii string
745 ************************************************************************/
747 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
749 bool ret;
750 uint32 last_change_time;
751 uint32 sec_channel_type;
753 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
754 if (!ret)
755 return ret;
757 SIVAL(&last_change_time, 0, time(NULL));
758 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
760 SIVAL(&sec_channel_type, 0, sec_channel);
761 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
763 return ret;
766 /************************************************************************
767 Routine to fetch the plaintext machine account password for a realm
768 the password is assumed to be a null terminated ascii string.
769 ************************************************************************/
771 char *secrets_fetch_machine_password(const char *domain,
772 time_t *pass_last_set_time,
773 uint32 *channel)
775 char *ret;
776 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
778 if (pass_last_set_time) {
779 size_t size;
780 uint32 *last_set_time;
781 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
782 if (last_set_time) {
783 *pass_last_set_time = IVAL(last_set_time,0);
784 SAFE_FREE(last_set_time);
785 } else {
786 *pass_last_set_time = 0;
790 if (channel) {
791 size_t size;
792 uint32 *channel_type;
793 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
794 if (channel_type) {
795 *channel = IVAL(channel_type,0);
796 SAFE_FREE(channel_type);
797 } else {
798 *channel = get_default_sec_channel();
802 return ret;
805 /************************************************************************
806 Routine to delete the password for trusted domain
807 ************************************************************************/
809 bool trusted_domain_password_delete(const char *domain)
811 return secrets_delete(trustdom_keystr(domain));
814 bool secrets_store_ldap_pw(const char* dn, char* pw)
816 char *key = NULL;
817 bool ret;
819 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
820 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
821 return False;
824 ret = secrets_store(key, pw, strlen(pw)+1);
826 SAFE_FREE(key);
827 return ret;
830 /*******************************************************************
831 Find the ldap password.
832 ******************************************************************/
834 bool fetch_ldap_pw(char **dn, char** pw)
836 char *key = NULL;
837 size_t size = 0;
839 *dn = smb_xstrdup(lp_ldap_admin_dn());
841 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
842 SAFE_FREE(*dn);
843 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
846 *pw=(char *)secrets_fetch(key, &size);
847 SAFE_FREE(key);
849 if (!size) {
850 /* Upgrade 2.2 style entry */
851 char *p;
852 char* old_style_key = SMB_STRDUP(*dn);
853 char *data;
854 fstring old_style_pw;
856 if (!old_style_key) {
857 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
858 return False;
861 for (p=old_style_key; *p; p++)
862 if (*p == ',') *p = '/';
864 data=(char *)secrets_fetch(old_style_key, &size);
865 if (!size && size < sizeof(old_style_pw)) {
866 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
867 SAFE_FREE(old_style_key);
868 SAFE_FREE(*dn);
869 return False;
872 size = MIN(size, sizeof(fstring)-1);
873 strncpy(old_style_pw, data, size);
874 old_style_pw[size] = 0;
876 SAFE_FREE(data);
878 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
879 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
880 SAFE_FREE(old_style_key);
881 SAFE_FREE(*dn);
882 return False;
884 if (!secrets_delete(old_style_key)) {
885 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
888 SAFE_FREE(old_style_key);
890 *pw = smb_xstrdup(old_style_pw);
893 return True;
897 * Get trusted domains info from secrets.tdb.
900 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
901 struct trustdom_info ***domains)
903 TDB_LIST_NODE *keys, *k;
904 char *pattern;
905 TALLOC_CTX *tmp_ctx;
907 if (!(tmp_ctx = talloc_new(mem_ctx))) {
908 return NT_STATUS_NO_MEMORY;
911 if (!secrets_init()) {
912 return NT_STATUS_ACCESS_DENIED;
915 /* generate searching pattern */
916 pattern = talloc_asprintf(tmp_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
917 if (pattern == NULL) {
918 DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
919 "failed!\n"));
920 TALLOC_FREE(tmp_ctx);
921 return NT_STATUS_NO_MEMORY;
924 *num_domains = 0;
927 * Make sure that a talloc context for the trustdom_info structs
928 * exists
931 if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
932 TALLOC_FREE(tmp_ctx);
933 return NT_STATUS_NO_MEMORY;
936 /* fetching trusted domains' data and collecting them in a list */
937 keys = tdb_search_keys(tdb, pattern);
939 /* searching for keys in secrets db -- way to go ... */
940 for (k = keys; k; k = k->next) {
941 uint8 *packed_pass;
942 size_t size = 0, packed_size = 0;
943 struct trusted_dom_pass pass;
944 char *secrets_key;
945 struct trustdom_info *dom_info;
947 /* important: ensure null-termination of the key string */
948 secrets_key = talloc_strndup(tmp_ctx,
949 (const char *)k->node_key.dptr,
950 k->node_key.dsize);
951 if (!secrets_key) {
952 DEBUG(0, ("strndup failed!\n"));
953 tdb_search_list_free(keys);
954 TALLOC_FREE(tmp_ctx);
955 return NT_STATUS_NO_MEMORY;
958 packed_pass = (uint8 *)secrets_fetch(secrets_key, &size);
959 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
960 &pass);
961 /* packed representation isn't needed anymore */
962 SAFE_FREE(packed_pass);
964 if (size != packed_size) {
965 DEBUG(2, ("Secrets record %s is invalid!\n",
966 secrets_key));
967 continue;
970 if (pass.domain_sid.num_auths != 4) {
971 DEBUG(0, ("SID %s is not a domain sid, has %d "
972 "auths instead of 4\n",
973 sid_string_dbg(&pass.domain_sid),
974 pass.domain_sid.num_auths));
975 continue;
978 if (!(dom_info = TALLOC_P(*domains, struct trustdom_info))) {
979 DEBUG(0, ("talloc failed\n"));
980 tdb_search_list_free(keys);
981 TALLOC_FREE(tmp_ctx);
982 return NT_STATUS_NO_MEMORY;
985 if (pull_ucs2_talloc(dom_info, &dom_info->name,
986 pass.uni_name) == (size_t)-1) {
987 DEBUG(2, ("pull_ucs2_talloc failed\n"));
988 tdb_search_list_free(keys);
989 TALLOC_FREE(tmp_ctx);
990 return NT_STATUS_NO_MEMORY;
993 sid_copy(&dom_info->sid, &pass.domain_sid);
995 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
996 domains, num_domains);
998 if (*domains == NULL) {
999 tdb_search_list_free(keys);
1000 TALLOC_FREE(tmp_ctx);
1001 return NT_STATUS_NO_MEMORY;
1005 DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
1006 *num_domains));
1008 /* free the results of searching the keys */
1009 tdb_search_list_free(keys);
1010 TALLOC_FREE(tmp_ctx);
1012 return NT_STATUS_OK;
1015 /*******************************************************************************
1016 Lock the secrets tdb based on a string - this is used as a primitive form of mutex
1017 between smbd instances.
1018 *******************************************************************************/
1020 bool secrets_named_mutex(const char *name, unsigned int timeout)
1022 int ret = 0;
1024 if (!secrets_init()) {
1025 return false;
1028 ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
1029 if (ret == 0) {
1030 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
1033 return (ret == 0);
1036 /*******************************************************************************
1037 Unlock a named mutex.
1038 *******************************************************************************/
1040 void secrets_named_mutex_release(const char *name)
1042 tdb_unlock_bystring(tdb, name);
1043 DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
1046 /*******************************************************************************
1047 Store a complete AFS keyfile into secrets.tdb.
1048 *******************************************************************************/
1050 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1052 fstring key;
1054 if ((cell == NULL) || (keyfile == NULL))
1055 return False;
1057 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1058 return False;
1060 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1061 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1064 /*******************************************************************************
1065 Fetch the current (highest) AFS key from secrets.tdb
1066 *******************************************************************************/
1067 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1069 fstring key;
1070 struct afs_keyfile *keyfile;
1071 size_t size = 0;
1072 uint32 i;
1074 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1076 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1078 if (keyfile == NULL)
1079 return False;
1081 if (size != sizeof(struct afs_keyfile)) {
1082 SAFE_FREE(keyfile);
1083 return False;
1086 i = ntohl(keyfile->nkeys);
1088 if (i > SECRETS_AFS_MAXKEYS) {
1089 SAFE_FREE(keyfile);
1090 return False;
1093 *result = keyfile->entry[i-1];
1095 result->kvno = ntohl(result->kvno);
1097 return True;
1100 /******************************************************************************
1101 When kerberos is not available, choose between anonymous or
1102 authenticated connections.
1104 We need to use an authenticated connection if DCs have the
1105 RestrictAnonymous registry entry set > 0, or the "Additional
1106 restrictions for anonymous connections" set in the win2k Local
1107 Security Policy.
1109 Caller to free() result in domain, username, password
1110 *******************************************************************************/
1111 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1113 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1114 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1115 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1117 if (*username && **username) {
1119 if (!*domain || !**domain)
1120 *domain = smb_xstrdup(lp_workgroup());
1122 if (!*password || !**password)
1123 *password = smb_xstrdup("");
1125 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1126 *domain, *username));
1128 } else {
1129 DEBUG(3, ("IPC$ connections done anonymously\n"));
1130 *username = smb_xstrdup("");
1131 *domain = smb_xstrdup("");
1132 *password = smb_xstrdup("");
1136 /******************************************************************************
1137 Open or create the schannel session store tdb.
1138 *******************************************************************************/
1140 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1142 TDB_DATA vers;
1143 uint32 ver;
1144 TDB_CONTEXT *tdb_sc = NULL;
1145 char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1147 if (!fname) {
1148 return NULL;
1151 tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1153 if (!tdb_sc) {
1154 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1155 TALLOC_FREE(fname);
1156 return NULL;
1159 vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1160 if (vers.dptr == NULL) {
1161 /* First opener, no version. */
1162 SIVAL(&ver,0,1);
1163 vers.dptr = (uint8 *)&ver;
1164 vers.dsize = 4;
1165 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1166 vers.dptr = NULL;
1167 } else if (vers.dsize == 4) {
1168 ver = IVAL(vers.dptr,0);
1169 if (ver != 1) {
1170 tdb_close(tdb_sc);
1171 tdb_sc = NULL;
1172 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1173 (int)ver, fname ));
1175 } else {
1176 tdb_close(tdb_sc);
1177 tdb_sc = NULL;
1178 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1179 (int)vers.dsize, fname ));
1182 SAFE_FREE(vers.dptr);
1183 TALLOC_FREE(fname);
1185 return tdb_sc;
1188 /******************************************************************************
1189 Store the schannel state after an AUTH2 call.
1190 Note we must be root here.
1191 *******************************************************************************/
1193 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1194 const char *remote_machine,
1195 const struct dcinfo *pdc)
1197 TDB_CONTEXT *tdb_sc = NULL;
1198 TDB_DATA value;
1199 bool ret;
1200 char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1201 SECRETS_SCHANNEL_STATE,
1202 remote_machine);
1203 if (!keystr) {
1204 return False;
1207 /* Work out how large the record is. */
1208 value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1209 pdc->sequence,
1210 8, pdc->seed_chal.data,
1211 8, pdc->clnt_chal.data,
1212 8, pdc->srv_chal.data,
1213 16, pdc->sess_key,
1214 16, pdc->mach_pw,
1215 pdc->mach_acct,
1216 pdc->remote_machine,
1217 pdc->domain);
1219 value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1220 if (!value.dptr) {
1221 TALLOC_FREE(keystr);
1222 return False;
1225 value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1226 pdc->sequence,
1227 8, pdc->seed_chal.data,
1228 8, pdc->clnt_chal.data,
1229 8, pdc->srv_chal.data,
1230 16, pdc->sess_key,
1231 16, pdc->mach_pw,
1232 pdc->mach_acct,
1233 pdc->remote_machine,
1234 pdc->domain);
1236 tdb_sc = open_schannel_session_store(mem_ctx);
1237 if (!tdb_sc) {
1238 TALLOC_FREE(keystr);
1239 TALLOC_FREE(value.dptr);
1240 return False;
1243 ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1245 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1246 keystr ));
1248 tdb_close(tdb_sc);
1249 TALLOC_FREE(keystr);
1250 TALLOC_FREE(value.dptr);
1251 return ret;
1254 /******************************************************************************
1255 Restore the schannel state on a client reconnect.
1256 Note we must be root here.
1257 *******************************************************************************/
1259 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1260 const char *remote_machine,
1261 struct dcinfo **ppdc)
1263 TDB_CONTEXT *tdb_sc = NULL;
1264 TDB_DATA value;
1265 unsigned char *pseed_chal = NULL;
1266 unsigned char *pclnt_chal = NULL;
1267 unsigned char *psrv_chal = NULL;
1268 unsigned char *psess_key = NULL;
1269 unsigned char *pmach_pw = NULL;
1270 uint32 l1, l2, l3, l4, l5;
1271 int ret;
1272 struct dcinfo *pdc = NULL;
1273 char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1274 SECRETS_SCHANNEL_STATE,
1275 remote_machine);
1277 *ppdc = NULL;
1279 if (!keystr) {
1280 return False;
1283 tdb_sc = open_schannel_session_store(mem_ctx);
1284 if (!tdb_sc) {
1285 TALLOC_FREE(keystr);
1286 return False;
1289 value = tdb_fetch_bystring(tdb_sc, keystr);
1290 if (!value.dptr) {
1291 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1292 keystr ));
1293 tdb_close(tdb_sc);
1294 return False;
1297 pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1299 /* Retrieve the record. */
1300 ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1301 &pdc->sequence,
1302 &l1, &pseed_chal,
1303 &l2, &pclnt_chal,
1304 &l3, &psrv_chal,
1305 &l4, &psess_key,
1306 &l5, &pmach_pw,
1307 &pdc->mach_acct,
1308 &pdc->remote_machine,
1309 &pdc->domain);
1311 if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1312 /* Bad record - delete it. */
1313 tdb_delete_bystring(tdb_sc, keystr);
1314 tdb_close(tdb_sc);
1315 TALLOC_FREE(keystr);
1316 TALLOC_FREE(pdc);
1317 SAFE_FREE(pseed_chal);
1318 SAFE_FREE(pclnt_chal);
1319 SAFE_FREE(psrv_chal);
1320 SAFE_FREE(psess_key);
1321 SAFE_FREE(pmach_pw);
1322 SAFE_FREE(value.dptr);
1323 return False;
1326 tdb_close(tdb_sc);
1328 memcpy(pdc->seed_chal.data, pseed_chal, 8);
1329 memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1330 memcpy(pdc->srv_chal.data, psrv_chal, 8);
1331 memcpy(pdc->sess_key, psess_key, 16);
1332 memcpy(pdc->mach_pw, pmach_pw, 16);
1334 /* We know these are true so didn't bother to store them. */
1335 pdc->challenge_sent = True;
1336 pdc->authenticated = True;
1338 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1339 keystr ));
1341 SAFE_FREE(pseed_chal);
1342 SAFE_FREE(pclnt_chal);
1343 SAFE_FREE(psrv_chal);
1344 SAFE_FREE(psess_key);
1345 SAFE_FREE(pmach_pw);
1347 TALLOC_FREE(keystr);
1348 SAFE_FREE(value.dptr);
1350 *ppdc = pdc;
1352 return True;
1355 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1357 char *tdbkey = NULL;
1358 bool ret;
1360 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1361 DEBUG(0, ("asprintf failed!\n"));
1362 return False;
1365 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1367 SAFE_FREE(tdbkey);
1368 return ret;
1371 /*******************************************************************
1372 Find the ldap password.
1373 ******************************************************************/
1375 char *secrets_fetch_generic(const char *owner, const char *key)
1377 char *secret = NULL;
1378 char *tdbkey = NULL;
1380 if (( ! owner) || ( ! key)) {
1381 DEBUG(1, ("Invalid Paramters"));
1382 return NULL;
1385 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1386 DEBUG(0, ("Out of memory!\n"));
1387 return NULL;
1390 secret = (char *)secrets_fetch(tdbkey, NULL);
1391 SAFE_FREE(tdbkey);
1393 return secret;