summaryrefslogtreecommitdiff
path: root/source4/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source4/rpc_server')
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c221
1 files changed, 139 insertions, 82 deletions
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index f3ef74641d..03d325020f 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -128,6 +128,7 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL
struct netr_ServerAuthenticate3 *r)
{
struct server_pipe_state *pipe_state = dce_call->context->private;
+ struct creds_CredentialState *creds;
void *sam_ctx;
struct samr_Password *mach_pwd;
uint16_t acct_flags;
@@ -203,37 +204,39 @@ 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(pipe_state, struct creds_CredentialState);
- if (!pipe_state->creds) {
+ creds = talloc(mem_ctx, struct creds_CredentialState);
+ if (!creds) {
return NT_STATUS_NO_MEMORY;
}
- creds_server_init(pipe_state->creds, &pipe_state->client_challenge,
+ creds_server_init(creds, &pipe_state->client_challenge,
&pipe_state->server_challenge, mach_pwd,
r->out.credentials,
*r->in.negotiate_flags);
- if (!creds_server_check(pipe_state->creds, r->in.credentials)) {
- talloc_free(pipe_state->creds);
- pipe_state->creds = NULL;
+ if (!creds_server_check(creds, r->in.credentials)) {
+ talloc_free(creds);
return NT_STATUS_ACCESS_DENIED;
}
- pipe_state->creds->account_name = talloc_steal(pipe_state->creds, r->in.account_name);
+ creds->account_name = talloc_steal(creds, r->in.account_name);
- pipe_state->creds->computer_name = talloc_steal(pipe_state->creds, r->in.computer_name);
+ creds->computer_name = talloc_steal(creds, r->in.computer_name);
+ creds->domain = talloc_strdup(creds, lp_workgroup());
- pipe_state->creds->secure_channel_type = r->in.secure_channel_type;
+ creds->secure_channel_type = r->in.secure_channel_type;
- pipe_state->creds->sid = samdb_result_dom_sid(pipe_state->creds, msgs[0], "objectSid");
+ creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
- pipe_state->creds->domain = talloc_strdup(pipe_state->creds, lp_workgroup());
/* remember this session key state */
- nt_status = schannel_store_session_key(mem_ctx, pipe_state->creds);
+ nt_status = schannel_store_session_key(mem_ctx, creds);
+
+ if (pipe_state->creds) {
+ talloc_free(pipe_state->creds);
+ }
+ talloc_steal(pipe_state, creds);
+ pipe_state->creds = creds;
return nt_status;
}
@@ -285,29 +288,76 @@ static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TAL
static NTSTATUS netr_creds_server_step_check(struct server_pipe_state *pipe_state,
+ TALLOC_CTX *mem_ctx,
struct netr_Authenticator *received_authenticator,
- struct netr_Authenticator *return_authenticator)
+ struct netr_Authenticator *return_authenticator,
+ struct creds_CredentialState **creds_out)
{
+ struct creds_CredentialState *creds;
+ NTSTATUS nt_status;
+ struct ldb_context *ldb;
+ int ret;
+
if (!pipe_state) {
DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
return NT_STATUS_ACCESS_DENIED;
}
- return creds_server_step_check(pipe_state->creds,
- received_authenticator,
- return_authenticator);
+ ldb = schannel_db_connect(mem_ctx);
+ if (!ldb) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ ret = ldb_transaction_start(ldb);
+ if (ret != 0) {
+ talloc_free(ldb);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ /* Because this is a shared structure (even across
+ * disconnects) we must update the database every time we
+ * update the structure */
+
+ nt_status = schannel_fetch_session_key_ldb(ldb, ldb, pipe_state->creds->computer_name,
+ pipe_state->creds->domain, &creds);
+ if (NT_STATUS_IS_OK(nt_status)) {
+ nt_status = creds_server_step_check(creds,
+ received_authenticator,
+ return_authenticator);
+ }
+ if (NT_STATUS_IS_OK(nt_status)) {
+ nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
+ }
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ ldb_transaction_commit(ldb);
+ if (creds_out) {
+ *creds_out = creds;
+ talloc_steal(mem_ctx, creds);
+ }
+ } else {
+ ldb_transaction_cancel(ldb);
+ }
+ talloc_free(ldb);
+ return nt_status;
}
+/*
+ Change the machine account password for the currently connected
+ client. Supplies only the NT#.
+*/
static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct netr_ServerPasswordSet *r)
{
struct server_pipe_state *pipe_state = dce_call->context->private;
-
+ struct creds_CredentialState *creds;
struct ldb_context *sam_ctx;
NTSTATUS nt_status;
- nt_status = netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator);
+ nt_status = netr_creds_server_step_check(pipe_state, mem_ctx,
+ &r->in.credential, &r->out.return_authenticator,
+ &creds);
NT_STATUS_NOT_OK_RETURN(nt_status);
sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
@@ -315,11 +365,11 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
- creds_des_decrypt(pipe_state->creds, &r->in.new_password);
+ creds_des_decrypt(creds, &r->in.new_password);
/* Using the sid for the account as the key, set the password */
nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
- pipe_state->creds->sid,
+ creds->sid,
NULL, /* Don't have plaintext */
NULL, &r->in.new_password,
False, /* This is not considered a password change */
@@ -328,6 +378,55 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO
return nt_status;
}
+/*
+ Change the machine account password for the currently connected
+ client. Supplies new plaintext.
+*/
+static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct netr_ServerPasswordSet2 *r)
+{
+ struct server_pipe_state *pipe_state = dce_call->context->private;
+ struct creds_CredentialState *creds;
+ struct ldb_context *sam_ctx;
+ NTSTATUS nt_status;
+ char new_pass[512];
+ uint32_t new_pass_len;
+ BOOL ret;
+
+ struct samr_CryptPassword password_buf;
+
+ nt_status = netr_creds_server_step_check(pipe_state, mem_ctx,
+ &r->in.credential, &r->out.return_authenticator,
+ &creds);
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
+ sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
+ if (sam_ctx == NULL) {
+ return NT_STATUS_INVALID_SYSTEM_SERVICE;
+ }
+
+ memcpy(password_buf.data, r->in.new_password.data, 512);
+ SIVAL(password_buf.data,512,r->in.new_password.length);
+ creds_arcfour_crypt(creds, password_buf.data, 516);
+
+ ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
+ &new_pass_len, STR_UNICODE);
+ if (!ret) {
+ DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* Using the sid for the account as the key, set the password */
+ nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
+ creds->sid,
+ new_pass, /* we have plaintext */
+ NULL, NULL,
+ False, /* This is not considered a password change */
+ False, /* don't restrict this password change (match w2k3) */
+ NULL, NULL);
+ return nt_status;
+}
+
/*
netr_LogonUasLogon
@@ -358,7 +457,7 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_
struct netr_LogonSamLogonEx *r)
{
struct server_pipe_state *pipe_state = dce_call->context->private;
-
+ struct creds_CredentialState *creds = pipe_state->creds;
struct auth_context *auth_context;
struct auth_usersupplied_info *user_info;
struct auth_serversupplied_info *server_info;
@@ -383,15 +482,15 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_
case 3:
case 5:
if (pipe_state->creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
- creds_arcfour_crypt(pipe_state->creds,
+ creds_arcfour_crypt(creds,
r->in.logon.password->lmpassword.hash,
sizeof(r->in.logon.password->lmpassword.hash));
- creds_arcfour_crypt(pipe_state->creds,
+ creds_arcfour_crypt(creds,
r->in.logon.password->ntpassword.hash,
sizeof(r->in.logon.password->ntpassword.hash));
} else {
- creds_des_decrypt(pipe_state->creds, &r->in.logon.password->lmpassword);
- creds_des_decrypt(pipe_state->creds, &r->in.logon.password->ntpassword);
+ creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
+ creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
}
/* TODO: we need to deny anonymous access here */
@@ -459,8 +558,8 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_
sizeof(sam->key.key)) != 0) {
/* This key is sent unencrypted without the ARCFOUR flag set */
- if (pipe_state->creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
- creds_arcfour_crypt(pipe_state->creds,
+ if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
+ creds_arcfour_crypt(creds,
sam->key.key,
sizeof(sam->key.key));
}
@@ -471,12 +570,12 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_
if ((r->in.validation_level != 6)
&& memcmp(sam->LMSessKey.key, zeros,
sizeof(sam->LMSessKey.key)) != 0) {
- if (pipe_state->creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
- creds_arcfour_crypt(pipe_state->creds,
+ if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
+ creds_arcfour_crypt(creds,
sam->LMSessKey.key,
sizeof(sam->LMSessKey.key));
} else {
- creds_des_encrypt_LMKey(pipe_state->creds,
+ creds_des_encrypt_LMKey(creds,
&sam->LMSessKey);
}
}
@@ -535,7 +634,9 @@ static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call,
return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
- nt_status = netr_creds_server_step_check(pipe_state, r->in.credential, return_authenticator);
+ nt_status = netr_creds_server_step_check(pipe_state, mem_ctx,
+ r->in.credential, return_authenticator,
+ NULL);
NT_STATUS_NOT_OK_RETURN(nt_status);
ZERO_STRUCT(r2);
@@ -844,8 +945,10 @@ static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALL
const char *local_domain;
- status = netr_creds_server_step_check(pipe_state,
- r->in.credential, r->out.return_authenticator);
+ status = netr_creds_server_step_check(pipe_state, mem_ctx,
+ r->in.credential,
+ r->out.return_authenticator,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -918,52 +1021,6 @@ static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALL
}
-/*
- netr_ServerPasswordSet2
-*/
-static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct netr_ServerPasswordSet2 *r)
-{
- struct server_pipe_state *pipe_state = dce_call->context->private;
-
- struct ldb_context *sam_ctx;
- NTSTATUS nt_status;
- char new_pass[512];
- uint32_t new_pass_len;
- BOOL ret;
-
- struct samr_CryptPassword password_buf;
-
- nt_status = netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator);
- NT_STATUS_NOT_OK_RETURN(nt_status);
-
- sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
- if (sam_ctx == NULL) {
- return NT_STATUS_INVALID_SYSTEM_SERVICE;
- }
-
- memcpy(password_buf.data, r->in.new_password.data, 512);
- SIVAL(password_buf.data,512,r->in.new_password.length);
- creds_arcfour_crypt(pipe_state->creds, password_buf.data, 516);
-
- ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
- &new_pass_len, STR_UNICODE);
- if (!ret) {
- DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- /* Using the sid for the account as the key, set the password */
- nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
- pipe_state->creds->sid,
- new_pass, /* we have plaintext */
- NULL, NULL,
- False, /* This is not considered a password change */
- False, /* don't restrict this password change (match w2k3) */
- NULL, NULL);
- return nt_status;
-}
-
/*
netr_NETRSERVERPASSWORDGET