summaryrefslogtreecommitdiffstats
path: root/source3/winbindd/wb_lookupsids.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/winbindd/wb_lookupsids.c')
-rw-r--r--source3/winbindd/wb_lookupsids.c96
1 files changed, 79 insertions, 17 deletions
diff --git a/source3/winbindd/wb_lookupsids.c b/source3/winbindd/wb_lookupsids.c
index 05601ad192b..03b2ca9029b 100644
--- a/source3/winbindd/wb_lookupsids.c
+++ b/source3/winbindd/wb_lookupsids.c
@@ -128,26 +128,26 @@ struct tevent_req *wb_lookupsids_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
- state->single_sids = TALLOC_ARRAY(state, uint32_t, num_sids);
+ state->single_sids = talloc_array(state, uint32_t, num_sids);
if (tevent_req_nomem(state->single_sids, req)) {
return tevent_req_post(req, ev);
}
- state->res_domains = TALLOC_ZERO_P(state, struct lsa_RefDomainList);
+ state->res_domains = talloc_zero(state, struct lsa_RefDomainList);
if (tevent_req_nomem(state->res_domains, req)) {
return tevent_req_post(req, ev);
}
- state->res_domains->domains = TALLOC_ARRAY(
+ state->res_domains->domains = talloc_array(
state->res_domains, struct lsa_DomainInfo, num_sids);
if (tevent_req_nomem(state->res_domains->domains, req)) {
return tevent_req_post(req, ev);
}
- state->res_names = TALLOC_ZERO_P(state, struct lsa_TransNameArray);
+ state->res_names = talloc_zero(state, struct lsa_TransNameArray);
if (tevent_req_nomem(state->res_names, req)) {
return tevent_req_post(req, ev);
}
- state->res_names->names = TALLOC_ARRAY(
+ state->res_names->names = talloc_array(
state->res_names, struct lsa_TranslatedName, num_sids);
if (tevent_req_nomem(state->res_names->names, req)) {
return tevent_req_post(req, ev);
@@ -187,7 +187,7 @@ static bool wb_lookupsids_next(struct tevent_req *req,
if (sid_check_is_domain(&d->sid)) {
state->rids.num_rids = d->sids.num_sids;
- state->rids.rids = TALLOC_ARRAY(state, uint32_t,
+ state->rids.rids = talloc_array(state, uint32_t,
state->rids.num_rids);
if (tevent_req_nomem(state->rids.rids, req)) {
return false;
@@ -325,7 +325,7 @@ static struct wb_lookupsids_domain *wb_lookupsids_get_domain(
return NULL;
}
- domains = TALLOC_REALLOC_ARRAY(
+ domains = talloc_realloc(
mem_ctx, domains, struct wb_lookupsids_domain, num_domains+1);
if (domains == NULL) {
return NULL;
@@ -337,13 +337,13 @@ static struct wb_lookupsids_domain *wb_lookupsids_get_domain(
sid_split_rid(&domain->sid, NULL);
domain->domain = wb_domain;
- domain->sids.sids = TALLOC_ARRAY(domains, struct lsa_SidPtr, num_sids);
+ domain->sids.sids = talloc_array(domains, struct lsa_SidPtr, num_sids);
if (domains->sids.sids == NULL) {
goto fail;
}
domain->sids.num_sids = 0;
- domain->sid_indexes = TALLOC_ARRAY(domains, uint32_t, num_sids);
+ domain->sid_indexes = talloc_array(domains, uint32_t, num_sids);
if (domain->sid_indexes == NULL) {
TALLOC_FREE(domain->sids.sids);
goto fail;
@@ -354,7 +354,7 @@ fail:
/*
* Realloc to the state it was in before
*/
- *pdomains = TALLOC_REALLOC_ARRAY(
+ *pdomains = talloc_realloc(
mem_ctx, domains, struct wb_lookupsids_domain, num_domains);
return NULL;
}
@@ -428,6 +428,7 @@ static void wb_lookupsids_done(struct tevent_req *subreq)
req, struct wb_lookupsids_state);
struct wb_lookupsids_domain *d;
uint32_t i;
+ bool fallback = false;
NTSTATUS status, result;
@@ -437,13 +438,31 @@ static void wb_lookupsids_done(struct tevent_req *subreq)
return;
}
+ d = &state->domains[state->domains_done];
+
+ if (NT_STATUS_IS_ERR(result)) {
+ fallback = true;
+ } else if (state->tmp_names.count != d->sids.num_sids) {
+ fallback = true;
+ }
+
+ if (fallback) {
+ for (i=0; i < d->sids.num_sids; i++) {
+ uint32_t res_sid_index = d->sid_indexes[i];
+
+ state->single_sids[state->num_single_sids] =
+ res_sid_index;
+ state->num_single_sids += 1;
+ }
+ state->domains_done += 1;
+ wb_lookupsids_next(req, state);
+ return;
+ }
+
/*
- * Ignore "result" here. We depend on the individual states in
- * the translated names.
+ * Look at the individual states in the translated names.
*/
- d = &state->domains[state->domains_done];
-
for (i=0; i<state->tmp_names.count; i++) {
uint32_t res_sid_index = d->sid_indexes[i];
@@ -462,7 +481,7 @@ static void wb_lookupsids_done(struct tevent_req *subreq)
&state->tmp_domains, &state->tmp_names.names[i],
state->res_domains, state->res_names,
res_sid_index)) {
- tevent_req_nomem(NULL, req);
+ tevent_req_oom(req);
return;
}
}
@@ -525,7 +544,7 @@ static void wb_lookupsids_single_done(struct tevent_req *subreq)
&src_domains, &src_name,
state->res_domains, state->res_names,
res_sid_index)) {
- tevent_req_nomem(NULL, req);
+ tevent_req_oom(req);
return;
}
state->single_sids_done += 1;
@@ -544,6 +563,7 @@ static void wb_lookupsids_lookuprids_done(struct tevent_req *subreq)
NTSTATUS status, result;
struct wb_lookupsids_domain *d;
uint32_t i;
+ bool fallback = false;
status = dcerpc_wbint_LookupRids_recv(subreq, state, &result);
TALLOC_FREE(subreq);
@@ -552,6 +572,30 @@ static void wb_lookupsids_lookuprids_done(struct tevent_req *subreq)
}
d = &state->domains[state->domains_done];
+
+ if (NT_STATUS_IS_ERR(result)) {
+ fallback = true;
+ } else if (state->rid_names.num_principals != d->sids.num_sids) {
+ fallback = true;
+ }
+
+ if (fallback) {
+ for (i=0; i < d->sids.num_sids; i++) {
+ uint32_t res_sid_index = d->sid_indexes[i];
+
+ state->single_sids[state->num_single_sids] =
+ res_sid_index;
+ state->num_single_sids += 1;
+ }
+ state->domains_done += 1;
+ wb_lookupsids_next(req, state);
+ return;
+ }
+
+ /*
+ * Look at the individual states in the translated names.
+ */
+
sid_copy(&src_domain_sid, get_global_sam_sid());
src_domain.name.string = get_global_sam_name();
src_domain.sid = &src_domain_sid;
@@ -575,7 +619,7 @@ static void wb_lookupsids_lookuprids_done(struct tevent_req *subreq)
&src_domains, &src_name,
state->res_domains, state->res_names,
res_sid_index)) {
- tevent_req_nomem(NULL, req);
+ tevent_req_oom(req);
return;
}
}
@@ -595,6 +639,24 @@ NTSTATUS wb_lookupsids_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
if (tevent_req_is_nterror(req, &status)) {
return status;
}
+
+ /*
+ * The returned names need to match the given sids,
+ * if not we have a bug in the code!
+ *
+ */
+ SMB_ASSERT(state->res_names->count == state->num_sids);
+
+ /*
+ * Not strictly needed, but it might make debugging in the callers
+ * easier in future, if the talloc_array_length() returns the
+ * expected result...
+ */
+ state->res_domains->domains = talloc_realloc(state->res_domains,
+ state->res_domains->domains,
+ struct lsa_DomainInfo,
+ state->res_domains->count);
+
*domains = talloc_move(mem_ctx, &state->res_domains);
*names = talloc_move(mem_ctx, &state->res_names);
return NT_STATUS_OK;