From 8e5ce1e2d53f36fd35eb8efad7da680dcf0b1ce1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 17 Nov 2012 02:30:07 +0100 Subject: [PATCH] s3:winbindd: factor winbindd_sids_to_xids into external and internal part - external part takes winbindd request/reponse structs (with sid strings) - internal part takes sid lists The new internal part implements functions wb_sids2xids_* that are moved into the new module wb_sids2xids.c. The purpose of this change is to use wb_sids2xids in winbindd_sid_to_uid and winbindd_sid_to_gid instead of the currently used wb_sid2uid and wb_sid2gid. We should just have one code path into id mapping and not several that behave differently. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher --- source3/Makefile.in | 1 + .../{winbindd_sids_to_xids.c => wb_sids2xids.c} | 128 +++++---------- source3/winbindd/winbindd_proto.h | 6 + source3/winbindd/winbindd_sids_to_xids.c | 180 ++------------------- source3/wscript_build | 1 + 5 files changed, 63 insertions(+), 253 deletions(-) copy source3/winbindd/{winbindd_sids_to_xids.c => wb_sids2xids.c} (62%) diff --git a/source3/Makefile.in b/source3/Makefile.in index 35556873ae1..bb0861fb38f 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1400,6 +1400,7 @@ WINBINDD_OBJ1 = \ winbindd/wb_sid2gid.o \ winbindd/wb_uid2sid.o \ winbindd/wb_gid2sid.o \ + winbindd/wb_sids2xids.o \ winbindd/wb_queryuser.o \ winbindd/wb_lookupuseraliases.o \ winbindd/wb_lookupusergroups.o \ diff --git a/source3/winbindd/winbindd_sids_to_xids.c b/source3/winbindd/wb_sids2xids.c similarity index 62% copy from source3/winbindd/winbindd_sids_to_xids.c copy to source3/winbindd/wb_sids2xids.c index 7456d3a3071..7a198c18cea 100644 --- a/source3/winbindd/winbindd_sids_to_xids.c +++ b/source3/winbindd/wb_sids2xids.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. - async implementation of WINBINDD_SIDS_TO_XIDS + async sids2xids Copyright (C) Volker Lendecke 2011 + Copyright (C) Michael Adam 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,11 +21,12 @@ #include "includes.h" #include "winbindd.h" #include "../libcli/security/security.h" -#include "librpc/gen_ndr/ndr_wbint_c.h" #include "idmap_cache.h" +#include "librpc/gen_ndr/ndr_wbint_c.h" -struct winbindd_sids_to_xids_state { +struct wb_sids2xids_state { struct tevent_context *ev; + struct dom_sid *sids; uint32_t num_sids; @@ -39,54 +41,45 @@ struct winbindd_sids_to_xids_state { struct wbint_TransIDArray ids; }; -static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid, - struct id_map *map); -static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq); -static void winbindd_sids_to_xids_done(struct tevent_req *subreq); -struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct winbindd_cli_state *cli, - struct winbindd_request *request) +static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map); +static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq); +static void wb_sids2xids_done(struct tevent_req *subreq); + +struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + const struct dom_sid *sids, + const uint32_t num_sids) { struct tevent_req *req, *subreq; - struct winbindd_sids_to_xids_state *state; + struct wb_sids2xids_state *state; uint32_t i; req = tevent_req_create(mem_ctx, &state, - struct winbindd_sids_to_xids_state); + struct wb_sids2xids_state); if (req == NULL) { return NULL; } + state->ev = ev; - DEBUG(3, ("sids_to_xids\n")); + state->num_sids = num_sids; - if (request->extra_len == 0) { - tevent_req_done(req); - return tevent_req_post(req, ev); - } - if (request->extra_data.data[request->extra_len-1] != '\0') { - DEBUG(10, ("Got invalid sids list\n")); - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); - return tevent_req_post(req, ev); - } - if (!parse_sidlist(state, request->extra_data.data, - &state->sids, &state->num_sids)) { - DEBUG(10, ("parse_sidlist failed\n")); - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + state->sids = talloc_zero_array(state, struct dom_sid, num_sids); + if (tevent_req_nomem(state->sids, req)) { return tevent_req_post(req, ev); } - DEBUG(10, ("num_sids: %d\n", (int)state->num_sids)); + for (i = 0; i < num_sids; i++) { + sid_copy(&state->sids[i], &sids[i]); + } - state->cached = talloc_zero_array(state, struct id_map, - state->num_sids); + state->cached = talloc_zero_array(state, struct id_map, num_sids); if (tevent_req_nomem(state->cached, req)) { return tevent_req_post(req, ev); } - state->non_cached = talloc_array(state, struct dom_sid, - state->num_sids); + + state->non_cached = talloc_array(state, struct dom_sid, num_sids); if (tevent_req_nomem(state->non_cached, req)) { return tevent_req_post(req, ev); } @@ -101,8 +94,7 @@ struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, DEBUG(10, ("SID %d: %s\n", (int)i, sid_string_dbg(&state->sids[i]))); - if (winbindd_sids_to_xids_in_cache(&state->sids[i], - &state->cached[i])) { + if (wb_sids2xids_in_cache(&state->sids[i], &state->cached[i])) { continue; } sid_copy(&state->non_cached[state->num_non_cached], @@ -120,13 +112,11 @@ struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, winbindd_sids_to_xids_lookupsids_done, - req); + tevent_req_set_callback(subreq, wb_sids2xids_lookupsids_done, req); return req; } -static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid, - struct id_map *map) +static bool wb_sids2xids_in_cache(struct dom_sid *sid, struct id_map *map) { struct unixid id; bool expired; @@ -148,12 +138,12 @@ static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid, static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type); -static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq) +static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); - struct winbindd_sids_to_xids_state *state = tevent_req_data( - req, struct winbindd_sids_to_xids_state); + struct wb_sids2xids_state *state = tevent_req_data( + req, struct wb_sids2xids_state); struct winbindd_child *child; NTSTATUS status; int i; @@ -190,7 +180,7 @@ static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq) if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, winbindd_sids_to_xids_done, req); + tevent_req_set_callback(subreq, wb_sids2xids_done, req); } static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type) @@ -216,12 +206,12 @@ static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type) } -static void winbindd_sids_to_xids_done(struct tevent_req *subreq) +static void wb_sids2xids_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); - struct winbindd_sids_to_xids_state *state = tevent_req_data( - req, struct winbindd_sids_to_xids_state); + struct wb_sids2xids_state *state = tevent_req_data( + req, struct wb_sids2xids_state); NTSTATUS status, result; status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result); @@ -233,13 +223,12 @@ static void winbindd_sids_to_xids_done(struct tevent_req *subreq) tevent_req_done(req); } -NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, - struct winbindd_response *response) +NTSTATUS wb_sids2xids_recv(struct tevent_req *req, + struct unixid *xids) { - struct winbindd_sids_to_xids_state *state = tevent_req_data( - req, struct winbindd_sids_to_xids_state); + struct wb_sids2xids_state *state = tevent_req_data( + req, struct wb_sids2xids_state); NTSTATUS status; - char *result = NULL; uint32_t i, num_non_cached; if (tevent_req_is_nterror(req, &status)) { @@ -247,16 +236,9 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, return status; } - result = talloc_strdup(response, ""); - if (result == NULL) { - return NT_STATUS_NO_MEMORY; - } - num_non_cached = 0; for (i=0; inum_sids; i++) { - char type = '\0'; - bool found = true; struct unixid xid; xid.id = UINT32_MAX; @@ -274,38 +256,8 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, num_non_cached += 1; } - switch (xid.type) { - case ID_TYPE_UID: - type = 'U'; - break; - case ID_TYPE_GID: - type = 'G'; - break; - case ID_TYPE_BOTH: - type = 'B'; - break; - default: - found = false; - break; - } - - if (xid.id == UINT32_MAX) { - found = false; - } - - if (found) { - result = talloc_asprintf_append_buffer( - result, "%c%lu\n", type, - (unsigned long)xid.id); - } else { - result = talloc_asprintf_append_buffer(result, "\n"); - } - if (result == NULL) { - return NT_STATUS_NO_MEMORY; - } + xids[i] = xid; } - response->extra_data.data = result; - response->length += talloc_get_size(result); return NT_STATUS_OK; } diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index b4f0852ac3f..4e5fb7389cc 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -860,6 +860,12 @@ NTSTATUS wb_lookupsids_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct lsa_RefDomainList **domains, struct lsa_TransNameArray **names); +struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + const struct dom_sid *sids, + const uint32_t num_sids); +NTSTATUS wb_sids2xids_recv(struct tevent_req *req, + struct unixid *xids); struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct winbindd_cli_state *cli, diff --git a/source3/winbindd/winbindd_sids_to_xids.c b/source3/winbindd/winbindd_sids_to_xids.c index 7456d3a3071..e4c7e3f0a9f 100644 --- a/source3/winbindd/winbindd_sids_to_xids.c +++ b/source3/winbindd/winbindd_sids_to_xids.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. async implementation of WINBINDD_SIDS_TO_XIDS Copyright (C) Volker Lendecke 2011 + Copyright (C) Michael Adam 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,28 +21,15 @@ #include "includes.h" #include "winbindd.h" #include "../libcli/security/security.h" -#include "librpc/gen_ndr/ndr_wbint_c.h" -#include "idmap_cache.h" + struct winbindd_sids_to_xids_state { struct tevent_context *ev; struct dom_sid *sids; uint32_t num_sids; - - struct id_map *cached; - - struct dom_sid *non_cached; - uint32_t num_non_cached; - - struct lsa_RefDomainList *domains; - struct lsa_TransNameArray *names; - - struct wbint_TransIDArray ids; + struct unixid *xids; }; -static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid, - struct id_map *map); -static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq); static void winbindd_sids_to_xids_done(struct tevent_req *subreq); struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, @@ -51,7 +39,6 @@ struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct winbindd_sids_to_xids_state *state; - uint32_t i; req = tevent_req_create(mem_ctx, &state, struct winbindd_sids_to_xids_state); @@ -80,154 +67,31 @@ struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, DEBUG(10, ("num_sids: %d\n", (int)state->num_sids)); - state->cached = talloc_zero_array(state, struct id_map, - state->num_sids); - if (tevent_req_nomem(state->cached, req)) { - return tevent_req_post(req, ev); - } - state->non_cached = talloc_array(state, struct dom_sid, - state->num_sids); - if (tevent_req_nomem(state->non_cached, 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 - * the same index. - */ - for (i=0; inum_sids; i++) { - - DEBUG(10, ("SID %d: %s\n", (int)i, - sid_string_dbg(&state->sids[i]))); - - if (winbindd_sids_to_xids_in_cache(&state->sids[i], - &state->cached[i])) { - continue; - } - sid_copy(&state->non_cached[state->num_non_cached], - &state->sids[i]); - state->num_non_cached += 1; - } - - if (state->num_non_cached == 0) { - tevent_req_done(req); - return tevent_req_post(req, ev); - } - - subreq = wb_lookupsids_send(state, ev, state->non_cached, - state->num_non_cached); + subreq = wb_sids2xids_send(state, ev, state->sids, state->num_sids); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, winbindd_sids_to_xids_lookupsids_done, - req); - return req; -} -static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid, - struct id_map *map) -{ - struct unixid id; - bool expired; - - if (!winbindd_use_idmap_cache()) { - return false; - } - if (idmap_cache_find_sid2unixid(sid, &id, &expired)) { - if (expired && is_domain_online(find_our_domain())) { - return false; - } - map->sid = sid; - map->xid = id; - map->status = ID_MAPPED; - return true; - } - return false; + tevent_req_set_callback(subreq, winbindd_sids_to_xids_done, req); + return req; } -static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type); - -static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq) +static void winbindd_sids_to_xids_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); struct winbindd_sids_to_xids_state *state = tevent_req_data( req, struct winbindd_sids_to_xids_state); - struct winbindd_child *child; NTSTATUS status; - int i; - - status = wb_lookupsids_recv(subreq, state, &state->domains, - &state->names); - TALLOC_FREE(subreq); - if (tevent_req_nterror(req, status)) { - return; - } - - state->ids.num_ids = state->num_non_cached; - state->ids.ids = talloc_array(state, struct wbint_TransID, - state->num_non_cached); - if (tevent_req_nomem(state->ids.ids, req)) { - return; - } - - for (i=0; inum_non_cached; i++) { - struct lsa_TranslatedName *n = &state->names->names[i]; - struct wbint_TransID *t = &state->ids.ids[i]; - - t->type = lsa_SidType_to_id_type(n->sid_type); - t->domain_index = n->sid_index; - sid_peek_rid(&state->non_cached[i], &t->rid); - t->unix_id = (uint64_t)-1; - } - - child = idmap_child(); - subreq = dcerpc_wbint_Sids2UnixIDs_send( - state, state->ev, child->binding_handle, state->domains, - &state->ids); - if (tevent_req_nomem(subreq, req)) { + state->xids = talloc_zero_array(state, struct unixid, state->num_sids); + if (tevent_req_nomem(state->xids, req)) { return; } - tevent_req_set_callback(subreq, winbindd_sids_to_xids_done, req); -} - -static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type) -{ - enum id_type type; - - switch(sid_type) { - case SID_NAME_COMPUTER: - case SID_NAME_USER: - type = ID_TYPE_UID; - break; - case SID_NAME_DOM_GRP: - case SID_NAME_ALIAS: - case SID_NAME_WKN_GRP: - type = ID_TYPE_GID; - break; - default: - type = ID_TYPE_NOT_SPECIFIED; - break; - } - - return type; -} - -static void winbindd_sids_to_xids_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct winbindd_sids_to_xids_state *state = tevent_req_data( - req, struct winbindd_sids_to_xids_state); - NTSTATUS status, result; - - status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result); + status = wb_sids2xids_recv(subreq, state->xids); TALLOC_FREE(subreq); - if (any_nt_status_not_ok(status, result, &status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -240,10 +104,10 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, req, struct winbindd_sids_to_xids_state); NTSTATUS status; char *result = NULL; - uint32_t i, num_non_cached; + uint32_t i; if (tevent_req_is_nterror(req, &status)) { - DEBUG(5, ("wb_sids_to_xids failed: %s\n", nt_errstr(status))); + DEBUG(5, ("Could not convert sids: %s\n", nt_errstr(status))); return status; } @@ -252,27 +116,12 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, return NT_STATUS_NO_MEMORY; } - num_non_cached = 0; - for (i=0; inum_sids; i++) { char type = '\0'; bool found = true; struct unixid xid; - xid.id = UINT32_MAX; - - if (state->cached[i].sid != NULL) { - xid = state->cached[i].xid; - } else { - xid.id = state->ids.ids[num_non_cached].unix_id; - xid.type = state->ids.ids[num_non_cached].type; - - idmap_cache_set_sid2unixid( - &state->non_cached[num_non_cached], - &xid); - - num_non_cached += 1; - } + xid = state->xids[i]; switch (xid.type) { case ID_TYPE_UID: @@ -307,5 +156,6 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, response->extra_data.data = result; response->length += talloc_get_size(result); + return NT_STATUS_OK; } diff --git a/source3/wscript_build b/source3/wscript_build index b9984fe98bd..039b6b795e2 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -269,6 +269,7 @@ WINBINDD_SRC1 = '''winbindd/winbindd.c winbindd/wb_sid2gid.c winbindd/wb_uid2sid.c winbindd/wb_gid2sid.c + winbindd/wb_sids2xids.c winbindd/wb_queryuser.c winbindd/wb_lookupuseraliases.c winbindd/wb_lookupusergroups.c -- 2.11.4.GIT