s3-winbindd: no reason to call winbindd_can_contact_domain() three times in query_user().
[ira/wip.git] / source3 / winbindd / winbindd_rpc.c
index 0d937ef30e8612b4ab99f5b1b288fad0b76b92c4..ac5c3d2d93a66339406c82b8c97c68fa63e26373 100644 (file)
@@ -6,17 +6,18 @@
    Copyright (C) Tim Potter 2000-2001,2003
    Copyright (C) Andrew Tridgell 2001
    Copyright (C) Volker Lendecke 2005
-   
+   Copyright (C) Guenther Deschner 2008 (pidl conversion)
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 static NTSTATUS query_user_list(struct winbindd_domain *domain,
                               TALLOC_CTX *mem_ctx,
                               uint32 *num_entries, 
-                              WINBIND_USERINFO **info)
+                              struct wbint_userinfo **info)
 {
        NTSTATUS result;
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        unsigned int i, start_idx;
        uint32 loop_count;
        struct rpc_pipe_client *cli;
@@ -63,29 +64,32 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
        do {
                uint32 num_dom_users, j;
                uint32 max_entries, max_size;
-               SAM_DISPINFO_CTR ctr;
-               SAM_DISPINFO_1 info1;
+               uint32_t total_size, returned_size;
 
-               ZERO_STRUCT( ctr );
-               ZERO_STRUCT( info1 );
-               ctr.sam.info1 = &info1;
+               union samr_DispInfo disp_info;
 
                /* this next bit is copied from net_user_list_internal() */
 
                get_query_dispinfo_params(loop_count, &max_entries,
                                          &max_size);
 
-               result = rpccli_samr_query_dispinfo(cli, mem_ctx, &dom_pol,
-                                                   &start_idx, 1,
-                                                   &num_dom_users,
-                                                   max_entries, max_size,
-                                                   &ctr);
-
+               result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
+                                                     &dom_pol,
+                                                     1,
+                                                     start_idx,
+                                                     max_entries,
+                                                     max_size,
+                                                     &total_size,
+                                                     &returned_size,
+                                                     &disp_info);
+               num_dom_users = disp_info.info1.count;
+               start_idx += disp_info.info1.count;
                loop_count++;
 
                *num_entries += num_dom_users;
 
-               *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO,
+               *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
+                                            struct wbint_userinfo,
                                             *num_entries);
 
                if (!(*info)) {
@@ -93,18 +97,17 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
                }
 
                for (j = 0; j < num_dom_users; i++, j++) {
-                       fstring username, fullname;
-                       uint32 rid = ctr.sam.info1->sam[j].rid_user;
-                       
-                       unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username));
-                       unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname));
-                       
-                       (*info)[i].acct_name = talloc_strdup(mem_ctx, username );
-                       (*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
+
+                       uint32_t rid = disp_info.info1.entries[j].rid;
+
+                       (*info)[i].acct_name = talloc_strdup(mem_ctx,
+                               disp_info.info1.entries[j].account_name.string);
+                       (*info)[i].full_name = talloc_strdup(mem_ctx,
+                               disp_info.info1.entries[j].full_name.string);
                        (*info)[i].homedir = NULL;
                        (*info)[i].shell = NULL;
                        sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
-                       
+
                        /* For the moment we set the primary group for
                           every user to be the Domain Users group.
                           There are serious problems with determining
@@ -112,7 +115,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
                           This should really be made into a 'winbind
                           force group' smb.conf parameter or
                           something like that. */
-                          
+
                        sid_compose(&(*info)[i].group_sid, &domain->sid, 
                                    DOMAIN_GROUP_RID_USERS);
                }
@@ -128,7 +131,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
                                uint32 *num_entries, 
                                struct acct_info **info)
 {
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        NTSTATUS status;
        uint32 start = 0;
        struct rpc_pipe_client *cli;
@@ -149,19 +152,22 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
                return status;
 
        do {
-               struct acct_info *info2 = NULL;
+               struct samr_SamArray *sam_array = NULL;
                uint32 count = 0;
                TALLOC_CTX *mem_ctx2;
+               int g;
 
                mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
 
                /* start is updated by this call. */
-               status = rpccli_samr_enum_dom_groups(cli, mem_ctx2, &dom_pol,
-                                                    &start,
-                                                    0xFFFF, /* buffer size? */
-                                                    &info2, &count);
+               status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
+                                                     &dom_pol,
+                                                     &start,
+                                                     &sam_array,
+                                                     0xFFFF, /* buffer size? */
+                                                     &count);
 
-               if (!NT_STATUS_IS_OK(status) && 
+               if (!NT_STATUS_IS_OK(status) &&
                    !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
                        talloc_destroy(mem_ctx2);
                        break;
@@ -175,7 +181,13 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
                        return NT_STATUS_NO_MEMORY;
                }
 
-               memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
+               for (g=0; g < count; g++) {
+
+                       fstrcpy((*info)[*num_entries + g].acct_name,
+                               sam_array->entries[g].name.string);
+                       (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
+               }
+
                (*num_entries) += count;
                talloc_destroy(mem_ctx2);
        } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
@@ -190,7 +202,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
                                uint32 *num_entries, 
                                struct acct_info **info)
 {
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        NTSTATUS result;
        struct rpc_pipe_client *cli;
 
@@ -210,18 +222,21 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
                return result;
 
        do {
-               struct acct_info *info2 = NULL;
+               struct samr_SamArray *sam_array = NULL;
                uint32 count = 0, start = *num_entries;
                TALLOC_CTX *mem_ctx2;
+               int g;
 
                mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
 
-               result = rpccli_samr_enum_als_groups( cli, mem_ctx2, &dom_pol,
-                                                     &start, 0xFFFF, &info2,
-                                                     &count);
-                                         
+               result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
+                                                      &dom_pol,
+                                                      &start,
+                                                      &sam_array,
+                                                      0xFFFF, /* buffer size? */
+                                                      &count);
                if (!NT_STATUS_IS_OK(result) &&
-                   !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) ) 
+                   !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
                {
                        talloc_destroy(mem_ctx2);
                        return result;
@@ -235,7 +250,13 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
                        return NT_STATUS_NO_MEMORY;
                }
 
-               memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
+               for (g=0; g < count; g++) {
+
+                       fstrcpy((*info)[*num_entries + g].acct_name,
+                               sam_array->entries[g].name.string);
+                       (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
+               }
+
                (*num_entries) += count;
                talloc_destroy(mem_ctx2);
 
@@ -245,20 +266,20 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
 }
 
 /* convert a single name to a sid in a domain */
-NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
-                          TALLOC_CTX *mem_ctx,
-                          enum winbindd_cmd original_cmd,
-                          const char *domain_name,
-                          const char *name,
-                          DOM_SID *sid,
-                          enum lsa_SidType *type)
+static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
+                                 TALLOC_CTX *mem_ctx,
+                                 const char *domain_name,
+                                 const char *name,
+                                 uint32_t flags,
+                                 DOM_SID *sid,
+                                 enum lsa_SidType *type)
 {
        NTSTATUS result;
        DOM_SID *sids = NULL;
        enum lsa_SidType *types = NULL;
        char *full_name = NULL;
-       struct rpc_pipe_client *cli;
-       POLICY_HND lsa_policy;
+       NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
+       char *mapped_name = NULL;
 
        if (name == NULL || *name=='\0') {
                full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
@@ -274,17 +295,23 @@ NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
 
        DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
 
-       ws_name_return( full_name, WB_REPLACE_CHAR );
+       name_map_status = normalize_name_unmap(mem_ctx, full_name,
+                                              &mapped_name);
 
-       DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name ));
+       /* Reset the full_name pointer if we mapped anytthing */
 
-       result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
-       if (!NT_STATUS_IS_OK(result))
-               return result;
+       if (NT_STATUS_IS_OK(name_map_status) ||
+           NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
+       {
+               full_name = mapped_name;
+       }
 
-       result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1, 
-                                        (const char**) &full_name, NULL, 1, &sids, &types);
-        
+       DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
+                full_name?full_name:"", domain_name ));
+
+       result = winbindd_lookup_names(mem_ctx, domain, 1,
+                                      (const char **)&full_name, NULL,
+                                      &sids, &types);
        if (!NT_STATUS_IS_OK(result))
                return result;
 
@@ -299,62 +326,66 @@ NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
 /*
   convert a domain SID to a user or group name
 */
-NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
-                           TALLOC_CTX *mem_ctx,
-                           const DOM_SID *sid,
-                           char **domain_name,
-                           char **name,
-                           enum lsa_SidType *type)
+static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
+                                 TALLOC_CTX *mem_ctx,
+                                 const DOM_SID *sid,
+                                 char **domain_name,
+                                 char **name,
+                                 enum lsa_SidType *type)
 {
        char **domains;
        char **names;
        enum lsa_SidType *types = NULL;
        NTSTATUS result;
-       struct rpc_pipe_client *cli;
-       POLICY_HND lsa_policy;
+       NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
+       char *mapped_name = NULL;
 
        DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
                 domain->name ));
 
-       result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
+       result = winbindd_lookup_sids(mem_ctx,
+                                     domain,
+                                     1,
+                                     sid,
+                                     &domains,
+                                     &names,
+                                     &types);
        if (!NT_STATUS_IS_OK(result)) {
-               DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
-                        nt_errstr(result)));           
+               DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
+                       nt_errstr(result)));
                return result;
        }
-       
 
-       result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
-                                       1, sid, &domains, &names, &types);
-       if (!NT_STATUS_IS_OK(result)) {         
-               DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids()  failed (%s)\n",
-                        nt_errstr(result)));           
-               return result;
-       }
 
        *type = (enum lsa_SidType)types[0];
        *domain_name = domains[0];
        *name = names[0];
 
-       ws_name_replace( *name, WB_REPLACE_CHAR );      
-               
        DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
+
+       name_map_status = normalize_name_map(mem_ctx, domain, *name,
+                                            &mapped_name);
+       if (NT_STATUS_IS_OK(name_map_status) ||
+           NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
+       {
+               *name = mapped_name;
+               DEBUG(5,("returning mapped name -- %s\n", *name));
+       }
+
        return NT_STATUS_OK;
 }
 
-NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
-                            TALLOC_CTX *mem_ctx,
-                            const DOM_SID *sid,
-                            uint32 *rids,
-                            size_t num_rids,
-                            char **domain_name,
-                            char ***names,
-                            enum lsa_SidType **types)
+static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
+                                   TALLOC_CTX *mem_ctx,
+                                   const DOM_SID *sid,
+                                   uint32 *rids,
+                                   size_t num_rids,
+                                   char **domain_name,
+                                   char ***names,
+                                   enum lsa_SidType **types)
 {
        char **domains;
        NTSTATUS result;
-       struct rpc_pipe_client *cli;
-       POLICY_HND lsa_policy;
        DOM_SID *sids;
        size_t i;
        char **ret_names;
@@ -376,14 +407,14 @@ NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
                }
        }
 
-       result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
-       if (!NT_STATUS_IS_OK(result)) {
-               return result;
-       }
+       result = winbindd_lookup_sids(mem_ctx,
+                                     domain,
+                                     num_rids,
+                                     sids,
+                                     &domains,
+                                     names,
+                                     types);
 
-       result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
-                                       num_rids, sids, &domains,
-                                       names, types);
        if (!NT_STATUS_IS_OK(result) &&
            !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
                return result;
@@ -391,8 +422,20 @@ NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
 
        ret_names = *names;
        for (i=0; i<num_rids; i++) {
+               NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
+               char *mapped_name = NULL;
+
                if ((*types)[i] != SID_NAME_UNKNOWN) {
-                       ws_name_replace( ret_names[i], WB_REPLACE_CHAR );
+                       name_map_status = normalize_name_map(mem_ctx,
+                                                            domain,
+                                                            ret_names[i],
+                                                            &mapped_name);
+                       if (NT_STATUS_IS_OK(name_map_status) ||
+                           NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
+                       {
+                               ret_names[i] = mapped_name;
+                       }
+
                        *domain_name = domains[i];
                }
        }
@@ -404,66 +447,54 @@ NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
 static NTSTATUS query_user(struct winbindd_domain *domain, 
                           TALLOC_CTX *mem_ctx, 
                           const DOM_SID *user_sid, 
-                          WINBIND_USERINFO *user_info)
+                          struct wbint_userinfo *user_info)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND dom_pol, user_pol;
-       SAM_USERINFO_CTR *ctr;
+       struct policy_handle dom_pol, user_pol;
+       union samr_UserInfo *info = NULL;
        uint32 user_rid;
-       NET_USER_INFO_3 *user;
+       struct netr_SamInfo3 *user;
        struct rpc_pipe_client *cli;
 
        DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
 
        if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
                return NT_STATUS_UNSUCCESSFUL;
-       
+
        user_info->homedir = NULL;
        user_info->shell = NULL;
        user_info->primary_gid = (gid_t)-1;
-                                               
+
        /* try netsamlogon cache first */
-                       
+
        if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL ) 
        {
-                               
+
                DEBUG(5,("query_user: Cache lookup succeeded for %s\n", 
                        sid_string_dbg(user_sid)));
 
-               sid_compose(&user_info->user_sid, &domain->sid, user->user_rid);
+               sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
                sid_compose(&user_info->group_sid, &domain->sid,
-                           user->group_rid);
-                               
-               user_info->acct_name = unistr2_to_ascii_talloc(mem_ctx,
-                                                   &user->uni_user_name);
-               user_info->full_name = unistr2_to_ascii_talloc(mem_ctx,
-                                                   &user->uni_full_name);
-               
+                           user->base.primary_gid);
+
+               user_info->acct_name = talloc_strdup(mem_ctx,
+                                                    user->base.account_name.string);
+               user_info->full_name = talloc_strdup(mem_ctx,
+                                                    user->base.full_name.string);
+
                TALLOC_FREE(user);
-                                               
-               return NT_STATUS_OK;
-       }
-                               
-       if ( !winbindd_can_contact_domain( domain ) ) {
-               DEBUG(10,("query_user: No incoming trust for domain %s\n",
-                         domain->name));
-               return NT_STATUS_OK;
-       }
-       
-       if ( !winbindd_can_contact_domain( domain ) ) {
-               DEBUG(10,("query_user: No incoming trust for domain %s\n",
-                         domain->name));
+
                return NT_STATUS_OK;
        }
-       
+
        if ( !winbindd_can_contact_domain( domain ) ) {
                DEBUG(10,("query_user: No incoming trust for domain %s\n",
                          domain->name));
                return NT_STATUS_OK;
        }
-       
+
        /* no cache; hit the wire */
-               
+
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
        if (!NT_STATUS_IS_OK(result))
                return result;
@@ -471,7 +502,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
        /* Get user handle */
        result = rpccli_samr_OpenUser(cli, mem_ctx,
                                      &dom_pol,
-                                     SEC_RIGHTS_MAXIMUM_ALLOWED,
+                                     SEC_FLAG_MAXIMUM_ALLOWED,
                                      user_rid,
                                      &user_pol);
 
@@ -479,8 +510,10 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
                return result;
 
        /* Get user info */
-       result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
-                                           0x15, &ctr);
+       result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
+                                          &user_pol,
+                                          0x15,
+                                          &info);
 
        rpccli_samr_Close(cli, mem_ctx, &user_pol);
 
@@ -489,11 +522,11 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
 
        sid_compose(&user_info->user_sid, &domain->sid, user_rid);
        sid_compose(&user_info->group_sid, &domain->sid,
-                   ctr->info.id21->group_rid);
-       user_info->acct_name = unistr2_to_ascii_talloc(mem_ctx, 
-                                           &ctr->info.id21->uni_user_name);
-       user_info->full_name = unistr2_to_ascii_talloc(mem_ctx, 
-                                           &ctr->info.id21->uni_full_name);
+                   info->info21.primary_gid);
+       user_info->acct_name = talloc_strdup(mem_ctx,
+                                            info->info21.account_name.string);
+       user_info->full_name = talloc_strdup(mem_ctx,
+                                            info->info21.full_name.string);
        user_info->homedir = NULL;
        user_info->shell = NULL;
        user_info->primary_gid = (gid_t)-1;
@@ -508,9 +541,9 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
                                  uint32 *num_groups, DOM_SID **user_grpsids)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND dom_pol, user_pol;
-       uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
-       DOM_GID *user_groups;
+       struct policy_handle dom_pol, user_pol;
+       uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
+       struct samr_RidWithAttributeArray *rid_array = NULL;
        unsigned int i;
        uint32 user_rid;
        struct rpc_pipe_client *cli;
@@ -541,7 +574,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
        }
 
        /* no cache; hit the wire */
-       
+
        result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
        if (!NT_STATUS_IS_OK(result))
                return result;
@@ -557,8 +590,10 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
                return result;
 
        /* Query user rids */
-       result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol, 
-                                          num_groups, &user_groups);
+       result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
+                                             &user_pol,
+                                             &rid_array);
+       *num_groups = rid_array->count;
 
        rpccli_samr_Close(cli, mem_ctx, &user_pol);
 
@@ -572,24 +607,26 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
        for (i=0;i<(*num_groups);i++) {
                sid_copy(&((*user_grpsids)[i]), &domain->sid);
                sid_append_rid(&((*user_grpsids)[i]),
-                               user_groups[i].g_rid);
+                               rid_array->rids[i].rid);
        }
-       
+
        return NT_STATUS_OK;
 }
 
-NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
-                                 TALLOC_CTX *mem_ctx,
-                                 uint32 num_sids, const DOM_SID *sids,
-                                 uint32 *num_aliases, uint32 **alias_rids)
+#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
+
+static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
+                                        TALLOC_CTX *mem_ctx,
+                                        uint32 num_sids, const DOM_SID *sids,
+                                        uint32 *num_aliases,
+                                        uint32 **alias_rids)
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       POLICY_HND dom_pol;
-       DOM_SID2 *query_sids;
+       struct policy_handle dom_pol;
        uint32 num_query_sids = 0;
        int i;
        struct rpc_pipe_client *cli;
-       uint32 *alias_rids_query, num_aliases_query;
+       struct samr_Ids alias_rids_query;
        int rangesize = MAX_SAM_ENTRIES_W2K;
        uint32 total_sids = 0;
        int num_queries = 1;
@@ -611,6 +648,9 @@ NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
 
        do {
                /* prepare query */
+               struct lsa_SidArray sid_array;
+
+               ZERO_STRUCT(sid_array);
 
                num_query_sids = MIN(num_sids - total_sids, rangesize);
 
@@ -618,45 +658,48 @@ NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
                        num_queries, num_query_sids));  
 
                if (num_query_sids) {
-                       query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids);
-                       if (query_sids == NULL) {
+                       sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
+                       if (sid_array.sids == NULL) {
                                return NT_STATUS_NO_MEMORY;
                        }
                } else {
-                       query_sids = NULL;
+                       sid_array.sids = NULL;
                }
 
                for (i=0; i<num_query_sids; i++) {
-                       sid_copy(&query_sids[i].sid, &sids[total_sids++]);
-                       query_sids[i].num_auths = query_sids[i].sid.num_auths;
+                       sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
+                       if (!sid_array.sids[i].sid) {
+                               TALLOC_FREE(sid_array.sids);
+                               return NT_STATUS_NO_MEMORY;
+                       }
                }
+               sid_array.num_sids = num_query_sids;
 
                /* do request */
-
-               result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
-                                                      num_query_sids, query_sids,
-                                                      &num_aliases_query, 
-                                                      &alias_rids_query);
+               result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
+                                                       &dom_pol,
+                                                       &sid_array,
+                                                       &alias_rids_query);
 
                if (!NT_STATUS_IS_OK(result)) {
                        *num_aliases = 0;
                        *alias_rids = NULL;
-                       TALLOC_FREE(query_sids);
+                       TALLOC_FREE(sid_array.sids);
                        goto done;
                }
 
                /* process output */
 
-               for (i=0; i<num_aliases_query; i++) {
+               for (i=0; i<alias_rids_query.count; i++) {
                        size_t na = *num_aliases;
-                       if (!add_rid_to_array_unique(mem_ctx, alias_rids_query[i], 
+                       if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
                                                alias_rids, &na)) {
                                return NT_STATUS_NO_MEMORY;
                        }
                        *num_aliases = na;
                }
 
-               TALLOC_FREE(query_sids);
+               TALLOC_FREE(sid_array.sids);
 
                num_queries++;
 
@@ -673,19 +716,22 @@ NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
 /* Lookup group membership given a rid.   */
 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
                                TALLOC_CTX *mem_ctx,
-                               const DOM_SID *group_sid, uint32 *num_names, 
+                               const DOM_SID *group_sid,
+                               enum lsa_SidType type,
+                               uint32 *num_names,
                                DOM_SID **sid_mem, char ***names, 
                                uint32 **name_types)
 {
         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
         uint32 i, total_names = 0;
-        POLICY_HND dom_pol, group_pol;
-        uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+        struct policy_handle dom_pol, group_pol;
+        uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
        uint32 *rid_mem = NULL;
        uint32 group_rid;
-       unsigned int j;
+       unsigned int j, r;
        struct rpc_pipe_client *cli;
        unsigned int orig_timeout;
+       struct samr_RidTypeArray *rids = NULL;
 
        DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
                  sid_string_dbg(group_sid)));
@@ -720,20 +766,23 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
        /* This call can take a long time - allow the server to time out.
           35 seconds should do it. */
 
-       orig_timeout = cli_set_timeout(cli->cli, 35000);
+       orig_timeout = rpccli_set_timeout(cli, 35000);
 
-        result = rpccli_samr_query_groupmem(cli, mem_ctx,
-                                           &group_pol, num_names, &rid_mem,
-                                           name_types);
+        result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
+                                             &group_pol,
+                                             &rids);
 
        /* And restore our original timeout. */
-       cli_set_timeout(cli->cli, orig_timeout);
+       rpccli_set_timeout(cli, orig_timeout);
 
        rpccli_samr_Close(cli, mem_ctx, &group_pol);
 
         if (!NT_STATUS_IS_OK(result))
                return result;
 
+       *num_names = rids->count;
+       rid_mem = rids->rids;
+
        if (!*num_names) {
                names = NULL;
                name_types = NULL;
@@ -754,42 +803,48 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
 
        for (j=0;j<(*num_names);j++)
                sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
-       
+
        if (*num_names>0 && (!*names || !*name_types))
                return NT_STATUS_NO_MEMORY;
 
-        for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
-                int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
-                uint32 tmp_num_names = 0;
-                char **tmp_names = NULL;
-                uint32 *tmp_types = NULL;
+       for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
+               int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
+               struct lsa_Strings tmp_names;
+               struct samr_Ids tmp_types;
 
-                /* Lookup a chunk of rids */
+               /* Lookup a chunk of rids */
 
-                result = rpccli_samr_lookup_rids(cli, mem_ctx,
-                                                &dom_pol,
-                                                num_lookup_rids,
-                                                &rid_mem[i],
-                                                &tmp_num_names,
-                                                &tmp_names, &tmp_types);
+               result = rpccli_samr_LookupRids(cli, mem_ctx,
+                                               &dom_pol,
+                                               num_lookup_rids,
+                                               &rid_mem[i],
+                                               &tmp_names,
+                                               &tmp_types);
 
                /* see if we have a real error (and yes the
                   STATUS_SOME_UNMAPPED is the one returned from 2k) */
-               
+
                 if (!NT_STATUS_IS_OK(result) &&
                    !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
                        return result;
-                       
-                /* Copy result into array.  The talloc system will take
-                   care of freeing the temporary arrays later on. */
 
-                memcpy(&(*names)[i], tmp_names, sizeof(char *) * 
-                       tmp_num_names);
+               /* Copy result into array.  The talloc system will take
+                  care of freeing the temporary arrays later on. */
 
-                memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
-                       tmp_num_names);
-               
-                total_names += tmp_num_names;
+               if (tmp_names.count != tmp_types.count) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+
+               for (r=0; r<tmp_names.count; r++) {
+                       if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
+                               continue;
+                       }
+                       (*names)[total_names] = fill_domain_username_talloc(
+                               mem_ctx, domain->name,
+                               tmp_names.names[r].string, true);
+                       (*name_types)[total_names] = tmp_types.ids[r];
+                       total_names += 1;
+               }
         }
 
         *num_names = total_names;
@@ -875,9 +930,9 @@ static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
 {
        TALLOC_CTX *mem_ctx;
-       SAM_UNK_CTR ctr;
+       union samr_DomainInfo *info = NULL;
        NTSTATUS result;
-       POLICY_HND dom_pol;
+       struct policy_handle dom_pol;
        bool got_seq_num = False;
        struct rpc_pipe_client *cli;
 
@@ -926,21 +981,27 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
 
        /* Query domain info */
 
-       result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);
+       result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
+                                            &dom_pol,
+                                            8,
+                                            &info);
 
        if (NT_STATUS_IS_OK(result)) {
-               *seq = ctr.info.inf8.seq_num;
+               *seq = info->info8.sequence_num;
                got_seq_num = True;
                goto seq_num;
        }
 
        /* retry with info-level 2 in case the dc does not support info-level 8
-        * (like all older samba2 and samba3 dc's - Guenther */
+        * (like all older samba2 and samba3 dc's) - Guenther */
+
+       result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
+                                            &dom_pol,
+                                            2,
+                                            &info);
 
-       result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);
-       
        if (NT_STATUS_IS_OK(result)) {
-               *seq = ctr.info.inf2.seq_num;
+               *seq = info->general.sequence_num;
                got_seq_num = True;
        }
 
@@ -972,7 +1033,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 enum_ctx = 0;
        struct rpc_pipe_client *cli;
-       POLICY_HND lsa_policy;
+       struct policy_handle lsa_policy;
 
        DEBUG(3,("rpc: trusted_domains\n"));
 
@@ -988,22 +1049,22 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
        result = STATUS_MORE_ENTRIES;
 
        while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
-               uint32 start_idx, num;
-               char **tmp_names;
-               DOM_SID *tmp_sids;
+               uint32 start_idx;
                int i;
+               struct lsa_DomainList dom_list;
 
-               result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,
-                                                  &lsa_policy, &enum_ctx,
-                                                  &num, &tmp_names,
-                                                  &tmp_sids);
+               result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
+                                                &lsa_policy,
+                                                &enum_ctx,
+                                                &dom_list,
+                                                (uint32_t)-1);
 
                if (!NT_STATUS_IS_OK(result) &&
                    !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
                        break;
 
                start_idx = *num_domains;
-               *num_domains += num;
+               *num_domains += dom_list.count;
                *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
                                              char *, *num_domains);
                *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
@@ -1014,9 +1075,9 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
                    (*alt_names == NULL))
                        return NT_STATUS_NO_MEMORY;
 
-               for (i=0; i<num; i++) {
-                       (*names)[start_idx+i] = tmp_names[i];
-                       (*dom_sids)[start_idx+i] = tmp_sids[i];
+               for (i=0; i<dom_list.count; i++) {
+                       (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
+                       (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
                        (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
                }
        }
@@ -1024,14 +1085,14 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
 }
 
 /* find the lockout policy for a domain */
-NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain, 
-                             TALLOC_CTX *mem_ctx,
-                             SAM_UNK_INFO_12 *lockout_policy)
+static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct samr_DomInfo12 *lockout_policy)
 {
        NTSTATUS result;
        struct rpc_pipe_client *cli;
-       POLICY_HND dom_pol;
-       SAM_UNK_CTR ctr;
+       struct policy_handle dom_pol;
+       union samr_DomainInfo *info = NULL;
 
        DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
 
@@ -1046,15 +1107,18 @@ NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
                goto done;
        }
 
-       result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr);
+       result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
+                                            &dom_pol,
+                                            12,
+                                            &info);
        if (!NT_STATUS_IS_OK(result)) {
                goto done;
        }
 
-       *lockout_policy = ctr.info.inf12;
+       *lockout_policy = info->info12;
 
-       DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n", 
-               ctr.info.inf12.bad_attempt_lockout));
+       DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
+               info->info12.lockout_threshold));
 
   done:
 
@@ -1062,14 +1126,14 @@ NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
 }
 
 /* find the password policy for a domain */
-NTSTATUS msrpc_password_policy(struct winbindd_domain *domain, 
-                              TALLOC_CTX *mem_ctx,
-                              SAM_UNK_INFO_1 *password_policy)
+static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
+                                     TALLOC_CTX *mem_ctx,
+                                     struct samr_DomInfo1 *password_policy)
 {
        NTSTATUS result;
        struct rpc_pipe_client *cli;
-       POLICY_HND dom_pol;
-       SAM_UNK_CTR ctr;
+       struct policy_handle dom_pol;
+       union samr_DomainInfo *info = NULL;
 
        DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
 
@@ -1084,21 +1148,154 @@ NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
                goto done;
        }
 
-       result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr);
+       result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
+                                            &dom_pol,
+                                            1,
+                                            &info);
        if (!NT_STATUS_IS_OK(result)) {
                goto done;
        }
 
-       *password_policy = ctr.info.inf1;
+       *password_policy = info->info1;
 
-       DEBUG(10,("msrpc_password_policy: min_length_password %d\n", 
-               ctr.info.inf1.min_length_password));
+       DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
+               info->info1.min_password_length));
 
   done:
 
        return result;
 }
 
+typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct policy_handle *pol,
+                                    int num_sids,
+                                    const DOM_SID *sids,
+                                    char ***pdomains,
+                                    char ***pnames,
+                                    enum lsa_SidType **ptypes);
+
+NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
+                             struct winbindd_domain *domain,
+                             uint32_t num_sids,
+                             const struct dom_sid *sids,
+                             char ***domains,
+                             char ***names,
+                             enum lsa_SidType **types)
+{
+       NTSTATUS status;
+       struct rpc_pipe_client *cli = NULL;
+       struct policy_handle lsa_policy;
+       unsigned int orig_timeout;
+       lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
+
+       if (domain->can_do_ncacn_ip_tcp) {
+               status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
+               if (NT_STATUS_IS_OK(status)) {
+                       lookup_sids_fn = rpccli_lsa_lookup_sids3;
+                       goto lookup;
+               }
+               domain->can_do_ncacn_ip_tcp = false;
+       }
+       status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+ lookup:
+       /*
+        * This call can take a long time
+        * allow the server to time out.
+        * 35 seconds should do it.
+        */
+       orig_timeout = rpccli_set_timeout(cli, 35000);
+
+       status = lookup_sids_fn(cli,
+                               mem_ctx,
+                               &lsa_policy,
+                               num_sids,
+                               sids,
+                               domains,
+                               names,
+                               types);
+
+       /* And restore our original timeout. */
+       rpccli_set_timeout(cli, orig_timeout);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       return status;
+}
+
+typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
+                                     TALLOC_CTX *mem_ctx,
+                                     struct policy_handle *pol,
+                                     int num_names,
+                                     const char **names,
+                                     const char ***dom_names,
+                                     int level,
+                                     struct dom_sid **sids,
+                                     enum lsa_SidType **types);
+
+NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
+                              struct winbindd_domain *domain,
+                              uint32_t num_names,
+                              const char **names,
+                              const char ***domains,
+                              struct dom_sid **sids,
+                              enum lsa_SidType **types)
+{
+       NTSTATUS status;
+       struct rpc_pipe_client *cli = NULL;
+       struct policy_handle lsa_policy;
+       unsigned int orig_timeout;
+       lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
+
+       if (domain->can_do_ncacn_ip_tcp) {
+               status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
+               if (NT_STATUS_IS_OK(status)) {
+                       lookup_names_fn = rpccli_lsa_lookup_names4;
+                       goto lookup;
+               }
+               domain->can_do_ncacn_ip_tcp = false;
+       }
+       status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+ lookup:
+
+       /*
+        * This call can take a long time
+        * allow the server to time out.
+        * 35 seconds should do it.
+        */
+       orig_timeout = rpccli_set_timeout(cli, 35000);
+
+       status = lookup_names_fn(cli,
+                                mem_ctx,
+                                &lsa_policy,
+                                num_names,
+                                (const char **) names,
+                                domains,
+                                1,
+                                sids,
+                                types);
+
+       /* And restore our original timeout. */
+       rpccli_set_timeout(cli, orig_timeout);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       return status;
+}
 
 /* the rpc backend methods are exposed via this structure */
 struct winbindd_methods msrpc_methods = {