From: Volker Lendecke Date: Sun, 28 Nov 2021 15:19:56 +0000 (+0100) Subject: rpc_server: Check info5->transport X-Git-Tag: tdb-1.4.6~372 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5fa62639489a97407ac53fcedbded2246328407;p=thirdparty%2Fsamba.git rpc_server: Check info5->transport 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 Reviewed-by: Stefan Metzmacher --- diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c index 1919fcd3650..a30565d8593 100644 --- a/source3/rpc_server/rpc_server.c +++ b/source3/rpc_server/rpc_server.c @@ -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", diff --git a/source4/samba/service_named_pipe.c b/source4/samba/service_named_pipe.c index e12d96b13cc..4b880fd85a3 100644 --- a/source4/samba/service_named_pipe.c +++ b/source4/samba/service_named_pipe.c @@ -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