]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
rpc_server: Check info5->transport
authorVolker Lendecke <vl@samba.org>
Sun, 28 Nov 2021 15:19:56 +0000 (16:19 +0100)
committerVolker Lendecke <vl@samba.org>
Fri, 10 Dec 2021 14:02:30 +0000 (14:02 +0000)
Eventually, this new mechanism might replace the ncalrpc_as_system mechanism: I
think with this we're much more flexible and even more secure: We rely on the
direct permissions on "np/" and don't have to pretend that the local client
came from a file on /root. We are more flexible because with this mechanism we
can easily fake arbitrary tokens and play with session keys.

However, this would require that the source4 librpc code needs to learn about
this mechanism, which I was not able to complete.

The source3 rpc_server side of this will go away soon, so for now only
allow NCACN_NP there. The check in source4 will stay with us for a
while, so allow NCACN_NP and NCALRPC to be set remotely here. With
NCACN_NP (the case for a client to connect on a named pipe), protect
against accidentially connecting as system.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/rpc_server/rpc_server.c
source4/samba/service_named_pipe.c

index 1919fcd3650d2752ac192ebac8868d49ba526736..a30565d8593022c0c9140165f483b944f76a9df4 100644 (file)
@@ -34,6 +34,7 @@
 #include "rpc_server/rpc_ncacn_np.h"
 #include "rpc_server/srv_pipe_hnd.h"
 #include "rpc_server/srv_pipe.h"
+#include "libcli/security/security_token.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
@@ -363,13 +364,14 @@ static void dcesrv_ncacn_np_accept_done(struct tevent_req *subreq)
        struct dcerpc_ncacn_conn *ncacn_conn = tevent_req_callback_data(
                subreq, struct dcerpc_ncacn_conn);
        struct auth_session_info_transport *session_info_transport = NULL;
+       enum dcerpc_transport_t transport;
        int error;
        int ret;
 
        ret = tstream_npa_accept_existing_recv(subreq, &error, ncacn_conn,
                                               &ncacn_conn->tstream,
                                               NULL,
-                                              NULL,
+                                              &transport,
                                               &ncacn_conn->remote_client_addr,
                                               &ncacn_conn->remote_client_name,
                                               &ncacn_conn->local_server_addr,
@@ -378,6 +380,21 @@ static void dcesrv_ncacn_np_accept_done(struct tevent_req *subreq)
        ncacn_conn->session_info = talloc_move(ncacn_conn,
                        &session_info_transport->session_info);
 
+       if (transport != NCACN_NP) {
+               ncacn_terminate_connection(
+                       ncacn_conn,
+                       "Only allow NCACN_NP transport on named pipes\n");
+               return;
+       }
+
+       if (security_token_is_system(
+                   ncacn_conn->session_info->security_token)) {
+               ncacn_terminate_connection(
+                       ncacn_conn,
+                       "No system token via NCACN_NP allowed\n");
+               return;
+       }
+
        TALLOC_FREE(subreq);
        if (ret != 0) {
                DBG_ERR("Failed to accept named pipe connection: %s\n",
index e12d96b13cc1cc98eaabf1a7d93ed932bcb6b4d2..4b880fd85a3a028a0d3311a9d8a24c04f41f817d 100644 (file)
@@ -140,6 +140,30 @@ static void named_pipe_accept_done(struct tevent_req *subreq)
                goto out;
        }
 
+       if (transport == NCACN_NP) {
+               if (security_token_is_system(conn->session_info->security_token)) {
+                       reason = talloc_asprintf(
+                               conn,
+                               "System token not allowed on transport %d\n",
+                               transport);
+                       goto out;
+               }
+       } else if (transport == NCALRPC) {
+               /*
+                * TODO:
+                * we should somehow remember the given transport on
+                * the connection, but that's a task for another day
+                * as it's not trivial to do...
+                */
+       } else {
+               reason = talloc_asprintf(
+                       conn,
+                       "Only allow NCACN_NP or NCALRPC transport on named pipes, "
+                       "got %d\n",
+                       (int)transport);
+               goto out;
+       }
+
        /*
         * hand over to the real pipe implementation,
         * now that we have setup the transport session_info