summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2018-01-19 13:42:40 +0100
committerRalph Boehme <slow@samba.org>2018-02-21 14:19:18 +0100
commit9b6a0b1a63f2ebfbd578047401dfbe38606c8c44 (patch)
tree9cfce6ac0feec4e10ef2b20d042613f53644ceba /source4
parentab7988aa2fd1a43f576a4b73a6893c61c7ef1957 (diff)
downloadsamba-9b6a0b1a63f2ebfbd578047401dfbe38606c8c44.tar.gz
s4:rpc_server/lsa: prepare dcesrv_lsa_LookupNames* for async processing
Bug: https://bugzilla.samba.org/show_bug.cgi?id=13286 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
Diffstat (limited to 'source4')
-rw-r--r--source4/rpc_server/lsa/lsa_lookup.c392
1 files changed, 250 insertions, 142 deletions
diff --git a/source4/rpc_server/lsa/lsa_lookup.c b/source4/rpc_server/lsa/lsa_lookup.c
index 62d29d3173e..83043cbe17e 100644
--- a/source4/rpc_server/lsa/lsa_lookup.c
+++ b/source4/rpc_server/lsa/lsa_lookup.c
@@ -933,13 +933,32 @@ NTSTATUS dcesrv_lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
return status;
}
-static NTSTATUS dcesrv_lsa_LookupNames_common(struct dcesrv_call_state *dce_call,
- TALLOC_CTX *mem_ctx,
- struct lsa_policy_state *policy_state,
- struct lsa_LookupNames3 *r)
+struct dcesrv_lsa_LookupNames_base_state {
+ struct dcesrv_call_state *dce_call;
+
+ TALLOC_CTX *mem_ctx;
+
+ struct lsa_policy_state *policy_state;
+
+ struct lsa_LookupNames4 r;
+
+ struct {
+ struct lsa_LookupNames *l;
+ struct lsa_LookupNames2 *l2;
+ struct lsa_LookupNames3 *l3;
+ struct lsa_LookupNames4 *l4;
+ } _r;
+};
+
+
+static NTSTATUS dcesrv_lsa_LookupNames_base_call(struct dcesrv_lsa_LookupNames_base_state *state)
{
- struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
- struct lsa_RefDomainList *domains;
+ struct loadparm_context *lp_ctx = state->dce_call->conn->dce_ctx->lp_ctx;
+ struct dcesrv_call_state *dce_call = state->dce_call;
+ struct lsa_policy_state *policy_state = state->policy_state;
+ TALLOC_CTX *mem_ctx = state->mem_ctx;
+ struct lsa_LookupNames4 *r = &state->r;
+ struct lsa_RefDomainList *domains = NULL;
uint32_t i;
*r->out.domains = NULL;
@@ -1009,6 +1028,97 @@ static NTSTATUS dcesrv_lsa_LookupNames_common(struct dcesrv_call_state *dce_call
return NT_STATUS_OK;
}
+static void dcesrv_lsa_LookupNames_base_map(
+ struct dcesrv_lsa_LookupNames_base_state *state)
+{
+ if (state->_r.l4 != NULL) {
+ struct lsa_LookupNames4 *r = state->_r.l4;
+
+ r->out.result = state->r.out.result;
+ return;
+ }
+
+ if (state->_r.l3 != NULL) {
+ struct lsa_LookupNames3 *r = state->_r.l3;
+
+ r->out.result = state->r.out.result;
+ return;
+ }
+
+ if (state->_r.l2 != NULL) {
+ struct lsa_LookupNames2 *r = state->_r.l2;
+ uint32_t i;
+
+ r->out.result = state->r.out.result;
+
+ SMB_ASSERT(state->r.out.sids->count <= r->in.num_names);
+ for (i = 0; i < state->r.out.sids->count; i++) {
+ const struct lsa_TranslatedSid3 *s3 =
+ &state->r.out.sids->sids[i];
+ struct lsa_TranslatedSid2 *s2 =
+ &r->out.sids->sids[i];
+
+ s2->sid_type = s3->sid_type;
+ if (s3->sid_type == SID_NAME_DOMAIN) {
+ s2->rid = UINT32_MAX;
+ } else if (s3->flags & 0x00000004) {
+ s2->rid = UINT32_MAX;
+ } else if (s3->sid == NULL) {
+ /*
+ * MS-LSAT 3.1.4.7 - rid zero is considered
+ * equivalent to sid NULL - so we should return
+ * 0 rid for unmapped entries
+ */
+ s2->rid = 0;
+ } else {
+ s2->rid = 0;
+ dom_sid_split_rid(NULL, s3->sid,
+ NULL, &s2->rid);
+ }
+ s2->sid_index = s3->sid_index;
+ s2->unknown = s3->flags;
+ }
+ r->out.sids->count = state->r.out.sids->count;
+ return;
+ }
+
+ if (state->_r.l != NULL) {
+ struct lsa_LookupNames *r = state->_r.l;
+ uint32_t i;
+
+ r->out.result = state->r.out.result;
+
+ SMB_ASSERT(state->r.out.sids->count <= r->in.num_names);
+ for (i = 0; i < state->r.out.sids->count; i++) {
+ struct lsa_TranslatedSid3 *s3 =
+ &state->r.out.sids->sids[i];
+ struct lsa_TranslatedSid *s =
+ &r->out.sids->sids[i];
+
+ s->sid_type = s3->sid_type;
+ if (s3->sid_type == SID_NAME_DOMAIN) {
+ s->rid = UINT32_MAX;
+ } else if (s3->flags & 0x00000004) {
+ s->rid = UINT32_MAX;
+ } else if (s3->sid == NULL) {
+ /*
+ * MS-LSAT 3.1.4.7 - rid zero is considered
+ * equivalent to sid NULL - so we should return
+ * 0 rid for unmapped entries
+ */
+ s->rid = 0;
+ } else {
+ s->rid = 0;
+ dom_sid_split_rid(NULL, s3->sid,
+ NULL, &s->rid);
+ }
+ s->sid_index = s3->sid_index;
+ }
+ r->out.sids->count = state->r.out.sids->count;
+ return;
+ }
+}
+
/*
lsa_LookupNames3
*/
@@ -1018,8 +1128,9 @@ NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
{
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
- struct lsa_policy_state *policy_state;
- struct dcesrv_handle *policy_handle;
+ struct dcesrv_lsa_LookupNames_base_state *state = NULL;
+ struct dcesrv_handle *policy_handle = NULL;
+ NTSTATUS status;
if (transport != NCACN_NP && transport != NCALRPC) {
DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
@@ -1027,12 +1138,44 @@ NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
- policy_state = policy_handle->data;
+ *r->out.domains = NULL;
+ r->out.sids->count = 0;
+ r->out.sids->sids = NULL;
+ *r->out.count = 0;
+
+ state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
+ if (state == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ state->dce_call = dce_call;
+ state->mem_ctx = mem_ctx;
+
+ state->policy_state = policy_handle->data;
+
+ state->r.in.num_names = r->in.num_names;
+ state->r.in.names = r->in.names;
+ state->r.in.level = r->in.level;
+ state->r.in.lookup_options = r->in.lookup_options;
+ state->r.in.client_revision = r->in.client_revision;
+ state->r.in.sids = r->in.sids;
+ state->r.in.count = r->in.count;
+ state->r.out.domains = r->out.domains;
+ state->r.out.sids = r->out.sids;
+ state->r.out.count = r->out.count;
+
+ state->_r.l3 = r;
+
+ status = dcesrv_lsa_LookupNames_base_call(state);
- return dcesrv_lsa_LookupNames_common(dce_call,
- mem_ctx,
- policy_state,
- r);
+ if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
+ return status;
+ }
+
+ state->r.out.result = status;
+ dcesrv_lsa_LookupNames_base_map(state);
+ TALLOC_FREE(state);
+ return status;
}
/*
@@ -1047,8 +1190,7 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
const struct dcesrv_auth *auth = &dce_call->conn->auth_state;
- struct lsa_policy_state *policy_state;
- struct lsa_LookupNames3 q;
+ struct dcesrv_lsa_LookupNames_base_state *state = NULL;
NTSTATUS status;
if (transport != NCACN_IP_TCP) {
@@ -1069,39 +1211,43 @@ NTSTATUS dcesrv_lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX
r->out.sids->sids = NULL;
*r->out.count = 0;
- status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx,
+ state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
+ if (state == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ state->dce_call = dce_call;
+ state->mem_ctx = mem_ctx;
+
+ status = dcesrv_lsa_get_policy_state(state->dce_call, state,
0, /* we skip access checks */
- &policy_state);
+ &state->policy_state);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- ZERO_STRUCT(q);
-
- q.in.handle = NULL;
- q.in.num_names = r->in.num_names;
- q.in.names = r->in.names;
- q.in.level = r->in.level;
- q.in.sids = r->in.sids;
- q.in.count = r->in.count;
- q.in.lookup_options = r->in.lookup_options;
- q.in.client_revision = r->in.client_revision;
-
- q.out.count = r->out.count;
- q.out.sids = r->out.sids;
- q.out.domains = r->out.domains;
+ state->r.in.num_names = r->in.num_names;
+ state->r.in.names = r->in.names;
+ state->r.in.level = r->in.level;
+ state->r.in.lookup_options = r->in.lookup_options;
+ state->r.in.client_revision = r->in.client_revision;
+ state->r.in.sids = r->in.sids;
+ state->r.in.count = r->in.count;
+ state->r.out.domains = r->out.domains;
+ state->r.out.sids = r->out.sids;
+ state->r.out.count = r->out.count;
- status = dcesrv_lsa_LookupNames_common(dce_call,
- mem_ctx,
- policy_state,
- &q);
+ state->_r.l4 = r;
- talloc_free(policy_state);
+ status = dcesrv_lsa_LookupNames_base_call(state);
- r->out.count = q.out.count;
- r->out.sids = q.out.sids;
- r->out.domains = q.out.domains;
+ if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
+ return status;
+ }
+ state->r.out.result = status;
+ dcesrv_lsa_LookupNames_base_map(state);
+ TALLOC_FREE(state);
return status;
}
@@ -1114,11 +1260,9 @@ NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
{
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
- struct lsa_policy_state *policy_state = NULL;
+ struct dcesrv_lsa_LookupNames_base_state *state = NULL;
struct dcesrv_handle *policy_handle = NULL;
- struct lsa_LookupNames3 r2;
NTSTATUS status;
- uint32_t i;
if (transport != NCACN_NP && transport != NCALRPC) {
DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
@@ -1126,8 +1270,6 @@ NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
- policy_state = policy_handle->data;
-
*r->out.domains = NULL;
r->out.sids->count = 0;
r->out.sids->sids = NULL;
@@ -1140,17 +1282,19 @@ NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCT(r2);
-
- r2.in.handle = r->in.handle;
- r2.in.num_names = r->in.num_names;
- r2.in.names = r->in.names;
- r2.in.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
- if (r2.in.sids == NULL) {
+ state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
+ if (state == NULL) {
return NT_STATUS_NO_MEMORY;
}
- r2.in.level = r->in.level;
- r2.in.count = r->in.count;
+
+ state->dce_call = dce_call;
+ state->mem_ctx = mem_ctx;
+
+ state->policy_state = policy_handle->data;
+
+ state->r.in.num_names = r->in.num_names;
+ state->r.in.names = r->in.names;
+ state->r.in.level = r->in.level;
/*
* MS-LSAT 3.1.4.7:
*
@@ -1158,48 +1302,31 @@ NTSTATUS dcesrv_lsa_LookupNames2(struct dcesrv_call_state *dce_call,
* Message processing MUST happen as if LookupOptions is set to
* 0x00000000 and ClientRevision is set to 0x00000002.
*/
- r2.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
- r2.in.client_revision = LSA_CLIENT_REVISION_2;
- r2.out.count = r->out.count;
- r2.out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
- if (r2.out.sids == NULL) {
+ state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
+ state->r.in.client_revision = LSA_CLIENT_REVISION_2;
+ state->r.in.sids = talloc_zero(state, struct lsa_TransSidArray3);
+ if (state->r.in.sids == NULL) {
return NT_STATUS_NO_MEMORY;
}
- r2.out.domains = r->out.domains;
-
- status = dcesrv_lsa_LookupNames_common(dce_call,
- mem_ctx,
- policy_state,
- &r2);
-
- SMB_ASSERT(r2.out.sids->count <= r->in.num_names);
- for (i=0;i<r2.out.sids->count;i++) {
- struct lsa_TranslatedSid3 *s3 =
- &r2.out.sids->sids[i];
- struct lsa_TranslatedSid2 *s2 =
- &r->out.sids->sids[i];
-
- s2->sid_type = s3->sid_type;
- if (s3->sid_type == SID_NAME_DOMAIN) {
- s2->rid = UINT32_MAX;
- } else if (s3->flags & 0x00000004) {
- s2->rid = UINT32_MAX;
- } else if (s3->sid == NULL) {
- /*
- * MS-LSAT 3.1.4.7 - rid zero is considered
- * equivalent to sid NULL - so we should return
- * 0 rid for unmapped entries
- */
- s2->rid = 0;
- } else {
- s2->rid = 0;
- dom_sid_split_rid(NULL, s3->sid,
- NULL, &s2->rid);
- }
- s2->sid_index = s3->sid_index;
+ state->r.in.count = r->in.count;
+ state->r.out.domains = r->out.domains;
+ state->r.out.sids = talloc_zero(state, struct lsa_TransSidArray3);
+ if (state->r.out.sids == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ state->r.out.count = r->out.count;
+
+ state->_r.l2 = r;
+
+ status = dcesrv_lsa_LookupNames_base_call(state);
+
+ if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
+ return status;
}
- r->out.sids->count = r2.out.sids->count;
+ state->r.out.result = status;
+ dcesrv_lsa_LookupNames_base_map(state);
+ TALLOC_FREE(state);
return status;
}
@@ -1211,11 +1338,9 @@ NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *
{
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
- struct lsa_policy_state *policy_state = NULL;
+ struct dcesrv_lsa_LookupNames_base_state *state = NULL;
struct dcesrv_handle *policy_handle = NULL;
- struct lsa_LookupNames3 r2;
NTSTATUS status;
- uint32_t i;
if (transport != NCACN_NP && transport != NCALRPC) {
DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
@@ -1223,8 +1348,6 @@ NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *
DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
- policy_state = policy_handle->data;
-
*r->out.domains = NULL;
r->out.sids->count = 0;
r->out.sids->sids = NULL;
@@ -1237,59 +1360,44 @@ NTSTATUS dcesrv_lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCT(r2);
+ state = talloc_zero(mem_ctx, struct dcesrv_lsa_LookupNames_base_state);
+ if (state == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ state->dce_call = dce_call;
+ state->mem_ctx = mem_ctx;
+
+ state->policy_state = policy_handle->data;
- r2.in.handle = r->in.handle;
- r2.in.num_names = r->in.num_names;
- r2.in.names = r->in.names;
- r2.in.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
- if (r2.in.sids == NULL) {
+ state->r.in.num_names = r->in.num_names;
+ state->r.in.names = r->in.names;
+ state->r.in.level = r->in.level;
+ state->r.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
+ state->r.in.client_revision = LSA_CLIENT_REVISION_1;
+ state->r.in.sids = talloc_zero(state, struct lsa_TransSidArray3);
+ if (state->r.in.sids == NULL) {
return NT_STATUS_NO_MEMORY;
}
- r2.in.level = r->in.level;
- r2.in.count = r->in.count;
- r2.in.lookup_options = LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES;
- r2.in.client_revision = LSA_CLIENT_REVISION_1;
- r2.out.count = r->out.count;
- r2.out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
- if (r2.out.sids == NULL) {
+ state->r.in.count = r->in.count;
+ state->r.out.domains = r->out.domains;
+ state->r.out.sids = talloc_zero(state, struct lsa_TransSidArray3);
+ if (state->r.out.sids == NULL) {
return NT_STATUS_NO_MEMORY;
}
- r2.out.domains = r->out.domains;
-
- status = dcesrv_lsa_LookupNames_common(dce_call,
- mem_ctx,
- policy_state,
- &r2);
-
- SMB_ASSERT(r2.out.sids->count <= r->in.num_names);
- for (i=0;i<r2.out.sids->count;i++) {
- struct lsa_TranslatedSid3 *s3 =
- &r2.out.sids->sids[i];
- struct lsa_TranslatedSid *s =
- &r->out.sids->sids[i];
-
- s->sid_type = s3->sid_type;
- if (s3->sid_type == SID_NAME_DOMAIN) {
- s->rid = UINT32_MAX;
- } else if (s3->flags & 0x00000004) {
- s->rid = UINT32_MAX;
- } else if (s3->sid == NULL) {
- /*
- * MS-LSAT 3.1.4.7 - rid zero is considered
- * equivalent to sid NULL - so we should return
- * 0 rid for unmapped entries
- */
- s->rid = 0;
- } else {
- s->rid = 0;
- dom_sid_split_rid(NULL, s3->sid,
- NULL, &s->rid);
- }
- s->sid_index = s3->sid_index;
+ state->r.out.count = r->out.count;
+
+ state->_r.l = r;
+
+ status = dcesrv_lsa_LookupNames_base_call(state);
+
+ if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
+ return status;
}
- r->out.sids->count = r2.out.sids->count;
+ state->r.out.result = status;
+ dcesrv_lsa_LookupNames_base_map(state);
+ TALLOC_FREE(state);
return status;
}