diff options
Diffstat (limited to 'source4/rpc_server/netlogon')
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 140 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/schannel_state.c | 13 |
2 files changed, 96 insertions, 57 deletions
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 422aa626ed..167c4e8ceb 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -317,12 +317,17 @@ static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TAL } -static BOOL netr_creds_server_step_check(struct server_pipe_state *pipe_state, - struct netr_Authenticator *received_authenticator, - struct netr_Authenticator *return_authenticator) +static NTSTATUS netr_creds_server_step_check(struct server_pipe_state *pipe_state, + struct netr_Authenticator *received_authenticator, + struct netr_Authenticator *return_authenticator) { + if (!pipe_state) { + DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); + return NT_STATUS_ACCESS_DENIED; + } + if (!pipe_state->authenticated) { - return False; + return NT_STATUS_ACCESS_DENIED; } return creds_server_step_check(pipe_state->creds, received_authenticator, @@ -351,13 +356,9 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO const char **domain_attrs = attrs; ZERO_STRUCT(mod); - if (!pipe_state) { - DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); - return NT_STATUS_ACCESS_DENIED; - } - - if (!netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator)) { - return NT_STATUS_ACCESS_DENIED; + nt_status = netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator); + if (NT_STATUS_IS_OK(nt_status)) { + return nt_status; } sam_ctx = samdb_connect(mem_ctx); @@ -461,9 +462,10 @@ static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX /* netr_LogonSamLogonWithFlags + This version of the function allows other wrappers to say 'do not check the credentials' */ -static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct netr_LogonSamLogonWithFlags *r) +static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct netr_LogonSamLogonEx *r) { struct server_pipe_state *pipe_state = dce_call->conn->private; @@ -478,30 +480,21 @@ static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, struct netr_SamInfo3 *sam3; struct netr_SamInfo6 *sam6; - if (!pipe_state) { - DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); - return NT_STATUS_ACCESS_DENIED; - } - - r->out.return_authenticator = talloc_p(mem_ctx, struct netr_Authenticator); - if (!r->out.return_authenticator) { - return NT_STATUS_NO_MEMORY; - } - - if (!netr_creds_server_step_check(pipe_state, r->in.credential, r->out.return_authenticator)) { - return NT_STATUS_ACCESS_DENIED; - } - switch (r->in.logon_level) { case 1: case 3: case 5: - creds_arcfour_crypt(pipe_state->creds, - r->in.logon.password->lmpassword.hash, - sizeof(r->in.logon.password->lmpassword.hash)); - creds_arcfour_crypt(pipe_state->creds, - r->in.logon.password->ntpassword.hash, - sizeof(r->in.logon.password->ntpassword.hash)); + if (pipe_state->creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + creds_arcfour_crypt(pipe_state->creds, + r->in.logon.password->lmpassword.hash, + sizeof(r->in.logon.password->lmpassword.hash)); + creds_arcfour_crypt(pipe_state->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); + } nt_status = make_auth_context_subsystem(pipe_state, &auth_context); if (!NT_STATUS_IS_OK(nt_status)) { @@ -600,9 +593,13 @@ static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, if ((r->in.validation_level != 6) && memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) { - creds_arcfour_crypt(pipe_state->creds, - sam->key.key, - sizeof(sam->key.key)); + + /* 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, + sam->key.key, + sizeof(sam->key.key)); + } } if (server_info->lm_session_key.length == sizeof(sam->LMSessKey.key)) { @@ -617,9 +614,14 @@ static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, if ((r->in.validation_level != 6) && memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) { - creds_arcfour_crypt(pipe_state->creds, - sam->LMSessKey.key, - sizeof(sam->LMSessKey.key)); + if (pipe_state->creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + creds_arcfour_crypt(pipe_state->creds, + sam->LMSessKey.key, + sizeof(sam->LMSessKey.key)); + } else { + creds_des_encrypt_LMKey(pipe_state->creds, + &sam->LMSessKey); + } } switch (r->in.validation_level) { @@ -657,6 +659,45 @@ static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, } /* + netr_LogonSamLogonWithFlags + +*/ +static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct netr_LogonSamLogonWithFlags *r) +{ + NTSTATUS nt_status; + struct netr_LogonSamLogonEx r2; + + struct server_pipe_state *pipe_state = dce_call->conn->private; + + r->out.return_authenticator = talloc_p(mem_ctx, struct netr_Authenticator); + if (!r->out.return_authenticator) { + return NT_STATUS_NO_MEMORY; + } + + nt_status = netr_creds_server_step_check(pipe_state, r->in.credential, r->out.return_authenticator); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + ZERO_STRUCT(r2); + + r2.in.server_name = r->in.server_name; + r2.in.workstation = r->in.workstation; + r2.in.logon_level = r->in.logon_level; + r2.in.logon = r->in.logon; + r2.in.validation_level = r->in.validation_level; + r2.in.flags = r->in.flags; + + nt_status = netr_LogonSamLogonEx(dce_call, mem_ctx, &r2); + + r->out.validation = r2.out.validation; + r->out.authoritative = r2.out.authoritative; + + return nt_status; +} + +/* netr_LogonSamLogon */ static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, @@ -940,13 +981,10 @@ static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALL int ret1, ret2, i; NTSTATUS status; - if (!pipe_state) { - return NT_STATUS_ACCESS_DENIED; - } - - if (!netr_creds_server_step_check(pipe_state, - r->in.credential, r->out.credential)) { - return NT_STATUS_ACCESS_DENIED; + status = netr_creds_server_step_check(pipe_state, + r->in.credential, r->out.credential); + if (!NT_STATUS_IS_OK(status)) { + return status; } sam_ctx = samdb_connect(mem_ctx); @@ -1134,16 +1172,6 @@ static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TAL /* - netr_LogonSamLogonEx -*/ -static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct netr_LogonSamLogonEx *r) -{ - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); -} - - -/* netr_DsrEnumerateDomainTrusts */ static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, diff --git a/source4/rpc_server/netlogon/schannel_state.c b/source4/rpc_server/netlogon/schannel_state.c index 564564e8c2..7dc60a1617 100644 --- a/source4/rpc_server/netlogon/schannel_state.c +++ b/source4/rpc_server/netlogon/schannel_state.c @@ -61,7 +61,8 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, struct ldb_wrap *ldb; struct ldb_message *msg; struct ldb_val val, seed; - char *s = NULL; + char *s; + char *f; time_t expiry = time(NULL) + SCHANNEL_CREDENTIALS_EXPIRY; int ret; @@ -77,6 +78,13 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } + f = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->negotiate_flags); + + if (f == NULL) { + talloc_free(ldb); + return NT_STATUS_NO_MEMORY; + } + msg = ldb_msg_new(mem_ctx); if (msg == NULL) { talloc_free(ldb); @@ -99,6 +107,7 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, ldb_msg_add_value(ldb->ldb, msg, "sessionKey", &val); 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_delete(ldb->ldb, msg->dn); @@ -180,6 +189,8 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, memcpy((*creds)->seed.data, val->data, 8); + (*creds)->negotiate_flags = ldb_msg_find_int(res[0], "negotiateFlags", 0); + talloc_free(ldb); return NT_STATUS_OK; |