From 5bd80cfd5cd36b41696db457598db30c760e6d70 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 7 Dec 2012 01:12:11 +0100 Subject: [PATCH 1/7] s3:winbindd: rename winbindd_getgrnam_lookupsid_done to winbindd_getgrnam_lookupname_done That's what it is. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit c0f47d43ecf8b603dc7a05822933c5a9a1d23c7c) --- source3/winbindd/winbindd_getgrnam.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/winbindd/winbindd_getgrnam.c b/source3/winbindd/winbindd_getgrnam.c index 9460ff4..9a2f64e 100644 --- a/source3/winbindd/winbindd_getgrnam.c +++ b/source3/winbindd/winbindd_getgrnam.c @@ -30,7 +30,7 @@ struct winbindd_getgrnam_state { struct talloc_dict *members; }; -static void winbindd_getgrnam_lookupsid_done(struct tevent_req *subreq); +static void winbindd_getgrnam_lookupname_done(struct tevent_req *subreq); static void winbindd_getgrnam_done(struct tevent_req *subreq); struct tevent_req *winbindd_getgrnam_send(TALLOC_CTX *mem_ctx, @@ -81,12 +81,12 @@ struct tevent_req *winbindd_getgrnam_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, winbindd_getgrnam_lookupsid_done, + tevent_req_set_callback(subreq, winbindd_getgrnam_lookupname_done, req); return req; } -static void winbindd_getgrnam_lookupsid_done(struct tevent_req *subreq) +static void winbindd_getgrnam_lookupname_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); -- 1.7.9.5 From bacf6710f4a9be9d86c614a826de8f642afd5152 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 7 Dec 2012 16:13:19 +0100 Subject: [PATCH 2/7] s3:winbindd: fix a cut'n'paste comment typo in wb_fill_pwent Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 3680cc4a11ef5476457b580f8422d0ab82451173) --- source3/winbindd/wb_fill_pwent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/wb_fill_pwent.c b/source3/winbindd/wb_fill_pwent.c index a6a9013..688afc6 100644 --- a/source3/winbindd/wb_fill_pwent.c +++ b/source3/winbindd/wb_fill_pwent.c @@ -120,7 +120,7 @@ static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq) * 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. + * 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); -- 1.7.9.5 From 638ed56a36ab414ebb5f946728f6482ccaac1f0d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 6 Dec 2012 18:06:49 +0100 Subject: [PATCH 3/7] s3:winbindd: factor add_wbint_Principal_to_dict() out of wb_group_members_done() for later reuse Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 729e2c36301620ccc61b1d97205fb3f482efbe15) --- source3/winbindd/wb_group_members.c | 59 +++++++++++++++++++++++++---------- source3/winbindd/winbindd_proto.h | 5 +++ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/source3/winbindd/wb_group_members.c b/source3/winbindd/wb_group_members.c index e4b4c0a..ecd07cf 100644 --- a/source3/winbindd/wb_group_members.c +++ b/source3/winbindd/wb_group_members.c @@ -349,6 +349,42 @@ static NTSTATUS wb_group_members_next_subreq( return NT_STATUS_OK; } + +/** + * compose a wbint_Principal and add it to talloc_dict + * + * NOTE: this has a side effect: *name needs to be talloc'd + * and it is talloc_move'd to mem_ctx. + */ +NTSTATUS add_wbint_Principal_to_dict(TALLOC_CTX *mem_ctx, + struct dom_sid *sid, + const char **name, + enum lsa_SidType type, + struct talloc_dict *dict) +{ + struct wbint_Principal *m; + DATA_BLOB key; + bool ok; + + m = talloc(mem_ctx, struct wbint_Principal); + if (m == NULL) { + return NT_STATUS_NO_MEMORY; + } + + sid_copy(&m->sid, sid); + m->name = talloc_move(m, name); + m->type = type; + + key = data_blob_const(&m->sid, sizeof(m->sid)); + + ok = talloc_dict_set(dict, key, &m); + if (!ok) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + static void wb_group_members_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( @@ -397,26 +433,15 @@ static void wb_group_members_done(struct tevent_req *subreq) /* * Add a copy of members[i] to state->users */ - struct wbint_Principal *m; - struct dom_sid *sid; - DATA_BLOB key; - - m = talloc(talloc_tos(), struct wbint_Principal); - if (tevent_req_nomem(m, req)) { + status = add_wbint_Principal_to_dict(talloc_tos(), + &members[i].sid, + &members[i].name, + members[i].type, + state->users); + if (tevent_req_nterror(req, status)) { return; } - sid_copy(&m->sid, &members[i].sid); - m->name = talloc_move(m, &members[i].name); - m->type = members[i].type; - - sid = &members[i].sid; - key = data_blob_const( - sid, ndr_size_dom_sid(sid, 0)); - if (!talloc_dict_set(state->users, key, &m)) { - tevent_req_nterror(req, NT_STATUS_NO_MEMORY); - return; - } break; } case SID_NAME_DOM_GRP: diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 0265227..41aa9ac 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -643,6 +643,11 @@ struct tevent_req *wb_group_members_send(TALLOC_CTX *mem_ctx, int max_depth); NTSTATUS wb_group_members_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct talloc_dict **members); +NTSTATUS add_wbint_Principal_to_dict(TALLOC_CTX *mem_ctx, + struct dom_sid *sid, + const char **name, + enum lsa_SidType type, + struct talloc_dict *dict); struct tevent_req *wb_getgrsid_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, -- 1.7.9.5 From 10f9cc569915afcb39cda00bfbf1addf31148046 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 6 Dec 2012 22:02:32 +0100 Subject: [PATCH 4/7] s3:winbindd: create group structs for gids that are coming from a user sid id-mapped with ID_TYPE_BOTH This "fake" group contains exctly one member, namely the user that the sid is actually belonging to. Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit d2360fe56c860fa20051f6373eb2fcc3e4def6b6) --- source3/winbindd/wb_getgrsid.c | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/source3/winbindd/wb_getgrsid.c b/source3/winbindd/wb_getgrsid.c index 2097539..fa376da 100644 --- a/source3/winbindd/wb_getgrsid.c +++ b/source3/winbindd/wb_getgrsid.c @@ -91,6 +91,11 @@ static void wb_getgrsid_lookupsid_done(struct tevent_req *subreq) case SID_NAME_DOM_GRP: case SID_NAME_ALIAS: case SID_NAME_WKN_GRP: + /* + * also treat user-type SIDS (they might map to ID_TYPE_BOTH) + */ + case SID_NAME_USER: + case SID_NAME_COMPUTER: break; default: tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); @@ -132,6 +137,50 @@ static void wb_getgrsid_sid2gid_done(struct tevent_req *subreq) state->gid = (gid_t)xid.id; + if (state->type == SID_NAME_USER || state->type == SID_NAME_COMPUTER) { + /* + * special treatment for a user sid that is + * mapped to ID_TYPE_BOTH: + * create a group with the sid/xid as only member + */ + char *name; + + if (xid.type != ID_TYPE_BOTH) { + tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); + return; + } + + state->members = talloc_dict_init(state); + if (tevent_req_nomem(state->members, req)) { + return; + } + + name = fill_domain_username_talloc(talloc_tos(), + state->domname, + state->name, + true /* can_assume */); + if (tevent_req_nomem(name, req)) { + return; + } + + status = add_wbint_Principal_to_dict(talloc_tos(), + &state->sid, + &name, + state->type, + state->members); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + + tevent_req_done(req); + return; + } + + /* + * the "regular" case of a group type sid. + */ + 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 d0262c19132b44694dadc00a487002e9cc893ab9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 7 Dec 2012 00:55:18 +0100 Subject: [PATCH 5/7] s3:winbindd:getgrnam: also produce a group struct for a user with ID_TYPE_BOTH Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 40e3df7c37a15b28f170699ff9b8102416a9107f) --- source3/winbindd/winbindd_getgrnam.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/source3/winbindd/winbindd_getgrnam.c b/source3/winbindd/winbindd_getgrnam.c index 9a2f64e..bc970cb 100644 --- a/source3/winbindd/winbindd_getgrnam.c +++ b/source3/winbindd/winbindd_getgrnam.c @@ -101,8 +101,19 @@ static void winbindd_getgrnam_lookupname_done(struct tevent_req *subreq) return; } - if ( (type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) ) { - DEBUG(5,("getgrnam_recv: not a group!\n")); + switch (type) { + case SID_NAME_DOM_GRP: + case SID_NAME_ALIAS: + case SID_NAME_WKN_GRP: + /* + * Also give user types a chance: + * These might be user sids mapped to the ID_TYPE_BOTH, + * and in that case we should construct a group struct. + */ + case SID_NAME_USER: + case SID_NAME_COMPUTER: + break; + default: tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); return; } -- 1.7.9.5 From e24fb30a6a42c0fb5549093601f8e9380b67b1a8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 22 Jan 2013 17:39:44 +0100 Subject: [PATCH 6/7] s3:winbindd: check the correct variable for talloc success in rpc_query_user() Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit b7095e9818bba8c43065cc1b1f29551203dc098b) --- source3/winbindd/winbindd_rpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index a96dbb1..44deeb0 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -526,7 +526,7 @@ NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx, user_info->full_name = talloc_strdup(user_info, info->info21.full_name.string); if ((info->info21.full_name.string != NULL) && - (user_info->acct_name == NULL)) + (user_info->full_name == NULL)) { return NT_STATUS_NO_MEMORY; } -- 1.7.9.5 From 2e3cb18401f5f6c66a7ebaf69f73c0931fb3f0cc Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 22 Jan 2013 18:08:25 +0100 Subject: [PATCH 7/7] s3:winbindd: change getpwsid() to return a passwd struct for a group sid id-mapped with ID_TYPE_BOTH Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Tue Jan 29 23:46:19 CET 2013 on sn-devel-104 (cherry picked from commit 394622ef8c916cf361f8596dba4664dc8d6bfc9e) --- source3/winbindd/wb_getpwsid.c | 52 +++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/source3/winbindd/wb_getpwsid.c b/source3/winbindd/wb_getpwsid.c index ef54ee5..df8b0f2 100644 --- a/source3/winbindd/wb_getpwsid.c +++ b/source3/winbindd/wb_getpwsid.c @@ -67,12 +67,10 @@ static void wb_getpwsid_queryuser_done(struct tevent_req *subreq) status = wb_queryuser_recv(subreq, state, &state->userinfo); TALLOC_FREE(subreq); - if (tevent_req_nterror(req, status)) { - return; - } - - if ((state->userinfo->acct_name != NULL) - && (state->userinfo->acct_name[0] != '\0')) { + if (NT_STATUS_IS_OK(status) + && (state->userinfo->acct_name != NULL) + && (state->userinfo->acct_name[0] != '\0')) + { /* * QueryUser got us a name, let's got directly to the * fill_pwent step @@ -87,10 +85,25 @@ static void wb_getpwsid_queryuser_done(struct tevent_req *subreq) } /* - * QueryUser didn't get us a name, do it via LSA. + * Either query_user did not succeed, or it + * succeeded but did not return an acct_name. + * (TODO: Can this happen at all???) + * ==> Try lsa_lookupsids. */ - subreq = wb_lookupsid_send(state, state->ev, - &state->userinfo->user_sid); + if (state->userinfo == NULL) { + state->userinfo = talloc_zero(state, struct wbint_userinfo); + if (tevent_req_nomem(state->userinfo, req)) { + return; + } + + /* a successful query_user call would have filled these */ + sid_copy(&state->userinfo->user_sid, &state->sid); + state->userinfo->homedir = NULL; + state->userinfo->shell = NULL; + state->userinfo->primary_gid = (gid_t)-1; + } + + subreq = wb_lookupsid_send(state, state->ev, &state->sid); if (tevent_req_nomem(subreq, req)) { return; } @@ -113,6 +126,27 @@ static void wb_getpwsid_lookupsid_done(struct tevent_req *subreq) if (tevent_req_nterror(req, status)) { return; } + + switch (type) { + case SID_NAME_USER: + case SID_NAME_COMPUTER: + /* + * user case: we only need the account name from lookup_sids + */ + break; + case SID_NAME_DOM_GRP: + case SID_NAME_ALIAS: + case SID_NAME_WKN_GRP: + /* + * also treat group-type SIDs (they might map to ID_TYPE_BOTH) + */ + sid_copy(&state->userinfo->group_sid, &state->sid); + break; + default: + tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); + return; + } + subreq = wb_fill_pwent_send(state, state->ev, state->userinfo, state->pw); if (tevent_req_nomem(subreq, req)) { -- 1.7.9.5