1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-26 01:49:31 +03:00

winbindd: let LookupNames return NT_STATUS_OK and SID_NAME_UNKNOWN for unmapped names

Previously LookupNames would fail if a name could not be translated, so winbindd
clients like libwbclient couldn't differentiate between not being able to talk
to a DC and just an unkown name.

As a visible change this alters

  $ bin/wbinfo -n Idontexist
  failed to call wbcLookupName: WBC_ERR_DOMAIN_NOT_FOUND
  Could not lookup name Idontexist

to

  $ bin/wbinfo -n Idontexist
  failed to call wbcLookupName: WBC_ERR_SOME_NOT_MAPPED
  Could not lookup name Idontexist

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
Ralph Boehme
2024-02-16 16:44:57 +01:00
committed by Stefan Metzmacher
parent 12c5adb49a
commit 148a102800
8 changed files with 85 additions and 20 deletions

View File

@ -1802,9 +1802,6 @@ static NTSTATUS wcache_name_to_sid(struct winbindd_domain *domain,
DBG_DEBUG("cache entry not found\n");
return NT_STATUS_NOT_FOUND;
}
if (*type == SID_NAME_UNKNOWN) {
return NT_STATUS_NONE_MAPPED;
}
return NT_STATUS_OK;
}
@ -1854,16 +1851,9 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain,
}
/* and save it */
if (domain->online &&
(NT_STATUS_IS_OK(status) || NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED))) {
enum lsa_SidType save_type = *type;
if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
save_type = SID_NAME_UNKNOWN;
}
if (domain->online && NT_STATUS_IS_OK(status)) {
wcache_save_name_to_sid(domain, status, domain_name, name, sid,
save_type);
*type);
/* Only save the reverse mapping if this was not a UPN */
if (!strchr(name, '@')) {
@ -1872,7 +1862,7 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain,
}
(void)strlower_m(discard_const_p(char, name));
wcache_save_sid_to_name(domain, status, sid,
dom_name, name, save_type);
dom_name, name, *type);
}
}

View File

@ -122,6 +122,9 @@ static void winbindd_getgrnam_lookupname_done(struct tevent_req *subreq)
status = wb_lookupname_recv(subreq, &state->sid, &type);
TALLOC_FREE(subreq);
if (NT_STATUS_IS_OK(status) && type == SID_NAME_UNKNOWN) {
status = NT_STATUS_NONE_MAPPED;
}
if (tevent_req_nterror(req, status)) {
return;
}

View File

@ -109,6 +109,9 @@ static void winbindd_getgroups_lookupname_done(struct tevent_req *subreq)
status = wb_lookupname_recv(subreq, &state->sid, &state->type);
TALLOC_FREE(subreq);
if (NT_STATUS_IS_OK(status) && state->type == SID_NAME_UNKNOWN) {
status = NT_STATUS_NONE_MAPPED;
}
if (tevent_req_nterror(req, status)) {
return;
}

View File

@ -106,6 +106,9 @@ static void winbindd_getpwnam_lookupname_done(struct tevent_req *subreq)
status = wb_lookupname_recv(subreq, &state->sid, &state->type);
TALLOC_FREE(subreq);
if (NT_STATUS_IS_OK(status) && state->type == SID_NAME_UNKNOWN) {
status = NT_STATUS_NONE_MAPPED;
}
if (tevent_req_nterror(req, status)) {
return;
}

View File

@ -386,6 +386,9 @@ static void wb_parent_idmap_setup_lookupname_done(struct tevent_req *subreq)
status = wb_lookupname_recv(subreq, &dom->sid, &type);
TALLOC_FREE(subreq);
if (NT_STATUS_IS_OK(status) && type == SID_NAME_UNKNOWN) {
status = NT_STATUS_NONE_MAPPED;
}
if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("Lookup domain name '%s' failed '%s'\n",
dom->name,

View File

@ -652,6 +652,9 @@ static void wb_irpc_lsa_LookupNames4_done(struct tevent_req *subreq)
state->num_pending--;
status = wb_lookupname_recv(subreq, &nstate->sid, &nstate->type);
TALLOC_FREE(subreq);
if (NT_STATUS_IS_OK(status) && nstate->type == SID_NAME_UNKNOWN) {
status = NT_STATUS_NONE_MAPPED;
}
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("RPC callback failed for %s - %s\n",
__func__, nt_errstr(status)));

View File

@ -226,8 +226,8 @@ static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
struct dom_sid *sids = NULL;
enum lsa_SidType *types = NULL;
char *full_name = NULL;
const char *names[1];
const char **domains;
const char *names[1] = { NULL, };
const char **domains = NULL;
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
char *mapped_name = NULL;
@ -270,13 +270,14 @@ static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
/* Return rid and type if lookup successful */
if (pdom_name != NULL) {
const char *dom_name;
const char *dom_name = NULL;
dom_name = talloc_strdup(mem_ctx, domains[0]);
if (dom_name == NULL) {
return NT_STATUS_NO_MEMORY;
if (domains[0] != NULL) {
dom_name = talloc_strdup(mem_ctx, domains[0]);
if (dom_name == NULL) {
return NT_STATUS_NO_MEMORY;
}
}
*pdom_name = dom_name;
}
@ -1049,6 +1050,12 @@ static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL;
connect:
if (domains == NULL) {
*domains = NULL;
}
*sids = NULL;
*types = NULL;
status = cm_connect_lsat(domain, mem_ctx, &cli, &lsa_policy);
if (!NT_STATUS_IS_OK(status)) {
return status;
@ -1098,6 +1105,52 @@ static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
status = NT_STATUS_ACCESS_DENIED;
}
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED)) {
if (num_names > 0) {
uint32_t i;
*sids = talloc_zero_array(mem_ctx, struct dom_sid, num_names);
if (*sids == NULL) {
return NT_STATUS_NO_MEMORY;
}
*types = talloc_zero_array(mem_ctx, enum lsa_SidType, num_names);
if (*types == NULL) {
return NT_STATUS_NO_MEMORY;
}
for (i = 0; i < num_names; i++) {
(*types)[i] = SID_NAME_UNKNOWN;
}
if (domains != NULL) {
*domains = talloc_zero_array(mem_ctx, const char *, num_names);
if (*domains == NULL) {
return NT_STATUS_NO_MEMORY;
}
}
}
result = NT_STATUS_OK;
} else if (NT_STATUS_EQUAL(result, NT_STATUS_SOME_NOT_MAPPED)) {
if (talloc_array_length(*sids) != num_names) {
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
if (talloc_array_length(*types) != num_names) {
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
if (domains != NULL) {
if (talloc_array_length(*domains) != num_names) {
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
}
result = NT_STATUS_OK;
}
if (any_nt_status_not_ok(status, result, &status)) {
return status;
}

View File

@ -679,6 +679,8 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
DBG_NOTICE("%s\\%s\n", domain_name, name);
*ptype = SID_NAME_UNKNOWN;
if (strequal(domain_name, unix_users_domain_name())) {
struct passwd *pwd = NULL;
@ -794,6 +796,11 @@ done:
status = NT_STATUS_OK;
fail:
if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) ||
NT_STATUS_EQUAL(status, NT_STATUS_SOME_NOT_MAPPED))
{
status = NT_STATUS_OK;
}
TALLOC_FREE(tmp_ctx);
return status;
}