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;
135 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
140 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
142 ret = secrets_store(key, sid, sizeof(DOM_SID));
144 /* Force a re-query, in case we modified our domain */
146 reset_global_sam_sid();
150 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
156 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
158 dyn_sid = (DOM_SID *)secrets_fetch(key, &size);
163 if (size != sizeof(DOM_SID)) {
173 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
177 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
179 return secrets_store(key, guid, sizeof(struct GUID));
182 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
184 struct GUID *dyn_guid;
187 struct GUID new_guid;
189 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
191 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
194 if (lp_server_role() == ROLE_DOMAIN_PDC) {
195 smb_uuid_generate_random(&new_guid);
196 if (!secrets_store_domain_guid(domain, &new_guid))
198 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
200 if (dyn_guid == NULL) {
205 if (size != sizeof(struct GUID)) {
206 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
217 * Form a key for fetching the machine trust account password
219 * @param domain domain name
221 * @return stored password's key
223 static const char *trust_keystr(const char *domain)
227 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
228 SECRETS_MACHINE_ACCT_PASS, domain);
229 SMB_ASSERT(keystr != NULL);
237 * Form a key for fetching a trusted domain password
239 * @param domain trusted domain name
241 * @return stored password's key
243 static char *trustdom_keystr(const char *domain)
247 keystr = talloc_asprintf(talloc_tos(), "%s/%s",
248 SECRETS_DOMTRUST_ACCT_PASS, domain);
249 SMB_ASSERT(keystr != NULL);
255 /************************************************************************
256 Lock the trust password entry.
257 ************************************************************************/
259 bool secrets_lock_trust_account_password(const char *domain, bool dolock)
265 return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
267 tdb_unlock_bystring(tdb, trust_keystr(domain));
271 /************************************************************************
272 Routine to get the default secure channel type for trust accounts
273 ************************************************************************/
275 uint32 get_default_sec_channel(void)
277 if (lp_server_role() == ROLE_DOMAIN_BDC ||
278 lp_server_role() == ROLE_DOMAIN_PDC) {
281 return SEC_CHAN_WKSTA;
285 /************************************************************************
286 Routine to get the trust account password for a domain.
287 This only tries to get the legacy hashed version of the password.
288 The user of this function must have locked the trust password file using
289 the above secrets_lock_trust_account_password().
290 ************************************************************************/
292 bool secrets_fetch_trust_account_password_legacy(const char *domain,
294 time_t *pass_last_set_time,
297 struct machine_acct_pass *pass;
300 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
301 trust_keystr(domain), &size))) {
302 DEBUG(5, ("secrets_fetch failed!\n"));
306 if (size != sizeof(*pass)) {
307 DEBUG(0, ("secrets were of incorrect size!\n"));
311 if (pass_last_set_time) {
312 *pass_last_set_time = pass->mod_time;
314 memcpy(ret_pwd, pass->hash, 16);
317 *channel = get_default_sec_channel();
320 /* Test if machine password has expired and needs to be changed */
321 if (lp_machine_password_timeout()) {
322 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
323 (time_t)lp_machine_password_timeout())) {
324 global_machine_password_needs_changing = True;
332 /************************************************************************
333 Routine to get the trust account password for a domain.
334 The user of this function must have locked the trust password file using
335 the above secrets_lock_trust_account_password().
336 ************************************************************************/
338 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
339 time_t *pass_last_set_time,
344 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
347 DEBUG(4,("Using cleartext machine password\n"));
348 E_md4hash(plaintext, ret_pwd);
349 SAFE_FREE(plaintext);
353 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
359 * Pack SID passed by pointer
361 * @param pack_buf pointer to buffer which is to be filled with packed data
362 * @param bufsize size of packing buffer
363 * @param sid pointer to sid to be packed
365 * @return length of the packed representation of the whole structure
367 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
372 int remaining_space = pack_buf ? bufsize : 0;
378 len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
382 remaining_space = bufsize - len;
385 for (idx = 0; idx < 6; idx++) {
386 len += tdb_pack(p, remaining_space, "b",
390 remaining_space = bufsize - len;
394 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
395 len += tdb_pack(p, remaining_space, "d",
396 sid->sub_auths[idx]);
399 remaining_space = bufsize - len;
407 * Unpack SID into a pointer
409 * @param pack_buf pointer to buffer with packed representation
410 * @param bufsize size of the buffer
411 * @param sid pointer to sid structure to be filled with unpacked data
413 * @return size of structure unpacked from buffer
415 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
419 if (!sid || !pack_buf) return -1;
421 len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
422 &sid->sid_rev_num, &sid->num_auths);
424 for (idx = 0; idx < 6; idx++) {
425 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
429 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
430 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
431 &sid->sub_auths[idx]);
438 * Pack TRUSTED_DOM_PASS passed by pointer
440 * @param pack_buf pointer to buffer which is to be filled with packed data
441 * @param bufsize size of the buffer
442 * @param pass pointer to trusted domain password to be packed
444 * @return length of the packed representation of the whole structure
446 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
447 TRUSTED_DOM_PASS* pass)
451 int remaining_space = pack_buf ? bufsize : 0;
457 /* packing unicode domain name and password */
458 len += tdb_pack(p, remaining_space, "d",
462 remaining_space = bufsize - len;
465 for (idx = 0; idx < 32; idx++) {
466 len += tdb_pack(p, remaining_space, "w",
467 pass->uni_name[idx]);
470 remaining_space = bufsize - len;
474 len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
475 pass->pass, pass->mod_time);
478 remaining_space = bufsize - len;
481 /* packing SID structure */
482 len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
485 remaining_space = bufsize - len;
493 * Unpack TRUSTED_DOM_PASS passed by pointer
495 * @param pack_buf pointer to buffer with packed representation
496 * @param bufsize size of the buffer
497 * @param pass pointer to trusted domain password to be filled with unpacked data
499 * @return size of structure unpacked from buffer
501 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
502 TRUSTED_DOM_PASS* pass)
507 if (!pack_buf || !pass) return -1;
509 /* unpack unicode domain name and plaintext password */
510 len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
512 for (idx = 0; idx < 32; idx++)
513 len += tdb_unpack(pack_buf + len, bufsize - len, "w",
514 &pass->uni_name[idx]);
516 len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
517 &pass->pass_len, &passp, &pass->mod_time);
519 fstrcpy(pass->pass, passp);
523 /* unpack domain sid */
524 len += tdb_sid_unpack(pack_buf + len, bufsize - len,
530 /************************************************************************
531 Routine to get account password to trusted domain
532 ************************************************************************/
534 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
535 DOM_SID *sid, time_t *pass_last_set_time)
537 struct trusted_dom_pass pass;
540 /* unpacking structures */
546 /* fetching trusted domain password structure */
547 if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
549 DEBUG(5, ("secrets_fetch failed!\n"));
553 /* unpack trusted domain password */
554 pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
557 if (pass_len != size) {
558 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
562 /* the trust's password */
564 *pwd = SMB_STRDUP(pass.pass);
570 /* last change time */
571 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
574 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
580 * Routine to store the password for trusted domain
582 * @param domain remote domain name
583 * @param pwd plain text password of trust relationship
584 * @param sid remote domain sid
586 * @return true if succeeded
589 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
592 smb_ucs2_t *uni_dom_name;
595 /* packing structures */
596 uint8 *pass_buf = NULL;
599 struct trusted_dom_pass pass;
602 if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
603 DEBUG(0, ("Could not convert domain name %s to unicode\n",
608 strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
609 pass.uni_name_len = strlen_w(uni_dom_name)+1;
610 SAFE_FREE(uni_dom_name);
612 /* last change time */
613 pass.mod_time = time(NULL);
615 /* password of the trust */
616 pass.pass_len = strlen(pwd);
617 fstrcpy(pass.pass, pwd);
620 sid_copy(&pass.domain_sid, sid);
622 /* Calculate the length. */
623 pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
624 pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
628 pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
629 ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
635 /************************************************************************
636 Routine to set the plaintext machine account password for a realm
637 the password is assumed to be a null terminated ascii string
638 ************************************************************************/
640 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
644 uint32 last_change_time;
645 uint32 sec_channel_type;
647 asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
652 ret = secrets_store(key, pass, strlen(pass)+1);
658 asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
663 SIVAL(&last_change_time, 0, time(NULL));
664 ret = secrets_store(key, &last_change_time, sizeof(last_change_time));
667 asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
672 SIVAL(&sec_channel_type, 0, sec_channel);
673 ret = secrets_store(key, &sec_channel_type, sizeof(sec_channel_type));
679 /************************************************************************
680 Routine to fetch the plaintext machine account password for a realm
681 the password is assumed to be a null terminated ascii string.
682 ************************************************************************/
684 char *secrets_fetch_machine_password(const char *domain,
685 time_t *pass_last_set_time,
690 asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
692 ret = (char *)secrets_fetch(key, NULL);
695 if (pass_last_set_time) {
697 uint32 *last_set_time;
698 asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
700 last_set_time = (unsigned int *)secrets_fetch(key, &size);
702 *pass_last_set_time = IVAL(last_set_time,0);
703 SAFE_FREE(last_set_time);
705 *pass_last_set_time = 0;
712 uint32 *channel_type;
713 asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
715 channel_type = (unsigned int *)secrets_fetch(key, &size);
717 *channel = IVAL(channel_type,0);
718 SAFE_FREE(channel_type);
720 *channel = get_default_sec_channel();
728 /************************************************************************
729 Routine to delete the password for trusted domain
730 ************************************************************************/
732 bool trusted_domain_password_delete(const char *domain)
734 return secrets_delete(trustdom_keystr(domain));
737 bool secrets_store_ldap_pw(const char* dn, char* pw)
742 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
743 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
747 ret = secrets_store(key, pw, strlen(pw)+1);
753 /*******************************************************************
754 Find the ldap password.
755 ******************************************************************/
757 bool fetch_ldap_pw(char **dn, char** pw)
762 *dn = smb_xstrdup(lp_ldap_admin_dn());
764 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
766 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
769 *pw=(char *)secrets_fetch(key, &size);
773 /* Upgrade 2.2 style entry */
775 char* old_style_key = SMB_STRDUP(*dn);
777 fstring old_style_pw;
779 if (!old_style_key) {
780 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
784 for (p=old_style_key; *p; p++)
785 if (*p == ',') *p = '/';
787 data=(char *)secrets_fetch(old_style_key, &size);
788 if (!size && size < sizeof(old_style_pw)) {
789 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
790 SAFE_FREE(old_style_key);
795 size = MIN(size, sizeof(fstring)-1);
796 strncpy(old_style_pw, data, size);
797 old_style_pw[size] = 0;
801 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
802 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
803 SAFE_FREE(old_style_key);
807 if (!secrets_delete(old_style_key)) {
808 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
811 SAFE_FREE(old_style_key);
813 *pw = smb_xstrdup(old_style_pw);
820 * Get trusted domains info from secrets.tdb.
823 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
824 struct trustdom_info ***domains)
826 TDB_LIST_NODE *keys, *k;
830 if (!(tmp_ctx = talloc_new(mem_ctx))) {
831 return NT_STATUS_NO_MEMORY;
834 if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
836 /* generate searching pattern */
837 pattern = talloc_asprintf(tmp_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
838 if (pattern == NULL) {
839 DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
841 TALLOC_FREE(tmp_ctx);
842 return NT_STATUS_NO_MEMORY;
848 * Make sure that a talloc context for the trustdom_info structs
852 if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
853 TALLOC_FREE(tmp_ctx);
854 return NT_STATUS_NO_MEMORY;
857 /* fetching trusted domains' data and collecting them in a list */
858 keys = tdb_search_keys(tdb, pattern);
860 /* searching for keys in secrets db -- way to go ... */
861 for (k = keys; k; k = k->next) {
863 size_t size = 0, packed_size = 0;
864 struct trusted_dom_pass pass;
866 struct trustdom_info *dom_info;
868 /* important: ensure null-termination of the key string */
869 secrets_key = talloc_strndup(tmp_ctx,
870 (const char *)k->node_key.dptr,
873 DEBUG(0, ("strndup failed!\n"));
874 tdb_search_list_free(keys);
875 TALLOC_FREE(tmp_ctx);
876 return NT_STATUS_NO_MEMORY;
879 packed_pass = (uint8 *)secrets_fetch(secrets_key, &size);
880 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
882 /* packed representation isn't needed anymore */
883 SAFE_FREE(packed_pass);
885 if (size != packed_size) {
886 DEBUG(2, ("Secrets record %s is invalid!\n",
891 if (pass.domain_sid.num_auths != 4) {
892 DEBUG(0, ("SID %s is not a domain sid, has %d "
893 "auths instead of 4\n",
894 sid_string_static(&pass.domain_sid),
895 pass.domain_sid.num_auths));
899 if (!(dom_info = TALLOC_P(*domains, struct trustdom_info))) {
900 DEBUG(0, ("talloc failed\n"));
901 tdb_search_list_free(keys);
902 TALLOC_FREE(tmp_ctx);
903 return NT_STATUS_NO_MEMORY;
906 if (pull_ucs2_talloc(dom_info, &dom_info->name,
907 pass.uni_name) == (size_t)-1) {
908 DEBUG(2, ("pull_ucs2_talloc failed\n"));
909 tdb_search_list_free(keys);
910 TALLOC_FREE(tmp_ctx);
911 return NT_STATUS_NO_MEMORY;
914 sid_copy(&dom_info->sid, &pass.domain_sid);
916 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
917 domains, num_domains);
919 if (*domains == NULL) {
920 tdb_search_list_free(keys);
921 TALLOC_FREE(tmp_ctx);
922 return NT_STATUS_NO_MEMORY;
926 DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
929 /* free the results of searching the keys */
930 tdb_search_list_free(keys);
931 TALLOC_FREE(tmp_ctx);
936 /*******************************************************************************
937 Lock the secrets tdb based on a string - this is used as a primitive form of mutex
938 between smbd instances.
939 *******************************************************************************/
941 bool secrets_named_mutex(const char *name, unsigned int timeout)
948 ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
950 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
955 /*******************************************************************************
956 Unlock a named mutex.
957 *******************************************************************************/
959 void secrets_named_mutex_release(const char *name)
961 tdb_unlock_bystring(tdb, name);
962 DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
965 /*******************************************************************************
966 Store a complete AFS keyfile into secrets.tdb.
967 *******************************************************************************/
969 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
973 if ((cell == NULL) || (keyfile == NULL))
976 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
979 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
980 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
983 /*******************************************************************************
984 Fetch the current (highest) AFS key from secrets.tdb
985 *******************************************************************************/
986 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
989 struct afs_keyfile *keyfile;
993 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
995 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1000 if (size != sizeof(struct afs_keyfile)) {
1005 i = ntohl(keyfile->nkeys);
1007 if (i > SECRETS_AFS_MAXKEYS) {
1012 *result = keyfile->entry[i-1];
1014 result->kvno = ntohl(result->kvno);
1019 /******************************************************************************
1020 When kerberos is not available, choose between anonymous or
1021 authenticated connections.
1023 We need to use an authenticated connection if DCs have the
1024 RestrictAnonymous registry entry set > 0, or the "Additional
1025 restrictions for anonymous connections" set in the win2k Local
1028 Caller to free() result in domain, username, password
1029 *******************************************************************************/
1030 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1032 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1033 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1034 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1036 if (*username && **username) {
1038 if (!*domain || !**domain)
1039 *domain = smb_xstrdup(lp_workgroup());
1041 if (!*password || !**password)
1042 *password = smb_xstrdup("");
1044 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1045 *domain, *username));
1048 DEBUG(3, ("IPC$ connections done anonymously\n"));
1049 *username = smb_xstrdup("");
1050 *domain = smb_xstrdup("");
1051 *password = smb_xstrdup("");
1055 /******************************************************************************
1056 Open or create the schannel session store tdb.
1057 *******************************************************************************/
1059 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1063 TDB_CONTEXT *tdb_sc = NULL;
1064 char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1070 tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1073 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1078 vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1079 if (vers.dptr == NULL) {
1080 /* First opener, no version. */
1082 vers.dptr = (uint8 *)&ver;
1084 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1086 } else if (vers.dsize == 4) {
1087 ver = IVAL(vers.dptr,0);
1091 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1097 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1098 (int)vers.dsize, fname ));
1101 SAFE_FREE(vers.dptr);
1107 /******************************************************************************
1108 Store the schannel state after an AUTH2 call.
1109 Note we must be root here.
1110 *******************************************************************************/
1112 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1113 const char *remote_machine,
1114 const struct dcinfo *pdc)
1116 TDB_CONTEXT *tdb_sc = NULL;
1119 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1127 /* Work out how large the record is. */
1128 value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1130 8, pdc->seed_chal.data,
1131 8, pdc->clnt_chal.data,
1132 8, pdc->srv_chal.data,
1136 pdc->remote_machine,
1139 value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1141 TALLOC_FREE(keystr);
1145 value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1147 8, pdc->seed_chal.data,
1148 8, pdc->clnt_chal.data,
1149 8, pdc->srv_chal.data,
1153 pdc->remote_machine,
1156 tdb_sc = open_schannel_session_store(mem_ctx);
1158 TALLOC_FREE(keystr);
1159 TALLOC_FREE(value.dptr);
1163 ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1165 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1169 TALLOC_FREE(keystr);
1170 TALLOC_FREE(value.dptr);
1174 /******************************************************************************
1175 Restore the schannel state on a client reconnect.
1176 Note we must be root here.
1177 *******************************************************************************/
1179 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1180 const char *remote_machine,
1181 struct dcinfo **ppdc)
1183 TDB_CONTEXT *tdb_sc = NULL;
1185 unsigned char *pseed_chal = NULL;
1186 unsigned char *pclnt_chal = NULL;
1187 unsigned char *psrv_chal = NULL;
1188 unsigned char *psess_key = NULL;
1189 unsigned char *pmach_pw = NULL;
1190 uint32 l1, l2, l3, l4, l5;
1192 struct dcinfo *pdc = NULL;
1193 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1204 tdb_sc = open_schannel_session_store(mem_ctx);
1206 TALLOC_FREE(keystr);
1210 value = tdb_fetch_bystring(tdb_sc, keystr);
1212 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1218 pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1220 /* Retrieve the record. */
1221 ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1229 &pdc->remote_machine,
1232 if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1233 /* Bad record - delete it. */
1234 tdb_delete_bystring(tdb_sc, keystr);
1236 TALLOC_FREE(keystr);
1238 SAFE_FREE(pseed_chal);
1239 SAFE_FREE(pclnt_chal);
1240 SAFE_FREE(psrv_chal);
1241 SAFE_FREE(psess_key);
1242 SAFE_FREE(pmach_pw);
1243 SAFE_FREE(value.dptr);
1249 memcpy(pdc->seed_chal.data, pseed_chal, 8);
1250 memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1251 memcpy(pdc->srv_chal.data, psrv_chal, 8);
1252 memcpy(pdc->sess_key, psess_key, 16);
1253 memcpy(pdc->mach_pw, pmach_pw, 16);
1255 /* We know these are true so didn't bother to store them. */
1256 pdc->challenge_sent = True;
1257 pdc->authenticated = True;
1259 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1262 SAFE_FREE(pseed_chal);
1263 SAFE_FREE(pclnt_chal);
1264 SAFE_FREE(psrv_chal);
1265 SAFE_FREE(psess_key);
1266 SAFE_FREE(pmach_pw);
1268 TALLOC_FREE(keystr);
1269 SAFE_FREE(value.dptr);
1276 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1278 char *tdbkey = NULL;
1281 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1282 DEBUG(0, ("asprintf failed!\n"));
1286 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1292 /*******************************************************************
1293 Find the ldap password.
1294 ******************************************************************/
1296 char *secrets_fetch_generic(const char *owner, const char *key)
1298 char *secret = NULL;
1299 char *tdbkey = NULL;
1301 if (( ! owner) || ( ! key)) {
1302 DEBUG(1, ("Invalid Paramters"));
1306 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1307 DEBUG(0, ("Out of memory!\n"));
1311 secret = (char *)secrets_fetch(tdbkey, NULL);