summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/auth/credentials.c8
-rw-r--r--source4/libcli/auth/credentials.h3
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c62
-rw-r--r--source4/rpc_server/netlogon/schannel_state.c22
4 files changed, 46 insertions, 49 deletions
diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c
index 8cae71180c..18ce6fec1b 100644
--- a/source4/libcli/auth/credentials.c
+++ b/source4/libcli/auth/credentials.c
@@ -292,13 +292,17 @@ BOOL creds_server_check(const struct creds_CredentialState *creds,
}
NTSTATUS creds_server_step_check(struct creds_CredentialState *creds,
- struct netr_Authenticator *received_authenticator,
- struct netr_Authenticator *return_authenticator)
+ struct netr_Authenticator *received_authenticator,
+ struct netr_Authenticator *return_authenticator)
{
if (!received_authenticator || !return_authenticator) {
return NT_STATUS_INVALID_PARAMETER;
}
+ if (!creds) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
/* TODO: this may allow the a replay attack on a non-signed
connection. Should we check that this is increasing? */
creds->sequence = received_authenticator->timestamp;
diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h
index 30114fe7fa..01206bc282 100644
--- a/source4/libcli/auth/credentials.h
+++ b/source4/libcli/auth/credentials.h
@@ -27,6 +27,9 @@ struct creds_CredentialState {
struct netr_Credential seed;
struct netr_Credential client;
struct netr_Credential server;
+ uint16_t secure_channel_type;
+ char *computer_name;
+ char *account_name;
};
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index afb066f4ee..ab67a2595e 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -32,11 +32,6 @@
struct server_pipe_state {
struct netr_Credential client_challenge;
struct netr_Credential server_challenge;
- BOOL authenticated;
- char *account_name;
- char *computer_name; /* for logging only */
- uint32_t acct_flags;
- uint16_t sec_chan_type;
struct creds_CredentialState *creds;
};
@@ -55,7 +50,6 @@ static NTSTATUS netlogon_schannel_setup(struct dcesrv_call_state *dce_call)
return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(state);
- state->authenticated = True;
if (dce_call->conn->auth_state.session_info == NULL) {
talloc_free(state);
@@ -102,16 +96,7 @@ static NTSTATUS netlogon_bind(struct dcesrv_call_state *dce_call, const struct d
return NT_STATUS_OK;
}
-/* this function is called when the client disconnects the endpoint */
-static void netlogon_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *di)
-{
- struct server_pipe_state *pipe_state = context->private;
- talloc_free(pipe_state);
- context->private = NULL;
-}
-
#define DCESRV_INTERFACE_NETLOGON_BIND netlogon_bind
-#define DCESRV_INTERFACE_NETLOGON_UNBIND netlogon_unbind
static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct netr_ServerReqChallenge *r)
@@ -132,10 +117,7 @@ static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALL
return NT_STATUS_NO_MEMORY;
}
- pipe_state->authenticated = False;
pipe_state->creds = NULL;
- pipe_state->account_name = NULL;
- pipe_state->computer_name = NULL;
pipe_state->client_challenge = *r->in.credentials;
@@ -220,8 +202,6 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL
return NT_STATUS_ACCESS_DENIED;
}
- pipe_state->acct_flags = acct_flags;
- pipe_state->sec_chan_type = r->in.secure_channel_type;
*r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], "objectSid", 0);
@@ -230,11 +210,12 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL
return NT_STATUS_ACCESS_DENIED;
}
+ if (pipe_state->creds) {
+ talloc_free(pipe_state->creds);
+ }
+ pipe_state->creds = talloc_p(pipe_state, struct creds_CredentialState);
if (!pipe_state->creds) {
- pipe_state->creds = talloc_p(pipe_state, struct creds_CredentialState);
- if (!pipe_state->creds) {
- return NT_STATUS_NO_MEMORY;
- }
+ return NT_STATUS_NO_MEMORY;
}
creds_server_init(pipe_state->creds, &pipe_state->client_challenge,
@@ -243,27 +224,19 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL
*r->in.negotiate_flags);
if (!creds_server_check(pipe_state->creds, r->in.credentials)) {
+ talloc_free(pipe_state->creds);
+ pipe_state->creds = NULL;
return NT_STATUS_ACCESS_DENIED;
}
- pipe_state->authenticated = True;
-
- if (pipe_state->account_name) {
- /* We don't want a memory leak on this long-lived talloc context */
- talloc_free(pipe_state->account_name);
- }
-
- pipe_state->account_name = talloc_strdup(pipe_state, r->in.account_name);
+ pipe_state->creds->account_name = talloc_reference(pipe_state->creds, r->in.account_name);
- if (pipe_state->computer_name) {
- /* We don't want a memory leak on this long-lived talloc context */
- talloc_free(pipe_state->computer_name);
- }
+ pipe_state->creds->computer_name = talloc_reference(pipe_state->creds, r->in.computer_name);
- pipe_state->computer_name = talloc_strdup(pipe_state, r->in.computer_name);
+ pipe_state->creds->secure_channel_type = r->in.secure_channel_type;
/* remember this session key state */
- nt_status = schannel_store_session_key(mem_ctx, pipe_state->computer_name, pipe_state->creds);
+ nt_status = schannel_store_session_key(mem_ctx, pipe_state->creds);
return nt_status;
}
@@ -323,9 +296,6 @@ static NTSTATUS netr_creds_server_step_check(struct server_pipe_state *pipe_stat
return NT_STATUS_ACCESS_DENIED;
}
- if (!pipe_state->authenticated) {
- return NT_STATUS_ACCESS_DENIED;
- }
return creds_server_step_check(pipe_state->creds,
received_authenticator,
return_authenticator);
@@ -365,17 +335,17 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO
/* pull the user attributes */
num_records = samdb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
"(&(sAMAccountName=%s)(objectclass=user))",
- pipe_state->account_name);
+ pipe_state->creds->account_name);
if (num_records == 0) {
DEBUG(3,("Couldn't find user [%s] in samdb.\n",
- pipe_state->account_name));
+ pipe_state->creds->account_name));
return NT_STATUS_NO_SUCH_USER;
}
if (num_records > 1) {
DEBUG(0,("Found %d records matching user [%s]\n", num_records,
- pipe_state->account_name));
+ pipe_state->creds->account_name));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -643,6 +613,9 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_
r->out.authoritative = 1;
+ /* TODO: Describe and deal with these flags */
+ r->out.flags = 0;
+
return NT_STATUS_OK;
}
@@ -681,6 +654,7 @@ static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call,
r->out.validation = r2.out.validation;
r->out.authoritative = r2.out.authoritative;
+ r->out.flags = r2.out.flags;
return nt_status;
}
diff --git a/source4/rpc_server/netlogon/schannel_state.c b/source4/rpc_server/netlogon/schannel_state.c
index 7dc60a1617..56f7152c14 100644
--- a/source4/rpc_server/netlogon/schannel_state.c
+++ b/source4/rpc_server/netlogon/schannel_state.c
@@ -55,7 +55,6 @@ static struct ldb_wrap *schannel_db_connect(TALLOC_CTX *mem_ctx)
use a simple ldb structure
*/
NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
- const char *computer_name,
struct creds_CredentialState *creds)
{
struct ldb_wrap *ldb;
@@ -63,6 +62,7 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
struct ldb_val val, seed;
char *s;
char *f;
+ char *sct;
time_t expiry = time(NULL) + SCHANNEL_CREDENTIALS_EXPIRY;
int ret;
@@ -85,13 +85,20 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
+ sct = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->secure_channel_type);
+
+ if (sct == NULL) {
+ talloc_free(ldb);
+ return NT_STATUS_NO_MEMORY;
+ }
+
msg = ldb_msg_new(mem_ctx);
if (msg == NULL) {
talloc_free(ldb);
return NT_STATUS_NO_MEMORY;
}
- msg->dn = talloc_strdup(msg, computer_name);
+ msg->dn = talloc_asprintf(msg, "computerName=%s", creds->computer_name);
if (msg->dn == NULL) {
talloc_free(ldb);
talloc_free(msg);
@@ -108,6 +115,9 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
ldb_msg_add_value(ldb->ldb, msg, "seed", &seed);
ldb_msg_add_string(ldb->ldb, msg, "expiry", s);
ldb_msg_add_string(ldb->ldb, msg, "negotiateFlags", f);
+ ldb_msg_add_string(ldb->ldb, msg, "secureChannelType", sct);
+ ldb_msg_add_string(ldb->ldb, msg, "accountName", creds->account_name);
+ ldb_msg_add_string(ldb->ldb, msg, "computerName", creds->computer_name);
ldb_delete(ldb->ldb, msg->dn);
@@ -154,7 +164,7 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- expr = talloc_asprintf(mem_ctx, "(dn=%s)", computer_name);
+ expr = talloc_asprintf(mem_ctx, "(dn=computerName=%s)", computer_name);
if (expr == NULL) {
talloc_free(ldb);
return NT_STATUS_NO_MEMORY;
@@ -191,6 +201,12 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
(*creds)->negotiate_flags = ldb_msg_find_int(res[0], "negotiateFlags", 0);
+ (*creds)->secure_channel_type = ldb_msg_find_int(res[0], "secureChannelType", 0);
+
+ (*creds)->account_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "accountName", NULL));
+
+ (*creds)->computer_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "computerName", NULL));
+
talloc_free(ldb);
return NT_STATUS_OK;