Cleanup size_t return values in callers of convert_string_allocate
[Samba/bb.git] / source3 / passdb / secrets.c
bloba7223b7e9f1621df5743a6e1c8bec5e9cb0ee55e
1 /*
2 Unix SMB/CIFS implementation.
3 Copyright (C) Andrew Tridgell 1992-2001
4 Copyright (C) Andrew Bartlett 2002
5 Copyright (C) Rafal Szczesniak 2002
6 Copyright (C) Tim Potter 2001
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /* the Samba secrets database stores any generated, private information
23 such as the local SID and machine trust password */
25 #include "includes.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_PASSDB
30 static struct db_context *db_ctx;
32 /* Urrrg. global.... */
33 bool global_machine_password_needs_changing;
35 /**
36 * Use a TDB to store an incrementing random seed.
38 * Initialised to the current pid, the very first time Samba starts,
39 * and incremented by one each time it is needed.
41 * @note Not called by systems with a working /dev/urandom.
43 static void get_rand_seed(int *new_seed)
45 *new_seed = sys_getpid();
46 if (db_ctx) {
47 dbwrap_change_int32_atomic(db_ctx, "INFO/random_seed",
48 new_seed, 1);
52 /* open up the secrets database */
53 bool secrets_init(void)
55 char *fname = NULL;
56 unsigned char dummy;
58 if (db_ctx != NULL)
59 return True;
61 fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
62 lp_private_dir());
63 if (fname == NULL) {
64 return false;
67 db_ctx = db_open_trans(NULL, fname, 0,
68 TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
70 if (db_ctx == NULL) {
71 DEBUG(0,("Failed to open %s\n", fname));
72 TALLOC_FREE(fname);
73 return False;
76 TALLOC_FREE(fname);
78 /**
79 * Set a reseed function for the crypto random generator
81 * This avoids a problem where systems without /dev/urandom
82 * could send the same challenge to multiple clients
84 set_rand_reseed_callback(get_rand_seed);
86 /* Ensure that the reseed is done now, while we are root, etc */
87 generate_random_buffer(&dummy, sizeof(dummy));
89 return True;
92 struct db_context *secrets_db_ctx(void)
94 if (!secrets_init()) {
95 return NULL;
98 return db_ctx;
102 * close secrets.tdb
104 void secrets_shutdown(void)
106 TALLOC_FREE(db_ctx);
109 /* read a entry from the secrets database - the caller must free the result
110 if size is non-null then the size of the entry is put in there
112 void *secrets_fetch(const char *key, size_t *size)
114 TDB_DATA dbuf;
115 void *result;
117 if (!secrets_init()) {
118 return NULL;
121 if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
122 &dbuf) != 0) {
123 return NULL;
126 result = memdup(dbuf.dptr, dbuf.dsize);
127 if (result == NULL) {
128 return NULL;
130 TALLOC_FREE(dbuf.dptr);
132 if (size) {
133 *size = dbuf.dsize;
136 return result;
139 /* store a secrets entry
141 bool secrets_store(const char *key, const void *data, size_t size)
143 NTSTATUS status;
145 if (!secrets_init()) {
146 return false;
149 status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
150 make_tdb_data((const uint8 *)data, size),
151 TDB_REPLACE);
152 return NT_STATUS_IS_OK(status);
156 /* delete a secets database entry
158 bool secrets_delete(const char *key)
160 NTSTATUS status;
161 if (!secrets_init()) {
162 return false;
165 status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
167 return NT_STATUS_IS_OK(status);
171 * Form a key for fetching the domain sid
173 * @param domain domain name
175 * @return keystring
177 static const char *domain_sid_keystr(const char *domain)
179 char *keystr;
181 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
182 SECRETS_DOMAIN_SID, domain);
183 SMB_ASSERT(keystr != NULL);
184 return keystr;
187 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
189 bool ret;
191 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
193 /* Force a re-query, in case we modified our domain */
194 if (ret)
195 reset_global_sam_sid();
196 return ret;
199 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
201 DOM_SID *dyn_sid;
202 size_t size = 0;
204 dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
206 if (dyn_sid == NULL)
207 return False;
209 if (size != sizeof(DOM_SID)) {
210 SAFE_FREE(dyn_sid);
211 return False;
214 *sid = *dyn_sid;
215 SAFE_FREE(dyn_sid);
216 return True;
219 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
221 fstring key;
223 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
224 strupper_m(key);
225 return secrets_store(key, guid, sizeof(struct GUID));
228 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
230 struct GUID *dyn_guid;
231 fstring key;
232 size_t size = 0;
233 struct GUID new_guid;
235 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
236 strupper_m(key);
237 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
239 if (!dyn_guid) {
240 if (lp_server_role() == ROLE_DOMAIN_PDC) {
241 smb_uuid_generate_random(&new_guid);
242 if (!secrets_store_domain_guid(domain, &new_guid))
243 return False;
244 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
246 if (dyn_guid == NULL) {
247 return False;
251 if (size != sizeof(struct GUID)) {
252 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
253 SAFE_FREE(dyn_guid);
254 return False;
257 *guid = *dyn_guid;
258 SAFE_FREE(dyn_guid);
259 return True;
263 * Form a key for fetching the machine trust account sec channel type
265 * @param domain domain name
267 * @return keystring
269 static const char *machine_sec_channel_type_keystr(const char *domain)
271 char *keystr;
273 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
274 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
275 domain);
276 SMB_ASSERT(keystr != NULL);
277 return keystr;
281 * Form a key for fetching the machine trust account last change time
283 * @param domain domain name
285 * @return keystring
287 static const char *machine_last_change_time_keystr(const char *domain)
289 char *keystr;
291 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
292 SECRETS_MACHINE_LAST_CHANGE_TIME,
293 domain);
294 SMB_ASSERT(keystr != NULL);
295 return keystr;
300 * Form a key for fetching the machine trust account password
302 * @param domain domain name
304 * @return keystring
306 static const char *machine_password_keystr(const char *domain)
308 char *keystr;
310 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
311 SECRETS_MACHINE_PASSWORD, domain);
312 SMB_ASSERT(keystr != NULL);
313 return keystr;
317 * Form a key for fetching the machine trust account password
319 * @param domain domain name
321 * @return stored password's key
323 static const char *trust_keystr(const char *domain)
325 char *keystr;
327 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
328 SECRETS_MACHINE_ACCT_PASS, domain);
329 SMB_ASSERT(keystr != NULL);
330 return keystr;
334 * Form a key for fetching a trusted domain password
336 * @param domain trusted domain name
338 * @return stored password's key
340 static char *trustdom_keystr(const char *domain)
342 char *keystr;
344 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
345 SECRETS_DOMTRUST_ACCT_PASS,
346 domain);
347 SMB_ASSERT(keystr != NULL);
348 return keystr;
351 /************************************************************************
352 Lock the trust password entry.
353 ************************************************************************/
355 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
357 if (!secrets_init()) {
358 return NULL;
361 return db_ctx->fetch_locked(
362 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
365 /************************************************************************
366 Routine to get the default secure channel type for trust accounts
367 ************************************************************************/
369 uint32 get_default_sec_channel(void)
371 if (lp_server_role() == ROLE_DOMAIN_BDC ||
372 lp_server_role() == ROLE_DOMAIN_PDC) {
373 return SEC_CHAN_BDC;
374 } else {
375 return SEC_CHAN_WKSTA;
379 /************************************************************************
380 Routine to get the trust account password for a domain.
381 This only tries to get the legacy hashed version of the password.
382 The user of this function must have locked the trust password file using
383 the above secrets_lock_trust_account_password().
384 ************************************************************************/
386 bool secrets_fetch_trust_account_password_legacy(const char *domain,
387 uint8 ret_pwd[16],
388 time_t *pass_last_set_time,
389 uint32 *channel)
391 struct machine_acct_pass *pass;
392 size_t size = 0;
394 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
395 trust_keystr(domain), &size))) {
396 DEBUG(5, ("secrets_fetch failed!\n"));
397 return False;
400 if (size != sizeof(*pass)) {
401 DEBUG(0, ("secrets were of incorrect size!\n"));
402 return False;
405 if (pass_last_set_time) {
406 *pass_last_set_time = pass->mod_time;
408 memcpy(ret_pwd, pass->hash, 16);
410 if (channel) {
411 *channel = get_default_sec_channel();
414 /* Test if machine password has expired and needs to be changed */
415 if (lp_machine_password_timeout()) {
416 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
417 (time_t)lp_machine_password_timeout())) {
418 global_machine_password_needs_changing = True;
422 SAFE_FREE(pass);
423 return True;
426 /************************************************************************
427 Routine to get the trust account password for a domain.
428 The user of this function must have locked the trust password file using
429 the above secrets_lock_trust_account_password().
430 ************************************************************************/
432 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
433 time_t *pass_last_set_time,
434 uint32 *channel)
436 char *plaintext;
438 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
439 channel);
440 if (plaintext) {
441 DEBUG(4,("Using cleartext machine password\n"));
442 E_md4hash(plaintext, ret_pwd);
443 SAFE_FREE(plaintext);
444 return True;
447 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
448 pass_last_set_time,
449 channel);
453 * Pack SID passed by pointer
455 * @param pack_buf pointer to buffer which is to be filled with packed data
456 * @param bufsize size of packing buffer
457 * @param sid pointer to sid to be packed
459 * @return length of the packed representation of the whole structure
461 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
463 int idx;
464 size_t len = 0;
465 uint8 *p = pack_buf;
466 int remaining_space = pack_buf ? bufsize : 0;
468 if (!sid) {
469 return -1;
472 len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
473 sid->num_auths);
474 if (pack_buf) {
475 p = pack_buf + len;
476 remaining_space = bufsize - len;
479 for (idx = 0; idx < 6; idx++) {
480 len += tdb_pack(p, remaining_space, "b",
481 sid->id_auth[idx]);
482 if (pack_buf) {
483 p = pack_buf + len;
484 remaining_space = bufsize - len;
488 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
489 len += tdb_pack(p, remaining_space, "d",
490 sid->sub_auths[idx]);
491 if (pack_buf) {
492 p = pack_buf + len;
493 remaining_space = bufsize - len;
497 return len;
501 * Unpack SID into a pointer
503 * @param pack_buf pointer to buffer with packed representation
504 * @param bufsize size of the buffer
505 * @param sid pointer to sid structure to be filled with unpacked data
507 * @return size of structure unpacked from buffer
509 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
511 int idx, len = 0;
513 if (!sid || !pack_buf) return -1;
515 len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
516 &sid->sid_rev_num, &sid->num_auths);
518 for (idx = 0; idx < 6; idx++) {
519 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
520 &sid->id_auth[idx]);
523 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
524 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
525 &sid->sub_auths[idx]);
528 return len;
532 * Pack TRUSTED_DOM_PASS passed by pointer
534 * @param pack_buf pointer to buffer which is to be filled with packed data
535 * @param bufsize size of the buffer
536 * @param pass pointer to trusted domain password to be packed
538 * @return length of the packed representation of the whole structure
540 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
541 TRUSTED_DOM_PASS* pass)
543 int idx, len = 0;
544 uint8 *p = pack_buf;
545 int remaining_space = pack_buf ? bufsize : 0;
547 if (!pass) {
548 return -1;
551 /* packing unicode domain name and password */
552 len += tdb_pack(p, remaining_space, "d",
553 pass->uni_name_len);
554 if (pack_buf) {
555 p = pack_buf + len;
556 remaining_space = bufsize - len;
559 for (idx = 0; idx < 32; idx++) {
560 len += tdb_pack(p, remaining_space, "w",
561 pass->uni_name[idx]);
562 if (pack_buf) {
563 p = pack_buf + len;
564 remaining_space = bufsize - len;
568 len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
569 pass->pass, pass->mod_time);
570 if (pack_buf) {
571 p = pack_buf + len;
572 remaining_space = bufsize - len;
575 /* packing SID structure */
576 len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
577 if (pack_buf) {
578 p = pack_buf + len;
579 remaining_space = bufsize - len;
582 return len;
587 * Unpack TRUSTED_DOM_PASS passed by pointer
589 * @param pack_buf pointer to buffer with packed representation
590 * @param bufsize size of the buffer
591 * @param pass pointer to trusted domain password to be filled with unpacked data
593 * @return size of structure unpacked from buffer
595 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
596 TRUSTED_DOM_PASS* pass)
598 int idx, len = 0;
599 char *passp = NULL;
601 if (!pack_buf || !pass) return -1;
603 /* unpack unicode domain name and plaintext password */
604 len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
606 for (idx = 0; idx < 32; idx++)
607 len += tdb_unpack(pack_buf + len, bufsize - len, "w",
608 &pass->uni_name[idx]);
610 len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
611 &pass->pass_len, &passp, &pass->mod_time);
612 if (passp) {
613 fstrcpy(pass->pass, passp);
615 SAFE_FREE(passp);
617 /* unpack domain sid */
618 len += tdb_sid_unpack(pack_buf + len, bufsize - len,
619 &pass->domain_sid);
621 return len;
624 /************************************************************************
625 Routine to get account password to trusted domain
626 ************************************************************************/
628 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
629 DOM_SID *sid, time_t *pass_last_set_time)
631 struct trusted_dom_pass pass;
632 size_t size = 0;
634 /* unpacking structures */
635 uint8 *pass_buf;
636 int pass_len = 0;
638 ZERO_STRUCT(pass);
640 /* fetching trusted domain password structure */
641 if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
642 &size))) {
643 DEBUG(5, ("secrets_fetch failed!\n"));
644 return False;
647 /* unpack trusted domain password */
648 pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
649 SAFE_FREE(pass_buf);
651 if (pass_len != size) {
652 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
653 return False;
656 /* the trust's password */
657 if (pwd) {
658 *pwd = SMB_STRDUP(pass.pass);
659 if (!*pwd) {
660 return False;
664 /* last change time */
665 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
667 /* domain sid */
668 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
670 return True;
674 * Routine to store the password for trusted domain
676 * @param domain remote domain name
677 * @param pwd plain text password of trust relationship
678 * @param sid remote domain sid
680 * @return true if succeeded
683 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
684 const DOM_SID *sid)
686 smb_ucs2_t *uni_dom_name;
687 bool ret;
688 size_t converted_size;
690 /* packing structures */
691 uint8 *pass_buf = NULL;
692 int pass_len = 0;
694 struct trusted_dom_pass pass;
695 ZERO_STRUCT(pass);
697 if (!push_ucs2_allocate(&uni_dom_name, domain, &converted_size)) {
698 DEBUG(0, ("Could not convert domain name %s to unicode\n",
699 domain));
700 return False;
703 strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
704 pass.uni_name_len = strlen_w(uni_dom_name)+1;
705 SAFE_FREE(uni_dom_name);
707 /* last change time */
708 pass.mod_time = time(NULL);
710 /* password of the trust */
711 pass.pass_len = strlen(pwd);
712 fstrcpy(pass.pass, pwd);
714 /* domain sid */
715 sid_copy(&pass.domain_sid, sid);
717 /* Calculate the length. */
718 pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
719 pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
720 if (!pass_buf) {
721 return false;
723 pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
724 ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
725 pass_len);
726 SAFE_FREE(pass_buf);
727 return ret;
730 /************************************************************************
731 Routine to delete the plaintext machine account password
732 ************************************************************************/
734 bool secrets_delete_machine_password(const char *domain)
736 return secrets_delete(machine_password_keystr(domain));
739 /************************************************************************
740 Routine to delete the plaintext machine account password, sec channel type and
741 last change time from secrets database
742 ************************************************************************/
744 bool secrets_delete_machine_password_ex(const char *domain)
746 if (!secrets_delete(machine_password_keystr(domain))) {
747 return false;
749 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
750 return false;
752 return secrets_delete(machine_last_change_time_keystr(domain));
755 /************************************************************************
756 Routine to delete the domain sid
757 ************************************************************************/
759 bool secrets_delete_domain_sid(const char *domain)
761 return secrets_delete(domain_sid_keystr(domain));
764 /************************************************************************
765 Routine to set the plaintext machine account password for a realm
766 the password is assumed to be a null terminated ascii string
767 ************************************************************************/
769 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
771 bool ret;
772 uint32 last_change_time;
773 uint32 sec_channel_type;
775 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
776 if (!ret)
777 return ret;
779 SIVAL(&last_change_time, 0, time(NULL));
780 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
782 SIVAL(&sec_channel_type, 0, sec_channel);
783 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
785 return ret;
788 /************************************************************************
789 Routine to fetch the plaintext machine account password for a realm
790 the password is assumed to be a null terminated ascii string.
791 ************************************************************************/
793 char *secrets_fetch_machine_password(const char *domain,
794 time_t *pass_last_set_time,
795 uint32 *channel)
797 char *ret;
798 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
800 if (pass_last_set_time) {
801 size_t size;
802 uint32 *last_set_time;
803 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
804 if (last_set_time) {
805 *pass_last_set_time = IVAL(last_set_time,0);
806 SAFE_FREE(last_set_time);
807 } else {
808 *pass_last_set_time = 0;
812 if (channel) {
813 size_t size;
814 uint32 *channel_type;
815 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
816 if (channel_type) {
817 *channel = IVAL(channel_type,0);
818 SAFE_FREE(channel_type);
819 } else {
820 *channel = get_default_sec_channel();
824 return ret;
827 /************************************************************************
828 Routine to delete the password for trusted domain
829 ************************************************************************/
831 bool trusted_domain_password_delete(const char *domain)
833 return secrets_delete(trustdom_keystr(domain));
836 bool secrets_store_ldap_pw(const char* dn, char* pw)
838 char *key = NULL;
839 bool ret;
841 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
842 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
843 return False;
846 ret = secrets_store(key, pw, strlen(pw)+1);
848 SAFE_FREE(key);
849 return ret;
852 /*******************************************************************
853 Find the ldap password.
854 ******************************************************************/
856 bool fetch_ldap_pw(char **dn, char** pw)
858 char *key = NULL;
859 size_t size = 0;
861 *dn = smb_xstrdup(lp_ldap_admin_dn());
863 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
864 SAFE_FREE(*dn);
865 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
868 *pw=(char *)secrets_fetch(key, &size);
869 SAFE_FREE(key);
871 if (!size) {
872 /* Upgrade 2.2 style entry */
873 char *p;
874 char* old_style_key = SMB_STRDUP(*dn);
875 char *data;
876 fstring old_style_pw;
878 if (!old_style_key) {
879 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
880 return False;
883 for (p=old_style_key; *p; p++)
884 if (*p == ',') *p = '/';
886 data=(char *)secrets_fetch(old_style_key, &size);
887 if (!size && size < sizeof(old_style_pw)) {
888 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
889 SAFE_FREE(old_style_key);
890 SAFE_FREE(*dn);
891 return False;
894 size = MIN(size, sizeof(fstring)-1);
895 strncpy(old_style_pw, data, size);
896 old_style_pw[size] = 0;
898 SAFE_FREE(data);
900 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
901 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
902 SAFE_FREE(old_style_key);
903 SAFE_FREE(*dn);
904 return False;
906 if (!secrets_delete(old_style_key)) {
907 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
910 SAFE_FREE(old_style_key);
912 *pw = smb_xstrdup(old_style_pw);
915 return True;
919 * Get trusted domains info from secrets.tdb.
922 struct list_trusted_domains_state {
923 uint32 num_domains;
924 struct trustdom_info **domains;
927 static int list_trusted_domain(struct db_record *rec, void *private_data)
929 const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
930 size_t converted_size, packed_size = 0;
931 struct trusted_dom_pass pass;
932 struct trustdom_info *dom_info;
934 struct list_trusted_domains_state *state =
935 (struct list_trusted_domains_state *)private_data;
937 if ((rec->key.dsize < prefix_len)
938 || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
939 prefix_len) != 0)) {
940 return 0;
943 packed_size = tdb_trusted_dom_pass_unpack(
944 rec->value.dptr, rec->value.dsize, &pass);
946 if (rec->value.dsize != packed_size) {
947 DEBUG(2, ("Secrets record is invalid!\n"));
948 return 0;
951 if (pass.domain_sid.num_auths != 4) {
952 DEBUG(0, ("SID %s is not a domain sid, has %d "
953 "auths instead of 4\n",
954 sid_string_dbg(&pass.domain_sid),
955 pass.domain_sid.num_auths));
956 return 0;
959 if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
960 DEBUG(0, ("talloc failed\n"));
961 return 0;
964 if (!pull_ucs2_talloc(dom_info, &dom_info->name, pass.uni_name,
965 &converted_size)) {
966 DEBUG(2, ("pull_ucs2_talloc failed\n"));
967 TALLOC_FREE(dom_info);
968 return 0;
971 sid_copy(&dom_info->sid, &pass.domain_sid);
973 ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
974 &state->domains, &state->num_domains);
976 if (state->domains == NULL) {
977 state->num_domains = 0;
978 return -1;
980 return 0;
983 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
984 struct trustdom_info ***domains)
986 struct list_trusted_domains_state state;
988 secrets_init();
990 if (db_ctx == NULL) {
991 return NT_STATUS_ACCESS_DENIED;
994 state.num_domains = 0;
997 * Make sure that a talloc context for the trustdom_info structs
998 * exists
1001 if (!(state.domains = TALLOC_ARRAY(
1002 mem_ctx, struct trustdom_info *, 1))) {
1003 return NT_STATUS_NO_MEMORY;
1006 db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
1008 *num_domains = state.num_domains;
1009 *domains = state.domains;
1010 return NT_STATUS_OK;
1013 /*******************************************************************************
1014 Store a complete AFS keyfile into secrets.tdb.
1015 *******************************************************************************/
1017 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1019 fstring key;
1021 if ((cell == NULL) || (keyfile == NULL))
1022 return False;
1024 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1025 return False;
1027 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1028 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1031 /*******************************************************************************
1032 Fetch the current (highest) AFS key from secrets.tdb
1033 *******************************************************************************/
1034 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1036 fstring key;
1037 struct afs_keyfile *keyfile;
1038 size_t size = 0;
1039 uint32 i;
1041 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1043 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1045 if (keyfile == NULL)
1046 return False;
1048 if (size != sizeof(struct afs_keyfile)) {
1049 SAFE_FREE(keyfile);
1050 return False;
1053 i = ntohl(keyfile->nkeys);
1055 if (i > SECRETS_AFS_MAXKEYS) {
1056 SAFE_FREE(keyfile);
1057 return False;
1060 *result = keyfile->entry[i-1];
1062 result->kvno = ntohl(result->kvno);
1064 return True;
1067 /******************************************************************************
1068 When kerberos is not available, choose between anonymous or
1069 authenticated connections.
1071 We need to use an authenticated connection if DCs have the
1072 RestrictAnonymous registry entry set > 0, or the "Additional
1073 restrictions for anonymous connections" set in the win2k Local
1074 Security Policy.
1076 Caller to free() result in domain, username, password
1077 *******************************************************************************/
1078 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1080 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1081 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1082 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1084 if (*username && **username) {
1086 if (!*domain || !**domain)
1087 *domain = smb_xstrdup(lp_workgroup());
1089 if (!*password || !**password)
1090 *password = smb_xstrdup("");
1092 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1093 *domain, *username));
1095 } else {
1096 DEBUG(3, ("IPC$ connections done anonymously\n"));
1097 *username = smb_xstrdup("");
1098 *domain = smb_xstrdup("");
1099 *password = smb_xstrdup("");
1103 /******************************************************************************
1104 Open or create the schannel session store tdb.
1105 *******************************************************************************/
1107 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1109 TDB_DATA vers;
1110 uint32 ver;
1111 TDB_CONTEXT *tdb_sc = NULL;
1112 char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1114 if (!fname) {
1115 return NULL;
1118 tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1120 if (!tdb_sc) {
1121 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1122 TALLOC_FREE(fname);
1123 return NULL;
1126 vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1127 if (vers.dptr == NULL) {
1128 /* First opener, no version. */
1129 SIVAL(&ver,0,1);
1130 vers.dptr = (uint8 *)&ver;
1131 vers.dsize = 4;
1132 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1133 vers.dptr = NULL;
1134 } else if (vers.dsize == 4) {
1135 ver = IVAL(vers.dptr,0);
1136 if (ver != 1) {
1137 tdb_close(tdb_sc);
1138 tdb_sc = NULL;
1139 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1140 (int)ver, fname ));
1142 } else {
1143 tdb_close(tdb_sc);
1144 tdb_sc = NULL;
1145 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1146 (int)vers.dsize, fname ));
1149 SAFE_FREE(vers.dptr);
1150 TALLOC_FREE(fname);
1152 return tdb_sc;
1155 /******************************************************************************
1156 Store the schannel state after an AUTH2 call.
1157 Note we must be root here.
1158 *******************************************************************************/
1160 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1161 const char *remote_machine,
1162 const struct dcinfo *pdc)
1164 TDB_CONTEXT *tdb_sc = NULL;
1165 TDB_DATA value;
1166 bool ret;
1167 char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1168 SECRETS_SCHANNEL_STATE,
1169 remote_machine);
1170 if (!keystr) {
1171 return False;
1174 /* Work out how large the record is. */
1175 value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1176 pdc->sequence,
1177 8, pdc->seed_chal.data,
1178 8, pdc->clnt_chal.data,
1179 8, pdc->srv_chal.data,
1180 16, pdc->sess_key,
1181 16, pdc->mach_pw,
1182 pdc->mach_acct,
1183 pdc->remote_machine,
1184 pdc->domain);
1186 value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1187 if (!value.dptr) {
1188 TALLOC_FREE(keystr);
1189 return False;
1192 value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1193 pdc->sequence,
1194 8, pdc->seed_chal.data,
1195 8, pdc->clnt_chal.data,
1196 8, pdc->srv_chal.data,
1197 16, pdc->sess_key,
1198 16, pdc->mach_pw,
1199 pdc->mach_acct,
1200 pdc->remote_machine,
1201 pdc->domain);
1203 tdb_sc = open_schannel_session_store(mem_ctx);
1204 if (!tdb_sc) {
1205 TALLOC_FREE(keystr);
1206 TALLOC_FREE(value.dptr);
1207 return False;
1210 ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1212 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1213 keystr ));
1215 tdb_close(tdb_sc);
1216 TALLOC_FREE(keystr);
1217 TALLOC_FREE(value.dptr);
1218 return ret;
1221 /******************************************************************************
1222 Restore the schannel state on a client reconnect.
1223 Note we must be root here.
1224 *******************************************************************************/
1226 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1227 const char *remote_machine,
1228 struct dcinfo **ppdc)
1230 TDB_CONTEXT *tdb_sc = NULL;
1231 TDB_DATA value;
1232 unsigned char *pseed_chal = NULL;
1233 unsigned char *pclnt_chal = NULL;
1234 unsigned char *psrv_chal = NULL;
1235 unsigned char *psess_key = NULL;
1236 unsigned char *pmach_pw = NULL;
1237 uint32 l1, l2, l3, l4, l5;
1238 int ret;
1239 struct dcinfo *pdc = NULL;
1240 char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1241 SECRETS_SCHANNEL_STATE,
1242 remote_machine);
1244 *ppdc = NULL;
1246 if (!keystr) {
1247 return False;
1250 tdb_sc = open_schannel_session_store(mem_ctx);
1251 if (!tdb_sc) {
1252 TALLOC_FREE(keystr);
1253 return False;
1256 value = tdb_fetch_bystring(tdb_sc, keystr);
1257 if (!value.dptr) {
1258 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1259 keystr ));
1260 tdb_close(tdb_sc);
1261 return False;
1264 pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1266 /* Retrieve the record. */
1267 ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1268 &pdc->sequence,
1269 &l1, &pseed_chal,
1270 &l2, &pclnt_chal,
1271 &l3, &psrv_chal,
1272 &l4, &psess_key,
1273 &l5, &pmach_pw,
1274 &pdc->mach_acct,
1275 &pdc->remote_machine,
1276 &pdc->domain);
1278 if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1279 /* Bad record - delete it. */
1280 tdb_delete_bystring(tdb_sc, keystr);
1281 tdb_close(tdb_sc);
1282 TALLOC_FREE(keystr);
1283 TALLOC_FREE(pdc);
1284 SAFE_FREE(pseed_chal);
1285 SAFE_FREE(pclnt_chal);
1286 SAFE_FREE(psrv_chal);
1287 SAFE_FREE(psess_key);
1288 SAFE_FREE(pmach_pw);
1289 SAFE_FREE(value.dptr);
1290 return False;
1293 tdb_close(tdb_sc);
1295 memcpy(pdc->seed_chal.data, pseed_chal, 8);
1296 memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1297 memcpy(pdc->srv_chal.data, psrv_chal, 8);
1298 memcpy(pdc->sess_key, psess_key, 16);
1299 memcpy(pdc->mach_pw, pmach_pw, 16);
1301 /* We know these are true so didn't bother to store them. */
1302 pdc->challenge_sent = True;
1303 pdc->authenticated = True;
1305 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1306 keystr ));
1308 SAFE_FREE(pseed_chal);
1309 SAFE_FREE(pclnt_chal);
1310 SAFE_FREE(psrv_chal);
1311 SAFE_FREE(psess_key);
1312 SAFE_FREE(pmach_pw);
1314 TALLOC_FREE(keystr);
1315 SAFE_FREE(value.dptr);
1317 *ppdc = pdc;
1319 return True;
1322 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1324 char *tdbkey = NULL;
1325 bool ret;
1327 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1328 DEBUG(0, ("asprintf failed!\n"));
1329 return False;
1332 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1334 SAFE_FREE(tdbkey);
1335 return ret;
1338 /*******************************************************************
1339 Find the ldap password.
1340 ******************************************************************/
1342 char *secrets_fetch_generic(const char *owner, const char *key)
1344 char *secret = NULL;
1345 char *tdbkey = NULL;
1347 if (( ! owner) || ( ! key)) {
1348 DEBUG(1, ("Invalid Paramters"));
1349 return NULL;
1352 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1353 DEBUG(0, ("Out of memory!\n"));
1354 return NULL;
1357 secret = (char *)secrets_fetch(tdbkey, NULL);
1358 SAFE_FREE(tdbkey);
1360 return secret;