]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:winbind: Delegate normalize_name_map to the idmap child in winbindd_getgrgid
authorSamuel Cabrero <scabrero@samba.org>
Fri, 23 May 2025 12:23:57 +0000 (14:23 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Tue, 24 Jun 2025 07:53:41 +0000 (07:53 +0000)
Delegate mapping to the idmap child to avoid blocking the parent while querying the
LDAP server, depending on the idmap configuration.

Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/winbindd/winbindd_getgrgid.c

index 4edd81b004c71394e8f6f02fca608c8a63d0fd53..265851480066328de286fb4f7d8f7a7af472cde7 100644 (file)
@@ -20,6 +20,7 @@
 #include "includes.h"
 #include "winbindd.h"
 #include "libcli/security/dom_sid.h"
+#include "librpc/gen_ndr/ndr_winbind_c.h"
 
 struct winbindd_getgrgid_state {
        struct tevent_context *ev;
@@ -27,6 +28,8 @@ struct winbindd_getgrgid_state {
        struct dom_sid *sid;
        const char *domname;
        const char *name;
+       const char *mapped_name;
+       const char *full_group_name;
        gid_t gid;
        struct db_context *members;
 };
@@ -93,6 +96,7 @@ static void winbindd_getgrgid_gid2sid_done(struct tevent_req *subreq)
        tevent_req_set_callback(subreq, winbindd_getgrgid_done, req);
 }
 
+static void winbindd_getgrgid_normalize_done(struct tevent_req *subreq);
 static void winbindd_getgrgid_done(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(
@@ -107,6 +111,50 @@ static void winbindd_getgrgid_done(struct tevent_req *subreq)
        if (tevent_req_nterror(req, status)) {
                return;
        }
+
+       subreq = dcerpc_wbint_NormalizeNameMap_send(state,
+                                                   state->ev,
+                                                   idmap_child_handle(),
+                                                   state->domname,
+                                                   state->name,
+                                                   &state->mapped_name);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, winbindd_getgrgid_normalize_done, req);
+}
+
+static void winbindd_getgrgid_normalize_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_getgrgid_state *state = tevent_req_data(
+               req, struct winbindd_getgrgid_state);
+       NTSTATUS status;
+       NTSTATUS result;
+
+       status = dcerpc_wbint_NormalizeNameMap_recv(subreq, state, &result);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               DBG_ERR("wbint_NormalizeNameMap(%s, %s) call failed: %s\n",
+                       state->domname,
+                       state->name,
+                       nt_errstr(status));
+               return;
+       } else if (NT_STATUS_IS_OK(result)) {
+               state->full_group_name = fill_domain_username_talloc(
+                       state, state->domname, state->mapped_name, true);
+       } else if (NT_STATUS_EQUAL(result, NT_STATUS_FILE_RENAMED)) {
+               state->full_group_name = state->mapped_name;
+       } else {
+               state->full_group_name = fill_domain_username_talloc(
+                       state, state->domname, state->name, true);
+       }
+
+       if (tevent_req_nomem(state->full_group_name, req)) {
+               D_WARNING("Failed to fill full group name.\n");
+               return;
+       }
        tevent_req_done(req);
 }
 
@@ -115,6 +163,7 @@ NTSTATUS winbindd_getgrgid_recv(struct tevent_req *req,
 {
        struct winbindd_getgrgid_state *state = tevent_req_data(
                req, struct winbindd_getgrgid_state);
+       struct winbindd_gr *gr = &response->data.gr;
        NTSTATUS status;
        int num_members;
        char *buf;
@@ -127,11 +176,12 @@ NTSTATUS winbindd_getgrgid_recv(struct tevent_req *req,
                return status;
        }
 
-       if (!fill_grent(talloc_tos(), &response->data.gr, state->domname,
-                       state->name, state->gid)) {
-               D_WARNING("fill_grent failed\n");
-               return NT_STATUS_NO_MEMORY;
-       }
+       gr->gr_gid = state->gid;
+
+       strlcpy(gr->gr_name, state->full_group_name, sizeof(gr->gr_name));
+       strlcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd));
+
+       D_DEBUG("Full group name is '%s'.\n", gr->gr_name);
 
        status = winbindd_print_groupmembers(state->members, response,
                                             &num_members, &buf);