LCOV - code coverage report
Current view: top level - source3/winbindd - winbindd_rpc.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 0 396 0.0 %
Date: 2024-04-13 12:30:31 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Unix SMB/CIFS implementation.
       3             :  *
       4             :  * Winbind rpc backend functions
       5             :  *
       6             :  * Copyright (c) 2000-2003 Tim Potter
       7             :  * Copyright (c) 2001      Andrew Tridgell
       8             :  * Copyright (c) 2005      Volker Lendecke
       9             :  * Copyright (c) 2008      Guenther Deschner (pidl conversion)
      10             :  * Copyright (c) 2010      Andreas Schneider <asn@samba.org>
      11             :  *
      12             :  * This program is free software; you can redistribute it and/or modify
      13             :  * it under the terms of the GNU General Public License as published by
      14             :  * the Free Software Foundation; either version 3 of the License, or
      15             :  * (at your option) any later version.
      16             :  *
      17             :  * This program is distributed in the hope that it will be useful,
      18             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20             :  * GNU General Public License for more details.
      21             :  *
      22             :  * You should have received a copy of the GNU General Public License
      23             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24             :  */
      25             : 
      26             : #include "includes.h"
      27             : #include "winbindd.h"
      28             : #include "winbindd_rpc.h"
      29             : #include "rpc_client/rpc_client.h"
      30             : #include "librpc/gen_ndr/ndr_samr_c.h"
      31             : #include "librpc/gen_ndr/ndr_lsa_c.h"
      32             : #include "rpc_client/cli_samr.h"
      33             : #include "rpc_client/cli_lsarpc.h"
      34             : #include "../libcli/security/security.h"
      35             : #include "lsa.h"
      36             : 
      37             : /* Query display info for a domain */
      38           0 : NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx,
      39             :                              struct rpc_pipe_client *samr_pipe,
      40             :                              struct policy_handle *samr_policy,
      41             :                              const struct dom_sid *domain_sid,
      42             :                              uint32_t **prids)
      43             : {
      44           0 :         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
      45           0 :         uint32_t *rids = NULL;
      46           0 :         uint32_t num_rids = 0;
      47           0 :         uint32_t i = 0;
      48           0 :         uint32_t resume_handle = 0;
      49           0 :         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
      50           0 :         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
      51           0 :         TALLOC_CTX *tmp_ctx;
      52             : 
      53           0 :         *prids = NULL;
      54             : 
      55           0 :         tmp_ctx = talloc_stackframe();
      56           0 :         if (tmp_ctx == NULL) {
      57           0 :                 return NT_STATUS_NO_MEMORY;
      58             :         }
      59             : 
      60           0 :         do {
      61           0 :                 struct samr_SamArray *sam_array = NULL;
      62           0 :                 uint32_t count = 0;
      63           0 :                 uint32_t *tmp;
      64             : 
      65           0 :                 status = dcerpc_samr_EnumDomainUsers(
      66             :                         b, tmp_ctx, samr_policy, &resume_handle,
      67             :                         ACB_NORMAL, &sam_array, 0xffff, &count, &result);
      68           0 :                 if (!NT_STATUS_IS_OK(status)) {
      69           0 :                         goto done;
      70             :                 }
      71           0 :                 if (!NT_STATUS_IS_OK(result)) {
      72           0 :                         if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
      73           0 :                                 DBG_WARNING("EnumDomainUsers failed: %s\n",
      74             :                                             nt_errstr(result));
      75           0 :                                 status = result;
      76           0 :                                 goto done;
      77             :                         }
      78             :                 }
      79             : 
      80           0 :                 if (num_rids + count < num_rids) {
      81           0 :                         status = NT_STATUS_INTEGER_OVERFLOW;
      82           0 :                         goto done;
      83             :                 }
      84             : 
      85           0 :                 tmp = talloc_realloc(tmp_ctx, rids, uint32_t, num_rids+count);
      86           0 :                 if (tmp == NULL) {
      87           0 :                         status = NT_STATUS_NO_MEMORY;
      88           0 :                         goto done;
      89             :                 }
      90           0 :                 rids = tmp;
      91             : 
      92           0 :                 for (i=0; i<count; i++) {
      93           0 :                         rids[num_rids++] = sam_array->entries[i].idx;
      94             :                 }
      95             : 
      96           0 :                 TALLOC_FREE(sam_array);
      97           0 :         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
      98             : 
      99           0 :         *prids = talloc_steal(mem_ctx, rids);
     100           0 :         status = NT_STATUS_OK;
     101             : 
     102           0 : done:
     103           0 :         TALLOC_FREE(tmp_ctx);
     104           0 :         return status;
     105             : }
     106             : 
     107             : /* List all domain groups */
     108           0 : NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx,
     109             :                              struct rpc_pipe_client *samr_pipe,
     110             :                              struct policy_handle *samr_policy,
     111             :                              uint32_t *pnum_info,
     112             :                              struct wb_acct_info **pinfo)
     113             : {
     114           0 :         struct wb_acct_info *info = NULL;
     115           0 :         uint32_t start = 0;
     116           0 :         uint32_t num_info = 0;
     117           0 :         NTSTATUS status, result;
     118           0 :         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     119             : 
     120           0 :         *pnum_info = 0;
     121             : 
     122           0 :         do {
     123           0 :                 struct samr_SamArray *sam_array = NULL;
     124           0 :                 uint32_t count = 0;
     125           0 :                 uint32_t g;
     126             : 
     127             :                 /* start is updated by this call. */
     128           0 :                 status = dcerpc_samr_EnumDomainGroups(b,
     129             :                                                       mem_ctx,
     130             :                                                       samr_policy,
     131             :                                                       &start,
     132             :                                                       &sam_array,
     133             :                                                       0xFFFF, /* buffer size? */
     134             :                                                       &count,
     135             :                                                       &result);
     136           0 :                 if (!NT_STATUS_IS_OK(status)) {
     137           0 :                         return status;
     138             :                 }
     139           0 :                 if (!NT_STATUS_IS_OK(result)) {
     140           0 :                         if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     141           0 :                                 DEBUG(2,("query_user_list: failed to enum domain groups: %s\n",
     142             :                                          nt_errstr(result)));
     143           0 :                                 return result;
     144             :                         }
     145             :                 }
     146             : 
     147           0 :                 info = talloc_realloc(mem_ctx,
     148             :                                             info,
     149             :                                             struct wb_acct_info,
     150             :                                             num_info + count);
     151           0 :                 if (info == NULL) {
     152           0 :                         return NT_STATUS_NO_MEMORY;
     153             :                 }
     154             : 
     155           0 :                 for (g = 0; g < count; g++) {
     156           0 :                         struct wb_acct_info *i = &info[num_info + g];
     157             : 
     158           0 :                         i->acct_name = talloc_strdup(info,
     159           0 :                                 sam_array->entries[g].name.string);
     160           0 :                         if (i->acct_name == NULL) {
     161           0 :                                 TALLOC_FREE(info);
     162           0 :                                 return NT_STATUS_NO_MEMORY;
     163             :                         }
     164           0 :                         i->acct_desc = NULL;
     165           0 :                         i->rid = sam_array->entries[g].idx;
     166             :                 }
     167             : 
     168           0 :                 num_info += count;
     169           0 :         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
     170             : 
     171           0 :         *pnum_info = num_info;
     172           0 :         *pinfo = info;
     173             : 
     174           0 :         return NT_STATUS_OK;
     175             : }
     176             : 
     177           0 : NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx,
     178             :                                struct rpc_pipe_client *samr_pipe,
     179             :                                struct policy_handle *samr_policy,
     180             :                                uint32_t *pnum_info,
     181             :                                struct wb_acct_info **pinfo)
     182             : {
     183           0 :         struct wb_acct_info *info = NULL;
     184           0 :         uint32_t num_info = 0;
     185           0 :         NTSTATUS status, result;
     186           0 :         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     187             : 
     188           0 :         *pnum_info = 0;
     189             : 
     190           0 :         do {
     191           0 :                 struct samr_SamArray *sam_array = NULL;
     192           0 :                 uint32_t count = 0;
     193           0 :                 uint32_t start = num_info;
     194           0 :                 uint32_t g;
     195             : 
     196           0 :                 status = dcerpc_samr_EnumDomainAliases(b,
     197             :                                                        mem_ctx,
     198             :                                                        samr_policy,
     199             :                                                        &start,
     200             :                                                        &sam_array,
     201             :                                                        0xFFFF, /* buffer size? */
     202             :                                                        &count,
     203             :                                                        &result);
     204           0 :                 if (!NT_STATUS_IS_OK(status)) {
     205           0 :                         return status;
     206             :                 }
     207           0 :                 if (!NT_STATUS_IS_OK(result)) {
     208           0 :                         if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     209           0 :                                 return result;
     210             :                         }
     211             :                 }
     212             : 
     213           0 :                 info = talloc_realloc(mem_ctx,
     214             :                                             info,
     215             :                                             struct wb_acct_info,
     216             :                                             num_info + count);
     217           0 :                 if (info == NULL) {
     218           0 :                         return  NT_STATUS_NO_MEMORY;
     219             :                 }
     220             : 
     221           0 :                 for (g = 0; g < count; g++) {
     222           0 :                         struct wb_acct_info *i = &info[num_info + g];
     223             : 
     224           0 :                         i->acct_name = talloc_strdup(info,
     225           0 :                                 sam_array->entries[g].name.string);
     226           0 :                         if (i->acct_name == NULL) {
     227           0 :                                 TALLOC_FREE(info);
     228           0 :                                 return NT_STATUS_NO_MEMORY;
     229             :                         }
     230           0 :                         i->acct_desc = NULL;
     231           0 :                         i->rid = sam_array->entries[g].idx;
     232             :                 }
     233             : 
     234           0 :                 num_info += count;
     235           0 :         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
     236             : 
     237           0 :         *pnum_info = num_info;
     238           0 :         *pinfo = info;
     239             : 
     240           0 :         return NT_STATUS_OK;
     241             : }
     242             : 
     243             : /* Lookup groups a user is a member of. */
     244           0 : NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx,
     245             :                                struct rpc_pipe_client *samr_pipe,
     246             :                                struct policy_handle *samr_policy,
     247             :                                const struct dom_sid *domain_sid,
     248             :                                const struct dom_sid *user_sid,
     249             :                                uint32_t *pnum_groups,
     250             :                                struct dom_sid **puser_grpsids)
     251             : {
     252           0 :         struct policy_handle user_policy;
     253           0 :         struct samr_RidWithAttributeArray *rid_array = NULL;
     254           0 :         struct dom_sid *user_grpsids = NULL;
     255           0 :         uint32_t num_groups = 0, i;
     256           0 :         uint32_t user_rid;
     257           0 :         NTSTATUS status, result;
     258           0 :         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     259             : 
     260           0 :         if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
     261           0 :                 return NT_STATUS_UNSUCCESSFUL;
     262             :         }
     263             : 
     264             :         /* Get user handle */
     265           0 :         status = dcerpc_samr_OpenUser(b,
     266             :                                       mem_ctx,
     267             :                                       samr_policy,
     268             :                                       SEC_FLAG_MAXIMUM_ALLOWED,
     269             :                                       user_rid,
     270             :                                       &user_policy,
     271             :                                       &result);
     272           0 :         if (!NT_STATUS_IS_OK(status)) {
     273           0 :                 return status;
     274             :         }
     275           0 :         if (!NT_STATUS_IS_OK(result)) {
     276           0 :                 return result;
     277             :         }
     278             : 
     279             :         /* Query user rids */
     280           0 :         status = dcerpc_samr_GetGroupsForUser(b,
     281             :                                               mem_ctx,
     282             :                                               &user_policy,
     283             :                                               &rid_array,
     284             :                                               &result);
     285             :         {
     286           0 :                 NTSTATUS _result;
     287           0 :                 dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
     288             :         }
     289             : 
     290           0 :         if (!NT_STATUS_IS_OK(status)) {
     291           0 :                 return status;
     292             :         }
     293           0 :         if (!NT_STATUS_IS_OK(result)) {
     294           0 :                 return result;
     295             :         }
     296             : 
     297           0 :         num_groups = rid_array->count;
     298             : 
     299           0 :         user_grpsids = talloc_array(mem_ctx, struct dom_sid, num_groups);
     300           0 :         if (user_grpsids == NULL) {
     301           0 :                 status = NT_STATUS_NO_MEMORY;
     302           0 :                 return status;
     303             :         }
     304             : 
     305           0 :         for (i = 0; i < num_groups; i++) {
     306           0 :                 sid_compose(&(user_grpsids[i]), domain_sid,
     307           0 :                             rid_array->rids[i].rid);
     308             :         }
     309             : 
     310           0 :         *pnum_groups = num_groups;
     311             : 
     312           0 :         *puser_grpsids = user_grpsids;
     313             : 
     314           0 :         return NT_STATUS_OK;
     315             : }
     316             : 
     317           0 : NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx,
     318             :                                 struct rpc_pipe_client *samr_pipe,
     319             :                                 struct policy_handle *samr_policy,
     320             :                                 uint32_t num_sids,
     321             :                                 const struct dom_sid *sids,
     322             :                                 uint32_t *pnum_aliases,
     323             :                                 uint32_t **palias_rids)
     324             : {
     325             : #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
     326           0 :         uint32_t num_query_sids = 0;
     327           0 :         uint32_t num_queries = 1;
     328           0 :         uint32_t num_aliases = 0;
     329           0 :         uint32_t total_sids = 0;
     330           0 :         uint32_t *alias_rids = NULL;
     331           0 :         uint32_t rangesize = MAX_SAM_ENTRIES_W2K;
     332           0 :         uint32_t i;
     333           0 :         struct samr_Ids alias_rids_query;
     334           0 :         NTSTATUS status, result;
     335           0 :         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     336             : 
     337           0 :         do {
     338             :                 /* prepare query */
     339           0 :                 struct lsa_SidArray sid_array;
     340             : 
     341           0 :                 ZERO_STRUCT(sid_array);
     342             : 
     343           0 :                 num_query_sids = MIN(num_sids - total_sids, rangesize);
     344             : 
     345           0 :                 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
     346             :                         num_queries, num_query_sids));
     347             : 
     348           0 :                 if (num_query_sids) {
     349           0 :                         sid_array.sids = talloc_zero_array(mem_ctx, struct lsa_SidPtr, num_query_sids);
     350           0 :                         if (sid_array.sids == NULL) {
     351           0 :                                 return NT_STATUS_NO_MEMORY;
     352             :                         }
     353             :                 } else {
     354           0 :                         sid_array.sids = NULL;
     355             :                 }
     356             : 
     357           0 :                 for (i = 0; i < num_query_sids; i++) {
     358           0 :                         sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]);
     359           0 :                         if (sid_array.sids[i].sid == NULL) {
     360           0 :                                 return NT_STATUS_NO_MEMORY;
     361             :                         }
     362             :                 }
     363           0 :                 sid_array.num_sids = num_query_sids;
     364             : 
     365             :                 /* do request */
     366           0 :                 status = dcerpc_samr_GetAliasMembership(b,
     367             :                                                         mem_ctx,
     368             :                                                         samr_policy,
     369             :                                                         &sid_array,
     370             :                                                         &alias_rids_query,
     371             :                                                         &result);
     372           0 :                 if (!NT_STATUS_IS_OK(status)) {
     373           0 :                         return status;
     374             :                 }
     375           0 :                 if (!NT_STATUS_IS_OK(result)) {
     376           0 :                         return result;
     377             :                 }
     378             : 
     379             :                 /* process output */
     380           0 :                 for (i = 0; i < alias_rids_query.count; i++) {
     381           0 :                         size_t na = num_aliases;
     382             : 
     383           0 :                         if (!add_rid_to_array_unique(mem_ctx,
     384           0 :                                                      alias_rids_query.ids[i],
     385             :                                                      &alias_rids,
     386             :                                                      &na)) {
     387           0 :                                         return NT_STATUS_NO_MEMORY;
     388             :                                 }
     389           0 :                                 num_aliases = na;
     390             :                 }
     391             : 
     392           0 :                 num_queries++;
     393             : 
     394           0 :         } while (total_sids < num_sids);
     395             : 
     396           0 :         DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
     397             :                   "(rangesize: %d)\n", num_aliases, num_queries, rangesize));
     398             : 
     399           0 :         *pnum_aliases = num_aliases;
     400           0 :         *palias_rids = alias_rids;
     401             : 
     402           0 :         return NT_STATUS_OK;
     403             : #undef MAX_SAM_ENTRIES_W2K
     404             : }
     405             : 
     406             : /* Lookup group membership given a rid.   */
     407           0 : NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
     408             :                              struct rpc_pipe_client *samr_pipe,
     409             :                              struct policy_handle *samr_policy,
     410             :                              const char *domain_name,
     411             :                              const struct dom_sid *domain_sid,
     412             :                              const struct dom_sid *group_sid,
     413             :                              enum lsa_SidType type,
     414             :                              uint32_t *pnum_names,
     415             :                              struct dom_sid **psid_mem,
     416             :                              char ***pnames,
     417             :                              uint32_t **pname_types)
     418             : {
     419           0 :         struct policy_handle group_policy;
     420           0 :         uint32_t group_rid;
     421           0 :         uint32_t *rid_mem = NULL;
     422             : 
     423           0 :         uint32_t num_names = 0;
     424           0 :         uint32_t total_names = 0;
     425           0 :         struct dom_sid *sid_mem = NULL;
     426           0 :         char **names = NULL;
     427           0 :         uint32_t *name_types = NULL;
     428             : 
     429           0 :         struct lsa_Strings tmp_names;
     430           0 :         struct samr_Ids tmp_types;
     431             : 
     432           0 :         uint32_t j, r;
     433           0 :         NTSTATUS status, result;
     434           0 :         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     435             : 
     436           0 :         if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
     437           0 :                 return NT_STATUS_UNSUCCESSFUL;
     438             :         }
     439             : 
     440           0 :         switch(type) {
     441           0 :         case SID_NAME_DOM_GRP:
     442             :         {
     443           0 :                 struct samr_RidAttrArray *rids = NULL;
     444             : 
     445           0 :                 status = dcerpc_samr_OpenGroup(b,
     446             :                                                mem_ctx,
     447             :                                                samr_policy,
     448             :                                                SEC_FLAG_MAXIMUM_ALLOWED,
     449             :                                                group_rid,
     450             :                                                &group_policy,
     451             :                                                &result);
     452           0 :                 if (!NT_STATUS_IS_OK(status)) {
     453           0 :                         return status;
     454             :                 }
     455           0 :                 if (!NT_STATUS_IS_OK(result)) {
     456           0 :                         return result;
     457             :                 }
     458             : 
     459             :                 /*
     460             :                  * Step #1: Get a list of user rids that are the members of the group.
     461             :                  */
     462           0 :                 status = dcerpc_samr_QueryGroupMember(b,
     463             :                                                       mem_ctx,
     464             :                                                       &group_policy,
     465             :                                                       &rids,
     466             :                                                       &result);
     467             :                 {
     468           0 :                         NTSTATUS _result;
     469           0 :                         dcerpc_samr_Close(b, mem_ctx, &group_policy, &_result);
     470             :                 }
     471             : 
     472           0 :                 if (!NT_STATUS_IS_OK(status)) {
     473           0 :                         return status;
     474             :                 }
     475           0 :                 if (!NT_STATUS_IS_OK(result)) {
     476           0 :                         return result;
     477             :                 }
     478             : 
     479             : 
     480           0 :                 if (rids == NULL || rids->count == 0) {
     481           0 :                         pnum_names = 0;
     482           0 :                         pnames = NULL;
     483           0 :                         pname_types = NULL;
     484           0 :                         psid_mem = NULL;
     485             : 
     486           0 :                         return NT_STATUS_OK;
     487             :                 }
     488             : 
     489           0 :                 num_names = rids->count;
     490           0 :                 rid_mem = rids->rids;
     491             : 
     492           0 :                 break;
     493             :         }
     494           0 :         default:
     495           0 :                 return NT_STATUS_UNSUCCESSFUL;
     496             :         }
     497             : 
     498             :         /*
     499             :          * Step #2: Convert list of rids into list of usernames.
     500             :          */
     501           0 :         if (num_names > 0) {
     502           0 :                 names = talloc_zero_array(mem_ctx, char *, num_names);
     503           0 :                 name_types = talloc_zero_array(mem_ctx, uint32_t, num_names);
     504           0 :                 sid_mem = talloc_zero_array(mem_ctx, struct dom_sid, num_names);
     505           0 :                 if (names == NULL || name_types == NULL || sid_mem == NULL) {
     506           0 :                         return NT_STATUS_NO_MEMORY;
     507             :                 }
     508             :         }
     509             : 
     510           0 :         for (j = 0; j < num_names; j++) {
     511           0 :                 sid_compose(&sid_mem[j], domain_sid, rid_mem[j]);
     512             :         }
     513             : 
     514           0 :         status = dcerpc_samr_LookupRids(b,
     515             :                                         mem_ctx,
     516             :                                         samr_policy,
     517             :                                         num_names,
     518             :                                         rid_mem,
     519             :                                         &tmp_names,
     520             :                                         &tmp_types,
     521             :                                         &result);
     522           0 :         if (!NT_STATUS_IS_OK(status)) {
     523           0 :                 return status;
     524             :         }
     525             : 
     526           0 :         if (!NT_STATUS_IS_OK(result)) {
     527           0 :                 if (!NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
     528           0 :                         return result;
     529             :                 }
     530             :         }
     531             : 
     532             :         /* Copy result into array.  The talloc system will take
     533             :            care of freeing the temporary arrays later on. */
     534           0 :         if (tmp_names.count != num_names) {
     535           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
     536             :         }
     537           0 :         if (tmp_types.count != num_names) {
     538           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
     539             :         }
     540             : 
     541           0 :         for (r = 0; r < tmp_names.count; r++) {
     542           0 :                 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
     543           0 :                         continue;
     544             :                 }
     545           0 :                 if (total_names >= num_names) {
     546           0 :                         break;
     547             :                 }
     548           0 :                 names[total_names] = fill_domain_username_talloc(names,
     549             :                                                                  domain_name,
     550           0 :                                                                  tmp_names.names[r].string,
     551             :                                                                  true);
     552           0 :                 if (names[total_names] == NULL) {
     553           0 :                         return NT_STATUS_NO_MEMORY;
     554             :                 }
     555           0 :                 name_types[total_names] = tmp_types.ids[r];
     556           0 :                 total_names++;
     557             :         }
     558             : 
     559           0 :         *pnum_names = total_names;
     560           0 :         *pnames = names;
     561           0 :         *pname_types = name_types;
     562           0 :         *psid_mem = sid_mem;
     563             : 
     564           0 :         return NT_STATUS_OK;
     565             : }
     566             : 
     567             : /* Lookup alias membership using a rid taken from alias_sid. */
     568           0 : NTSTATUS rpc_lookup_aliasmem(TALLOC_CTX *mem_ctx,
     569             :                              struct rpc_pipe_client *samr_pipe,
     570             :                              struct policy_handle *samr_policy,
     571             :                              const struct dom_sid *domain_sid,
     572             :                              const struct dom_sid *alias_sid,
     573             :                              enum lsa_SidType type,
     574             :                              uint32_t *pnum_sids,
     575             :                              struct dom_sid **psids)
     576             : {
     577           0 :         uint32_t alias_rid;
     578           0 :         struct dom_sid *sid_mem = NULL;
     579           0 :         struct lsa_SidArray sid_array;
     580           0 :         uint32_t i;
     581           0 :         NTSTATUS status, result;
     582           0 :         struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     583             : 
     584           0 :         if (!sid_peek_check_rid(domain_sid, alias_sid, &alias_rid)) {
     585           0 :                 return NT_STATUS_UNSUCCESSFUL;
     586             :         }
     587             : 
     588           0 :         switch (type) {
     589           0 :         case SID_NAME_ALIAS: {
     590           0 :                 struct policy_handle alias_policy;
     591             : 
     592           0 :                 status = dcerpc_samr_OpenAlias(b,
     593             :                                                mem_ctx,
     594             :                                                samr_policy,
     595             :                                                SEC_FLAG_MAXIMUM_ALLOWED,
     596             :                                                alias_rid,
     597             :                                                &alias_policy,
     598             :                                                &result);
     599           0 :                 if (any_nt_status_not_ok(status, result, &status)) {
     600           0 :                         return status;
     601             :                 }
     602             : 
     603           0 :                 status = dcerpc_samr_GetMembersInAlias(b,
     604             :                                                        mem_ctx,
     605             :                                                        &alias_policy,
     606             :                                                        &sid_array,
     607             :                                                        &result);
     608             :                 {
     609           0 :                         NTSTATUS _result;
     610           0 :                         dcerpc_samr_Close(b, mem_ctx, &alias_policy, &_result);
     611             :                 }
     612           0 :                 if (any_nt_status_not_ok(status, result, &status)) {
     613           0 :                         return status;
     614             :                 }
     615             : 
     616           0 :                 sid_mem = talloc_zero_array(mem_ctx,
     617             :                                             struct dom_sid,
     618             :                                             sid_array.num_sids);
     619           0 :                 if (sid_mem == NULL) {
     620           0 :                         return NT_STATUS_NO_MEMORY;
     621             :                 }
     622             : 
     623             :                 /*
     624             :                  * We cannot just simply assign '*psids = sid_array.sids;'
     625             :                  * we need to copy every sid since these are incompatible types:
     626             :                  * 'struct dom_sid *' vs 'struct lsa_SidPtr *'
     627             :                  */
     628           0 :                 for (i = 0; i < sid_array.num_sids; i++) {
     629           0 :                         sid_copy(&sid_mem[i], sid_array.sids[i].sid);
     630             :                 }
     631             : 
     632           0 :                 *pnum_sids = sid_array.num_sids;
     633           0 :                 *psids = sid_mem;
     634             : 
     635           0 :                 return NT_STATUS_OK;
     636             :         }
     637           0 :         default:
     638           0 :                 return NT_STATUS_UNSUCCESSFUL;
     639             :         }
     640             : }
     641             : 
     642             : /* Get a list of trusted domains */
     643           0 : NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
     644             :                              struct rpc_pipe_client *lsa_pipe,
     645             :                              struct policy_handle *lsa_policy,
     646             :                              uint32_t *pnum_trusts,
     647             :                              struct netr_DomainTrust **ptrusts)
     648             : {
     649           0 :         struct netr_DomainTrust *array = NULL;
     650           0 :         uint32_t enum_ctx = 0;
     651           0 :         uint32_t count = 0;
     652           0 :         NTSTATUS status, result;
     653           0 :         struct dcerpc_binding_handle *b = lsa_pipe->binding_handle;
     654             : 
     655           0 :         do {
     656           0 :                 struct lsa_DomainList dom_list;
     657           0 :                 struct lsa_DomainListEx dom_list_ex;
     658           0 :                 bool has_ex = false;
     659           0 :                 uint32_t i;
     660             : 
     661             :                 /*
     662             :                  * We don't run into deadlocks here, cause winbind_off() is
     663             :                  * called in the main function.
     664             :                  */
     665           0 :                 status = dcerpc_lsa_EnumTrustedDomainsEx(b,
     666             :                                                          mem_ctx,
     667             :                                                          lsa_policy,
     668             :                                                          &enum_ctx,
     669             :                                                          &dom_list_ex,
     670             :                                                          (uint32_t) -1,
     671             :                                                          &result);
     672           0 :                 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_ERR(result) &&
     673           0 :                     dom_list_ex.count > 0) {
     674           0 :                         count += dom_list_ex.count;
     675           0 :                         has_ex = true;
     676             :                 } else {
     677           0 :                         status = dcerpc_lsa_EnumTrustDom(b,
     678             :                                                          mem_ctx,
     679             :                                                          lsa_policy,
     680             :                                                          &enum_ctx,
     681             :                                                          &dom_list,
     682             :                                                          (uint32_t) -1,
     683             :                                                          &result);
     684           0 :                         if (!NT_STATUS_IS_OK(status)) {
     685           0 :                                 return status;
     686             :                         }
     687           0 :                         if (!NT_STATUS_IS_OK(result)) {
     688           0 :                                 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     689           0 :                                         return result;
     690             :                                 }
     691             :                         }
     692             : 
     693           0 :                         count += dom_list.count;
     694             :                 }
     695             : 
     696           0 :                 array = talloc_realloc(mem_ctx,
     697             :                                        array,
     698             :                                        struct netr_DomainTrust,
     699             :                                        count);
     700           0 :                 if (array == NULL) {
     701           0 :                         return NT_STATUS_NO_MEMORY;
     702             :                 }
     703             : 
     704           0 :                 for (i = 0; i < count; i++) {
     705           0 :                         struct netr_DomainTrust *trust = &array[i];
     706           0 :                         struct dom_sid *sid;
     707             : 
     708           0 :                         ZERO_STRUCTP(trust);
     709             : 
     710           0 :                         sid = talloc(array, struct dom_sid);
     711           0 :                         if (sid == NULL) {
     712           0 :                                 return NT_STATUS_NO_MEMORY;
     713             :                         }
     714             : 
     715           0 :                         if (dom_list_ex.domains[i].sid == NULL) {
     716           0 :                                 DBG_ERR("Trusted domain %s has no SID, "
     717             :                                         "skipping!\n",
     718             :                                         trust->dns_name);
     719           0 :                                 continue;
     720             :                         }
     721             : 
     722           0 :                         if (has_ex) {
     723           0 :                                 trust->netbios_name = talloc_move(array,
     724             :                                                                   &dom_list_ex.domains[i].netbios_name.string);
     725           0 :                                 trust->dns_name = talloc_move(array,
     726             :                                                               &dom_list_ex.domains[i].domain_name.string);
     727           0 :                                 sid_copy(sid, dom_list_ex.domains[i].sid);
     728             :                         } else {
     729           0 :                                 trust->netbios_name = talloc_move(array,
     730             :                                                                   &dom_list.domains[i].name.string);
     731           0 :                                 trust->dns_name = NULL;
     732             : 
     733           0 :                                 sid_copy(sid, dom_list.domains[i].sid);
     734             :                         }
     735             : 
     736           0 :                         trust->sid = sid;
     737             :                 }
     738           0 :         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
     739             : 
     740           0 :         *pnum_trusts = count;
     741           0 :         *ptrusts = array;
     742             : 
     743           0 :         return NT_STATUS_OK;
     744             : }
     745             : 
     746           0 : static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
     747             :                                      struct winbindd_domain *domain,
     748             :                                      struct rpc_pipe_client *cli,
     749             :                                      struct lsa_SidArray *sids,
     750             :                                      struct lsa_RefDomainList **pdomains,
     751             :                                      struct lsa_TransNameArray **pnames)
     752             : {
     753           0 :         struct lsa_TransNameArray2 lsa_names2;
     754           0 :         struct lsa_TransNameArray *names = *pnames;
     755           0 :         uint32_t i, count = 0;
     756           0 :         NTSTATUS status, result;
     757             : 
     758           0 :         ZERO_STRUCT(lsa_names2);
     759           0 :         status = dcerpc_lsa_LookupSids3(cli->binding_handle,
     760             :                                         mem_ctx,
     761             :                                         sids,
     762             :                                         pdomains,
     763             :                                         &lsa_names2,
     764             :                                         LSA_LOOKUP_NAMES_ALL,
     765             :                                         &count,
     766             :                                         LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES,
     767             :                                         LSA_CLIENT_REVISION_2,
     768             :                                         &result);
     769           0 :         if (!NT_STATUS_IS_OK(status)) {
     770           0 :                 return status;
     771             :         }
     772           0 :         if (NT_STATUS_LOOKUP_ERR(result)) {
     773           0 :                 return result;
     774             :         }
     775           0 :         if (sids->num_sids != lsa_names2.count) {
     776           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
     777             :         }
     778             : 
     779           0 :         names->count = lsa_names2.count;
     780           0 :         names->names = talloc_array(names, struct lsa_TranslatedName,
     781             :                                     names->count);
     782           0 :         if (names->names == NULL) {
     783           0 :                 return NT_STATUS_NO_MEMORY;
     784             :         }
     785           0 :         for (i=0; i<names->count; i++) {
     786           0 :                 names->names[i].sid_type = lsa_names2.names[i].sid_type;
     787           0 :                 names->names[i].name.string = talloc_move(
     788             :                         names->names, &lsa_names2.names[i].name.string);
     789           0 :                 names->names[i].sid_index = lsa_names2.names[i].sid_index;
     790             : 
     791           0 :                 if (names->names[i].sid_index == UINT32_MAX) {
     792           0 :                         continue;
     793             :                 }
     794           0 :                 if ((*pdomains) == NULL) {
     795           0 :                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
     796             :                 }
     797           0 :                 if (names->names[i].sid_index >= (*pdomains)->count) {
     798           0 :                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
     799             :                 }
     800             :         }
     801           0 :         return NT_STATUS_OK;
     802             : }
     803             : 
     804           0 : NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
     805             :                          struct winbindd_domain *domain,
     806             :                          struct lsa_SidArray *sids,
     807             :                          struct lsa_RefDomainList **pdomains,
     808             :                          struct lsa_TransNameArray **pnames)
     809             : {
     810           0 :         struct lsa_TransNameArray *names = *pnames;
     811           0 :         struct rpc_pipe_client *cli = NULL;
     812           0 :         struct policy_handle lsa_policy;
     813           0 :         uint32_t count;
     814           0 :         uint32_t i;
     815           0 :         NTSTATUS status, result;
     816             : 
     817           0 :         status = cm_connect_lsat(domain, mem_ctx, &cli, &lsa_policy);
     818           0 :         if (!NT_STATUS_IS_OK(status)) {
     819           0 :                 return status;
     820             :         }
     821             : 
     822           0 :         if (cli->transport->transport == NCACN_IP_TCP) {
     823           0 :                 return rpc_try_lookup_sids3(mem_ctx, domain, cli, sids,
     824             :                                             pdomains, pnames);
     825             :         }
     826             : 
     827           0 :         status = dcerpc_lsa_LookupSids(cli->binding_handle, mem_ctx,
     828             :                                        &lsa_policy, sids, pdomains,
     829             :                                        names, LSA_LOOKUP_NAMES_ALL,
     830             :                                        &count, &result);
     831           0 :         if (!NT_STATUS_IS_OK(status)) {
     832           0 :                 return status;
     833             :         }
     834           0 :         if (NT_STATUS_LOOKUP_ERR(result)) {
     835           0 :                 return result;
     836             :         }
     837             : 
     838           0 :         if (sids->num_sids != names->count) {
     839           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
     840             :         }
     841             : 
     842           0 :         for (i=0; i < names->count; i++) {
     843           0 :                 if (names->names[i].sid_index == UINT32_MAX) {
     844           0 :                         continue;
     845             :                 }
     846           0 :                 if ((*pdomains) == NULL) {
     847           0 :                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
     848             :                 }
     849           0 :                 if (names->names[i].sid_index >= (*pdomains)->count) {
     850           0 :                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
     851             :                 }
     852             :         }
     853             : 
     854           0 :         return NT_STATUS_OK;
     855             : }

Generated by: LCOV version 1.14