struct dom_sid **sid_mem, char ***names,
uint32_t **name_types);
+ /* find all members of the alias with the specified alias_sid */
+ NTSTATUS (*lookup_aliasmem)(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const struct dom_sid *alias_sid,
+ enum lsa_SidType type,
+ uint32_t *num_sids,
+ struct dom_sid **sid_mem);
+
/* return the lockout policy */
NTSTATUS (*lockout_policy)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
return status;
}
+static NTSTATUS lookup_aliasmem(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const struct dom_sid *sid,
+ enum lsa_SidType type,
+ uint32_t *num_sids,
+ struct dom_sid **sids)
+{
+ char **names = NULL;
+ uint32_t *name_types = NULL;
+ struct dom_sid_buf buf;
+
+ DBG_DEBUG("ads: lookup_aliasmem %s sid=%s\n",
+ domain->name,
+ dom_sid_str_buf(sid, &buf));
+ /* Search for alias and group membership uses the same LDAP command. */
+ return lookup_groupmem(domain,
+ mem_ctx,
+ sid,
+ type,
+ num_sids,
+ sids,
+ &names,
+ &name_types);
+}
+
/* find the lockout policy of a domain - use rpc methods */
static NTSTATUS lockout_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
lookup_usergroups,
lookup_useraliases,
lookup_groupmem,
+ lookup_aliasmem,
lockout_policy,
password_policy,
trusted_domains,
return status;
}
+/* lookup alias membership */
+static NTSTATUS msrpc_lookup_aliasmem(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const struct dom_sid *alias_sid,
+ enum lsa_SidType type,
+ uint32_t *pnum_sids,
+ struct dom_sid **sid_mem)
+{
+ struct rpc_pipe_client *samr_pipe = NULL;
+ struct policy_handle dom_pol;
+ struct dom_sid *alias_members = NULL;
+ struct dom_sid_buf buf;
+ uint32_t num_groups = 0;
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ NTSTATUS status;
+
+ D_INFO("Lookup alias members in domain=%s for sid=%s.\n",
+ domain->name,
+ dom_sid_str_buf(alias_sid, &buf));
+
+ *pnum_sids = 0;
+
+ if (!winbindd_can_contact_domain(domain)) {
+ D_DEBUG("No incoming trust for domain %s\n", domain->name);
+ status = NT_STATUS_OK;
+ goto done;
+ }
+
+ status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpc_lookup_aliasmem(tmp_ctx,
+ samr_pipe,
+ &dom_pol,
+ &domain->sid,
+ alias_sid,
+ type,
+ &num_groups,
+ &alias_members);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ *pnum_sids = num_groups;
+ if (sid_mem) {
+ *sid_mem = talloc_move(mem_ctx, &alias_members);
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ return status;
+}
/* Lookup group membership given a rid. */
static NTSTATUS msrpc_lookup_groupmem(struct winbindd_domain *domain,
msrpc_lookup_usergroups,
msrpc_lookup_useraliases,
msrpc_lookup_groupmem,
+ msrpc_lookup_aliasmem,
msrpc_lockout_policy,
msrpc_password_policy,
msrpc_trusted_domains,
return result;
}
+/* Lookup alias membership given */
+static NTSTATUS lookup_aliasmem(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const struct dom_sid *sid,
+ enum lsa_SidType type,
+ uint32_t *num_sids,
+ struct dom_sid **sids)
+{
+ NTSTATUS result;
+
+ result = msrpc_methods.lookup_aliasmem(domain,
+ mem_ctx,
+ sid,
+ type,
+ num_sids,
+ sids);
+
+ if (reconnect_need_retry(result, domain))
+ result = msrpc_methods.lookup_aliasmem(domain,
+ mem_ctx,
+ sid,
+ type,
+ num_sids,
+ sids);
+
+ return result;
+}
+
/* Lookup group membership given a rid. */
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
lookup_usergroups,
lookup_useraliases,
lookup_groupmem,
+ lookup_aliasmem,
lockout_policy,
password_policy,
trusted_domains,
return result;
}
+static NTSTATUS lookup_aliasmem(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const struct dom_sid *group_sid,
+ enum lsa_SidType type,
+ uint32_t *num_names,
+ struct dom_sid **sid_mem)
+{
+ NTSTATUS result = NT_STATUS_OK;
+
+ result = ads_methods.lookup_aliasmem(domain,
+ mem_ctx,
+ group_sid,
+ type,
+ num_names,
+ sid_mem);
+
+ if (ldap_reconnect_need_retry(result, domain)) {
+ result = ads_methods.lookup_aliasmem(domain,
+ mem_ctx,
+ group_sid,
+ type,
+ num_names,
+ sid_mem);
+ }
+ return result;
+}
+
/* find the lockout policy of a domain */
static NTSTATUS lockout_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
lookup_usergroups,
lookup_useraliases,
lookup_groupmem,
+ lookup_aliasmem,
lockout_policy,
password_policy,
trusted_domains,
return NT_STATUS_OK;
}
+/* Lookup alias membership using a rid taken from alias_sid. */
+NTSTATUS rpc_lookup_aliasmem(TALLOC_CTX *mem_ctx,
+ struct rpc_pipe_client *samr_pipe,
+ struct policy_handle *samr_policy,
+ const struct dom_sid *domain_sid,
+ const struct dom_sid *alias_sid,
+ enum lsa_SidType type,
+ uint32_t *pnum_sids,
+ struct dom_sid **psids)
+{
+ uint32_t alias_rid;
+ struct dom_sid *sid_mem = NULL;
+ struct lsa_SidArray sid_array;
+ uint32_t i;
+ NTSTATUS status, result;
+ struct dcerpc_binding_handle *b = samr_pipe->binding_handle;
+
+ if (!sid_peek_check_rid(domain_sid, alias_sid, &alias_rid)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ switch (type) {
+ case SID_NAME_ALIAS: {
+ struct policy_handle alias_policy;
+
+ status = dcerpc_samr_OpenAlias(b,
+ mem_ctx,
+ samr_policy,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ alias_rid,
+ &alias_policy,
+ &result);
+ if (any_nt_status_not_ok(status, result, &status)) {
+ return status;
+ }
+
+ status = dcerpc_samr_GetMembersInAlias(b,
+ mem_ctx,
+ &alias_policy,
+ &sid_array,
+ &result);
+ {
+ NTSTATUS _result;
+ dcerpc_samr_Close(b, mem_ctx, &alias_policy, &_result);
+ }
+ if (any_nt_status_not_ok(status, result, &status)) {
+ return status;
+ }
+
+ sid_mem = talloc_zero_array(mem_ctx,
+ struct dom_sid,
+ sid_array.num_sids);
+ if (sid_mem == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /*
+ * We cannot just simply assign '*psids = sid_array.sids;'
+ * we need to copy every sid since these are incompatible types:
+ * 'struct dom_sid *' vs 'struct lsa_SidPtr *'
+ */
+ for (i = 0; i < sid_array.num_sids; i++) {
+ sid_copy(&sid_mem[i], sid_array.sids[i].sid);
+ }
+
+ *pnum_sids = sid_array.num_sids;
+ *psids = sid_mem;
+
+ return NT_STATUS_OK;
+ }
+ default:
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+}
+
/* Get a list of trusted domains */
NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
struct rpc_pipe_client *lsa_pipe,
char ***pnames,
uint32_t **pname_types);
+NTSTATUS rpc_lookup_aliasmem(TALLOC_CTX *mem_ctx,
+ struct rpc_pipe_client *samr_pipe,
+ struct policy_handle *samr_policy,
+ const struct dom_sid *domain_sid,
+ const struct dom_sid *group_sid,
+ enum lsa_SidType type,
+ uint32_t *pnum_sids,
+ struct dom_sid **psids);
+
/* Get a list of trusted domains */
NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
struct rpc_pipe_client *lsa_pipe,
return status;
}
+/* Lookup alias membership */
+static NTSTATUS sam_lookup_aliasmem(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const struct dom_sid *group_sid,
+ enum lsa_SidType type,
+ uint32_t *pnum_sids,
+ struct dom_sid **psid_mem)
+{
+ struct rpc_pipe_client *samr_pipe;
+ struct policy_handle dom_pol = {0};
+
+ uint32_t num_sids = 0;
+ struct dom_sid *sid_mem = NULL;
+
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ NTSTATUS status;
+ bool retry = false;
+
+ DBG_INFO("sam_lookup_aliasmem\n");
+
+ /* Paranoia check */
+ if (type != SID_NAME_ALIAS) {
+ status = NT_STATUS_NO_SUCH_ALIAS;
+ goto done;
+ }
+
+ if (pnum_sids) {
+ *pnum_sids = 0;
+ }
+
+again:
+ status = open_cached_internal_pipe_conn(domain,
+ &samr_pipe,
+ &dom_pol,
+ NULL,
+ NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpc_lookup_aliasmem(tmp_ctx,
+ samr_pipe,
+ &dom_pol,
+ &domain->sid,
+ group_sid,
+ type,
+ &num_sids,
+ &sid_mem);
+
+ if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
+ retry = true;
+ goto again;
+ }
+
+ if (pnum_sids) {
+ *pnum_sids = num_sids;
+ }
+
+ if (psid_mem) {
+ *psid_mem = talloc_move(mem_ctx, &sid_mem);
+ }
+
+done:
+ TALLOC_FREE(tmp_ctx);
+ return status;
+}
+
/*********************************************************************
BUILTIN specific functions.
*********************************************************************/
.lookup_usergroups = sam_lookup_usergroups,
.lookup_useraliases = sam_lookup_useraliases,
.lookup_groupmem = sam_lookup_groupmem,
+ .lookup_aliasmem = sam_lookup_aliasmem,
.lockout_policy = sam_lockout_policy,
.password_policy = sam_password_policy,
.trusted_domains = builtin_trusted_domains
.lookup_usergroups = sam_lookup_usergroups,
.lookup_useraliases = sam_lookup_useraliases,
.lookup_groupmem = sam_lookup_groupmem,
+ .lookup_aliasmem = sam_lookup_aliasmem,
.lockout_policy = sam_lockout_policy,
.password_policy = sam_password_policy,
.trusted_domains = sam_trusted_domains