return dcesrv_interface_bind_reject_connect(dce_call, iface);
}
+static void dcesrv_netr_generic_delay_done(struct tevent_req *subreq);
+
+static NTSTATUS dcesrv_netr_generic_delay(struct dcesrv_call_state *dce_call,
+ const char *name)
+{
+ long to_min = lpcfg_parm_long(dce_call->conn->dce_ctx->lp_ctx, NULL,
+ "netlogon delay min", name, 0);
+ long to_max = lpcfg_parm_long(dce_call->conn->dce_ctx->lp_ctx, NULL,
+ "netlogon delay max", name, 0);
+ long to_range = 0;
+ long to_random = 0;
+ long delay = 0;
+ struct timeval to;
+ struct tevent_req *subreq;
+
+ if (to_max > to_min) {
+ to_range = (to_max - to_min) + 1;
+ to_random = generate_random() % to_range;
+ }
+
+ delay = to_min + to_random;
+
+ if (delay == 0) {
+ return NT_STATUS_OK;
+ }
+
+ to = timeval_current_ofs(delay, 0);
+
+ /* forward the call */
+ subreq = tevent_wakeup_send(dce_call, dce_call->event_ctx, to);
+ NT_STATUS_HAVE_NO_MEMORY(subreq);
+
+ dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
+
+ /* setup the callback */
+ tevent_req_set_callback(subreq,
+ dcesrv_netr_generic_delay_done,
+ dce_call);
+
+ return NT_STATUS_OK;
+}
+
+static void dcesrv_netr_generic_delay_done(struct tevent_req *subreq)
+{
+ struct dcesrv_call_state *dce_call =
+ tevent_req_callback_data(subreq,
+ struct dcesrv_call_state);
+ NTSTATUS status;
+
+ tevent_wakeup_recv(subreq);
+ TALLOC_FREE(subreq);
+
+ status = dcesrv_reply(dce_call);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
+ }
+}
+
struct netlogon_server_pipe_state {
struct netr_Credential client_challenge;
struct netr_Credential server_challenge;
NULL, r->in.new_password,
NULL, oldNtHash, /* Password change */
NULL, NULL);
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
+ nt_status = dcesrv_netr_generic_delay(dce_call, "password set");
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
return nt_status;
}
NULL, NULL,
oldLmHash, oldNtHash, /* Password change */
NULL, NULL);
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
+ nt_status = dcesrv_netr_generic_delay(dce_call, "password set2");
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
return nt_status;
}
{
struct netr_LogonSamLogonEx *r = &state->r;
NTSTATUS status;
+ const char *name = NULL;
if (NT_STATUS_IS_OK(r->out.result)) {
netlogon_creds_encrypt_samlogon_validation(state->creds,
if (state->_r.lslex != NULL) {
struct netr_LogonSamLogonEx *_r = state->_r.lslex;
_r->out.result = r->out.result;
+ name = "logon ex";
} else if (state->_r.lslwf != NULL) {
struct netr_LogonSamLogonWithFlags *_r = state->_r.lslwf;
_r->out.result = r->out.result;
+ name = "logon with flags";
} else if (state->_r.lsl != NULL) {
struct netr_LogonSamLogon *_r = state->_r.lsl;
_r->out.result = r->out.result;
+ name = "logon";
+ }
+
+ status = dcesrv_netr_generic_delay(dce_call, logon);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("dcesrv_netr_generic_delay(%s) failed - %s\n",
+ name, nt_errstr(status));
+ } else {
+ return;
}
status = dcesrv_reply(state->dce_call);
return nt_status;
}
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
+ nt_status = dcesrv_netr_generic_delay(dce_call, "logon ex");
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
return nt_status;
}
return nt_status;
}
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
+ nt_status = dcesrv_netr_generic_delay(dce_call, "logon with flags");
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
return nt_status;
}
return nt_status;
}
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
+ nt_status = dcesrv_netr_generic_delay(dce_call, "logon");
+ NT_STATUS_NOT_OK_RETURN(nt_status);
+
return nt_status;
}
r->out.capabilities->server_capabilities = creds->negotiate_flags;
+ status = dcesrv_netr_generic_delay(dce_call, "capabilities");
+ NT_STATUS_NOT_OK_RETURN(status);
+
return NT_STATUS_OK;
}