1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

s3:winbind: Add lookup_aliasmem to winbindd_methods and implement it in all backends

Signed-off-by: Pavel Filipenský <pfilipensky@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
Pavel Filipenský 2023-03-08 08:40:58 +01:00 committed by Andreas Schneider
parent b67dc2586f
commit 92b2eb9c3f
8 changed files with 299 additions and 0 deletions

View File

@ -279,6 +279,14 @@ struct winbindd_methods {
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,

View File

@ -1371,6 +1371,31 @@ done:
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,
@ -1568,6 +1593,7 @@ struct winbindd_methods ads_methods = {
lookup_usergroups,
lookup_useraliases,
lookup_groupmem,
lookup_aliasmem,
lockout_policy,
password_policy,
trusted_domains,

View File

@ -544,6 +544,60 @@ done:
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,
@ -1069,6 +1123,7 @@ struct winbindd_methods msrpc_methods = {
msrpc_lookup_usergroups,
msrpc_lookup_useraliases,
msrpc_lookup_groupmem,
msrpc_lookup_aliasmem,
msrpc_lockout_policy,
msrpc_password_policy,
msrpc_trusted_domains,

View File

@ -235,6 +235,34 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
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,
@ -319,6 +347,7 @@ struct winbindd_methods reconnect_methods = {
lookup_usergroups,
lookup_useraliases,
lookup_groupmem,
lookup_aliasmem,
lockout_policy,
password_policy,
trusted_domains,

View File

@ -266,6 +266,33 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
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,
@ -326,6 +353,7 @@ struct winbindd_methods reconnect_ads_methods = {
lookup_usergroups,
lookup_useraliases,
lookup_groupmem,
lookup_aliasmem,
lockout_policy,
password_policy,
trusted_domains,

View File

@ -606,6 +606,81 @@ NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
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,

View File

@ -76,6 +76,15 @@ NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
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,

View File

@ -488,6 +488,73 @@ done:
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.
*********************************************************************/
@ -1331,6 +1398,7 @@ struct winbindd_methods builtin_passdb_methods = {
.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
@ -1349,6 +1417,7 @@ struct winbindd_methods sam_passdb_methods = {
.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