1
0
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:
Volker Lendecke 2011-02-06 15:50:04 +01:00 committed by Volker Lendecke
parent 47d07df37f
commit d515c6cd5c
3 changed files with 69 additions and 47 deletions

View File

@ -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)) {

View File

@ -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 */

View File

@ -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
* *