mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s3: Fix auth_netlogond to cope with netlogon_creds_CredentialState
Autobuild-User: Volker Lendecke <vlendec@samba.org> Autobuild-Date: Sun Feb 6 17:30:48 CET 2011 on sn-devel-104
This commit is contained in:
parent
47d07df37f
commit
d515c6cd5c
@ -20,6 +20,7 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "../libcli/auth/libcli_auth.h"
|
#include "../libcli/auth/libcli_auth.h"
|
||||||
#include "../librpc/gen_ndr/ndr_netlogon.h"
|
#include "../librpc/gen_ndr/ndr_netlogon.h"
|
||||||
|
#include "librpc/gen_ndr/ndr_schannel.h"
|
||||||
#include "rpc_client/cli_netlogon.h"
|
#include "rpc_client/cli_netlogon.h"
|
||||||
#include "secrets.h"
|
#include "secrets.h"
|
||||||
#include "tldap.h"
|
#include "tldap.h"
|
||||||
@ -28,10 +29,65 @@
|
|||||||
#undef DBGC_CLASS
|
#undef DBGC_CLASS
|
||||||
#define DBGC_CLASS DBGC_AUTH
|
#define DBGC_CLASS DBGC_AUTH
|
||||||
|
|
||||||
|
static bool secrets_store_local_schannel_creds(
|
||||||
|
const struct netlogon_creds_CredentialState *creds)
|
||||||
|
{
|
||||||
|
DATA_BLOB blob;
|
||||||
|
enum ndr_err_code ndr_err;
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
ndr_err = ndr_push_struct_blob(
|
||||||
|
&blob, talloc_tos(), creds,
|
||||||
|
(ndr_push_flags_fn_t)ndr_push_netlogon_creds_CredentialState);
|
||||||
|
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
|
DEBUG(10, ("ndr_push_netlogon_creds_CredentialState failed: "
|
||||||
|
"%s\n", ndr_errstr(ndr_err)));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ret = secrets_store(SECRETS_LOCAL_SCHANNEL_KEY,
|
||||||
|
blob.data, blob.length);
|
||||||
|
data_blob_free(&blob);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct netlogon_creds_CredentialState *
|
||||||
|
secrets_fetch_local_schannel_creds(TALLOC_CTX *mem_ctx)
|
||||||
|
{
|
||||||
|
struct netlogon_creds_CredentialState *creds;
|
||||||
|
enum ndr_err_code ndr_err;
|
||||||
|
DATA_BLOB blob;
|
||||||
|
|
||||||
|
blob.data = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY,
|
||||||
|
&blob.length);
|
||||||
|
if (blob.data == NULL) {
|
||||||
|
DEBUG(10, ("secrets_fetch failed\n"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
creds = talloc(mem_ctx, struct netlogon_creds_CredentialState);
|
||||||
|
if (creds == NULL) {
|
||||||
|
DEBUG(10, ("talloc failed\n"));
|
||||||
|
SAFE_FREE(blob.data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ndr_err = ndr_pull_struct_blob(
|
||||||
|
&blob, creds, creds,
|
||||||
|
(ndr_pull_flags_fn_t)ndr_pull_netlogon_creds_CredentialState);
|
||||||
|
SAFE_FREE(blob.data);
|
||||||
|
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
|
DEBUG(10, ("ndr_pull_netlogon_creds_CredentialState failed: "
|
||||||
|
"%s\n", ndr_errstr(ndr_err)));
|
||||||
|
TALLOC_FREE(creds);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return creds;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx,
|
static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx,
|
||||||
const struct auth_context *auth_context,
|
const struct auth_context *auth_context,
|
||||||
const char *ncalrpc_sockname,
|
const char *ncalrpc_sockname,
|
||||||
uint8_t schannel_key[16],
|
struct netlogon_creds_CredentialState *creds,
|
||||||
const struct auth_usersupplied_info *user_info,
|
const struct auth_usersupplied_info *user_info,
|
||||||
struct netr_SamInfo3 **pinfo3,
|
struct netr_SamInfo3 **pinfo3,
|
||||||
NTSTATUS *schannel_bind_result)
|
NTSTATUS *schannel_bind_result)
|
||||||
@ -51,17 +107,7 @@ static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
p->dc = creds;
|
||||||
* We have to fake a struct dcinfo, so that
|
|
||||||
* rpccli_netlogon_sam_network_logon_ex can decrypt the session keys.
|
|
||||||
*/
|
|
||||||
|
|
||||||
p->dc = netlogon_creds_client_init_session_key(p, schannel_key);
|
|
||||||
if (p->dc == NULL) {
|
|
||||||
DEBUG(0, ("talloc failed\n"));
|
|
||||||
TALLOC_FREE(p);
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = rpccli_schannel_bind_data(p, lp_workgroup(),
|
status = rpccli_schannel_bind_data(p, lp_workgroup(),
|
||||||
DCERPC_AUTH_LEVEL_PRIVACY,
|
DCERPC_AUTH_LEVEL_PRIVACY,
|
||||||
@ -242,7 +288,7 @@ static NTSTATUS check_netlogond_security(const struct auth_context *auth_context
|
|||||||
struct pipe_auth_data *auth = NULL;
|
struct pipe_auth_data *auth = NULL;
|
||||||
uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
|
uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
|
||||||
uint8_t machine_password[16];
|
uint8_t machine_password[16];
|
||||||
uint8_t schannel_key[16];
|
struct netlogon_creds_CredentialState *creds;
|
||||||
NTSTATUS schannel_bind_result, status;
|
NTSTATUS schannel_bind_result, status;
|
||||||
struct named_mutex *mutex = NULL;
|
struct named_mutex *mutex = NULL;
|
||||||
const char *ncalrpcsock;
|
const char *ncalrpcsock;
|
||||||
@ -262,12 +308,13 @@ static NTSTATUS check_netlogond_security(const struct auth_context *auth_context
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!secrets_fetch_local_schannel_key(schannel_key)) {
|
creds = secrets_fetch_local_schannel_creds(talloc_tos());
|
||||||
|
if (creds == NULL) {
|
||||||
goto new_key;
|
goto new_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock,
|
status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock,
|
||||||
schannel_key, user_info, &info3,
|
creds, user_info, &info3,
|
||||||
&schannel_bind_result);
|
&schannel_bind_result);
|
||||||
|
|
||||||
DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status)));
|
DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status)));
|
||||||
@ -322,6 +369,9 @@ static NTSTATUS check_netlogond_security(const struct auth_context *auth_context
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG(10, ("machinepw "));
|
||||||
|
dump_data(10, machine_password, 16);
|
||||||
|
|
||||||
status = rpccli_netlogon_setup_creds(
|
status = rpccli_netlogon_setup_creds(
|
||||||
p, global_myname(), lp_workgroup(), global_myname(),
|
p, global_myname(), lp_workgroup(), global_myname(),
|
||||||
global_myname(), machine_password, SEC_CHAN_BDC, &neg_flags);
|
global_myname(), machine_password, SEC_CHAN_BDC, &neg_flags);
|
||||||
@ -332,10 +382,7 @@ static NTSTATUS check_netlogond_security(const struct auth_context *auth_context
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(schannel_key, p->dc->session_key, 16);
|
secrets_store_local_schannel_creds(p->dc);
|
||||||
secrets_store_local_schannel_key(schannel_key);
|
|
||||||
|
|
||||||
TALLOC_FREE(p);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retry the authentication with the mutex held. This way nobody else
|
* Retry the authentication with the mutex held. This way nobody else
|
||||||
@ -343,9 +390,11 @@ static NTSTATUS check_netlogond_security(const struct auth_context *auth_context
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock,
|
status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock,
|
||||||
schannel_key, user_info, &info3,
|
creds, user_info, &info3,
|
||||||
&schannel_bind_result);
|
&schannel_bind_result);
|
||||||
|
|
||||||
|
TALLOC_FREE(p);
|
||||||
|
|
||||||
DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status)));
|
DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status)));
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
@ -123,7 +123,5 @@ void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
|
|||||||
bool secrets_store_generic(const char *owner, const char *key, const char *secret);
|
bool secrets_store_generic(const char *owner, const char *key, const char *secret);
|
||||||
char *secrets_fetch_generic(const char *owner, const char *key);
|
char *secrets_fetch_generic(const char *owner, const char *key);
|
||||||
bool secrets_delete_generic(const char *owner, const char *key);
|
bool secrets_delete_generic(const char *owner, const char *key);
|
||||||
bool secrets_store_local_schannel_key(uint8_t schannel_key[16]);
|
|
||||||
bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16]);
|
|
||||||
|
|
||||||
#endif /* _SECRETS_H */
|
#endif /* _SECRETS_H */
|
||||||
|
@ -169,31 +169,6 @@ bool secrets_delete(const char *key)
|
|||||||
return NT_STATUS_IS_OK(status);
|
return NT_STATUS_IS_OK(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 a trusted domain password
|
* Form a key for fetching a trusted domain password
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user