diff -u -r --new-file --exclude .svn --exclude CVS samba-3.6.9/source3/rpc_client/cli_lsarpc.c samba-3.6.10/source3/rpc_client/cli_lsarpc.c --- samba-3.6.9/source3/rpc_client/cli_lsarpc.c 2012-10-29 10:05:46.000000000 +0100 +++ samba-3.6.10/source3/rpc_client/cli_lsarpc.c 2012-12-06 10:28:00.000000000 +0100 @@ -330,16 +330,16 @@ * at 20480 for win2k3, but we keep it at a save 1000 for now. */ #define LOOKUP_SIDS_HUNK_SIZE 1000 -static NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h, - TALLOC_CTX *mem_ctx, - struct policy_handle *pol, - int num_sids, - const struct dom_sid *sids, - char ***pdomains, - char ***pnames, - enum lsa_SidType **ptypes, - bool use_lookupsids3, - NTSTATUS *presult) +NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_sids, + const struct dom_sid *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes, + bool use_lookupsids3, + NTSTATUS *presult) { NTSTATUS status = NT_STATUS_OK; NTSTATUS result = NT_STATUS_OK; @@ -539,48 +539,19 @@ result); } -NTSTATUS rpccli_lsa_lookup_sids3(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - struct policy_handle *pol, - int num_sids, - const struct dom_sid *sids, - char ***pdomains, - char ***pnames, - enum lsa_SidType **ptypes) -{ - NTSTATUS status; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle, - mem_ctx, - pol, - num_sids, - sids, - pdomains, - pnames, - ptypes, - true, - &result); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - return result; -} - /** Lookup a list of names */ -static NTSTATUS dcerpc_lsa_lookup_names_generic(struct dcerpc_binding_handle *h, - TALLOC_CTX *mem_ctx, - struct policy_handle *pol, - uint32_t num_names, - const char **names, - const char ***dom_names, - enum lsa_LookupNamesLevel level, - struct dom_sid **sids, - enum lsa_SidType **types, - bool use_lookupnames4, - NTSTATUS *presult) +NTSTATUS dcerpc_lsa_lookup_names_generic(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + uint32_t num_names, + const char **names, + const char ***dom_names, + enum lsa_LookupNamesLevel level, + struct dom_sid **sids, + enum lsa_SidType **types, + bool use_lookupnames4, + NTSTATUS *presult) { NTSTATUS status; struct lsa_String *lsa_names = NULL; @@ -790,33 +761,3 @@ true, result); } - -NTSTATUS rpccli_lsa_lookup_names4(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 status; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - status = dcerpc_lsa_lookup_names4(cli->binding_handle, - mem_ctx, - pol, - num_names, - names, - dom_names, - level, - sids, - types, - &result); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - return result; -} diff -u -r --new-file --exclude .svn --exclude CVS samba-3.6.9/source3/rpc_client/cli_lsarpc.h samba-3.6.10/source3/rpc_client/cli_lsarpc.h --- samba-3.6.9/source3/rpc_client/cli_lsarpc.h 2012-10-29 10:05:46.000000000 +0100 +++ samba-3.6.10/source3/rpc_client/cli_lsarpc.h 2012-12-06 10:28:00.000000000 +0100 @@ -125,7 +125,16 @@ char ***pdomains, char ***pnames, enum lsa_SidType **ptypes); - +NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_sids, + const struct dom_sid *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes, + bool use_lookupsids3, + NTSTATUS *presult); /** * @brief Look up the names that correspond to an array of sids. * @@ -158,15 +167,6 @@ char ***pnames, enum lsa_SidType **ptypes, NTSTATUS *result); -NTSTATUS rpccli_lsa_lookup_sids3(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - struct policy_handle *pol, - int num_sids, - const struct dom_sid *sids, - char ***pdomains, - char ***pnames, - enum lsa_SidType **ptypes); - NTSTATUS dcerpc_lsa_lookup_names(struct dcerpc_binding_handle *h, TALLOC_CTX *mem_ctx, struct policy_handle *pol, @@ -196,14 +196,17 @@ struct dom_sid **sids, enum lsa_SidType **types, NTSTATUS *result); -NTSTATUS rpccli_lsa_lookup_names4(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 dcerpc_lsa_lookup_names_generic(struct dcerpc_binding_handle *h, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + uint32_t num_names, + const char **names, + const char ***dom_names, + enum lsa_LookupNamesLevel level, + struct dom_sid **sids, + enum lsa_SidType **types, + bool use_lookupnames4, + NTSTATUS *presult); bool fetch_domain_sid( char *domain, char *remote_machine, struct dom_sid *psid); diff -u -r --new-file --exclude .svn --exclude CVS samba-3.6.9/source3/winbindd/winbindd_cm.c samba-3.6.10/source3/winbindd/winbindd_cm.c --- samba-3.6.9/source3/winbindd/winbindd_cm.c 2012-10-29 10:05:46.000000000 +0100 +++ samba-3.6.10/source3/winbindd/winbindd_cm.c 2012-12-06 10:28:00.000000000 +0100 @@ -1602,6 +1602,10 @@ result = cm_prepare_connection(domain, fd, domain->dcname, &new_conn->cli, &retry); + if (!NT_STATUS_IS_OK(result)) { + /* Don't leak the smb connection socket */ + close(fd); + } if (!retry) break; @@ -2564,6 +2568,37 @@ } /**************************************************************************** +Open a LSA connection to a DC, suiteable for LSA lookup calls. +****************************************************************************/ + +NTSTATUS cm_connect_lsat(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + struct rpc_pipe_client **cli, + struct policy_handle *lsa_policy) +{ + NTSTATUS status; + + if (domain->can_do_ncacn_ip_tcp) { + status = cm_connect_lsa_tcp(domain, mem_ctx, cli); + if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || + NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) || + NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) { + invalidate_cm_connection(&domain->conn); + status = cm_connect_lsa_tcp(domain, mem_ctx, cli); + } + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; + } + + status = cm_connect_lsa(domain, mem_ctx, cli, lsa_policy); + + return status; +} + +/**************************************************************************** Open the netlogon pipe to this DC. Use schannel if specified in client conf. session key stored in conn->netlogon_pipe->dc->sess_key. ****************************************************************************/ diff -u -r --new-file --exclude .svn --exclude CVS samba-3.6.9/source3/winbindd/winbindd_msrpc.c samba-3.6.10/source3/winbindd/winbindd_msrpc.c --- samba-3.6.9/source3/winbindd/winbindd_msrpc.c 2012-10-29 10:05:46.000000000 +0100 +++ samba-3.6.10/source3/winbindd/winbindd_msrpc.c 2012-12-06 10:28:00.000000000 +0100 @@ -35,6 +35,13 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND +static 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); /* Query display info for a domain. This returns enough information plus a bit extra to give an overview of domain users for the User Manager @@ -1057,16 +1064,6 @@ return status; } -typedef NTSTATUS (*lookup_sids_fn_t)(struct dcerpc_binding_handle *h, - TALLOC_CTX *mem_ctx, - struct policy_handle *pol, - int num_sids, - const struct dom_sid *sids, - char ***pdomains, - char ***pnames, - enum lsa_SidType **ptypes, - NTSTATUS *result); - NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, uint32_t num_sids, @@ -1081,25 +1078,21 @@ struct dcerpc_binding_handle *b = NULL; struct policy_handle lsa_policy; unsigned int orig_timeout; - lookup_sids_fn_t lookup_sids_fn = dcerpc_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 = dcerpc_lsa_lookup_sids3; - goto lookup; - } - domain->can_do_ncacn_ip_tcp = false; - } - status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); + bool use_lookupsids3 = false; + bool retried = false; + connect: + status = cm_connect_lsat(domain, mem_ctx, &cli, &lsa_policy); if (!NT_STATUS_IS_OK(status)) { return status; } - lookup: b = cli->binding_handle; + if (cli->transport->transport == NCACN_IP_TCP) { + use_lookupsids3 = true; + } + /* * This call can take a long time * allow the server to time out. @@ -1107,21 +1100,23 @@ */ orig_timeout = dcerpc_binding_handle_set_timeout(b, 35000); - status = lookup_sids_fn(b, - mem_ctx, - &lsa_policy, - num_sids, - sids, - domains, - names, - types, - &result); + status = dcerpc_lsa_lookup_sids_generic(b, + mem_ctx, + &lsa_policy, + num_sids, + sids, + domains, + names, + types, + use_lookupsids3, + &result); /* And restore our original timeout. */ dcerpc_binding_handle_set_timeout(b, orig_timeout); if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || - NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) { + NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) || + NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) { /* * This can happen if the schannel key is not * valid anymore, we need to invalidate the @@ -1129,6 +1124,11 @@ * a netlogon connection first. */ invalidate_cm_connection(&domain->conn); + domain->can_do_ncacn_ip_tcp = domain->active_directory; + if (!retried) { + retried = true; + goto connect; + } status = NT_STATUS_ACCESS_DENIED; } @@ -1143,24 +1143,13 @@ return NT_STATUS_OK; } -typedef NTSTATUS (*lookup_names_fn_t)(struct dcerpc_binding_handle *h, - TALLOC_CTX *mem_ctx, - struct policy_handle *pol, +static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, + struct winbindd_domain *domain, uint32_t num_names, const char **names, - const char ***dom_names, - enum lsa_LookupNamesLevel level, + const char ***domains, struct dom_sid **sids, - enum lsa_SidType **types, - NTSTATUS *result); - -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) + enum lsa_SidType **types) { NTSTATUS status; NTSTATUS result; @@ -1168,25 +1157,21 @@ struct dcerpc_binding_handle *b = NULL; struct policy_handle lsa_policy; unsigned int orig_timeout = 0; - lookup_names_fn_t lookup_names_fn = dcerpc_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 = dcerpc_lsa_lookup_names4; - goto lookup; - } - domain->can_do_ncacn_ip_tcp = false; - } - status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); + bool use_lookupnames4 = false; + bool retried = false; + connect: + status = cm_connect_lsat(domain, mem_ctx, &cli, &lsa_policy); if (!NT_STATUS_IS_OK(status)) { return status; } - lookup: b = cli->binding_handle; + if (cli->transport->transport == NCACN_IP_TCP) { + use_lookupnames4 = true; + } + /* * This call can take a long time * allow the server to time out. @@ -1194,22 +1179,24 @@ */ orig_timeout = dcerpc_binding_handle_set_timeout(b, 35000); - status = lookup_names_fn(b, - mem_ctx, - &lsa_policy, - num_names, - (const char **) names, - domains, - 1, - sids, - types, - &result); + status = dcerpc_lsa_lookup_names_generic(b, + mem_ctx, + &lsa_policy, + num_names, + (const char **) names, + domains, + 1, + sids, + types, + use_lookupnames4, + &result); /* And restore our original timeout. */ dcerpc_binding_handle_set_timeout(b, orig_timeout); if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || - NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) { + NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) || + NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) { /* * This can happen if the schannel key is not * valid anymore, we need to invalidate the @@ -1217,6 +1204,10 @@ * a netlogon connection first. */ invalidate_cm_connection(&domain->conn); + if (!retried) { + retried = true; + goto connect; + } status = NT_STATUS_ACCESS_DENIED; } diff -u -r --new-file --exclude .svn --exclude CVS samba-3.6.9/source3/winbindd/winbindd_proto.h samba-3.6.10/source3/winbindd/winbindd_proto.h --- samba-3.6.9/source3/winbindd/winbindd_proto.h 2012-10-29 10:05:46.000000000 +0100 +++ samba-3.6.10/source3/winbindd/winbindd_proto.h 2012-12-06 10:28:00.000000000 +0100 @@ -47,13 +47,6 @@ char ***domains, char ***names, 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 rpc_lookup_sids(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, struct lsa_SidArray *sids, @@ -170,6 +163,10 @@ NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, struct rpc_pipe_client **cli); +NTSTATUS cm_connect_lsat(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + struct rpc_pipe_client **cli, + struct policy_handle *lsa_policy); NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, struct rpc_pipe_client **cli); bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx, diff -u -r --new-file --exclude .svn --exclude CVS samba-3.6.9/source3/winbindd/winbindd_rpc.c samba-3.6.10/source3/winbindd/winbindd_rpc.c --- samba-3.6.9/source3/winbindd/winbindd_rpc.c 2012-10-29 10:05:46.000000000 +0100 +++ samba-3.6.10/source3/winbindd/winbindd_rpc.c 2012-12-06 10:28:00.000000000 +0100 @@ -1033,6 +1033,7 @@ static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, + struct rpc_pipe_client *cli, struct lsa_SidArray *sids, struct lsa_RefDomainList **pdomains, struct lsa_TransNameArray **pnames) @@ -1040,15 +1041,8 @@ struct lsa_TransNameArray2 lsa_names2; struct lsa_TransNameArray *names; uint32_t i, count; - struct rpc_pipe_client *cli; NTSTATUS status, result; - status = cm_connect_lsa_tcp(domain, talloc_tos(), &cli); - if (!NT_STATUS_IS_OK(status)) { - domain->can_do_ncacn_ip_tcp = false; - return status; - } - ZERO_STRUCT(lsa_names2); status = dcerpc_lsa_LookupSids3(cli->binding_handle, mem_ctx, @@ -1098,19 +1092,16 @@ uint32_t count; NTSTATUS status, result; - if (domain->can_do_ncacn_ip_tcp) { - status = rpc_try_lookup_sids3(mem_ctx, domain, sids, - pdomains, pnames); - if (!NT_STATUS_IS_ERR(status)) { - return status; - } - } - - status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); + status = cm_connect_lsat(domain, mem_ctx, &cli, &lsa_policy); if (!NT_STATUS_IS_OK(status)) { return status; } + if (cli->transport->transport == NCACN_IP_TCP) { + return rpc_try_lookup_sids3(mem_ctx, domain, cli, sids, + pdomains, pnames); + } + names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray); if (names == NULL) { return NT_STATUS_NO_MEMORY;