#include "includes.h"
#include "winbindd.h"
#include "winbindd_rpc.h"
+#include "lib/util_unixsids.h"
#include "rpc_client/rpc_client.h"
+#include "rpc_client/cli_pipe.h"
#include "../librpc/gen_ndr/ndr_samr_c.h"
#include "rpc_client/cli_samr.h"
#include "../librpc/gen_ndr/ndr_lsa_c.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)
-{
- struct rpc_pipe_client *cli = NULL;
- struct auth_session_info *session_info = NULL;
- NTSTATUS status;
-
- status = make_session_info_system(mem_ctx, &session_info);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("open_samr_pipe: Could not create auth_session_info: %s\n",
- nt_errstr(status)));
- return status;
- }
-
- /* create a samr connection */
- if (lp_parm_bool(-1, "winbindd", "use external pipes", false)) {
- status = rpc_pipe_open_interface(mem_ctx,
- &ndr_table_samr,
- session_info,
- NULL,
- winbind_messaging_context(),
- &cli);
- } else {
- status = rpc_pipe_open_internal(mem_ctx,
- &ndr_table_samr.syntax_id,
- session_info,
- NULL,
- winbind_messaging_context(),
- &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;
- }
-
- if (samr_pipe) {
- *samr_pipe = cli;
- }
+/*
+ * The other end of this won't go away easily, so we can trust it
+ *
+ * It is either a long-lived process with the same lifetime as
+ * winbindd or a part of this process
+ */
+struct winbind_internal_pipes {
+ struct rpc_pipe_client *samr_pipe;
+ struct policy_handle samr_domain_hnd;
+ struct rpc_pipe_client *lsa_pipe;
+ struct policy_handle lsa_hnd;
+};
- return NT_STATUS_OK;
-}
NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
struct winbindd_domain *domain,
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;
}
return result;
}
-static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
- struct rpc_pipe_client **lsa_pipe)
+NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
+ struct rpc_pipe_client **lsa_pipe,
+ struct policy_handle *lsa_hnd)
{
- struct rpc_pipe_client *cli = NULL;
- struct auth_session_info *session_info = NULL;
NTSTATUS status;
- status = make_session_info_system(mem_ctx, &session_info);
+ status = wb_open_internal_pipe(mem_ctx, &ndr_table_lsarpc, lsa_pipe);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("open_lsa_pipe: Could not create auth_session_info: %s\n",
- nt_errstr(status)));
return status;
}
- /* create a lsa connection */
- if (lp_parm_bool(-1, "winbindd", "use external pipes", false)) {
- status = rpc_pipe_open_interface(mem_ctx,
- &ndr_table_lsarpc,
- session_info,
- NULL,
- winbind_messaging_context(),
- &cli);
- } else {
- status = rpc_pipe_open_internal(mem_ctx,
- &ndr_table_lsarpc.syntax_id,
- session_info,
- NULL,
- winbind_messaging_context(),
- &cli);
+ status = rpccli_lsa_open_policy((*lsa_pipe),
+ mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ lsa_hnd);
+
+ return status;
+}
+
+
+static NTSTATUS open_cached_internal_pipe_conn(
+ struct winbindd_domain *domain,
+ struct rpc_pipe_client **samr_pipe,
+ struct policy_handle *samr_domain_hnd,
+ struct rpc_pipe_client **lsa_pipe,
+ struct policy_handle *lsa_hnd)
+{
+ struct winbind_internal_pipes *internal_pipes = NULL;
+
+ if (domain->private_data == NULL) {
+ TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status;
+
+ internal_pipes = talloc_zero(frame,
+ struct winbind_internal_pipes);
+
+ status = open_internal_samr_conn(
+ internal_pipes,
+ domain,
+ &internal_pipes->samr_pipe,
+ &internal_pipes->samr_domain_hnd);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
+ return status;
+ }
+
+ status = open_internal_lsa_conn(internal_pipes,
+ &internal_pipes->lsa_pipe,
+ &internal_pipes->lsa_hnd);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
+ return status;
+ }
+
+ domain->private_data = talloc_move(domain, &internal_pipes);
+
+ TALLOC_FREE(frame);
+
}
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
- nt_errstr(status)));
- return status;
+
+ internal_pipes = talloc_get_type_abort(
+ domain->private_data, struct winbind_internal_pipes);
+
+ if (samr_domain_hnd) {
+ *samr_domain_hnd = internal_pipes->samr_domain_hnd;
+ }
+
+ if (samr_pipe) {
+ *samr_pipe = internal_pipes->samr_pipe;
+ }
+
+ if (lsa_hnd) {
+ *lsa_hnd = internal_pipes->lsa_hnd;
}
if (lsa_pipe) {
- *lsa_pipe = cli;
+ *lsa_pipe = internal_pipes->lsa_pipe;
}
return NT_STATUS_OK;
}
-static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
- struct rpc_pipe_client **lsa_pipe,
- struct policy_handle *lsa_hnd)
+static bool reset_connection_on_error(struct winbindd_domain *domain,
+ struct rpc_pipe_client *p,
+ NTSTATUS status)
{
- NTSTATUS status;
+ struct winbind_internal_pipes *internal_pipes = NULL;
- status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ internal_pipes = talloc_get_type_abort(
+ domain->private_data, struct winbind_internal_pipes);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR))
+ {
+ TALLOC_FREE(internal_pipes);
+ domain->private_data = NULL;
+ return true;
}
- status = rpccli_lsa_open_policy((*lsa_pipe),
- mem_ctx,
- true,
- SEC_FLAG_MAXIMUM_ALLOWED,
- lsa_hnd);
+ if (!rpccli_is_connected(p)) {
+ TALLOC_FREE(internal_pipes);
+ domain->private_data = NULL;
+ return true;
+ }
- return status;
+ return false;
}
/*********************************************************************
struct wb_acct_info **pinfo)
{
struct rpc_pipe_client *samr_pipe;
- struct policy_handle dom_pol;
+ struct policy_handle dom_pol = { 0 };
struct wb_acct_info *info = NULL;
uint32_t num_info = 0;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("sam_enum_dom_groups\n"));
- ZERO_STRUCT(dom_pol);
-
if (pnum_info) {
*pnum_info = 0;
}
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ &samr_pipe,
+ &dom_pol,
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
- goto error;
+ TALLOC_FREE(tmp_ctx);
+ return status;
}
- b = samr_pipe->binding_handle;
-
status = rpc_enum_dom_groups(tmp_ctx,
samr_pipe,
&dom_pol,
&num_info,
&info);
+
+ if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
- goto error;
+ TALLOC_FREE(tmp_ctx);
+ return status;
}
if (pnum_info) {
*pinfo = talloc_move(mem_ctx, &info);
}
-error:
- if (b && is_valid_policy_hnd(&dom_pol)) {
- dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
- }
TALLOC_FREE(tmp_ctx);
return status;
}
/* Query display info for a domain */
static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32_t *pnum_info,
- struct wbint_userinfo **pinfo)
+ uint32_t **prids)
{
struct rpc_pipe_client *samr_pipe = NULL;
- struct policy_handle dom_pol;
- struct wbint_userinfo *info = NULL;
- uint32_t num_info = 0;
+ struct policy_handle dom_pol = { 0 };
+ uint32_t *rids = NULL;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("samr_query_user_list\n"));
- ZERO_STRUCT(dom_pol);
-
- if (pnum_info) {
- *pnum_info = 0;
- }
-
tmp_ctx = talloc_stackframe();
if (tmp_ctx == NULL) {
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ &samr_pipe,
+ &dom_pol,
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = samr_pipe->binding_handle;
-
status = rpc_query_user_list(tmp_ctx,
samr_pipe,
&dom_pol,
&domain->sid,
- &num_info,
- &info);
- if (!NT_STATUS_IS_OK(status)) {
- goto done;
+ &rids);
+ if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+ retry = true;
+ goto again;
}
- if (pnum_info) {
- *pnum_info = num_info;
- }
-
- if (pinfo) {
- *pinfo = talloc_move(mem_ctx, &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;
-}
-
-/* Lookup user information from a rid or username. */
-static NTSTATUS sam_query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const struct dom_sid *user_sid,
- struct wbint_userinfo *user_info)
-{
- struct rpc_pipe_client *samr_pipe;
- struct policy_handle dom_pol;
- TALLOC_CTX *tmp_ctx;
- 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_sam(user_sid)) {
- return NT_STATUS_NO_SUCH_USER;
- }
-
- user_info->homedir = NULL;
- user_info->shell = NULL;
- user_info->primary_gid = (gid_t) -1;
-
- tmp_ctx = talloc_stackframe();
- if (tmp_ctx == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = samr_pipe->binding_handle;
-
- status = rpc_query_user(tmp_ctx,
- samr_pipe,
- &dom_pol,
- &domain->sid,
- user_sid,
- user_info);
-
-done:
- if (b && is_valid_policy_hnd(&dom_pol)) {
- dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
+ if (prids != NULL) {
+ *prids = talloc_move(mem_ctx, &rids);
}
+done:
+ TALLOC_FREE(rids);
TALLOC_FREE(tmp_ctx);
return status;
}
struct netr_DomainTrustList *ptrust_list)
{
struct rpc_pipe_client *lsa_pipe;
- struct policy_handle lsa_policy;
+ struct policy_handle lsa_policy = { 0 };
struct netr_DomainTrust *trusts = NULL;
uint32_t num_trusts = 0;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("samr: trusted domains\n"));
- ZERO_STRUCT(lsa_policy);
-
if (ptrust_list) {
ZERO_STRUCTP(ptrust_list);
}
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ NULL,
+ NULL,
+ &lsa_pipe,
+ &lsa_policy);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = lsa_pipe->binding_handle;
-
status = rpc_trusted_domains(tmp_ctx,
lsa_pipe,
&lsa_policy,
&num_trusts,
&trusts);
+
+ if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
}
done:
- if (b && is_valid_policy_hnd(&lsa_policy)) {
- dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
- }
-
TALLOC_FREE(tmp_ctx);
return status;
}
uint32_t **pname_types)
{
struct rpc_pipe_client *samr_pipe;
- struct policy_handle dom_pol;
+ struct policy_handle dom_pol = { 0 };
uint32_t num_names = 0;
struct dom_sid *sid_mem = NULL;
uint32_t *name_types = NULL;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("sam_lookup_groupmem\n"));
- 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_MEMORY;
}
- status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ &samr_pipe,
+ &dom_pol,
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = samr_pipe->binding_handle;
-
status = rpc_lookup_groupmem(tmp_ctx,
samr_pipe,
&dom_pol,
&names,
&name_types);
+ if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (pnum_names) {
*pnum_names = num_names;
}
}
done:
- if (b && is_valid_policy_hnd(&dom_pol)) {
- dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
- }
-
TALLOC_FREE(tmp_ctx);
return status;
}
/* List all domain groups */
static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32_t *num_entries,
struct wb_acct_info **info)
{
/* BUILTIN doesn't have domain groups */
/* Query display info for a domain */
static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct wbint_userinfo **info)
+ uint32_t **rids)
{
/* We don't have users */
- *num_entries = 0;
- *info = NULL;
+ *rids = NULL;
return NT_STATUS_OK;
}
-/* Lookup user information from a rid or username. */
-static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const struct dom_sid *user_sid,
- struct wbint_userinfo *user_info)
-{
- return NT_STATUS_NO_SUCH_USER;
-}
-
/* get a list of trusted domains - builtin domain */
static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
struct wb_acct_info **pinfo)
{
struct rpc_pipe_client *samr_pipe;
- struct policy_handle dom_pol;
+ struct policy_handle dom_pol = { 0 };
struct wb_acct_info *info = NULL;
uint32_t num_info = 0;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("samr: enum local groups\n"));
- ZERO_STRUCT(dom_pol);
-
if (pnum_info) {
*pnum_info = 0;
}
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ &samr_pipe,
+ &dom_pol,
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = samr_pipe->binding_handle;
-
status = rpc_enum_local_groups(mem_ctx,
samr_pipe,
&dom_pol,
&num_info,
+
&info);
+ if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
}
done:
- if (b && is_valid_policy_hnd(&dom_pol)) {
- dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
- }
-
TALLOC_FREE(tmp_ctx);
return status;
}
enum lsa_SidType *ptype)
{
struct rpc_pipe_client *lsa_pipe;
- struct policy_handle lsa_policy;
+ struct policy_handle lsa_policy = { 0 };
struct dom_sid sid;
enum lsa_SidType type;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("sam_name_to_sid\n"));
- ZERO_STRUCT(lsa_policy);
-
tmp_ctx = talloc_stackframe();
if (tmp_ctx == NULL) {
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ NULL,
+ NULL,
+ &lsa_pipe,
+ &lsa_policy);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = lsa_pipe->binding_handle;
-
status = rpc_name_to_sid(tmp_ctx,
lsa_pipe,
&lsa_policy,
flags,
&sid,
&type);
+
+ if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
}
done:
- if (b && is_valid_policy_hnd(&lsa_policy)) {
- dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
- }
-
TALLOC_FREE(tmp_ctx);
return status;
}
enum lsa_SidType *ptype)
{
struct rpc_pipe_client *lsa_pipe;
- struct policy_handle lsa_policy;
+ struct policy_handle lsa_policy = { 0 };
char *domain_name = NULL;
char *name = NULL;
enum lsa_SidType type;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("sam_sid_to_name\n"));
- ZERO_STRUCT(lsa_policy);
-
/* Paranoia check */
if (!sid_check_is_in_builtin(sid) &&
!sid_check_is_builtin(sid) &&
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ NULL,
+ NULL,
+ &lsa_pipe,
+ &lsa_policy);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = lsa_pipe->binding_handle;
-
status = rpc_sid_to_name(tmp_ctx,
lsa_pipe,
&lsa_policy,
&name,
&type);
+ if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (ptype) {
*ptype = type;
}
}
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 *domain_sid,
- uint32 *rids,
+ uint32_t *rids,
size_t num_rids,
char **pdomain_name,
char ***pnames,
enum lsa_SidType **ptypes)
{
struct rpc_pipe_client *lsa_pipe;
- struct policy_handle lsa_policy;
+ struct policy_handle lsa_policy = { 0 };
enum lsa_SidType *types = NULL;
char *domain_name = NULL;
char **names = NULL;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
- ZERO_STRUCT(lsa_policy);
-
/* Paranoia check */
if (!sid_check_is_builtin(domain_sid) &&
!sid_check_is_our_sam(domain_sid) &&
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ NULL,
+ NULL,
+ &lsa_pipe,
+ &lsa_policy);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = lsa_pipe->binding_handle;
-
status = rpc_rids_to_names(tmp_ctx,
lsa_pipe,
&lsa_policy,
&domain_name,
&names,
&types);
+
+ if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
}
done:
- if (b && is_valid_policy_hnd(&lsa_policy)) {
- dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
- }
-
TALLOC_FREE(tmp_ctx);
return status;
}
struct samr_DomInfo12 *lockout_policy)
{
struct rpc_pipe_client *samr_pipe;
- struct policy_handle dom_pol;
+ struct policy_handle dom_pol = { 0 };
union samr_DomainInfo *info = NULL;
TALLOC_CTX *tmp_ctx;
NTSTATUS status, result;
struct dcerpc_binding_handle *b = NULL;
+ bool retry = false;
DEBUG(3,("sam_lockout_policy\n"));
- ZERO_STRUCT(dom_pol);
-
tmp_ctx = talloc_stackframe();
if (tmp_ctx == NULL) {
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ &samr_pipe,
+ &dom_pol,
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
goto error;
}
DomainLockoutInformation,
&info,
&result);
+
+ if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
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;
}
struct samr_DomInfo1 *passwd_policy)
{
struct rpc_pipe_client *samr_pipe;
- struct policy_handle dom_pol;
+ struct policy_handle dom_pol = { 0 };
union samr_DomainInfo *info = NULL;
TALLOC_CTX *tmp_ctx;
NTSTATUS status, result;
struct dcerpc_binding_handle *b = NULL;
+ bool retry = false;
DEBUG(3,("sam_password_policy\n"));
- ZERO_STRUCT(dom_pol);
-
tmp_ctx = talloc_stackframe();
if (tmp_ctx == NULL) {
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ &samr_pipe,
+ &dom_pol,
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
goto error;
}
DomainPasswordInformation,
&info,
&result);
+
+ if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
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;
}
struct dom_sid *user_grpsids = NULL;
uint32_t num_groups = 0;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("sam_lookup_usergroups\n"));
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ &samr_pipe,
+ &dom_pol,
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = samr_pipe->binding_handle;
-
status = rpc_lookup_usergroups(tmp_ctx,
samr_pipe,
&dom_pol,
user_sid,
&num_groups,
&user_grpsids);
+
+ if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
}
done:
- if (b && is_valid_policy_hnd(&dom_pol)) {
- dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
- }
TALLOC_FREE(tmp_ctx);
return status;
uint32_t **palias_rids)
{
struct rpc_pipe_client *samr_pipe;
- struct policy_handle dom_pol;
+ struct policy_handle dom_pol = { 0 };
uint32_t num_aliases = 0;
uint32_t *alias_rids = NULL;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("sam_lookup_useraliases\n"));
- ZERO_STRUCT(dom_pol);
-
if (pnum_aliases) {
*pnum_aliases = 0;
}
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ &samr_pipe,
+ &dom_pol,
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = samr_pipe->binding_handle;
-
status = rpc_lookup_useraliases(tmp_ctx,
samr_pipe,
&dom_pol,
sids,
&num_aliases,
&alias_rids);
+
+ if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
}
done:
- if (b && is_valid_policy_hnd(&dom_pol)) {
- dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
- }
TALLOC_FREE(tmp_ctx);
return status;
uint32_t *pseq)
{
struct rpc_pipe_client *samr_pipe;
- struct policy_handle dom_pol;
- uint32_t seq;
+ struct policy_handle dom_pol = { 0 };
+ uint32_t seq = DOM_SEQUENCE_NONE;
TALLOC_CTX *tmp_ctx;
- NTSTATUS status, result;
- struct dcerpc_binding_handle *b = NULL;
+ NTSTATUS status;
+ bool retry = false;
DEBUG(3,("samr: sequence number\n"));
- ZERO_STRUCT(dom_pol);
-
if (pseq) {
*pseq = DOM_SEQUENCE_NONE;
}
return NT_STATUS_NO_MEMORY;
}
- status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ &samr_pipe,
+ &dom_pol,
+ NULL,
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = samr_pipe->binding_handle;
-
status = rpc_sequence_number(tmp_ctx,
samr_pipe,
&dom_pol,
domain->name,
&seq);
+
+ if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
if (pseq) {
*pseq = seq;
}
-done:
- if (b && is_valid_policy_hnd(&dom_pol)) {
- dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
- }
+done:
TALLOC_FREE(tmp_ctx);
return status;
}
.name_to_sid = sam_name_to_sid,
.sid_to_name = sam_sid_to_name,
.rids_to_names = sam_rids_to_names,
- .query_user = builtin_query_user,
.lookup_usergroups = sam_lookup_usergroups,
.lookup_useraliases = sam_lookup_useraliases,
.lookup_groupmem = sam_lookup_groupmem,
.name_to_sid = sam_name_to_sid,
.sid_to_name = sam_sid_to_name,
.rids_to_names = sam_rids_to_names,
- .query_user = sam_query_user,
.lookup_usergroups = sam_lookup_usergroups,
.lookup_useraliases = sam_lookup_useraliases,
.lookup_groupmem = sam_lookup_groupmem,