mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
wb_sids2xids: inline wb_sids2xids_extract_for_domain_index() into wb_sids2xids_next_sids2unix()
Instead of re-creating the dom_ids element, we just use a pre-allocated map_ids_in array. This is a bit tricky as we need to use map_ids_out as a copy of map_ids_in, because the _ids argument of dcerpc_wbint_Sids2UnixIDs_send() in [in,out], which means that _ids->ids is changed between dcerpc_wbint_Sids2UnixIDs_send() and dcerpc_wbint_Sids2UnixIDs_recv()! If the domain doesn't need any mappings, we'll move to the next domain early, for now this can't happend but it will in future. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
This commit is contained in:
parent
231c8d04b1
commit
f6bb0ed21f
@ -39,6 +39,9 @@ struct wb_sids2xids_state {
|
||||
uint32_t lookup_count;
|
||||
struct dom_sid *lookup_sids;
|
||||
|
||||
struct wbint_TransIDArray map_ids_in;
|
||||
struct wbint_TransIDArray map_ids_out;
|
||||
|
||||
/*
|
||||
* Domain array to use for the idmap call. The output from
|
||||
* lookupsids cannot be used directly since for migrated
|
||||
@ -53,7 +56,6 @@ struct wb_sids2xids_state {
|
||||
struct lsa_RefDomainList idmap_doms;
|
||||
|
||||
uint32_t dom_index;
|
||||
struct wbint_TransIDArray *dom_ids;
|
||||
struct lsa_RefDomainList idmap_dom;
|
||||
bool tried_dclookup;
|
||||
|
||||
@ -107,6 +109,11 @@ struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx,
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
state->map_ids_in.ids = talloc_zero_array(state, struct wbint_TransID, num_sids);
|
||||
if (tevent_req_nomem(state->map_ids_in.ids, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract those sids that can not be resolved from cache
|
||||
* into a separate list to be handed to id mapping, keeping
|
||||
@ -218,9 +225,6 @@ static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map)
|
||||
}
|
||||
|
||||
static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type);
|
||||
static struct wbint_TransIDArray *wb_sids2xids_extract_for_domain_index(
|
||||
TALLOC_CTX *mem_ctx, const struct wbint_TransIDArray *src,
|
||||
uint32_t domain_index);
|
||||
|
||||
static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq)
|
||||
{
|
||||
@ -308,7 +312,11 @@ static void wb_sids2xids_next_sids2unix(struct tevent_req *req)
|
||||
req, struct wb_sids2xids_state);
|
||||
struct tevent_req *subreq = NULL;
|
||||
struct dcerpc_binding_handle *child_binding_handle = NULL;
|
||||
const struct wbint_TransIDArray *src = NULL;
|
||||
struct wbint_TransIDArray *dst = NULL;
|
||||
uint32_t si;
|
||||
|
||||
next_domain:
|
||||
state->tried_dclookup = false;
|
||||
|
||||
if (state->dom_index == state->idmap_doms.count) {
|
||||
@ -316,10 +324,23 @@ static void wb_sids2xids_next_sids2unix(struct tevent_req *req)
|
||||
return;
|
||||
}
|
||||
|
||||
state->dom_ids = wb_sids2xids_extract_for_domain_index(
|
||||
state, &state->ids, state->dom_index);
|
||||
if (tevent_req_nomem(state->dom_ids, req)) {
|
||||
return;
|
||||
src = &state->ids;
|
||||
dst = &state->map_ids_in;
|
||||
dst->num_ids = 0;
|
||||
|
||||
for (si=0; si < src->num_ids; si++) {
|
||||
if (src->ids[si].domain_index != state->dom_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dst->ids[dst->num_ids] = src->ids[si];
|
||||
dst->ids[dst->num_ids].domain_index = 0;
|
||||
dst->num_ids += 1;
|
||||
}
|
||||
|
||||
if (dst->num_ids == 0) {
|
||||
state->dom_index += 1;
|
||||
goto next_domain;
|
||||
}
|
||||
|
||||
state->idmap_dom = (struct lsa_RefDomainList) {
|
||||
@ -328,10 +349,23 @@ static void wb_sids2xids_next_sids2unix(struct tevent_req *req)
|
||||
.max_size = 1
|
||||
};
|
||||
|
||||
/*
|
||||
* dcerpc_wbint_Sids2UnixIDs_send/recv will
|
||||
* allocate a new array for the response
|
||||
* and overwrite _ids->ids pointer.
|
||||
*
|
||||
* So we better make a temporary copy
|
||||
* of state->map_ids_in (which contains the request array)
|
||||
* into state->map_ids_out.
|
||||
*
|
||||
* That makes it possible to reuse the pre-allocated
|
||||
* state->map_ids_in.ids array.
|
||||
*/
|
||||
state->map_ids_out = state->map_ids_in;
|
||||
child_binding_handle = idmap_child_handle();
|
||||
subreq = dcerpc_wbint_Sids2UnixIDs_send(
|
||||
state, state->ev, child_binding_handle, &state->idmap_dom,
|
||||
state->dom_ids);
|
||||
&state->map_ids_out);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
@ -394,7 +428,7 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
|
||||
return;
|
||||
}
|
||||
|
||||
src = state->dom_ids;
|
||||
src = &state->map_ids_out;
|
||||
src_idx = 0;
|
||||
dst = &state->ids;
|
||||
|
||||
@ -405,11 +439,17 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
|
||||
/*
|
||||
* All we can do here is to report "not mapped"
|
||||
*/
|
||||
src = &state->map_ids_in;
|
||||
for (i=0; i<src->num_ids; i++) {
|
||||
src->ids[i].xid.type = ID_TYPE_NOT_SPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
if (src->num_ids != state->map_ids_in.num_ids) {
|
||||
tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<dst->num_ids; i++) {
|
||||
if (dst->ids[i].domain_index == state->dom_index) {
|
||||
dst->ids[i].xid = src->ids[src_idx].xid;
|
||||
@ -417,7 +457,17 @@ static void wb_sids2xids_done(struct tevent_req *subreq)
|
||||
}
|
||||
}
|
||||
|
||||
TALLOC_FREE(state->dom_ids);
|
||||
state->map_ids_in.num_ids = 0;
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
/*
|
||||
* If we got a valid response, we expect
|
||||
* state->map_ids_out.ids to be a new allocated
|
||||
* array, which we want to free early.
|
||||
*/
|
||||
SMB_ASSERT(state->map_ids_out.ids != state->map_ids_in.ids);
|
||||
TALLOC_FREE(state->map_ids_out.ids);
|
||||
}
|
||||
state->map_ids_out = (struct wbint_TransIDArray) { .num_ids = 0, };
|
||||
|
||||
state->dom_index += 1;
|
||||
|
||||
@ -453,10 +503,23 @@ static void wb_sids2xids_gotdc(struct tevent_req *subreq)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dcerpc_wbint_Sids2UnixIDs_send/recv will
|
||||
* allocate a new array for the response
|
||||
* and overwrite _ids->ids pointer.
|
||||
*
|
||||
* So we better make a temporary copy
|
||||
* of state->map_ids_in (which contains the request array)
|
||||
* into state->map_ids_out.
|
||||
*
|
||||
* That makes it possible to reuse the pre-allocated
|
||||
* state->map_ids_in.ids array.
|
||||
*/
|
||||
state->map_ids_out = state->map_ids_in;
|
||||
child_binding_handle = idmap_child_handle();
|
||||
subreq = dcerpc_wbint_Sids2UnixIDs_send(
|
||||
state, state->ev, child_binding_handle, &state->idmap_dom,
|
||||
state->dom_ids);
|
||||
&state->map_ids_out);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
@ -504,31 +567,3 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req,
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static struct wbint_TransIDArray *wb_sids2xids_extract_for_domain_index(
|
||||
TALLOC_CTX *mem_ctx, const struct wbint_TransIDArray *src,
|
||||
uint32_t domain_index)
|
||||
{
|
||||
struct wbint_TransIDArray *ret;
|
||||
uint32_t i;
|
||||
|
||||
ret = talloc_zero(mem_ctx, struct wbint_TransIDArray);
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ret->ids = talloc_array(ret, struct wbint_TransID, src->num_ids);
|
||||
if (ret->ids == NULL) {
|
||||
TALLOC_FREE(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i<src->num_ids; i++) {
|
||||
if (src->ids[i].domain_index == domain_index) {
|
||||
ret->ids[ret->num_ids] = src->ids[i];
|
||||
ret->ids[ret->num_ids].domain_index = 0;
|
||||
ret->num_ids += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user