such as the local SID and machine trust password */
#include "includes.h"
+#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB
-static TDB_CONTEXT *tdb;
+static struct db_context *db_ctx;
/* Urrrg. global.... */
bool global_machine_password_needs_changing;
*
* @note Not called by systems with a working /dev/urandom.
*/
-static void get_rand_seed(int *new_seed)
+static void get_rand_seed(void *userdata, int *new_seed)
{
*new_seed = sys_getpid();
- if (tdb) {
- tdb_change_int32_atomic(tdb, "INFO/random_seed", new_seed, 1);
+ if (db_ctx) {
+ dbwrap_trans_change_int32_atomic(db_ctx, "INFO/random_seed",
+ new_seed, 1);
}
}
/* open up the secrets database */
bool secrets_init(void)
{
- TALLOC_CTX *ctx;
char *fname = NULL;
unsigned char dummy;
- if (tdb)
+ if (db_ctx != NULL)
return True;
- ctx = talloc_init("secrets_init");
- if (!ctx) {
- return false;
- }
- fname = talloc_asprintf(ctx,
- "%s/secrets.tdb",
- lp_private_dir());
- if (!fname) {
- TALLOC_FREE(ctx);
+ fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
+ lp_private_dir());
+ if (fname == NULL) {
return false;
}
- tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ db_ctx = db_open(NULL, fname, 0,
+ TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb) {
+ if (db_ctx == NULL) {
DEBUG(0,("Failed to open %s\n", fname));
- TALLOC_FREE(ctx);
+ TALLOC_FREE(fname);
return False;
}
- TALLOC_FREE(ctx);
+ TALLOC_FREE(fname);
/**
* Set a reseed function for the crypto random generator
* This avoids a problem where systems without /dev/urandom
* could send the same challenge to multiple clients
*/
- set_rand_reseed_callback(get_rand_seed);
+ set_rand_reseed_callback(get_rand_seed, NULL);
/* Ensure that the reseed is done now, while we are root, etc */
generate_random_buffer(&dummy, sizeof(dummy));
return True;
}
+struct db_context *secrets_db_ctx(void)
+{
+ if (!secrets_init()) {
+ return NULL;
+ }
+
+ return db_ctx;
+}
+
/*
* close secrets.tdb
*/
void secrets_shutdown(void)
{
- if (!tdb) {
- return;
- }
-
- tdb_close(tdb);
- tdb = NULL;
+ TALLOC_FREE(db_ctx);
}
/* read a entry from the secrets database - the caller must free the result
void *secrets_fetch(const char *key, size_t *size)
{
TDB_DATA dbuf;
- secrets_init();
- if (!tdb)
+ void *result;
+
+ if (!secrets_init()) {
+ return NULL;
+ }
+
+ if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
+ &dbuf) != 0) {
return NULL;
- dbuf = tdb_fetch(tdb, string_tdb_data(key));
- if (size)
+ }
+
+ result = memdup(dbuf.dptr, dbuf.dsize);
+ if (result == NULL) {
+ return NULL;
+ }
+ TALLOC_FREE(dbuf.dptr);
+
+ if (size) {
*size = dbuf.dsize;
- return dbuf.dptr;
+ }
+
+ return result;
}
/* store a secrets entry
*/
bool secrets_store(const char *key, const void *data, size_t size)
{
- secrets_init();
- if (!tdb)
- return False;
- return tdb_trans_store(tdb, string_tdb_data(key),
- make_tdb_data((const uint8 *)data, size),
- TDB_REPLACE) == 0;
+ NTSTATUS status;
+
+ if (!secrets_init()) {
+ return false;
+ }
+
+ status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
+ make_tdb_data((const uint8 *)data, size),
+ TDB_REPLACE);
+ return NT_STATUS_IS_OK(status);
}
*/
bool secrets_delete(const char *key)
{
- secrets_init();
- if (!tdb)
- return False;
- return tdb_trans_delete(tdb, string_tdb_data(key)) == 0;
+ NTSTATUS status;
+ if (!secrets_init()) {
+ return false;
+ }
+
+ status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
+
+ return NT_STATUS_IS_OK(status);
}
/**
{
char *keystr;
- keystr = talloc_asprintf(talloc_tos(), "%s/%s",
- SECRETS_DOMAIN_SID, domain);
+ keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
+ SECRETS_DOMAIN_SID, domain);
SMB_ASSERT(keystr != NULL);
-
- strupper_m(keystr);
-
return keystr;
}
if (!dyn_guid) {
if (lp_server_role() == ROLE_DOMAIN_PDC) {
- smb_uuid_generate_random(&new_guid);
+ new_guid = GUID_random();
if (!secrets_store_domain_guid(domain, &new_guid))
return False;
dyn_guid = (struct GUID *)secrets_fetch(key, &size);
return True;
}
+bool secrets_store_local_schannel_key(uint8_t schannel_key[16])
+{
+ return secrets_store(SECRETS_LOCAL_SCHANNEL_KEY, schannel_key, 16);
+}
+
+bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16])
+{
+ size_t size = 0;
+ uint8_t *key;
+
+ key = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY, &size);
+ if (key == NULL) {
+ return false;
+ }
+
+ if (size != 16) {
+ SAFE_FREE(key);
+ return false;
+ }
+
+ memcpy(schannel_key, key, 16);
+ SAFE_FREE(key);
+ return true;
+}
+
/**
* Form a key for fetching the machine trust account sec channel type
*
{
char *keystr;
- keystr = talloc_asprintf(talloc_tos(), "%s/%s",
- SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
+ keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
+ SECRETS_MACHINE_SEC_CHANNEL_TYPE,
+ domain);
SMB_ASSERT(keystr != NULL);
-
- strupper_m(keystr);
-
return keystr;
}
{
char *keystr;
- keystr = talloc_asprintf(talloc_tos(), "%s/%s",
- SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
+ keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
+ SECRETS_MACHINE_LAST_CHANGE_TIME,
+ domain);
SMB_ASSERT(keystr != NULL);
-
- strupper_m(keystr);
-
return keystr;
}
{
char *keystr;
- keystr = talloc_asprintf(talloc_tos(), "%s/%s",
- SECRETS_MACHINE_PASSWORD, domain);
+ keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
+ SECRETS_MACHINE_PASSWORD, domain);
SMB_ASSERT(keystr != NULL);
-
- strupper_m(keystr);
-
return keystr;
}
{
char *keystr;
- keystr = talloc_asprintf(talloc_tos(), "%s/%s",
- SECRETS_MACHINE_ACCT_PASS, domain);
+ keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
+ SECRETS_MACHINE_ACCT_PASS, domain);
SMB_ASSERT(keystr != NULL);
-
- strupper_m(keystr);
-
return keystr;
}
{
char *keystr;
- keystr = talloc_asprintf(talloc_tos(), "%s/%s",
- SECRETS_DOMTRUST_ACCT_PASS, domain);
+ keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
+ SECRETS_DOMTRUST_ACCT_PASS,
+ domain);
SMB_ASSERT(keystr != NULL);
- strupper_m(keystr);
-
return keystr;
}
Lock the trust password entry.
************************************************************************/
-bool secrets_lock_trust_account_password(const char *domain, bool dolock)
+void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
{
- if (!tdb)
- return False;
+ if (!secrets_init()) {
+ return NULL;
+ }
- if (dolock)
- return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
- else
- tdb_unlock_bystring(tdb, trust_keystr(domain));
- return True;
+ return db_ctx->fetch_locked(
+ db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
}
/************************************************************************
Routine to get the default secure channel type for trust accounts
************************************************************************/
-uint32 get_default_sec_channel(void)
+enum netr_SchannelType get_default_sec_channel(void)
{
if (lp_server_role() == ROLE_DOMAIN_BDC ||
lp_server_role() == ROLE_DOMAIN_PDC) {
bool secrets_fetch_trust_account_password_legacy(const char *domain,
uint8 ret_pwd[16],
time_t *pass_last_set_time,
- uint32 *channel)
+ enum netr_SchannelType *channel)
{
struct machine_acct_pass *pass;
size_t size = 0;
if (size != sizeof(*pass)) {
DEBUG(0, ("secrets were of incorrect size!\n"));
+ SAFE_FREE(pass);
return False;
}
bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
time_t *pass_last_set_time,
- uint32 *channel)
+ enum netr_SchannelType *channel)
{
char *plaintext;
{
smb_ucs2_t *uni_dom_name;
bool ret;
+ size_t converted_size;
/* packing structures */
uint8 *pass_buf = NULL;
struct trusted_dom_pass pass;
ZERO_STRUCT(pass);
- if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
+ if (!push_ucs2_talloc(talloc_tos(), &uni_dom_name, domain, &converted_size)) {
DEBUG(0, ("Could not convert domain name %s to unicode\n",
domain));
return False;
strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
pass.uni_name_len = strlen_w(uni_dom_name)+1;
- SAFE_FREE(uni_dom_name);
+ TALLOC_FREE(uni_dom_name);
/* last change time */
pass.mod_time = time(NULL);
/* Calculate the length. */
pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
- pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
+ pass_buf = talloc_array(talloc_tos(), uint8, pass_len);
if (!pass_buf) {
return false;
}
pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
pass_len);
- SAFE_FREE(pass_buf);
+ TALLOC_FREE(pass_buf);
return ret;
}
the password is assumed to be a null terminated ascii string
************************************************************************/
-bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
+bool secrets_store_machine_password(const char *pass, const char *domain,
+ enum netr_SchannelType sec_channel)
{
bool ret;
uint32 last_change_time;
char *secrets_fetch_machine_password(const char *domain,
time_t *pass_last_set_time,
- uint32 *channel)
+ enum netr_SchannelType *channel)
{
char *ret;
ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
SAFE_FREE(*dn);
DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
+ return false;
}
*pw=(char *)secrets_fetch(key, &size);
if (*p == ',') *p = '/';
data=(char *)secrets_fetch(old_style_key, &size);
- if (!size && size < sizeof(old_style_pw)) {
+ if ((data == NULL) || (size < sizeof(old_style_pw))) {
DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
SAFE_FREE(old_style_key);
SAFE_FREE(*dn);
+ SAFE_FREE(data);
return False;
}
* Get trusted domains info from secrets.tdb.
**/
-NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
- struct trustdom_info ***domains)
+struct list_trusted_domains_state {
+ uint32 num_domains;
+ struct trustdom_info **domains;
+};
+
+static int list_trusted_domain(struct db_record *rec, void *private_data)
{
- TDB_LIST_NODE *keys, *k;
- char *pattern;
- TALLOC_CTX *tmp_ctx;
+ const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
+ size_t converted_size, packed_size = 0;
+ struct trusted_dom_pass pass;
+ struct trustdom_info *dom_info;
- if (!(tmp_ctx = talloc_new(mem_ctx))) {
- return NT_STATUS_NO_MEMORY;
+ struct list_trusted_domains_state *state =
+ (struct list_trusted_domains_state *)private_data;
+
+ if ((rec->key.dsize < prefix_len)
+ || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
+ prefix_len) != 0)) {
+ return 0;
}
- if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
+ packed_size = tdb_trusted_dom_pass_unpack(
+ rec->value.dptr, rec->value.dsize, &pass);
- /* generate searching pattern */
- pattern = talloc_asprintf(tmp_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
- if (pattern == NULL) {
- DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
- "failed!\n"));
- TALLOC_FREE(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
+ if (rec->value.dsize != packed_size) {
+ DEBUG(2, ("Secrets record is invalid!\n"));
+ return 0;
}
- *num_domains = 0;
+ if (pass.domain_sid.num_auths != 4) {
+ DEBUG(0, ("SID %s is not a domain sid, has %d "
+ "auths instead of 4\n",
+ sid_string_dbg(&pass.domain_sid),
+ pass.domain_sid.num_auths));
+ return 0;
+ }
- /*
- * Make sure that a talloc context for the trustdom_info structs
- * exists
- */
+ if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
+ DEBUG(0, ("talloc failed\n"));
+ return 0;
+ }
- if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
- TALLOC_FREE(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
+ if (!pull_ucs2_talloc(dom_info, &dom_info->name, pass.uni_name,
+ &converted_size)) {
+ DEBUG(2, ("pull_ucs2_talloc failed\n"));
+ TALLOC_FREE(dom_info);
+ return 0;
}
- /* fetching trusted domains' data and collecting them in a list */
- keys = tdb_search_keys(tdb, pattern);
-
- /* searching for keys in secrets db -- way to go ... */
- for (k = keys; k; k = k->next) {
- uint8 *packed_pass;
- size_t size = 0, packed_size = 0;
- struct trusted_dom_pass pass;
- char *secrets_key;
- struct trustdom_info *dom_info;
-
- /* important: ensure null-termination of the key string */
- secrets_key = talloc_strndup(tmp_ctx,
- (const char *)k->node_key.dptr,
- k->node_key.dsize);
- if (!secrets_key) {
- DEBUG(0, ("strndup failed!\n"));
- tdb_search_list_free(keys);
- TALLOC_FREE(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
+ sid_copy(&dom_info->sid, &pass.domain_sid);
- packed_pass = (uint8 *)secrets_fetch(secrets_key, &size);
- packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
- &pass);
- /* packed representation isn't needed anymore */
- SAFE_FREE(packed_pass);
+ ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
+ &state->domains, &state->num_domains);
- if (size != packed_size) {
- DEBUG(2, ("Secrets record %s is invalid!\n",
- secrets_key));
- continue;
- }
+ if (state->domains == NULL) {
+ state->num_domains = 0;
+ return -1;
+ }
+ return 0;
+}
- if (pass.domain_sid.num_auths != 4) {
- DEBUG(0, ("SID %s is not a domain sid, has %d "
- "auths instead of 4\n",
- sid_string_dbg(&pass.domain_sid),
- pass.domain_sid.num_auths));
- continue;
- }
+NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
+ struct trustdom_info ***domains)
+{
+ struct list_trusted_domains_state state;
- if (!(dom_info = TALLOC_P(*domains, struct trustdom_info))) {
- DEBUG(0, ("talloc failed\n"));
- tdb_search_list_free(keys);
- TALLOC_FREE(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
+ secrets_init();
- if (pull_ucs2_talloc(dom_info, &dom_info->name,
- pass.uni_name) == (size_t)-1) {
- DEBUG(2, ("pull_ucs2_talloc failed\n"));
- tdb_search_list_free(keys);
- TALLOC_FREE(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
+ if (db_ctx == NULL) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
- sid_copy(&dom_info->sid, &pass.domain_sid);
+ state.num_domains = 0;
- ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
- domains, num_domains);
+ /*
+ * Make sure that a talloc context for the trustdom_info structs
+ * exists
+ */
- if (*domains == NULL) {
- tdb_search_list_free(keys);
- TALLOC_FREE(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
+ if (!(state.domains = TALLOC_ARRAY(
+ mem_ctx, struct trustdom_info *, 1))) {
+ return NT_STATUS_NO_MEMORY;
}
- DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
- *num_domains));
-
- /* free the results of searching the keys */
- tdb_search_list_free(keys);
- TALLOC_FREE(tmp_ctx);
+ db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
+ *num_domains = state.num_domains;
+ *domains = state.domains;
return NT_STATUS_OK;
}
-/*******************************************************************************
- Lock the secrets tdb based on a string - this is used as a primitive form of mutex
- between smbd instances.
-*******************************************************************************/
-
-bool secrets_named_mutex(const char *name, unsigned int timeout)
-{
- int ret = 0;
-
- if (!secrets_init())
- return False;
-
- ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
- if (ret == 0)
- DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
-
- return (ret == 0);
-}
-
-/*******************************************************************************
- Unlock a named mutex.
-*******************************************************************************/
-
-void secrets_named_mutex_release(const char *name)
-{
- tdb_unlock_bystring(tdb, name);
- DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
-}
-
/*******************************************************************************
Store a complete AFS keyfile into secrets.tdb.
*******************************************************************************/
result->kvno = ntohl(result->kvno);
+ SAFE_FREE(keyfile);
+
return True;
}
Open or create the schannel session store tdb.
*******************************************************************************/
-static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
+#define SCHANNEL_STORE_VERSION_1 1
+#define SCHANNEL_STORE_VERSION_2 2 /* should not be used */
+#define SCHANNEL_STORE_VERSION_CURRENT SCHANNEL_STORE_VERSION_1
+
+TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
{
TDB_DATA vers;
uint32 ver;
return NULL;
}
+ again:
vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
if (vers.dptr == NULL) {
/* First opener, no version. */
- SIVAL(&ver,0,1);
+ SIVAL(&ver,0,SCHANNEL_STORE_VERSION_CURRENT);
vers.dptr = (uint8 *)&ver;
vers.dsize = 4;
tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
vers.dptr = NULL;
} else if (vers.dsize == 4) {
ver = IVAL(vers.dptr,0);
- if (ver != 1) {
- tdb_close(tdb_sc);
- tdb_sc = NULL;
+ if (ver == SCHANNEL_STORE_VERSION_2) {
DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
(int)ver, fname ));
+ tdb_wipe_all(tdb_sc);
+ goto again;
+ }
+ if (ver != SCHANNEL_STORE_VERSION_CURRENT) {
+ DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
+ (int)ver, fname ));
+ tdb_close(tdb_sc);
+ tdb_sc = NULL;
}
} else {
tdb_close(tdb_sc);
return tdb_sc;
}
-/******************************************************************************
- Store the schannel state after an AUTH2 call.
- Note we must be root here.
-*******************************************************************************/
-
-bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
- const char *remote_machine,
- const struct dcinfo *pdc)
-{
- TDB_CONTEXT *tdb_sc = NULL;
- TDB_DATA value;
- bool ret;
- char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
- remote_machine);
- if (!keystr) {
- return False;
- }
-
- strupper_m(keystr);
-
- /* Work out how large the record is. */
- value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
- pdc->sequence,
- 8, pdc->seed_chal.data,
- 8, pdc->clnt_chal.data,
- 8, pdc->srv_chal.data,
- 16, pdc->sess_key,
- 16, pdc->mach_pw,
- pdc->mach_acct,
- pdc->remote_machine,
- pdc->domain);
-
- value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
- if (!value.dptr) {
- TALLOC_FREE(keystr);
- return False;
- }
-
- value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
- pdc->sequence,
- 8, pdc->seed_chal.data,
- 8, pdc->clnt_chal.data,
- 8, pdc->srv_chal.data,
- 16, pdc->sess_key,
- 16, pdc->mach_pw,
- pdc->mach_acct,
- pdc->remote_machine,
- pdc->domain);
-
- tdb_sc = open_schannel_session_store(mem_ctx);
- if (!tdb_sc) {
- TALLOC_FREE(keystr);
- TALLOC_FREE(value.dptr);
- return False;
- }
-
- ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
-
- DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
- keystr ));
-
- tdb_close(tdb_sc);
- TALLOC_FREE(keystr);
- TALLOC_FREE(value.dptr);
- return ret;
-}
-
-/******************************************************************************
- Restore the schannel state on a client reconnect.
- Note we must be root here.
-*******************************************************************************/
-
-bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
- const char *remote_machine,
- struct dcinfo **ppdc)
-{
- TDB_CONTEXT *tdb_sc = NULL;
- TDB_DATA value;
- unsigned char *pseed_chal = NULL;
- unsigned char *pclnt_chal = NULL;
- unsigned char *psrv_chal = NULL;
- unsigned char *psess_key = NULL;
- unsigned char *pmach_pw = NULL;
- uint32 l1, l2, l3, l4, l5;
- int ret;
- struct dcinfo *pdc = NULL;
- char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
- remote_machine);
-
- *ppdc = NULL;
-
- if (!keystr) {
- return False;
- }
-
- strupper_m(keystr);
-
- tdb_sc = open_schannel_session_store(mem_ctx);
- if (!tdb_sc) {
- TALLOC_FREE(keystr);
- return False;
- }
-
- value = tdb_fetch_bystring(tdb_sc, keystr);
- if (!value.dptr) {
- DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
- keystr ));
- tdb_close(tdb_sc);
- return False;
- }
-
- pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
-
- /* Retrieve the record. */
- ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
- &pdc->sequence,
- &l1, &pseed_chal,
- &l2, &pclnt_chal,
- &l3, &psrv_chal,
- &l4, &psess_key,
- &l5, &pmach_pw,
- &pdc->mach_acct,
- &pdc->remote_machine,
- &pdc->domain);
-
- if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
- /* Bad record - delete it. */
- tdb_delete_bystring(tdb_sc, keystr);
- tdb_close(tdb_sc);
- TALLOC_FREE(keystr);
- TALLOC_FREE(pdc);
- SAFE_FREE(pseed_chal);
- SAFE_FREE(pclnt_chal);
- SAFE_FREE(psrv_chal);
- SAFE_FREE(psess_key);
- SAFE_FREE(pmach_pw);
- SAFE_FREE(value.dptr);
- return False;
- }
-
- tdb_close(tdb_sc);
-
- memcpy(pdc->seed_chal.data, pseed_chal, 8);
- memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
- memcpy(pdc->srv_chal.data, psrv_chal, 8);
- memcpy(pdc->sess_key, psess_key, 16);
- memcpy(pdc->mach_pw, pmach_pw, 16);
-
- /* We know these are true so didn't bother to store them. */
- pdc->challenge_sent = True;
- pdc->authenticated = True;
-
- DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
- keystr ));
-
- SAFE_FREE(pseed_chal);
- SAFE_FREE(pclnt_chal);
- SAFE_FREE(psrv_chal);
- SAFE_FREE(psess_key);
- SAFE_FREE(pmach_pw);
-
- TALLOC_FREE(keystr);
- SAFE_FREE(value.dptr);
-
- *ppdc = pdc;
-
- return True;
-}
-
bool secrets_store_generic(const char *owner, const char *key, const char *secret)
{
char *tdbkey = NULL;