From c4b8acb561d19853aa0313e0770c87d6651791c6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Sep 2012 15:31:26 -0700 Subject: [PATCH 01/50] s3: Fix idmap_hash Calling be_init with NULL safely crashes, because we dereference NULL. We don't need to call it here, this is called in all workers anyway. Thanks to Jiri Sasek for finding this. Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Thu Sep 20 05:03:54 CEST 2012 on sn-devel-104 (cherry picked from commit 03055af9b2af8a5a1c23946369a21d6437cf1b8c) --- source3/winbindd/idmap_hash/idmap_hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c index cb518a8..bff1e9e 100644 --- a/source3/winbindd/idmap_hash/idmap_hash.c +++ b/source3/winbindd/idmap_hash/idmap_hash.c @@ -259,7 +259,7 @@ done: static NTSTATUS nss_hash_init(struct nss_domain_entry *e ) { - return be_init(NULL); + return NT_STATUS_OK; } /********************************************************************** -- 1.7.9.5 From 82abfc631e1de2b960a45be412caae8d16893cb6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 19 Sep 2012 02:57:37 +0200 Subject: [PATCH 02/50] s3:winbind:idmap_tdb_common: improve readability of assignment by adding an "if" in idmap_tdb_common_unixids_to_sids() (cherry picked from commit d1de2b4d3999dda96df9156da30a239af3b2b88e) --- source3/winbindd/idmap_tdb_common.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source3/winbindd/idmap_tdb_common.c b/source3/winbindd/idmap_tdb_common.c index 2b16d0b..b232729 100644 --- a/source3/winbindd/idmap_tdb_common.c +++ b/source3/winbindd/idmap_tdb_common.c @@ -320,9 +320,11 @@ NTSTATUS idmap_tdb_common_unixids_to_sids(struct idmap_domain * dom, talloc_get_type_abort(dom->private_data, struct idmap_tdb_common_context); - unixid_to_sid_fn = - (ctx->unixid_to_sid_fn == - NULL) ? idmap_tdb_common_unixid_to_sid : ctx->unixid_to_sid_fn; + if (ctx->unixid_to_sid_fn == NULL) { + unixid_to_sid_fn = idmap_tdb_common_unixid_to_sid; + } else { + unixid_to_sid_fn = ctx->unixid_to_sid_fn; + } /* initialize the status to avoid surprise */ for (i = 0; ids[i]; i++) { -- 1.7.9.5 From 2d6cf47cc41b4b453be25a605298b48f79d13b81 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 19 Sep 2012 02:57:37 +0200 Subject: [PATCH 03/50] s3:winbind:idmap_tdb_common: improve readability of assignment by adding an "if" in idmap_tdb_common_sids_to_unixids() (cherry picked from commit 38994f6ff34316ad08961f62a1f57429f7968e70) --- source3/winbindd/idmap_tdb_common.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source3/winbindd/idmap_tdb_common.c b/source3/winbindd/idmap_tdb_common.c index b232729..5713fe2 100644 --- a/source3/winbindd/idmap_tdb_common.c +++ b/source3/winbindd/idmap_tdb_common.c @@ -638,9 +638,11 @@ NTSTATUS idmap_tdb_common_sids_to_unixids(struct idmap_domain * dom, state.dom = dom; state.ids = ids; state.allocate_unmapped = false; - state.sid_to_unixid_fn = - (ctx->sid_to_unixid_fn == - NULL) ? idmap_tdb_common_sid_to_unixid : ctx->sid_to_unixid_fn; + if (ctx->sid_to_unixid_fn == NULL) { + state.sid_to_unixid_fn = idmap_tdb_common_sid_to_unixid; + } else { + state.sid_to_unixid_fn = ctx->sid_to_unixid_fn; + } ret = idmap_tdb_common_sids_to_unixids_action(ctx->db, &state); -- 1.7.9.5 From bcee4a45b956542d0b9d743499bcb09f1e36eefa Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Sat, 22 Sep 2012 13:32:00 -0700 Subject: [PATCH 04/50] s3:winbindd fix a compiler warning about result being potentially uninitialized (cherry picked from commit 1b5256c184ec378783e6219b34b5a3e512c4df99) --- source3/winbindd/winbindd_sids_to_xids.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_sids_to_xids.c b/source3/winbindd/winbindd_sids_to_xids.c index 09d9a9b..ad02189 100644 --- a/source3/winbindd/winbindd_sids_to_xids.c +++ b/source3/winbindd/winbindd_sids_to_xids.c @@ -223,7 +223,7 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, struct winbindd_sids_to_xids_state *state = tevent_req_data( req, struct winbindd_sids_to_xids_state); NTSTATUS status; - char *result; + char *result = NULL; uint32_t i, num_non_cached; if (tevent_req_is_nterror(req, &status)) { -- 1.7.9.5 From 6b5874f9774c3797678b04f24014f3f30ea22c09 Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Sat, 22 Sep 2012 20:44:41 -0700 Subject: [PATCH 05/50] s3:winbindd fix a compiler warning about type potentially being used uninitialized Autobuild-User(master): Christian Ambach Autobuild-Date(master): Mon Sep 24 03:49:53 CEST 2012 on sn-devel-104 (cherry picked from commit f767059911460c0944d5e9289148a0776aeb97e5) --- source3/winbindd/winbindd_sids_to_xids.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_sids_to_xids.c b/source3/winbindd/winbindd_sids_to_xids.c index ad02189..f500f24 100644 --- a/source3/winbindd/winbindd_sids_to_xids.c +++ b/source3/winbindd/winbindd_sids_to_xids.c @@ -239,7 +239,7 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, num_non_cached = 0; for (i=0; inum_sids; i++) { - char type; + char type = '\0'; uint32_t unix_id = UINT32_MAX; bool found = true; -- 1.7.9.5 From b7aac11dba3f1ed7224792f6003c8c48ac04f5c7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 9 Nov 2012 11:32:47 +0100 Subject: [PATCH 06/50] s3:winbindd:util: add a comment explaining the function parse_sidlist() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 3f0c31fbd388986d636b5701f66ed7b215a1b903) --- source3/winbindd/winbindd_util.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 25ef750..6e13ca8 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1360,6 +1360,15 @@ bool is_domain_online(const struct winbindd_domain *domain) return !is_domain_offline(domain); } +/** + * Parse an char array into a list of sids. + * + * The input sidstr should consist of 0-terminated strings + * representing sids, separated by newline characters '\n'. + * The list is terminated by an empty string, i.e. + * character '\0' directly following a character '\n' + * (or '\0' right at the start of sidstr). + */ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, struct dom_sid **sids, uint32_t *num_sids) { -- 1.7.9.5 From 495bb84ecbdd921b001e7421be901b35029a1210 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 9 Nov 2012 13:54:20 +0100 Subject: [PATCH 07/50] s3:winbindd: simplify winbindd_sids_to_xids_recv() a bit. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit b435e668aa8b2805cd94bde37b9ddf6a7ad335f8) --- source3/winbindd/winbindd_sids_to_xids.c | 65 ++++++++++++------------------ 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/source3/winbindd/winbindd_sids_to_xids.c b/source3/winbindd/winbindd_sids_to_xids.c index f500f24..f1dd401 100644 --- a/source3/winbindd/winbindd_sids_to_xids.c +++ b/source3/winbindd/winbindd_sids_to_xids.c @@ -240,62 +240,47 @@ NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, for (i=0; inum_sids; i++) { char type = '\0'; - uint32_t unix_id = UINT32_MAX; bool found = true; + struct unixid xid; + + xid.id = UINT32_MAX; if (state->cached[i].sid != NULL) { - unix_id = state->cached[i].xid.id; - - switch (state->cached[i].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; - } + xid = state->cached[i].xid; } else { - struct unixid id; - - unix_id = state->ids.ids[num_non_cached].unix_id; + xid.id = state->ids.ids[num_non_cached].unix_id; + xid.type = state->ids.ids[num_non_cached].type; - id.id = unix_id; - id.type = state->ids.ids[num_non_cached].type; idmap_cache_set_sid2unixid( &state->non_cached[num_non_cached], - &id); - - switch (id.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; - } + &xid); + num_non_cached += 1; } - if (unix_id == UINT32_MAX) { + 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)unix_id); + (unsigned long)xid.id); } else { result = talloc_asprintf_append_buffer(result, "\n"); } -- 1.7.9.5 From ceb09d2bfcef6ac81f8c168626ada9979522c35e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 9 Nov 2012 14:09:10 +0100 Subject: [PATCH 08/50] s3:winbindd: factor lsa_SidType_to_id_type() out of winbindd_sids_to_xids_lookupsids_done() for readability Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit be033a1d165f815bbddceda46384be1f9c0c2b7f) --- source3/winbindd/winbindd_sids_to_xids.c | 39 +++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/source3/winbindd/winbindd_sids_to_xids.c b/source3/winbindd/winbindd_sids_to_xids.c index f1dd401..0b04056 100644 --- a/source3/winbindd/winbindd_sids_to_xids.c +++ b/source3/winbindd/winbindd_sids_to_xids.c @@ -141,6 +141,7 @@ static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid, return false; } +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) { @@ -170,20 +171,7 @@ static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq) struct lsa_TranslatedName *n = &state->names->names[i]; struct wbint_TransID *t = &state->ids.ids[i]; - switch (n->sid_type) { - case SID_NAME_USER: - case SID_NAME_COMPUTER: - t->type = ID_TYPE_UID; - break; - case SID_NAME_DOM_GRP: - case SID_NAME_ALIAS: - case SID_NAME_WKN_GRP: - t->type = ID_TYPE_GID; - break; - default: - t->type = ID_TYPE_NOT_SPECIFIED; - break; - }; + 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; @@ -200,6 +188,29 @@ static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq) 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( -- 1.7.9.5 From 3412d518dd8c728d087c1983d989b64a9fd6acef Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 9 Nov 2012 16:09:59 +0100 Subject: [PATCH 09/50] s3:winbindd: add explaining comment winbindd_sids_to_xids_send() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 349b9ac05242f87fa5afcc06c72ccc02bdb05d8b) --- source3/winbindd/winbindd_sids_to_xids.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/winbindd/winbindd_sids_to_xids.c b/source3/winbindd/winbindd_sids_to_xids.c index 0b04056..518606d 100644 --- a/source3/winbindd/winbindd_sids_to_xids.c +++ b/source3/winbindd/winbindd_sids_to_xids.c @@ -91,6 +91,11 @@ struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, 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, -- 1.7.9.5 From ffbb09dc68d15469ca663887520555f2d81d6ffb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 16 Nov 2012 17:49:25 +0100 Subject: [PATCH 10/50] s3:winbindd: convert some spaces to tabs in winbindd_sids_to_xids_send() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit c58c68d5ba58855098d24c54db9c0cda19db0f4b) --- source3/winbindd/winbindd_sids_to_xids.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source3/winbindd/winbindd_sids_to_xids.c b/source3/winbindd/winbindd_sids_to_xids.c index 518606d..7456d3a 100644 --- a/source3/winbindd/winbindd_sids_to_xids.c +++ b/source3/winbindd/winbindd_sids_to_xids.c @@ -110,10 +110,10 @@ struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, state->num_non_cached += 1; } - if (state->num_non_cached == 0) { - tevent_req_done(req); - return tevent_req_post(req, ev); - } + 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); -- 1.7.9.5 From 761b05f58608c9cf606faaf3e31e2950876783e4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 17 Nov 2012 02:30:07 +0100 Subject: [PATCH 11/50] 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 (cherry picked from commit 8e5ce1e2d53f36fd35eb8efad7da680dcf0b1ce1) --- source3/Makefile.in | 1 + source3/winbindd/wb_sids2xids.c | 263 ++++++++++++++++++++++++++++++ source3/winbindd/winbindd_proto.h | 6 + source3/winbindd/winbindd_sids_to_xids.c | 180 ++------------------ source3/wscript_build | 1 + 5 files changed, 286 insertions(+), 165 deletions(-) create mode 100644 source3/winbindd/wb_sids2xids.c diff --git a/source3/Makefile.in b/source3/Makefile.in index c729e20..0a96b28 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1398,6 +1398,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/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c new file mode 100644 index 0000000..7a198c1 --- /dev/null +++ b/source3/winbindd/wb_sids2xids.c @@ -0,0 +1,263 @@ +/* + Unix SMB/CIFS implementation. + 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "winbindd.h" +#include "../libcli/security/security.h" +#include "idmap_cache.h" +#include "librpc/gen_ndr/ndr_wbint_c.h" + +struct wb_sids2xids_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; +}; + + +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 wb_sids2xids_state *state; + uint32_t i; + + req = tevent_req_create(mem_ctx, &state, + struct wb_sids2xids_state); + if (req == NULL) { + return NULL; + } + + state->ev = ev; + + state->num_sids = num_sids; + + state->sids = talloc_zero_array(state, struct dom_sid, num_sids); + if (tevent_req_nomem(state->sids, req)) { + return tevent_req_post(req, ev); + } + + for (i = 0; i < num_sids; i++) { + sid_copy(&state->sids[i], &sids[i]); + } + + 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, 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 (wb_sids2xids_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); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, wb_sids2xids_lookupsids_done, req); + return req; +} + +static bool wb_sids2xids_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; +} + +static enum id_type lsa_SidType_to_id_type(const enum lsa_SidType sid_type); + +static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_sids2xids_state *state = tevent_req_data( + req, struct wb_sids2xids_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)) { + return; + } + tevent_req_set_callback(subreq, wb_sids2xids_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 wb_sids2xids_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wb_sids2xids_state *state = tevent_req_data( + req, struct wb_sids2xids_state); + NTSTATUS status, result; + + status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result); + TALLOC_FREE(subreq); + if (any_nt_status_not_ok(status, result, &status)) { + tevent_req_nterror(req, status); + return; + } + tevent_req_done(req); +} + +NTSTATUS wb_sids2xids_recv(struct tevent_req *req, + struct unixid *xids) +{ + struct wb_sids2xids_state *state = tevent_req_data( + req, struct wb_sids2xids_state); + NTSTATUS status; + uint32_t i, num_non_cached; + + if (tevent_req_is_nterror(req, &status)) { + DEBUG(5, ("wb_sids_to_xids failed: %s\n", nt_errstr(status))); + return status; + } + + num_non_cached = 0; + + for (i=0; inum_sids; i++) { + 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; + } + + xids[i] = xid; + } + + return NT_STATUS_OK; +} diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 5cc90f2..e5bacde 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -857,6 +857,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 7456d3a..e4c7e3f 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 b87b4d1..c8f4f69 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 -- 1.7.9.5 From 3c50002d23a74db84e3319d26c47dafbecf5b1a5 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 17 Nov 2012 13:04:41 +0100 Subject: [PATCH 12/50] s3:winbindd: use wb_sids2xids instead of wb_sid2uid in winbindd_sid_to_uid The main purpose of the change is to hand the sid into the idmap backend and handle responsiblity for handling the sid-type correctly to the idmap backend instead of failing directly when the sid is not of type user. Hence backends like rid who are sid-type agnostic, can return uids also for sids of other types. This is an important fix to make sid_to_uid behave the consistently with and without the presence of cache entries. We need to additionally filter the result for id type UID or more general (BOTH) to keep the behaviour. This is a step towards using only one codepath to id_mapping. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 7637c93472492f1bfd7bf46b8f855ef4818c75a9) --- source3/winbindd/winbindd_sid_to_uid.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/source3/winbindd/winbindd_sid_to_uid.c b/source3/winbindd/winbindd_sid_to_uid.c index 9ce564f..67fe952 100644 --- a/source3/winbindd/winbindd_sid_to_uid.c +++ b/source3/winbindd/winbindd_sid_to_uid.c @@ -54,7 +54,7 @@ struct tevent_req *winbindd_sid_to_uid_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - subreq = wb_sid2uid_send(state, ev, &state->sid); + subreq = wb_sids2xids_send(state, ev, &state->sid, 1); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -69,12 +69,26 @@ static void winbindd_sid_to_uid_done(struct tevent_req *subreq) struct winbindd_sid_to_uid_state *state = tevent_req_data( req, struct winbindd_sid_to_uid_state); NTSTATUS status; + struct unixid xid; - status = wb_sid2uid_recv(subreq, &state->uid); + status = wb_sids2xids_recv(subreq, &xid); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; } + + /* + * We are filtering further down in sids2xids, but that filtering + * depends on the actual type of the sid handed in (as determined + * by lookupsids). Here we need to filter for the type of object + * actually requested, in this case uid. + */ + if (!(xid.type == ID_TYPE_UID || xid.type == ID_TYPE_BOTH)) { + tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); + return; + } + + state->uid = (uid_t)xid.id; tevent_req_done(req); } -- 1.7.9.5 From a351cf83c2f8c7bbf700ec34320c8b22b2c6883e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 17 Nov 2012 13:10:26 +0100 Subject: [PATCH 13/50] s3:winbindd: use wb_sids2xids instead of wb_sid2gid in winbindd_sid_to_gid The main purpose of the change is to hand the sid into the idmap backend and handle responsiblity for handling the sid-type correctly to the idmap backend instead of failing directly when the sid is not of group type. Hence backends like rid who are sid-type agnostic, can return gids also for sids of other types. This is an important fix to make sid_to_gid behave the consistently with and without the presence of cache entries. We need to additionally filter the result for id type GID or more general (BOTH) to keep the behaviour. This is a step towards using only one codepath to id_mapping. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 3e7f04b70f89d528aacfdc420b635d8aff0f4af6) --- source3/winbindd/winbindd_sid_to_gid.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/source3/winbindd/winbindd_sid_to_gid.c b/source3/winbindd/winbindd_sid_to_gid.c index df44ed8..46ca903 100644 --- a/source3/winbindd/winbindd_sid_to_gid.c +++ b/source3/winbindd/winbindd_sid_to_gid.c @@ -54,7 +54,7 @@ struct tevent_req *winbindd_sid_to_gid_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - subreq = wb_sid2gid_send(state, ev, &state->sid); + subreq = wb_sids2xids_send(state, ev, &state->sid, 1); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -69,12 +69,26 @@ static void winbindd_sid_to_gid_done(struct tevent_req *subreq) struct winbindd_sid_to_gid_state *state = tevent_req_data( req, struct winbindd_sid_to_gid_state); NTSTATUS status; + struct unixid xid; - status = wb_sid2gid_recv(subreq, &state->gid); + status = wb_sids2xids_recv(subreq, &xid); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; } + + /* + * We are filtering further down in sids2xids, but that filtering + * depends on the actual type of the sid handed in (as determined + * by lookupsids). Here we need to filter for the type of object + * actually requested, in this case gid. + */ + if (!(xid.type == ID_TYPE_GID || xid.type == ID_TYPE_BOTH)) { + tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); + return; + } + + state->gid = (gid_t)xid.id; tevent_req_done(req); } -- 1.7.9.5 From b36a90ade05c94060a16344a5158e13402a62e3f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 18 Nov 2012 19:29:37 +0100 Subject: [PATCH 14/50] s3:winbindd: add an explanatory comment to _wbint_Sids2UnixIDs() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 75a752473f932f84d15ba043c9b9167db10dd572) --- source3/winbindd/winbindd_dual_srv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index d394543..bb0f225 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -189,6 +189,11 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p, num_ids = 0; + /* + * Convert the input data into a list of + * id_map structs suitable for handing in + * to the idmap sids_to_unixids method. + */ for (j=0; jin.ids->num_ids; j++) { struct wbint_TransID *id = &r->in.ids->ids[j]; -- 1.7.9.5 From a80181793a4b6cfe88a36743a68c8b9e2037f56f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 18 Nov 2012 19:58:07 +0100 Subject: [PATCH 15/50] s3:winbindd: add an explanatory comment to _wbint_Sids2UnixIDs() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit da8d0263806260fdb4973f22fc874710bd490421) --- source3/winbindd/winbindd_dual_srv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index bb0f225..9fb2911 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -215,6 +215,9 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p, DEBUG(10, ("sids_to_unixids returned %s\n", nt_errstr(status))); + /* + * Extract the results for handing them back to the caller. + */ for (j=0; jin.ids->ids[id_idx[j]]; -- 1.7.9.5 From 5f9b5872e906d65d2cc7e06b44585b339cb80fd9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 18 Nov 2012 13:51:13 +0100 Subject: [PATCH 16/50] s3:winbindd: use struct unixid instead of uint64 in Sids2Xids parent<->child This implicitly also hands the type of the resulting unix-id that the idmap backend has created back to the caller. This is important for backends that would set a broader type than the requested one, e.g. rid backend returning BOTH instead of UID or GID. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 28e7d73bdcdf1a3d588e92eee982ff01db53d65d) --- source3/librpc/idl/wbint.idl | 2 +- source3/winbindd/wb_sids2xids.c | 6 +++--- source3/winbindd/winbindd_dual_srv.c | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source3/librpc/idl/wbint.idl b/source3/librpc/idl/wbint.idl index 159af76..c836f0f 100644 --- a/source3/librpc/idl/wbint.idl +++ b/source3/librpc/idl/wbint.idl @@ -53,7 +53,7 @@ interface wbint id_type type; uint32 domain_index; uint32 rid; - hyper unix_id; + unixid xid; } wbint_TransID; typedef struct { diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c index 7a198c1..cbd4444 100644 --- a/source3/winbindd/wb_sids2xids.c +++ b/source3/winbindd/wb_sids2xids.c @@ -169,7 +169,8 @@ static void wb_sids2xids_lookupsids_done(struct tevent_req *subreq) 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; + t->xid.id = UINT32_MAX; + t->xid.type = t->type; } child = idmap_child(); @@ -246,8 +247,7 @@ NTSTATUS wb_sids2xids_recv(struct tevent_req *req, 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; + xid = state->ids.ids[num_non_cached].xid; idmap_cache_set_sid2unixid( &state->non_cached[num_non_cached], diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 9fb2911..35d9451 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -222,9 +222,12 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p, struct wbint_TransID *id = &r->in.ids->ids[id_idx[j]]; if (ids[j].status != ID_MAPPED) { + id->xid.id = UINT32_MAX; + id->xid.type = ID_TYPE_NOT_SPECIFIED; continue; } - id->unix_id = ids[j].xid.id; + + id->xid = ids[j].xid; } } status = NT_STATUS_OK; -- 1.7.9.5 From 185bb6e1ab4514b875ef89f4198ac6064e2e9209 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 20 Nov 2012 16:48:23 +0100 Subject: [PATCH 17/50] selftest:Samba3: provision the domain adminstrators group in the s3 environments I discovered that this sid / mapping is missing by working with the Sids2Uids code and test. I do even wonder why this test could succeed prior to my pending changes to the winbindd sids-to-xids code, for example against the s3:local environment, since the test tries to map the sid -512. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit ee17a516c82acbdf347c2a47e7003b6a7fb879de) --- selftest/target/Samba3.pm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 5c86612..2b99419 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -816,7 +816,7 @@ sub provision($$$$$$) my ($max_uid, $max_gid); my ($uid_nobody, $uid_root, $uid_pdbtest); - my ($gid_nobody, $gid_nogroup, $gid_root, $gid_domusers); + my ($gid_nobody, $gid_nogroup, $gid_root, $gid_domusers, $gid_domadmins); if ($unix_uid < 0xffff - 2) { $max_uid = 0xffff; @@ -838,6 +838,7 @@ sub provision($$$$$$) $gid_nogroup = $max_gid - 2; $gid_root = $max_gid - 3; $gid_domusers = $max_gid - 4; + $gid_domadmins = $max_gid - 5; ## ## create conffile @@ -1040,6 +1041,7 @@ pdbtest:x:$uid_pdbtest:$gid_nogroup:pdbtest gecos:$prefix_abs:/bin/false nogroup:x:$gid_nogroup:nobody $unix_name-group:x:$unix_gids[0]: domusers:X:$gid_domusers: +domadmins:X:$gid_domadmins: "; if ($unix_gids[0] != 0) { print GROUP "root:x:$gid_root:"; @@ -1141,6 +1143,10 @@ sub wait_for_start($$) if ($ret != 0) { return 1; } + $ret = system(Samba::bindir_path($self, "net") ." $envvars->{CONFIGURATION} groupmap add rid=512 unixgroup=domadmins type=domain"); + if ($ret != 0) { + return 1; + } print $self->getlog_env($envvars); -- 1.7.9.5 From 3b6125b9856127f5cabc455a91695a5c4601c5c4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 22 Nov 2012 16:21:53 +0100 Subject: [PATCH 18/50] s3:winbindd: rename idmap_init_passdb_domain() -> idmap_passdb_domain() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 150cfb4b97e2ee67ec1fa8fc379ac03d42002da9) --- source3/winbindd/idmap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index f6e48d3..07295e7 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -325,7 +325,7 @@ static struct idmap_domain *idmap_init_default_domain(TALLOC_CTX *mem_ctx) * No config, passdb has its own configuration. */ -static struct idmap_domain *idmap_init_passdb_domain(TALLOC_CTX *mem_ctx) +static struct idmap_domain *idmap_passdb_domain(TALLOC_CTX *mem_ctx) { idmap_init(); @@ -483,7 +483,7 @@ NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id) * Always give passdb a chance first */ - dom = idmap_init_passdb_domain(NULL); + dom = idmap_passdb_domain(NULL); if ((dom != NULL) && NT_STATUS_IS_OK(dom->methods->unixids_to_sids(dom, maps)) && id->status == ID_MAPPED) { @@ -516,7 +516,7 @@ NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id) DEBUG(10, ("asking passdb...\n")); - dom = idmap_init_passdb_domain(NULL); + dom = idmap_passdb_domain(NULL); if (dom == NULL) { return NT_STATUS_NONE_MAPPED; } -- 1.7.9.5 From cdcd892928d6378def6503789508cb2aad05ee96 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 22 Nov 2012 18:16:31 +0100 Subject: [PATCH 19/50] s3:winbindd: add idmap_find_domain_with_sid() This will return the passdb domain if the given sid is in our sam or builtin or is the domain sid of those domains. Otherwise it returns the idmap domain that results from the idmap configuration. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 370d62578dd171c6f898f4868f382cdddb908bcf) --- source3/winbindd/idmap.c | 16 ++++++++++++++++ source3/winbindd/winbindd_proto.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 07295e7..065b7e6 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -422,6 +422,22 @@ struct idmap_domain *idmap_find_domain(const char *domname) return result; } +struct idmap_domain *idmap_find_domain_with_sid(const char *domname, + const struct dom_sid *sid) +{ + idmap_init(); + + if (sid_check_is_in_builtin(sid) || + sid_check_is_builtin(sid) || + sid_check_is_in_our_sam(sid) || + sid_check_is_our_sam(sid)) + { + return idmap_passdb_domain(NULL); + } + + return idmap_find_domain(domname); +} + void idmap_close(void) { TALLOC_FREE(default_idmap_domain); diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index e5bacde..6ad46ae 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -314,6 +314,8 @@ NTSTATUS winbindd_print_groupmembers(struct talloc_dict *members, void init_idmap_child(void); struct winbindd_child *idmap_child(void); struct idmap_domain *idmap_find_domain(const char *domname); +struct idmap_domain *idmap_find_domain_with_sid(const char *domname, + const struct dom_sid *sid); /* The following definitions come from winbindd/winbindd_locator.c */ -- 1.7.9.5 From f6a21b4ee73f670c4f9e2e84b9cab68ae77aec9b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 25 Nov 2012 02:13:15 +0100 Subject: [PATCH 20/50] s3:winbindd: also use idmap_passdb for own sam and builtin in wbint_Sids2UnixIDs() This is the way the singular calls work and how they should (currently) work. The two code paths need to give the same results. It is important to use the passdb backend, otherwise groups don't work. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 27f88ba2deeec8b5b0a72ef97ae84c1016532a3c) --- source3/winbindd/winbindd_dual_srv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 35d9451..6600082 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -151,10 +151,10 @@ NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p, struct idmap_domain *dom; uint32_t num_ids; - dom = idmap_find_domain(d->name.string); + dom = idmap_find_domain_with_sid(d->name.string, d->sid); if (dom == NULL) { - DEBUG(10, ("idmap domain %s not found\n", - d->name.string)); + DEBUG(10, ("idmap domain %s:%s not found\n", + d->name.string, sid_string_dbg(d->sid))); continue; } -- 1.7.9.5 From 6ba2ceea6caf7434a41add0ba10c4012dbf10803 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 27 Nov 2012 01:11:16 +0100 Subject: [PATCH 21/50] s3:winbindd: make idmap_find_domain() static. idmap_find_domain_with_sid() should be used instead Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 4210e08109d9bc24168740f5a8a52953c532df4a) --- source3/winbindd/idmap.c | 2 +- source3/winbindd/winbindd_proto.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 065b7e6..5a690f1 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -367,7 +367,7 @@ static struct idmap_domain *idmap_passdb_domain(TALLOC_CTX *mem_ctx) * add_trusted_domain. */ -struct idmap_domain *idmap_find_domain(const char *domname) +static struct idmap_domain *idmap_find_domain(const char *domname) { struct idmap_domain *result; int i; diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 6ad46ae..04b1047 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -313,7 +313,6 @@ NTSTATUS winbindd_print_groupmembers(struct talloc_dict *members, void init_idmap_child(void); struct winbindd_child *idmap_child(void); -struct idmap_domain *idmap_find_domain(const char *domname); struct idmap_domain *idmap_find_domain_with_sid(const char *domname, const struct dom_sid *sid); -- 1.7.9.5 From 98a93035b1ec27db31ed2957503ee9c40fd259e6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 00:02:33 +0100 Subject: [PATCH 22/50] selftest:Samba3: call wait_for_start() from check_or_start() ...instead of calling the two one after another each time. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit f7dca55224af2cb2ac172831755246f5c9b04e0f) --- selftest/target/Samba3.pm | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 2b99419..ca5b1e2 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -201,10 +201,7 @@ sub setup_s3dc($$) $vars or return undef; - $self->check_or_start($vars, - "yes", "yes", "yes"); - - if (not $self->wait_for_start($vars)) { + if (not $self->check_or_start($vars, "yes", "yes", "yes")) { return undef; } @@ -247,9 +244,7 @@ sub setup_member($$$) return undef; } - $self->check_or_start($ret, "yes", "yes", "yes"); - - if (not $self->wait_for_start($ret)) { + if (not $self->check_or_start($ret, "yes", "yes", "yes")) { return undef; } @@ -320,10 +315,9 @@ sub setup_admember($$$$) # access the share for tests. chmod 0777, "$prefix/share"; - $self->check_or_start($ret, - "yes", "yes", "yes"); - - $self->wait_for_start($ret); + if (not $self->check_or_start($ret, "yes", "yes", "yes")) { + return undef; + } $ret->{DC_SERVER} = $dcvars->{SERVER}; $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP}; @@ -364,9 +358,7 @@ sub setup_simpleserver($$) $vars or return undef; - $self->check_or_start($vars, "yes", "no", "yes"); - - if (not $self->wait_for_start($vars)) { + if (not $self->check_or_start($vars, "yes", "no", "yes")) { return undef; } @@ -462,9 +454,7 @@ $ret->{USERNAME} = KTEST\\Administrator # access the share for tests. chmod 0777, "$prefix/share"; - $self->check_or_start($ret, "yes", "no", "yes"); - - if (not $self->wait_for_start($ret)) { + if (not $self->check_or_start($ret, "yes", "no", "yes")) { return undef; } return $ret; @@ -487,10 +477,7 @@ map to guest = bad user $vars or return undef; - $self->check_or_start($vars, - "yes", "no", "yes"); - - if (not $self->wait_for_start($vars)) { + if (not $self->check_or_start($vars, "yes", "no", "yes")) { return undef; } @@ -688,7 +675,7 @@ sub check_or_start($$$$$) { close(STDIN_READER); - return 0; + return $self->wait_for_start($env_vars); } sub provision($$$$$$) -- 1.7.9.5 From c5887673efb85b5652c97acab885fb714b5e2f6b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 00:09:43 +0100 Subject: [PATCH 23/50] selftest:Samba3: add nmbd, winbindd smbd arguments to wait_for_start() to make checks conditional Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 5b975ce78cc77bd9ff39e2ec0c2e7d674bf61ebe) --- selftest/target/Samba3.pm | 61 ++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index ca5b1e2..6c8939c 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -675,7 +675,7 @@ sub check_or_start($$$$$) { close(STDIN_READER); - return $self->wait_for_start($env_vars); + return $self->wait_for_start($env_vars, $nmbd, $winbindd, $smbd); } sub provision($$$$$$) @@ -1093,38 +1093,43 @@ domadmins:X:$gid_domadmins: return \%ret; } -sub wait_for_start($$) +sub wait_for_start($$$$$) { - my ($self, $envvars) = @_; - - # give time for nbt server to register its names - print "delaying for nbt name registration\n"; - sleep(10); - # This will return quickly when things are up, but be slow if we need to wait for (eg) SSL init - my $nmblookup = Samba::bindir_path($self, "nmblookup3"); - system("$nmblookup $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} __SAMBA__"); - system("$nmblookup $envvars->{CONFIGURATION} __SAMBA__"); - system("$nmblookup $envvars->{CONFIGURATION} -U 127.255.255.255 __SAMBA__"); - system("$nmblookup $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} $envvars->{SERVER}"); - system("$nmblookup $envvars->{CONFIGURATION} $envvars->{SERVER}"); + my ($self, $envvars, $nmbd, $winbindd, $smbd) = @_; + + if ($nmbd eq "yes") { + # give time for nbt server to register its names + print "delaying for nbt name registration\n"; + sleep(10); + # This will return quickly when things are up, but be slow if we need to wait for (eg) SSL init + my $nmblookup = Samba::bindir_path($self, "nmblookup3"); + system("$nmblookup $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} __SAMBA__"); + system("$nmblookup $envvars->{CONFIGURATION} __SAMBA__"); + system("$nmblookup $envvars->{CONFIGURATION} -U 127.255.255.255 __SAMBA__"); + system("$nmblookup $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} $envvars->{SERVER}"); + system("$nmblookup $envvars->{CONFIGURATION} $envvars->{SERVER}"); + } - # make sure smbd is also up set - print "wait for smbd\n"; + if ($smbd eq "yes") { + # make sure smbd is also up set + print "wait for smbd\n"; - my $count = 0; - my $ret; - do { - $ret = system(Samba::bindir_path($self, "smbclient3") ." $envvars->{CONFIGURATION} -L $envvars->{SERVER} -U% -p 139"); - if ($ret != 0) { - sleep(2); + my $count = 0; + my $ret; + do { + $ret = system(Samba::bindir_path($self, "smbclient3") ." $envvars->{CONFIGURATION} -L $envvars->{SERVER} -U% -p 139"); + if ($ret != 0) { + sleep(2); + } + $count++ + } while ($ret != 0 && $count < 10); + if ($count == 10) { + print "SMBD failed to start up in a reasonable time (20sec)\n"; + teardown_env($self, $envvars); + return 0; } - $count++ - } while ($ret != 0 && $count < 10); - if ($count == 10) { - print "SMBD failed to start up in a reasonable time (20sec)\n"; - teardown_env($self, $envvars); - return 0; } + # Ensure we have domain users mapped. $ret = system(Samba::bindir_path($self, "net") ." $envvars->{CONFIGURATION} groupmap add rid=513 unixgroup=domusers type=domain"); if ($ret != 0) { -- 1.7.9.5 From 4dbfb1a8847f1fc598e9a3f3c59ad0f10d4f40dc Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 00:18:44 +0100 Subject: [PATCH 24/50] selftest:Samba3: add "wbinfo -p" test to wait_for_start() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 11ca06338670c3aa1ad6928232f2c582116f42e8) --- selftest/target/Samba3.pm | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 6c8939c..3a0b9d9 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1096,6 +1096,7 @@ domadmins:X:$gid_domadmins: sub wait_for_start($$$$$) { my ($self, $envvars, $nmbd, $winbindd, $smbd) = @_; + my $ret; if ($nmbd eq "yes") { # give time for nbt server to register its names @@ -1110,12 +1111,28 @@ sub wait_for_start($$$$$) system("$nmblookup $envvars->{CONFIGURATION} $envvars->{SERVER}"); } + if ($winbindd eq "yes") { + print "checking for winbindd\n"; + my $count = 0; + do { + $ret = system("WINBINDD_SOCKET_DIR=" . $envvars->{WINBINDD_SOCKET_DIR} . " " . Samba::bindir_path($self, "wbinfo") . " -p"); + if ($ret != 0) { + sleep(2); + } + $count++; + } while ($ret != 0 && $count < 10); + if ($count == 10) { + print "WINBINDD not reachable after 20 seconds\n"; + teardown_env($self, $envvars); + return 0; + } + } + if ($smbd eq "yes") { # make sure smbd is also up set print "wait for smbd\n"; my $count = 0; - my $ret; do { $ret = system(Samba::bindir_path($self, "smbclient3") ." $envvars->{CONFIGURATION} -L $envvars->{SERVER} -U% -p 139"); if ($ret != 0) { -- 1.7.9.5 From afc66b927aa908f6e18ab3e7713a670edd2ddd6d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 01:35:30 +0100 Subject: [PATCH 25/50] selftest:Samba3: provision the BUILTIN\Users group if the environment runs winbindd Note that in order to create a local group (alias), the id-allocator of id-mapping is needed, so this can only work if winbindd is running. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 46f2dfa7a51487e1b21c329dfb2e4cac3e6ada11) --- selftest/target/Samba3.pm | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 3a0b9d9..2037a2e 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1157,6 +1157,30 @@ sub wait_for_start($$$$$) return 1; } + if ($winbindd eq "yes") { + # note: creating builtin groups requires winbindd for the + # unix id allocator + $ret = system("WINBINDD_SOCKET_DIR=" . $envvars->{WINBINDD_SOCKET_DIR} . " " . Samba::bindir_path($self, "net") ." $envvars->{CONFIGURATION} sam createbuiltingroup Users"); + if ($ret != 0) { + print "Failed to create BUILTIN\\Users group\n"; + return 0; + } + my $count = 0; + do { + system(Samba::bindir_path($self, "net") . " $envvars->{CONFIGURATION} cache flush"); + $ret = system("WINBINDD_SOCKET_DIR=" . $envvars->{WINBINDD_SOCKET_DIR} . " " . Samba::bindir_path($self, "wbinfo") . " --sid-to-gid=S-1-5-32-545"); + if ($ret != 0) { + sleep(2); + } + $count++; + } while ($ret != 0 && $count < 10); + if ($count == 10) { + print "WINBINDD not reachable after 20 seconds\n"; + teardown_env($self, $envvars); + return 0; + } + } + print $self->getlog_env($envvars); return 1; -- 1.7.9.5 From 52960a9590e53993d0606865856369028685ee78 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 16:40:48 +0100 Subject: [PATCH 26/50] s3:winbindd: change wb_fill_pwent to use wb_sids2xids instead of wb_sid2[ug]id We can optimize this later and just do one wb_sids2xids_send/recv call. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 55ea9210e9b9cbb5a8b4633f492920af7eda77ab) --- source3/winbindd/wb_fill_pwent.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/source3/winbindd/wb_fill_pwent.c b/source3/winbindd/wb_fill_pwent.c index 62b1b4a..a6a9013 100644 --- a/source3/winbindd/wb_fill_pwent.c +++ b/source3/winbindd/wb_fill_pwent.c @@ -54,7 +54,7 @@ struct tevent_req *wb_fill_pwent_send(TALLOC_CTX *mem_ctx, state->info = info; state->pw = pw; - subreq = wb_sid2uid_send(state, state->ev, &state->info->user_sid); + subreq = wb_sids2xids_send(state, state->ev, &state->info->user_sid, 1); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -69,14 +69,28 @@ static void wb_fill_pwent_sid2uid_done(struct tevent_req *subreq) struct wb_fill_pwent_state *state = tevent_req_data( req, struct wb_fill_pwent_state); NTSTATUS status; + struct unixid xid; - status = wb_sid2uid_recv(subreq, &state->pw->pw_uid); + status = wb_sids2xids_recv(subreq, &xid); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; } - subreq = wb_sid2gid_send(state, state->ev, &state->info->group_sid); + /* + * We are filtering further down in sids2xids, but that filtering + * depends on the actual type of the sid handed in (as determined + * by lookupsids). Here we need to filter for the type of object + * actually requested, in this case uid. + */ + if (!(xid.type == ID_TYPE_UID || xid.type == ID_TYPE_BOTH)) { + tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); + return; + } + + state->pw->pw_uid = (uid_t)xid.id; + + subreq = wb_sids2xids_send(state, state->ev, &state->info->group_sid, 1); if (tevent_req_nomem(subreq, req)) { return; } @@ -94,13 +108,27 @@ static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq) fstring user_name, output_username; char *mapped_name = NULL; NTSTATUS status; + struct unixid xid; - status = wb_sid2gid_recv(subreq, &state->pw->pw_gid); + status = wb_sids2xids_recv(subreq, &xid); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; } + /* + * We are filtering further down in sids2xids, but that filtering + * depends on the actual type of the sid handed in (as determined + * by lookupsids). Here we need to filter for the type of object + * actually requested, in this case uid. + */ + if (!(xid.type == ID_TYPE_GID || xid.type == ID_TYPE_BOTH)) { + tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); + return; + } + + state->pw->pw_gid = (gid_t)xid.id; + domain = find_domain_from_sid_noinit(&state->info->user_sid); if (domain == NULL) { tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); -- 1.7.9.5 From 4f2944053ed871b9625fa24e6b8695de79e4a0be Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 16:44:41 +0100 Subject: [PATCH 27/50] s3:winbindd: change wb_getgrsid to use wb_sids2xids instead of wb_sid2gid Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit eb0fca9b7b06a2aebce0da3031b1af313f0c8081) --- source3/winbindd/wb_getgrsid.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/source3/winbindd/wb_getgrsid.c b/source3/winbindd/wb_getgrsid.c index 7d7e56a..2097539 100644 --- a/source3/winbindd/wb_getgrsid.c +++ b/source3/winbindd/wb_getgrsid.c @@ -97,7 +97,7 @@ static void wb_getgrsid_lookupsid_done(struct tevent_req *subreq) return; } - subreq = wb_sid2gid_send(state, state->ev, &state->sid); + subreq = wb_sids2xids_send(state, state->ev, &state->sid, 1); if (tevent_req_nomem(subreq, req)) { return; } @@ -111,12 +111,27 @@ static void wb_getgrsid_sid2gid_done(struct tevent_req *subreq) struct wb_getgrsid_state *state = tevent_req_data( req, struct wb_getgrsid_state); NTSTATUS status; + struct unixid xid; - status = wb_sid2gid_recv(subreq, &state->gid); + status = wb_sids2xids_recv(subreq, &xid); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; } + + /* + * We are filtering further down in sids2xids, but that filtering + * depends on the actual type of the sid handed in (as determined + * by lookupsids). Here we need to filter for the type of object + * actually requested, in this case uid. + */ + if (!(xid.type == ID_TYPE_GID || xid.type == ID_TYPE_BOTH)) { + tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); + return; + } + + state->gid = (gid_t)xid.id; + subreq = wb_group_members_send(state, state->ev, &state->sid, state->type, state->max_nesting); if (tevent_req_nomem(subreq, req)) { -- 1.7.9.5 From 710c9540a829bb2f9b48c9287118212f6d6024dc Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 16:54:36 +0100 Subject: [PATCH 28/50] s3:winbindd: change winbindd_getgroups to use wb_sids2xids instead of wb_sid2gid Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 5e746768c8adf77551d7904f8534372f88475675) --- source3/winbindd/winbindd_getgroups.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/source3/winbindd/winbindd_getgroups.c b/source3/winbindd/winbindd_getgroups.c index a42986f..1774901 100644 --- a/source3/winbindd/winbindd_getgroups.c +++ b/source3/winbindd/winbindd_getgroups.c @@ -134,8 +134,8 @@ static void winbindd_getgroups_gettoken_done(struct tevent_req *subreq) state->num_gids = 0; state->next_sid = 1; - subreq = wb_sid2gid_send(state, state->ev, - &state->sids[state->next_sid]); + subreq = wb_sids2xids_send(state, state->ev, + &state->sids[state->next_sid], 1); if (tevent_req_nomem(subreq, req)) { return; } @@ -149,9 +149,18 @@ static void winbindd_getgroups_sid2gid_done(struct tevent_req *subreq) struct winbindd_getgroups_state *state = tevent_req_data( req, struct winbindd_getgroups_state); NTSTATUS status; + struct unixid xid; - status = wb_sid2gid_recv(subreq, &state->gids[state->num_gids]); + xid.type = ID_TYPE_NOT_SPECIFIED; + xid.id = UINT32_MAX; + + status = wb_sids2xids_recv(subreq, &xid); TALLOC_FREE(subreq); + if (xid.type == ID_TYPE_GID || xid.type == ID_TYPE_BOTH) { + state->gids[state->num_gids] = (gid_t)xid.id; + } else { + state->gids[state->num_gids] = (uid_t)-1; + } /* * In case of failure, just continue with the next gid @@ -166,8 +175,8 @@ static void winbindd_getgroups_sid2gid_done(struct tevent_req *subreq) return; } - subreq = wb_sid2gid_send(state, state->ev, - &state->sids[state->next_sid]); + subreq = wb_sids2xids_send(state, state->ev, + &state->sids[state->next_sid], 1); if (tevent_req_nomem(subreq, req)) { return; } -- 1.7.9.5 From e101b1baedf79d4018dc44d0fd01d182db829ef4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 17:05:01 +0100 Subject: [PATCH 29/50] s3:winbindd: remove now unused wb_sid2uid and wb_sid2gid modules Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit de2cf94719fa07847b9c1b8149144bb1e36ba403) --- source3/Makefile.in | 2 - source3/winbindd/wb_sid2gid.c | 167 ------------------------------------- source3/winbindd/wb_sid2uid.c | 165 ------------------------------------ source3/winbindd/winbindd_proto.h | 10 --- source3/wscript_build | 2 - 5 files changed, 346 deletions(-) delete mode 100644 source3/winbindd/wb_sid2gid.c delete mode 100644 source3/winbindd/wb_sid2uid.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 0a96b28..3ddfa5c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1394,8 +1394,6 @@ WINBINDD_OBJ1 = \ winbindd/wb_lookupsid.o \ winbindd/wb_lookupsids.o \ winbindd/wb_lookupname.o \ - winbindd/wb_sid2uid.o \ - winbindd/wb_sid2gid.o \ winbindd/wb_uid2sid.o \ winbindd/wb_gid2sid.o \ winbindd/wb_sids2xids.o \ diff --git a/source3/winbindd/wb_sid2gid.c b/source3/winbindd/wb_sid2gid.c deleted file mode 100644 index cb95191..0000000 --- a/source3/winbindd/wb_sid2gid.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - Unix SMB/CIFS implementation. - async sid2gid - Copyright (C) Volker Lendecke 2009 - - 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 - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "winbindd.h" -#include "librpc/gen_ndr/ndr_wbint_c.h" -#include "idmap_cache.h" -#include "../libcli/security/security.h" - -struct wb_sid2gid_state { - struct tevent_context *ev; - struct dom_sid sid; - char *dom_name; - uint64 gid64; - gid_t gid; -}; - -static void wb_sid2gid_lookup_done(struct tevent_req *subreq); -static void wb_sid2gid_done(struct tevent_req *subreq); - - -struct tevent_req *wb_sid2gid_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - const struct dom_sid *sid) -{ - struct tevent_req *req, *subreq; - struct wb_sid2gid_state *state; - bool expired; - - req = tevent_req_create(mem_ctx, &state, struct wb_sid2gid_state); - if (req == NULL) { - return NULL; - } - sid_copy(&state->sid, sid); - state->ev = ev; - - if (winbindd_use_idmap_cache() - && idmap_cache_find_sid2gid(sid, &state->gid, &expired)) { - - DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n", - (int)state->gid, expired ? " (expired)": "")); - - if (!expired || is_domain_offline(find_our_domain())) { - if (state->gid == -1) { - tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); - } else { - tevent_req_done(req); - } - return tevent_req_post(req, ev); - } - } - - /* - * We need to make sure the sid is of the right type to not flood - * idmap with wrong entries - */ - - subreq = wb_lookupsid_send(state, ev, &state->sid); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, wb_sid2gid_lookup_done, req); - return req; -} - -static void wb_sid2gid_lookup_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_sid2gid_state *state = tevent_req_data( - req, struct wb_sid2gid_state); - struct winbindd_domain *domain; - const char *domname; - const char *name; - enum lsa_SidType type; - NTSTATUS status; - struct winbindd_child *child; - - status = wb_lookupsid_recv(subreq, talloc_tos(), &type, &domname, - &name); - if (tevent_req_nterror(req, status)) { - return; - } - - if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) - && (type != SID_NAME_WKN_GRP)) { - DEBUG(5, ("Sid %s is not a group.\n", - sid_string_dbg(&state->sid))); - /* - * We have to set the cache ourselves here, the child - * which is normally responsible was not queried yet. - */ - idmap_cache_set_sid2gid(&state->sid, -1); - tevent_req_nterror(req, NT_STATUS_INVALID_SID); - return; - } - - domain = find_domain_from_sid_noinit(&state->sid); - - /* - * TODO: Issue a gettrustinfo here in case we don't have "domain" yet? - */ - - if ((domain != NULL) && domain->have_idmap_config) { - state->dom_name = domain->name; - } else { - state->dom_name = NULL; - } - - child = idmap_child(); - - subreq = dcerpc_wbint_Sid2Gid_send(state, state->ev, child->binding_handle, - state->dom_name, &state->sid, - &state->gid64); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, wb_sid2gid_done, req); -} - -static void wb_sid2gid_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_sid2gid_state *state = tevent_req_data( - req, struct wb_sid2gid_state); - NTSTATUS status, result; - - status = dcerpc_wbint_Sid2Gid_recv(subreq, state, &result); - TALLOC_FREE(subreq); - if (any_nt_status_not_ok(status, result, &status)) { - tevent_req_nterror(req, status); - return; - } - - state->gid = state->gid64; - tevent_req_done(req); -} - -NTSTATUS wb_sid2gid_recv(struct tevent_req *req, gid_t *gid) -{ - struct wb_sid2gid_state *state = tevent_req_data( - req, struct wb_sid2gid_state); - NTSTATUS status; - - if (tevent_req_is_nterror(req, &status)) { - return status; - } - *gid = state->gid; - return NT_STATUS_OK; -} diff --git a/source3/winbindd/wb_sid2uid.c b/source3/winbindd/wb_sid2uid.c deleted file mode 100644 index a2e0f97..0000000 --- a/source3/winbindd/wb_sid2uid.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - Unix SMB/CIFS implementation. - async sid2uid - Copyright (C) Volker Lendecke 2009 - - 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 - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "winbindd.h" -#include "librpc/gen_ndr/ndr_wbint_c.h" -#include "idmap_cache.h" -#include "../libcli/security/security.h" - -struct wb_sid2uid_state { - struct tevent_context *ev; - struct dom_sid sid; - char *dom_name; - uint64 uid64; - uid_t uid; -}; - -static void wb_sid2uid_lookup_done(struct tevent_req *subreq); -static void wb_sid2uid_done(struct tevent_req *subreq); - -struct tevent_req *wb_sid2uid_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - const struct dom_sid *sid) -{ - struct tevent_req *req, *subreq; - struct wb_sid2uid_state *state; - bool expired; - - req = tevent_req_create(mem_ctx, &state, struct wb_sid2uid_state); - if (req == NULL) { - return NULL; - } - sid_copy(&state->sid, sid); - state->ev = ev; - - if (winbindd_use_idmap_cache() - && idmap_cache_find_sid2uid(sid, &state->uid, &expired)) { - - DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n", - (int)state->uid, expired ? " (expired)": "")); - - if (!expired || is_domain_offline(find_our_domain())) { - if (state->uid == -1) { - tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); - } else { - tevent_req_done(req); - } - return tevent_req_post(req, ev); - } - } - - /* - * We need to make sure the sid is of the right type to not flood - * idmap with wrong entries - */ - - subreq = wb_lookupsid_send(state, ev, &state->sid); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, wb_sid2uid_lookup_done, req); - return req; -} - -static void wb_sid2uid_lookup_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_sid2uid_state *state = tevent_req_data( - req, struct wb_sid2uid_state); - struct winbindd_domain *domain; - const char *domname; - const char *name; - enum lsa_SidType type; - NTSTATUS status; - struct winbindd_child *child; - - status = wb_lookupsid_recv(subreq, talloc_tos(), &type, &domname, - &name); - if (tevent_req_nterror(req, status)) { - return; - } - - if ((type != SID_NAME_USER) && (type != SID_NAME_COMPUTER)) { - DEBUG(5, ("Sid %s is not a user or a computer.\n", - sid_string_dbg(&state->sid))); - /* - * We have to set the cache ourselves here, the child - * which is normally responsible was not queried yet. - */ - idmap_cache_set_sid2uid(&state->sid, -1); - tevent_req_nterror(req, NT_STATUS_INVALID_SID); - return; - } - - domain = find_domain_from_sid_noinit(&state->sid); - - /* - * TODO: Issue a gettrustinfo here in case we don't have "domain" yet? - */ - - if ((domain != NULL) && domain->have_idmap_config) { - state->dom_name = domain->name; - } else { - state->dom_name = NULL; - } - - child = idmap_child(); - - subreq = dcerpc_wbint_Sid2Uid_send(state, state->ev, child->binding_handle, - state->dom_name, &state->sid, - &state->uid64); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, wb_sid2uid_done, req); -} - -static void wb_sid2uid_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct wb_sid2uid_state *state = tevent_req_data( - req, struct wb_sid2uid_state); - NTSTATUS status, result; - - status = dcerpc_wbint_Sid2Uid_recv(subreq, state, &result); - TALLOC_FREE(subreq); - if (any_nt_status_not_ok(status, result, &status)) { - tevent_req_nterror(req, status); - return; - } - - state->uid = state->uid64; - tevent_req_done(req); -} - -NTSTATUS wb_sid2uid_recv(struct tevent_req *req, uid_t *uid) -{ - struct wb_sid2uid_state *state = tevent_req_data( - req, struct wb_sid2uid_state); - NTSTATUS status; - - if (tevent_req_is_nterror(req, &status)) { - return status; - } - *uid = state->uid; - return NT_STATUS_OK; -} diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 04b1047..909b06f 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -492,11 +492,6 @@ struct tevent_req *winbindd_lookupname_send(TALLOC_CTX *mem_ctx, NTSTATUS winbindd_lookupname_recv(struct tevent_req *req, struct winbindd_response *response); -struct tevent_req *wb_sid2uid_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - const struct dom_sid *sid); -NTSTATUS wb_sid2uid_recv(struct tevent_req *req, uid_t *uid); - struct tevent_req *winbindd_sid_to_uid_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct winbindd_cli_state *cli, @@ -504,11 +499,6 @@ struct tevent_req *winbindd_sid_to_uid_send(TALLOC_CTX *mem_ctx, NTSTATUS winbindd_sid_to_uid_recv(struct tevent_req *req, struct winbindd_response *response); -struct tevent_req *wb_sid2gid_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - const struct dom_sid *sid); -NTSTATUS wb_sid2gid_recv(struct tevent_req *req, gid_t *gid); - struct tevent_req *winbindd_sid_to_gid_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct winbindd_cli_state *cli, diff --git a/source3/wscript_build b/source3/wscript_build index c8f4f69..49e023c 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -265,8 +265,6 @@ WINBINDD_SRC1 = '''winbindd/winbindd.c winbindd/wb_lookupsid.c winbindd/wb_lookupsids.c winbindd/wb_lookupname.c - winbindd/wb_sid2uid.c - winbindd/wb_sid2gid.c winbindd/wb_uid2sid.c winbindd/wb_gid2sid.c winbindd/wb_sids2xids.c -- 1.7.9.5 From a9bf76cf299a8b0ba1e81540192d2ef77e586d93 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 17:48:36 +0100 Subject: [PATCH 30/50] s3:winbindd: remove wbint_Sid2Uid() from the wbint.idl Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 8b73556e3f583af0a073a743f4973967aa5ad004) --- source3/librpc/idl/wbint.idl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source3/librpc/idl/wbint.idl b/source3/librpc/idl/wbint.idl index c836f0f..035afb5 100644 --- a/source3/librpc/idl/wbint.idl +++ b/source3/librpc/idl/wbint.idl @@ -37,12 +37,6 @@ interface wbint [out] dom_sid *sid ); - NTSTATUS wbint_Sid2Uid( - [in,unique,string,charset(UTF8)] char *dom_name, - [in] dom_sid *sid, - [out] hyper *uid - ); - NTSTATUS wbint_Sid2Gid( [in,unique,string,charset(UTF8)] char *dom_name, [in] dom_sid *sid, -- 1.7.9.5 From cc17e73e52fe25123f20062bc2cc90da79644ccd Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 17:49:09 +0100 Subject: [PATCH 31/50] s3:winbindd: remove wbint_Sid2Gid from the wbint.idl Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit aa771618718378bc3449b1caa78d1d942ff937c4) --- source3/librpc/idl/wbint.idl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source3/librpc/idl/wbint.idl b/source3/librpc/idl/wbint.idl index 035afb5..f05107a 100644 --- a/source3/librpc/idl/wbint.idl +++ b/source3/librpc/idl/wbint.idl @@ -37,12 +37,6 @@ interface wbint [out] dom_sid *sid ); - NTSTATUS wbint_Sid2Gid( - [in,unique,string,charset(UTF8)] char *dom_name, - [in] dom_sid *sid, - [out] hyper *gid - ); - typedef struct { id_type type; uint32 domain_index; -- 1.7.9.5 From b739e7445697a53a4fceb1cb7581a7713b0f28c2 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 17:50:11 +0100 Subject: [PATCH 32/50] s3:winbindd: remove unused server implementation of wbint_Sid2Uid() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit c927ff4b3641e10369f9e17b20d92d3148f55633) --- source3/winbindd/winbindd_dual_srv.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 6600082..914647e 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -108,20 +108,6 @@ NTSTATUS _wbint_LookupName(struct pipes_struct *p, struct wbint_LookupName *r) return status; } -NTSTATUS _wbint_Sid2Uid(struct pipes_struct *p, struct wbint_Sid2Uid *r) -{ - uid_t uid; - NTSTATUS status; - - status = idmap_sid_to_uid(r->in.dom_name ? r->in.dom_name : "", - r->in.sid, &uid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - *r->out.uid = uid; - return NT_STATUS_OK; -} - NTSTATUS _wbint_Sid2Gid(struct pipes_struct *p, struct wbint_Sid2Gid *r) { gid_t gid; -- 1.7.9.5 From 14d37cefa1acd40f9a54ced6202a62c68e0da8e0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 17:50:50 +0100 Subject: [PATCH 33/50] s3:winbindd: remove unused server implementation of wbint_Sid2Gid() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit b47be53a1f68735b1a95d57781eaf9beea68481b) --- source3/winbindd/winbindd_dual_srv.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 914647e..5344063 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -108,20 +108,6 @@ NTSTATUS _wbint_LookupName(struct pipes_struct *p, struct wbint_LookupName *r) return status; } -NTSTATUS _wbint_Sid2Gid(struct pipes_struct *p, struct wbint_Sid2Gid *r) -{ - gid_t gid; - NTSTATUS status; - - status = idmap_sid_to_gid(r->in.dom_name ? r->in.dom_name : "", - r->in.sid, &gid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - *r->out.gid = gid; - return NT_STATUS_OK; -} - NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p, struct wbint_Sids2UnixIDs *r) { -- 1.7.9.5 From ec8a9a71aa0b9e95cb824abe1c9df942e9e3a711 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 17:53:04 +0100 Subject: [PATCH 34/50] s3:winbindd: remove unused idmap_sid_to_uid() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 5f7a3720036c422142774ce49147328dc784fec8) --- source3/winbindd/idmap_proto.h | 1 - source3/winbindd/idmap_util.c | 74 ---------------------------------------- 2 files changed, 75 deletions(-) diff --git a/source3/winbindd/idmap_proto.h b/source3/winbindd/idmap_proto.h index 4fa9ed1..c6f76bd 100644 --- a/source3/winbindd/idmap_proto.h +++ b/source3/winbindd/idmap_proto.h @@ -55,7 +55,6 @@ NTSTATUS idmap_tdb_init(void); NTSTATUS idmap_uid_to_sid(const char *domname, struct dom_sid *sid, uid_t uid); NTSTATUS idmap_gid_to_sid(const char *domname, struct dom_sid *sid, gid_t gid); -NTSTATUS idmap_sid_to_uid(const char *dom_name, struct dom_sid *sid, uid_t *uid); NTSTATUS idmap_sid_to_gid(const char *domname, struct dom_sid *sid, gid_t *gid); bool idmap_unix_id_is_in_range(uint32_t id, struct idmap_domain *dom); diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c index 8e9d468..7acef8d 100644 --- a/source3/winbindd/idmap_util.c +++ b/source3/winbindd/idmap_util.c @@ -155,80 +155,6 @@ backend: } /***************************************************************** - Returns the UID mapped to the given SID. - If mapping is not possible or SID maps to a GID returns an error. -*****************************************************************/ - -NTSTATUS idmap_sid_to_uid(const char *dom_name, struct dom_sid *sid, uid_t *uid) -{ - NTSTATUS ret; - struct id_map map; - bool expired; - - DEBUG(10,("idmap_sid_to_uid: sid = [%s], domain = '%s'\n", - sid_string_dbg(sid), dom_name)); - - if (winbindd_use_idmap_cache() - && idmap_cache_find_sid2uid(sid, uid, &expired)) { - DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n", - (int)(*uid), expired ? " (expired)": "")); - if (expired && idmap_is_online()) { - DEBUG(10, ("revalidating expired entry\n")); - goto backend; - } - if ((*uid) == -1) { - DEBUG(10, ("Returning negative cache entry\n")); - return NT_STATUS_NONE_MAPPED; - } - DEBUG(10, ("Returning positive cache entry\n")); - return NT_STATUS_OK; - } - -backend: - ZERO_STRUCT(map); - map.sid = sid; - map.xid.type = ID_TYPE_UID; - - ret = idmap_backends_sid_to_unixid(dom_name, &map); - - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(10, ("idmap_backends_sid_to_unixid failed: %s\n", - nt_errstr(ret))); - if (winbindd_use_idmap_cache()) { - idmap_cache_set_sid2uid(sid, -1); - } - return ret; - } - - if (map.status != ID_MAPPED) { - DEBUG(10, ("sid [%s] is not mapped\n", sid_string_dbg(sid))); - if (winbindd_use_idmap_cache()) { - idmap_cache_set_sid2uid(sid, -1); - } - return NT_STATUS_NONE_MAPPED; - } - - if (map.xid.type != ID_TYPE_UID) { - DEBUG(10, ("sid [%s] not mapped to a uid " - "[%u,%u,%u]\n", - sid_string_dbg(sid), - map.status, - map.xid.type, - map.xid.id)); - if (winbindd_use_idmap_cache()) { - idmap_cache_set_sid2uid(sid, -1); - } - return NT_STATUS_NONE_MAPPED; - } - - *uid = (uid_t)map.xid.id; - if (winbindd_use_idmap_cache()) { - idmap_cache_set_sid2unixid(sid, &map.xid); - } - return NT_STATUS_OK; -} - -/***************************************************************** Returns the GID mapped to the given SID. If mapping is not possible or SID maps to a UID returns an error. *****************************************************************/ -- 1.7.9.5 From 8db4d6c6992b61ea9c44d3b4e13e054d8f86a9ef Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 23 Nov 2012 17:53:39 +0100 Subject: [PATCH 35/50] s3:winbindd: remove unused idmap_sid_to_gid() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit c408126b47b0ce496a8b2293a8481d439b4234cf) --- source3/winbindd/idmap_proto.h | 1 - source3/winbindd/idmap_util.c | 74 ---------------------------------------- 2 files changed, 75 deletions(-) diff --git a/source3/winbindd/idmap_proto.h b/source3/winbindd/idmap_proto.h index c6f76bd..6b3d8cf 100644 --- a/source3/winbindd/idmap_proto.h +++ b/source3/winbindd/idmap_proto.h @@ -55,7 +55,6 @@ NTSTATUS idmap_tdb_init(void); NTSTATUS idmap_uid_to_sid(const char *domname, struct dom_sid *sid, uid_t uid); NTSTATUS idmap_gid_to_sid(const char *domname, struct dom_sid *sid, gid_t gid); -NTSTATUS idmap_sid_to_gid(const char *domname, struct dom_sid *sid, gid_t *gid); bool idmap_unix_id_is_in_range(uint32_t id, struct idmap_domain *dom); #endif /* _WINBINDD_IDMAP_PROTO_H_ */ diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c index 7acef8d..9d9ada7 100644 --- a/source3/winbindd/idmap_util.c +++ b/source3/winbindd/idmap_util.c @@ -154,80 +154,6 @@ backend: return NT_STATUS_OK; } -/***************************************************************** - Returns the GID mapped to the given SID. - If mapping is not possible or SID maps to a UID returns an error. -*****************************************************************/ - -NTSTATUS idmap_sid_to_gid(const char *domname, struct dom_sid *sid, gid_t *gid) -{ - NTSTATUS ret; - struct id_map map; - bool expired; - - DEBUG(10,("idmap_sid_to_gid: sid = [%s], domain = '%s'\n", - sid_string_dbg(sid), domname)); - - if (winbindd_use_idmap_cache() - && idmap_cache_find_sid2gid(sid, gid, &expired)) { - DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n", - (int)(*gid), expired ? " (expired)": "")); - if (expired && idmap_is_online()) { - DEBUG(10, ("revalidating expired entry\n")); - goto backend; - } - if ((*gid) == -1) { - DEBUG(10, ("Returning negative cache entry\n")); - return NT_STATUS_NONE_MAPPED; - } - DEBUG(10, ("Returning positive cache entry\n")); - return NT_STATUS_OK; - } - -backend: - ZERO_STRUCT(map); - map.sid = sid; - map.xid.type = ID_TYPE_GID; - - ret = idmap_backends_sid_to_unixid(domname, &map); - - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(10, ("idmap_backends_sid_to_unixid failed: %s\n", - nt_errstr(ret))); - if (winbindd_use_idmap_cache()) { - idmap_cache_set_sid2gid(sid, -1); - } - return ret; - } - - if (map.status != ID_MAPPED) { - DEBUG(10, ("sid [%s] is not mapped\n", sid_string_dbg(sid))); - if (winbindd_use_idmap_cache()) { - idmap_cache_set_sid2gid(sid, -1); - } - return NT_STATUS_NONE_MAPPED; - } - - if (map.xid.type != ID_TYPE_GID) { - DEBUG(10, ("sid [%s] not mapped to a gid " - "[%u,%u,%u]\n", - sid_string_dbg(sid), - map.status, - map.xid.type, - map.xid.id)); - if (winbindd_use_idmap_cache()) { - idmap_cache_set_sid2gid(sid, -1); - } - return NT_STATUS_NONE_MAPPED; - } - - *gid = map.xid.id; - if (winbindd_use_idmap_cache()) { - idmap_cache_set_sid2unixid(sid, &map.xid); - } - return NT_STATUS_OK; -} - /** * check whether a given unix id is inside the filter range of an idmap domain */ -- 1.7.9.5 From 4535504623e4378ec568a5f3ee7c10aa906dd7ea Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 15 Oct 2012 16:32:25 +0200 Subject: [PATCH 36/50] s3:idmap_rid: force mapping type to ID_TYPE_BOTH for sid->unixid mapping This is to remove problems with the same unix-id being used both as a uid and a gid. The rid backend will map a given number to the same SID, no matter whether this is a uid or a gid. This will prime the idmap cache with mappings. The sid-to-u/gid mapping, when not going through the cache, instead checks for the type of the sid and only allows unix ids of the corresponding type. Hence the rid backend will give different results, depending on whether the cache is filled or not. This patch lets the rid backend always create sid->id mappings of type both. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 55607f0f334ca5d72f35eb6b259db5283b35e86a) --- source3/winbindd/idmap_rid.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/winbindd/idmap_rid.c b/source3/winbindd/idmap_rid.c index 4112fb8..f10f493 100644 --- a/source3/winbindd/idmap_rid.c +++ b/source3/winbindd/idmap_rid.c @@ -92,6 +92,7 @@ static NTSTATUS idmap_rid_id_to_sid(struct idmap_domain *dom, struct id_map *map that is a deficiency in the idmap_rid design. */ map->status = ID_MAPPED; + map->xid.type = ID_TYPE_BOTH; return NT_STATUS_OK; } @@ -109,6 +110,7 @@ static NTSTATUS idmap_rid_sid_to_id(struct idmap_domain *dom, struct id_map *map sid_peek_rid(map->sid, &rid); map->xid.id = rid - ctx->base_rid + dom->low_id; + map->xid.type = ID_TYPE_BOTH; /* apply filters before returning result */ -- 1.7.9.5 From 5dd2640fb50b173bb079b33c4716e1fa5e28e3c6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 15 Oct 2012 16:34:02 +0200 Subject: [PATCH 37/50] s3:idmap_autorid: force mapping type to ID_TYPE_BOTH for sid->unixid mapping This is to remove problems with the same unix-id being used both as a uid and a gid. The autorid backend will map a given number to the same SID, no matter whether this is a uid or a gid. This will prime the idmap cache with mappings. The sid-to-u/gid mapping, when not going through the cache, instead checks for the type of the sid and only allows unix ids of the corresponding type. Hence the rid backend will give different results, depending on whether the cache is filled or not. This patch lets the autorid backend always create sid->id mappings of type both. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit a1411a884c5361bb8b090695236724cd25857269) --- source3/winbindd/idmap_autorid.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c index 3f3f649..621cae9 100644 --- a/source3/winbindd/idmap_autorid.c +++ b/source3/winbindd/idmap_autorid.c @@ -309,6 +309,8 @@ static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg, that is a deficiency in the idmap_rid design. */ map->status = ID_MAPPED; + map->xid.type = ID_TYPE_BOTH; + return NT_STATUS_OK; } @@ -333,6 +335,7 @@ static NTSTATUS idmap_autorid_sid_to_id(struct autorid_global_config *global, } map->xid.id = global->minvalue + (global->rangesize * domain->domainnum)+rid; + map->xid.type = ID_TYPE_BOTH; /* We **really** should have some way of validating the SID exists and is the correct type here. But -- 1.7.9.5 From aac7e61ebedbc1d86ad51eb24289ce72e8e1d28b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 27 Nov 2012 22:43:04 +0100 Subject: [PATCH 38/50] s3:test: fix intialization of WBINFO in test_wbinfo_sids2xids.sh Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 25018d8ae6de32a2a51168a30788545646fddcae) --- source3/script/tests/test_wbinfo_sids2xids.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/script/tests/test_wbinfo_sids2xids.sh b/source3/script/tests/test_wbinfo_sids2xids.sh index 5bb33ee..99d066f 100755 --- a/source3/script/tests/test_wbinfo_sids2xids.sh +++ b/source3/script/tests/test_wbinfo_sids2xids.sh @@ -1,6 +1,6 @@ #!/bin/sh -WBINFO="$VALGRIND ${NET:-$BINDIR/wbinfo} $CONFIGURATION" +WBINFO="$VALGRIND ${WBINFO:-$BINDIR/wbinfo} $CONFIGURATION" TEST_INT=`dirname $0`/test_wbinfo_sids2xids_int.py incdir=`dirname $0`/../../../testprogs/blackbox -- 1.7.9.5 From 591a80f7a841fbf544d711e4de1fd6cf760085e7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 27 Nov 2012 12:08:33 +0100 Subject: [PATCH 39/50] s3:test:wbinfo_sids2xids: test the results with singular calls with filled and with empty cache Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 7f2f29647a5d5906db5a267f614f30607d9162e3) --- source3/script/tests/test_wbinfo_sids2xids.sh | 3 +- source3/script/tests/test_wbinfo_sids2xids_int.py | 37 +++++++++++++++------ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/source3/script/tests/test_wbinfo_sids2xids.sh b/source3/script/tests/test_wbinfo_sids2xids.sh index 99d066f..c500605 100755 --- a/source3/script/tests/test_wbinfo_sids2xids.sh +++ b/source3/script/tests/test_wbinfo_sids2xids.sh @@ -1,11 +1,12 @@ #!/bin/sh WBINFO="$VALGRIND ${WBINFO:-$BINDIR/wbinfo} $CONFIGURATION" +NET="$VALGRIND ${NET:-$BINDIR/net} $CONFIGURATION" TEST_INT=`dirname $0`/test_wbinfo_sids2xids_int.py incdir=`dirname $0`/../../../testprogs/blackbox . $incdir/subunit.sh -testit "sids2xids" ${TEST_INT} ${WBINFO} || failed=`expr $failed + 1` +testit "sids2xids" ${TEST_INT} ${WBINFO} ${NET} || failed=`expr $failed + 1` testok $0 $failed diff --git a/source3/script/tests/test_wbinfo_sids2xids_int.py b/source3/script/tests/test_wbinfo_sids2xids_int.py index 87db0ef..8826f53 100755 --- a/source3/script/tests/test_wbinfo_sids2xids_int.py +++ b/source3/script/tests/test_wbinfo_sids2xids_int.py @@ -2,11 +2,17 @@ import sys,os,subprocess -if len(sys.argv) != 2: - print "Usage: test_wbinfo_sids2xids_int.py wbinfo" + +if len(sys.argv) != 3: + print "Usage: test_wbinfo_sids2xids_int.py wbinfo net" sys.exit(1) wbinfo = sys.argv[1] +netcmd = sys.argv[2] + +def flush_cache(): + os.system(netcmd + "cache flush") + domain = subprocess.Popen([wbinfo, "--own-domain"], stdout=subprocess.PIPE).communicate()[0].strip() domsid = subprocess.Popen([wbinfo, "-n", domain + "\\"], @@ -18,6 +24,8 @@ domsid = domsid.split(' ')[0] sids=[ domsid + '-512', 'S-1-5-32-545', domsid + '-513' ] +flush_cache + sids2xids = subprocess.Popen([wbinfo, '--sids-to-unix-ids=' + ','.join(sids)], stdout=subprocess.PIPE).communicate()[0].strip() @@ -34,14 +42,23 @@ for line in sids2xids.split('\n'): gid = '' gids.append(gid) -i=0 +# Check the list produced by the sids-to-xids call with the +# singular variant (sid-to-gid) for each sid in turn. +def check_singular(sids, gids): + i=0 + for sid in sids: + gid = subprocess.Popen([wbinfo, '--sid-to-gid', sid], + stdout=subprocess.PIPE).communicate()[0].strip() + if gid != gids[i]: + print "Expected %s, got %s\n", gid, gids[i] + sys.exit(1) + i+=1 + +# first round: with filled cache +check_singular(sids, gids) -for sid in sids: - gid = subprocess.Popen([wbinfo, '--sid-to-gid', sid], - stdout=subprocess.PIPE).communicate()[0].strip() - if gid != gids[i]: - print "Expected %s, got %s\n", gid, gids[i] - sys.exit(1) - i+=1 +# second round: with empty cache +flush_cache +check_singular(sids, gids) sys.exit(0) -- 1.7.9.5 From 63ebc986454e3bba65f7e010c0aa9639e9f773c7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 30 Nov 2012 15:27:15 +0100 Subject: [PATCH 40/50] s3:winbindd: remove unused function idmap_backends_sid_to_unixid() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit e3ee3971403c7dac4e8e3578a60973b97451af68) --- source3/winbindd/idmap.c | 41 ---------------------------------------- source3/winbindd/idmap_proto.h | 2 -- 2 files changed, 43 deletions(-) diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index 5a690f1..ae4fb2b 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -513,44 +513,3 @@ NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id) return dom->methods->unixids_to_sids(dom, maps); } - -NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id) -{ - struct idmap_domain *dom; - struct id_map *maps[2]; - - DEBUG(10, ("idmap_backends_sid_to_unixid: domain = '%s', sid = [%s]\n", - domain?domain:"NULL", sid_string_dbg(id->sid))); - - maps[0] = id; - maps[1] = NULL; - - if (sid_check_is_in_builtin(id->sid) - || (sid_check_is_in_our_sam(id->sid))) - { - NTSTATUS status; - - DEBUG(10, ("asking passdb...\n")); - - dom = idmap_passdb_domain(NULL); - if (dom == NULL) { - return NT_STATUS_NONE_MAPPED; - } - status = dom->methods->sids_to_unixids(dom, maps); - - if (NT_STATUS_IS_OK(status) && id->status == ID_MAPPED) { - return status; - } - - DEBUG(10, ("passdb could not map.\n")); - - return NT_STATUS_NONE_MAPPED; - } - - dom = idmap_find_domain(domain); - if (dom == NULL) { - return NT_STATUS_NONE_MAPPED; - } - - return dom->methods->sids_to_unixids(dom, maps); -} diff --git a/source3/winbindd/idmap_proto.h b/source3/winbindd/idmap_proto.h index 6b3d8cf..892b258 100644 --- a/source3/winbindd/idmap_proto.h +++ b/source3/winbindd/idmap_proto.h @@ -36,8 +36,6 @@ NTSTATUS idmap_allocate_uid(struct unixid *id); NTSTATUS idmap_allocate_gid(struct unixid *id); NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id); -NTSTATUS idmap_backends_sid_to_unixid(const char *domname, - struct id_map *id); /* The following definitions come from winbindd/idmap_nss.c */ -- 1.7.9.5 From 5703f2684ae05fb530762443d79304877f1a0532 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 30 Nov 2012 12:27:00 +0100 Subject: [PATCH 41/50] s3:lib: add utility function sid_check_is_for_passdb() This function checks whether the given sid should be treated by passdb (e.g. for id mapping). Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit fecdf48aaf514e6cda5cd0412d7407319a3ff89f) --- source3/lib/util_sid_passdb.c | 72 +++++++++++++++++++++++++++++++++++++++++ source3/lib/util_sid_passdb.h | 30 +++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 source3/lib/util_sid_passdb.c create mode 100644 source3/lib/util_sid_passdb.h diff --git a/source3/lib/util_sid_passdb.c b/source3/lib/util_sid_passdb.c new file mode 100644 index 0000000..4378d0f --- /dev/null +++ b/source3/lib/util_sid_passdb.c @@ -0,0 +1,72 @@ +/* + Unix SMB/CIFS implementation. + sid utility functions + + 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "includes.h" +#include "lib/util_sid_passdb.h" +#include "passdb/machine_sid.h" + +/** + * check whether this is an object- or domain-sid that should + * be treated by the passdb, e.g. for id-mapping. + */ +bool sid_check_is_for_passdb(const struct dom_sid *sid) +{ + if (sid_check_is_our_sam(sid)) { + return true; + } + + if (sid_check_is_in_our_sam(sid)) { + return true; + } + + if (sid_check_is_builtin(sid)) { + return true; + } + + if (sid_check_is_in_builtin(sid)) { + return true; + } + + if (sid_check_is_wellknown_domain(sid, NULL)) { + return true; + } + + if (sid_check_is_in_wellknown_domain(sid)) { + return true; + } + + if (sid_check_is_unix_users(sid)) { + return true; + } + + if (sid_check_is_in_unix_users(sid)) { + return true; + } + + if (sid_check_is_unix_groups(sid)) { + return true; + } + + if (sid_check_is_in_unix_groups(sid)) { + return true; + } + + return false; +} diff --git a/source3/lib/util_sid_passdb.h b/source3/lib/util_sid_passdb.h new file mode 100644 index 0000000..bd62e9e --- /dev/null +++ b/source3/lib/util_sid_passdb.h @@ -0,0 +1,30 @@ +/* + Unix SMB/CIFS implementation. + sid utility functions + + 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#ifndef __LIB_UTIL_SID_PASSDB_H__ +#define __LIB_UTIL_SID_PASSDB_H__ + +/** + * check whether this is an object- or domain-sid that should + * be treated by the passdb, e.g. for id-mapping. + */ +bool sid_check_is_for_passdb(const struct dom_sid *sid); + +#endif /* __LIB_UTIL_SID_PASSDB_H__ */ -- 1.7.9.5 From 8cc7f509d58317b89cbfe8558234c91ae2f2e79b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 30 Nov 2012 16:26:28 +0100 Subject: [PATCH 42/50] build the new sid_check_is_for_passdb() function into passdb Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 845a14210729c6a4c39a65be00e2f8b19fc13ec0) --- source3/Makefile.in | 1 + source3/passdb/ABI/pdb-0.sigs | 1 + source3/wscript_build | 1 + 3 files changed, 3 insertions(+) diff --git a/source3/Makefile.in b/source3/Makefile.in index 3ddfa5c..4424306 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -823,6 +823,7 @@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ lib/util_wellknown.o lib/util_builtin.o passdb/pdb_compat.o \ + lib/util_sid_passdb.o \ lib/util_unixsids.o passdb/lookup_sid.o \ passdb/login_cache.o @PDB_STATIC@ \ passdb/account_pol.o $(PRIVILEGES_OBJ) \ diff --git a/source3/passdb/ABI/pdb-0.sigs b/source3/passdb/ABI/pdb-0.sigs index bc82ff3..47d9423 100644 --- a/source3/passdb/ABI/pdb-0.sigs +++ b/source3/passdb/ABI/pdb-0.sigs @@ -256,6 +256,7 @@ samu_new: struct samu *(TALLOC_CTX *) samu_set_unix: NTSTATUS (struct samu *, const struct passwd *) secrets_trusted_domains: NTSTATUS (TALLOC_CTX *, uint32_t *, struct trustdom_info ***) sid_check_is_builtin: bool (const struct dom_sid *) +sid_check_is_for_passdb: bool (const struct dom_sid *) sid_check_is_in_builtin: bool (const struct dom_sid *) sid_check_is_in_unix_groups: bool (const struct dom_sid *) sid_check_is_in_unix_users: bool (const struct dom_sid *) diff --git a/source3/wscript_build b/source3/wscript_build index 49e023c..eb6b638 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -209,6 +209,7 @@ PASSDB_GET_SET_SRC = '''passdb/pdb_get_set.c''' PASSDB_SRC = '''${PASSDB_GET_SET_SRC} passdb/passdb.c lib/util_wellknown.c lib/util_builtin.c passdb/pdb_compat.c + lib/util_sid_passdb.c lib/util_unixsids.c passdb/lookup_sid.c passdb/login_cache.c passdb/account_pol.c ${PRIVILEGES_SRC} -- 1.7.9.5 From abcc5a34c843305c82bd860f7b93c8b82502518c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 30 Nov 2012 16:27:59 +0100 Subject: [PATCH 43/50] s3:winbindd: use the new sid_check_is_for_passdb() in idmap_find_domain_with_sid() This is more correct than the original one: It also hands the wellknown and "Unix Users" and "Unix Groups" sids to passdb for id mapping. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 2d3f7e31411cc63d5c83337f7280fcd6d2330282) --- source3/winbindd/idmap.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index ae4fb2b..d5eeac6 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -24,7 +24,7 @@ #include "includes.h" #include "winbindd.h" #include "idmap.h" -#include "passdb/machine_sid.h" +#include "lib/util_sid_passdb.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_IDMAP @@ -427,11 +427,7 @@ struct idmap_domain *idmap_find_domain_with_sid(const char *domname, { idmap_init(); - if (sid_check_is_in_builtin(sid) || - sid_check_is_builtin(sid) || - sid_check_is_in_our_sam(sid) || - sid_check_is_our_sam(sid)) - { + if (sid_check_is_for_passdb(sid)) { return idmap_passdb_domain(NULL); } -- 1.7.9.5 From c304bf453184e967b63fe09c655a0dd7381cb2f7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 22 Nov 2012 23:12:19 +0100 Subject: [PATCH 44/50] s3:passdb: don't bail out in pdb_default_sid_to_id() if sid is not in our sam This code treats the own sam, builtin, wellknown, and sids from the "Unix User" and "Unix Group" pseudo-domains. This reverts part of commit 02e25b2a43ae02205a3412f862a1482d24b70aa4. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit ef0ed56eb15f24db5934f174f90f65d3f5c3c526) --- source3/passdb/pdb_interface.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 767808c..1527b39 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1430,11 +1430,6 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, uint32_t rid; id->id = -1; - if (!sid_check_is_in_our_sam(sid)) { - /* Not our SID */ - return False; - } - mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { -- 1.7.9.5 From 5aa83c5cd5a921ad0706086174e36969f2a52759 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 3 Dec 2012 01:34:32 +0100 Subject: [PATCH 45/50] s3:passdb: factor pdb_sid_to_id_unix_users_and_groups() out of pdb_default_sid_to_id() The special treatment of the "Unix User" and "Unix Group" pseudo domains can be reused. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit d96aeded6193cb6381540c1073182bfb7f079025) --- source3/include/passdb.h | 3 +++ source3/passdb/pdb_interface.c | 48 ++++++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 5202bd3..908631d 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -908,6 +908,9 @@ NTSTATUS pdb_set_secret(const char *secret_name, DATA_BLOB *secret_old, struct security_descriptor *sd); NTSTATUS pdb_delete_secret(const char *secret_name); +bool pdb_sid_to_id_unix_users_and_groups(const struct dom_sid *sid, + struct unixid *id); + /* The following definitions come from passdb/pdb_util.c */ diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 1527b39..436e774 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1421,6 +1421,32 @@ static bool pdb_default_gid_to_sid(struct pdb_methods *methods, gid_t gid, return true; } +/** + * The "Unix User" and "Unix Group" domains have a special + * id mapping that is a rid-algorithm with range starting at 0. + */ +_PRIVATE_ bool pdb_sid_to_id_unix_users_and_groups(const struct dom_sid *sid, + struct unixid *id) +{ + uint32_t rid; + + id->id = -1; + + if (sid_peek_check_rid(&global_sid_Unix_Users, sid, &rid)) { + id->id = rid; + id->type = ID_TYPE_UID; + return true; + } + + if (sid_peek_check_rid(&global_sid_Unix_Groups, sid, &rid)) { + id->id = rid; + id->type = ID_TYPE_GID; + return true; + } + + return false; +} + static bool pdb_default_sid_to_id(struct pdb_methods *methods, const struct dom_sid *sid, struct unixid *id) @@ -1467,22 +1493,12 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, goto done; } - /* check for "Unix User" */ - - if ( sid_peek_check_rid(&global_sid_Unix_Users, sid, &rid) ) { - id->id = rid; - id->type = ID_TYPE_UID; - ret = True; - goto done; - } - - /* check for "Unix Group" */ - - if ( sid_peek_check_rid(&global_sid_Unix_Groups, sid, &rid) ) { - id->id = rid; - id->type = ID_TYPE_GID; - ret = True; - goto done; + /* + * "Unix User" and "Unix Group" + */ + ret = pdb_sid_to_id_unix_users_and_groups(sid, id); + if (ret == true) { + goto done; } /* BUILTIN */ -- 1.7.9.5 From 2ea95a1105af18330c5a8f2ed12579f5fd5ef52a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 3 Dec 2012 01:40:37 +0100 Subject: [PATCH 46/50] s3:passdb: add sid_check_object_is_for_passdb() Variant of sid_check_is_for_passdb() that only checks for objects in the various domains, not for the domain sids themselves. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 671f534e5e02adafe945a4e77813e80b5adaeb70) --- source3/lib/util_sid_passdb.c | 28 ++++++++++++++++++++++++++++ source3/lib/util_sid_passdb.h | 6 ++++++ source3/passdb/ABI/pdb-0.sigs | 1 + 3 files changed, 35 insertions(+) diff --git a/source3/lib/util_sid_passdb.c b/source3/lib/util_sid_passdb.c index 4378d0f..33fb542 100644 --- a/source3/lib/util_sid_passdb.c +++ b/source3/lib/util_sid_passdb.c @@ -23,6 +23,34 @@ #include "passdb/machine_sid.h" /** + * check whether this is an object-sid that should + * be treated by the passdb, e.g. for id-mapping. + */ +bool sid_check_object_is_for_passdb(const struct dom_sid *sid) +{ + if (sid_check_is_in_our_sam(sid)) { + return true; + } + + if (sid_check_is_in_builtin(sid)) { + return true; + } + + if (sid_check_is_in_wellknown_domain(sid)) { + return true; + } + + if (sid_check_is_in_unix_users(sid)) { + return true; + } + + if (sid_check_is_in_unix_groups(sid)) { + return true; + } + + return false; +} +/** * check whether this is an object- or domain-sid that should * be treated by the passdb, e.g. for id-mapping. */ diff --git a/source3/lib/util_sid_passdb.h b/source3/lib/util_sid_passdb.h index bd62e9e..381d63c 100644 --- a/source3/lib/util_sid_passdb.h +++ b/source3/lib/util_sid_passdb.h @@ -22,6 +22,12 @@ #define __LIB_UTIL_SID_PASSDB_H__ /** + * check whether this is an object-sid that should + * be treated by the passdb, e.g. for id-mapping. + */ +bool sid_check_object_is_for_passdb(const struct dom_sid *sid); + +/** * check whether this is an object- or domain-sid that should * be treated by the passdb, e.g. for id-mapping. */ diff --git a/source3/passdb/ABI/pdb-0.sigs b/source3/passdb/ABI/pdb-0.sigs index 47d9423..f32ca4f 100644 --- a/source3/passdb/ABI/pdb-0.sigs +++ b/source3/passdb/ABI/pdb-0.sigs @@ -265,6 +265,7 @@ sid_check_is_unix_groups: bool (const struct dom_sid *) sid_check_is_unix_users: bool (const struct dom_sid *) sid_check_is_wellknown_builtin: bool (const struct dom_sid *) sid_check_is_wellknown_domain: bool (const struct dom_sid *, const char **) +sid_check_object_is_for_passdb: bool (const struct dom_sid *) sid_to_gid: bool (const struct dom_sid *, gid_t *) sid_to_uid: bool (const struct dom_sid *, uid_t *) sids_to_unixids: bool (const struct dom_sid *, uint32_t, struct unixid *) -- 1.7.9.5 From ebc056bc067f53c06154efabbccc1b1fdcb57454 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 3 Dec 2012 01:42:38 +0100 Subject: [PATCH 47/50] s3:passdb:pdb_ldap: pre-validate sid with sid_check_object_is_for_passdb() instead of sid_check_sid_is_in_our_sam). This allows for builtin sids, wellknown sids and "Unix User" and "Unix Group" domains. This broadens up the check moved here in commit 02e25b2a43ae02205a3412f862a1482d24b70aa4. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit a0f41294488fcf4c9dbe5e85be6539394b6d6d1a) --- source3/passdb/pdb_ldap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index b41f58b..5795a26 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -53,6 +53,7 @@ #include "lib/winbind_util.h" #include "librpc/gen_ndr/idmap.h" #include "lib/param/loadparm.h" +#include "lib/util_sid_passdb.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -4938,9 +4939,8 @@ static bool ldapsam_sid_to_id(struct pdb_methods *methods, TALLOC_CTX *mem_ctx; - if (!sid_check_is_in_our_sam(sid)) { - /* Not our SID */ - return False; + if (!sid_check_object_is_for_passdb(sid)) { + return false; } mem_ctx = talloc_new(NULL); -- 1.7.9.5 From 0faccc07dcca6a14d953d60320ac55e10d251c35 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 3 Dec 2012 01:44:49 +0100 Subject: [PATCH 48/50] s3:passdb:pdb_ldap: treat "Unix User" and "Unix Group" in sid_to_id() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 5fbdc5f35a122ff040c6120e2aa2cf5485e32097) --- source3/passdb/pdb_ldap.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 5795a26..ca35ef7 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -4943,6 +4943,11 @@ static bool ldapsam_sid_to_id(struct pdb_methods *methods, return false; } + ret = pdb_sid_to_id_unix_users_and_groups(sid, id); + if (ret == true) { + return true; + } + mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { DEBUG(0, ("talloc_new failed\n")); -- 1.7.9.5 From 767f82369cda30ddbba33cd3cc023382d655e38c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 3 Dec 2012 08:34:43 +0100 Subject: [PATCH 49/50] s3:passdb: don't look into group mappings in legacy_sid_to_unixid() The backends (tdbsam and ldapsam) do this. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 93c0c0749a2c3cbb1bc85e18b7dd77989a3eada8) --- source3/passdb/lookup_sid.c | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index e48420d..6ec6ce8 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -1083,45 +1083,18 @@ static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid) static bool legacy_sid_to_unixid(const struct dom_sid *psid, struct unixid *id) { - GROUP_MAP *map; bool ret; become_root(); ret = pdb_sid_to_id(psid, id); unbecome_root(); - if (ret) { - goto done; - } - - if ((sid_check_is_in_builtin(psid) || - sid_check_is_in_wellknown_domain(psid))) { - map = talloc_zero(NULL, GROUP_MAP); - if (!map) { - return false; - } - - become_root(); - ret = pdb_getgrsid(map, *psid); - unbecome_root(); - - if (ret) { - id->id = map->gid; - id->type = ID_TYPE_GID; - TALLOC_FREE(map); - goto done; - } - TALLOC_FREE(map); + if (!ret) { DEBUG(10,("LEGACY: mapping failed for sid %s\n", sid_string_dbg(psid))); return false; } - DEBUG(10,("LEGACY: mapping failed for sid %s\n", - sid_string_dbg(psid))); - return false; - -done: return true; } -- 1.7.9.5 From f08a7520825e8371b4368d4f8cd46e0253cad504 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 3 Dec 2012 02:25:40 +0100 Subject: [PATCH 50/50] s3:selftest: extend sids2xids test script to cope with "ID_TYPE_BOTH mappings Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher Autobuild-User(master): Michael Adam Autobuild-Date(master): Mon Dec 3 10:47:17 CET 2012 on sn-devel-104 (cherry picked from commit 99efe8480ebb0493be93a6ca5f77a1fe640f3be0) --- source3/script/tests/test_wbinfo_sids2xids_int.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/script/tests/test_wbinfo_sids2xids_int.py b/source3/script/tests/test_wbinfo_sids2xids_int.py index 8826f53..1b79e00 100755 --- a/source3/script/tests/test_wbinfo_sids2xids_int.py +++ b/source3/script/tests/test_wbinfo_sids2xids_int.py @@ -34,7 +34,7 @@ gids=[] for line in sids2xids.split('\n'): result = line.split(' ')[2:] - if result[0] == 'gid': + if result[0] == 'gid' or result[0] == 'uid/gid': gid = result[1] else: gid = '' -- 1.7.9.5