Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/winbindd/winbindd_rpc.c

    r596 r745  
    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 */
     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 */
    2425
    2526#include "includes.h"
    2627#include "winbindd.h"
    27 #include "../librpc/gen_ndr/cli_samr.h"
    28 #include "../librpc/gen_ndr/cli_lsa.h"
    29 
    30 #undef DBGC_CLASS
    31 #define DBGC_CLASS DBGC_WINBIND
    32 
    33 
    34 /* Query display info for a domain.  This returns enough information plus a
    35    bit extra to give an overview of domain users for the User Manager
    36    application. */
    37 static NTSTATUS query_user_list(struct winbindd_domain *domain,
    38                                TALLOC_CTX *mem_ctx,
    39                                uint32 *num_entries,
    40                                struct wbint_userinfo **info)
    41 {
    42         NTSTATUS result;
    43         struct policy_handle dom_pol;
    44         unsigned int i, start_idx;
    45         uint32 loop_count;
    46         struct rpc_pipe_client *cli;
    47 
    48         DEBUG(3,("rpc: query_user_list\n"));
    49 
    50         *num_entries = 0;
    51         *info = NULL;
    52 
    53         if ( !winbindd_can_contact_domain( domain ) ) {
    54                 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
    55                           domain->name));
    56                 return NT_STATUS_OK;
    57         }
    58 
    59         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    60         if (!NT_STATUS_IS_OK(result))
    61                 return result;
    62 
    63         i = start_idx = 0;
    64         loop_count = 0;
     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
     36/* Query display info for a domain */
     37NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx,
     38                             struct rpc_pipe_client *samr_pipe,
     39                             struct policy_handle *samr_policy,
     40                             const struct dom_sid *domain_sid,
     41                             uint32_t *pnum_info,
     42                             struct wbint_userinfo **pinfo)
     43{
     44        struct wbint_userinfo *info = NULL;
     45        uint32_t num_info = 0;
     46        uint32_t loop_count = 0;
     47        uint32_t start_idx = 0;
     48        uint32_t i = 0;
     49        NTSTATUS status, result;
     50        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     51
     52        *pnum_info = 0;
    6553
    6654        do {
    67                 uint32 num_dom_users, j;
    68                 uint32 max_entries, max_size;
     55                uint32_t j;
     56                uint32_t num_dom_users;
     57                uint32_t max_entries, max_size;
    6958                uint32_t total_size, returned_size;
    70 
    7159                union samr_DispInfo disp_info;
    7260
    73                 /* this next bit is copied from net_user_list_internal() */
    74 
    75                 get_query_dispinfo_params(loop_count, &max_entries,
    76                                           &max_size);
    77 
    78                 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
    79                                                       &dom_pol,
    80                                                       1,
     61                dcerpc_get_query_dispinfo_params(loop_count,
     62                                                 &max_entries,
     63                                                 &max_size);
     64
     65                status = dcerpc_samr_QueryDisplayInfo(b,
     66                                                      mem_ctx,
     67                                                      samr_policy,
     68                                                      1, /* level */
    8169                                                      start_idx,
    8270                                                      max_entries,
     
    8472                                                      &total_size,
    8573                                                      &returned_size,
    86                                                       &disp_info);
    87 
     74                                                      &disp_info,
     75                                                      &result);
     76                if (!NT_STATUS_IS_OK(status)) {
     77                        return status;
     78                }
    8879                if (!NT_STATUS_IS_OK(result)) {
    89                         if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
    90                                 return result;
    91                         }
    92                 }
    93 
    94                 num_dom_users = disp_info.info1.count;
     80                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     81                                return result;
     82                        }
     83                }
     84
     85                /* increment required start query values */
    9586                start_idx += disp_info.info1.count;
    9687                loop_count++;
    97 
    98                 *num_entries += num_dom_users;
    99 
    100                 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
    101                                              struct wbint_userinfo,
    102                                              *num_entries);
    103 
    104                 if (!(*info)) {
     88                num_dom_users = disp_info.info1.count;
     89
     90                num_info += num_dom_users;
     91
     92                info = TALLOC_REALLOC_ARRAY(mem_ctx,
     93                                            info,
     94                                            struct wbint_userinfo,
     95                                            num_info);
     96                if (info == NULL) {
    10597                        return NT_STATUS_NO_MEMORY;
    10698                }
    10799
    108100                for (j = 0; j < num_dom_users; i++, j++) {
    109 
    110101                        uint32_t rid = disp_info.info1.entries[j].rid;
    111 
    112                         (*info)[i].acct_name = talloc_strdup(mem_ctx,
    113                                 disp_info.info1.entries[j].account_name.string);
    114                         (*info)[i].full_name = talloc_strdup(mem_ctx,
    115                                 disp_info.info1.entries[j].full_name.string);
    116                         (*info)[i].homedir = NULL;
    117                         (*info)[i].shell = NULL;
    118                         sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
     102                        struct samr_DispEntryGeneral *src;
     103                        struct wbint_userinfo *dst;
     104
     105                        src = &(disp_info.info1.entries[j]);
     106                        dst = &(info[i]);
     107
     108                        dst->acct_name = talloc_strdup(info,
     109                                                       src->account_name.string);
     110                        if (dst->acct_name == NULL) {
     111                                return NT_STATUS_NO_MEMORY;
     112                        }
     113
     114                        dst->full_name = talloc_strdup(info, src->full_name.string);
     115                        if ((src->full_name.string != NULL) &&
     116                            (dst->full_name == NULL))
     117                        {
     118                                return NT_STATUS_NO_MEMORY;
     119                        }
     120
     121                        dst->homedir = NULL;
     122                        dst->shell = NULL;
     123
     124                        sid_compose(&dst->user_sid, domain_sid, rid);
    119125
    120126                        /* For the moment we set the primary group for
     
    125131                           force group' smb.conf parameter or
    126132                           something like that. */
    127 
    128                         sid_compose(&(*info)[i].group_sid, &domain->sid,
    129                                     DOMAIN_GROUP_RID_USERS);
    130                 }
    131 
     133                        sid_compose(&dst->group_sid, domain_sid,
     134                                    DOMAIN_RID_USERS);
     135                }
    132136        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
    133137
    134         return result;
    135 }
    136 
    137 /* list all domain groups */
    138 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
    139                                 TALLOC_CTX *mem_ctx,
    140                                 uint32 *num_entries,
    141                                 struct acct_info **info)
    142 {
    143         struct policy_handle dom_pol;
    144         NTSTATUS status;
    145         uint32 start = 0;
    146         struct rpc_pipe_client *cli;
    147 
    148         *num_entries = 0;
    149         *info = NULL;
    150 
    151         DEBUG(3,("rpc: enum_dom_groups\n"));
    152 
    153         if ( !winbindd_can_contact_domain( domain ) ) {
    154                 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
    155                           domain->name));
    156                 return NT_STATUS_OK;
    157         }
    158 
    159         status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    160         if (!NT_STATUS_IS_OK(status))
    161                 return status;
     138        *pnum_info = num_info;
     139        *pinfo = info;
     140
     141        return NT_STATUS_OK;
     142}
     143
     144/* List all domain groups */
     145NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx,
     146                             struct rpc_pipe_client *samr_pipe,
     147                             struct policy_handle *samr_policy,
     148                             uint32_t *pnum_info,
     149                             struct wb_acct_info **pinfo)
     150{
     151        struct wb_acct_info *info = NULL;
     152        uint32_t start = 0;
     153        uint32_t num_info = 0;
     154        NTSTATUS status, result;
     155        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     156
     157        *pnum_info = 0;
    162158
    163159        do {
    164160                struct samr_SamArray *sam_array = NULL;
    165                 uint32 count = 0;
    166                 TALLOC_CTX *mem_ctx2;
    167                 int g;
    168 
    169                 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
     161                uint32_t count = 0;
     162                uint32_t g;
    170163
    171164                /* start is updated by this call. */
    172                 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
    173                                                       &dom_pol,
     165                status = dcerpc_samr_EnumDomainGroups(b,
     166                                                      mem_ctx,
     167                                                      samr_policy,
    174168                                                      &start,
    175169                                                      &sam_array,
    176170                                                      0xFFFF, /* buffer size? */
    177                                                       &count);
    178 
    179                 if (!NT_STATUS_IS_OK(status) &&
    180                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
    181                         talloc_destroy(mem_ctx2);
    182                         break;
    183                 }
    184 
    185                 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
    186                                                struct acct_info,
    187                                                (*num_entries) + count);
    188                 if (! *info) {
    189                         talloc_destroy(mem_ctx2);
     171                                                      &count,
     172                                                      &result);
     173                if (!NT_STATUS_IS_OK(status)) {
     174                        return status;
     175                }
     176                if (!NT_STATUS_IS_OK(result)) {
     177                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     178                                DEBUG(2,("query_user_list: failed to enum domain groups: %s\n",
     179                                         nt_errstr(result)));
     180                                return result;
     181                        }
     182                }
     183
     184                info = TALLOC_REALLOC_ARRAY(mem_ctx,
     185                                            info,
     186                                            struct wb_acct_info,
     187                                            num_info + count);
     188                if (info == NULL) {
    190189                        return NT_STATUS_NO_MEMORY;
    191190                }
    192191
    193                 for (g=0; g < count; g++) {
    194 
    195                         fstrcpy((*info)[*num_entries + g].acct_name,
     192                for (g = 0; g < count; g++) {
     193                        fstrcpy(info[num_info + g].acct_name,
    196194                                sam_array->entries[g].name.string);
    197                         (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
    198                 }
    199 
    200                 (*num_entries) += count;
    201                 talloc_destroy(mem_ctx2);
    202         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
    203 
    204         return status;
    205 }
    206 
    207 /* List all domain groups */
    208 
    209 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
    210                                 TALLOC_CTX *mem_ctx,
    211                                 uint32 *num_entries,
    212                                 struct acct_info **info)
    213 {
    214         struct policy_handle dom_pol;
    215         NTSTATUS result;
    216         struct rpc_pipe_client *cli;
    217 
    218         *num_entries = 0;
    219         *info = NULL;
    220 
    221         DEBUG(3,("rpc: enum_local_groups\n"));
    222 
    223         if ( !winbindd_can_contact_domain( domain ) ) {
    224                 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
    225                           domain->name));
    226                 return NT_STATUS_OK;
    227         }
    228 
    229         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    230         if (!NT_STATUS_IS_OK(result))
    231                 return result;
     195
     196                        info[num_info + g].rid = sam_array->entries[g].idx;
     197                }
     198
     199                num_info += count;
     200        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
     201
     202        *pnum_info = num_info;
     203        *pinfo = info;
     204
     205        return NT_STATUS_OK;
     206}
     207
     208NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx,
     209                               struct rpc_pipe_client *samr_pipe,
     210                               struct policy_handle *samr_policy,
     211                               uint32_t *pnum_info,
     212                               struct wb_acct_info **pinfo)
     213{
     214        struct wb_acct_info *info = NULL;
     215        uint32_t num_info = 0;
     216        NTSTATUS status, result;
     217        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     218
     219        *pnum_info = 0;
    232220
    233221        do {
    234222                struct samr_SamArray *sam_array = NULL;
    235                 uint32 count = 0, start = *num_entries;
    236                 TALLOC_CTX *mem_ctx2;
    237                 int g;
    238 
    239                 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
    240 
    241                 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
    242                                                        &dom_pol,
     223                uint32_t count = 0;
     224                uint32_t start = num_info;
     225                uint32_t g;
     226
     227                status = dcerpc_samr_EnumDomainAliases(b,
     228                                                       mem_ctx,
     229                                                       samr_policy,
    243230                                                       &start,
    244231                                                       &sam_array,
    245232                                                       0xFFFF, /* buffer size? */
    246                                                        &count);
    247                 if (!NT_STATUS_IS_OK(result) &&
    248                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
    249                 {
    250                         talloc_destroy(mem_ctx2);
    251                         return result;
    252                 }
    253 
    254                 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
    255                                                struct acct_info,
    256                                                (*num_entries) + count);
    257                 if (! *info) {
    258                         talloc_destroy(mem_ctx2);
    259                         return NT_STATUS_NO_MEMORY;
    260                 }
    261 
    262                 for (g=0; g < count; g++) {
    263 
    264                         fstrcpy((*info)[*num_entries + g].acct_name,
     233                                                       &count,
     234                                                       &result);
     235                if (!NT_STATUS_IS_OK(status)) {
     236                        return status;
     237                }
     238                if (!NT_STATUS_IS_OK(result)) {
     239                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     240                                return result;
     241                        }
     242                }
     243
     244                info = TALLOC_REALLOC_ARRAY(mem_ctx,
     245                                            info,
     246                                            struct wb_acct_info,
     247                                            num_info + count);
     248                if (info == NULL) {
     249                        return  NT_STATUS_NO_MEMORY;
     250                }
     251
     252                for (g = 0; g < count; g++) {
     253                        fstrcpy(info[num_info + g].acct_name,
    265254                                sam_array->entries[g].name.string);
    266                         (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
    267                 }
    268 
    269                 (*num_entries) += count;
    270                 talloc_destroy(mem_ctx2);
    271 
     255                        info[num_info + g].rid = sam_array->entries[g].idx;
     256                }
     257
     258                num_info += count;
    272259        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
    273260
    274         return result;
     261        *pnum_info = num_info;
     262        *pinfo = info;
     263
     264        return NT_STATUS_OK;
    275265}
    276266
    277267/* convert a single name to a sid in a domain */
    278 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
    279                                   TALLOC_CTX *mem_ctx,
    280                                   const char *domain_name,
    281                                   const char *name,
    282                                   uint32_t flags,
    283                                   DOM_SID *sid,
    284                                   enum lsa_SidType *type)
    285 {
    286         NTSTATUS result;
    287         DOM_SID *sids = NULL;
     268NTSTATUS rpc_name_to_sid(TALLOC_CTX *mem_ctx,
     269                         struct rpc_pipe_client *lsa_pipe,
     270                         struct policy_handle *lsa_policy,
     271                         const char *domain_name,
     272                         const char *name,
     273                         uint32_t flags,
     274                         struct dom_sid *sid,
     275                         enum lsa_SidType *type)
     276{
    288277        enum lsa_SidType *types = NULL;
     278        struct dom_sid *sids = NULL;
    289279        char *full_name = NULL;
    290         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
    291280        char *mapped_name = NULL;
    292 
    293         if (name == NULL || *name=='\0') {
     281        NTSTATUS status;
     282
     283        if (name == NULL || name[0] == '\0') {
    294284                full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
    295         } else if (domain_name == NULL || *domain_name == '\0') {
     285        } else if (domain_name == NULL || domain_name[0] == '\0') {
    296286                full_name = talloc_asprintf(mem_ctx, "%s", name);
    297287        } else {
    298288                full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
    299289        }
    300         if (!full_name) {
    301                 DEBUG(0, ("talloc_asprintf failed!\n"));
     290
     291        if (full_name == NULL) {
    302292                return NT_STATUS_NO_MEMORY;
    303293        }
    304294
    305         DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
    306 
    307         name_map_status = normalize_name_unmap(mem_ctx, full_name,
    308                                                &mapped_name);
    309 
    310         /* Reset the full_name pointer if we mapped anytthing */
    311 
    312         if (NT_STATUS_IS_OK(name_map_status) ||
    313             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
    314         {
     295        status = normalize_name_unmap(mem_ctx, full_name, &mapped_name);
     296        /* Reset the full_name pointer if we mapped anything */
     297        if (NT_STATUS_IS_OK(status) ||
     298            NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
    315299                full_name = mapped_name;
    316300        }
    317301
    318         DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
    319                  full_name?full_name:"", domain_name ));
    320 
    321         result = winbindd_lookup_names(mem_ctx, domain, 1,
    322                                        (const char **)&full_name, NULL,
    323                                        &sids, &types);
    324         if (!NT_STATUS_IS_OK(result))
    325                 return result;
    326 
    327         /* Return rid and type if lookup successful */
     302        DEBUG(3,("name_to_sid: %s for domain %s\n",
     303                 full_name ? full_name : "", domain_name ));
     304
     305        /*
     306         * We don't run into deadlocks here, cause winbind_off() is
     307         * called in the main function.
     308         */
     309        status = rpccli_lsa_lookup_names(lsa_pipe,
     310                                         mem_ctx,
     311                                         lsa_policy,
     312                                         1, /* num_names */
     313                                         (const char **) &full_name,
     314                                         NULL, /* domains */
     315                                         1, /* level */
     316                                         &sids,
     317                                         &types);
     318        if (!NT_STATUS_IS_OK(status)) {
     319                DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
     320                        nt_errstr(status)));
     321                return status;
     322        }
    328323
    329324        sid_copy(sid, &sids[0]);
     
    333328}
    334329
    335 /*
    336   convert a domain SID to a user or group name
    337 */
    338 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
    339                                   TALLOC_CTX *mem_ctx,
    340                                   const DOM_SID *sid,
    341                                   char **domain_name,
    342                                   char **name,
    343                                   enum lsa_SidType *type)
    344 {
    345         char **domains;
    346         char **names;
     330/* Convert a domain SID to a user or group name */
     331NTSTATUS rpc_sid_to_name(TALLOC_CTX *mem_ctx,
     332                         struct rpc_pipe_client *lsa_pipe,
     333                         struct policy_handle *lsa_policy,
     334                         struct winbindd_domain *domain,
     335                         const struct dom_sid *sid,
     336                         char **pdomain_name,
     337                         char **pname,
     338                         enum lsa_SidType *ptype)
     339{
     340        char *mapped_name = NULL;
     341        char **domains = NULL;
     342        char **names = NULL;
    347343        enum lsa_SidType *types = NULL;
    348         NTSTATUS result;
    349         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
    350         char *mapped_name = NULL;
    351 
    352         DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
    353                  domain->name ));
    354 
    355         result = winbindd_lookup_sids(mem_ctx,
    356                                       domain,
    357                                       1,
    358                                       sid,
    359                                       &domains,
    360                                       &names,
    361                                       &types);
    362         if (!NT_STATUS_IS_OK(result)) {
    363                 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
    364                         nt_errstr(result)));
    365                 return result;
    366         }
    367 
    368 
    369         *type = (enum lsa_SidType)types[0];
    370         *domain_name = domains[0];
    371         *name = names[0];
    372 
    373         DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
    374 
    375         name_map_status = normalize_name_map(mem_ctx, domain, *name,
    376                                              &mapped_name);
    377         if (NT_STATUS_IS_OK(name_map_status) ||
    378             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
    379         {
    380                 *name = mapped_name;
    381                 DEBUG(5,("returning mapped name -- %s\n", *name));
     344        NTSTATUS map_status;
     345        NTSTATUS status;
     346
     347        status = rpccli_lsa_lookup_sids(lsa_pipe,
     348                                        mem_ctx,
     349                                        lsa_policy,
     350                                        1, /* num_sids */
     351                                        sid,
     352                                        &domains,
     353                                        &names,
     354                                        &types);
     355        if (!NT_STATUS_IS_OK(status)) {
     356                DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
     357                        nt_errstr(status)));
     358                return status;
     359        }
     360
     361        *ptype = (enum lsa_SidType) types[0];
     362
     363        map_status = normalize_name_map(mem_ctx,
     364                                        domain,
     365                                        *pname,
     366                                        &mapped_name);
     367        if (NT_STATUS_IS_OK(map_status) ||
     368            NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
     369                *pname = talloc_strdup(mem_ctx, mapped_name);
     370                DEBUG(5,("returning mapped name -- %s\n", *pname));
     371        } else {
     372                *pname = talloc_strdup(mem_ctx, names[0]);
     373        }
     374        if (*pname == NULL) {
     375                return NT_STATUS_NO_MEMORY;
     376        }
     377
     378        *pdomain_name = talloc_strdup(mem_ctx, domains[0]);
     379        if (*pdomain_name == NULL) {
     380                return NT_STATUS_NO_MEMORY;
    382381        }
    383382
     
    385384}
    386385
    387 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
    388                                     TALLOC_CTX *mem_ctx,
    389                                     const DOM_SID *sid,
    390                                     uint32 *rids,
    391                                     size_t num_rids,
    392                                     char **domain_name,
    393                                     char ***names,
    394                                     enum lsa_SidType **types)
    395 {
    396         char **domains;
    397         NTSTATUS result;
    398         DOM_SID *sids;
     386/* Convert a bunch of rids to user or group names */
     387NTSTATUS rpc_rids_to_names(TALLOC_CTX *mem_ctx,
     388                           struct rpc_pipe_client *lsa_pipe,
     389                           struct policy_handle *lsa_policy,
     390                           struct winbindd_domain *domain,
     391                           const struct dom_sid *sid,
     392                           uint32_t *rids,
     393                           size_t num_rids,
     394                           char **pdomain_name,
     395                           char ***pnames,
     396                           enum lsa_SidType **ptypes)
     397{
     398        enum lsa_SidType *types = NULL;
     399        char *domain_name = NULL;
     400        char **domains = NULL;
     401        char **names = NULL;
     402        struct dom_sid *sids;
    399403        size_t i;
    400         char **ret_names;
    401 
    402         DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
    403 
    404         if (num_rids) {
    405                 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
     404        NTSTATUS status;
     405
     406        if (num_rids > 0) {
     407                sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
    406408                if (sids == NULL) {
    407409                        return NT_STATUS_NO_MEMORY;
     
    411413        }
    412414
    413         for (i=0; i<num_rids; i++) {
     415        for (i = 0; i < num_rids; i++) {
    414416                if (!sid_compose(&sids[i], sid, rids[i])) {
    415417                        return NT_STATUS_INTERNAL_ERROR;
     
    417419        }
    418420
    419         result = winbindd_lookup_sids(mem_ctx,
    420                                       domain,
    421                                       num_rids,
    422                                       sids,
    423                                       &domains,
    424                                       names,
    425                                       types);
    426 
    427         if (!NT_STATUS_IS_OK(result) &&
    428             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
     421        status = rpccli_lsa_lookup_sids(lsa_pipe,
     422                                        mem_ctx,
     423                                        lsa_policy,
     424                                        num_rids,
     425                                        sids,
     426                                        &domains,
     427                                        &names,
     428                                        &types);
     429        if (!NT_STATUS_IS_OK(status) &&
     430            !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
     431                DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
     432                        nt_errstr(status)));
     433                return status;
     434        }
     435
     436        for (i = 0; i < num_rids; i++) {
     437                char *mapped_name = NULL;
     438                NTSTATUS map_status;
     439
     440                if (types[i] != SID_NAME_UNKNOWN) {
     441                        map_status = normalize_name_map(mem_ctx,
     442                                                        domain,
     443                                                        names[i],
     444                                                        &mapped_name);
     445                        if (NT_STATUS_IS_OK(map_status) ||
     446                            NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
     447                                TALLOC_FREE(names[i]);
     448                                names[i] = talloc_strdup(names, mapped_name);
     449                                if (names[i] == NULL) {
     450                                        return NT_STATUS_NO_MEMORY;
     451                                }
     452                        }
     453
     454                        domain_name = domains[i];
     455                }
     456        }
     457
     458        *pdomain_name = domain_name;
     459        *ptypes = types;
     460        *pnames = names;
     461
     462        return NT_STATUS_OK;
     463}
     464
     465/* Lookup user information from a rid or username. */
     466NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx,
     467                        struct rpc_pipe_client *samr_pipe,
     468                        struct policy_handle *samr_policy,
     469                        const struct dom_sid *domain_sid,
     470                        const struct dom_sid *user_sid,
     471                        struct wbint_userinfo *user_info)
     472{
     473        struct policy_handle user_policy;
     474        union samr_UserInfo *info = NULL;
     475        uint32_t user_rid;
     476        NTSTATUS status, result;
     477        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     478
     479        if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
     480                return NT_STATUS_UNSUCCESSFUL;
     481        }
     482
     483        /* Get user handle */
     484        status = dcerpc_samr_OpenUser(b,
     485                                      mem_ctx,
     486                                      samr_policy,
     487                                      SEC_FLAG_MAXIMUM_ALLOWED,
     488                                      user_rid,
     489                                      &user_policy,
     490                                      &result);
     491        if (!NT_STATUS_IS_OK(status)) {
     492                return status;
     493        }
     494        if (!NT_STATUS_IS_OK(result)) {
    429495                return result;
    430496        }
    431497
    432         ret_names = *names;
    433         for (i=0; i<num_rids; i++) {
    434                 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
    435                 char *mapped_name = NULL;
    436 
    437                 if ((*types)[i] != SID_NAME_UNKNOWN) {
    438                         name_map_status = normalize_name_map(mem_ctx,
    439                                                              domain,
    440                                                              ret_names[i],
    441                                                              &mapped_name);
    442                         if (NT_STATUS_IS_OK(name_map_status) ||
    443                             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
    444                         {
    445                                 ret_names[i] = mapped_name;
    446                         }
    447 
    448                         *domain_name = domains[i];
    449                 }
    450         }
    451 
    452         return result;
    453 }
    454 
    455 /* Lookup user information from a rid or username. */
    456 static NTSTATUS query_user(struct winbindd_domain *domain,
    457                            TALLOC_CTX *mem_ctx,
    458                            const DOM_SID *user_sid,
    459                            struct wbint_userinfo *user_info)
    460 {
    461         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    462         struct policy_handle dom_pol, user_pol;
    463         union samr_UserInfo *info = NULL;
    464         uint32 user_rid;
    465         struct netr_SamInfo3 *user;
    466         struct rpc_pipe_client *cli;
    467 
    468         DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
    469 
    470         if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
    471                 return NT_STATUS_UNSUCCESSFUL;
     498        /* Get user info */
     499        status = dcerpc_samr_QueryUserInfo(b,
     500                                           mem_ctx,
     501                                           &user_policy,
     502                                           0x15,
     503                                           &info,
     504                                           &result);
     505        {
     506                NTSTATUS _result;
     507                dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
     508        }
     509        if (!NT_STATUS_IS_OK(status)) {
     510                return status;
     511        }
     512        if (!NT_STATUS_IS_OK(result)) {
     513                return result;
     514        }
     515
     516        sid_compose(&user_info->user_sid, domain_sid, user_rid);
     517        sid_compose(&user_info->group_sid, domain_sid,
     518                    info->info21.primary_gid);
     519
     520        user_info->acct_name = talloc_strdup(user_info,
     521                                        info->info21.account_name.string);
     522        if (user_info->acct_name == NULL) {
     523                return NT_STATUS_NO_MEMORY;
     524        }
     525
     526        user_info->full_name = talloc_strdup(user_info,
     527                                        info->info21.full_name.string);
     528        if ((info->info21.full_name.string != NULL) &&
     529            (user_info->acct_name == NULL))
     530        {
     531                return NT_STATUS_NO_MEMORY;
     532        }
    472533
    473534        user_info->homedir = NULL;
     
    475536        user_info->primary_gid = (gid_t)-1;
    476537
    477         /* try netsamlogon cache first */
    478 
    479         if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
    480         {
    481 
    482                 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
    483                         sid_string_dbg(user_sid)));
    484 
    485                 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
    486                 sid_compose(&user_info->group_sid, &domain->sid,
    487                             user->base.primary_gid);
    488 
    489                 user_info->acct_name = talloc_strdup(mem_ctx,
    490                                                      user->base.account_name.string);
    491                 user_info->full_name = talloc_strdup(mem_ctx,
    492                                                      user->base.full_name.string);
    493 
    494                 TALLOC_FREE(user);
    495 
    496                 return NT_STATUS_OK;
    497         }
    498 
    499         if ( !winbindd_can_contact_domain( domain ) ) {
    500                 DEBUG(10,("query_user: No incoming trust for domain %s\n",
    501                           domain->name));
    502                 return NT_STATUS_OK;
    503         }
    504 
    505         /* no cache; hit the wire */
    506 
    507         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    508         if (!NT_STATUS_IS_OK(result))
    509                 return result;
     538        return NT_STATUS_OK;
     539}
     540
     541/* Lookup groups a user is a member of. */
     542NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx,
     543                               struct rpc_pipe_client *samr_pipe,
     544                               struct policy_handle *samr_policy,
     545                               const struct dom_sid *domain_sid,
     546                               const struct dom_sid *user_sid,
     547                               uint32_t *pnum_groups,
     548                               struct dom_sid **puser_grpsids)
     549{
     550        struct policy_handle user_policy;
     551        struct samr_RidWithAttributeArray *rid_array = NULL;
     552        struct dom_sid *user_grpsids = NULL;
     553        uint32_t num_groups = 0, i;
     554        uint32_t user_rid;
     555        NTSTATUS status, result;
     556        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     557
     558        if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
     559                return NT_STATUS_UNSUCCESSFUL;
     560        }
    510561
    511562        /* Get user handle */
    512         result = rpccli_samr_OpenUser(cli, mem_ctx,
    513                                       &dom_pol,
     563        status = dcerpc_samr_OpenUser(b,
     564                                      mem_ctx,
     565                                      samr_policy,
    514566                                      SEC_FLAG_MAXIMUM_ALLOWED,
    515567                                      user_rid,
    516                                       &user_pol);
    517 
    518         if (!NT_STATUS_IS_OK(result))
     568                                      &user_policy,
     569                                      &result);
     570        if (!NT_STATUS_IS_OK(status)) {
     571                return status;
     572        }
     573        if (!NT_STATUS_IS_OK(result)) {
    519574                return result;
    520 
    521         /* Get user info */
    522         result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
    523                                            &user_pol,
    524                                            0x15,
    525                                            &info);
    526 
    527         rpccli_samr_Close(cli, mem_ctx, &user_pol);
    528 
    529         if (!NT_STATUS_IS_OK(result))
     575        }
     576
     577        /* Query user rids */
     578        status = dcerpc_samr_GetGroupsForUser(b,
     579                                              mem_ctx,
     580                                              &user_policy,
     581                                              &rid_array,
     582                                              &result);
     583        num_groups = rid_array->count;
     584
     585        {
     586                NTSTATUS _result;
     587                dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result);
     588        }
     589
     590        if (!NT_STATUS_IS_OK(status)) {
     591                return status;
     592        }
     593        if (!NT_STATUS_IS_OK(result) || num_groups == 0) {
    530594                return result;
    531 
    532         sid_compose(&user_info->user_sid, &domain->sid, user_rid);
    533         sid_compose(&user_info->group_sid, &domain->sid,
    534                     info->info21.primary_gid);
    535         user_info->acct_name = talloc_strdup(mem_ctx,
    536                                              info->info21.account_name.string);
    537         user_info->full_name = talloc_strdup(mem_ctx,
    538                                              info->info21.full_name.string);
    539         user_info->homedir = NULL;
    540         user_info->shell = NULL;
    541         user_info->primary_gid = (gid_t)-1;
     595        }
     596
     597        user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups);
     598        if (user_grpsids == NULL) {
     599                status = NT_STATUS_NO_MEMORY;
     600                return status;
     601        }
     602
     603        for (i = 0; i < num_groups; i++) {
     604                sid_compose(&(user_grpsids[i]), domain_sid,
     605                            rid_array->rids[i].rid);
     606        }
     607
     608        *pnum_groups = num_groups;
     609
     610        *puser_grpsids = user_grpsids;
    542611
    543612        return NT_STATUS_OK;
    544 }                                   
    545 
    546 /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
    547 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
    548                                   TALLOC_CTX *mem_ctx,
    549                                   const DOM_SID *user_sid,
    550                                   uint32 *num_groups, DOM_SID **user_grpsids)
    551 {
    552         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    553         struct policy_handle dom_pol, user_pol;
    554         uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
    555         struct samr_RidWithAttributeArray *rid_array = NULL;
    556         unsigned int i;
    557         uint32 user_rid;
    558         struct rpc_pipe_client *cli;
    559 
    560         DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
    561 
    562         if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
    563                 return NT_STATUS_UNSUCCESSFUL;
    564 
    565         *num_groups = 0;
    566         *user_grpsids = NULL;
    567 
    568         /* so lets see if we have a cached user_info_3 */
    569         result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
    570                                           num_groups, user_grpsids);
    571 
    572         if (NT_STATUS_IS_OK(result)) {
    573                 return NT_STATUS_OK;
    574         }
    575 
    576         if ( !winbindd_can_contact_domain( domain ) ) {
    577                 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
    578                           domain->name));
    579 
    580                 /* Tell the cache manager not to remember this one */
    581 
    582                 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
    583         }
    584 
    585         /* no cache; hit the wire */
    586 
    587         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    588         if (!NT_STATUS_IS_OK(result))
    589                 return result;
    590 
    591         /* Get user handle */
    592         result = rpccli_samr_OpenUser(cli, mem_ctx,
    593                                       &dom_pol,
    594                                       des_access,
    595                                       user_rid,
    596                                       &user_pol);
    597 
    598         if (!NT_STATUS_IS_OK(result))
    599                 return result;
    600 
    601         /* Query user rids */
    602         result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
    603                                               &user_pol,
    604                                               &rid_array);
    605         *num_groups = rid_array->count;
    606 
    607         rpccli_samr_Close(cli, mem_ctx, &user_pol);
    608 
    609         if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
    610                 return result;
    611 
    612         (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
    613         if (!(*user_grpsids))
    614                 return NT_STATUS_NO_MEMORY;
    615 
    616         for (i=0;i<(*num_groups);i++) {
    617                 sid_copy(&((*user_grpsids)[i]), &domain->sid);
    618                 sid_append_rid(&((*user_grpsids)[i]),
    619                                 rid_array->rids[i].rid);
    620         }
    621 
    622         return NT_STATUS_OK;
    623 }
    624 
     613}
     614
     615NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx,
     616                                struct rpc_pipe_client *samr_pipe,
     617                                struct policy_handle *samr_policy,
     618                                uint32_t num_sids,
     619                                const struct dom_sid *sids,
     620                                uint32_t *pnum_aliases,
     621                                uint32_t **palias_rids)
     622{
    625623#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
    626 
    627 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
    628                                          TALLOC_CTX *mem_ctx,
    629                                          uint32 num_sids, const DOM_SID *sids,
    630                                          uint32 *num_aliases,
    631                                          uint32 **alias_rids)
    632 {
    633         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    634         struct policy_handle dom_pol;
    635         uint32 num_query_sids = 0;
    636         int i;
    637         struct rpc_pipe_client *cli;
     624        uint32_t num_query_sids = 0;
     625        uint32_t num_queries = 1;
     626        uint32_t num_aliases = 0;
     627        uint32_t total_sids = 0;
     628        uint32_t *alias_rids = NULL;
     629        uint32_t rangesize = MAX_SAM_ENTRIES_W2K;
     630        uint32_t i;
    638631        struct samr_Ids alias_rids_query;
    639         int rangesize = MAX_SAM_ENTRIES_W2K;
    640         uint32 total_sids = 0;
    641         int num_queries = 1;
    642 
    643         *num_aliases = 0;
    644         *alias_rids = NULL;
    645 
    646         DEBUG(3,("rpc: lookup_useraliases\n"));
    647 
    648         if ( !winbindd_can_contact_domain( domain ) ) {
    649                 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
    650                           domain->name));
    651                 return NT_STATUS_OK;
    652         }
    653 
    654         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    655         if (!NT_STATUS_IS_OK(result))
    656                 return result;
     632        NTSTATUS status, result;
     633        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
    657634
    658635        do {
     
    664641                num_query_sids = MIN(num_sids - total_sids, rangesize);
    665642
    666                 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 
    667                         num_queries, num_query_sids)); 
     643                DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
     644                        num_queries, num_query_sids));
    668645
    669646                if (num_query_sids) {
     
    676653                }
    677654
    678                 for (i=0; i<num_query_sids; i++) {
    679                         sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
    680                         if (!sid_array.sids[i].sid) {
    681                                 TALLOC_FREE(sid_array.sids);
     655                for (i = 0; i < num_query_sids; i++) {
     656                        sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]);
     657                        if (sid_array.sids[i].sid == NULL) {
    682658                                return NT_STATUS_NO_MEMORY;
    683659                        }
     
    686662
    687663                /* do request */
    688                 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
    689                                                         &dom_pol,
     664                status = dcerpc_samr_GetAliasMembership(b,
     665                                                        mem_ctx,
     666                                                        samr_policy,
    690667                                                        &sid_array,
    691                                                         &alias_rids_query);
    692 
     668                                                        &alias_rids_query,
     669                                                        &result);
     670                if (!NT_STATUS_IS_OK(status)) {
     671                        return status;
     672                }
    693673                if (!NT_STATUS_IS_OK(result)) {
    694                         *num_aliases = 0;
    695                         *alias_rids = NULL;
    696                         TALLOC_FREE(sid_array.sids);
    697                         goto done;
     674                        return result;
    698675                }
    699676
    700677                /* process output */
    701 
    702                 for (i=0; i<alias_rids_query.count; i++) {
    703                         size_t na = *num_aliases;
    704                         if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
    705                                                 alias_rids, &na)) {
    706                                 return NT_STATUS_NO_MEMORY;
    707                         }
    708                         *num_aliases = na;
    709                 }
    710 
    711                 TALLOC_FREE(sid_array.sids);
     678                for (i = 0; i < alias_rids_query.count; i++) {
     679                        size_t na = num_aliases;
     680
     681                        if (!add_rid_to_array_unique(mem_ctx,
     682                                                     alias_rids_query.ids[i],
     683                                                     &alias_rids,
     684                                                     &na)) {
     685                                        return NT_STATUS_NO_MEMORY;
     686                                }
     687                                num_aliases = na;
     688                }
    712689
    713690                num_queries++;
     
    715692        } while (total_sids < num_sids);
    716693
    717  done:
    718         DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
    719                 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
    720 
    721         return result;
    722 }
    723 
     694        DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
     695                  "(rangesize: %d)\n", num_aliases, num_queries, rangesize));
     696
     697        *pnum_aliases = num_aliases;
     698        *palias_rids = alias_rids;
     699
     700        return NT_STATUS_OK;
     701#undef MAX_SAM_ENTRIES_W2K
     702}
    724703
    725704/* Lookup group membership given a rid.   */
    726 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
    727                                 TALLOC_CTX *mem_ctx,
    728                                 const DOM_SID *group_sid,
    729                                 enum lsa_SidType type,
    730                                 uint32 *num_names,
    731                                 DOM_SID **sid_mem, char ***names,
    732                                 uint32 **name_types)
    733 {
    734         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    735         uint32 i, total_names = 0;
    736         struct policy_handle dom_pol, group_pol;
    737         uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
    738         uint32 *rid_mem = NULL;
    739         uint32 group_rid;
    740         unsigned int j, r;
    741         struct rpc_pipe_client *cli;
    742         unsigned int orig_timeout;
    743         struct samr_RidTypeArray *rids = NULL;
    744 
    745         DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
    746                   sid_string_dbg(group_sid)));
    747 
    748         if ( !winbindd_can_contact_domain( domain ) ) {
    749                 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
    750                           domain->name));
    751                 return NT_STATUS_OK;
    752         }
    753 
    754         if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
     705NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
     706                             struct rpc_pipe_client *samr_pipe,
     707                             struct policy_handle *samr_policy,
     708                             const char *domain_name,
     709                             const struct dom_sid *domain_sid,
     710                             const struct dom_sid *group_sid,
     711                             enum lsa_SidType type,
     712                             uint32_t *pnum_names,
     713                             struct dom_sid **psid_mem,
     714                             char ***pnames,
     715                             uint32_t **pname_types)
     716{
     717        struct policy_handle group_policy;
     718        uint32_t group_rid;
     719        uint32_t *rid_mem = NULL;
     720
     721        uint32_t num_names = 0;
     722        uint32_t total_names = 0;
     723        struct dom_sid *sid_mem = NULL;
     724        char **names = NULL;
     725        uint32_t *name_types = NULL;
     726
     727        struct lsa_Strings tmp_names;
     728        struct samr_Ids tmp_types;
     729
     730        uint32_t j, r;
     731        NTSTATUS status, result;
     732        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     733
     734        if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
    755735                return NT_STATUS_UNSUCCESSFUL;
    756 
    757         *num_names = 0;
    758 
    759         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    760         if (!NT_STATUS_IS_OK(result))
    761                 return result;
    762 
    763         result = rpccli_samr_OpenGroup(cli, mem_ctx,
    764                                        &dom_pol,
    765                                        des_access,
    766                                        group_rid,
    767                                        &group_pol);
    768 
    769         if (!NT_STATUS_IS_OK(result))
    770                 return result;
    771 
    772         /* Step #1: Get a list of user rids that are the members of the
    773            group. */
    774 
    775         /* This call can take a long time - allow the server to time out.
    776            35 seconds should do it. */
    777 
    778         orig_timeout = rpccli_set_timeout(cli, 35000);
    779 
    780         result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
    781                                               &group_pol,
    782                                               &rids);
    783 
    784         /* And restore our original timeout. */
    785         rpccli_set_timeout(cli, orig_timeout);
    786 
    787         rpccli_samr_Close(cli, mem_ctx, &group_pol);
    788 
    789         if (!NT_STATUS_IS_OK(result))
    790                 return result;
    791 
    792         if (!rids || !rids->count) {
    793                 names = NULL;
    794                 name_types = NULL;
    795                 sid_mem = NULL;
    796                 return NT_STATUS_OK;
    797         }
    798 
    799         *num_names = rids->count;
    800         rid_mem = rids->rids;
    801 
    802         /* Step #2: Convert list of rids into list of usernames.  Do this
    803            in bunches of ~1000 to avoid crashing NT4.  It looks like there
    804            is a buffer overflow or something like that lurking around
    805            somewhere. */
    806 
    807 #define MAX_LOOKUP_RIDS 900
    808 
    809         *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
    810         *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
    811         *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
    812 
    813         for (j=0;j<(*num_names);j++)
    814                 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
    815 
    816         if (*num_names>0 && (!*names || !*name_types))
    817                 return NT_STATUS_NO_MEMORY;
    818 
    819         for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
    820                 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
    821                 struct lsa_Strings tmp_names;
    822                 struct samr_Ids tmp_types;
    823 
    824                 /* Lookup a chunk of rids */
    825 
    826                 result = rpccli_samr_LookupRids(cli, mem_ctx,
    827                                                 &dom_pol,
    828                                                 num_lookup_rids,
    829                                                 &rid_mem[i],
    830                                                 &tmp_names,
    831                                                 &tmp_types);
    832 
    833                 /* see if we have a real error (and yes the
    834                    STATUS_SOME_UNMAPPED is the one returned from 2k) */
    835 
    836                 if (!NT_STATUS_IS_OK(result) &&
    837                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
     736        }
     737
     738        switch(type) {
     739        case SID_NAME_DOM_GRP:
     740        {
     741                struct samr_RidAttrArray *rids = NULL;
     742
     743                status = dcerpc_samr_OpenGroup(b,
     744                                               mem_ctx,
     745                                               samr_policy,
     746                                               SEC_FLAG_MAXIMUM_ALLOWED,
     747                                               group_rid,
     748                                               &group_policy,
     749                                               &result);
     750                if (!NT_STATUS_IS_OK(status)) {
     751                        return status;
     752                }
     753                if (!NT_STATUS_IS_OK(result)) {
    838754                        return result;
    839 
    840                 /* Copy result into array.  The talloc system will take
    841                    care of freeing the temporary arrays later on. */
    842 
    843                 if (tmp_names.count != tmp_types.count) {
    844                         return NT_STATUS_UNSUCCESSFUL;
    845                 }
    846 
    847                 for (r=0; r<tmp_names.count; r++) {
    848                         if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
    849                                 continue;
    850                         }
    851                         (*names)[total_names] = fill_domain_username_talloc(
    852                                 mem_ctx, domain->name,
    853                                 tmp_names.names[r].string, true);
    854                         (*name_types)[total_names] = tmp_types.ids[r];
    855                         total_names += 1;
    856                 }
    857         }
    858 
    859         *num_names = total_names;
     755                }
     756
     757                /*
     758                 * Step #1: Get a list of user rids that are the members of the group.
     759                 */
     760                status = dcerpc_samr_QueryGroupMember(b,
     761                                                      mem_ctx,
     762                                                      &group_policy,
     763                                                      &rids,
     764                                                      &result);
     765                {
     766                        NTSTATUS _result;
     767                        dcerpc_samr_Close(b, mem_ctx, &group_policy, &_result);
     768                }
     769
     770                if (!NT_STATUS_IS_OK(status)) {
     771                        return status;
     772                }
     773                if (!NT_STATUS_IS_OK(result)) {
     774                        return result;
     775                }
     776
     777
     778                if (rids == NULL || rids->count == 0) {
     779                        pnum_names = 0;
     780                        pnames = NULL;
     781                        pname_types = NULL;
     782                        psid_mem = NULL;
     783
     784                        return NT_STATUS_OK;
     785                }
     786
     787                num_names = rids->count;
     788                rid_mem = rids->rids;
     789
     790                break;
     791        }
     792        case SID_NAME_WKN_GRP:
     793        case SID_NAME_ALIAS:
     794        {
     795                struct lsa_SidArray sid_array;
     796                struct lsa_SidPtr sid_ptr;
     797                struct samr_Ids rids_query;
     798
     799                sid_ptr.sid = dom_sid_dup(mem_ctx, group_sid);
     800                if (sid_ptr.sid == NULL) {
     801                        return NT_STATUS_NO_MEMORY;
     802                }
     803
     804                sid_array.num_sids = 1;
     805                sid_array.sids = &sid_ptr;
     806
     807                status = dcerpc_samr_GetAliasMembership(b,
     808                                                        mem_ctx,
     809                                                        samr_policy,
     810                                                        &sid_array,
     811                                                        &rids_query,
     812                                                        &result);
     813                if (!NT_STATUS_IS_OK(status)) {
     814                        return status;
     815                }
     816                if (!NT_STATUS_IS_OK(result)) {
     817                        return result;
     818                }
     819
     820                if (rids_query.count == 0) {
     821                        pnum_names = 0;
     822                        pnames = NULL;
     823                        pname_types = NULL;
     824                        psid_mem = NULL;
     825
     826                        return NT_STATUS_OK;
     827                }
     828
     829                num_names = rids_query.count;
     830                rid_mem = rids_query.ids;
     831
     832                break;
     833        }
     834        default:
     835                return NT_STATUS_UNSUCCESSFUL;
     836        }
     837
     838        /*
     839         * Step #2: Convert list of rids into list of usernames.
     840         */
     841        if (num_names > 0) {
     842                names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_names);
     843                name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32_t, num_names);
     844                sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_names);
     845                if (names == NULL || name_types == NULL || sid_mem == NULL) {
     846                        return NT_STATUS_NO_MEMORY;
     847                }
     848        }
     849
     850        for (j = 0; j < num_names; j++) {
     851                sid_compose(&sid_mem[j], domain_sid, rid_mem[j]);
     852        }
     853
     854        status = dcerpc_samr_LookupRids(b,
     855                                        mem_ctx,
     856                                        samr_policy,
     857                                        num_names,
     858                                        rid_mem,
     859                                        &tmp_names,
     860                                        &tmp_types,
     861                                        &result);
     862        if (!NT_STATUS_IS_OK(status)) {
     863                return status;
     864        }
     865
     866        if (!NT_STATUS_IS_OK(result)) {
     867                if (!NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
     868                        return result;
     869                }
     870        }
     871
     872        /* Copy result into array.  The talloc system will take
     873           care of freeing the temporary arrays later on. */
     874        if (tmp_names.count != tmp_types.count) {
     875                return NT_STATUS_UNSUCCESSFUL;
     876        }
     877
     878        for (r = 0; r < tmp_names.count; r++) {
     879                if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
     880                        continue;
     881                }
     882                names[total_names] = fill_domain_username_talloc(names,
     883                                                                 domain_name,
     884                                                                 tmp_names.names[r].string,
     885                                                                 true);
     886                if (names[total_names] == NULL) {
     887                        return NT_STATUS_NO_MEMORY;
     888                }
     889                name_types[total_names] = tmp_types.ids[r];
     890                total_names++;
     891        }
     892
     893        *pnum_names = total_names;
     894        *pnames = names;
     895        *pname_types = name_types;
     896        *psid_mem = sid_mem;
    860897
    861898        return NT_STATUS_OK;
    862899}
    863900
    864 #ifdef HAVE_LDAP
    865 
    866 #include <ldap.h>
    867 
    868 static int get_ldap_seq(const char *server, int port, uint32 *seq)
    869 {
    870         int ret = -1;
    871         struct timeval to;
    872         const char *attrs[] = {"highestCommittedUSN", NULL};
    873         LDAPMessage *res = NULL;
    874         char **values = NULL;
    875         LDAP *ldp = NULL;
    876 
    877         *seq = DOM_SEQUENCE_NONE;
    878 
    879         /*
    880          * Parameterised (5) second timeout on open. This is needed as the
    881          * search timeout doesn't seem to apply to doing an open as well. JRA.
    882          */
    883 
    884         ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
    885         if (ldp == NULL)
    886                 return -1;
    887 
    888         /* Timeout if no response within 20 seconds. */
    889         to.tv_sec = 10;
    890         to.tv_usec = 0;
    891 
    892         if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
    893                            CONST_DISCARD(char **, attrs), 0, &to, &res))
    894                 goto done;
    895 
    896         if (ldap_count_entries(ldp, res) != 1)
    897                 goto done;
    898 
    899         values = ldap_get_values(ldp, res, "highestCommittedUSN");
    900         if (!values || !values[0])
    901                 goto done;
    902 
    903         *seq = atoi(values[0]);
    904         ret = 0;
    905 
    906   done:
    907 
    908         if (values)
    909                 ldap_value_free(values);
    910         if (res)
    911                 ldap_msgfree(res);
    912         if (ldp)
    913                 ldap_unbind(ldp);
    914         return ret;
    915 }
    916 
    917 /**********************************************************************
    918  Get the sequence number for a Windows AD native mode domain using
    919  LDAP queries.
    920 **********************************************************************/
    921 
    922 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
    923 {
    924         int ret = -1;
    925         char addr[INET6_ADDRSTRLEN];
    926 
    927         print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
    928         if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
    929                 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
    930                           "number for Domain (%s) from DC (%s)\n",
    931                         domain->name, addr));
    932         }
    933         return ret;
    934 }
    935 
    936 #endif /* HAVE_LDAP */
    937 
    938 /* find the sequence number for a domain */
    939 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
    940 {
    941         TALLOC_CTX *mem_ctx;
     901/* Find the sequence number for a domain */
     902NTSTATUS rpc_sequence_number(TALLOC_CTX *mem_ctx,
     903                             struct rpc_pipe_client *samr_pipe,
     904                             struct policy_handle *samr_policy,
     905                             const char *domain_name,
     906                             uint32_t *pseq)
     907{
    942908        union samr_DomainInfo *info = NULL;
    943         NTSTATUS result;
    944         struct policy_handle dom_pol;
    945         bool got_seq_num = False;
    946         struct rpc_pipe_client *cli;
    947 
    948         DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
    949 
    950         if ( !winbindd_can_contact_domain( domain ) ) {
    951                 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
    952                           domain->name));
    953                 *seq = time(NULL);
    954                 return NT_STATUS_OK;
    955         }
    956 
    957         *seq = DOM_SEQUENCE_NONE;
    958 
    959         if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
    960                 return NT_STATUS_NO_MEMORY;
    961 
    962 #ifdef HAVE_LDAP
    963         if ( domain->active_directory )
    964         {
    965                 int res;
    966 
    967                 DEBUG(8,("using get_ldap_seq() to retrieve the "
    968                          "sequence number\n"));
    969 
    970                 res =  get_ldap_sequence_number( domain, seq );
    971                 if (res == 0)
    972                 {                       
    973                         result = NT_STATUS_OK;
    974                         DEBUG(10,("domain_sequence_number: LDAP for "
    975                                   "domain %s is %u\n",
    976                                   domain->name, *seq));
    977                         goto done;
    978                 }
    979 
    980                 DEBUG(10,("domain_sequence_number: failed to get LDAP "
    981                           "sequence number for domain %s\n",
    982                           domain->name ));
    983         }
    984 #endif /* HAVE_LDAP */
    985 
    986         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    987         if (!NT_STATUS_IS_OK(result)) {
    988                 goto done;
    989         }
    990 
    991         /* Query domain info */
    992 
    993         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
    994                                              &dom_pol,
     909        bool got_seq_num = false;
     910        NTSTATUS status, result;
     911        struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
     912
     913        /* query domain info */
     914        status = dcerpc_samr_QueryDomainInfo(b,
     915                                             mem_ctx,
     916                                             samr_policy,
    995917                                             8,
    996                                              &info);
    997 
    998         if (NT_STATUS_IS_OK(result)) {
    999                 *seq = info->info8.sequence_num;
    1000                 got_seq_num = True;
     918                                             &info,
     919                                             &result);
     920        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
     921                *pseq = info->info8.sequence_num;
     922                got_seq_num = true;
    1001923                goto seq_num;
    1002924        }
     
    1004926        /* retry with info-level 2 in case the dc does not support info-level 8
    1005927         * (like all older samba2 and samba3 dc's) - Guenther */
    1006 
    1007         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
    1008                                              &dom_pol,
     928        status = dcerpc_samr_QueryDomainInfo(b,
     929                                            mem_ctx,
     930                                             samr_policy,
    1009931                                             2,
    1010                                              &info);
    1011 
    1012         if (NT_STATUS_IS_OK(result)) {
    1013                 *seq = info->general.sequence_num;
    1014                 got_seq_num = True;
    1015         }
    1016 
    1017  seq_num:
     932                                             &info,
     933                                             &result);
     934        if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
     935                *pseq = info->general.sequence_num;
     936                got_seq_num = true;
     937                goto seq_num;
     938        }
     939
     940        if (!NT_STATUS_IS_OK(status)) {
     941                goto seq_num;
     942        }
     943
     944        status = result;
     945
     946seq_num:
    1018947        if (got_seq_num) {
    1019948                DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
    1020                           domain->name, (unsigned)*seq));
     949                          domain_name, (unsigned) *pseq));
    1021950        } else {
    1022951                DEBUG(10,("domain_sequence_number: failed to get sequence "
    1023952                          "number (%u) for domain %s\n",
    1024                           (unsigned)*seq, domain->name ));
    1025         }
    1026 
    1027   done:
    1028 
    1029         talloc_destroy(mem_ctx);
    1030 
    1031         return result;
    1032 }
    1033 
    1034 /* get a list of trusted domains */
    1035 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
    1036                                 TALLOC_CTX *mem_ctx,
    1037                                 struct netr_DomainTrustList *trusts)
    1038 {
    1039         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    1040         uint32 enum_ctx = 0;
    1041         struct rpc_pipe_client *cli;
    1042         struct policy_handle lsa_policy;
    1043 
    1044         DEBUG(3,("rpc: trusted_domains\n"));
    1045 
    1046         ZERO_STRUCTP(trusts);
    1047 
    1048         result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
    1049         if (!NT_STATUS_IS_OK(result))
    1050                 return result;
    1051 
    1052         result = STATUS_MORE_ENTRIES;
    1053 
    1054         while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
    1055                 uint32 start_idx;
    1056                 int i;
     953                          (unsigned) *pseq, domain_name ));
     954                status = NT_STATUS_OK;
     955        }
     956
     957        return status;
     958}
     959
     960/* Get a list of trusted domains */
     961NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
     962                             struct rpc_pipe_client *lsa_pipe,
     963                             struct policy_handle *lsa_policy,
     964                             uint32_t *pnum_trusts,
     965                             struct netr_DomainTrust **ptrusts)
     966{
     967        struct netr_DomainTrust *array = NULL;
     968        uint32_t enum_ctx = 0;
     969        uint32_t count = 0;
     970        NTSTATUS status, result;
     971        struct dcerpc_binding_handle *b = lsa_pipe->binding_handle;
     972
     973        do {
    1057974                struct lsa_DomainList dom_list;
    1058 
    1059                 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
    1060                                                  &lsa_policy,
     975                uint32_t start_idx;
     976                uint32_t i;
     977
     978                /*
     979                 * We don't run into deadlocks here, cause winbind_off() is
     980                 * called in the main function.
     981                 */
     982                status = dcerpc_lsa_EnumTrustDom(b,
     983                                                 mem_ctx,
     984                                                 lsa_policy,
    1061985                                                 &enum_ctx,
    1062986                                                 &dom_list,
    1063                                                  (uint32_t)-1);
    1064 
    1065                 if (!NT_STATUS_IS_OK(result) &&
    1066                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
    1067                         break;
    1068 
    1069                 start_idx = trusts->count;
    1070                 trusts->count += dom_list.count;
    1071 
    1072                 trusts->array = talloc_realloc(
    1073                         mem_ctx, trusts->array, struct netr_DomainTrust,
    1074                         trusts->count);
    1075                 if (trusts->array == NULL) {
     987                                                 (uint32_t) -1,
     988                                                 &result);
     989                if (!NT_STATUS_IS_OK(status)) {
     990                        return status;
     991                }
     992                if (!NT_STATUS_IS_OK(result)) {
     993                        if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     994                                return result;
     995                        }
     996                }
     997
     998                start_idx = count;
     999                count += dom_list.count;
     1000
     1001                array = talloc_realloc(mem_ctx,
     1002                                       array,
     1003                                       struct netr_DomainTrust,
     1004                                       count);
     1005                if (array == NULL) {
    10761006                        return NT_STATUS_NO_MEMORY;
    10771007                }
    10781008
    1079                 for (i=0; i<dom_list.count; i++) {
    1080                         struct netr_DomainTrust *trust = &trusts->array[i];
     1009                for (i = 0; i < dom_list.count; i++) {
     1010                        struct netr_DomainTrust *trust = &array[i];
    10811011                        struct dom_sid *sid;
    10821012
    10831013                        ZERO_STRUCTP(trust);
    10841014
    1085                         trust->netbios_name = talloc_move(
    1086                                 trusts->array,
    1087                                 &dom_list.domains[i].name.string);
     1015                        trust->netbios_name = talloc_move(array,
     1016                                                          &dom_list.domains[i].name.string);
    10881017                        trust->dns_name = NULL;
    10891018
    1090                         sid = talloc(trusts->array, struct dom_sid);
     1019                        sid = talloc(array, struct dom_sid);
    10911020                        if (sid == NULL) {
    10921021                                return NT_STATUS_NO_MEMORY;
     
    10951024                        trust->sid = sid;
    10961025                }
    1097         }
     1026        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
     1027
     1028        *pnum_trusts = count;
     1029        *ptrusts = array;
     1030
     1031        return NT_STATUS_OK;
     1032}
     1033
     1034static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
     1035                                     struct winbindd_domain *domain,
     1036                                     struct lsa_SidArray *sids,
     1037                                     struct lsa_RefDomainList **pdomains,
     1038                                     struct lsa_TransNameArray **pnames)
     1039{
     1040        struct lsa_TransNameArray2 lsa_names2;
     1041        struct lsa_TransNameArray *names;
     1042        uint32_t i, count;
     1043        struct rpc_pipe_client *cli;
     1044        NTSTATUS status, result;
     1045
     1046        status = cm_connect_lsa_tcp(domain, talloc_tos(), &cli);
     1047        if (!NT_STATUS_IS_OK(status)) {
     1048                domain->can_do_ncacn_ip_tcp = false;
     1049                return status;
     1050        }
     1051
     1052        ZERO_STRUCT(lsa_names2);
     1053        status = dcerpc_lsa_LookupSids3(cli->binding_handle,
     1054                                        mem_ctx,
     1055                                        sids,
     1056                                        pdomains,
     1057                                        &lsa_names2,
     1058                                        LSA_LOOKUP_NAMES_ALL,
     1059                                        &count,
     1060                                        LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES,
     1061                                        LSA_CLIENT_REVISION_2,
     1062                                        &result);
     1063        if (!NT_STATUS_IS_OK(status)) {
     1064                return status;
     1065        }
     1066        if (NT_STATUS_IS_ERR(result)) {
     1067                return result;
     1068        }
     1069        names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray);
     1070        if (names == NULL) {
     1071                return NT_STATUS_NO_MEMORY;
     1072        }
     1073        names->count = lsa_names2.count;
     1074        names->names = talloc_array(names, struct lsa_TranslatedName,
     1075                                    names->count);
     1076        if (names->names == NULL) {
     1077                return NT_STATUS_NO_MEMORY;
     1078        }
     1079        for (i=0; i<names->count; i++) {
     1080                names->names[i].sid_type = lsa_names2.names[i].sid_type;
     1081                names->names[i].name.string = talloc_move(
     1082                        names->names, &lsa_names2.names[i].name.string);
     1083                names->names[i].sid_index = lsa_names2.names[i].sid_index;
     1084        }
     1085        *pnames = names;
    10981086        return result;
    10991087}
    11001088
    1101 /* find the lockout policy for a domain */
    1102 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
    1103                                      TALLOC_CTX *mem_ctx,
    1104                                      struct samr_DomInfo12 *lockout_policy)
    1105 {
    1106         NTSTATUS result;
    1107         struct rpc_pipe_client *cli;
    1108         struct policy_handle dom_pol;
    1109         union samr_DomainInfo *info = NULL;
    1110 
    1111         DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
    1112 
    1113         if ( !winbindd_can_contact_domain( domain ) ) {
    1114                 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
    1115                           domain->name));
    1116                 return NT_STATUS_NOT_SUPPORTED;
    1117         }
    1118 
    1119         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    1120         if (!NT_STATUS_IS_OK(result)) {
    1121                 goto done;
    1122         }
    1123 
    1124         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
    1125                                              &dom_pol,
    1126                                              12,
    1127                                              &info);
    1128         if (!NT_STATUS_IS_OK(result)) {
    1129                 goto done;
    1130         }
    1131 
    1132         *lockout_policy = info->info12;
    1133 
    1134         DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
    1135                 info->info12.lockout_threshold));
    1136 
    1137   done:
    1138 
    1139         return result;
    1140 }
    1141 
    1142 /* find the password policy for a domain */
    1143 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
    1144                                       TALLOC_CTX *mem_ctx,
    1145                                       struct samr_DomInfo1 *password_policy)
    1146 {
    1147         NTSTATUS result;
    1148         struct rpc_pipe_client *cli;
    1149         struct policy_handle dom_pol;
    1150         union samr_DomainInfo *info = NULL;
    1151 
    1152         DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
    1153 
    1154         if ( !winbindd_can_contact_domain( domain ) ) {
    1155                 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
    1156                           domain->name));
    1157                 return NT_STATUS_NOT_SUPPORTED;
    1158         }
    1159 
    1160         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
    1161         if (!NT_STATUS_IS_OK(result)) {
    1162                 goto done;
    1163         }
    1164 
    1165         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
    1166                                              &dom_pol,
    1167                                              1,
    1168                                              &info);
    1169         if (!NT_STATUS_IS_OK(result)) {
    1170                 goto done;
    1171         }
    1172 
    1173         *password_policy = info->info1;
    1174 
    1175         DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
    1176                 info->info1.min_password_length));
    1177 
    1178   done:
    1179 
    1180         return result;
    1181 }
    1182 
    1183 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
    1184                                      TALLOC_CTX *mem_ctx,
    1185                                      struct policy_handle *pol,
    1186                                      int num_sids,
    1187                                      const DOM_SID *sids,
    1188                                      char ***pdomains,
    1189                                      char ***pnames,
    1190                                      enum lsa_SidType **ptypes);
    1191 
    1192 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
    1193                               struct winbindd_domain *domain,
    1194                               uint32_t num_sids,
    1195                               const struct dom_sid *sids,
    1196                               char ***domains,
    1197                               char ***names,
    1198                               enum lsa_SidType **types)
    1199 {
    1200         NTSTATUS status;
     1089NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
     1090                         struct winbindd_domain *domain,
     1091                         struct lsa_SidArray *sids,
     1092                         struct lsa_RefDomainList **pdomains,
     1093                         struct lsa_TransNameArray **pnames)
     1094{
     1095        struct lsa_TransNameArray *names;
    12011096        struct rpc_pipe_client *cli = NULL;
    12021097        struct policy_handle lsa_policy;
    1203         unsigned int orig_timeout;
    1204         lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
     1098        uint32_t count;
     1099        NTSTATUS status, result;
    12051100
    12061101        if (domain->can_do_ncacn_ip_tcp) {
    1207                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
    1208                 if (NT_STATUS_IS_OK(status)) {
    1209                         lookup_sids_fn = rpccli_lsa_lookup_sids3;
    1210                         goto lookup;
    1211                 }
    1212                 domain->can_do_ncacn_ip_tcp = false;
    1213         }
     1102                status = rpc_try_lookup_sids3(mem_ctx, domain, sids,
     1103                                              pdomains, pnames);
     1104                if (!NT_STATUS_IS_ERR(status)) {
     1105                        return status;
     1106                }
     1107        }
     1108
    12141109        status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
    1215 
    12161110        if (!NT_STATUS_IS_OK(status)) {
    12171111                return status;
    12181112        }
    12191113
    1220  lookup:
    1221         /*
    1222          * This call can take a long time
    1223          * allow the server to time out.
    1224          * 35 seconds should do it.
    1225          */
    1226         orig_timeout = rpccli_set_timeout(cli, 35000);
    1227 
    1228         status = lookup_sids_fn(cli,
    1229                                 mem_ctx,
    1230                                 &lsa_policy,
    1231                                 num_sids,
    1232                                 sids,
    1233                                 domains,
    1234                                 names,
    1235                                 types);
    1236 
    1237         /* And restore our original timeout. */
    1238         rpccli_set_timeout(cli, orig_timeout);
    1239 
    1240         if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
    1241             NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
    1242                 /*
    1243                  * This can happen if the schannel key is not
    1244                  * valid anymore, we need to invalidate the
    1245                  * all connections to the dc and reestablish
    1246                  * a netlogon connection first.
    1247                  */
    1248                 invalidate_cm_connection(&domain->conn);
    1249                 status = NT_STATUS_ACCESS_DENIED;
    1250         }
    1251 
     1114        names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray);
     1115        if (names == NULL) {
     1116                return NT_STATUS_NO_MEMORY;
     1117        }
     1118        status = dcerpc_lsa_LookupSids(cli->binding_handle, mem_ctx,
     1119                                       &lsa_policy, sids, pdomains,
     1120                                       names, LSA_LOOKUP_NAMES_ALL,
     1121                                       &count, &result);
    12521122        if (!NT_STATUS_IS_OK(status)) {
    12531123                return status;
    12541124        }
    1255 
    1256         return status;
    1257 }
    1258 
    1259 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
    1260                                       TALLOC_CTX *mem_ctx,
    1261                                       struct policy_handle *pol,
    1262                                       int num_names,
    1263                                       const char **names,
    1264                                       const char ***dom_names,
    1265                                       int level,
    1266                                       struct dom_sid **sids,
    1267                                       enum lsa_SidType **types);
    1268 
    1269 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
    1270                                struct winbindd_domain *domain,
    1271                                uint32_t num_names,
    1272                                const char **names,
    1273                                const char ***domains,
    1274                                struct dom_sid **sids,
    1275                                enum lsa_SidType **types)
    1276 {
    1277         NTSTATUS status;
    1278         struct rpc_pipe_client *cli = NULL;
    1279         struct policy_handle lsa_policy;
    1280         unsigned int orig_timeout = 0;
    1281         lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
    1282 
    1283         if (domain->can_do_ncacn_ip_tcp) {
    1284                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
    1285                 if (NT_STATUS_IS_OK(status)) {
    1286                         lookup_names_fn = rpccli_lsa_lookup_names4;
    1287                         goto lookup;
    1288                 }
    1289                 domain->can_do_ncacn_ip_tcp = false;
    1290         }
    1291         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
    1292 
    1293         if (!NT_STATUS_IS_OK(status)) {
    1294                 return status;
    1295         }
    1296 
    1297  lookup:
    1298 
    1299         /*
    1300          * This call can take a long time
    1301          * allow the server to time out.
    1302          * 35 seconds should do it.
    1303          */
    1304         orig_timeout = rpccli_set_timeout(cli, 35000);
    1305 
    1306         status = lookup_names_fn(cli,
    1307                                  mem_ctx,
    1308                                  &lsa_policy,
    1309                                  num_names,
    1310                                  (const char **) names,
    1311                                  domains,
    1312                                  1,
    1313                                  sids,
    1314                                  types);
    1315 
    1316         /* And restore our original timeout. */
    1317         rpccli_set_timeout(cli, orig_timeout);
    1318 
    1319         if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
    1320             NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
    1321                 /*
    1322                  * This can happen if the schannel key is not
    1323                  * valid anymore, we need to invalidate the
    1324                  * all connections to the dc and reestablish
    1325                  * a netlogon connection first.
    1326                  */
    1327                 invalidate_cm_connection(&domain->conn);
    1328                 status = NT_STATUS_ACCESS_DENIED;
    1329         }
    1330 
    1331         if (!NT_STATUS_IS_OK(status)) {
    1332                 return status;
    1333         }
    1334 
    1335         return status;
    1336 }
    1337 
    1338 /* the rpc backend methods are exposed via this structure */
    1339 struct winbindd_methods msrpc_methods = {
    1340         False,
    1341         query_user_list,
    1342         enum_dom_groups,
    1343         enum_local_groups,
    1344         msrpc_name_to_sid,
    1345         msrpc_sid_to_name,
    1346         msrpc_rids_to_names,
    1347         query_user,
    1348         lookup_usergroups,
    1349         msrpc_lookup_useraliases,
    1350         lookup_groupmem,
    1351         sequence_number,
    1352         msrpc_lockout_policy,
    1353         msrpc_password_policy,
    1354         trusted_domains,
    1355 };
     1125        if (NT_STATUS_IS_ERR(result)) {
     1126                return result;
     1127        }
     1128        *pnames = names;
     1129        return result;
     1130}
Note: See TracChangeset for help on using the changeset viewer.