]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:winbind: Add lookup_aliasmem to winbindd_methods and implement it in all backends
authorPavel Filipenský <pfilipensky@samba.org>
Wed, 8 Mar 2023 07:40:58 +0000 (08:40 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Tue, 13 Jun 2023 12:15:32 +0000 (12:15 +0000)
Signed-off-by: Pavel Filipenský <pfilipensky@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/winbindd/winbindd.h
source3/winbindd/winbindd_ads.c
source3/winbindd/winbindd_msrpc.c
source3/winbindd/winbindd_reconnect.c
source3/winbindd/winbindd_reconnect_ads.c
source3/winbindd/winbindd_rpc.c
source3/winbindd/winbindd_rpc.h
source3/winbindd/winbindd_samr.c

index 8a40208e3786df6b7eb47b4dbd81a405ae55b8a7..eae2ea9584f36e04372fc1683e54f9065e6d6bce 100644 (file)
@@ -279,6 +279,14 @@ struct winbindd_methods {
                                    struct dom_sid **sid_mem, char ***names,
                                    uint32_t **name_types);
 
+       /* find all members of the alias with the specified alias_sid */
+       NTSTATUS (*lookup_aliasmem)(struct winbindd_domain *domain,
+                                   TALLOC_CTX *mem_ctx,
+                                   const struct dom_sid *alias_sid,
+                                   enum lsa_SidType type,
+                                   uint32_t *num_sids,
+                                   struct dom_sid **sid_mem);
+
        /* return the lockout policy */
        NTSTATUS (*lockout_policy)(struct winbindd_domain *domain,
                                   TALLOC_CTX *mem_ctx,
index 814dd52cdfd29235983c4f53215f62bbe1d1fe94..f9f9dc4f823b6fe953dfb3fbbc5ccca9fdcc830e 100644 (file)
@@ -1371,6 +1371,31 @@ done:
        return status;
 }
 
+static NTSTATUS lookup_aliasmem(struct winbindd_domain *domain,
+                               TALLOC_CTX *mem_ctx,
+                               const struct dom_sid *sid,
+                               enum lsa_SidType type,
+                               uint32_t *num_sids,
+                               struct dom_sid **sids)
+{
+       char **names = NULL;
+       uint32_t *name_types = NULL;
+       struct dom_sid_buf buf;
+
+       DBG_DEBUG("ads: lookup_aliasmem %s sid=%s\n",
+                 domain->name,
+                 dom_sid_str_buf(sid, &buf));
+       /* Search for alias and group membership uses the same LDAP command. */
+       return lookup_groupmem(domain,
+                              mem_ctx,
+                              sid,
+                              type,
+                              num_sids,
+                              sids,
+                              &names,
+                              &name_types);
+}
+
 /* find the lockout policy of a domain - use rpc methods */
 static NTSTATUS lockout_policy(struct winbindd_domain *domain,
                               TALLOC_CTX *mem_ctx,
@@ -1568,6 +1593,7 @@ struct winbindd_methods ads_methods = {
        lookup_usergroups,
        lookup_useraliases,
        lookup_groupmem,
+       lookup_aliasmem,
        lockout_policy,
        password_policy,
        trusted_domains,
index 6a6caa7a4987a0869b8c41938c6f723b931ed727..3233846ca3f1f2b8d3c5f3429a7fc4ecca3ce885 100644 (file)
@@ -544,6 +544,60 @@ done:
        return status;
 }
 
+/* lookup alias membership */
+static NTSTATUS msrpc_lookup_aliasmem(struct winbindd_domain *domain,
+                                     TALLOC_CTX *mem_ctx,
+                                     const struct dom_sid *alias_sid,
+                                     enum lsa_SidType type,
+                                     uint32_t *pnum_sids,
+                                     struct dom_sid **sid_mem)
+{
+       struct rpc_pipe_client *samr_pipe = NULL;
+       struct policy_handle dom_pol;
+       struct dom_sid *alias_members = NULL;
+       struct dom_sid_buf buf;
+       uint32_t num_groups = 0;
+       TALLOC_CTX *tmp_ctx = talloc_stackframe();
+       NTSTATUS status;
+
+       D_INFO("Lookup alias members in domain=%s for sid=%s.\n",
+              domain->name,
+              dom_sid_str_buf(alias_sid, &buf));
+
+       *pnum_sids = 0;
+
+       if (!winbindd_can_contact_domain(domain)) {
+               D_DEBUG("No incoming trust for domain %s\n", domain->name);
+               status = NT_STATUS_OK;
+               goto done;
+       }
+
+       status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       status = rpc_lookup_aliasmem(tmp_ctx,
+                                    samr_pipe,
+                                    &dom_pol,
+                                    &domain->sid,
+                                    alias_sid,
+                                    type,
+                                    &num_groups,
+                                    &alias_members);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       *pnum_sids = num_groups;
+       if (sid_mem) {
+               *sid_mem = talloc_move(mem_ctx, &alias_members);
+       }
+
+done:
+       talloc_free(tmp_ctx);
+       return status;
+}
 
 /* Lookup group membership given a rid.   */
 static NTSTATUS msrpc_lookup_groupmem(struct winbindd_domain *domain,
@@ -1069,6 +1123,7 @@ struct winbindd_methods msrpc_methods = {
        msrpc_lookup_usergroups,
        msrpc_lookup_useraliases,
        msrpc_lookup_groupmem,
+       msrpc_lookup_aliasmem,
        msrpc_lockout_policy,
        msrpc_password_policy,
        msrpc_trusted_domains,
index 9086c40ba57fec06dcb5d861f384d5f6f85f100e..c49831b3c136645354ac489d3a2b1d3f4923046e 100644 (file)
@@ -235,6 +235,34 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
        return result;
 }
 
+/* Lookup alias membership given */
+static NTSTATUS lookup_aliasmem(struct winbindd_domain *domain,
+                               TALLOC_CTX *mem_ctx,
+                               const struct dom_sid *sid,
+                               enum lsa_SidType type,
+                               uint32_t *num_sids,
+                               struct dom_sid **sids)
+{
+       NTSTATUS result;
+
+       result = msrpc_methods.lookup_aliasmem(domain,
+                                              mem_ctx,
+                                              sid,
+                                              type,
+                                              num_sids,
+                                              sids);
+
+       if (reconnect_need_retry(result, domain))
+               result = msrpc_methods.lookup_aliasmem(domain,
+                                                      mem_ctx,
+                                                      sid,
+                                                      type,
+                                                      num_sids,
+                                                      sids);
+
+       return result;
+}
+
 /* Lookup group membership given a rid.   */
 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                                TALLOC_CTX *mem_ctx,
@@ -319,6 +347,7 @@ struct winbindd_methods reconnect_methods = {
        lookup_usergroups,
        lookup_useraliases,
        lookup_groupmem,
+       lookup_aliasmem,
        lockout_policy,
        password_policy,
        trusted_domains,
index dbea90caded8ef114c591d585501eedca1a6618a..367f4c68e88cd675c92a41a332e07accd2f9488d 100644 (file)
@@ -266,6 +266,33 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
        return result;
 }
 
+static NTSTATUS lookup_aliasmem(struct winbindd_domain *domain,
+                               TALLOC_CTX *mem_ctx,
+                               const struct dom_sid *group_sid,
+                               enum lsa_SidType type,
+                               uint32_t *num_names,
+                               struct dom_sid **sid_mem)
+{
+       NTSTATUS result = NT_STATUS_OK;
+
+       result = ads_methods.lookup_aliasmem(domain,
+                                            mem_ctx,
+                                            group_sid,
+                                            type,
+                                            num_names,
+                                            sid_mem);
+
+       if (ldap_reconnect_need_retry(result, domain)) {
+               result = ads_methods.lookup_aliasmem(domain,
+                                                    mem_ctx,
+                                                    group_sid,
+                                                    type,
+                                                    num_names,
+                                                    sid_mem);
+       }
+       return result;
+}
+
 /* find the lockout policy of a domain */
 static NTSTATUS lockout_policy(struct winbindd_domain *domain,
                               TALLOC_CTX *mem_ctx,
@@ -326,6 +353,7 @@ struct winbindd_methods reconnect_ads_methods = {
        lookup_usergroups,
        lookup_useraliases,
        lookup_groupmem,
+       lookup_aliasmem,
        lockout_policy,
        password_policy,
        trusted_domains,
index d1c2f05ac536d7220152c397cfb254a20eec4146..6a0f2b2e7aa277b959743a7f3c913e8de560cf53 100644 (file)
@@ -606,6 +606,81 @@ NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
+/* Lookup alias membership using a rid taken from alias_sid. */
+NTSTATUS rpc_lookup_aliasmem(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 *alias_sid,
+                            enum lsa_SidType type,
+                            uint32_t *pnum_sids,
+                            struct dom_sid **psids)
+{
+       uint32_t alias_rid;
+       struct dom_sid *sid_mem = NULL;
+       struct lsa_SidArray sid_array;
+       uint32_t i;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
+
+       if (!sid_peek_check_rid(domain_sid, alias_sid, &alias_rid)) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       switch (type) {
+       case SID_NAME_ALIAS: {
+               struct policy_handle alias_policy;
+
+               status = dcerpc_samr_OpenAlias(b,
+                                              mem_ctx,
+                                              samr_policy,
+                                              SEC_FLAG_MAXIMUM_ALLOWED,
+                                              alias_rid,
+                                              &alias_policy,
+                                              &result);
+               if (any_nt_status_not_ok(status, result, &status)) {
+                       return status;
+               }
+
+               status = dcerpc_samr_GetMembersInAlias(b,
+                                                      mem_ctx,
+                                                      &alias_policy,
+                                                      &sid_array,
+                                                      &result);
+               {
+                       NTSTATUS _result;
+                       dcerpc_samr_Close(b, mem_ctx, &alias_policy, &_result);
+               }
+               if (any_nt_status_not_ok(status, result, &status)) {
+                       return status;
+               }
+
+               sid_mem = talloc_zero_array(mem_ctx,
+                                           struct dom_sid,
+                                           sid_array.num_sids);
+               if (sid_mem == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               /*
+                * We cannot just simply assign '*psids = sid_array.sids;'
+                * we need to copy every sid since these are incompatible types:
+                * 'struct dom_sid *' vs 'struct lsa_SidPtr *'
+                */
+               for (i = 0; i < sid_array.num_sids; i++) {
+                       sid_copy(&sid_mem[i], sid_array.sids[i].sid);
+               }
+
+               *pnum_sids = sid_array.num_sids;
+               *psids = sid_mem;
+
+               return NT_STATUS_OK;
+       }
+       default:
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+}
+
 /* Get a list of trusted domains */
 NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
                             struct rpc_pipe_client *lsa_pipe,
index 67d4ac6743301c9d30dd7809c3225d5210af140b..020958f44893d8d89e29fef4e1667cafa3c02ba0 100644 (file)
@@ -76,6 +76,15 @@ NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
                             char ***pnames,
                             uint32_t **pname_types);
 
+NTSTATUS rpc_lookup_aliasmem(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 *group_sid,
+                            enum lsa_SidType type,
+                            uint32_t *pnum_sids,
+                            struct dom_sid **psids);
+
 /* Get a list of trusted domains */
 NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
                             struct rpc_pipe_client *lsa_pipe,
index 92dd1851abd2dec7c959e8239dc5750e3da22d29..83bffb13481118e57fd89ae5cd0e069b3b89d696 100644 (file)
@@ -488,6 +488,73 @@ done:
        return status;
 }
 
+/* Lookup alias membership */
+static NTSTATUS sam_lookup_aliasmem(struct winbindd_domain *domain,
+                                   TALLOC_CTX *mem_ctx,
+                                   const struct dom_sid *group_sid,
+                                   enum lsa_SidType type,
+                                   uint32_t *pnum_sids,
+                                   struct dom_sid **psid_mem)
+{
+       struct rpc_pipe_client *samr_pipe;
+       struct policy_handle dom_pol = {0};
+
+       uint32_t num_sids = 0;
+       struct dom_sid *sid_mem = NULL;
+
+       TALLOC_CTX *tmp_ctx = talloc_stackframe();
+       NTSTATUS status;
+       bool retry = false;
+
+       DBG_INFO("sam_lookup_aliasmem\n");
+
+       /* Paranoia check */
+       if (type != SID_NAME_ALIAS) {
+               status = NT_STATUS_NO_SUCH_ALIAS;
+               goto done;
+       }
+
+       if (pnum_sids) {
+               *pnum_sids = 0;
+       }
+
+again:
+       status = open_cached_internal_pipe_conn(domain,
+                                               &samr_pipe,
+                                               &dom_pol,
+                                               NULL,
+                                               NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       status = rpc_lookup_aliasmem(tmp_ctx,
+                                    samr_pipe,
+                                    &dom_pol,
+                                    &domain->sid,
+                                    group_sid,
+                                    type,
+                                    &num_sids,
+                                    &sid_mem);
+
+       if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+               retry = true;
+               goto again;
+       }
+
+       if (pnum_sids) {
+               *pnum_sids = num_sids;
+       }
+
+       if (psid_mem) {
+               *psid_mem = talloc_move(mem_ctx, &sid_mem);
+       }
+
+done:
+       TALLOC_FREE(tmp_ctx);
+       return status;
+}
+
 /*********************************************************************
  BUILTIN specific functions.
 *********************************************************************/
@@ -1331,6 +1398,7 @@ struct winbindd_methods builtin_passdb_methods = {
        .lookup_usergroups     = sam_lookup_usergroups,
        .lookup_useraliases    = sam_lookup_useraliases,
        .lookup_groupmem       = sam_lookup_groupmem,
+       .lookup_aliasmem       = sam_lookup_aliasmem,
        .lockout_policy        = sam_lockout_policy,
        .password_policy       = sam_password_policy,
        .trusted_domains       = builtin_trusted_domains
@@ -1349,6 +1417,7 @@ struct winbindd_methods sam_passdb_methods = {
        .lookup_usergroups     = sam_lookup_usergroups,
        .lookup_useraliases    = sam_lookup_useraliases,
        .lookup_groupmem       = sam_lookup_groupmem,
+       .lookup_aliasmem       = sam_lookup_aliasmem,
        .lockout_policy        = sam_lockout_policy,
        .password_policy       = sam_password_policy,
        .trusted_domains       = sam_trusted_domains