LCOV - code coverage report
Current view: top level - source3/winbindd - winbindd_msrpc.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 398 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 15 0.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Winbind rpc backend functions
       5             : 
       6             :    Copyright (C) Tim Potter 2000-2001,2003
       7             :    Copyright (C) Andrew Tridgell 2001
       8             :    Copyright (C) Volker Lendecke 2005
       9             :    Copyright (C) Guenther Deschner 2008 (pidl conversion)
      10             : 
      11             :    This program is free software; you can redistribute it and/or modify
      12             :    it under the terms of the GNU General Public License as published by
      13             :    the Free Software Foundation; either version 3 of the License, or
      14             :    (at your option) any later version.
      15             : 
      16             :    This program is distributed in the hope that it will be useful,
      17             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :    GNU General Public License for more details.
      20             : 
      21             :    You should have received a copy of the GNU General Public License
      22             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "includes.h"
      26             : #include "winbindd.h"
      27             : #include "winbindd_rpc.h"
      28             : 
      29             : #include "../librpc/gen_ndr/ndr_samr_c.h"
      30             : #include "rpc_client/cli_pipe.h"
      31             : #include "rpc_client/cli_samr.h"
      32             : #include "rpc_client/cli_lsarpc.h"
      33             : #include "../libcli/security/security.h"
      34             : #include "libsmb/samlogon_cache.h"
      35             : 
      36             : #undef DBGC_CLASS
      37             : #define DBGC_CLASS DBGC_WINBIND
      38             : 
      39             : static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
      40             :                                       struct winbindd_domain *domain,
      41             :                                       uint32_t num_names,
      42             :                                       const char **names,
      43             :                                       const char ***domains,
      44             :                                       struct dom_sid **sids,
      45             :                                       enum lsa_SidType **types);
      46             : 
      47             : /* Query display info for a domain.  This returns enough information plus a
      48             :    bit extra to give an overview of domain users for the User Manager
      49             :    application. */
      50           0 : static NTSTATUS msrpc_query_user_list(struct winbindd_domain *domain,
      51             :                                       TALLOC_CTX *mem_ctx,
      52             :                                       uint32_t **prids)
      53             : {
      54           0 :         struct rpc_pipe_client *samr_pipe = NULL;
      55             :         struct policy_handle dom_pol;
      56           0 :         uint32_t *rids = NULL;
      57             :         TALLOC_CTX *tmp_ctx;
      58             :         NTSTATUS status;
      59             : 
      60           0 :         DEBUG(3, ("msrpc_query_user_list\n"));
      61             : 
      62           0 :         tmp_ctx = talloc_stackframe();
      63           0 :         if (tmp_ctx == NULL) {
      64           0 :                 return NT_STATUS_NO_MEMORY;
      65             :         }
      66             : 
      67           0 :         if ( !winbindd_can_contact_domain( domain ) ) {
      68           0 :                 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
      69             :                           domain->name));
      70           0 :                 status = NT_STATUS_OK;
      71           0 :                 goto done;
      72             :         }
      73             : 
      74           0 :         status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
      75           0 :         if (!NT_STATUS_IS_OK(status)) {
      76           0 :                 goto done;
      77             :         }
      78             : 
      79           0 :         status = rpc_query_user_list(tmp_ctx,
      80             :                                      samr_pipe,
      81             :                                      &dom_pol,
      82           0 :                                      &domain->sid,
      83             :                                      &rids);
      84           0 :         if (!NT_STATUS_IS_OK(status)) {
      85           0 :                 goto done;
      86             :         }
      87             : 
      88           0 :         if (prids) {
      89           0 :                 *prids = talloc_move(mem_ctx, &rids);
      90             :         }
      91             : 
      92           0 : done:
      93           0 :         TALLOC_FREE(rids);
      94           0 :         TALLOC_FREE(tmp_ctx);
      95           0 :         return status;
      96             : }
      97             : 
      98             : /* list all domain groups */
      99           0 : static NTSTATUS msrpc_enum_dom_groups(struct winbindd_domain *domain,
     100             :                                       TALLOC_CTX *mem_ctx,
     101             :                                       uint32_t *pnum_info,
     102             :                                       struct wb_acct_info **pinfo)
     103             : {
     104             :         struct rpc_pipe_client *samr_pipe;
     105             :         struct policy_handle dom_pol;
     106           0 :         struct wb_acct_info *info = NULL;
     107           0 :         uint32_t num_info = 0;
     108             :         TALLOC_CTX *tmp_ctx;
     109             :         NTSTATUS status;
     110             : 
     111           0 :         DEBUG(3,("msrpc_enum_dom_groups\n"));
     112             : 
     113           0 :         if (pnum_info) {
     114           0 :                 *pnum_info = 0;
     115             :         }
     116             : 
     117           0 :         tmp_ctx = talloc_stackframe();
     118           0 :         if (tmp_ctx == NULL) {
     119           0 :                 return NT_STATUS_NO_MEMORY;
     120             :         }
     121             : 
     122           0 :         if ( !winbindd_can_contact_domain( domain ) ) {
     123           0 :                 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
     124             :                           domain->name));
     125           0 :                 status = NT_STATUS_OK;
     126           0 :                 goto done;
     127             :         }
     128             : 
     129           0 :         status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
     130           0 :         if (!NT_STATUS_IS_OK(status)) {
     131           0 :                 goto done;
     132             :         }
     133             : 
     134           0 :         status = rpc_enum_dom_groups(tmp_ctx,
     135             :                                      samr_pipe,
     136             :                                      &dom_pol,
     137             :                                      &num_info,
     138             :                                      &info);
     139           0 :         if (!NT_STATUS_IS_OK(status)) {
     140           0 :                 goto done;
     141             :         }
     142             : 
     143           0 :         if (pnum_info) {
     144           0 :                 *pnum_info = num_info;
     145             :         }
     146             : 
     147           0 :         if (pinfo) {
     148           0 :                 *pinfo = talloc_move(mem_ctx, &info);
     149             :         }
     150             : 
     151           0 : done:
     152           0 :         TALLOC_FREE(tmp_ctx);
     153           0 :         return status;
     154             : }
     155             : 
     156             : /* List all domain groups */
     157             : 
     158           0 : static NTSTATUS msrpc_enum_local_groups(struct winbindd_domain *domain,
     159             :                                         TALLOC_CTX *mem_ctx,
     160             :                                         uint32_t *pnum_info,
     161             :                                         struct wb_acct_info **pinfo)
     162             : {
     163             :         struct rpc_pipe_client *samr_pipe;
     164             :         struct policy_handle dom_pol;
     165           0 :         struct wb_acct_info *info = NULL;
     166           0 :         uint32_t num_info = 0;
     167             :         TALLOC_CTX *tmp_ctx;
     168             :         NTSTATUS status;
     169             : 
     170           0 :         DEBUG(3,("msrpc_enum_local_groups\n"));
     171             : 
     172           0 :         if (pnum_info) {
     173           0 :                 *pnum_info = 0;
     174             :         }
     175             : 
     176           0 :         tmp_ctx = talloc_stackframe();
     177           0 :         if (tmp_ctx == NULL) {
     178           0 :                 return NT_STATUS_NO_MEMORY;
     179             :         }
     180             : 
     181           0 :         if ( !winbindd_can_contact_domain( domain ) ) {
     182           0 :                 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
     183             :                           domain->name));
     184           0 :                 status = NT_STATUS_OK;
     185           0 :                 goto done;
     186             :         }
     187             : 
     188           0 :         status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
     189           0 :         if (!NT_STATUS_IS_OK(status)) {
     190           0 :                 goto done;
     191             :         }
     192             : 
     193           0 :         status = rpc_enum_local_groups(mem_ctx,
     194             :                                        samr_pipe,
     195             :                                        &dom_pol,
     196             :                                        &num_info,
     197             :                                        &info);
     198           0 :         if (!NT_STATUS_IS_OK(status)) {
     199           0 :                 goto done;
     200             :         }
     201             : 
     202           0 :         if (pnum_info) {
     203           0 :                 *pnum_info = num_info;
     204             :         }
     205             : 
     206           0 :         if (pinfo) {
     207           0 :                 *pinfo = talloc_move(mem_ctx, &info);
     208             :         }
     209             : 
     210           0 : done:
     211           0 :         TALLOC_FREE(tmp_ctx);
     212           0 :         return status;
     213             : }
     214             : 
     215             : /* convert a single name to a sid in a domain */
     216           0 : static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
     217             :                                   TALLOC_CTX *mem_ctx,
     218             :                                   const char *domain_name,
     219             :                                   const char *name,
     220             :                                   uint32_t flags,
     221             :                                   const char **pdom_name,
     222             :                                   struct dom_sid *sid,
     223             :                                   enum lsa_SidType *type)
     224             : {
     225             :         NTSTATUS result;
     226           0 :         struct dom_sid *sids = NULL;
     227           0 :         enum lsa_SidType *types = NULL;
     228           0 :         char *full_name = NULL;
     229             :         const char *names[1];
     230             :         const char **domains;
     231           0 :         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
     232           0 :         char *mapped_name = NULL;
     233             : 
     234           0 :         if (name == NULL || *name=='\0') {
     235           0 :                 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
     236           0 :         } else if (domain_name == NULL || *domain_name == '\0') {
     237           0 :                 full_name = talloc_asprintf(mem_ctx, "%s", name);
     238             :         } else {
     239           0 :                 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
     240             :         }
     241           0 :         if (!full_name) {
     242           0 :                 DEBUG(0, ("talloc_asprintf failed!\n"));
     243           0 :                 return NT_STATUS_NO_MEMORY;
     244             :         }
     245             : 
     246           0 :         DEBUG(3, ("msrpc_name_to_sid: name=%s\n", full_name));
     247             : 
     248           0 :         name_map_status = normalize_name_unmap(mem_ctx, full_name,
     249             :                                                &mapped_name);
     250             : 
     251             :         /* Reset the full_name pointer if we mapped anything */
     252             : 
     253           0 :         if (NT_STATUS_IS_OK(name_map_status) ||
     254           0 :             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
     255             :         {
     256           0 :                 full_name = mapped_name;
     257             :         }
     258             : 
     259           0 :         DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
     260             :                  full_name?full_name:"", domain_name ));
     261             : 
     262           0 :         names[0] = full_name;
     263             : 
     264           0 :         result = winbindd_lookup_names(mem_ctx, domain, 1,
     265             :                                        names, &domains,
     266             :                                        &sids, &types);
     267           0 :         if (!NT_STATUS_IS_OK(result))
     268           0 :                 return result;
     269             : 
     270             :         /* Return rid and type if lookup successful */
     271             : 
     272           0 :         if (pdom_name != NULL) {
     273             :                 const char *dom_name;
     274             : 
     275           0 :                 dom_name = talloc_strdup(mem_ctx, domains[0]);
     276           0 :                 if (dom_name == NULL) {
     277           0 :                         return NT_STATUS_NO_MEMORY;
     278             :                 }
     279             : 
     280           0 :                 *pdom_name = dom_name;
     281             :         }
     282             : 
     283           0 :         sid_copy(sid, &sids[0]);
     284           0 :         *type = types[0];
     285             : 
     286           0 :         return NT_STATUS_OK;
     287             : }
     288             : 
     289             : /*
     290             :   convert a domain SID to a user or group name
     291             : */
     292           0 : static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
     293             :                                   TALLOC_CTX *mem_ctx,
     294             :                                   const struct dom_sid *sid,
     295             :                                   char **domain_name,
     296             :                                   char **name,
     297             :                                   enum lsa_SidType *type)
     298             : {
     299             :         char **domains;
     300             :         char **names;
     301           0 :         enum lsa_SidType *types = NULL;
     302             :         NTSTATUS result;
     303           0 :         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
     304           0 :         char *mapped_name = NULL;
     305             :         struct dom_sid_buf buf;
     306             : 
     307           0 :         DEBUG(3, ("msrpc_sid_to_name: %s for domain %s\n",
     308             :                   dom_sid_str_buf(sid, &buf),
     309             :                   domain->name));
     310             : 
     311           0 :         result = winbindd_lookup_sids(mem_ctx,
     312             :                                       domain,
     313             :                                       1,
     314             :                                       sid,
     315             :                                       &domains,
     316             :                                       &names,
     317             :                                       &types);
     318           0 :         if (!NT_STATUS_IS_OK(result)) {
     319           0 :                 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
     320             :                         nt_errstr(result)));
     321           0 :                 return result;
     322             :         }
     323             : 
     324             : 
     325           0 :         *type = (enum lsa_SidType)types[0];
     326           0 :         *domain_name = domains[0];
     327           0 :         *name = names[0];
     328             : 
     329           0 :         DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
     330             : 
     331           0 :         name_map_status = normalize_name_map(mem_ctx, domain->name, *name,
     332             :                                              &mapped_name);
     333           0 :         if (NT_STATUS_IS_OK(name_map_status) ||
     334           0 :             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
     335             :         {
     336           0 :                 *name = mapped_name;
     337           0 :                 DEBUG(5,("returning mapped name -- %s\n", *name));
     338             :         }
     339             : 
     340           0 :         return NT_STATUS_OK;
     341             : }
     342             : 
     343           0 : static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
     344             :                                     TALLOC_CTX *mem_ctx,
     345             :                                     const struct dom_sid *sid,
     346             :                                     uint32_t *rids,
     347             :                                     size_t num_rids,
     348             :                                     char **domain_name,
     349             :                                     char ***names,
     350             :                                     enum lsa_SidType **types)
     351             : {
     352             :         char **domains;
     353             :         NTSTATUS result;
     354             :         struct dom_sid *sids;
     355             :         size_t i;
     356             :         char **ret_names;
     357             : 
     358           0 :         DEBUG(3, ("msrpc_rids_to_names: domain %s\n", domain->name ));
     359             : 
     360           0 :         if (num_rids) {
     361           0 :                 sids = talloc_array(mem_ctx, struct dom_sid, num_rids);
     362           0 :                 if (sids == NULL) {
     363           0 :                         return NT_STATUS_NO_MEMORY;
     364             :                 }
     365             :         } else {
     366           0 :                 sids = NULL;
     367             :         }
     368             : 
     369           0 :         for (i=0; i<num_rids; i++) {
     370           0 :                 if (!sid_compose(&sids[i], sid, rids[i])) {
     371           0 :                         return NT_STATUS_INTERNAL_ERROR;
     372             :                 }
     373             :         }
     374             : 
     375           0 :         result = winbindd_lookup_sids(mem_ctx,
     376             :                                       domain,
     377             :                                       num_rids,
     378             :                                       sids,
     379             :                                       &domains,
     380             :                                       names,
     381             :                                       types);
     382             : 
     383           0 :         if (!NT_STATUS_IS_OK(result) &&
     384           0 :             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
     385           0 :                 return result;
     386             :         }
     387             : 
     388           0 :         ret_names = *names;
     389           0 :         for (i=0; i<num_rids; i++) {
     390           0 :                 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
     391           0 :                 char *mapped_name = NULL;
     392             : 
     393           0 :                 if ((*types)[i] != SID_NAME_UNKNOWN) {
     394           0 :                         name_map_status = normalize_name_map(mem_ctx,
     395           0 :                                                              domain->name,
     396           0 :                                                              ret_names[i],
     397             :                                                              &mapped_name);
     398           0 :                         if (NT_STATUS_IS_OK(name_map_status) ||
     399           0 :                             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
     400             :                         {
     401           0 :                                 ret_names[i] = mapped_name;
     402             :                         }
     403             : 
     404           0 :                         *domain_name = domains[i];
     405             :                 }
     406             :         }
     407             : 
     408           0 :         return result;
     409             : }
     410             : 
     411             : /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
     412           0 : static NTSTATUS msrpc_lookup_usergroups(struct winbindd_domain *domain,
     413             :                                         TALLOC_CTX *mem_ctx,
     414             :                                         const struct dom_sid *user_sid,
     415             :                                         uint32_t *pnum_groups,
     416             :                                         struct dom_sid **puser_grpsids)
     417             : {
     418             :         struct rpc_pipe_client *samr_pipe;
     419             :         struct policy_handle dom_pol;
     420           0 :         struct dom_sid *user_grpsids = NULL;
     421             :         struct dom_sid_buf buf;
     422           0 :         uint32_t num_groups = 0;
     423             :         TALLOC_CTX *tmp_ctx;
     424             :         NTSTATUS status;
     425             : 
     426           0 :         DEBUG(3,("msrpc_lookup_usergroups sid=%s\n",
     427             :                  dom_sid_str_buf(user_sid, &buf)));
     428             : 
     429           0 :         *pnum_groups = 0;
     430             : 
     431           0 :         tmp_ctx = talloc_stackframe();
     432           0 :         if (tmp_ctx == NULL) {
     433           0 :                 return NT_STATUS_NO_MEMORY;
     434             :         }
     435             : 
     436             :         /* Check if we have a cached user_info_3 */
     437           0 :         status = lookup_usergroups_cached(tmp_ctx,
     438             :                                           user_sid,
     439             :                                           &num_groups,
     440             :                                           &user_grpsids);
     441           0 :         if (NT_STATUS_IS_OK(status)) {
     442           0 :                 goto cached;
     443             :         }
     444             : 
     445           0 :         if ( !winbindd_can_contact_domain( domain ) ) {
     446           0 :                 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
     447             :                           domain->name));
     448             : 
     449             :                 /* Tell the cache manager not to remember this one */
     450           0 :                 status = NT_STATUS_SYNCHRONIZATION_REQUIRED;
     451           0 :                 goto done;
     452             :         }
     453             : 
     454             :         /* no cache; hit the wire */
     455           0 :         status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
     456           0 :         if (!NT_STATUS_IS_OK(status)) {
     457           0 :                 goto done;
     458             :         }
     459             : 
     460           0 :         status = rpc_lookup_usergroups(tmp_ctx,
     461             :                                        samr_pipe,
     462             :                                        &dom_pol,
     463           0 :                                        &domain->sid,
     464             :                                        user_sid,
     465             :                                        &num_groups,
     466             :                                        &user_grpsids);
     467           0 :         if (!NT_STATUS_IS_OK(status)) {
     468           0 :                 goto done;
     469             :         }
     470             : 
     471           0 : cached:
     472           0 :         *pnum_groups = num_groups;
     473             : 
     474           0 :         if (puser_grpsids) {
     475           0 :                 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
     476             :         }
     477             : 
     478           0 : done:
     479           0 :         TALLOC_FREE(tmp_ctx);
     480           0 :         return status;
     481             :         return NT_STATUS_OK;
     482             : }
     483             : 
     484             : #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
     485             : 
     486           0 : static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
     487             :                                          TALLOC_CTX *mem_ctx,
     488             :                                          uint32_t num_sids, const struct dom_sid *sids,
     489             :                                          uint32_t *pnum_aliases,
     490             :                                          uint32_t **palias_rids)
     491             : {
     492             :         struct rpc_pipe_client *samr_pipe;
     493             :         struct policy_handle dom_pol;
     494           0 :         uint32_t num_aliases = 0;
     495           0 :         uint32_t *alias_rids = NULL;
     496             :         TALLOC_CTX *tmp_ctx;
     497             :         NTSTATUS status;
     498             : 
     499           0 :         DEBUG(3,("msrpc_lookup_useraliases\n"));
     500             : 
     501           0 :         if (pnum_aliases) {
     502           0 :                 *pnum_aliases = 0;
     503             :         }
     504             : 
     505           0 :         tmp_ctx = talloc_stackframe();
     506           0 :         if (tmp_ctx == NULL) {
     507           0 :                 return NT_STATUS_NO_MEMORY;
     508             :         }
     509             : 
     510           0 :         if (!winbindd_can_contact_domain(domain)) {
     511           0 :                 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
     512             :                           domain->name));
     513             :                 /* Tell the cache manager not to remember this one */
     514           0 :                 status = NT_STATUS_SYNCHRONIZATION_REQUIRED;
     515           0 :                 goto done;
     516             :         }
     517             : 
     518           0 :         status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
     519           0 :         if (!NT_STATUS_IS_OK(status)) {
     520           0 :                 goto done;
     521             :         }
     522             : 
     523           0 :         status = rpc_lookup_useraliases(tmp_ctx,
     524             :                                         samr_pipe,
     525             :                                         &dom_pol,
     526             :                                         num_sids,
     527             :                                         sids,
     528             :                                         &num_aliases,
     529             :                                         &alias_rids);
     530           0 :         if (!NT_STATUS_IS_OK(status)) {
     531           0 :                 goto done;
     532             :         }
     533             : 
     534           0 :         if (pnum_aliases) {
     535           0 :                 *pnum_aliases = num_aliases;
     536             :         }
     537             : 
     538           0 :         if (palias_rids) {
     539           0 :                 *palias_rids = talloc_move(mem_ctx, &alias_rids);
     540             :         }
     541             : 
     542           0 : done:
     543           0 :         TALLOC_FREE(tmp_ctx);
     544           0 :         return status;
     545             : }
     546             : 
     547             : 
     548             : /* Lookup group membership given a rid.   */
     549           0 : static NTSTATUS msrpc_lookup_groupmem(struct winbindd_domain *domain,
     550             :                                       TALLOC_CTX *mem_ctx,
     551             :                                       const struct dom_sid *group_sid,
     552             :                                       enum lsa_SidType type,
     553             :                                       uint32_t *num_names,
     554             :                                       struct dom_sid **sid_mem,
     555             :                                       char ***names,
     556             :                                       uint32_t **name_types)
     557             : {
     558             :         NTSTATUS status, result;
     559           0 :         uint32_t i, total_names = 0;
     560             :         struct policy_handle dom_pol, group_pol;
     561           0 :         uint32_t des_access = SEC_FLAG_MAXIMUM_ALLOWED;
     562           0 :         uint32_t *rid_mem = NULL;
     563             :         uint32_t group_rid;
     564             :         unsigned int j, r;
     565             :         struct rpc_pipe_client *cli;
     566             :         unsigned int orig_timeout;
     567           0 :         struct samr_RidAttrArray *rids = NULL;
     568             :         struct dcerpc_binding_handle *b;
     569             :         struct dom_sid_buf buf;
     570             : 
     571           0 :         DEBUG(3,("msrpc_lookup_groupmem: %s sid=%s\n", domain->name,
     572             :                  dom_sid_str_buf(group_sid, &buf)));
     573             : 
     574           0 :         if ( !winbindd_can_contact_domain( domain ) ) {
     575           0 :                 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
     576             :                           domain->name));
     577           0 :                 return NT_STATUS_OK;
     578             :         }
     579             : 
     580           0 :         if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
     581           0 :                 return NT_STATUS_UNSUCCESSFUL;
     582             : 
     583           0 :         *num_names = 0;
     584             : 
     585           0 :         result = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol);
     586           0 :         if (!NT_STATUS_IS_OK(result))
     587           0 :                 return result;
     588             : 
     589           0 :         b = cli->binding_handle;
     590             : 
     591           0 :         status = dcerpc_samr_OpenGroup(b, mem_ctx,
     592             :                                        &dom_pol,
     593             :                                        des_access,
     594             :                                        group_rid,
     595             :                                        &group_pol,
     596             :                                        &result);
     597           0 :         if (any_nt_status_not_ok(status, result, &status)) {
     598           0 :                 return status;
     599             :         }
     600             : 
     601             :         /* Step #1: Get a list of user rids that are the members of the
     602             :            group. */
     603             : 
     604             :         /* This call can take a long time - allow the server to time out.
     605             :            35 seconds should do it. */
     606             : 
     607           0 :         orig_timeout = rpccli_set_timeout(cli, 35000);
     608             : 
     609           0 :         status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
     610             :                                               &group_pol,
     611             :                                               &rids,
     612             :                                               &result);
     613             : 
     614             :         /* And restore our original timeout. */
     615           0 :         rpccli_set_timeout(cli, orig_timeout);
     616             : 
     617             :         {
     618             :                 NTSTATUS _result;
     619           0 :                 dcerpc_samr_Close(b, mem_ctx, &group_pol, &_result);
     620             :         }
     621             : 
     622           0 :         if (any_nt_status_not_ok(status, result, &status)) {
     623           0 :                 return status;
     624             :         }
     625             : 
     626           0 :         if (!rids || !rids->count) {
     627           0 :                 names = NULL;
     628           0 :                 name_types = NULL;
     629           0 :                 sid_mem = NULL;
     630           0 :                 return NT_STATUS_OK;
     631             :         }
     632             : 
     633           0 :         *num_names = rids->count;
     634           0 :         rid_mem = rids->rids;
     635             : 
     636             :         /* Step #2: Convert list of rids into list of usernames.  Do this
     637             :            in bunches of ~1000 to avoid crashing NT4.  It looks like there
     638             :            is a buffer overflow or something like that lurking around
     639             :            somewhere. */
     640             : 
     641             : #define MAX_LOOKUP_RIDS 900
     642             : 
     643           0 :         *names = talloc_zero_array(mem_ctx, char *, *num_names);
     644           0 :         *name_types = talloc_zero_array(mem_ctx, uint32_t, *num_names);
     645           0 :         *sid_mem = talloc_zero_array(mem_ctx, struct dom_sid, *num_names);
     646             : 
     647           0 :         for (j=0;j<(*num_names);j++)
     648           0 :                 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
     649             : 
     650           0 :         if (*num_names>0 && (!*names || !*name_types))
     651           0 :                 return NT_STATUS_NO_MEMORY;
     652             : 
     653           0 :         for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
     654           0 :                 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
     655             :                 struct lsa_Strings tmp_names;
     656             :                 struct samr_Ids tmp_types;
     657             : 
     658             :                 /* Lookup a chunk of rids */
     659             : 
     660           0 :                 status = dcerpc_samr_LookupRids(b, mem_ctx,
     661             :                                                 &dom_pol,
     662             :                                                 num_lookup_rids,
     663           0 :                                                 &rid_mem[i],
     664             :                                                 &tmp_names,
     665             :                                                 &tmp_types,
     666             :                                                 &result);
     667           0 :                 if (!NT_STATUS_IS_OK(status)) {
     668           0 :                         return status;
     669             :                 }
     670             : 
     671             :                 /* see if we have a real error (and yes the
     672             :                    STATUS_SOME_UNMAPPED is the one returned from 2k) */
     673             : 
     674           0 :                 if (!NT_STATUS_IS_OK(result) &&
     675           0 :                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
     676           0 :                         return result;
     677             : 
     678             :                 /* Copy result into array.  The talloc system will take
     679             :                    care of freeing the temporary arrays later on. */
     680             : 
     681           0 :                 if (tmp_names.count != num_lookup_rids) {
     682           0 :                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
     683             :                 }
     684           0 :                 if (tmp_types.count != num_lookup_rids) {
     685           0 :                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
     686             :                 }
     687             : 
     688           0 :                 for (r=0; r<tmp_names.count; r++) {
     689           0 :                         if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
     690           0 :                                 continue;
     691             :                         }
     692           0 :                         if (total_names >= *num_names) {
     693           0 :                                 break;
     694             :                         }
     695           0 :                         (*names)[total_names] = fill_domain_username_talloc(
     696           0 :                                 mem_ctx, domain->name,
     697           0 :                                 tmp_names.names[r].string, true);
     698           0 :                         (*name_types)[total_names] = tmp_types.ids[r];
     699           0 :                         total_names += 1;
     700             :                 }
     701             :         }
     702             : 
     703           0 :         *num_names = total_names;
     704             : 
     705           0 :         return NT_STATUS_OK;
     706             : }
     707             : 
     708             : /* get a list of trusted domains */
     709           0 : static NTSTATUS msrpc_trusted_domains(struct winbindd_domain *domain,
     710             :                                       TALLOC_CTX *mem_ctx,
     711             :                                       struct netr_DomainTrustList *ptrust_list)
     712             : {
     713             :         struct rpc_pipe_client *lsa_pipe;
     714             :         struct policy_handle lsa_policy;
     715           0 :         struct netr_DomainTrust *trusts = NULL;
     716           0 :         uint32_t num_trusts = 0;
     717             :         TALLOC_CTX *tmp_ctx;
     718             :         NTSTATUS status;
     719             : 
     720           0 :         DEBUG(3,("msrpc_trusted_domains\n"));
     721             : 
     722           0 :         if (ptrust_list) {
     723           0 :                 ZERO_STRUCTP(ptrust_list);
     724             :         }
     725             : 
     726           0 :         tmp_ctx = talloc_stackframe();
     727           0 :         if (tmp_ctx == NULL) {
     728           0 :                 return NT_STATUS_NO_MEMORY;
     729             :         }
     730             : 
     731           0 :         status = cm_connect_lsa(domain, tmp_ctx, &lsa_pipe, &lsa_policy);
     732           0 :         if (!NT_STATUS_IS_OK(status)) {
     733           0 :                 goto done;
     734             :         }
     735             : 
     736           0 :         status = rpc_trusted_domains(tmp_ctx,
     737             :                                      lsa_pipe,
     738             :                                      &lsa_policy,
     739             :                                      &num_trusts,
     740             :                                      &trusts);
     741           0 :         if (!NT_STATUS_IS_OK(status)) {
     742           0 :                 goto done;
     743             :         }
     744             : 
     745           0 :         if (ptrust_list) {
     746           0 :                 ptrust_list->count = num_trusts;
     747           0 :                 ptrust_list->array = talloc_move(mem_ctx, &trusts);
     748             :         }
     749             : 
     750           0 : done:
     751           0 :         TALLOC_FREE(tmp_ctx);
     752           0 :         return status;
     753             : }
     754             : 
     755             : /* find the lockout policy for a domain */
     756           0 : static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
     757             :                                      TALLOC_CTX *mem_ctx,
     758             :                                      struct samr_DomInfo12 *lockout_policy)
     759             : {
     760             :         NTSTATUS status, result;
     761             :         struct rpc_pipe_client *cli;
     762             :         struct policy_handle dom_pol;
     763           0 :         union samr_DomainInfo *info = NULL;
     764             :         struct dcerpc_binding_handle *b;
     765             : 
     766           0 :         DEBUG(3, ("msrpc_lockout_policy: fetch lockout policy for %s\n", domain->name));
     767             : 
     768           0 :         if ( !winbindd_can_contact_domain( domain ) ) {
     769           0 :                 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
     770             :                           domain->name));
     771           0 :                 return NT_STATUS_NOT_SUPPORTED;
     772             :         }
     773             : 
     774           0 :         status = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol);
     775           0 :         if (!NT_STATUS_IS_OK(status)) {
     776           0 :                 goto done;
     777             :         }
     778             : 
     779           0 :         b = cli->binding_handle;
     780             : 
     781           0 :         status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
     782             :                                              &dom_pol,
     783             :                                              DomainLockoutInformation,
     784             :                                              &info,
     785             :                                              &result);
     786           0 :         if (any_nt_status_not_ok(status, result, &status)) {
     787           0 :                 return status;
     788             :         }
     789             : 
     790           0 :         *lockout_policy = info->info12;
     791             : 
     792           0 :         DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
     793             :                 info->info12.lockout_threshold));
     794             : 
     795           0 :   done:
     796             : 
     797           0 :         return status;
     798             : }
     799             : 
     800             : /* find the password policy for a domain */
     801           0 : static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
     802             :                                       TALLOC_CTX *mem_ctx,
     803             :                                       struct samr_DomInfo1 *password_policy)
     804             : {
     805             :         NTSTATUS status, result;
     806             :         struct rpc_pipe_client *cli;
     807             :         struct policy_handle dom_pol;
     808           0 :         union samr_DomainInfo *info = NULL;
     809             :         struct dcerpc_binding_handle *b;
     810             : 
     811           0 :         DEBUG(3, ("msrpc_password_policy: fetch password policy for %s\n",
     812             :                   domain->name));
     813             : 
     814           0 :         if ( !winbindd_can_contact_domain( domain ) ) {
     815           0 :                 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
     816             :                           domain->name));
     817           0 :                 return NT_STATUS_NOT_SUPPORTED;
     818             :         }
     819             : 
     820           0 :         status = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol);
     821           0 :         if (!NT_STATUS_IS_OK(status)) {
     822           0 :                 goto done;
     823             :         }
     824             : 
     825           0 :         b = cli->binding_handle;
     826             : 
     827           0 :         status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
     828             :                                              &dom_pol,
     829             :                                              DomainPasswordInformation,
     830             :                                              &info,
     831             :                                              &result);
     832           0 :         if (!NT_STATUS_IS_OK(status)) {
     833           0 :                 goto done;
     834             :         }
     835           0 :         if (!NT_STATUS_IS_OK(result)) {
     836           0 :                 goto done;
     837             :         }
     838             : 
     839           0 :         *password_policy = info->info1;
     840             : 
     841           0 :         DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
     842             :                 info->info1.min_password_length));
     843             : 
     844           0 :   done:
     845             : 
     846           0 :         return status;
     847             : }
     848             : 
     849           0 : static enum lsa_LookupNamesLevel winbindd_lookup_level(
     850             :         struct winbindd_domain *domain)
     851             : {
     852           0 :         enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_DOMAINS_ONLY;
     853             : 
     854           0 :         if (domain->internal) {
     855           0 :                 level = LSA_LOOKUP_NAMES_ALL;
     856           0 :         } else if (domain->secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
     857           0 :                 if (domain->domain_flags & NETR_TRUST_FLAG_IN_FOREST) {
     858             :                         /*
     859             :                          * TODO:
     860             :                          *
     861             :                          * Depending on what we want to resolve. We need to use:
     862             :                          * 1. LsapLookupXForestReferral(5)/LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY
     863             :                          *    if we want to pass the request into the direction of the forest
     864             :                          *    root domain. The forest root domain uses
     865             :                          *    LsapLookupXForestResolve(6)/LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2
     866             :                          *    when passing the request to trusted forests.
     867             :                          * 2. LsapLookupGC(4)/LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY
     868             :                          *    if we're not a GC and want to resolve a name within our own forest.
     869             :                          *
     870             :                          * As we don't support more than one domain in our own forest
     871             :                          * and always try to be a GC for now, we just set
     872             :                          * LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY.
     873             :                          */
     874           0 :                         level = LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY;
     875           0 :                 } else if (domain->domain_trust_attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
     876             :                         /*
     877             :                          * This is LsapLookupXForestResolve(6)/LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2
     878             :                          */
     879           0 :                         level = LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2;
     880             :                 } else {
     881             :                         /*
     882             :                          * This is LsapLookupTDL(3)/LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
     883             :                          */
     884           0 :                         level = LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY;
     885             :                 }
     886           0 :         } else if (domain->secure_channel_type == SEC_CHAN_DOMAIN) {
     887             :                 /*
     888             :                  * This is LsapLookupTDL(3)/LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY
     889             :                  */
     890           0 :                 level = LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY;
     891           0 :         } else if (domain->rodc) {
     892           0 :                 level = LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC;
     893             :         } else {
     894             :                 /*
     895             :                  * This is LsapLookupPDC(2)/LSA_LOOKUP_NAMES_DOMAINS_ONLY
     896             :                  */
     897           0 :                 level = LSA_LOOKUP_NAMES_DOMAINS_ONLY;
     898             :         }
     899             : 
     900           0 :         return level;
     901             : }
     902             : 
     903           0 : NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
     904             :                               struct winbindd_domain *domain,
     905             :                               uint32_t num_sids,
     906             :                               const struct dom_sid *sids,
     907             :                               char ***domains,
     908             :                               char ***names,
     909             :                               enum lsa_SidType **types)
     910             : {
     911             :         NTSTATUS status;
     912             :         NTSTATUS result;
     913           0 :         struct rpc_pipe_client *cli = NULL;
     914           0 :         struct dcerpc_binding_handle *b = NULL;
     915             :         struct policy_handle lsa_policy;
     916             :         unsigned int orig_timeout;
     917           0 :         bool use_lookupsids3 = false;
     918           0 :         bool retried = false;
     919           0 :         enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL;
     920             : 
     921           0 :  connect:
     922           0 :         status = cm_connect_lsat(domain, mem_ctx, &cli, &lsa_policy);
     923           0 :         if (!NT_STATUS_IS_OK(status)) {
     924           0 :                 return status;
     925             :         }
     926             : 
     927           0 :         b = cli->binding_handle;
     928             : 
     929           0 :         if (cli->transport->transport == NCACN_IP_TCP) {
     930           0 :                 use_lookupsids3 = true;
     931             :         }
     932             : 
     933           0 :         level = winbindd_lookup_level(domain);
     934             : 
     935             :         /*
     936             :          * This call can take a long time
     937             :          * allow the server to time out.
     938             :          * 35 seconds should do it.
     939             :          */
     940           0 :         orig_timeout = dcerpc_binding_handle_set_timeout(b, 35000);
     941             : 
     942           0 :         status = dcerpc_lsa_lookup_sids_generic(b,
     943             :                                                 mem_ctx,
     944             :                                                 &lsa_policy,
     945             :                                                 num_sids,
     946             :                                                 sids,
     947             :                                                 level,
     948             :                                                 domains,
     949             :                                                 names,
     950             :                                                 types,
     951             :                                                 use_lookupsids3,
     952             :                                                 &result);
     953             : 
     954             :         /* And restore our original timeout. */
     955           0 :         dcerpc_binding_handle_set_timeout(b, orig_timeout);
     956             : 
     957           0 :         if (reset_cm_connection_on_error(domain, b, status)) {
     958             :                 /*
     959             :                  * This can happen if the schannel key is not
     960             :                  * valid anymore, we need to invalidate the
     961             :                  * all connections to the dc and reestablish
     962             :                  * a netlogon connection first.
     963             :                  */
     964           0 :                 domain->can_do_ncacn_ip_tcp = domain->active_directory;
     965           0 :                 if (!retried) {
     966           0 :                         retried = true;
     967           0 :                         goto connect;
     968             :                 }
     969           0 :                 status = NT_STATUS_ACCESS_DENIED;
     970             :         }
     971             : 
     972           0 :         if (any_nt_status_not_ok(status, result, &status)) {
     973           0 :                 return status;
     974             :         }
     975             : 
     976           0 :         return NT_STATUS_OK;
     977             : }
     978             : 
     979           0 : static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
     980             :                                       struct winbindd_domain *domain,
     981             :                                       uint32_t num_names,
     982             :                                       const char **names,
     983             :                                       const char ***domains,
     984             :                                       struct dom_sid **sids,
     985             :                                       enum lsa_SidType **types)
     986             : {
     987             :         NTSTATUS status;
     988             :         NTSTATUS result;
     989           0 :         struct rpc_pipe_client *cli = NULL;
     990           0 :         struct dcerpc_binding_handle *b = NULL;
     991             :         struct policy_handle lsa_policy;
     992           0 :         unsigned int orig_timeout = 0;
     993           0 :         bool use_lookupnames4 = false;
     994           0 :         bool retried = false;
     995           0 :         enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL;
     996             : 
     997           0 :  connect:
     998           0 :         status = cm_connect_lsat(domain, mem_ctx, &cli, &lsa_policy);
     999           0 :         if (!NT_STATUS_IS_OK(status)) {
    1000           0 :                 return status;
    1001             :         }
    1002             : 
    1003           0 :         b = cli->binding_handle;
    1004             : 
    1005           0 :         if (cli->transport->transport == NCACN_IP_TCP) {
    1006           0 :                 use_lookupnames4 = true;
    1007             :         }
    1008             : 
    1009           0 :         level = winbindd_lookup_level(domain);
    1010             : 
    1011             :         /*
    1012             :          * This call can take a long time
    1013             :          * allow the server to time out.
    1014             :          * 35 seconds should do it.
    1015             :          */
    1016           0 :         orig_timeout = dcerpc_binding_handle_set_timeout(b, 35000);
    1017             : 
    1018           0 :         status = dcerpc_lsa_lookup_names_generic(b,
    1019             :                                                  mem_ctx,
    1020             :                                                  &lsa_policy,
    1021             :                                                  num_names,
    1022             :                                                  (const char **) names,
    1023             :                                                  domains,
    1024             :                                                  level,
    1025             :                                                  sids,
    1026             :                                                  types,
    1027             :                                                  use_lookupnames4,
    1028             :                                                  &result);
    1029             : 
    1030             :         /* And restore our original timeout. */
    1031           0 :         dcerpc_binding_handle_set_timeout(b, orig_timeout);
    1032             : 
    1033           0 :         if (reset_cm_connection_on_error(domain, b, status)) {
    1034             :                 /*
    1035             :                  * This can happen if the schannel key is not
    1036             :                  * valid anymore, we need to invalidate the
    1037             :                  * all connections to the dc and reestablish
    1038             :                  * a netlogon connection first.
    1039             :                  */
    1040           0 :                 if (!retried) {
    1041           0 :                         retried = true;
    1042           0 :                         goto connect;
    1043             :                 }
    1044           0 :                 status = NT_STATUS_ACCESS_DENIED;
    1045             :         }
    1046             : 
    1047           0 :         if (any_nt_status_not_ok(status, result, &status)) {
    1048           0 :                 return status;
    1049             :         }
    1050             : 
    1051           0 :         return NT_STATUS_OK;
    1052             : }
    1053             : 
    1054             : /* the rpc backend methods are exposed via this structure */
    1055             : struct winbindd_methods msrpc_methods = {
    1056             :         False,
    1057             :         msrpc_query_user_list,
    1058             :         msrpc_enum_dom_groups,
    1059             :         msrpc_enum_local_groups,
    1060             :         msrpc_name_to_sid,
    1061             :         msrpc_sid_to_name,
    1062             :         msrpc_rids_to_names,
    1063             :         msrpc_lookup_usergroups,
    1064             :         msrpc_lookup_useraliases,
    1065             :         msrpc_lookup_groupmem,
    1066             :         msrpc_lockout_policy,
    1067             :         msrpc_password_policy,
    1068             :         msrpc_trusted_domains,
    1069             : };

Generated by: LCOV version 1.13