The Samba-Bugzilla – Attachment 14836 Details for
Bug 13371
idmap_rid: default group always set to "Domain Users" not evaluating PrimaryGroupID ldap attribute
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
retrieve the primary group ID when using idmap_rid and there is no cached netlogon
idmap_rid.patch (text/plain), 15.38 KB, created by
David Mulder
on 2019-02-07 15:28:20 UTC
(
hide
)
Description:
retrieve the primary group ID when using idmap_rid and there is no cached netlogon
Filename:
MIME Type:
Creator:
David Mulder
Created:
2019-02-07 15:28:20 UTC
Size:
15.38 KB
patch
obsolete
>From c36e0abffdfc09fc4ee48decdca73295884b23a0 Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <scabrero@suse.de> >Date: Fri, 13 Apr 2018 16:20:16 +0200 >Subject: [PATCH 1/3] Revert "winbind: Remove wbint_QueryUser" > >This reverts commit 5b2d74bd1116ef182b4a2a58cb8949ae8f10638f. > >Signed-off-by: Samuel Cabrero <scabrero@suse.de> >(cherry picked from commit 622fa7c65140fb8a83f84305dae051c62d97e822) >--- > librpc/idl/winbind.idl | 5 +++++ > source3/winbindd/winbindd_dual_srv.c | 15 +++++++++++++++ > 2 files changed, 20 insertions(+) > >diff --git a/librpc/idl/winbind.idl b/librpc/idl/winbind.idl >index ab9af2d1509..eb860b1358f 100644 >--- a/librpc/idl/winbind.idl >+++ b/librpc/idl/winbind.idl >@@ -85,6 +85,11 @@ interface winbind > dom_sid group_sid; > } wbint_userinfo; > >+ NTSTATUS wbint_QueryUser( >+ [in] dom_sid *sid, >+ [out] wbint_userinfo *info >+ ); >+ > NTSTATUS wbint_GetNssInfo( > [in,out] wbint_userinfo *info > ); >diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c >index df380955a00..570af2b2e39 100644 >--- a/source3/winbindd/winbindd_dual_srv.c >+++ b/source3/winbindd/winbindd_dual_srv.c >@@ -269,6 +269,21 @@ NTSTATUS _wbint_AllocateGid(struct pipes_struct *p, struct wbint_AllocateGid *r) > return NT_STATUS_OK; > } > >+NTSTATUS _wbint_QueryUser(struct pipes_struct *p, struct wbint_QueryUser *r) >+{ >+ struct winbindd_domain *domain = wb_child_domain(); >+ NTSTATUS status; >+ >+ if (domain == NULL) { >+ return NT_STATUS_REQUEST_NOT_ACCEPTED; >+ } >+ >+ status = wb_cache_query_user(domain, p->mem_ctx, r->in.sid, >+ r->out.info); >+ reset_cm_connection_on_error(domain, status); >+ return status; >+} >+ > NTSTATUS _wbint_GetNssInfo(struct pipes_struct *p, struct wbint_GetNssInfo *r) > { > struct idmap_domain *domain; >-- >2.20.1 > > >From e075937d4a8919c1b5d1dca43b68be5a53e70098 Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <scabrero@suse.de> >Date: Fri, 13 Apr 2018 16:42:42 +0200 >Subject: [PATCH 2/3] Revert "winbind: Remove rpc_query_user" > >This reverts commit a8ab48ee193f68217e7c53b71bf6c57d2d15f8d7. > >Signed-off-by: Samuel Cabrero <scabrero@suse.de> >(cherry picked from commit f77dd0e7a96f79bd25f5883a06c5cc0c35bd65c9) >--- > source3/winbindd/winbindd_rpc.c | 76 +++++++++++++++++++++++++++++++++ > source3/winbindd/winbindd_rpc.h | 8 ++++ > 2 files changed, 84 insertions(+) > >diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c >index 9fb22400c1d..eb31ce2d520 100644 >--- a/source3/winbindd/winbindd_rpc.c >+++ b/source3/winbindd/winbindd_rpc.c >@@ -438,6 +438,82 @@ NTSTATUS rpc_rids_to_names(TALLOC_CTX *mem_ctx, > return NT_STATUS_OK; > } > >+/* Lookup user information from a rid or username. */ >+NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx, >+ struct rpc_pipe_client *samr_pipe, >+ struct policy_handle *samr_policy, >+ const struct dom_sid *domain_sid, >+ const struct dom_sid *user_sid, >+ struct wbint_userinfo *user_info) >+{ >+ struct policy_handle user_policy; >+ union samr_UserInfo *info = NULL; >+ uint32_t user_rid; >+ NTSTATUS status, result; >+ struct dcerpc_binding_handle *b = samr_pipe->binding_handle; >+ >+ if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) { >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ >+ /* Get user handle */ >+ status = dcerpc_samr_OpenUser(b, >+ mem_ctx, >+ samr_policy, >+ SEC_FLAG_MAXIMUM_ALLOWED, >+ user_rid, >+ &user_policy, >+ &result); >+ if (!NT_STATUS_IS_OK(status)) { >+ return status; >+ } >+ if (!NT_STATUS_IS_OK(result)) { >+ return result; >+ } >+ >+ /* Get user info */ >+ status = dcerpc_samr_QueryUserInfo(b, >+ mem_ctx, >+ &user_policy, >+ 0x15, >+ &info, >+ &result); >+ { >+ NTSTATUS _result; >+ dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result); >+ } >+ if (!NT_STATUS_IS_OK(status)) { >+ return status; >+ } >+ if (!NT_STATUS_IS_OK(result)) { >+ return result; >+ } >+ >+ sid_compose(&user_info->user_sid, domain_sid, user_rid); >+ sid_compose(&user_info->group_sid, domain_sid, >+ info->info21.primary_gid); >+ >+ user_info->acct_name = talloc_strdup(user_info, >+ info->info21.account_name.string); >+ if (user_info->acct_name == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ >+ user_info->full_name = talloc_strdup(user_info, >+ info->info21.full_name.string); >+ if ((info->info21.full_name.string != NULL) && >+ (user_info->full_name == NULL)) >+ { >+ return NT_STATUS_NO_MEMORY; >+ } >+ >+ user_info->homedir = NULL; >+ user_info->shell = NULL; >+ user_info->primary_gid = (gid_t)-1; >+ >+ return NT_STATUS_OK; >+} >+ > /* Lookup groups a user is a member of. */ > NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx, > struct rpc_pipe_client *samr_pipe, >diff --git a/source3/winbindd/winbindd_rpc.h b/source3/winbindd/winbindd_rpc.h >index 162f1ef3329..ee0f5432c64 100644 >--- a/source3/winbindd/winbindd_rpc.h >+++ b/source3/winbindd/winbindd_rpc.h >@@ -78,6 +78,14 @@ NTSTATUS rpc_rids_to_names(TALLOC_CTX *mem_ctx, > char ***pnames, > enum lsa_SidType **ptypes); > >+/* Lookup user information from a rid or username. */ >+NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx, >+ struct rpc_pipe_client *samr_pipe, >+ struct policy_handle *samr_policy, >+ const struct dom_sid *domain_sid, >+ const struct dom_sid *user_sid, >+ struct wbint_userinfo *user_info); >+ > /* Lookup groups a user is a member of. */ > NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx, > struct rpc_pipe_client *samr_pipe, >-- >2.20.1 > > >From c8131e7e20f9a0acfb734a3eb4e4c7c2e2915976 Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <scabrero@suse.de> >Date: Mon, 16 Apr 2018 10:33:17 +0200 >Subject: [PATCH 3/3] s3: winbind: Call SAMR QueryUserInfo if no valid netlogon > cache entry > >In the way to 4.6.0 a lot of code was pulled out from winbind with the premise >that returned user info is correct only for users who logged on [1] (user >and group enumeration, user group membership and user information). Part >of these changes were reverted due to user complains in the RC stage [2], >but the bits related to query user information were lost. > >When there isn't a valid netlogon cache entry wb_queryuser defaults the >user primary group sid to -513 (Domain users), and will become correct once >there is a valid netlogon cache entry. > >In an effort to return as accurate as possible information, try to obtain >the missing fields calling SAMR QueryUserInfo when it cannot be extracted >from netlogon cache. > >This new behavior requires to open a SAMR pipe to a DC in the domain the user >belongs to, and as RPC to domain controllers outside winbind's primary domain >has to be avoided, it is disabled by default. > >To enable, set "winbind: query user rpc fallback = yes". > >[1] https://lists.samba.org/archive/samba-technical/2016-November/116972.html >[2] https://lists.samba.org/archive/samba-technical/2017-March/119066.html > >Signed-off-by: Samuel Cabrero <scabrero@suse.de> >(cherry picked from commit 0b64dce0b9ce3366b7df338145f36ac245c77e81) >--- > source3/winbindd/wb_queryuser.c | 137 ++++++++++++++++++++++++--- > source3/winbindd/winbindd_dual_srv.c | 19 +++- > 2 files changed, 142 insertions(+), 14 deletions(-) > >diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c >index 69b4c8dad5a..82355c716e5 100644 >--- a/source3/winbindd/wb_queryuser.c >+++ b/source3/winbindd/wb_queryuser.c >@@ -25,13 +25,18 @@ > > struct wb_queryuser_state { > struct tevent_context *ev; >- struct wbint_userinfo *info; > bool tried_dclookup; >+ bool cached_samlogon; >+ /* Returned to caller */ >+ struct wbint_userinfo *info; >+ /* Returned from SAMR QueryUserInfo */ >+ struct wbint_userinfo *samr_info; > }; > > static void wb_queryuser_got_uid(struct tevent_req *subreq); > static void wb_queryuser_got_domain(struct tevent_req *subreq); > static void wb_queryuser_got_dc(struct tevent_req *subreq); >+static void wb_queryuser_got_nssinfo(struct tevent_req *subreq); > static void wb_queryuser_got_gid(struct tevent_req *subreq); > static void wb_queryuser_got_group_name(struct tevent_req *subreq); > static void wb_queryuser_done(struct tevent_req *subreq); >@@ -89,8 +94,8 @@ static void wb_queryuser_got_uid(struct tevent_req *subreq) > req, struct wb_queryuser_state); > struct wbint_userinfo *info = state->info; > struct netr_SamInfo3 *info3; >- struct winbindd_child *child; > struct unixid xid; >+ struct winbindd_child *child; > NTSTATUS status; > > status = wb_sids2xids_recv(subreq, &xid, 1); >@@ -127,7 +132,6 @@ static void wb_queryuser_got_uid(struct tevent_req *subreq) > > info3 = netsamlogon_cache_get(state, &info->user_sid); > if (info3 != NULL) { >- > sid_compose(&info->group_sid, info3->base.domain_sid, > info3->base.primary_gid); > info->acct_name = talloc_move( >@@ -139,6 +143,7 @@ static void wb_queryuser_got_uid(struct tevent_req *subreq) > state, &info3->base.logon_domain.string); > > TALLOC_FREE(info3); >+ state->cached_samlogon = true; > } > > if (info->domain_name == NULL) { >@@ -150,6 +155,39 @@ static void wb_queryuser_got_uid(struct tevent_req *subreq) > return; > } > >+ if (!state->cached_samlogon && >+ lp_parm_bool(-1, "winbindd", "query user rpc fallback", false)) { >+ struct winbindd_domain *domain; >+ >+ /* If not found in cache, call SAMR QueryUserInfo */ >+ domain = find_domain_from_name(info->domain_name); >+ if (domain == NULL) { >+ DEBUG(5, ("Could not find domain for '%s'\n", >+ info->domain_name)); >+ tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); >+ return; >+ } >+ >+ state->samr_info = talloc_zero(state, struct wbint_userinfo); >+ if (tevent_req_nomem(state->samr_info, req)) { >+ return; >+ } >+ >+ subreq = dcerpc_wbint_QueryUser_send( >+ state, state->ev, >+ dom_child_handle(domain), >+ &info->user_sid, state->samr_info); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, wb_queryuser_done, req); >+ return; >+ } >+ >+ /* The user information should be correct at this point, even from >+ * the netlogon cache or retrived calling SAMR QueryUserInfo. Now >+ * let the idmap backend override the info. */ >+ > child = idmap_child(); > > subreq = dcerpc_wbint_GetNssInfo_send( >@@ -157,7 +195,7 @@ static void wb_queryuser_got_uid(struct tevent_req *subreq) > if (tevent_req_nomem(subreq, req)) { > return; > } >- tevent_req_set_callback(subreq, wb_queryuser_done, req); >+ tevent_req_set_callback(subreq, wb_queryuser_got_nssinfo, req); > } > > static void wb_queryuser_got_domain(struct tevent_req *subreq) >@@ -184,6 +222,38 @@ static void wb_queryuser_got_domain(struct tevent_req *subreq) > return; > } > >+ if (!state->cached_samlogon && >+ lp_parm_bool(-1, "winbindd", "query user rpc fallback", false)) { >+ struct winbindd_domain *domain; >+ >+ /* If not found in cache, call SAMR QueryUserInfo */ >+ domain = find_domain_from_name(info->domain_name); >+ if (domain == NULL) { >+ DEBUG(5, ("Could not find domain for '%s'\n", >+ info->domain_name)); >+ tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); >+ return; >+ } >+ >+ state->samr_info = talloc_zero(state, struct wbint_userinfo); >+ if (tevent_req_nomem(state->samr_info, req)) { >+ return; >+ } >+ >+ subreq = dcerpc_wbint_QueryUser_send( >+ state, state->ev, >+ dom_child_handle(domain), >+ &info->user_sid, state->samr_info); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, wb_queryuser_done, req); >+ return; >+ } >+ >+ /* The user information should be correct at this point from >+ * the netlogon cache, let the idmap backend override the info. */ >+ > child = idmap_child(); > > subreq = dcerpc_wbint_GetNssInfo_send( >@@ -191,10 +261,51 @@ static void wb_queryuser_got_domain(struct tevent_req *subreq) > if (tevent_req_nomem(subreq, req)) { > return; > } >- tevent_req_set_callback(subreq, wb_queryuser_done, req); >+ tevent_req_set_callback(subreq, wb_queryuser_got_nssinfo, req); > } > > static void wb_queryuser_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct wb_queryuser_state *state = tevent_req_data( >+ req, struct wb_queryuser_state); >+ struct winbindd_child *child; >+ NTSTATUS status, result; >+ >+ status = dcerpc_wbint_QueryUser_recv(subreq, state, &result); >+ TALLOC_FREE(subreq); >+ >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ >+ /* Ignore errors and let the idmap backend obtain the info. Otherwise >+ * the defaults will be returned */ >+ if (NT_STATUS_IS_OK(result)) { >+ sid_copy(&state->info->group_sid, >+ &state->samr_info->group_sid); >+ state->info->acct_name = talloc_strdup( >+ state->info, state->samr_info->acct_name); >+ state->info->full_name = talloc_strdup( >+ state->info, state->samr_info->full_name); >+ } >+ >+ /* The user information should be correct at this point, retrived >+ * calling SAMR QueryUserInfo. Now let the idmap backend override >+ * the info. */ >+ >+ child = idmap_child(); >+ >+ subreq = dcerpc_wbint_GetNssInfo_send( >+ state, state->ev, child->binding_handle, state->info); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, wb_queryuser_got_nssinfo, req); >+} >+ >+static void wb_queryuser_got_nssinfo(struct tevent_req *subreq) > { > struct tevent_req *req = tevent_req_callback_data( > subreq, struct tevent_req); >@@ -219,13 +330,17 @@ static void wb_queryuser_done(struct tevent_req *subreq) > } > tevent_req_set_callback(subreq, wb_queryuser_got_dc, req); > return; >+ } else if (!NT_STATUS_EQUAL(result, NT_STATUS_OK) && >+ !NT_STATUS_EQUAL(result, NT_STATUS_REQUEST_NOT_ACCEPTED)) >+ { >+ /* If the idmap backend returns NT_STATUS_REQUEST_NOT_ACCEPTED >+ * ignore, means it does not override the current values */ >+ tevent_req_nterror(req, result); >+ return; > } > >- /* >- * Ignore failure in "result" here. We'll try to fill in stuff >- * that misses further down. >- */ >- >+ /* info->group_sid should be correct, even from the netlogon cache >+ * or obtained calling SAMR QueryUser */ > if (state->info->primary_gid == (gid_t)-1) { > subreq = wb_sids2xids_send( > state, state->ev, &info->group_sid, 1); >@@ -280,7 +395,7 @@ static void wb_queryuser_got_dc(struct tevent_req *subreq) > if (tevent_req_nomem(subreq, req)) { > return; > } >- tevent_req_set_callback(subreq, wb_queryuser_done, req); >+ tevent_req_set_callback(subreq, wb_queryuser_got_nssinfo, req); > } > > static void wb_queryuser_got_gid(struct tevent_req *subreq) >diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c >index 570af2b2e39..31f072a681c 100644 >--- a/source3/winbindd/winbindd_dual_srv.c >+++ b/source3/winbindd/winbindd_dual_srv.c >@@ -23,6 +23,7 @@ > #include "includes.h" > #include "winbindd/winbindd.h" > #include "winbindd/winbindd_proto.h" >+#include "winbindd/winbindd_rpc.h" > #include "rpc_client/cli_pipe.h" > #include "ntdomain.h" > #include "librpc/gen_ndr/srv_winbind.h" >@@ -272,15 +273,27 @@ NTSTATUS _wbint_AllocateGid(struct pipes_struct *p, struct wbint_AllocateGid *r) > NTSTATUS _wbint_QueryUser(struct pipes_struct *p, struct wbint_QueryUser *r) > { > struct winbindd_domain *domain = wb_child_domain(); >+ struct rpc_pipe_client *samr_pipe; >+ struct policy_handle samr_domain_handle; > NTSTATUS status; > > if (domain == NULL) { > return NT_STATUS_REQUEST_NOT_ACCEPTED; > } > >- status = wb_cache_query_user(domain, p->mem_ctx, r->in.sid, >- r->out.info); >- reset_cm_connection_on_error(domain, status); >+ status = cm_connect_sam(domain, p->mem_ctx, false, >+ &samr_pipe, &samr_domain_handle); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(3, ("could not open handle to SAMR pipe: %s\n", >+ nt_errstr(status))); >+ return status; >+ } >+ >+ status = rpc_query_user(p->mem_ctx, samr_pipe, >+ &samr_domain_handle, >+ &domain->sid, r->in.sid, >+ r->out.info); >+ > return status; > } > >-- >2.20.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 13371
:
14107
| 14836