Change all uint32/16/8 to 32_t/16_t/8_t in winbindd.
[kamenim/samba-autobuild/.git] / source3 / winbindd / winbindd_samr.c
index a3bbb27df950eafd3b38783dbf3841776de431a5..b94dfc8dc6e55fdd1a4afbf80aebfdc894f99d8c 100644 (file)
 #include "includes.h"
 #include "winbindd.h"
 #include "winbindd_rpc.h"
-
-#include "../librpc/gen_ndr/cli_samr.h"
+#include "rpc_client/rpc_client.h"
+#include "../librpc/gen_ndr/ndr_samr_c.h"
 #include "rpc_client/cli_samr.h"
-#include "../librpc/gen_ndr/srv_samr.h"
-#include "../librpc/gen_ndr/cli_lsa.h"
+#include "../librpc/gen_ndr/ndr_lsa_c.h"
 #include "rpc_client/cli_lsarpc.h"
-#include "../librpc/gen_ndr/srv_lsa.h"
+#include "rpc_server/rpc_ncacn_np.h"
+#include "../libcli/security/security.h"
+#include "passdb/machine_sid.h"
+#include "auth.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
-static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
-                                       struct rpc_pipe_client **samr_pipe)
-{
-       static struct rpc_pipe_client *cli = NULL;
-       struct auth_serversupplied_info *server_info = NULL;
-       NTSTATUS status;
-
-       if (cli != NULL) {
-               goto done;
-       }
-
-       if (server_info == NULL) {
-               status = make_server_info_system(mem_ctx, &server_info);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",
-                                 nt_errstr(status)));
-                       return status;
-               }
-       }
-
-       /* create a samr connection */
-       status = rpc_pipe_open_internal(talloc_autofree_context(),
-                                       &ndr_table_samr.syntax_id,
-                                       rpc_samr_dispatch,
-                                       server_info,
-                                       &cli);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
-                         nt_errstr(status)));
-               return status;
-       }
-
-done:
-       if (samr_pipe) {
-               *samr_pipe = cli;
-       }
-
-       return NT_STATUS_OK;
-}
-
-static NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
-                                       struct winbindd_domain *domain,
-                                       struct rpc_pipe_client **samr_pipe,
-                                       struct policy_handle *samr_domain_hnd)
+NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
+                                struct winbindd_domain *domain,
+                                struct rpc_pipe_client **samr_pipe,
+                                struct policy_handle *samr_domain_hnd)
 {
-       NTSTATUS status;
+       NTSTATUS status, result;
        struct policy_handle samr_connect_hnd;
+       struct dcerpc_binding_handle *b;
 
-       status = open_internal_samr_pipe(mem_ctx, samr_pipe);
+       status = wb_open_internal_pipe(mem_ctx, &ndr_table_samr, samr_pipe);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       status = rpccli_samr_Connect2((*samr_pipe),
-                                     mem_ctx,
+       b = (*samr_pipe)->binding_handle;
+
+       status = dcerpc_samr_Connect2(b, mem_ctx,
                                      (*samr_pipe)->desthost,
                                      SEC_FLAG_MAXIMUM_ALLOWED,
-                                     &samr_connect_hnd);
+                                     &samr_connect_hnd,
+                                     &result);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               return result;
+       }
 
-       status = rpccli_samr_OpenDomain((*samr_pipe),
-                                       mem_ctx,
+       status = dcerpc_samr_OpenDomain(b, mem_ctx,
                                        &samr_connect_hnd,
                                        SEC_FLAG_MAXIMUM_ALLOWED,
                                        &domain->sid,
-                                       samr_domain_hnd);
-
-       return status;
-}
-
-static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
-                                      struct rpc_pipe_client **lsa_pipe)
-{
-       static struct rpc_pipe_client *cli = NULL;
-       struct auth_serversupplied_info *server_info = NULL;
-       NTSTATUS status;
-
-       if (cli != NULL) {
-               goto done;
-       }
-
-       if (server_info == NULL) {
-               status = make_server_info_system(mem_ctx, &server_info);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",
-                                 nt_errstr(status)));
-                       return status;
-               }
-       }
-
-       /* create a samr connection */
-       status = rpc_pipe_open_internal(talloc_autofree_context(),
-                                       &ndr_table_lsarpc.syntax_id,
-                                       rpc_lsarpc_dispatch,
-                                       server_info,
-                                       &cli);
+                                       samr_domain_hnd,
+                                       &result);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
-                         nt_errstr(status)));
                return status;
        }
 
-done:
-       if (lsa_pipe) {
-               *lsa_pipe = cli;
-       }
-
-       return NT_STATUS_OK;
+       return result;
 }
 
-static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
-                                      struct rpc_pipe_client **lsa_pipe,
-                                      struct policy_handle *lsa_hnd)
+NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
+                               struct rpc_pipe_client **lsa_pipe,
+                               struct policy_handle *lsa_hnd)
 {
        NTSTATUS status;
 
-       status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
+       status = wb_open_internal_pipe(mem_ctx, &ndr_table_lsarpc, lsa_pipe);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -177,17 +108,20 @@ static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
                                    TALLOC_CTX *mem_ctx,
                                    uint32_t *pnum_info,
-                                   struct acct_info **pinfo)
+                                   struct wb_acct_info **pinfo)
 {
        struct rpc_pipe_client *samr_pipe;
        struct policy_handle dom_pol;
-       struct acct_info *info = NULL;
+       struct wb_acct_info *info = NULL;
        uint32_t num_info = 0;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("sam_enum_dom_groups\n"));
 
+       ZERO_STRUCT(dom_pol);
+
        if (pnum_info) {
                *pnum_info = 0;
        }
@@ -202,6 +136,8 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
                goto error;
        }
 
+       b = samr_pipe->binding_handle;
+
        status = rpc_enum_dom_groups(tmp_ctx,
                                     samr_pipe,
                                     &dom_pol,
@@ -220,6 +156,9 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
        }
 
 error:
+       if (b && is_valid_policy_hnd(&dom_pol)) {
+               dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
+       }
        TALLOC_FREE(tmp_ctx);
        return status;
 }
@@ -235,10 +174,13 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
        struct wbint_userinfo *info = NULL;
        uint32_t num_info = 0;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("samr_query_user_list\n"));
 
+       ZERO_STRUCT(dom_pol);
+
        if (pnum_info) {
                *pnum_info = 0;
        }
@@ -253,6 +195,8 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
                goto done;
        }
 
+       b = samr_pipe->binding_handle;
+
        status = rpc_query_user_list(tmp_ctx,
                                     samr_pipe,
                                     &dom_pol,
@@ -272,6 +216,10 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
        }
 
 done:
+       if (b && is_valid_policy_hnd(&dom_pol)) {
+               dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
@@ -285,20 +233,21 @@ static NTSTATUS sam_query_user(struct winbindd_domain *domain,
        struct rpc_pipe_client *samr_pipe;
        struct policy_handle dom_pol;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("sam_query_user\n"));
 
+       ZERO_STRUCT(dom_pol);
+
        /* Paranoia check */
-       if (!sid_check_is_in_our_domain(user_sid)) {
+       if (!sid_check_is_in_our_sam(user_sid)) {
                return NT_STATUS_NO_SUCH_USER;
        }
 
-       if (user_info) {
-               user_info->homedir = NULL;
-               user_info->shell = NULL;
-               user_info->primary_gid = (gid_t) -1;
-       }
+       user_info->homedir = NULL;
+       user_info->shell = NULL;
+       user_info->primary_gid = (gid_t) -1;
 
        tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
@@ -310,6 +259,8 @@ static NTSTATUS sam_query_user(struct winbindd_domain *domain,
                goto done;
        }
 
+       b = samr_pipe->binding_handle;
+
        status = rpc_query_user(tmp_ctx,
                                samr_pipe,
                                &dom_pol,
@@ -318,6 +269,10 @@ static NTSTATUS sam_query_user(struct winbindd_domain *domain,
                                user_info);
 
 done:
+       if (b && is_valid_policy_hnd(&dom_pol)) {
+               dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
@@ -325,18 +280,24 @@ done:
 /* get a list of trusted domains - builtin domain */
 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
                                    TALLOC_CTX *mem_ctx,
-                                   struct netr_DomainTrustList *trusts)
+                                   struct netr_DomainTrustList *ptrust_list)
 {
        struct rpc_pipe_client *lsa_pipe;
-       struct netr_DomainTrust *array = NULL;
        struct policy_handle lsa_policy;
-       uint32_t enum_ctx = 0;
-       uint32_t count = 0;
+       struct netr_DomainTrust *trusts = NULL;
+       uint32_t num_trusts = 0;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("samr: trusted domains\n"));
 
+       ZERO_STRUCT(lsa_policy);
+
+       if (ptrust_list) {
+               ZERO_STRUCTP(ptrust_list);
+       }
+
        tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return NT_STATUS_NO_MEMORY;
@@ -344,68 +305,30 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
 
        status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
        if (!NT_STATUS_IS_OK(status)) {
-               goto error;
+               goto done;
        }
 
-       do {
-               struct lsa_DomainList dom_list;
-               uint32_t start_idx;
-               uint32_t i;
-
-               /*
-                * We don't run into deadlocks here, cause winbind_off() is
-                * called in the main function.
-                */
-               status = rpccli_lsa_EnumTrustDom(lsa_pipe,
-                                                tmp_ctx,
-                                                &lsa_policy,
-                                                &enum_ctx,
-                                                &dom_list,
-                                                (uint32_t) -1);
-               if (!NT_STATUS_IS_OK(status)) {
-                       if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
-                               goto error;
-                       }
-               }
-
-               start_idx = trusts->count;
-               count += dom_list.count;
-
-               array = talloc_realloc(tmp_ctx,
-                                      array,
-                                      struct netr_DomainTrust,
-                                      count);
-               if (array == NULL) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto error;
-               }
-
-               for (i = 0; i < dom_list.count; i++) {
-                       struct netr_DomainTrust *trust = &array[i];
-                       struct dom_sid *sid;
-
-                       ZERO_STRUCTP(trust);
-
-                       trust->netbios_name = talloc_move(array,
-                                                         &dom_list.domains[i].name.string);
-                       trust->dns_name = NULL;
-
-                       sid = talloc(array, struct dom_sid);
-                       if (sid == NULL) {
-                               status = NT_STATUS_NO_MEMORY;
-                               goto error;
-                       }
-                       sid_copy(sid, dom_list.domains[i].sid);
-                       trust->sid = sid;
-               }
-       } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
-
-       if (trusts) {
-               trusts->count = count;
-               trusts->array = talloc_move(mem_ctx, &array);
+       b = lsa_pipe->binding_handle;
+
+       status = rpc_trusted_domains(tmp_ctx,
+                                    lsa_pipe,
+                                    &lsa_policy,
+                                    &num_trusts,
+                                    &trusts);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
+       }
+
+       if (ptrust_list) {
+               ptrust_list->count = num_trusts;
+               ptrust_list->array = talloc_move(mem_ctx, &trusts);
+       }
+
+done:
+       if (b && is_valid_policy_hnd(&lsa_policy)) {
+               dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
        }
 
-error:
        TALLOC_FREE(tmp_ctx);
        return status;
 }
@@ -421,33 +344,29 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
                                    uint32_t **pname_types)
 {
        struct rpc_pipe_client *samr_pipe;
-       struct policy_handle dom_pol, group_pol;
-       uint32_t samr_access = SEC_FLAG_MAXIMUM_ALLOWED;
-       struct samr_RidTypeArray *rids = NULL;
-       uint32_t group_rid;
-       uint32_t *rid_mem = NULL;
+       struct policy_handle dom_pol;
 
        uint32_t num_names = 0;
-       uint32_t total_names = 0;
        struct dom_sid *sid_mem = NULL;
        char **names = NULL;
        uint32_t *name_types = NULL;
 
-       struct lsa_Strings tmp_names;
-       struct samr_Ids tmp_types;
-
-       uint32_t j, r;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
-       DEBUG(3,("samr: lookup groupmem\n"));
+       DEBUG(3,("sam_lookup_groupmem\n"));
 
-       if (pnum_names) {
-               pnum_names = 0;
+       ZERO_STRUCT(dom_pol);
+
+       /* Paranoia check */
+       if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
+               /* There's no groups, only aliases in BUILTIN */
+               return NT_STATUS_NO_SUCH_GROUP;
        }
 
-       if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) {
-               return NT_STATUS_UNSUCCESSFUL;
+       if (pnum_names) {
+               *pnum_names = 0;
        }
 
        tmp_ctx = talloc_stackframe();
@@ -457,99 +376,25 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
 
        status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
        if (!NT_STATUS_IS_OK(status)) {
-               goto error;
-       }
-
-       status = rpccli_samr_OpenGroup(samr_pipe,
-                                      tmp_ctx,
-                                      &dom_pol,
-                                      samr_access,
-                                      group_rid,
-                                      &group_pol);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto error;
-       }
-
-       /*
-        * Step #1: Get a list of user rids that are the members of the group.
-        */
-       status = rpccli_samr_QueryGroupMember(samr_pipe,
-                                             tmp_ctx,
-                                             &group_pol,
-                                             &rids);
-
-       rpccli_samr_Close(samr_pipe, tmp_ctx, &group_pol);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               goto error;
-       }
-
-       if (rids == NULL || rids->count == 0) {
-               pnum_names = 0;
-               pnames = NULL;
-               pname_types = NULL;
-               psid_mem = NULL;
-
-               status = NT_STATUS_OK;
-               goto error;
-       }
-
-       num_names = rids->count;
-       rid_mem = rids->rids;
-
-       /*
-        * Step #2: Convert list of rids into list of usernames.
-        */
-#define MAX_LOOKUP_RIDS 900
-
-       if (num_names > 0) {
-               names = TALLOC_ZERO_ARRAY(tmp_ctx, char *, num_names);
-               name_types = TALLOC_ZERO_ARRAY(tmp_ctx, uint32_t, num_names);
-               sid_mem = TALLOC_ZERO_ARRAY(tmp_ctx, struct dom_sid, num_names);
-               if (names == NULL || name_types == NULL || sid_mem == NULL) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto error;
-               }
-       }
-
-       for (j = 0; j < num_names; j++) {
-               sid_compose(&sid_mem[j], &domain->sid, rid_mem[j]);
-       }
-
-       status = rpccli_samr_LookupRids(samr_pipe,
-                                       tmp_ctx,
-                                       &dom_pol,
-                                       num_names,
-                                       rid_mem,
-                                       &tmp_names,
-                                       &tmp_types);
-       if (!NT_STATUS_IS_OK(status)) {
-               if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
-                       goto error;
-               }
+               goto done;
        }
 
-       /* Copy result into array.  The talloc system will take
-          care of freeing the temporary arrays later on. */
-       if (tmp_names.count != tmp_types.count) {
-               status = NT_STATUS_UNSUCCESSFUL;
-               goto error;
-       }
+       b = samr_pipe->binding_handle;
 
-       for (r = 0; r < tmp_names.count; r++) {
-               if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
-                       continue;
-               }
-               names[total_names] = fill_domain_username_talloc(names,
-                                                                domain->name,
-                                                                tmp_names.names[r].string,
-                                                                true);
-               name_types[total_names] = tmp_types.ids[r];
-               total_names++;
-       }
+       status = rpc_lookup_groupmem(tmp_ctx,
+                                    samr_pipe,
+                                    &dom_pol,
+                                    domain->name,
+                                    &domain->sid,
+                                    group_sid,
+                                    type,
+                                    &num_names,
+                                    &sid_mem,
+                                    &names,
+                                    &name_types);
 
        if (pnum_names) {
-               *pnum_names = total_names;
+               *pnum_names = num_names;
        }
 
        if (pnames) {
@@ -564,7 +409,11 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
                *psid_mem = talloc_move(mem_ctx, &sid_mem);
        }
 
-error:
+done:
+       if (b && is_valid_policy_hnd(&dom_pol)) {
+               dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
@@ -576,8 +425,8 @@ error:
 /* List all domain groups */
 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
                                TALLOC_CTX *mem_ctx,
-                               uint32 *num_entries,
-                               struct acct_info **info)
+                               uint32_t *num_entries,
+                               struct wb_acct_info **info)
 {
        /* BUILTIN doesn't have domain groups */
        *num_entries = 0;
@@ -588,7 +437,7 @@ static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
 /* Query display info for a domain */
 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
                                TALLOC_CTX *mem_ctx,
-                               uint32 *num_entries,
+                               uint32_t *num_entries,
                                struct wbint_userinfo **info)
 {
        /* We don't have users */
@@ -623,17 +472,20 @@ static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
                                      TALLOC_CTX *mem_ctx,
                                      uint32_t *pnum_info,
-                                     struct acct_info **pinfo)
+                                     struct wb_acct_info **pinfo)
 {
        struct rpc_pipe_client *samr_pipe;
        struct policy_handle dom_pol;
-       struct acct_info *info = NULL;
+       struct wb_acct_info *info = NULL;
        uint32_t num_info = 0;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("samr: enum local groups\n"));
 
+       ZERO_STRUCT(dom_pol);
+
        if (pnum_info) {
                *pnum_info = 0;
        }
@@ -648,6 +500,8 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
                goto done;
        }
 
+       b = samr_pipe->binding_handle;
+
        status = rpc_enum_local_groups(mem_ctx,
                                       samr_pipe,
                                       &dom_pol,
@@ -666,6 +520,10 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
        }
 
 done:
+       if (b && is_valid_policy_hnd(&dom_pol)) {
+               dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
@@ -684,10 +542,13 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
        struct dom_sid sid;
        enum lsa_SidType type;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("sam_name_to_sid\n"));
 
+       ZERO_STRUCT(lsa_policy);
+
        tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return NT_STATUS_NO_MEMORY;
@@ -698,6 +559,8 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
                goto done;
        }
 
+       b = lsa_pipe->binding_handle;
+
        status = rpc_name_to_sid(tmp_ctx,
                                 lsa_pipe,
                                 &lsa_policy,
@@ -718,6 +581,10 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
        }
 
 done:
+       if (b && is_valid_policy_hnd(&lsa_policy)) {
+               dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
@@ -736,13 +603,18 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
        char *name = NULL;
        enum lsa_SidType type;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("sam_sid_to_name\n"));
 
+       ZERO_STRUCT(lsa_policy);
+
        /* Paranoia check */
        if (!sid_check_is_in_builtin(sid) &&
-           !sid_check_is_in_our_domain(sid) &&
+           !sid_check_is_builtin(sid) &&
+           !sid_check_is_in_our_sam(sid) &&
+           !sid_check_is_our_sam(sid) &&
            !sid_check_is_in_unix_users(sid) &&
            !sid_check_is_unix_users(sid) &&
            !sid_check_is_in_unix_groups(sid) &&
@@ -763,6 +635,8 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
                goto done;
        }
 
+       b = lsa_pipe->binding_handle;
+
        status = rpc_sid_to_name(tmp_ctx,
                                 lsa_pipe,
                                 &lsa_policy,
@@ -785,14 +659,18 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
        }
 
 done:
+       if (b && is_valid_policy_hnd(&lsa_policy)) {
+               dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
 
 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
                                  TALLOC_CTX *mem_ctx,
-                                 const struct dom_sid *sid,
-                                 uint32 *rids,
+                                 const struct dom_sid *domain_sid,
+                                 uint32_t *rids,
                                  size_t num_rids,
                                  char **pdomain_name,
                                  char ***pnames,
@@ -804,20 +682,21 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
        char *domain_name = NULL;
        char **names = NULL;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
 
+       ZERO_STRUCT(lsa_policy);
+
        /* Paranoia check */
-       if (!sid_check_is_in_builtin(sid) &&
-           !sid_check_is_in_our_domain(sid) &&
-           !sid_check_is_in_unix_users(sid) &&
-           !sid_check_is_unix_users(sid) &&
-           !sid_check_is_in_unix_groups(sid) &&
-           !sid_check_is_unix_groups(sid) &&
-           !sid_check_is_in_wellknown_domain(sid)) {
+       if (!sid_check_is_builtin(domain_sid) &&
+           !sid_check_is_our_sam(domain_sid) &&
+           !sid_check_is_unix_users(domain_sid) &&
+           !sid_check_is_unix_groups(domain_sid) &&
+           !sid_check_is_in_wellknown_domain(domain_sid)) {
                DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
-                         "lookup SID %s\n", sid_string_dbg(sid)));
+                         "lookup SID %s\n", sid_string_dbg(domain_sid)));
                return NT_STATUS_NONE_MAPPED;
        }
 
@@ -831,11 +710,13 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
                goto done;
        }
 
+       b = lsa_pipe->binding_handle;
+
        status = rpc_rids_to_names(tmp_ctx,
                                   lsa_pipe,
                                   &lsa_policy,
                                   domain,
-                                  sid,
+                                  domain_sid,
                                   rids,
                                   num_rids,
                                   &domain_name,
@@ -858,21 +739,28 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
        }
 
 done:
+       if (b && is_valid_policy_hnd(&lsa_policy)) {
+               dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
 
-static NTSTATUS common_lockout_policy(struct winbindd_domain *domain,
-                                     TALLOC_CTX *mem_ctx,
-                                     struct samr_DomInfo12 *lockout_policy)
+static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct samr_DomInfo12 *lockout_policy)
 {
        struct rpc_pipe_client *samr_pipe;
        struct policy_handle dom_pol;
        union samr_DomainInfo *info = NULL;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
+
+       DEBUG(3,("sam_lockout_policy\n"));
 
-       DEBUG(3,("samr: lockout policy\n"));
+       ZERO_STRUCT(dom_pol);
 
        tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
@@ -884,33 +772,47 @@ static NTSTATUS common_lockout_policy(struct winbindd_domain *domain,
                goto error;
        }
 
-       status = rpccli_samr_QueryDomainInfo(samr_pipe,
+       b = samr_pipe->binding_handle;
+
+       status = dcerpc_samr_QueryDomainInfo(b,
                                             mem_ctx,
                                             &dom_pol,
-                                            12,
-                                            &info);
+                                            DomainLockoutInformation,
+                                            &info,
+                                            &result);
        if (!NT_STATUS_IS_OK(status)) {
                goto error;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               status = result;
+               goto error;
+       }
 
        *lockout_policy = info->info12;
 
 error:
+       if (b && is_valid_policy_hnd(&dom_pol)) {
+               dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
 
-static NTSTATUS common_password_policy(struct winbindd_domain *domain,
-                                      TALLOC_CTX *mem_ctx,
-                                      struct samr_DomInfo1 *passwd_policy)
+static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
+                                   TALLOC_CTX *mem_ctx,
+                                   struct samr_DomInfo1 *passwd_policy)
 {
        struct rpc_pipe_client *samr_pipe;
        struct policy_handle dom_pol;
        union samr_DomainInfo *info = NULL;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
+
+       DEBUG(3,("sam_password_policy\n"));
 
-       DEBUG(3,("samr: password policy\n"));
+       ZERO_STRUCT(dom_pol);
 
        tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
@@ -922,18 +824,29 @@ static NTSTATUS common_password_policy(struct winbindd_domain *domain,
                goto error;
        }
 
-       status = rpccli_samr_QueryDomainInfo(samr_pipe,
+       b = samr_pipe->binding_handle;
+
+       status = dcerpc_samr_QueryDomainInfo(b,
                                             mem_ctx,
                                             &dom_pol,
-                                            1,
-                                            &info);
+                                            DomainPasswordInformation,
+                                            &info,
+                                            &result);
        if (!NT_STATUS_IS_OK(status)) {
                goto error;
        }
+       if (!NT_STATUS_IS_OK(result)) {
+               status = result;
+               goto error;
+       }
 
        *passwd_policy = info->info1;
 
 error:
+       if (b && is_valid_policy_hnd(&dom_pol)) {
+               dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
@@ -950,10 +863,13 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
        struct dom_sid *user_grpsids = NULL;
        uint32_t num_groups = 0;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("sam_lookup_usergroups\n"));
 
+       ZERO_STRUCT(dom_pol);
+
        if (pnum_groups) {
                *pnum_groups = 0;
        }
@@ -968,6 +884,8 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
                goto done;
        }
 
+       b = samr_pipe->binding_handle;
+
        status = rpc_lookup_usergroups(tmp_ctx,
                                       samr_pipe,
                                       &dom_pol,
@@ -988,6 +906,10 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
        }
 
 done:
+       if (b && is_valid_policy_hnd(&dom_pol)) {
+               dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
@@ -1004,10 +926,13 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
        uint32_t num_aliases = 0;
        uint32_t *alias_rids = NULL;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("sam_lookup_useraliases\n"));
 
+       ZERO_STRUCT(dom_pol);
+
        if (pnum_aliases) {
                *pnum_aliases = 0;
        }
@@ -1022,6 +947,8 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
                goto done;
        }
 
+       b = samr_pipe->binding_handle;
+
        status = rpc_lookup_useraliases(tmp_ctx,
                                        samr_pipe,
                                        &dom_pol,
@@ -1042,78 +969,63 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
        }
 
 done:
+       if (b && is_valid_policy_hnd(&dom_pol)) {
+               dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
+       }
+
        TALLOC_FREE(tmp_ctx);
        return status;
 }
 
 /* find the sequence number for a domain */
-static NTSTATUS common_sequence_number(struct winbindd_domain *domain,
-                                      uint32_t *seq)
+static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
+                                   uint32_t *pseq)
 {
        struct rpc_pipe_client *samr_pipe;
        struct policy_handle dom_pol;
-       union samr_DomainInfo *info = NULL;
-       bool got_seq_num = false;
-       TALLOC_CTX *mem_ctx;
-       NTSTATUS status;
+       uint32_t seq;
+       TALLOC_CTX *tmp_ctx;
+       NTSTATUS status, result;
+       struct dcerpc_binding_handle *b = NULL;
 
        DEBUG(3,("samr: sequence number\n"));
 
-       mem_ctx = talloc_init("common_sequence_number");
-       if (mem_ctx == NULL) {
+       ZERO_STRUCT(dom_pol);
+
+       if (pseq) {
+               *pseq = DOM_SEQUENCE_NONE;
+       }
+
+       tmp_ctx = talloc_stackframe();
+       if (tmp_ctx == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (seq) {
-               *seq = DOM_SEQUENCE_NONE;
+       status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto done;
        }
 
-       status = open_internal_samr_conn(mem_ctx, domain, &samr_pipe, &dom_pol);
+       b = samr_pipe->binding_handle;
+
+       status = rpc_sequence_number(tmp_ctx,
+                                    samr_pipe,
+                                    &dom_pol,
+                                    domain->name,
+                                    &seq);
        if (!NT_STATUS_IS_OK(status)) {
-               goto error;
+               goto done;
        }
 
-       /* query domain info */
-       status = rpccli_samr_QueryDomainInfo(samr_pipe,
-                                            mem_ctx,
-                                            &dom_pol,
-                                            8,
-                                            &info);
-       if (NT_STATUS_IS_OK(status)) {
-               if (seq) {
-                       *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 */
-       status = rpccli_samr_QueryDomainInfo(samr_pipe,
-                                            mem_ctx,
-                                            &dom_pol,
-                                            2,
-                                            &info);
-       if (NT_STATUS_IS_OK(status)) {
-               if (seq) {
-                       *seq = info->general.sequence_num;
-                       got_seq_num = true;
-               }
-       }
-
-seq_num:
-       if (got_seq_num) {
-               DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
-                         domain->name, (unsigned)*seq));
-       } else {
-               DEBUG(10,("domain_sequence_number: failed to get sequence "
-                         "number (%u) for domain %s\n",
-                         (unsigned) *seq, domain->name ));
-               status = NT_STATUS_OK;
+       if (pseq) {
+               *pseq = seq;
+       }
+done:
+       if (b && is_valid_policy_hnd(&dom_pol)) {
+               dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
        }
 
-error:
-       talloc_destroy(mem_ctx);
+       TALLOC_FREE(tmp_ctx);
        return status;
 }
 
@@ -1131,9 +1043,9 @@ struct winbindd_methods builtin_passdb_methods = {
        .lookup_usergroups     = sam_lookup_usergroups,
        .lookup_useraliases    = sam_lookup_useraliases,
        .lookup_groupmem       = sam_lookup_groupmem,
-       .sequence_number       = common_sequence_number,
-       .lockout_policy        = common_lockout_policy,
-       .password_policy       = common_password_policy,
+       .sequence_number       = sam_sequence_number,
+       .lockout_policy        = sam_lockout_policy,
+       .password_policy       = sam_password_policy,
        .trusted_domains       = builtin_trusted_domains
 };
 
@@ -1151,8 +1063,8 @@ struct winbindd_methods sam_passdb_methods = {
        .lookup_usergroups     = sam_lookup_usergroups,
        .lookup_useraliases    = sam_lookup_useraliases,
        .lookup_groupmem       = sam_lookup_groupmem,
-       .sequence_number       = common_sequence_number,
-       .lockout_policy        = common_lockout_policy,
-       .password_policy       = common_password_policy,
+       .sequence_number       = sam_sequence_number,
+       .lockout_policy        = sam_lockout_policy,
+       .password_policy       = sam_password_policy,
        .trusted_domains       = sam_trusted_domains
 };