]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
winbindd: let LookupNames return NT_STATUS_OK and SID_NAME_UNKNOWN for unmapped names
authorRalph Boehme <slow@samba.org>
Fri, 16 Feb 2024 15:44:57 +0000 (16:44 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 26 Jul 2024 10:06:31 +0000 (10:06 +0000)
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>
source3/winbindd/winbindd_cache.c
source3/winbindd/winbindd_getgrnam.c
source3/winbindd/winbindd_getgroups.c
source3/winbindd/winbindd_getpwnam.c
source3/winbindd/winbindd_idmap.c
source3/winbindd/winbindd_irpc.c
source3/winbindd/winbindd_msrpc.c
source3/winbindd/winbindd_samr.c

index 22a23f5a4b2cf5c31e248219f771ddf0bd34e0db..7a000c482592078a5823d8d2f37ca1b7d66627ed 100644 (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);
                }
        }
 
index 6b277c2dc9708c1ab7b5e7517cc7cf06f92f0d42..24fef6c2c20df8c835b1b36ba3e7913942bd81be 100644 (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;
        }
index c1c108e4155bec7b7581a7b899cc7d8d198848e8..5f901d62d5302c6f77e163d861a3440cf19b0c53 100644 (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;
        }
index 2bf15c0fe7d13e360eb58c02c1c857d9a756bb0e..db14fc96ad30860dc695e461f40bfec461e0d08b 100644 (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;
        }
index 362211223eb6c43b47376930bf56240d86f5caaa..bf5c4d9ff32eee415bea8e5bdb64ffdf49b5f5d2 100644 (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,
index f66d797da5ef3ef4da382299b96571334453f852..5981eb2d244582245af2e74c1936272df0cbbb16 100644 (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)));
index a7bd9be4377b36b176f419a79d297d1d9eaf4eb1..0c849c04e1939b5b66162f303efb4b35f1134aa0 100644 (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;
        }
index 65e9932c25ef3b37d9bf526a962425047aabd2e5..9ba9f22eb4a5198f7f1175315ff2be7c8ceda5f5 100644 (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;
 }