Trying to understand epmapper registration
Andrew Bartlett
abartlet at samba.org
Sat Mar 3 14:27:49 MST 2012
On Sat, 2012-03-03 at 12:38 +0100, Andreas Schneider wrote:
> On Saturday 03 March 2012 21:44:55 Andrew Bartlett wrote:
> > > Do you mean the table with the GUID, endpoint names, and on which
> > > endpoints it should be available? I don't really get what you're talking
> > > about and what the problem is :)
> >
> > I'm sorry, clearly I have not been specific enough. To continue using
> > dssetup as my example, here is the relevant fucntion in master:
> >
> > static bool rpc_setup_dssetup(struct tevent_context *ev_ctx,
> > struct messaging_context *msg_ctx,
> > const struct dcerpc_binding_vector *v)
> > {
> > const struct ndr_interface_table *t = &ndr_table_dssetup;
> > const char *pipe_name = "dssetup";
> > struct dcerpc_binding_vector *v2;
> > enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
> > NTSTATUS status;
> > bool ok;
> >
> > status = rpc_dssetup_init(NULL);
> > if (!NT_STATUS_IS_OK(status)) {
> > return false;
> > }
> >
> > if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
> > v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
> > if (v2 == NULL) {
> > return false;
> > }
> >
> > status = dcerpc_binding_vector_replace_iface(t, v2);
> > if (!NT_STATUS_IS_OK(status)) {
> > return false;
> > }
> >
> > status = dcerpc_binding_vector_add_np_default(t, v2);
> > if (!NT_STATUS_IS_OK(status)) {
> > return false;
> > }
> >
> > ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
> > msg_ctx,
> > pipe_name,
> > NULL);
> > if (!ok) {
> > return false;
> > }
> >
> > status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
> > if (!NT_STATUS_IS_OK(status)) {
> > return false;
> > }
> >
> > status = rpc_ep_register(ev_ctx,
> > msg_ctx,
> > t,
> > v2);
> > if (!NT_STATUS_IS_OK(status)) {
> > return false;
> > }
> > }
> >
> > return true;
> > }
> >
> > The function does:
> > - copies in the TCP/IP port bindings
>
> Only if it is enabled and this is normally not the case cause smbd can't
> handle rpc tcpip connection. This is why we developed the prefork stuff and
> have lsasd.
>
> This is normally and emtpy structure.
>
> > - registers ncacn_np pipes based on the IDL interface table
> > - registers the ncaclrpc pipe
> >
> > My question is: Is there a reason why this is not entirely table
> > driven, based on this IDL interface table:
>
> No, I think there is no reason.
>
> >
> > [
> > uuid("3919286a-b10c-11d0-9ba8-00c04fd92ef5"),
> > version(0.0),
> > endpoint("ncacn_np:[\\pipe\\lsarpc]", "ncacn_np:[\\pipe\\lsass]",
> > "ncacn_ip_tcp:", "ncalrpc:"),
> > pointer_default(unique),
> > helpstring("Active Directory Setup")
> > ] interface dssetup
> >
> > (this is used by dcerpc_binding_vector_add_np_default already).
> >
> > I'm not trying to poke blame or suggest that hard-coding it was not the
> > most expedient option available at the time. I'm just trying to
> > understand the why behind the code we have so far, as it seems I will be
> > needing to undertake some significant works in this area. It helps to
> > understand not just the actions, but the intentions of those who have
> > been before me. Naturally, I'll also keep you in the loop as I do the
> > work.
>
> It made it easier to do it somehow manually than relying on the IDL table for
> the service. For RPC over TCPIP we only open one port. Copying it and
> replacing the GUID was the easiest way to implement it. If you want to always
> rely on the idl then you can do that, but then you always have to pass all
> options like ip address and ports to the functions even if you don't need it.
>
> As it is now it was the simplest way to pass around a structure with all ip
> address and port combination we can have.
>
> I someone specifies ip addresses to listen on you need to open a random port
> on all of them and register each service for all of them on the endpoint
> mapper. So it was the easiest to setup the endpoint mapper structure and pass
> it down and only replace the GUID. I didn't want to introduce yet another
> structure to pass around the information.
>
> Maybe we should create more abstract functions for registering and have a
> public library which can be used by openchange to register their endpoints.
>
> > > We need(ed) to call rpc_spoolss_init() or if you connect over a named pipe
> > > to smbd, then smbd will tell the client that it doesn't know the rpc
> > > protocol and drop the connection. This registration is (was) needed to
> > > accept the connection and forward it over the named pipe proxy to the
> > > correct service, spoolssd.
> > >
> > > Maybe this has changed and isn't needed anymore. It was needed by the time
> > > I was doing the work. I think we need to try it and maybe make sure it
> > > isn't requried anymore.
> >
> > I'll do that. We should be able to put our RPC services into one of two
> > categories: Services that are embedded in the forked smbd SMB child
> > process, and external services (the rest). We should not need to
> > register external services except to the epmapper, and just fail
> > gracefully if we cannot find the socket.
>
> I agree. Maybe it is already working in the meantime. We just need to move the
> rpc_<service>_init() calls into the embedded case.
> > > > Given the support for automatically removing registrations when
> > > > processes shut down, I imagined it would need to be registred from the
> > > > same process.
> > >
> > > Do you talk about registered endpoints in smbd or rpc_<rpc>_init() now?
> >
> > I'm sorry, I was confused by the rpc_setup_lsarpc() call, being called
> > from main() -> dcesrv_ep_setup -> rpc_setup_lsarpc(). However, it is
> > guarded and the registration only applies in embedded mode.
> >
> > The rpc_lsarpc_init() function appears to be called from both that and
> > setup_lsasd(). I don't know if that matters.
>
> As you explained above it should only be called in smbd if it is embedded. The
> rpc_lsarpc_init() call was required to get the proxy connection to the
> external daemon working.
In which case, is my second patch from my initial mail
(0002-s3-rpc_server-Do-not-register-external-rpc-servers.patch) correct?
> > > We should differentiate between registering the process on epmd or make
> > > smbd aware of handling the connection for dssetup and forwarding it. If
> > > you mean the letter than we need to make sure that this will work.
> >
> > If possible, I would like to make 'smbd' essentially unaware of external
> > rpc pipes, just working on what sockets exist in the ncaclrpc/np
> > directory. Then epmd (wherever it is implemented) can deal with
> > registrations.
>
> I would like to have epmd in its own deamon and be started like smbd from
> s3fs. This was it could be used by s4 and s3/lsasd. I'm also fine if we create
> a library and fork it from s3/s4.
Thanks. I'll let you know what I'm proposing once I have a working
prototype.
Andrew Bartlett
--
Andrew Bartlett http://samba.org/~abartlet/
Authentication Developer, Samba Team http://samba.org
More information about the samba-technical
mailing list