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 */
28 #define DBGC_CLASS DBGC_PASSDB
30 static TDB_CONTEXT *tdb;
32 /* Urrrg. global.... */
33 bool global_machine_password_needs_changing;
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();
47 tdb_change_int32_atomic(tdb, "INFO/random_seed", new_seed, 1);
51 /* open up the secrets database */
52 bool secrets_init(void)
61 ctx = talloc_init("secrets_init");
65 fname = talloc_asprintf(ctx,
73 tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
76 DEBUG(0,("Failed to open %s\n", fname));
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));
97 /* read a entry from the secrets database - the caller must free the result
98 if size is non-null then the size of the entry is put in there
100 void *secrets_fetch(const char *key, size_t *size)
106 dbuf = tdb_fetch(tdb, string_tdb_data(key));
112 /* store a secrets entry
114 bool secrets_store(const char *key, const void *data, size_t size)
119 return tdb_trans_store(tdb, string_tdb_data(key),
120 make_tdb_data((const uint8 *)data, size),
125 /* delete a secets database entry
127 bool secrets_delete(const char *key)
132 return tdb_trans_delete(tdb, string_tdb_data(key)) == 0;
136 * Form a key for fetching the domain sid
138 * @param domain domain name
142 static const char *domain_sid_keystr(const char *domain)
146 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
147 SECRETS_DOMAIN_SID, domain);
148 SMB_ASSERT(keystr != NULL);
155 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
159 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
161 /* Force a re-query, in case we modified our domain */
163 reset_global_sam_sid();
167 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
172 dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
177 if (size != sizeof(DOM_SID)) {
187 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
191 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
193 return secrets_store(key, guid, sizeof(struct GUID));
196 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
198 struct GUID *dyn_guid;
201 struct GUID new_guid;
203 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
205 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
208 if (lp_server_role() == ROLE_DOMAIN_PDC) {
209 smb_uuid_generate_random(&new_guid);
210 if (!secrets_store_domain_guid(domain, &new_guid))
212 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
214 if (dyn_guid == NULL) {
219 if (size != sizeof(struct GUID)) {
220 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
231 * Form a key for fetching the machine trust account sec channel type
233 * @param domain domain name
237 static const char *machine_sec_channel_type_keystr(const char *domain)
241 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
242 SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
243 SMB_ASSERT(keystr != NULL);
251 * Form a key for fetching the machine trust account last change time
253 * @param domain domain name
257 static const char *machine_last_change_time_keystr(const char *domain)
261 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
262 SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
263 SMB_ASSERT(keystr != NULL);
272 * Form a key for fetching the machine trust account password
274 * @param domain domain name
278 static const char *machine_password_keystr(const char *domain)
282 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
283 SECRETS_MACHINE_PASSWORD, domain);
284 SMB_ASSERT(keystr != NULL);
292 * Form a key for fetching the machine trust account password
294 * @param domain domain name
296 * @return stored password's key
298 static const char *trust_keystr(const char *domain)
302 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
303 SECRETS_MACHINE_ACCT_PASS, domain);
304 SMB_ASSERT(keystr != NULL);
312 * Form a key for fetching a trusted domain password
314 * @param domain trusted domain name
316 * @return stored password's key
318 static char *trustdom_keystr(const char *domain)
322 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
323 SECRETS_DOMTRUST_ACCT_PASS, domain);
324 SMB_ASSERT(keystr != NULL);
330 /************************************************************************
331 Lock the trust password entry.
332 ************************************************************************/
334 bool secrets_lock_trust_account_password(const char *domain, bool dolock)
340 return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
342 tdb_unlock_bystring(tdb, trust_keystr(domain));
346 /************************************************************************
347 Routine to get the default secure channel type for trust accounts
348 ************************************************************************/
350 uint32 get_default_sec_channel(void)
352 if (lp_server_role() == ROLE_DOMAIN_BDC ||
353 lp_server_role() == ROLE_DOMAIN_PDC) {
356 return SEC_CHAN_WKSTA;
360 /************************************************************************
361 Routine to get the trust account password for a domain.
362 This only tries to get the legacy hashed version of the password.
363 The user of this function must have locked the trust password file using
364 the above secrets_lock_trust_account_password().
365 ************************************************************************/
367 bool secrets_fetch_trust_account_password_legacy(const char *domain,
369 time_t *pass_last_set_time,
372 struct machine_acct_pass *pass;
375 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
376 trust_keystr(domain), &size))) {
377 DEBUG(5, ("secrets_fetch failed!\n"));
381 if (size != sizeof(*pass)) {
382 DEBUG(0, ("secrets were of incorrect size!\n"));
386 if (pass_last_set_time) {
387 *pass_last_set_time = pass->mod_time;
389 memcpy(ret_pwd, pass->hash, 16);
392 *channel = get_default_sec_channel();
395 /* Test if machine password has expired and needs to be changed */
396 if (lp_machine_password_timeout()) {
397 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
398 (time_t)lp_machine_password_timeout())) {
399 global_machine_password_needs_changing = True;
407 /************************************************************************
408 Routine to get the trust account password for a domain.
409 The user of this function must have locked the trust password file using
410 the above secrets_lock_trust_account_password().
411 ************************************************************************/
413 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
414 time_t *pass_last_set_time,
419 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
422 DEBUG(4,("Using cleartext machine password\n"));
423 E_md4hash(plaintext, ret_pwd);
424 SAFE_FREE(plaintext);
428 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
434 * Pack SID passed by pointer
436 * @param pack_buf pointer to buffer which is to be filled with packed data
437 * @param bufsize size of packing buffer
438 * @param sid pointer to sid to be packed
440 * @return length of the packed representation of the whole structure
442 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
447 int remaining_space = pack_buf ? bufsize : 0;
453 len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
457 remaining_space = bufsize - len;
460 for (idx = 0; idx < 6; idx++) {
461 len += tdb_pack(p, remaining_space, "b",
465 remaining_space = bufsize - len;
469 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
470 len += tdb_pack(p, remaining_space, "d",
471 sid->sub_auths[idx]);
474 remaining_space = bufsize - len;
482 * Unpack SID into a pointer
484 * @param pack_buf pointer to buffer with packed representation
485 * @param bufsize size of the buffer
486 * @param sid pointer to sid structure to be filled with unpacked data
488 * @return size of structure unpacked from buffer
490 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
494 if (!sid || !pack_buf) return -1;
496 len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
497 &sid->sid_rev_num, &sid->num_auths);
499 for (idx = 0; idx < 6; idx++) {
500 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
504 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
505 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
506 &sid->sub_auths[idx]);
513 * Pack TRUSTED_DOM_PASS passed by pointer
515 * @param pack_buf pointer to buffer which is to be filled with packed data
516 * @param bufsize size of the buffer
517 * @param pass pointer to trusted domain password to be packed
519 * @return length of the packed representation of the whole structure
521 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
522 TRUSTED_DOM_PASS* pass)
526 int remaining_space = pack_buf ? bufsize : 0;
532 /* packing unicode domain name and password */
533 len += tdb_pack(p, remaining_space, "d",
537 remaining_space = bufsize - len;
540 for (idx = 0; idx < 32; idx++) {
541 len += tdb_pack(p, remaining_space, "w",
542 pass->uni_name[idx]);
545 remaining_space = bufsize - len;
549 len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
550 pass->pass, pass->mod_time);
553 remaining_space = bufsize - len;
556 /* packing SID structure */
557 len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
560 remaining_space = bufsize - len;
568 * Unpack TRUSTED_DOM_PASS passed by pointer
570 * @param pack_buf pointer to buffer with packed representation
571 * @param bufsize size of the buffer
572 * @param pass pointer to trusted domain password to be filled with unpacked data
574 * @return size of structure unpacked from buffer
576 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
577 TRUSTED_DOM_PASS* pass)
582 if (!pack_buf || !pass) return -1;
584 /* unpack unicode domain name and plaintext password */
585 len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
587 for (idx = 0; idx < 32; idx++)
588 len += tdb_unpack(pack_buf + len, bufsize - len, "w",
589 &pass->uni_name[idx]);
591 len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
592 &pass->pass_len, &passp, &pass->mod_time);
594 fstrcpy(pass->pass, passp);
598 /* unpack domain sid */
599 len += tdb_sid_unpack(pack_buf + len, bufsize - len,
605 /************************************************************************
606 Routine to get account password to trusted domain
607 ************************************************************************/
609 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
610 DOM_SID *sid, time_t *pass_last_set_time)
612 struct trusted_dom_pass pass;
615 /* unpacking structures */
621 /* fetching trusted domain password structure */
622 if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
624 DEBUG(5, ("secrets_fetch failed!\n"));
628 /* unpack trusted domain password */
629 pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
632 if (pass_len != size) {
633 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
637 /* the trust's password */
639 *pwd = SMB_STRDUP(pass.pass);
645 /* last change time */
646 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
649 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
655 * Routine to store the password for trusted domain
657 * @param domain remote domain name
658 * @param pwd plain text password of trust relationship
659 * @param sid remote domain sid
661 * @return true if succeeded
664 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
667 smb_ucs2_t *uni_dom_name;
670 /* packing structures */
671 uint8 *pass_buf = NULL;
674 struct trusted_dom_pass pass;
677 if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
678 DEBUG(0, ("Could not convert domain name %s to unicode\n",
683 strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
684 pass.uni_name_len = strlen_w(uni_dom_name)+1;
685 SAFE_FREE(uni_dom_name);
687 /* last change time */
688 pass.mod_time = time(NULL);
690 /* password of the trust */
691 pass.pass_len = strlen(pwd);
692 fstrcpy(pass.pass, pwd);
695 sid_copy(&pass.domain_sid, sid);
697 /* Calculate the length. */
698 pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
699 pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
703 pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
704 ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
710 /************************************************************************
711 Routine to delete the plaintext machine account password
712 ************************************************************************/
714 bool secrets_delete_machine_password(const char *domain)
716 return secrets_delete(machine_password_keystr(domain));
719 /************************************************************************
720 Routine to delete the plaintext machine account password, sec channel type and
721 last change time from secrets database
722 ************************************************************************/
724 bool secrets_delete_machine_password_ex(const char *domain)
726 if (!secrets_delete(machine_password_keystr(domain))) {
729 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
732 return secrets_delete(machine_last_change_time_keystr(domain));
735 /************************************************************************
736 Routine to delete the domain sid
737 ************************************************************************/
739 bool secrets_delete_domain_sid(const char *domain)
741 return secrets_delete(domain_sid_keystr(domain));
744 /************************************************************************
745 Routine to set the plaintext machine account password for a realm
746 the password is assumed to be a null terminated ascii string
747 ************************************************************************/
749 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
752 uint32 last_change_time;
753 uint32 sec_channel_type;
755 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
759 SIVAL(&last_change_time, 0, time(NULL));
760 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
762 SIVAL(&sec_channel_type, 0, sec_channel);
763 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
768 /************************************************************************
769 Routine to fetch the plaintext machine account password for a realm
770 the password is assumed to be a null terminated ascii string.
771 ************************************************************************/
773 char *secrets_fetch_machine_password(const char *domain,
774 time_t *pass_last_set_time,
778 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
780 if (pass_last_set_time) {
782 uint32 *last_set_time;
783 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
785 *pass_last_set_time = IVAL(last_set_time,0);
786 SAFE_FREE(last_set_time);
788 *pass_last_set_time = 0;
794 uint32 *channel_type;
795 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
797 *channel = IVAL(channel_type,0);
798 SAFE_FREE(channel_type);
800 *channel = get_default_sec_channel();
807 /************************************************************************
808 Routine to delete the password for trusted domain
809 ************************************************************************/
811 bool trusted_domain_password_delete(const char *domain)
813 return secrets_delete(trustdom_keystr(domain));
816 bool secrets_store_ldap_pw(const char* dn, char* pw)
821 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
822 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
826 ret = secrets_store(key, pw, strlen(pw)+1);
832 /*******************************************************************
833 Find the ldap password.
834 ******************************************************************/
836 bool fetch_ldap_pw(char **dn, char** pw)
841 *dn = smb_xstrdup(lp_ldap_admin_dn());
843 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
845 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
848 *pw=(char *)secrets_fetch(key, &size);
852 /* Upgrade 2.2 style entry */
854 char* old_style_key = SMB_STRDUP(*dn);
856 fstring old_style_pw;
858 if (!old_style_key) {
859 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
863 for (p=old_style_key; *p; p++)
864 if (*p == ',') *p = '/';
866 data=(char *)secrets_fetch(old_style_key, &size);
867 if (!size && size < sizeof(old_style_pw)) {
868 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
869 SAFE_FREE(old_style_key);
874 size = MIN(size, sizeof(fstring)-1);
875 strncpy(old_style_pw, data, size);
876 old_style_pw[size] = 0;
880 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
881 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
882 SAFE_FREE(old_style_key);
886 if (!secrets_delete(old_style_key)) {
887 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
890 SAFE_FREE(old_style_key);
892 *pw = smb_xstrdup(old_style_pw);
899 * Get trusted domains info from secrets.tdb.
902 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
903 struct trustdom_info ***domains)
905 TDB_LIST_NODE *keys, *k;
909 if (!(tmp_ctx = talloc_new(mem_ctx))) {
910 return NT_STATUS_NO_MEMORY;
913 if (!secrets_init()) 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() "
920 TALLOC_FREE(tmp_ctx);
921 return NT_STATUS_NO_MEMORY;
927 * Make sure that a talloc context for the trustdom_info structs
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) {
942 size_t size = 0, packed_size = 0;
943 struct trusted_dom_pass pass;
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,
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,
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",
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));
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",
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)
1024 if (!secrets_init())
1027 ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
1029 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
1034 /*******************************************************************************
1035 Unlock a named mutex.
1036 *******************************************************************************/
1038 void secrets_named_mutex_release(const char *name)
1040 tdb_unlock_bystring(tdb, name);
1041 DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
1044 /*******************************************************************************
1045 Store a complete AFS keyfile into secrets.tdb.
1046 *******************************************************************************/
1048 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1052 if ((cell == NULL) || (keyfile == NULL))
1055 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1058 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1059 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1062 /*******************************************************************************
1063 Fetch the current (highest) AFS key from secrets.tdb
1064 *******************************************************************************/
1065 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1068 struct afs_keyfile *keyfile;
1072 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1074 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1076 if (keyfile == NULL)
1079 if (size != sizeof(struct afs_keyfile)) {
1084 i = ntohl(keyfile->nkeys);
1086 if (i > SECRETS_AFS_MAXKEYS) {
1091 *result = keyfile->entry[i-1];
1093 result->kvno = ntohl(result->kvno);
1098 /******************************************************************************
1099 When kerberos is not available, choose between anonymous or
1100 authenticated connections.
1102 We need to use an authenticated connection if DCs have the
1103 RestrictAnonymous registry entry set > 0, or the "Additional
1104 restrictions for anonymous connections" set in the win2k Local
1107 Caller to free() result in domain, username, password
1108 *******************************************************************************/
1109 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1111 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1112 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1113 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1115 if (*username && **username) {
1117 if (!*domain || !**domain)
1118 *domain = smb_xstrdup(lp_workgroup());
1120 if (!*password || !**password)
1121 *password = smb_xstrdup("");
1123 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1124 *domain, *username));
1127 DEBUG(3, ("IPC$ connections done anonymously\n"));
1128 *username = smb_xstrdup("");
1129 *domain = smb_xstrdup("");
1130 *password = smb_xstrdup("");
1134 /******************************************************************************
1135 Open or create the schannel session store tdb.
1136 *******************************************************************************/
1138 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1142 TDB_CONTEXT *tdb_sc = NULL;
1143 char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1149 tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1152 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1157 vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1158 if (vers.dptr == NULL) {
1159 /* First opener, no version. */
1161 vers.dptr = (uint8 *)&ver;
1163 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1165 } else if (vers.dsize == 4) {
1166 ver = IVAL(vers.dptr,0);
1170 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1176 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1177 (int)vers.dsize, fname ));
1180 SAFE_FREE(vers.dptr);
1186 /******************************************************************************
1187 Store the schannel state after an AUTH2 call.
1188 Note we must be root here.
1189 *******************************************************************************/
1191 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1192 const char *remote_machine,
1193 const struct dcinfo *pdc)
1195 TDB_CONTEXT *tdb_sc = NULL;
1198 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1206 /* Work out how large the record is. */
1207 value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1209 8, pdc->seed_chal.data,
1210 8, pdc->clnt_chal.data,
1211 8, pdc->srv_chal.data,
1215 pdc->remote_machine,
1218 value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1220 TALLOC_FREE(keystr);
1224 value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1226 8, pdc->seed_chal.data,
1227 8, pdc->clnt_chal.data,
1228 8, pdc->srv_chal.data,
1232 pdc->remote_machine,
1235 tdb_sc = open_schannel_session_store(mem_ctx);
1237 TALLOC_FREE(keystr);
1238 TALLOC_FREE(value.dptr);
1242 ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1244 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1248 TALLOC_FREE(keystr);
1249 TALLOC_FREE(value.dptr);
1253 /******************************************************************************
1254 Restore the schannel state on a client reconnect.
1255 Note we must be root here.
1256 *******************************************************************************/
1258 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1259 const char *remote_machine,
1260 struct dcinfo **ppdc)
1262 TDB_CONTEXT *tdb_sc = NULL;
1264 unsigned char *pseed_chal = NULL;
1265 unsigned char *pclnt_chal = NULL;
1266 unsigned char *psrv_chal = NULL;
1267 unsigned char *psess_key = NULL;
1268 unsigned char *pmach_pw = NULL;
1269 uint32 l1, l2, l3, l4, l5;
1271 struct dcinfo *pdc = NULL;
1272 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1283 tdb_sc = open_schannel_session_store(mem_ctx);
1285 TALLOC_FREE(keystr);
1289 value = tdb_fetch_bystring(tdb_sc, keystr);
1291 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1297 pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1299 /* Retrieve the record. */
1300 ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1308 &pdc->remote_machine,
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);
1315 TALLOC_FREE(keystr);
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);
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",
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);
1355 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1357 char *tdbkey = NULL;
1360 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1361 DEBUG(0, ("asprintf failed!\n"));
1365 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
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"));
1385 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1386 DEBUG(0, ("Out of memory!\n"));
1390 secret = (char *)secrets_fetch(tdbkey, NULL);