root/source3/winbindd/winbindd_rpc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. query_user_list
  2. enum_dom_groups
  3. enum_local_groups
  4. msrpc_name_to_sid
  5. msrpc_sid_to_name
  6. msrpc_rids_to_names
  7. query_user
  8. lookup_usergroups
  9. msrpc_lookup_useraliases
  10. lookup_groupmem
  11. get_ldap_seq
  12. get_ldap_sequence_number
  13. sequence_number
  14. trusted_domains
  15. msrpc_lockout_policy
  16. msrpc_password_policy
  17. winbindd_lookup_sids
  18. winbindd_lookup_names

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    Winbind rpc backend functions
   5 
   6    Copyright (C) Tim Potter 2000-2001,2003
   7    Copyright (C) Andrew Tridgell 2001
   8    Copyright (C) Volker Lendecke 2005
   9    Copyright (C) Guenther Deschner 2008 (pidl conversion)
  10    
  11    This program is free software; you can redistribute it and/or modify
  12    it under the terms of the GNU General Public License as published by
  13    the Free Software Foundation; either version 3 of the License, or
  14    (at your option) any later version.
  15    
  16    This program is distributed in the hope that it will be useful,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19    GNU General Public License for more details.
  20    
  21    You should have received a copy of the GNU General Public License
  22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  23 */
  24 
  25 #include "includes.h"
  26 #include "winbindd.h"
  27 
  28 #undef DBGC_CLASS
  29 #define DBGC_CLASS DBGC_WINBIND
  30 
  31 
  32 /* Query display info for a domain.  This returns enough information plus a
  33    bit extra to give an overview of domain users for the User Manager
  34    application. */
  35 static NTSTATUS query_user_list(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
  36                                TALLOC_CTX *mem_ctx,
  37                                uint32 *num_entries, 
  38                                WINBIND_USERINFO **info)
  39 {
  40         NTSTATUS result;
  41         struct policy_handle dom_pol;
  42         unsigned int i, start_idx;
  43         uint32 loop_count;
  44         struct rpc_pipe_client *cli;
  45 
  46         DEBUG(3,("rpc: query_user_list\n"));
  47 
  48         *num_entries = 0;
  49         *info = NULL;
  50 
  51         if ( !winbindd_can_contact_domain( domain ) ) {
  52                 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
  53                           domain->name));
  54                 return NT_STATUS_OK;
  55         }
  56 
  57         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
  58         if (!NT_STATUS_IS_OK(result))
  59                 return result;
  60 
  61         i = start_idx = 0;
  62         loop_count = 0;
  63 
  64         do {
  65                 uint32 num_dom_users, j;
  66                 uint32 max_entries, max_size;
  67                 uint32_t total_size, returned_size;
  68 
  69                 union samr_DispInfo disp_info;
  70 
  71                 /* this next bit is copied from net_user_list_internal() */
  72 
  73                 get_query_dispinfo_params(loop_count, &max_entries,
  74                                           &max_size);
  75 
  76                 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
  77                                                       &dom_pol,
  78                                                       1,
  79                                                       start_idx,
  80                                                       max_entries,
  81                                                       max_size,
  82                                                       &total_size,
  83                                                       &returned_size,
  84                                                       &disp_info);
  85                 num_dom_users = disp_info.info1.count;
  86                 start_idx += disp_info.info1.count;
  87                 loop_count++;
  88 
  89                 *num_entries += num_dom_users;
  90 
  91                 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO,
  92                                              *num_entries);
  93 
  94                 if (!(*info)) {
  95                         return NT_STATUS_NO_MEMORY;
  96                 }
  97 
  98                 for (j = 0; j < num_dom_users; i++, j++) {
  99 
 100                         uint32_t rid = disp_info.info1.entries[j].rid;
 101 
 102                         (*info)[i].acct_name = talloc_strdup(mem_ctx,
 103                                 disp_info.info1.entries[j].account_name.string);
 104                         (*info)[i].full_name = talloc_strdup(mem_ctx,
 105                                 disp_info.info1.entries[j].full_name.string);
 106                         (*info)[i].homedir = NULL;
 107                         (*info)[i].shell = NULL;
 108                         sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
 109                         
 110                         /* For the moment we set the primary group for
 111                            every user to be the Domain Users group.
 112                            There are serious problems with determining
 113                            the actual primary group for large domains.
 114                            This should really be made into a 'winbind
 115                            force group' smb.conf parameter or
 116                            something like that. */
 117                            
 118                         sid_compose(&(*info)[i].group_sid, &domain->sid, 
 119                                     DOMAIN_GROUP_RID_USERS);
 120                 }
 121 
 122         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
 123 
 124         return result;
 125 }
 126 
 127 /* list all domain groups */
 128 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 129                                 TALLOC_CTX *mem_ctx,
 130                                 uint32 *num_entries, 
 131                                 struct acct_info **info)
 132 {
 133         struct policy_handle dom_pol;
 134         NTSTATUS status;
 135         uint32 start = 0;
 136         struct rpc_pipe_client *cli;
 137 
 138         *num_entries = 0;
 139         *info = NULL;
 140 
 141         DEBUG(3,("rpc: enum_dom_groups\n"));
 142 
 143         if ( !winbindd_can_contact_domain( domain ) ) {
 144                 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
 145                           domain->name));
 146                 return NT_STATUS_OK;
 147         }
 148 
 149         status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
 150         if (!NT_STATUS_IS_OK(status))
 151                 return status;
 152 
 153         do {
 154                 struct samr_SamArray *sam_array = NULL;
 155                 uint32 count = 0;
 156                 TALLOC_CTX *mem_ctx2;
 157                 int g;
 158 
 159                 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
 160 
 161                 /* start is updated by this call. */
 162                 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
 163                                                       &dom_pol,
 164                                                       &start,
 165                                                       &sam_array,
 166                                                       0xFFFF, /* buffer size? */
 167                                                       &count);
 168 
 169                 if (!NT_STATUS_IS_OK(status) &&
 170                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
 171                         talloc_destroy(mem_ctx2);
 172                         break;
 173                 }
 174 
 175                 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
 176                                                struct acct_info,
 177                                                (*num_entries) + count);
 178                 if (! *info) {
 179                         talloc_destroy(mem_ctx2);
 180                         return NT_STATUS_NO_MEMORY;
 181                 }
 182 
 183                 for (g=0; g < count; g++) {
 184 
 185                         fstrcpy((*info)[*num_entries + g].acct_name,
 186                                 sam_array->entries[g].name.string);
 187                         (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
 188                 }
 189 
 190                 (*num_entries) += count;
 191                 talloc_destroy(mem_ctx2);
 192         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
 193 
 194         return NT_STATUS_OK;
 195 }
 196 
 197 /* List all domain groups */
 198 
 199 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 200                                 TALLOC_CTX *mem_ctx,
 201                                 uint32 *num_entries, 
 202                                 struct acct_info **info)
 203 {
 204         struct policy_handle dom_pol;
 205         NTSTATUS result;
 206         struct rpc_pipe_client *cli;
 207 
 208         *num_entries = 0;
 209         *info = NULL;
 210 
 211         DEBUG(3,("rpc: enum_local_groups\n"));
 212 
 213         if ( !winbindd_can_contact_domain( domain ) ) {
 214                 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
 215                           domain->name));
 216                 return NT_STATUS_OK;
 217         }
 218 
 219         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
 220         if (!NT_STATUS_IS_OK(result))
 221                 return result;
 222 
 223         do {
 224                 struct samr_SamArray *sam_array = NULL;
 225                 uint32 count = 0, start = *num_entries;
 226                 TALLOC_CTX *mem_ctx2;
 227                 int g;
 228 
 229                 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
 230 
 231                 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
 232                                                        &dom_pol,
 233                                                        &start,
 234                                                        &sam_array,
 235                                                        0xFFFF, /* buffer size? */
 236                                                        &count);
 237                 if (!NT_STATUS_IS_OK(result) &&
 238                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
 239                 {
 240                         talloc_destroy(mem_ctx2);
 241                         return result;
 242                 }
 243 
 244                 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
 245                                                struct acct_info,
 246                                                (*num_entries) + count);
 247                 if (! *info) {
 248                         talloc_destroy(mem_ctx2);
 249                         return NT_STATUS_NO_MEMORY;
 250                 }
 251 
 252                 for (g=0; g < count; g++) {
 253 
 254                         fstrcpy((*info)[*num_entries + g].acct_name,
 255                                 sam_array->entries[g].name.string);
 256                         (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
 257                 }
 258 
 259                 (*num_entries) += count;
 260                 talloc_destroy(mem_ctx2);
 261 
 262         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
 263 
 264         return NT_STATUS_OK;
 265 }
 266 
 267 /* convert a single name to a sid in a domain */
 268 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 269                                   TALLOC_CTX *mem_ctx,
 270                                   enum winbindd_cmd original_cmd,
 271                                   const char *domain_name,
 272                                   const char *name,
 273                                   DOM_SID *sid,
 274                                   enum lsa_SidType *type)
 275 {
 276         NTSTATUS result;
 277         DOM_SID *sids = NULL;
 278         enum lsa_SidType *types = NULL;
 279         char *full_name = NULL;
 280         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
 281         char *mapped_name = NULL;
 282 
 283         if (name == NULL || *name=='\0') {
 284                 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
 285         } else if (domain_name == NULL || *domain_name == '\0') {
 286                 full_name = talloc_asprintf(mem_ctx, "%s", name);
 287         } else {
 288                 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
 289         }
 290         if (!full_name) {
 291                 DEBUG(0, ("talloc_asprintf failed!\n"));
 292                 return NT_STATUS_NO_MEMORY;
 293         }
 294 
 295         DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
 296 
 297         name_map_status = normalize_name_unmap(mem_ctx, full_name,
 298                                                &mapped_name);
 299 
 300         /* Reset the full_name pointer if we mapped anytthing */
 301 
 302         if (NT_STATUS_IS_OK(name_map_status) ||
 303             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
 304         {
 305                 full_name = mapped_name;
 306         }
 307 
 308         DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
 309                  full_name?full_name:"", domain_name ));
 310 
 311         result = winbindd_lookup_names(mem_ctx, domain, 1,
 312                                        (const char **)&full_name, NULL,
 313                                        &sids, &types);
 314         if (!NT_STATUS_IS_OK(result))
 315                 return result;
 316 
 317         /* Return rid and type if lookup successful */
 318 
 319         sid_copy(sid, &sids[0]);
 320         *type = types[0];
 321 
 322         return NT_STATUS_OK;
 323 }
 324 
 325 /*
 326   convert a domain SID to a user or group name
 327 */
 328 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 329                                   TALLOC_CTX *mem_ctx,
 330                                   const DOM_SID *sid,
 331                                   char **domain_name,
 332                                   char **name,
 333                                   enum lsa_SidType *type)
 334 {
 335         char **domains;
 336         char **names;
 337         enum lsa_SidType *types = NULL;
 338         NTSTATUS result;
 339         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
 340         char *mapped_name = NULL;
 341 
 342         DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
 343                  domain->name ));
 344 
 345         result = winbindd_lookup_sids(mem_ctx,
 346                                       domain,
 347                                       1,
 348                                       sid,
 349                                       &domains,
 350                                       &names,
 351                                       &types);
 352         if (!NT_STATUS_IS_OK(result)) {
 353                 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
 354                         nt_errstr(result)));
 355                 return result;
 356         }
 357         
 358 
 359         *type = (enum lsa_SidType)types[0];
 360         *domain_name = domains[0];
 361         *name = names[0];
 362 
 363         DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
 364 
 365         name_map_status = normalize_name_map(mem_ctx, domain, *name,
 366                                              &mapped_name);
 367         if (NT_STATUS_IS_OK(name_map_status) ||
 368             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
 369         {
 370                 *name = mapped_name;
 371                 DEBUG(5,("returning mapped name -- %s\n", *name));
 372         }
 373 
 374         return NT_STATUS_OK;
 375 }
 376 
 377 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 378                                     TALLOC_CTX *mem_ctx,
 379                                     const DOM_SID *sid,
 380                                     uint32 *rids,
 381                                     size_t num_rids,
 382                                     char **domain_name,
 383                                     char ***names,
 384                                     enum lsa_SidType **types)
 385 {
 386         char **domains;
 387         NTSTATUS result;
 388         DOM_SID *sids;
 389         size_t i;
 390         char **ret_names;
 391 
 392         DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
 393 
 394         if (num_rids) {
 395                 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
 396                 if (sids == NULL) {
 397                         return NT_STATUS_NO_MEMORY;
 398                 }
 399         } else {
 400                 sids = NULL;
 401         }
 402 
 403         for (i=0; i<num_rids; i++) {
 404                 if (!sid_compose(&sids[i], sid, rids[i])) {
 405                         return NT_STATUS_INTERNAL_ERROR;
 406                 }
 407         }
 408 
 409         result = winbindd_lookup_sids(mem_ctx,
 410                                       domain,
 411                                       num_rids,
 412                                       sids,
 413                                       &domains,
 414                                       names,
 415                                       types);
 416 
 417         if (!NT_STATUS_IS_OK(result) &&
 418             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
 419                 return result;
 420         }
 421 
 422         ret_names = *names;
 423         for (i=0; i<num_rids; i++) {
 424                 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
 425                 char *mapped_name = NULL;
 426 
 427                 if ((*types)[i] != SID_NAME_UNKNOWN) {
 428                         name_map_status = normalize_name_map(mem_ctx,
 429                                                              domain,
 430                                                              ret_names[i],
 431                                                              &mapped_name);
 432                         if (NT_STATUS_IS_OK(name_map_status) ||
 433                             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
 434                         {
 435                                 ret_names[i] = mapped_name;
 436                         }
 437 
 438                         *domain_name = domains[i];
 439                 }
 440         }
 441 
 442         return result;
 443 }
 444 
 445 /* Lookup user information from a rid or username. */
 446 static NTSTATUS query_user(struct winbindd_domain *domain, 
     /* [<][>][^][v][top][bottom][index][help] */
 447                            TALLOC_CTX *mem_ctx, 
 448                            const DOM_SID *user_sid, 
 449                            WINBIND_USERINFO *user_info)
 450 {
 451         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 452         struct policy_handle dom_pol, user_pol;
 453         union samr_UserInfo *info = NULL;
 454         uint32 user_rid;
 455         struct netr_SamInfo3 *user;
 456         struct rpc_pipe_client *cli;
 457 
 458         DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
 459 
 460         if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
 461                 return NT_STATUS_UNSUCCESSFUL;
 462         
 463         user_info->homedir = NULL;
 464         user_info->shell = NULL;
 465         user_info->primary_gid = (gid_t)-1;
 466                                                 
 467         /* try netsamlogon cache first */
 468                         
 469         if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL ) 
 470         {
 471                                 
 472                 DEBUG(5,("query_user: Cache lookup succeeded for %s\n", 
 473                         sid_string_dbg(user_sid)));
 474 
 475                 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
 476                 sid_compose(&user_info->group_sid, &domain->sid,
 477                             user->base.primary_gid);
 478                                 
 479                 user_info->acct_name = talloc_strdup(mem_ctx,
 480                                                      user->base.account_name.string);
 481                 user_info->full_name = talloc_strdup(mem_ctx,
 482                                                      user->base.full_name.string);
 483                 
 484                 TALLOC_FREE(user);
 485                                                 
 486                 return NT_STATUS_OK;
 487         }
 488                                 
 489         if ( !winbindd_can_contact_domain( domain ) ) {
 490                 DEBUG(10,("query_user: No incoming trust for domain %s\n",
 491                           domain->name));
 492                 return NT_STATUS_OK;
 493         }
 494         
 495         if ( !winbindd_can_contact_domain( domain ) ) {
 496                 DEBUG(10,("query_user: No incoming trust for domain %s\n",
 497                           domain->name));
 498                 return NT_STATUS_OK;
 499         }
 500         
 501         if ( !winbindd_can_contact_domain( domain ) ) {
 502                 DEBUG(10,("query_user: No incoming trust for domain %s\n",
 503                           domain->name));
 504                 return NT_STATUS_OK;
 505         }
 506         
 507         /* no cache; hit the wire */
 508                 
 509         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
 510         if (!NT_STATUS_IS_OK(result))
 511                 return result;
 512 
 513         /* Get user handle */
 514         result = rpccli_samr_OpenUser(cli, mem_ctx,
 515                                       &dom_pol,
 516                                       SEC_FLAG_MAXIMUM_ALLOWED,
 517                                       user_rid,
 518                                       &user_pol);
 519 
 520         if (!NT_STATUS_IS_OK(result))
 521                 return result;
 522 
 523         /* Get user info */
 524         result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
 525                                            &user_pol,
 526                                            0x15,
 527                                            &info);
 528 
 529         rpccli_samr_Close(cli, mem_ctx, &user_pol);
 530 
 531         if (!NT_STATUS_IS_OK(result))
 532                 return result;
 533 
 534         sid_compose(&user_info->user_sid, &domain->sid, user_rid);
 535         sid_compose(&user_info->group_sid, &domain->sid,
 536                     info->info21.primary_gid);
 537         user_info->acct_name = talloc_strdup(mem_ctx,
 538                                              info->info21.account_name.string);
 539         user_info->full_name = talloc_strdup(mem_ctx,
 540                                              info->info21.full_name.string);
 541         user_info->homedir = NULL;
 542         user_info->shell = NULL;
 543         user_info->primary_gid = (gid_t)-1;
 544 
 545         return NT_STATUS_OK;
 546 }                                   
 547 
 548 /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
 549 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 550                                   TALLOC_CTX *mem_ctx,
 551                                   const DOM_SID *user_sid,
 552                                   uint32 *num_groups, DOM_SID **user_grpsids)
 553 {
 554         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 555         struct policy_handle dom_pol, user_pol;
 556         uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
 557         struct samr_RidWithAttributeArray *rid_array = NULL;
 558         unsigned int i;
 559         uint32 user_rid;
 560         struct rpc_pipe_client *cli;
 561 
 562         DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
 563 
 564         if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
 565                 return NT_STATUS_UNSUCCESSFUL;
 566 
 567         *num_groups = 0;
 568         *user_grpsids = NULL;
 569 
 570         /* so lets see if we have a cached user_info_3 */
 571         result = lookup_usergroups_cached(domain, mem_ctx, user_sid, 
 572                                           num_groups, user_grpsids);
 573 
 574         if (NT_STATUS_IS_OK(result)) {
 575                 return NT_STATUS_OK;
 576         }
 577 
 578         if ( !winbindd_can_contact_domain( domain ) ) {
 579                 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
 580                           domain->name));
 581 
 582                 /* Tell the cache manager not to remember this one */
 583 
 584                 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
 585         }
 586 
 587         /* no cache; hit the wire */
 588         
 589         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
 590         if (!NT_STATUS_IS_OK(result))
 591                 return result;
 592 
 593         /* Get user handle */
 594         result = rpccli_samr_OpenUser(cli, mem_ctx,
 595                                       &dom_pol,
 596                                       des_access,
 597                                       user_rid,
 598                                       &user_pol);
 599 
 600         if (!NT_STATUS_IS_OK(result))
 601                 return result;
 602 
 603         /* Query user rids */
 604         result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
 605                                               &user_pol,
 606                                               &rid_array);
 607         *num_groups = rid_array->count;
 608 
 609         rpccli_samr_Close(cli, mem_ctx, &user_pol);
 610 
 611         if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
 612                 return result;
 613 
 614         (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
 615         if (!(*user_grpsids))
 616                 return NT_STATUS_NO_MEMORY;
 617 
 618         for (i=0;i<(*num_groups);i++) {
 619                 sid_copy(&((*user_grpsids)[i]), &domain->sid);
 620                 sid_append_rid(&((*user_grpsids)[i]),
 621                                 rid_array->rids[i].rid);
 622         }
 623 
 624         return NT_STATUS_OK;
 625 }
 626 
 627 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
 628 
 629 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 630                                          TALLOC_CTX *mem_ctx,
 631                                          uint32 num_sids, const DOM_SID *sids,
 632                                          uint32 *num_aliases,
 633                                          uint32 **alias_rids)
 634 {
 635         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 636         struct policy_handle dom_pol;
 637         uint32 num_query_sids = 0;
 638         int i;
 639         struct rpc_pipe_client *cli;
 640         struct samr_Ids alias_rids_query;
 641         int rangesize = MAX_SAM_ENTRIES_W2K;
 642         uint32 total_sids = 0;
 643         int num_queries = 1;
 644 
 645         *num_aliases = 0;
 646         *alias_rids = NULL;
 647 
 648         DEBUG(3,("rpc: lookup_useraliases\n"));
 649 
 650         if ( !winbindd_can_contact_domain( domain ) ) {
 651                 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
 652                           domain->name));
 653                 return NT_STATUS_OK;
 654         }
 655 
 656         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
 657         if (!NT_STATUS_IS_OK(result))
 658                 return result;
 659 
 660         do {
 661                 /* prepare query */
 662                 struct lsa_SidArray sid_array;
 663 
 664                 ZERO_STRUCT(sid_array);
 665 
 666                 num_query_sids = MIN(num_sids - total_sids, rangesize);
 667 
 668                 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 
 669                         num_queries, num_query_sids));  
 670 
 671                 if (num_query_sids) {
 672                         sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
 673                         if (sid_array.sids == NULL) {
 674                                 return NT_STATUS_NO_MEMORY;
 675                         }
 676                 } else {
 677                         sid_array.sids = NULL;
 678                 }
 679 
 680                 for (i=0; i<num_query_sids; i++) {
 681                         sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
 682                         if (!sid_array.sids[i].sid) {
 683                                 TALLOC_FREE(sid_array.sids);
 684                                 return NT_STATUS_NO_MEMORY;
 685                         }
 686                 }
 687                 sid_array.num_sids = num_query_sids;
 688 
 689                 /* do request */
 690                 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
 691                                                         &dom_pol,
 692                                                         &sid_array,
 693                                                         &alias_rids_query);
 694 
 695                 if (!NT_STATUS_IS_OK(result)) {
 696                         *num_aliases = 0;
 697                         *alias_rids = NULL;
 698                         TALLOC_FREE(sid_array.sids);
 699                         goto done;
 700                 }
 701 
 702                 /* process output */
 703 
 704                 for (i=0; i<alias_rids_query.count; i++) {
 705                         size_t na = *num_aliases;
 706                         if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
 707                                                 alias_rids, &na)) {
 708                                 return NT_STATUS_NO_MEMORY;
 709                         }
 710                         *num_aliases = na;
 711                 }
 712 
 713                 TALLOC_FREE(sid_array.sids);
 714 
 715                 num_queries++;
 716 
 717         } while (total_sids < num_sids);
 718 
 719  done:
 720         DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
 721                 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
 722 
 723         return result;
 724 }
 725 
 726 
 727 /* Lookup group membership given a rid.   */
 728 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 729                                 TALLOC_CTX *mem_ctx,
 730                                 const DOM_SID *group_sid, 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))
 755                 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))
 838                         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;
 860 
 861         return NT_STATUS_OK;
 862 }
 863 
 864 #ifdef HAVE_LDAP
 865 
 866 #include <ldap.h>
 867 
 868 static int get_ldap_seq(const char *server, int port, uint32 *seq)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 940 {
 941         TALLOC_CTX *mem_ctx;
 942         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,
 995                                              8,
 996                                              &info);
 997 
 998         if (NT_STATUS_IS_OK(result)) {
 999                 *seq = info->info8.sequence_num;
1000                 got_seq_num = True;
1001                 goto seq_num;
1002         }
1003 
1004         /* retry with info-level 2 in case the dc does not support info-level 8
1005          * (like all older samba2 and samba3 dc's) - Guenther */
1006 
1007         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1008                                              &dom_pol,
1009                                              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:
1018         if (got_seq_num) {
1019                 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1020                           domain->name, (unsigned)*seq));
1021         } else {
1022                 DEBUG(10,("domain_sequence_number: failed to get sequence "
1023                           "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,
     /* [<][>][^][v][top][bottom][index][help] */
1036                                 TALLOC_CTX *mem_ctx,
1037                                 uint32 *num_domains,
1038                                 char ***names,
1039                                 char ***alt_names,
1040                                 DOM_SID **dom_sids)
1041 {
1042         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1043         uint32 enum_ctx = 0;
1044         struct rpc_pipe_client *cli;
1045         struct policy_handle lsa_policy;
1046 
1047         DEBUG(3,("rpc: trusted_domains\n"));
1048 
1049         *num_domains = 0;
1050         *names = NULL;
1051         *alt_names = NULL;
1052         *dom_sids = NULL;
1053 
1054         result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1055         if (!NT_STATUS_IS_OK(result))
1056                 return result;
1057 
1058         result = STATUS_MORE_ENTRIES;
1059 
1060         while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1061                 uint32 start_idx;
1062                 int i;
1063                 struct lsa_DomainList dom_list;
1064 
1065                 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1066                                                  &lsa_policy,
1067                                                  &enum_ctx,
1068                                                  &dom_list,
1069                                                  (uint32_t)-1);
1070 
1071                 if (!NT_STATUS_IS_OK(result) &&
1072                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1073                         break;
1074 
1075                 start_idx = *num_domains;
1076                 *num_domains += dom_list.count;
1077                 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1078                                               char *, *num_domains);
1079                 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1080                                                  DOM_SID, *num_domains);
1081                 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1082                                                  char *, *num_domains);
1083                 if ((*names == NULL) || (*dom_sids == NULL) ||
1084                     (*alt_names == NULL))
1085                         return NT_STATUS_NO_MEMORY;
1086 
1087                 for (i=0; i<dom_list.count; i++) {
1088                         (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1089                         (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1090                         (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1091                 }
1092         }
1093         return result;
1094 }
1095 
1096 /* find the lockout policy for a domain */
1097 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
1098                                      TALLOC_CTX *mem_ctx,
1099                                      struct samr_DomInfo12 *lockout_policy)
1100 {
1101         NTSTATUS result;
1102         struct rpc_pipe_client *cli;
1103         struct policy_handle dom_pol;
1104         union samr_DomainInfo *info = NULL;
1105 
1106         DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1107 
1108         if ( !winbindd_can_contact_domain( domain ) ) {
1109                 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1110                           domain->name));
1111                 return NT_STATUS_NOT_SUPPORTED;
1112         }
1113 
1114         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1115         if (!NT_STATUS_IS_OK(result)) {
1116                 goto done;
1117         }
1118 
1119         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1120                                              &dom_pol,
1121                                              12,
1122                                              &info);
1123         if (!NT_STATUS_IS_OK(result)) {
1124                 goto done;
1125         }
1126 
1127         *lockout_policy = info->info12;
1128 
1129         DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1130                 info->info12.lockout_threshold));
1131 
1132   done:
1133 
1134         return result;
1135 }
1136 
1137 /* find the password policy for a domain */
1138 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
     /* [<][>][^][v][top][bottom][index][help] */
1139                                       TALLOC_CTX *mem_ctx,
1140                                       struct samr_DomInfo1 *password_policy)
1141 {
1142         NTSTATUS result;
1143         struct rpc_pipe_client *cli;
1144         struct policy_handle dom_pol;
1145         union samr_DomainInfo *info = NULL;
1146 
1147         DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1148 
1149         if ( !winbindd_can_contact_domain( domain ) ) {
1150                 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1151                           domain->name));
1152                 return NT_STATUS_NOT_SUPPORTED;
1153         }
1154 
1155         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1156         if (!NT_STATUS_IS_OK(result)) {
1157                 goto done;
1158         }
1159 
1160         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1161                                              &dom_pol,
1162                                              1,
1163                                              &info);
1164         if (!NT_STATUS_IS_OK(result)) {
1165                 goto done;
1166         }
1167 
1168         *password_policy = info->info1;
1169 
1170         DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1171                 info->info1.min_password_length));
1172 
1173   done:
1174 
1175         return result;
1176 }
1177 
1178 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1179                                      TALLOC_CTX *mem_ctx,
1180                                      struct policy_handle *pol,
1181                                      int num_sids,
1182                                      const DOM_SID *sids,
1183                                      char ***pdomains,
1184                                      char ***pnames,
1185                                      enum lsa_SidType **ptypes);
1186 
1187 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1188                               struct winbindd_domain *domain,
1189                               uint32_t num_sids,
1190                               const struct dom_sid *sids,
1191                               char ***domains,
1192                               char ***names,
1193                               enum lsa_SidType **types)
1194 {
1195         NTSTATUS status;
1196         struct rpc_pipe_client *cli = NULL;
1197         struct policy_handle lsa_policy;
1198         unsigned int orig_timeout;
1199         lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1200 
1201         if (domain->can_do_ncacn_ip_tcp) {
1202                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1203                 if (NT_STATUS_IS_OK(status)) {
1204                         lookup_sids_fn = rpccli_lsa_lookup_sids3;
1205                         goto lookup;
1206                 }
1207                 domain->can_do_ncacn_ip_tcp = false;
1208         }
1209         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1210 
1211         if (!NT_STATUS_IS_OK(status)) {
1212                 return status;
1213         }
1214 
1215  lookup:
1216         /*
1217          * This call can take a long time
1218          * allow the server to time out.
1219          * 35 seconds should do it.
1220          */
1221         orig_timeout = rpccli_set_timeout(cli, 35000);
1222 
1223         status = lookup_sids_fn(cli,
1224                                 mem_ctx,
1225                                 &lsa_policy,
1226                                 num_sids,
1227                                 sids,
1228                                 domains,
1229                                 names,
1230                                 types);
1231 
1232         /* And restore our original timeout. */
1233         rpccli_set_timeout(cli, orig_timeout);
1234 
1235         if (!NT_STATUS_IS_OK(status)) {
1236                 return status;
1237         }
1238 
1239         return status;
1240 }
1241 
1242 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1243                                       TALLOC_CTX *mem_ctx,
1244                                       struct policy_handle *pol,
1245                                       int num_names,
1246                                       const char **names,
1247                                       const char ***dom_names,
1248                                       int level,
1249                                       struct dom_sid **sids,
1250                                       enum lsa_SidType **types);
1251 
1252 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1253                                struct winbindd_domain *domain,
1254                                uint32_t num_names,
1255                                const char **names,
1256                                const char ***domains,
1257                                struct dom_sid **sids,
1258                                enum lsa_SidType **types)
1259 {
1260         NTSTATUS status;
1261         struct rpc_pipe_client *cli = NULL;
1262         struct policy_handle lsa_policy;
1263         unsigned int orig_timeout;
1264         lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1265 
1266         if (domain->can_do_ncacn_ip_tcp) {
1267                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1268                 if (NT_STATUS_IS_OK(status)) {
1269                         lookup_names_fn = rpccli_lsa_lookup_names4;
1270                         goto lookup;
1271                 }
1272                 domain->can_do_ncacn_ip_tcp = false;
1273         }
1274         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1275 
1276         if (!NT_STATUS_IS_OK(status)) {
1277                 return status;
1278         }
1279 
1280  lookup:
1281 
1282         /*
1283          * This call can take a long time
1284          * allow the server to time out.
1285          * 35 seconds should do it.
1286          */
1287         orig_timeout = rpccli_set_timeout(cli, 35000);
1288 
1289         status = lookup_names_fn(cli,
1290                                  mem_ctx,
1291                                  &lsa_policy,
1292                                  num_names,
1293                                  (const char **) names,
1294                                  domains,
1295                                  1,
1296                                  sids,
1297                                  types);
1298 
1299         /* And restore our original timeout. */
1300         rpccli_set_timeout(cli, orig_timeout);
1301 
1302         if (!NT_STATUS_IS_OK(status)) {
1303                 return status;
1304         }
1305 
1306         return status;
1307 }
1308 
1309 /* the rpc backend methods are exposed via this structure */
1310 struct winbindd_methods msrpc_methods = {
1311         False,
1312         query_user_list,
1313         enum_dom_groups,
1314         enum_local_groups,
1315         msrpc_name_to_sid,
1316         msrpc_sid_to_name,
1317         msrpc_rids_to_names,
1318         query_user,
1319         lookup_usergroups,
1320         msrpc_lookup_useraliases,
1321         lookup_groupmem,
1322         sequence_number,
1323         msrpc_lockout_policy,
1324         msrpc_password_policy,
1325         trusted_domains,
1326 };

/* [<][>][^][v][top][bottom][index][help] */