libmsrpc for Samba 3

tridge at samba.org tridge at samba.org
Tue Jul 19 23:29:29 GMT 2005


Jerry,

 > Tridge, I looked at torture/rpc/*.c.  Is this what
 > you meant?

You are probably better off looking directly at the IDL files in
librpc/idl/*.idl as the client API is directly generated from those
files.


 > All of the client functions have a prototype
 > by fn( pipe *p, mem_ctx *ctx, rpc_struct *r ) where for
 > example, r could be defined as
 > 
 > struct svcctl_EnumServicesStatusW {
 > 	struct {
 > 		struct policy_handle *handle;/* [ref] */
 > 		uint32_t type;
 > 		uint32_t state;
 > 		uint32_t buf_size;
 > 		uint32_t *resume_handle;/* [unique] */
 > 	} in;
 > 
 > 	struct {
 > 		uint8_t *service;/* [size_is(buf_size)] */
 > 		uint32_t bytes_needed;
 > 		uint32_t services_returned;
 > 		uint32_t *resume_handle;/* [unique] */
 > 		WERROR result;
 > 	} out;
 > };
 > 
 > Is this what you were suggesting?  That the client fill in
 > the necessary components of r prior to the call ?

the client fills in the in.* components, and any [ref] pointers in the
out.* components. The server fills in the out.* components.

The trick is that the API is extremely consistent, which makes it
possible to write generic routines that deal with any type of rpc
call, using function pointers to the handling routines. This is also
what makes it possible for us to have both sync and async versions of
all calls.

 > Is so then Samba 4 has simply pushed the application
 > layer into what samba 3 uses for rpc_client/cli_*.c
 > and you interface is based on the CLI_DO_RPC interface
 > used by our newer client code (cli_spoolss.c in trunk,
 > cli_reg.c, etc ...).

There are similarities between the two approaches, but one is not
based on the other. The API in Samba4 is based directly on the IDL
files. The [in] parameters in an IDL function become in.* components,
the [out] parameters become out.* components and [in,out] parameters
appear in both in.* and out.*.

So to make the above call a client does this:

	struct svcctl_EnumServicesStatusW io;

	io.in.handle = h;
	io.in.type = SERVICE_TYPE_WIN32;
	io.in.state = SERVICE_STATE_ALL;
	io.in.buf_size = 0;
	io.in.resume_handle = &resume_handle;
	io.out.resume_handle = &resume_handle;

	status = dcerpc_svcctl_EnumServicesStatusW(p, mem_ctx, &io);

At first you might think it is easier to have a conventional function
interface, and have a win32 style function with 8 parameters, but I
have found that it is in fact much easier to program with the in.* and
out.* interface than the win32 style interface. The reason is that
with so many parameters of the same type it is incredibly easy to get
the call mixed up. By explicitly naming the parameters as you set them
you end up with much less error prone code.

This is similar to the trend in C99 to use named structure element
initialisers rather than unnamed. That has helped make C better
because just listing a dozen elements of the same type one after the
other is extremely error prone, whereas naming the structure elements,
while more verbose, leads to far fewer programmer errors.

The other reason I find it easier is that the natural way to print the
contents of the structures maps directly onto the way you write them
in code. So when you see a structure printed out your eye can match up
the elements very easily against your code. In a similar fashion the
way ethereal displays structures maps almost directly on to the way
you write the code.

 > So then I'm confused by your comment to me about using
 > a compatible client interface between Samba 3 and 4
 > for this library.  I'm not sure how I see that is possible.
 > Am I looking in the right place ?

Unless you adopted the auto-generated code from pidl I think it would
be a huge task to make a new rpc library for Samba3 be compatible with
the Samba4 API. What you perhaps could do is make the APIs as close as
possible so that it is less painful for users of the library to
transition between the two.

I don't think there is any question that the future of RPC in Samba
has got to be based on auto-generation from IDL. It is just far too
much manual work to do any other way. I think that means that if we
are going to be inventing a new RPC client API that we want people to
use that we should try to design that API to be able to fit in with
the auto-generated framework.

Cheers, Tridge


More information about the samba-technical mailing list