#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
goto done;
}
- status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
+ status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
goto done;
}
- status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
+ status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
goto done;
}
- status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
+ status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
struct dom_sid *sids = NULL;
enum lsa_SidType *types = NULL;
char *full_name = NULL;
+ const char *names[1];
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
char *mapped_name = NULL;
name_map_status = normalize_name_unmap(mem_ctx, full_name,
&mapped_name);
- /* Reset the full_name pointer if we mapped anytthing */
+ /* Reset the full_name pointer if we mapped anything */
if (NT_STATUS_IS_OK(name_map_status) ||
NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
full_name?full_name:"", domain_name ));
+ names[0] = full_name;
+
result = winbindd_lookup_names(mem_ctx, domain, 1,
- (const char **)&full_name, NULL,
+ names, NULL,
&sids, &types);
if (!NT_STATUS_IS_OK(result))
return result;
static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
const struct dom_sid *sid,
- uint32 *rids,
+ uint32_t *rids,
size_t num_rids,
char **domain_name,
char ***names,
DEBUG(3, ("msrpc_rids_to_names: domain %s\n", domain->name ));
if (num_rids) {
- sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
+ sids = talloc_array(mem_ctx, struct dom_sid, num_rids);
if (sids == NULL) {
return NT_STATUS_NO_MEMORY;
}
user_info->full_name = talloc_strdup(user_info,
user->base.full_name.string);
+ if (user_info->full_name == NULL) {
+ /* this might fail so we don't check the return code */
+ wcache_query_user_fullname(domain,
+ mem_ctx,
+ user_sid,
+ &user_info->full_name);
+ }
+
status = NT_STATUS_OK;
goto done;
}
}
/* no cache; hit the wire */
- status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
+ status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
}
/* no cache; hit the wire */
- status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
+ status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 num_sids, const struct dom_sid *sids,
- uint32 *pnum_aliases,
- uint32 **palias_rids)
+ uint32_t num_sids, const struct dom_sid *sids,
+ uint32_t *pnum_aliases,
+ uint32_t **palias_rids)
{
struct rpc_pipe_client *samr_pipe;
struct policy_handle dom_pol;
goto done;
}
- status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
+ status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
uint32_t **name_types)
{
NTSTATUS status, result;
- uint32 i, total_names = 0;
+ uint32_t i, total_names = 0;
struct policy_handle dom_pol, group_pol;
- uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
- uint32 *rid_mem = NULL;
- uint32 group_rid;
+ uint32_t des_access = SEC_FLAG_MAXIMUM_ALLOWED;
+ uint32_t *rid_mem = NULL;
+ uint32_t group_rid;
unsigned int j, r;
struct rpc_pipe_client *cli;
unsigned int orig_timeout;
*num_names = 0;
- result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
+ result = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol);
if (!NT_STATUS_IS_OK(result))
return result;
#define MAX_LOOKUP_RIDS 900
- *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
- *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
- *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, *num_names);
+ *names = talloc_zero_array(mem_ctx, char *, *num_names);
+ *name_types = talloc_zero_array(mem_ctx, uint32_t, *num_names);
+ *sid_mem = talloc_zero_array(mem_ctx, struct dom_sid, *num_names);
for (j=0;j<(*num_names);j++)
sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
/* Copy result into array. The talloc system will take
care of freeing the temporary arrays later on. */
- if (tmp_names.count != tmp_types.count) {
- return NT_STATUS_UNSUCCESSFUL;
+ if (tmp_names.count != num_lookup_rids) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ if (tmp_types.count != num_lookup_rids) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
for (r=0; r<tmp_names.count; r++) {
if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
continue;
}
+ if (total_names >= *num_names) {
+ break;
+ }
(*names)[total_names] = fill_domain_username_talloc(
mem_ctx, domain->name,
tmp_names.names[r].string, true);
#ifdef HAVE_LDAP
-#include <ldap.h>
+#include "ads.h"
-static int get_ldap_seq(const char *server, int port, uint32 *seq)
+static int get_ldap_seq(const char *server, struct sockaddr_storage *ss, int port, uint32_t *seq)
{
int ret = -1;
struct timeval to;
* search timeout doesn't seem to apply to doing an open as well. JRA.
*/
- ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
+ ldp = ldap_open_with_timeout(server, ss, port, lp_ldap_timeout());
if (ldp == NULL)
return -1;
to.tv_usec = 0;
if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
- CONST_DISCARD(char **, attrs), 0, &to, &res))
+ discard_const_p(char *, attrs), 0, &to, &res))
goto done;
if (ldap_count_entries(ldp, res) != 1)
LDAP queries.
**********************************************************************/
-static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
+static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32_t *seq)
{
int ret = -1;
char addr[INET6_ADDRSTRLEN];
print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
- if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
+ if ((ret = get_ldap_seq(addr, &domain->dcaddr, LDAP_PORT, seq)) == 0) {
DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
"number for Domain (%s) from DC (%s)\n",
domain->name, addr));
{
struct rpc_pipe_client *samr_pipe;
struct policy_handle dom_pol;
- uint32_t seq;
+ uint32_t seq = DOM_SEQUENCE_NONE;
TALLOC_CTX *tmp_ctx;
NTSTATUS status;
}
#endif /* HAVE_LDAP */
- status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
+ status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
}
status = cm_connect_lsa(domain, tmp_ctx, &lsa_pipe, &lsa_policy);
- if (!NT_STATUS_IS_OK(status))
- return status;
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
status = rpc_trusted_domains(tmp_ctx,
lsa_pipe,
return NT_STATUS_NOT_SUPPORTED;
}
- status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
+ status = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
return NT_STATUS_NOT_SUPPORTED;
}
- status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
+ status = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
return status;
}
-typedef NTSTATUS (*lookup_sids_fn_t)(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 winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
struct winbindd_domain *domain,
uint32_t num_sids,
enum lsa_SidType **types)
{
NTSTATUS status;
+ NTSTATUS result;
struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = 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);
+ 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.
* 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);
+ orig_timeout = dcerpc_binding_handle_set_timeout(b, 35000);
+
+ 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. */
- rpccli_set_timeout(cli, orig_timeout);
+ dcerpc_binding_handle_set_timeout(b, orig_timeout);
- if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
- NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
+ 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)) {
/*
* This can happen if the schannel key is not
* valid anymore, we need to invalidate the
* all connections to the dc and reestablish
* a netlogon connection first.
*/
- invalidate_cm_connection(&domain->conn);
+ invalidate_cm_connection(domain);
+ domain->can_do_ncacn_ip_tcp = domain->active_directory;
+ if (!retried) {
+ retried = true;
+ goto connect;
+ }
status = NT_STATUS_ACCESS_DENIED;
}
return status;
}
- return status;
+ if (!NT_STATUS_IS_OK(result)) {
+ return result;
+ }
+
+ return NT_STATUS_OK;
}
-typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx,
- struct policy_handle *pol,
- int num_names,
+static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
+ struct winbindd_domain *domain,
+ uint32_t num_names,
const char **names,
- const char ***dom_names,
- int level,
+ const char ***domains,
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)
+ enum lsa_SidType **types)
{
NTSTATUS status;
+ NTSTATUS result;
struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = NULL;
struct policy_handle lsa_policy;
unsigned int orig_timeout = 0;
- 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);
+ 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.
* 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);
+ orig_timeout = dcerpc_binding_handle_set_timeout(b, 35000);
+
+ 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. */
- rpccli_set_timeout(cli, orig_timeout);
+ dcerpc_binding_handle_set_timeout(b, orig_timeout);
- if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
- NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
+ 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)) {
/*
* This can happen if the schannel key is not
* valid anymore, we need to invalidate the
* all connections to the dc and reestablish
* a netlogon connection first.
*/
- invalidate_cm_connection(&domain->conn);
+ invalidate_cm_connection(domain);
+ if (!retried) {
+ retried = true;
+ goto connect;
+ }
status = NT_STATUS_ACCESS_DENIED;
}
return status;
}
- return status;
+ if (!NT_STATUS_IS_OK(result)) {
+ return result;
+ }
+
+ return NT_STATUS_OK;
}
/* the rpc backend methods are exposed via this structure */