mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
winbindd: Avoid deadlock in sam_name_to_sid()
"Unix Users" and "Unix Groups" can recurse into nsswitch and thus into winbind. In the binding process, we have winbindd_off(), but if we pass the lookupNames request to a forked lsad, lsad does not necessarily have that setting. So lsad might turn back to winbind, which could lead to a deadlock. Handle the nsswitch lookups in winbind. While there, also do the simple wellknown names and the "DOMAIN\" type 3 lookups directly in winbind. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
30e0cac46b
commit
57246e1f81
@ -569,14 +569,71 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
|
||||
struct rpc_pipe_client *lsa_pipe;
|
||||
struct policy_handle lsa_policy = { 0 };
|
||||
struct dom_sid sid;
|
||||
const char *dom_name;
|
||||
const char *dom_name = domain_name;
|
||||
enum lsa_SidType type;
|
||||
TALLOC_CTX *tmp_ctx = talloc_stackframe();
|
||||
NTSTATUS status;
|
||||
NTSTATUS status = NT_STATUS_NONE_MAPPED;
|
||||
bool retry = false;
|
||||
bool ok;
|
||||
|
||||
DBG_NOTICE("%s\\%s\n", domain_name, name);
|
||||
|
||||
if (strequal(domain_name, unix_users_domain_name())) {
|
||||
struct passwd *pwd = NULL;
|
||||
|
||||
if (name[0] == '\0') {
|
||||
sid_copy(&sid, &global_sid_Unix_Users);
|
||||
type = SID_NAME_DOMAIN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
pwd = Get_Pwnam_alloc(tmp_ctx, name);
|
||||
if (pwd == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
ok = sid_compose(&sid, &global_sid_Unix_Users, pwd->pw_uid);
|
||||
if (!ok) {
|
||||
status = NT_STATUS_INTERNAL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
type = SID_NAME_USER;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (strequal(domain_name, unix_groups_domain_name())) {
|
||||
struct group *grp = NULL;
|
||||
|
||||
if (name[0] == '\0') {
|
||||
sid_copy(&sid, &global_sid_Unix_Groups);
|
||||
type = SID_NAME_DOMAIN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
grp = getgrnam(name);
|
||||
if (grp == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
ok = sid_compose(&sid, &global_sid_Unix_Groups, grp->gr_gid);
|
||||
if (!ok) {
|
||||
status = NT_STATUS_INTERNAL_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
type = SID_NAME_DOM_GRP;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (name[0] == '\0') {
|
||||
sid_copy(&sid, &domain->sid);
|
||||
type = SID_NAME_DOMAIN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ok = lookup_wellknown_name(mem_ctx, name, &sid, &dom_name);
|
||||
if (ok) {
|
||||
type = SID_NAME_WKN_GRP;
|
||||
goto done;
|
||||
}
|
||||
|
||||
again:
|
||||
status = open_cached_internal_pipe_conn(domain,
|
||||
NULL,
|
||||
@ -584,7 +641,7 @@ again:
|
||||
&lsa_pipe,
|
||||
&lsa_policy);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
status = rpc_name_to_sid(tmp_ctx,
|
||||
@ -603,14 +660,15 @@ again:
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
done:
|
||||
if (pdom_name != NULL) {
|
||||
*pdom_name = talloc_strdup(mem_ctx, dom_name);
|
||||
if (*pdom_name == NULL) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
@ -621,7 +679,8 @@ again:
|
||||
*ptype = type;
|
||||
}
|
||||
|
||||
done:
|
||||
status = NT_STATUS_OK;
|
||||
fail:
|
||||
TALLOC_FREE(tmp_ctx);
|
||||
return status;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user