outsourcing DCE/RPC to alternate programs - runtime config option

tridge at samba.org tridge at samba.org
Sat Dec 11 22:52:52 GMT 2004


Metze,

The more I think about it, the more I come to the conclusion that the
right approach for projects that wish to hook into our rpc server
infrastructure is to build upon your existing rpc_server/remote/
capability, along with the additional rpc transport support that
Jelmer has added recently.

Think about the following setup with the existing Samba4 server code:

  	dcerpc endpoint servers = epmapper samr netlogon lsarpc remote

	dcerpc_remote:binding = ncacn_unix_stream:localhost[connect,/var/rpc/myapp]
	dcerpc_remote:interfaces = spoolss atsvc

That sets up Samba4 to internally handle epmapper, samr, netlogon and
lsarpc, but passes all requests that come into spoolss or atsvc onto
whatever program is listening on the unix domain socket /var/rpc/myapp.

The external program sees a new unix domain socket connect for each
incoming rpc connection. It would then see a connect rpc bind,
followed by the requests with signing and sealing removed. The Samba4
rpc server acts as both a gateway and an authentication server.

The obvious missing piece is passing the authentication information. I
can see two fairly neat ways of solving this. 

The first one would be to define a new auth type in dcerpc_bind. The
new auth type would pass a NDR encoded security_token structure in the
dcerpc_bind.auth_info blob, but in other respects would be equivalent
to the existing 'connect' auth type.  The security_token holds the
user SIDs and the privilege_mask, which should be sufficient
information for the external server. That obviously would require
external rpc servers to implement the new auth level.

The second solution would be to define a "well known" rpc operation
number, such as 65535. We then define IDL for this well known
operation to contain the security_token, and whatever other useful
information external rpc servers might need. For example:

   /* operation number 0xFFFF */
   NTSTATUS external_rpc_auth(
	[in]      security_token *nt_token,
	[in]      unix_sec_ctx   *unix_tokn,
        [out,ref] uint32         *fault_code,
        [out,ref] uint32         *reason
   );

The forwarding server would then attempt this call after doing a
simple bind. If the call fails with a DCERPC_FAULT_OP_RNG_ERROR then
the external server doesn't support the operation, and no harm is
done. If the call does not fault then the NTSTATUS result is looked
at, and if it is other than NT_STATUS_OK then the connection is
dropped with a rpc fault, using the given fault code and reason.

The disadvantage of the second method is that it requires an IDL
compiler that can implement non-contiguous operation numbers. This
might be difficult with some IDL compilers.

Let's assume we solve the authentication problem, perhaps using one of
the above two methods. What else is there to be done? Well, currently
the rpc_server/remote/ code does a full NDR decode of incoming
requests before re-encoding them and sending them to the external
server. That only works if Samba4 has the full IDL for the external
interface builtin, which creates a maintainence problem. 

The solution to to create a new rpc_server/external/ endpoint server
that is very similar to the current rpc_server/remote/ code, but fills
in the dcerpc_interface_table with a single function that uses a
talloc_memdup() for the table->calls[].ndr_push() and
table->calls[].ndr_pull() methods. That will allow the unwrapped
(signing and sealing removed) requests to pass through to the external
server unchanged.

I've CCd Luke Howard on this, as he is the only one who has real
experience with building external rpc servers for Samba3. I'd be
interested in whether he thinks the above system would be workable for
a potential future version of XAD combined with Samba4.

One minor problem is that the "dcerpc endpoint servers" syntax is a
bit cumbersome. It would require the smb.conf to list all the internal
rpc servers that Samba defines apart from those handled remotely. We
can either define a new "additional endpoint servers" option, or allow
for syntax like this:

   dcerpc endpoint servers -= spoolss atsvc
   dcerpc endpoint servers += remote

The += and -= operations would only be allowed for parameter types of
type P_LIST in loadparm (as they make no sense for other types of
parameters).

Cheers, Tridge


More information about the samba-technical mailing list