[jcifs] Samba4 IDL, RPCs, NDR Slight-of-hand, NdrBuffer, ...

Michael B Allen mba2000 at ioplex.com
Tue Jul 13 08:28:25 GMT 2004

Unfortunately I think our hope to use Samba4 IDL as-is to generate large
swaths of RPC functionality will not be realized. There are a variety
of "Samba-isms" that I would prefer to leave out in favor of an IDL
compiler that is closer to MIDL or the DCE spec so that there is a greater
potential for it to be used in different contexts (e.g. Jarapac, DCOM,
MAPI, etc). Most stuff like extension attributes (e.g. nodiscriminant,
value, flag) could just be ignored but will need to then compensate for
whatever it is these attributes do.

I think the plan right now is to simply copy over fragments of
IDL and refactor the compiler as necessary. I'm going to start by
getting NetServerEnumAll to work with Jarapac but I'm going to bypass a
boat-load of code. Instead of creating a single file I'm going to create
a directory with the interface name (e.g. "srvsvc") and then a class for
each operation (e.g. "NetShareEnumAll.java"). So the class for operation
"test4" (from the example in idlc package) might look like this:

public class test4 implements InputParameters, OutputParameters {

    public class info4 {
        public String name;
        public int type;
        public String comment;

        public void write(NetworkDataRepresentation ndr, NdrBuffer dst) {
            if (name == null) {
            } else {
        public void read(NetworkDataRepresentation ndr, NdrBuffer src) {
    public void write(NetworkDataRepresentation ndr) {
    public void read(NetworkDataRepresentation ndr) {
        NdrBuffer src = new NdrBuffer(ndr.getBuffer(), 16);
        int p;

        p = src.readLong();
        if (p != 0) { 
            if(info == null) { 
                info = new info4();
            info.read(ndr, src.getDeferred(12));
        p = src.readLong();
        if (p != 0) { 

    public String servername;
    public test3_type info;
    public int prefmaxlen;
    public int entriesread;
    public int totalentries;
    public int resume_handle;

    public test4(String servername,
                test3_type info,
                int prefmaxlen,
                int resume_handle) {
        this.servername = servername;
        this.info = info; 
        this.prefmaxlen = prefmaxlen;
        this.resume_handle = resume_handle;

It is noteworty that NdrBuffer is fairly different from Jarapac's
Buffer. I'm pretty sure it's going to be something like this:

public class NdrBuffer {
    byte[] buf;
    int index;
    NdrBuffer deferred; /* Behaves like a global variable */

     * Create an NdrBuffer with an index of 0 and a deferred index of
     * deferred. The deferred parameter cannot be zero.
    NdrBuffer(byte[] buf, int deferred) {
        this.buf = buf;
        if (deferred != 0) {
            this.deferred = NbtBuffer(buf, 0);
            this.deferred.index = deferred);
     * Get a new buffer with an index at the deferred location and advance
     * deferred location by advance.
    NdrBuffer getDeferred(int advance) {
        NdrBuffer nb = new NdrBuffer(buf, 0);
        nd.index = deferred.index;
        nb.deferred = deferred;
        deferred.index += advance;
        return nb;

The getDeferred method is where the slight-of-hand occurs. So the current
position and the deferred position are encoded at the same time but are
largely independent of one another. Simple!

As you can see this is all sort of add-hoc still (in fact the above is
incorrect because top-level pointers are not embedded at a deferred
location). The idl compiler currently generates C stubs so I need
to figure out how the Java stubs should look and then write the stub
generation routines.


Does Jarapac support server-side routines? Currently the idl compiler
generates server stubs but should I bother with the Java server stubs?


Any thoughts?


Greedo shoots first? Not in my Star Wars.

More information about the jcifs mailing list