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
*
* @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 (db_ctx) {
- dbwrap_change_int32_atomic(db_ctx, "INFO/random_seed",
- new_seed, 1);
+ dbwrap_trans_change_int32_atomic(db_ctx, "INFO/random_seed",
+ new_seed, 1);
}
}
* 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));
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
*
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;
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;
struct trusted_dom_pass pass;
ZERO_STRUCT(pass);
- if (!push_ucs2_allocate(&uni_dom_name, domain, &converted_size)) {
+ 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);
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_strupper_m(mem_ctx, "%s/%s",
- SECRETS_SCHANNEL_STATE,
- remote_machine);
- if (!keystr) {
- return False;
- }
-
- /* 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_strupper_m(mem_ctx, "%s/%s",
- SECRETS_SCHANNEL_STATE,
- remote_machine);
-
- *ppdc = NULL;
-
- if (!keystr) {
- return False;
- }
-
- 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;