]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
rpc_server3: Pass winbind_env_set() state through to rpcd_*
authorVolker Lendecke <vl@samba.org>
Tue, 18 Apr 2023 10:47:04 +0000 (12:47 +0200)
committerJule Anger <janger@samba.org>
Tue, 23 May 2023 08:09:23 +0000 (08:09 +0000)
Winbind can ask rpcd_lsad for LookupNames etc. This can recurse back
into winbind for getpwnam. We have the "_NO_WINBINDD" environment
variable set in winbind itself for this case, but this is lost on the
way into rpcd_lsad. Use a flag in global_sid_Samba_NPA_Flags to pass
this information to dcerpc_core, where it sets the variable on every
call if requested.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=15361
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Tue May 16 11:54:32 UTC 2023 on atb-devel-224

(cherry picked from commit 59694ad0a4cc489f1baa4c2c94c6322c0f22c1df)

Autobuild-User(v4-17-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-17-test): Tue May 23 08:09:23 UTC 2023 on sn-devel-184

libcli/security/dom_sid.h
librpc/rpc/dcesrv_core.c
librpc/rpc/dcesrv_core.h
source3/rpc_client/local_np.c
source3/rpc_server/rpc_worker.c

index 65d8adc71958cf142c6fd150e0127e98052a0e78..c362fa6fe8064e9e2fd7bf92c07dd92840caca7c 100644 (file)
@@ -68,6 +68,7 @@ extern const struct dom_sid global_sid_Samba_SMB3;
 
 extern const struct dom_sid global_sid_Samba_NPA_Flags;
 #define SAMBA_NPA_FLAGS_NEED_IDLE 1
+#define SAMBA_NPA_FLAGS_WINBIND_OFF 2
 
 enum lsa_SidType;
 
index 9fd7181290563e070e79d288aa37b3e29be437cf..ead37c219885fa49f40a945f102e1a136a8292b2 100644 (file)
@@ -34,6 +34,7 @@
 #include "librpc/gen_ndr/ndr_dcerpc.h"
 #include "lib/util/tevent_ntstatus.h"
 #include "system/network.h"
+#include "nsswitch/winbind_client.h"
 
 /**
  * @file
@@ -1838,6 +1839,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
        enum dcerpc_transport_t transport =
                dcerpc_binding_get_transport(endpoint->ep_description);
        struct ndr_pull *pull;
+       bool turn_winbind_on = false;
        NTSTATUS status;
 
        if (auth->auth_invalid) {
@@ -1953,8 +1955,23 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
                         pull->data_size - pull->offset));
        }
 
+       if (call->state_flags & DCESRV_CALL_STATE_FLAG_WINBIND_OFF) {
+               bool winbind_active = !winbind_env_set();
+               if (winbind_active) {
+                       DBG_DEBUG("turning winbind off\n");
+                       (void)winbind_off();
+                       turn_winbind_on = true;
+               }
+       }
+
        /* call the dispatch function */
        status = call->context->iface->dispatch(call, call, call->r);
+
+       if (turn_winbind_on) {
+               DBG_DEBUG("turning winbind on\n");
+               (void)winbind_on();
+       }
+
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
                         call->context->iface->name,
index 69815b71f3dd91b025e49c51fb655081f2068408..aefb3f127322b4d637494d45592fce907c5c15c5 100644 (file)
@@ -125,6 +125,7 @@ struct dcesrv_call_state {
 #define DCESRV_CALL_STATE_FLAG_MAY_ASYNC (1<<1)
 #define DCESRV_CALL_STATE_FLAG_MULTIPLEXED (1<<3)
 #define DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL (1<<4)
+#define DCESRV_CALL_STATE_FLAG_WINBIND_OFF (1 << 5)
        uint32_t state_flags;
 
        /* the time the request arrived in the server */
index 499d9705e3f9ae7809f36d5b2a939bfbd3e6e20b..0b323404f06b7d1d1af27fd9a7a2785ae1a9749b 100644 (file)
@@ -26,6 +26,7 @@
 #include "auth/auth_util.h"
 #include "libcli/security/dom_sid.h"
 #include "libcli/security/security_token.h"
+#include "nsswitch/winbind_client.h"
 
 /**
  * @file local_np.c
@@ -629,6 +630,11 @@ struct tevent_req *local_np_connect_send(
                npa_flags |= SAMBA_NPA_FLAGS_NEED_IDLE;
        }
 
+       ok = winbind_env_set();
+       if (ok) {
+               npa_flags |= SAMBA_NPA_FLAGS_WINBIND_OFF;
+       }
+
        ok = sid_append_rid(&npa_sid, npa_flags);
        if (!ok) {
                tevent_req_error(req, EINVAL);
index 23b678576980d0bc8db5163ff5a1071a25a1c692..dc3bde7bde9d1d811c0253bc0377a0edced7f01b 100644 (file)
@@ -42,6 +42,8 @@
 #include "nsswitch/winbind_client.h"
 #include "source3/include/messages.h"
 #include "libcli/security/security_token.h"
+#include "libcli/security/dom_sid.h"
+#include "source3/include/proto.h"
 
 /*
  * This is the generic code that becomes the
@@ -181,6 +183,9 @@ static void rpc_worker_new_client(
        struct dcesrv_connection *dcesrv_conn = NULL;
        DATA_BLOB buffer = { .data = NULL };
        struct ncacn_packet *pkt = NULL;
+       struct security_token *token = NULL;
+       uint32_t npa_flags, state_flags;
+       bool found_npa_flags;
        NTSTATUS status;
        int ret;
 
@@ -374,13 +379,31 @@ static void rpc_worker_new_client(
        }
        sock = -1;
 
-       if (security_token_is_system(
-                   info7->session_info->session_info->security_token) &&
-           (transport != NCALRPC)) {
+       token = info7->session_info->session_info->security_token;
+
+       if (security_token_is_system(token) && (transport != NCALRPC)) {
                DBG_DEBUG("System token only allowed on NCALRPC\n");
                goto fail;
        }
 
+       state_flags = DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
+
+       found_npa_flags = security_token_find_npa_flags(token, &npa_flags);
+       if (found_npa_flags) {
+               if (npa_flags & SAMBA_NPA_FLAGS_WINBIND_OFF) {
+                       state_flags |=
+                               DCESRV_CALL_STATE_FLAG_WINBIND_OFF;
+               }
+
+               /*
+                * Delete the flags so that we don't bail in
+                * local_np_connect_send() on subsequent
+                * connects. Once we connect to another RPC service, a
+                * new flags sid will be added if required.
+                */
+               security_token_del_npa_flags(token);
+       }
+
        ncacn_conn->p.msg_ctx = global_messaging_context();
        ncacn_conn->p.transport = transport;
 
@@ -389,7 +412,7 @@ static void rpc_worker_new_client(
                                         ep,
                                         info7->session_info->session_info,
                                         global_event_context(),
-                                        DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
+                                        state_flags,
                                         &dcesrv_conn);
        if (!NT_STATUS_IS_OK(status)) {
                DBG_DEBUG("Failed to connect to endpoint: %s\n",