jcifs-1.2.11 from tgz
authorFelix Schumacher <p0354740@isib001.(none)>
Wed, 6 Aug 2008 14:39:55 +0000 (16:39 +0200)
committerFelix Schumacher <p0354740@isib001.(none)>
Wed, 6 Aug 2008 14:39:55 +0000 (16:39 +0200)
Wed Nov 29 11:34:01 EST 2006
jcifs-1.2.11b released / SID Resolution

This release significantly expands the SID and ACE classes by using the
new MSRPC infrastructure to resolve SIDs to their associated account
names. A new SmbFile.getSecurity() method has been added which if called
with a boolean value of true will resolve the SIDs returned within the
ACE[] array such that SID.toString()/getDomainName()/getAccountName()
will return text about the account associated with that SID suitable for
display to users (e.g. MYDOM\alice, SYSTEM, etc). Documentation for all
associated methods and classes has been added.

32 files changed:
README.txt
build.xml
examples/GetSecurity.java [new file with mode: 0644]
examples/GrowWrite.java
examples/ListACL.java
examples/Makefile
examples/SidCacheTest.java [new file with mode: 0644]
examples/SidCrawler.java [new file with mode: 0644]
examples/SidFragment.java [new file with mode: 0644]
examples/SidLookup.java [new file with mode: 0644]
examples/run1.sh
examples/runtests.sh
examples/web.xml
patches/DnsSrv.patch [new file with mode: 0644]
patches/jcifs1.2.8_aclresolve.patch [deleted file]
src/jcifs/dcerpc/DcerpcBinding.java
src/jcifs/dcerpc/DcerpcHandle.java
src/jcifs/dcerpc/DcerpcMessage.java
src/jcifs/dcerpc/DcerpcPipeHandle.java
src/jcifs/dcerpc/UnicodeString.java [new file with mode: 0644]
src/jcifs/dcerpc/msrpc/LsaPolicyHandle.java [new file with mode: 0644]
src/jcifs/dcerpc/msrpc/LsarSidArrayX.java [new file with mode: 0644]
src/jcifs/dcerpc/msrpc/MsrpcLookupSids.java [new file with mode: 0644]
src/jcifs/dcerpc/msrpc/MsrpcLsarOpenPolicy2.java [new file with mode: 0644]
src/jcifs/dcerpc/msrpc/lsarpc.idl [new file with mode: 0644]
src/jcifs/dcerpc/msrpc/lsarpc.java [new file with mode: 0644]
src/jcifs/dcerpc/msrpc/srvsvc.idl
src/jcifs/smb/ACE.java
src/jcifs/smb/BufferCache.java
src/jcifs/smb/NtStatus.java
src/jcifs/smb/SID.java
src/jcifs/smb/SmbFile.java

index 305bbca..5e02bf1 100644 (file)
@@ -1,3 +1,15 @@
+Wed Nov 29 11:34:01 EST 2006
+jcifs-1.2.11b released / SID Resolution
+
+This release significantly expands the SID and ACE classes by using the
+new MSRPC infrastructure to resolve SIDs to their associated account
+names. A new SmbFile.getSecurity() method has been added which if called
+with a boolean value of true will resolve the SIDs returned within the
+ACE[] array such that SID.toString()/getDomainName()/getAccountName()
+will return text about the account associated with that SID suitable for
+display to users (e.g. MYDOM\alice, SYSTEM, etc). Documentation for all
+associated methods and classes has been added.
+
 Fri Nov 24 11:58:14 EST 2006
 jcifs-1.2.10 released / Minor Adjustments
 
index a2e023f..01931d9 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -1,7 +1,7 @@
 <project name="jcifs" default="usage" basedir=".">
 
-    <property name="version" value="1.2.10"/>
-    <property name="reldate" value="Nov 24, 2006"/>
+    <property name="version" value="1.2.11"/>
+    <property name="reldate" value="Dec 9, 2006"/>
 
     <target name="usage">
         <echo>
diff --git a/examples/GetSecurity.java b/examples/GetSecurity.java
new file mode 100644 (file)
index 0000000..84f9f1f
--- /dev/null
@@ -0,0 +1,14 @@
+import jcifs.smb.*;
+
+public class GetSecurity {
+
+    public static void main( String[] argv ) throws Exception {
+
+        SmbFile file = new SmbFile( argv[0] );
+        ACE[] security = file.getSecurity(true);
+
+        for (int ai = 0; ai < security.length; ai++) {
+            System.out.println(security[ai].toString());
+        }
+    }
+}
index f064338..69d0721 100644 (file)
@@ -4,7 +4,7 @@ import java.io.FileInputStream;
 
 public class GrowWrite {
 
-    static final int SIZE = 0x1FFF;
+    static final int SIZE = 0xFFF;
 
     public static void main( String argv[] ) throws Exception {
         int n, tot;
index c671c13..5db5783 100644 (file)
@@ -5,12 +5,19 @@ public class ListACL {
     public static void main( String[] args ) throws Exception {
         if (args.length < 1) {
             System.err.println( "usage: ListACL <smburl>\n" );
-            return 0;
+            return;
         }
         SmbFile f = new SmbFile( args[0] );
         ACE[] acl = f.getSecurity();
         for (int i = 0; i < acl.length; i++) {
             System.out.println( acl[i] );
+            SID sid = acl[i].getSID();
+            System.out.println("      toString: " + sid.toString());
+            System.out.println("   toSidString: " + sid.toSidString());
+            System.out.println("       getType: " + sid.getType());
+            System.out.println("   getTypeText: " + sid.getTypeText());
+            System.out.println(" getDomainName: " + sid.getDomainName());
+            System.out.println("getAccountName: " + sid.getAccountName());
         }
     }
 }
index 1051bdf..4eb71d0 100644 (file)
@@ -3,7 +3,7 @@ CLASSPATH=../build:.
 
 .SUFFIXES: .java .class
 
-CLASSFILES=InterruptedTest.class AllocInfo.class Append.class AuthListFiles.class CallNamedPipe.class CopyTo.class CreateFile.class Delete.class Equals.class Exists.class FileInfo.class FileOps.class FilterFiles.class Format.class GetDate.class GetDfsPath.class Get.class GetType.class GetURL.class GrowWrite.class HttpURL.class Interleave.class IsDir.class Length.class ListFiles.class List.class ListTypes.class Mkdir.class NodeStatus.class OpenExclusive.class PeekNamedPipe.class PipeTalk.class Put.class Query.class RenameTo.class SetAttrs.class SetTime.class SlowRead.class SlowWrite.class SmbCrawler.class SmbShell.class SmbTableFile.class SmbTableFileRecord.class T2Crawler.class TestRandomAccess.class TestSmbURL.class TestUnicode.class ThreadedNbtQuery.class ThreadedSmbCrawler.class ThreadedUniQuery.class Torture1.class Torture2.class TortureTest5.class TransactNamedPipe.class URLTest.class VerifyGuest.class VerifyIO.class VerifyReads.class
+CLASSFILES=SidCacheTest.class GetSecurity.class SidCrawler.class InterruptTest.class AllocInfo.class Append.class AuthListFiles.class CallNamedPipe.class CopyTo.class CreateFile.class Delete.class Equals.class Exists.class FileInfo.class FileOps.class FilterFiles.class Format.class GetDate.class GetDfsPath.class Get.class GetType.class GetURL.class GrowWrite.class HttpURL.class Interleave.class IsDir.class Length.class ListFiles.class List.class ListTypes.class Mkdir.class NodeStatus.class OpenExclusive.class PeekNamedPipe.class PipeTalk.class Put.class Query.class RenameTo.class SetAttrs.class SetTime.class SlowRead.class SlowWrite.class SmbCrawler.class SmbShell.class SmbTableFile.class SmbTableFileRecord.class T2Crawler.class TestRandomAccess.class TestSmbURL.class TestUnicode.class ThreadedNbtQuery.class ThreadedSmbCrawler.class ThreadedUniQuery.class Torture1.class Torture2.class TortureTest5.class TransactNamedPipe.class URLTest.class VerifyGuest.class VerifyIO.class VerifyReads.class
 
 all: ${CLASSFILES}
 
diff --git a/examples/SidCacheTest.java b/examples/SidCacheTest.java
new file mode 100644 (file)
index 0000000..8a8c349
--- /dev/null
@@ -0,0 +1,20 @@
+import jcifs.smb.*;
+
+public class SidCacheTest {
+
+    public static void main( String[] argv ) throws Exception {
+        long t1, t2, t3;
+        SmbFile file;
+        ACE[] security;
+        int ai;
+
+        file = new SmbFile(argv[0]);
+        t1 = System.currentTimeMillis();
+        security = file.getSecurity(true);
+        t2 = System.currentTimeMillis();
+        security = file.getSecurity(true);
+        t3 = System.currentTimeMillis();
+
+        System.out.println("dt1=" + (t2 - t1) + ",dt2=" + (t3 - t2) + " " + ((t2 - t1) / (t3 - t2)) + "x increase");
+    }
+}
diff --git a/examples/SidCrawler.java b/examples/SidCrawler.java
new file mode 100644 (file)
index 0000000..1b16b16
--- /dev/null
@@ -0,0 +1,61 @@
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.net.MalformedURLException;
+import java.io.IOException;
+
+import jcifs.smb.*;
+
+public class SidCrawler {
+
+    static final byte[] SP = "                                              ".getBytes();
+
+    static void printSpace(int count) {
+        if (count > SP.length)
+            count = SP.length;
+        System.out.write(SP, 0, count);
+    }
+
+    int maxDepth;
+
+    SidCrawler( int maxDepth ) {
+        this.maxDepth = maxDepth;
+    }
+
+    void traverse( SmbFile f, int depth ) throws MalformedURLException, IOException {
+        int indent = maxDepth - depth;
+
+        if( depth == 0 ) {
+            return;
+        }
+
+        SmbFile[] l = f.listFiles();
+
+        for(int i = 0; l != null && i < l.length; i++ ) {
+            try {
+                printSpace(indent * 4);
+                ACE[] acl = l[i].getSecurity(true);
+                System.out.println( l[i] );
+                for (int ai = 0; ai < acl.length; ai++) {
+                    printSpace((indent + 1) * 4);
+                    System.out.println("+ " + acl[ai].toString());
+                }
+                if( l[i].isDirectory() ) {
+                    traverse( l[i], depth - 1 );
+                }
+            } catch( IOException ioe ) {
+                System.out.println( l[i] + ":" );
+                ioe.printStackTrace( System.out );
+            }
+        }
+    }
+
+    public static void main(String[] argv) throws Exception {
+        if (argv.length < 2) {
+            System.err.println("usage: SidCrawler <smburl> <depth>");
+            return;
+        }
+        int depth = Integer.parseInt( argv[1] );
+        SidCrawler sc = new SidCrawler( depth );
+        sc.traverse( new SmbFile( argv[0] ), depth );
+    }
+}
diff --git a/examples/SidFragment.java b/examples/SidFragment.java
new file mode 100644 (file)
index 0000000..29b7683
--- /dev/null
@@ -0,0 +1,28 @@
+import jcifs.smb.*;
+
+public class SidFragment {
+
+    public static void main(String[] argv) throws Exception {
+        if (argv.length < 1) {
+            System.err.println("usage: SidFragment <textual domain sid>");
+            return;
+        }
+
+        SID domsid = new SID(argv[0]);
+        int rid = 1120;
+        int count = 150;
+        int si;
+
+        SID[] sids = new SID[count];
+
+        for (si = 0; si < sids.length; si++) {
+            sids[si] = new SID(domsid, rid++);
+        }
+
+        SID.resolveSids("ts0", null, sids);
+
+        for (si = 0; si < sids.length; si++) {
+            System.out.println(sids[si].toString());
+        }
+    }
+}
diff --git a/examples/SidLookup.java b/examples/SidLookup.java
new file mode 100644 (file)
index 0000000..2c2a7bf
--- /dev/null
@@ -0,0 +1,20 @@
+import jcifs.smb.*;
+
+public class SidLookup {
+
+    public static void main(String[] argv) throws Exception {
+        if (argv.length < 1) {
+            System.err.println("usage: SidLookup S-1-5-21-1496946806-2192648263-3843101252");
+            return;
+        }
+
+        SID sid = new SID(argv[0]);
+        sid.resolve("ts0", null);
+        System.out.println("      toString: " + sid.toString());
+        System.out.println("   toSidString: " + sid.toSidString());
+        System.out.println("       getType: " + sid.getType());
+        System.out.println("   getTypeText: " + sid.getTypeText());
+        System.out.println(" getDomainName: " + sid.getDomainName());
+        System.out.println("getAccountName: " + sid.getAccountName());
+    }
+}
index 286eef3..80b3da7 100644 (file)
@@ -5,7 +5,7 @@ CLASSPATH=../build:.
 PROPERTIES=../../miallen.prp
 RUN="${JAVA_HOME}/bin/java -cp ${CLASSPATH} -Djcifs.properties=${PROPERTIES}"
 
-SERVER=xp3
+SERVER=ts0
 SHARE=tmp
 WRITE_DIR=test/
 SRC_DIR=test/Junk
@@ -14,6 +14,9 @@ FILE1=test/Junk/10883563.doc
 URL_SHARE=smb://${SERVER}/${SHARE}/
 URL_WRITE_DIR=${URL_SHARE}${WRITE_DIR}
 
+[ "$1" = "SidCacheTest" ] && $RUN SidCacheTest ${URL_WRITE_DIR}
+[ "$1" = "GetSecurity" ] && $RUN GetSecurity ${URL_WRITE_DIR}
+[ "$1" = "SidCrawler" ] && $RUN SidCrawler ${URL_WRITE_DIR} 5
 [ "$1" = "InterruptTest" ] && $RUN InterruptTest ${URL_WRITE_DIR}Append.txt
 [ "$1" = "AllocInfo" ] && $RUN AllocInfo ${URL_SHARE}
 [ "$1" = "Append" ] && $RUN Append ${URL_WRITE_DIR}Append.txt
index 98ad6f8..235ded2 100644 (file)
@@ -5,7 +5,7 @@ CLASSPATH=../build:.
 PROPERTIES=../../miallen.prp
 RUN="${JAVA_HOME}/bin/java -cp ${CLASSPATH} -Djcifs.properties=${PROPERTIES}"
 
-SERVER=xp3
+SERVER=ts0
 SHARE=tmp
 WRITE_DIR=test/
 SRC_DIR=test/Junk
@@ -16,6 +16,9 @@ URL_WRITE_DIR=${URL_SHARE}${WRITE_DIR}
 
 set -x
 
+$RUN SidCacheTest ${URL_WRITE_DIR}
+$RUN GetSecurity ${URL_WRITE_DIR}
+$RUN SidCrawler ${URL_WRITE_DIR} 5
 $RUN InterruptTest ${URL_WRITE_DIR}Append.txt
 $RUN AllocInfo ${URL_SHARE}
 $RUN Append ${URL_WRITE_DIR}Append.txt
@@ -33,7 +36,7 @@ $RUN Get ${URL_SHARE}${FILE1}
 $RUN GetType ${URL_SHARE}
 $RUN GrowWrite ${URL_WRITE_DIR}GrowWrite.txt
 $RUN GetURL ${URL_WRITE_DIR}Append.txt
-$RUN HttpURL ${URL_WRITE_DIR}Append.txt
+$RUN HttpURL ${URL_WRITE_DIR} ../Append.txt
 $RUN Interleave ${URL_WRITE_DIR} 3
 $RUN IsDir ${URL_SHARE}${SRC_DIR}/
 $RUN Length ${URL_SHARE}${FILE1}
index b5f61e4..5a65b1e 100644 (file)
@@ -16,7 +16,7 @@
 
     <init-param>
         <param-name>jcifs.smb.client.username</param-name>
-        <param-value>jcifsmachacct</param-value>
+        <param-value>jcifssvcacct</param-value>
     </init-param>
     <init-param>
         <param-name>jcifs.smb.client.password</param-name>
diff --git a/patches/DnsSrv.patch b/patches/DnsSrv.patch
new file mode 100644 (file)
index 0000000..d89f8e2
--- /dev/null
@@ -0,0 +1,102 @@
+diff -Naur old-src/jcifs/smb/SmbSession.java src/jcifs/smb/SmbSession.java
+--- old-src/jcifs/smb/SmbSession.java   2006-11-29 12:12:52.000000000 -0500
++++ src/jcifs/smb/SmbSession.java   2006-12-01 06:52:28.498008700 -0500
+@@ -18,6 +18,8 @@
+ package jcifs.smb;
++import java.util.ArrayList;
++import java.util.List;
+ import java.util.Vector;
+ import java.util.Enumeration;
+ import java.net.InetAddress;
+@@ -26,6 +28,11 @@
+ import jcifs.UniAddress;
+ import jcifs.netbios.NbtAddress;
++import javax.naming.NamingException;
++
++import javax.naming.directory.Attributes;
++import javax.naming.directory.DirContext;
++import javax.naming.directory.InitialDirContext;
+ /**
+  * The class represents a user's session established with an SMB/CIFS
+  * server. This class is used internally to the jCIFS library however
+@@ -63,12 +70,11 @@
+     private static final int CACHE_POLICY =
+                 Config.getInt( "jcifs.netbios.cachePolicy", 60 * 10 ) * 60; /* 10 hours */
+-    static NbtAddress[] dc_list = null;
++    static UniAddress[] dc_list = null;
+     static long dc_list_expiration;
+     static int dc_list_counter;
+-    private static NtlmChallenge interrogate( NbtAddress addr ) throws SmbException {
+-        UniAddress dc = new UniAddress( addr );
++    private static NtlmChallenge interrogate( UniAddress dc ) throws SmbException {
+         SmbTransport trans = SmbTransport.getSmbTransport( dc, 0 );
+         if (USERNAME == null) {
+             trans.connect();
+@@ -95,13 +101,59 @@
+ do {
+             if (dc_list_expiration < now) {
+                 dc_list_expiration = now + CACHE_POLICY * 1000L;
+-                NbtAddress[] list = NbtAddress.getAllByName( DOMAIN, 0x1C, null, null );
+-                if (list != null && list.length > 0) {
++                UniAddress[] list = null;
++                if (NbtAddress.getWINSAddress() != null) {
++                    NbtAddress[] nbt_list = NbtAddress.getAllByName( DOMAIN,
++                            0x1C, null, null );
++                    if (nbt_list != null && nbt_list.length > 0) {
++                        list = new UniAddress[nbt_list.length];
++                        for (int i = 0; i < list.length; i++) {
++                            list[i] = new UniAddress(nbt_list[i]);
++                        }
++                    }
++                } else {
++                    try {
++                        DirContext context = new InitialDirContext();
++                        Attributes attributes = context.getAttributes(
++                                "dns:/_ldap._tcp.dc._msdcs." + DOMAIN,
++                                        new String[] { "SRV" });
++                        Enumeration values = attributes.get("SRV").getAll();
++                        List results = new ArrayList();
++                        while (values.hasMoreElements()) {
++                            String value = (String) values.nextElement();
++                            value = value.replaceFirst(
++                                    "^\\d* \\d* \\d+ (.*)\\.$", "$1");
++                            try {
++                                InetAddress server =
++                                        InetAddress.getByName(value);
++                                results.add(new UniAddress(server));
++                            } catch (UnknownHostException ex) {
++                                if (SmbTransport.log.level >= 2) {
++                                    SmbTransport.log.println(
++                                            "Unable to resolve DC SRV entry: " +
++                                                    value);
++                                    if (SmbTransport.log.level > 2) {
++                                        ex.printStackTrace(SmbTransport.log);
++                                    }
++                                }
++                            }
++                        }
++                        if (!results.isEmpty()) {
++                            list = (UniAddress[])
++                                    results.toArray(new UniAddress[0]);
++                        }
++                    } catch (NamingException ne) {
++                        if (SmbTransport.log.level > 2) {
++                            ne.printStackTrace(SmbTransport.log);
++                        }
++                    }
++                }
++                if (list != null) {
+                     dc_list = list;
+                 } else { /* keep using the old list */
+                     dc_list_expiration = now + 1000 * 60 * 15; /* 15 min */
+                     if (SmbTransport.log.level >= 2) {
+-                        SmbTransport.log.println( "Failed to retrieve DC list from WINS" );
++                        SmbTransport.log.println( "Failed to retrieve DC list" );
+                     }
+                 }
+             }
diff --git a/patches/jcifs1.2.8_aclresolve.patch b/patches/jcifs1.2.8_aclresolve.patch
deleted file mode 100644 (file)
index 5fadcd7..0000000
+++ /dev/null
@@ -1,898 +0,0 @@
-diff -N -r Code/jcifs_1.2.8/src/jcifs/rpc/LsaRPC.java temp/jcifs_1.2.8/src/jcifs/rpc/LsaRPC.java
-1,124d0
-< package jcifs.rpc;
-< 
-< import java.io.IOException;
-< import java.io.UnsupportedEncodingException;
-< import java.util.Properties;
-< 
-< import jcifs.smb.NtStatus;
-< import jcifs.smb.ACE;
-< import jcifs.smb.SID;
-< 
-< /**
-<  * @author Martin Pedersen, mdp@visanti.com
-<  *
-<  */
-< public class LsaRPC extends LsaStub {
-< 
-<   String servername;
-< 
-<   public LsaRPC(String servername) {
-<       init(servername,null);
-<   }
-<   
-<   public LsaRPC(String servername, Properties prop) {
-<       init(servername,prop);
-<   }
-<   
-<   private void init(String servername, Properties prop) {
-<       this.servername = servername;
-<       setAddress("ncacn_np:" + servername + "[\\PIPE\\lsarpc]");
-<       if(prop!=null)
-<           setProperties(prop);
-<   }
-<   
-<   private static String uniCodeToString(UnicodeString in) throws UnsupportedEncodingException {
-<       if(in==null || (in.length==0 && in.buffer==null)) {
-<           return null;
-<       }
-<       byte[] s = new byte[in.length];
-<       for(int idx=0; idx < in.buffer.length; idx++) {
-<           int p = idx*2;
-<           s[p] = (byte)(in.buffer[idx] & 0x00FF);
-<           s[p+1] = (byte) (in.buffer[idx] & 0xFF00);
-<       }
-<       return new String(s,"UTF-16LE");
-<   }
-<   
-<   private RpcTypes.policy_handle openPolicy() throws IOException {
-<       RpcTypes.policy_handle handle = new RpcTypes.policy_handle();
-<       ObjectAttributes attrs = new ObjectAttributes();
-<       QosInfo qos = new QosInfo();
-< 
-<       handle.uuid = new RpcTypes.uuid_t();
-< 
-<       qos.length = 12;
-<       qos.impersonation_level = 2;
-<       qos.context_mode = 1;
-< 
-<       attrs.length = 24;
-<       attrs.security_quality_of_service = qos;
-< 
-<       OpenPolicy req = new OpenPolicy("\\", attrs, 0x02000000, handle);
-<       call(0, req);
-<       return handle;
-<   }
-<   private void closePolicy(RpcTypes.policy_handle handle) throws IOException {
-<       ClosePolicy req = new ClosePolicy(handle);
-<       call(0, req);
-<   }
-<   
-<   private RpcTypes.sid_t SIDToRpcType(SID p_sid) {
-<       RpcTypes.sid_t val = new RpcTypes.sid_t();
-<       val.revision = p_sid.getRevision();
-<       val.identifier_authority = new byte[6];
-<       int[] subAuth = p_sid.getSubAuthority();
-<       val.sub_authority_count = (byte)subAuth.length;
-<       val.sub_authority = new int[val.sub_authority_count];
-<       for(int idx=0; idx < val.sub_authority_count; idx++) {
-<           val.sub_authority[idx] = subAuth[idx];
-<       }
-<       byte[] b = p_sid.getIdentifierAuthority();
-<       for(int idx=0; idx < b.length; idx++) {
-<           val.identifier_authority[idx] = b[idx];
-<       }
-<       return val;     
-<   }
-<   
-<   /**
-<    * 
-<    * @param aces Array of ACE/SIDs to be resolved. The input array is modified with the resolved name
-<    * @throws IOException
-<    */
-<   public void lookupSids(ACE[] aces) throws IOException {
-<       RpcTypes.policy_handle handle = null;
-<       handle = openPolicy();
-<       RefDomainList rd = new RefDomainList();
-<       rd.count=0;
-<       TransNameArray tna = new TransNameArray();
-<       
-<       SidArray sa = new SidArray();
-<       sa.num_sids=aces.length;
-<       sa.sids= new SidPtr[sa.num_sids];
-<       for(int idx = 0; idx < sa.num_sids; idx++) {
-<           sa.sids[idx] = new SidPtr();
-<           sa.sids[idx].sid= SIDToRpcType(aces[idx].getSID());
-<       }
-<       
-<       LookupSids ls = new LookupSids(handle,sa,rd,tna,(short)1,0);
-<       call(0,ls);
-<       if(ls.retval==NtStatus.NT_STATUS_OK ||
-<               ls.retval==NtStatus.NT_STATUS_SOME_NOT_MAPPED) {
-<           for(int idx = 0; idx < tna.count; idx++) {
-<               int type = tna.names[idx].sid_type;
-<               if(type != SID.TYPE_UNKNOWN) {
-<                   String domain = uniCodeToString(rd.domains[tna.names[idx].sid_index].name);
-<                   String name = uniCodeToString(tna.names[idx].name);
-<                   aces[idx].getSID().setResolved(domain,name,type);
-<               }
-<           }
-<       }
-<       closePolicy(handle);
-<       detach();
-<   }
-< }
-< 
-diff -N -r Code/jcifs_1.2.8/src/jcifs/rpc/LsaStub.java temp/jcifs_1.2.8/src/jcifs/rpc/LsaStub.java
-1,485d0
-< package jcifs.rpc;
-< import rpc.*;
-< import ndr.*;
-< 
-< public class LsaStub extends Stub {
-< 
-<     protected String getSyntax() {
-<         return "12345778-1234-abcd-ef00-0123456789ab:0.0";
-<     }
-< 
-<     public static class UnicodeString extends NdrObject {
-< 
-<         public short length=0;
-<         public short maximum_length=0;
-<         public short[] buffer;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_short(length);
-<             _dst.enc_ndr_short(maximum_length);
-<             _dst.enc_ndr_referent(buffer, 1);
-< 
-<             int _buffers = maximum_length / 2;
-<             _dst.enc_ndr_long(_buffers);
-<             _dst.enc_ndr_long(0);
-<             int _bufferl = maximum_length / 2;
-<             _dst.enc_ndr_long(_bufferl);
-<             for (int _i = 0; _i < _bufferl; _i++) {
-<                 _dst.enc_ndr_short(buffer[_i]);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             length = (short)_src.dec_ndr_short();
-<             maximum_length = (short)_src.dec_ndr_short();
-<             int _bufferp = _src.dec_ndr_long();
-< 
-<             int _buffers = _src.dec_ndr_long();
-<             _src.dec_ndr_long();
-<             int _bufferl = _src.dec_ndr_long();
-<             int _bufferi = _src.index;
-<             _src.advance(2 * _bufferl);
-< 
-<             _src = _src.derive(_bufferi);
-<             if (buffer == null) {
-<                 if (_buffers > 0xFFFF) throw new NdrException("invalid array dimensions");
-<                 buffer = new short[_buffers];
-<             }
-<             for (int _i = 0; _i < _bufferl; _i++) {
-<                 buffer[_i] = (short)_src.dec_ndr_short();
-<             }
-<         }
-<     }
-<     public static class QosInfo extends NdrObject {
-< 
-<         public int length;
-<         public short impersonation_level;
-<         public byte context_mode;
-<         public byte effective_only;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_long(length);
-<             _dst.enc_ndr_short(impersonation_level);
-<             _dst.enc_ndr_small(context_mode);
-<             _dst.enc_ndr_small(effective_only);
-< 
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             length = (int)_src.dec_ndr_long();
-<             impersonation_level = (short)_src.dec_ndr_short();
-<             context_mode = (byte)_src.dec_ndr_small();
-<             effective_only = (byte)_src.dec_ndr_small();
-< 
-<         }
-<     }
-<     public static class ObjectAttributes extends NdrObject {
-< 
-<         public int length;
-<         public NdrSmall root_directory;
-<         public UnicodeString object_name;
-<         public int attributes;
-<         public int security_descriptor;
-<         public QosInfo security_quality_of_service;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_long(length);
-<             _dst.enc_ndr_referent(root_directory, 1);
-<             _dst.enc_ndr_referent(object_name, 1);
-<             _dst.enc_ndr_long(attributes);
-<             _dst.enc_ndr_long(security_descriptor);
-<             _dst.enc_ndr_referent(security_quality_of_service, 1);
-< 
-<             if (root_directory != null) {
-<                 _dst = _dst.deferred;
-<                 root_directory.encode(ndr, _dst);
-<             }
-<             if (object_name != null) {
-<                 _dst = _dst.deferred;
-<                 object_name.encode(ndr, _dst);
-<             }
-<             if (security_quality_of_service != null) {
-<                 _dst = _dst.deferred;
-<                 security_quality_of_service.encode(ndr, _dst);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             length = (int)_src.dec_ndr_long();
-<             int _root_directoryp = _src.dec_ndr_long();
-<             int _object_namep = _src.dec_ndr_long();
-<             attributes = (int)_src.dec_ndr_long();
-<             security_descriptor = (int)_src.dec_ndr_long();
-<             int _security_quality_of_servicep = _src.dec_ndr_long();
-< 
-<             if (_root_directoryp != 0) {
-<                 _src = _src.deferred;
-<                 root_directory.decode(ndr, _src);
-<             }
-<             if (_object_namep != 0) {
-<                 _src = _src.deferred;
-<                 object_name.decode(ndr, _src);
-<             }
-<             if (_security_quality_of_servicep != 0) {
-<                 _src = _src.deferred;
-<                 security_quality_of_service.decode(ndr, _src);
-<             }
-<         }
-<     }
-< 
-<     public static class ClosePolicy extends NdrObject {
-< 
-<         public int getOpnum() { return 0x00; }
-< 
-<         public int retval;
-<         public RpcTypes.policy_handle handle;
-< 
-<         public ClosePolicy(RpcTypes.policy_handle handle) {
-<             this.handle = handle;
-<         }
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             handle.encode(ndr, _dst);
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             handle.decode(ndr, _src);
-<             retval = (int)_src.dec_ndr_long();
-<         }
-<     }
-<     public static class OpenPolicy extends NdrObject {
-< 
-<         public int getOpnum() { return 0x2c; }
-< 
-<         public int retval;
-<         public String system_name;
-<         public ObjectAttributes object_attributes;
-<         public int desired_access;
-<         public RpcTypes.policy_handle policy_handle;
-< 
-<         public OpenPolicy(String system_name,
-<                     ObjectAttributes object_attributes,
-<                     int desired_access,
-<                     RpcTypes.policy_handle policy_handle) {
-<             this.system_name = system_name;
-<             this.object_attributes = object_attributes;
-<             this.desired_access = desired_access;
-<             this.policy_handle = policy_handle;
-<         }
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_referent(system_name, 1);
-<                 _dst.enc_ndr_string(system_name);
-<             object_attributes.encode(ndr, _dst);
-<             _dst.enc_ndr_long(desired_access);
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             policy_handle.decode(ndr, _src);
-<             retval = (int)_src.dec_ndr_long();
-<         }
-<     }
-<     public static class TranslatedName extends NdrObject {
-< 
-<         public short sid_type;
-<         public UnicodeString name = new UnicodeString();
-<         public int sid_index;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_short(sid_type);
-<             _dst.enc_ndr_short(name.length);
-<             _dst.enc_ndr_short(name.maximum_length);
-<             _dst.enc_ndr_referent(name.buffer, 1);
-<             _dst.enc_ndr_long(sid_index);
-< 
-<             int _name_buffers = name.maximum_length / 2;
-<             _dst.enc_ndr_long(_name_buffers);
-<             _dst.enc_ndr_long(0);
-<             int _name_bufferl = name.maximum_length / 2;
-<             _dst.enc_ndr_long(_name_bufferl);
-< 
-<             for (int _i = 0; _i < _name_bufferl; _i++) {
-<                 _dst.enc_ndr_short(name.buffer[_i]);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             sid_type = (short)_src.dec_ndr_short();
-<             _src.dec_ndr_short(); // ????
-<             name.length = (short)_src.dec_ndr_short();
-<             name.maximum_length = (short)_src.dec_ndr_short();
-<             int _name_bufferp = _src.dec_ndr_long();
-<             sid_index = (int)_src.dec_ndr_long();
-< 
-<             int _name_buffers = _src.dec_ndr_long();
-<             _src.dec_ndr_long();
-<             int _name_bufferl = _src.dec_ndr_long();
-< 
-<             if (name.buffer == null) {
-<                 if (_name_buffers > 0xFFFF) throw new NdrException("invalid array dimensions");
-<                 name.buffer = new short[_name_buffers];
-<             }
-<             for (int _i = 0; _i < _name_bufferl; _i++) {
-<                 name.buffer[_i] = (short)_src.dec_ndr_short();
-<             }
-<         }
-<     }
-<     public static class TransNameArray extends NdrObject {
-< 
-<         public int count;
-<         public TranslatedName[] names;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_long(count);
-< 
-<             int _namess = count;
-<             _dst.enc_ndr_long(_namess);
-< 
-<             for (int _i = 0; _i < _namess; _i++) {
-<                 names[_i].encode(ndr, _dst);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             count = (int)_src.dec_ndr_long();
-<             int _namesp = _src.dec_ndr_long();
-<             if(_namesp==0)
-<               return;
-< 
-<             int _namess = _src.dec_ndr_long();
-<             if (names == null) {
-<                 if (_namess > 0xFFFF) throw new NdrException("invalid array dimensions");
-<                 names = new TranslatedName[_namess];
-<             }
-<             for (int _i = 0; _i < _namess; _i++) {
-<                 if (names[_i] == null) {
-<                     names[_i] = new TranslatedName();
-<                 }
-<                 names[_i].sid_type = (short)_src.dec_ndr_short();
-<                 _src.dec_ndr_short(); // ????
-<                 names[_i].name.maximum_length = (short)_src.dec_ndr_short();
-<                 int _size = _src.dec_ndr_short();
-<                 int _charp = _src.dec_ndr_long();
-<                 names[_i].sid_index=_src.dec_ndr_long();
-<             }
-<             for (int _i = 0; _i < _namess; _i++) {
-<               int _buflen = names[_i].name.maximum_length/2;
-<               if(_buflen > 0) {
-<                   _src.dec_ndr_long(); // Max Count
-<                   _src.dec_ndr_long(); // Offset 
-<                   _src.dec_ndr_long(); // Actual Count
-<                   
-<                   names[_i].name.length=(short)(_buflen*2);
-<                   names[_i].name.buffer=new short[_buflen];
-<                   for(int idx=0; idx < _buflen; idx++) {
-<                       names[_i].name.buffer[idx]=(short)_src.dec_ndr_short();
-<                   }
-<               }
-<             }
-< 
-<         }
-<     }
-<     public static class SidPtr extends NdrObject {
-< 
-<         public RpcTypes.sid_t sid;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             if (sid != null) {
-<                 _dst = _dst.deferred;
-<                 sid.encode(ndr, _dst);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             int _sidp = _src.dec_ndr_long();
-< 
-<             if (_sidp != 0) {
-<                 _src = _src.deferred;
-<                 sid.decode(ndr, _src);
-<             }
-<         }
-<     }
-<     public static class SidArray extends NdrObject {
-< 
-<         public int num_sids;
-<         public SidPtr[] sids;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_long(num_sids);
-<             _dst.enc_ndr_referent(sids, 1);
-< 
-<             int _sidss = num_sids;
-<             _dst.enc_ndr_long(_sidss);
-< 
-<             for(int _i=0; _i < _sidss; _i++) {
-<               _dst.enc_ndr_referent(sids[_i], 1);
-<             }
-<             
-<             for (int _i = 0; _i < _sidss; _i++) {
-<                 sids[_i].encode(ndr, _dst);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             num_sids = (int)_src.dec_ndr_long();
-<             int _sidsp = _src.dec_ndr_long();
-< 
-<             int _sidss = _src.dec_ndr_long();
-<             int _sidsi = _src.index;
-<             _src.advance(4 * _sidss);
-< 
-<             _src = _src.derive(_sidsi);
-<             if (sids == null) {
-<                 if (_sidss > 0xFFFF) throw new NdrException("invalid array dimensions");
-<                 sids = new SidPtr[_sidss];
-<             }
-<             for (int _i = 0; _i < _sidss; _i++) {
-<                 if (sids[_i] == null) {
-<                     sids[_i] = new SidPtr();
-<                 }
-<                 sids[_i].decode(ndr, _src);
-<             }
-<         }
-<     }
-<     public static class TrustInformation extends NdrObject {
-< 
-<         public UnicodeString name = new UnicodeString();
-<         public RpcTypes.sid_t sid = new RpcTypes.sid_t();
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_short(name.length);
-<             _dst.enc_ndr_short(name.maximum_length);
-<             _dst.enc_ndr_referent(name.buffer, 1);
-<             _dst.enc_ndr_referent(sid, 1);
-< 
-<             int _name_buffers = name.maximum_length / 2;
-<             _dst.enc_ndr_long(_name_buffers);
-<             _dst.enc_ndr_long(0);
-<             int _name_bufferl = name.maximum_length / 2;
-<             _dst.enc_ndr_long(_name_bufferl);
-< 
-<             for (int _i = 0; _i < _name_bufferl; _i++) {
-<                 _dst.enc_ndr_short(name.buffer[_i]);
-<             }
-<             if (sid != null) {
-<                 _dst = _dst.deferred;
-<                 sid.encode(ndr, _dst);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             name.length = (short)_src.dec_ndr_short();
-<             name.maximum_length = (short)_src.dec_ndr_short();
-<             int _name_bufferp = _src.dec_ndr_long();
-<             int _sidp = _src.dec_ndr_long();
-< 
-<             int _name_buffers = _src.dec_ndr_long();
-<             _src.dec_ndr_long();
-<             int _name_bufferl = _src.dec_ndr_long();
-< 
-<             if (name.buffer == null) {
-<                 if (_name_buffers > 0xFFFF) throw new NdrException("invalid array dimensions");
-<                 name.buffer = new short[_name_buffers];
-<             }
-<             for (int _i = 0; _i < _name_bufferl; _i++) {
-<                 name.buffer[_i] = (short)_src.dec_ndr_short();
-<             }
-<             if (_sidp != 0) {
-<               _src.dec_ndr_short();
-<               _src.dec_ndr_long();
-<                 sid.decode(ndr, _src);
-<             }
-<         }
-<     }
-<     public static class RefDomainList extends NdrObject {
-< 
-<         public int count;
-<         public TrustInformation[] domains;
-<         public int max_count;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_long(count);
-<             _dst.enc_ndr_referent(domains, 1);
-<             _dst.enc_ndr_long(max_count);
-< 
-<             int _domainss = count;
-<             _dst.enc_ndr_long(_domainss);
-< 
-<             for (int _i = 0; _i < _domainss; _i++) {
-<                 domains[_i].encode(ndr, _dst);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<           int _domainlp = _src.dec_ndr_long();
-<           if(_domainlp==0)
-<               return;
-<             count = (int)_src.dec_ndr_long();
-<             int _domainsp = _src.dec_ndr_long();
-<             max_count = (int)_src.dec_ndr_long();
-<             if(_domainsp==0)
-<               return;
-<             int _domainss = _src.dec_ndr_long();
-< 
-<             if (domains == null) {
-<                 if (_domainss > 0xFFFF) throw new NdrException("invalid array dimensions");
-<                 domains = new TrustInformation[_domainss];
-<             }
-<             for (int _i = 0; _i < _domainss; _i++) {
-<                 if (domains[_i] == null) {
-<                     domains[_i] = new TrustInformation();
-<                 }
-<                 short _len =(short)_src.dec_ndr_short();
-<                 short _size =(short)_src.dec_ndr_short();
-<                 int _charref = _src.dec_ndr_long();
-<                 if(_charref==0) {
-<                     domains[_i].name=null;
-<                 }
-<                 int _sidref  = _src.dec_ndr_long();
-<             }
-<             for (int _i = 0; _i < _domainss; _i++) {
-<                 if(domains[_i].name!=null) {
-<                     domains[_i].name.maximum_length = (short)(_src.dec_ndr_long()*2);
-<                     int _offset = _src.dec_ndr_long();
-<                     int _buflen = _src.dec_ndr_long();
-<                     domains[_i].name.length = (short)(_buflen*2);
-<                     domains[_i].name.buffer = new short[_buflen];
-<                     for(int idx = 0; idx < _buflen; idx++) {
-<                         domains[_i].name.buffer[idx] = (short)_src.dec_ndr_short();
-<                     }
-<                 }
-<               int _count = _src.dec_ndr_long();
-<               domains[_i].sid.decode(ndr,_src);
-<             }
-<         }
-<     }
-<     public static class LookupSids extends NdrObject {
-< 
-<         public int getOpnum() { return 0x0f; }
-< 
-<         public int retval;
-<         public RpcTypes.policy_handle handle;
-<         public SidArray sids;
-<         public RefDomainList domains;
-<         public TransNameArray names;
-<         public short level;
-<         public int numMapped;
-< 
-<         public LookupSids(RpcTypes.policy_handle handle,
-<                     SidArray sids,
-<                     RefDomainList domains,
-<                     TransNameArray names,
-<                     short level,
-<                     int count) {
-<             this.handle = handle;
-<             this.sids = sids;
-<             this.domains = domains;
-<             this.names = names;
-<             this.level = level;
-<             this.numMapped = count;
-<         }
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             handle.encode(ndr, _dst);
-<             sids.encode(ndr, _dst);
-<             names.encode(ndr, _dst);
-<             _dst.enc_ndr_short(level);
-<             _dst.enc_ndr_long(numMapped);
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             domains.decode(ndr, _src);
-<             names.decode(ndr, _src);
-<             numMapped = (int)_src.dec_ndr_long();
-<             retval = (int)_src.dec_ndr_long();
-<         }
-<     }
-< }
-diff -N -r Code/jcifs_1.2.8/src/jcifs/rpc/RpcTypes.java temp/jcifs_1.2.8/src/jcifs/rpc/RpcTypes.java
-1,128d0
-< package jcifs.rpc;
-< import ndr.*;
-< 
-< public class RpcTypes {
-< 
-<     public static class uuid_t extends NdrObject {
-< 
-<         public int time_low;
-<         public short time_mid;
-<         public short time_hi_and_version;
-<         public byte clock_seq_hi_and_reserved;
-<         public byte clock_seq_low;
-<         public byte[] node;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_long(time_low);
-<             _dst.enc_ndr_short(time_mid);
-<             _dst.enc_ndr_short(time_hi_and_version);
-<             _dst.enc_ndr_small(clock_seq_hi_and_reserved);
-<             _dst.enc_ndr_small(clock_seq_low);
-<             int _nodes = 6;
-<             for (int _i = 0; _i < _nodes; _i++) {
-<                 _dst.enc_ndr_small(node[_i]);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             time_low = (int)_src.dec_ndr_long();
-<             time_mid = (short)_src.dec_ndr_short();
-<             time_hi_and_version = (short)_src.dec_ndr_short();
-<             clock_seq_hi_and_reserved = (byte)_src.dec_ndr_small();
-<             clock_seq_low = (byte)_src.dec_ndr_small();
-<             int _nodes = 6;
-<             int _nodei = _src.index;
-<             _src.advance(6);
-< 
-<             _src = _src.derive(_nodei);
-<             if (node == null) {
-<                 if (_nodes > 0xFFFF) throw new NdrException("invalid array dimensions");
-<                 node = new byte[_nodes];
-<             }
-<             for (int _i = 0; _i < _nodes; _i++) {
-<                 node[_i] = (byte)_src.dec_ndr_small();
-<             }
-<         }
-<     }
-<     public static class policy_handle extends NdrObject {
-< 
-<         public int type;
-<         public uuid_t uuid;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_long(type);
-<             _dst.enc_ndr_long(uuid.time_low);
-<             _dst.enc_ndr_short(uuid.time_mid);
-<             _dst.enc_ndr_short(uuid.time_hi_and_version);
-<             _dst.enc_ndr_small(uuid.clock_seq_hi_and_reserved);
-<             _dst.enc_ndr_small(uuid.clock_seq_low);
-<             int _uuid_nodes = 6;
-<             for (int _i = 0; _i < _uuid_nodes; _i++) {
-<                 _dst.enc_ndr_small(uuid.node[_i]);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {
-<             type = (int)_src.dec_ndr_long();
-<             uuid.time_low = (int)_src.dec_ndr_long();
-<             uuid.time_mid = (short)_src.dec_ndr_short();
-<             uuid.time_hi_and_version = (short)_src.dec_ndr_short();
-<             uuid.clock_seq_hi_and_reserved = (byte)_src.dec_ndr_small();
-<             uuid.clock_seq_low = (byte)_src.dec_ndr_small();
-<             int _uuid_nodes = 6;
-<             int _uuid_nodei = _src.index;
-<             _src.advance(6);
-< 
-<             _src = _src.derive(_uuid_nodei);
-<             if (uuid.node == null) {
-<                 if (_uuid_nodes > 0xFFFF) throw new NdrException("invalid array dimensions");
-<                 uuid.node = new byte[_uuid_nodes];
-<             }
-<             for (int _i = 0; _i < _uuid_nodes; _i++) {
-<                 uuid.node[_i] = (byte)_src.dec_ndr_small();
-<             }
-<         }
-<     }
-<     public static class sid_t extends NdrObject {
-< 
-<         public byte revision;
-<         public byte sub_authority_count;
-<         public byte[] identifier_authority;
-<         public int[] sub_authority;
-< 
-<         public void encode(NetworkDataRepresentation ndr, NdrBuffer _dst) throws NdrException {
-<             _dst.enc_ndr_long(sub_authority_count);
-<             _dst.enc_ndr_small(revision);
-<             _dst.enc_ndr_small(sub_authority_count);
-<             int _identifier_authoritys = 6;
-<             int _sub_authoritys = sub_authority_count;
-< 
-<             for (int _i = 0; _i < _identifier_authoritys; _i++) {
-<                 _dst.enc_ndr_small(identifier_authority[_i]);
-<             }
-<             for (int _i = 0; _i < _sub_authoritys; _i++) {
-<                 _dst.enc_ndr_long(sub_authority[_i]);
-<             }
-<         }
-<         public void decode(NetworkDataRepresentation ndr, NdrBuffer _src) throws NdrException {            
-<             revision = (byte)_src.dec_ndr_small();
-<             sub_authority_count = (byte)_src.dec_ndr_small();
-<             int _sub_authoritys = sub_authority_count;
-<             int _identifier_authoritys = 6;
-< 
-<             if (identifier_authority == null) {
-<                 if (_identifier_authoritys > 0xFFFF) throw new NdrException("invalid array dimensions");
-<                 identifier_authority = new byte[_identifier_authoritys];
-<             }
-<             for (int _i = 0; _i < _identifier_authoritys; _i++) {
-<                 identifier_authority[_i] = (byte)_src.dec_ndr_small();
-<             }
-< 
-<             if (sub_authority == null) {
-<                 if (_sub_authoritys > 0xFFFF) throw new NdrException("invalid array dimensions");
-<                 sub_authority = new int[_sub_authoritys];
-<             }
-<             for (int _i = 0; _i < _sub_authoritys; _i++) {
-<                 sub_authority[_i] = (int)_src.dec_ndr_long();
-<             }
-<         }
-<     }
-< }
-diff -N -r Code/jcifs_1.2.8/src/jcifs/smb/ACE.java temp/jcifs_1.2.8/src/jcifs/smb/ACE.java
-7,14c7,24
-<   // NT ACE Flags
-<   public final static byte FLAG_AUDIT_FAILED      = (byte)0x80;
-<   public final static byte FLAG_AUDIT_SUCCESS     = (byte)0x40;
-<   public final static byte FLAG_INHERIT_PARENT    = (byte)0x10;
-<   public final static byte FLAG_INHERIT_ONLY      = (byte)0x08;
-<   public final static byte FLAG_INHERIT_NONPROP   = (byte)0x04;
-<   public final static byte FLAG_INHERIT_CONTAINER = (byte)0x02;
-<   public final static byte FLAG_INHERIT_OBJECT    = (byte)0x01;
----
->     public static final int FILE_READ_DATA        = 0x00000001; // 1
->     public static final int FILE_WRITE_DATA       = 0x00000002; // 2
->     public static final int FILE_APPEND_DATA      = 0x00000004; // 3
->     public static final int FILE_READ_EA          = 0x00000008; // 4
->     public static final int FILE_WRITE_EA         = 0x00000010; // 5
->     public static final int FILE_EXECUTE          = 0x00000020; // 6
->     public static final int FILE_DELETE           = 0x00000040; // 7
->     public static final int FILE_READ_ATTRIBUTES  = 0x00000080; // 8
->     public static final int FILE_WRITE_ATTRIBUTES = 0x00000100; // 9
->     public static final int DELETE                = 0x00010000; // 16
->     public static final int READ_CONTROL          = 0x00020000; // 17
->     public static final int WRITE_DAC             = 0x00040000; // 18
->     public static final int WRITE_OWNER           = 0x00080000; // 19
->     public static final int SYNCHRONIZE           = 0x00100000; // 20
->     public static final int GENERIC_ALL           = 0x10000000; // 28
->     public static final int GENERIC_EXECUTE       = 0x20000000; // 29
->     public static final int GENERIC_WRITE         = 0x40000000; // 30
->     public static final int GENERIC_READ          = 0x80000000; // 31
-16,45d25
-<   // Specific Rights
-<   public final static int RIGHT_FOLDER_LIST    = (int)0x00000001;
-<   public final static int RIGHT_DATA_READ      = (int)0x00000001;
-<   public final static int RIGHT_FILE_CREATE    = (int)0x00000002;
-<   public final static int RIGHT_DATA_WRITE     = (int)0x00000002;
-<   public final static int RIGHT_FOLDER_CREATE  = (int)0x00000004;
-<   public final static int RIGHT_DATA_APPEND    = (int)0x00000004;
-<   public final static int RIGHT_EAS_READ       = (int)0x00000008;
-<   public final static int RIGHT_EAS_WRITE      = (int)0x00000010;
-<   public final static int RIGHT_FOLDER_TRAVERSE= (int)0x00000020;
-<   public final static int RIGHT_FILE_EXECUTE   = (int)0x00000020;
-<     public static final int RIGHT_FILE_DELETE    = (int)0x00000040;   
-<   public final static int RIGHT_ATTR_READ      = (int)0x00000080;
-<   public final static int RIGHT_ATTR_WRITE     = (int)0x00000100;
-<   // Standard Rights
-<   public final static int RIGHT_DELETE         = (int)0x00010000;
-<   public final static int RIGHT_DAC_READ       = (int)0x00020000;
-<   public final static int RIGHT_DAC_WRITE      = (int)0x00040000;
-<   public final static int RIGHT_OWNER_WRITE    = (int)0x00080000;
-<   public final static int RIGHT_SYNCHRONIZE    = (int)0x00100000;
-<   
-<     // Generic Rights
-<     public static final int RIGHT_GENERIC_FULL     = 0x10000000; // 28
-<     public static final int RIGHT_GENERIC_EXECUTE  = 0x20000000; // 29
-<     public static final int RIGHT_GENERIC_WRITE    = 0x40000000; // 30
-<     public static final int RIGHT_GENERIC_READ     = 0x80000000; // 31
-<     
-<     public static final boolean STATE_ALLOW = true;
-<     public static final boolean STATE_DENY = false;
-<     
-55c35
-<         return (flags & FLAG_INHERIT_PARENT) != 0;
----
->         return (flags & 0x10) != 0;
-75,82d54
-<   public boolean checkRights(int p_rights) {
-<       return ((access & p_rights) == p_rights);
-<   }
-<   
-<   public boolean checkFlags(byte p_flags) {
-<       return ((flags & p_flags) == p_flags); 
-<   }
-<     
-diff -N -r Code/jcifs_1.2.8/src/jcifs/smb/NtStatus.java temp/jcifs_1.2.8/src/jcifs/smb/NtStatus.java
-28d27
-<     public static final int NT_STATUS_SOME_NOT_MAPPED = 0x00000107;    
-diff -N -r Code/jcifs_1.2.8/src/jcifs/smb/SID.java temp/jcifs_1.2.8/src/jcifs/smb/SID.java
-2a3
-> import java.util.*;
-6,17c7,8
-<   public final static int TYPE_UNRESOLVED       = 0;
-<   public final static int TYPE_USER             = 1;
-<   public final static int TYPE_GROUP            = 2;
-<   public final static int TYPE_ALIAS            = 4;
-<   public final static int TYPE_WELL_KNOWN_GROUP = 5;
-<   public final static int TYPE_UNKNOWN          = 8;
-<   
-<   private String domain = null;
-<   private String name = null;
-<   private int type = TYPE_UNRESOLVED;
-<   
-<     byte revision;
----
-> 
->     int revision;
-37,63d27
-<       String ret = getSID();
-<         String resolve = getResolved();
-<         if(resolve!=null) {
-<           ret += ":"+resolve;
-<         }
-<         return ret;
-<     }
-<     
-<     public void setResolved(String domain, String name, int type) {
-<       this.domain=domain;
-<       this.name=name;
-<       this.type=type;
-<     }
-<     
-<     public byte getRevision() {
-<       return revision;
-<     }
-<     
-<     public int[] getSubAuthority() {
-<       return sub_authority;
-<     }
-<     
-<     public byte[] getIdentifierAuthority() {
-<       return identifier_authority;
-<     }
-<     
-<     public String getSID() {
-80a45
-> 
-83,90d47
-<     
-<     public String getResolved() {
-<       if(type>TYPE_UNRESOLVED && type < TYPE_UNKNOWN) {
-<           return domain+'\\'+name;
-<       } else {
-<           return null;
-<       }
-<     }
-diff -N -r Code/jcifs_1.2.8/src/jcifs/smb/SmbFile.java temp/jcifs_1.2.8/src/jcifs/smb/SmbFile.java
-31d30
-< import jcifs.rpc.LsaRPC;
-2526,2533c2525,2526
-<         LsaRPC lsa = new LsaRPC(getServer());
-<         try {
-<           lsa.lookupSids(response.aces);
-<         } catch(IOException e) {
-<           throw new SmbException("Unable to resolve SIDs",e);
-<         } finally {
-<           close( f, 0L );
-<         }
----
-> 
->         close( f, 0L );
-diff -N -r Code/jcifs_1.2.8/src/jcifs/smb/TransactNamedPipeOutputStream.java temp/jcifs_1.2.8/src/jcifs/smb/TransactNamedPipeOutputStream.java
-60,61c60
-<             //pipe.open(SmbFile.O_EXCL, pipe.pipeType & 0xFFFF0000, SmbFile.ATTR_NORMAL, 0 );
-<           pipe.open(( pipe.pipeType & 0xFF0000 ) | SmbFile.O_EXCL,0, SmbFile.ATTR_NORMAL, 0 );
----
->             pipe.open(SmbFile.O_EXCL, pipe.pipeType & 0xFFFF0000, SmbFile.ATTR_NORMAL, 0 );
index 8329d47..240ffc3 100644 (file)
@@ -31,6 +31,7 @@ class DcerpcBinding {
     static {
         INTERFACES = new HashMap();
         INTERFACES.put("srvsvc", srvsvc.getSyntax());
+        INTERFACES.put("lsarpc", lsarpc.getSyntax());
     }
 
     String proto;
index b5df2c3..bc2c018 100644 (file)
@@ -121,7 +121,6 @@ public abstract class DcerpcHandle implements DcerpcConstants {
         NdrBuffer buf;
         boolean isLast;
         DcerpcException de;
-        int off = 24;
 
         if (state == 0) {
             state = 1;
@@ -129,51 +128,80 @@ public abstract class DcerpcHandle implements DcerpcConstants {
             sendrecv(bind);
         }
 
-        stub = frag = new byte[max_recv];
-        buf = new NdrBuffer(frag, 0);
-
-        msg.encode(buf);
-
-        // assumes 1 fragment for now
-        msg.call_id = call_id++;
-        doSendFragment(frag, 0, buf.getLength());
-
-        doReceiveFragment(frag);
-        buf.reset();
-        msg.decode_header(buf);
-
-        if (msg.ptype == 2 && msg.isFlagSet(DCERPC_LAST_FRAG) == false) {
-            msg.alloc_hint = buf.dec_ndr_long();
-            if (msg.alloc_hint > (stub.length - 24)) {
-                stub = new byte[msg.alloc_hint];
-                System.arraycopy(frag, 0, stub, 0, msg.length);
+        stub = frag = jcifs.smb.BufferCache.getBuffer();
+        try {
+            int off, tot, n;
+
+            buf = new NdrBuffer(stub, 0);
+
+            msg.flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG;
+            msg.call_id = call_id;
+
+            msg.encode(buf);
+
+            tot = buf.getLength();
+            off = 0;
+            while (off < tot) {
+                msg.call_id = call_id++;
+
+                if ((tot - off) > max_xmit) {
+                    /* Multiple fragments. Need to set flags and length
+                     * and re-encode header
+                    msg.length = n = max_xmit;
+                    msg.flags &= ~DCERPC_LAST_FRAG;
+                    buf.start = off;
+                    buf.reset();
+                    msg.encode_header(buf);
+                     */
+                    throw new DcerpcException("Fragmented request PDUs currently not supported");
+                } else {
+                    n = tot - off;
+                }
+
+                doSendFragment(stub, off, n);
+                off += n;
             }
-            off = msg.length;
-        }
-
-        while (msg.isFlagSet(DCERPC_LAST_FRAG) == false) {
-            int stub_frag_len;
 
             doReceiveFragment(frag);
             buf.reset();
             msg.decode_header(buf);
-            stub_frag_len = msg.length - 24;
-
-            if ((off + stub_frag_len) > stub.length) {
-                // shouldn't happen if alloc_hint is correct or greater
-                byte[] tmp = new byte[off + stub_frag_len];
-                System.arraycopy(stub, 0, tmp, 0, off);
-                stub = tmp;
+    
+            off = 24;
+            if (msg.ptype == 2 && msg.isFlagSet(DCERPC_LAST_FRAG) == false) {
+                msg.alloc_hint = buf.dec_ndr_long();
+                if (msg.alloc_hint > (stub.length - 24)) {
+                    stub = new byte[msg.alloc_hint];
+                    System.arraycopy(frag, 0, stub, 0, msg.length);
+                }
+                off = msg.length;
             }
-
-            System.arraycopy(frag, 24, stub, off, stub_frag_len);
-            off += stub_frag_len;
+    
+            while (msg.isFlagSet(DCERPC_LAST_FRAG) == false) {
+                int stub_frag_len;
+    
+                doReceiveFragment(frag);
+                buf.reset();
+                msg.decode_header(buf);
+                stub_frag_len = msg.length - 24;
+    
+                if ((off + stub_frag_len) > stub.length) {
+                    // shouldn't happen if alloc_hint is correct or greater
+                    byte[] tmp = new byte[off + stub_frag_len];
+                    System.arraycopy(stub, 0, tmp, 0, off);
+                    stub = tmp;
+                }
+    
+                System.arraycopy(frag, 24, stub, off, stub_frag_len);
+                off += stub_frag_len;
+            }
+    
+            buf = new NdrBuffer(stub, 0);
+    
+            msg.decode(buf);
+        } finally {
+            jcifs.smb.BufferCache.releaseBuffer(stub);
         }
 
-        buf = new NdrBuffer(stub, 0);
-
-        msg.decode(buf);
-
         if ((de = msg.getResult()) != null)
             throw de;
     }
index 83df082..e91a5e1 100644 (file)
@@ -34,6 +34,12 @@ public abstract class DcerpcMessage extends NdrObject implements DcerpcConstants
     public boolean isFlagSet(int flag) {
         return (flags & flag) == flag;
     }
+    public void unsetFlag(int flag) {
+        flags |= flag;
+    }
+    public void setFlag(int flag) {
+        flags |= flag;
+    }
     public DcerpcException getResult() {
         if (result != 0)
             return new DcerpcException(result);
index 7d7a824..5f2b931 100644 (file)
@@ -47,7 +47,7 @@ public class DcerpcPipeHandle extends DcerpcHandle {
     protected void doSendFragment(byte[] buf, int off, int length) throws IOException {
         in = (SmbFileInputStream)pipe.getNamedPipeInputStream();
         out = pipe.getNamedPipeOutputStream();
-        out.write(buf, 0, length);
+        out.write(buf, off, length);
     }
     protected void doReceiveFragment(byte[] buf) throws IOException {
         int off, flags, length;
@@ -77,7 +77,8 @@ public class DcerpcPipeHandle extends DcerpcHandle {
         }
     }
     public void close() throws IOException {
-        out.close();
+        if (out != null)
+            out.close();
     }
 }
 
diff --git a/src/jcifs/dcerpc/UnicodeString.java b/src/jcifs/dcerpc/UnicodeString.java
new file mode 100644 (file)
index 0000000..3c67c01
--- /dev/null
@@ -0,0 +1,62 @@
+/* jcifs msrpc client library in Java
+ * Copyright (C) 2006  "Michael B. Allen" <jcifs at samba dot org>
+ *                     "Eric Glass" <jcifs at samba dot org>
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package jcifs.dcerpc;
+
+public class UnicodeString extends rpc.unicode_string {
+
+    boolean zterm;
+
+    public UnicodeString(boolean zterm) {
+        this.zterm = zterm;
+    }
+    public UnicodeString(rpc.unicode_string rus, boolean zterm) {
+        this.length = rus.length;
+        this.maximum_length = rus.maximum_length;
+        this.buffer = rus.buffer;
+        this.zterm = zterm;
+    }
+
+    public UnicodeString(String str, boolean zterm) {
+        this.zterm = zterm;
+
+        int len = str.length();
+        int zt = zterm ? 1 : 0;
+
+        length = maximum_length = (short)((len + zt) * 2);
+        buffer = new short[len + zt];
+
+        int i;
+        for (i = 0; i < len; i++) {
+            buffer[i] = (short)str.charAt(i);
+        }
+        if (zterm) {
+            buffer[i] = (short)0;
+        }
+    }
+
+    public String toString() {
+        int len = length / 2 - (zterm ? 1 : 0);
+        char[] ca = new char[len];
+        for (int i = 0; i < len; i++) {
+            ca[i] = (char)buffer[i];
+        }
+        return new String(ca, 0, len);
+    }
+}
diff --git a/src/jcifs/dcerpc/msrpc/LsaPolicyHandle.java b/src/jcifs/dcerpc/msrpc/LsaPolicyHandle.java
new file mode 100644 (file)
index 0000000..90ce2c0
--- /dev/null
@@ -0,0 +1,38 @@
+/* jcifs msrpc client library in Java
+ * Copyright (C) 2006  "Michael B. Allen" <jcifs at samba dot org>
+ *                     "Eric Glass" <jcifs at samba dot org>
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package jcifs.dcerpc.msrpc;
+
+import java.io.IOException;
+
+import jcifs.dcerpc.*;
+
+public class LsaPolicyHandle extends rpc.policy_handle {
+
+    public LsaPolicyHandle(DcerpcHandle handle, String server, int access) throws IOException {
+        if (server == null)
+            server = "\\\\";
+        MsrpcLsarOpenPolicy2 rpc = new MsrpcLsarOpenPolicy2(server, access, this);
+        handle.sendrecv(rpc);
+    }
+
+    public void close() throws IOException {
+    }
+}
+
diff --git a/src/jcifs/dcerpc/msrpc/LsarSidArrayX.java b/src/jcifs/dcerpc/msrpc/LsarSidArrayX.java
new file mode 100644 (file)
index 0000000..f985e04
--- /dev/null
@@ -0,0 +1,15 @@
+package jcifs.dcerpc.msrpc;
+
+import jcifs.smb.SID;
+
+class LsarSidArrayX extends lsarpc.LsarSidArray {
+
+    LsarSidArrayX(SID[] sids) {
+        this.num_sids = sids.length;
+        this.sids = new lsarpc.LsarSidPtr[sids.length];
+        for (int si = 0; si < sids.length; si++) {
+            this.sids[si] = new lsarpc.LsarSidPtr();
+            this.sids[si].sid = sids[si];
+        }
+    }
+}
diff --git a/src/jcifs/dcerpc/msrpc/MsrpcLookupSids.java b/src/jcifs/dcerpc/msrpc/MsrpcLookupSids.java
new file mode 100644 (file)
index 0000000..b625fe5
--- /dev/null
@@ -0,0 +1,41 @@
+/* jcifs msrpc client library in Java
+ * Copyright (C) 2006  "Michael B. Allen" <jcifs at samba dot org>
+ *                     "Eric Glass" <jcifs at samba dot org>
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package jcifs.dcerpc.msrpc;
+
+import jcifs.smb.*;
+import jcifs.util.Hexdump;
+import jcifs.dcerpc.*;
+
+public class MsrpcLookupSids extends lsarpc.LsarLookupSids {
+
+    SID[] sids;
+
+    public MsrpcLookupSids(LsaPolicyHandle policyHandle, SID[] sids) {
+        super(policyHandle,
+                new LsarSidArrayX(sids),
+                new lsarpc.LsarRefDomainList(),
+                new lsarpc.LsarTransNameArray(),
+                (short)1,
+                sids.length);
+        this.sids = sids;
+        ptype = 0;
+        flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG;
+    }
+}
diff --git a/src/jcifs/dcerpc/msrpc/MsrpcLsarOpenPolicy2.java b/src/jcifs/dcerpc/msrpc/MsrpcLsarOpenPolicy2.java
new file mode 100644 (file)
index 0000000..8f09e66
--- /dev/null
@@ -0,0 +1,30 @@
+/* jcifs msrpc client library in Java
+ * Copyright (C) 2006  "Michael B. Allen" <jcifs at samba dot org>
+ *                     "Eric Glass" <jcifs at samba dot org>
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+package jcifs.dcerpc.msrpc;
+
+public class MsrpcLsarOpenPolicy2 extends lsarpc.LsarOpenPolicy2 {
+
+    public MsrpcLsarOpenPolicy2(String server, int access, LsaPolicyHandle policyHandle) {
+        super(server, new lsarpc.LsarObjectAttributes(), access, policyHandle);
+        object_attributes.length = 24;
+        ptype = 0;
+        flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG;
+    }
+}
diff --git a/src/jcifs/dcerpc/msrpc/lsarpc.idl b/src/jcifs/dcerpc/msrpc/lsarpc.idl
new file mode 100644 (file)
index 0000000..1cfa764
--- /dev/null
@@ -0,0 +1,132 @@
+[
+       uuid(12345778-1234-abcd-ef00-0123456789ab),
+       version(0.0)
+]
+interface lsarpc
+{
+       import "../rpc.idl";
+
+       typedef struct {
+               uint32_t length;
+               uint16_t impersonation_level;
+               uint8_t context_mode;
+               uint8_t effective_only;
+       } LsarQosInfo;
+
+       typedef struct {
+               uint32_t length;
+               uint8_t *root_directory;
+               unicode_string *object_name;
+               uint32_t attributes;
+               uint32_t security_descriptor;
+               LsarQosInfo *security_quality_of_service;
+       } LsarObjectAttributes;
+
+       typedef struct {
+               unicode_string name;
+               sid_t *sid;
+       } LsarDomainInfo;
+
+       typedef struct {
+               unicode_string name;
+               unicode_string dns_domain;
+               unicode_string dns_forest;
+               uuid_t domain_guid;
+               sid_t *sid;
+       } LsarDnsDomainInfo;
+
+       enum {
+               POLICY_INFO_AUDIT_EVENTS   = 2,
+               POLICY_INFO_PRIMARY_DOMAIN = 3,
+               POLICY_INFO_ACCOUNT_DOMAIN = 5,
+               POLICY_INFO_SERVER_ROLE    = 6,
+               POLICY_INFO_MODIFICATION   = 9,
+               POLICY_INFO_DNS_DOMAIN     = 12
+       };
+
+       typedef [switch_type(short)] union {
+               [case(POLICY_INFO_ACCOUNT_DOMAIN)] LsarDomainInfo account_domain;
+               [case(POLICY_INFO_DNS_DOMAIN)] LsarDnsDomainInfo dns_domain;
+       } LsarPolicyInfo;
+
+       typedef struct {
+               sid_t *sid;
+       } LsarSidPtr;
+
+       typedef struct {
+               [range(0,1000)] uint32_t num_sids;
+               [size_is(num_sids)] LsarSidPtr *sids;
+       } LsarSidArray;
+
+       typedef enum {
+               SID_NAME_USE_NONE = 0, /* NOTUSED */
+               SID_NAME_USER     = 1, /* user */
+               SID_NAME_DOM_GRP  = 2, /* domain group */
+               SID_NAME_DOMAIN   = 3, /* domain: don't know what this is */
+               SID_NAME_ALIAS    = 4, /* local group */
+               SID_NAME_WKN_GRP  = 5, /* well-known group */
+               SID_NAME_DELETED  = 6, /* deleted account: needed for c2 rating */
+               SID_NAME_INVALID  = 7, /* invalid account */
+               SID_NAME_UNKNOWN  = 8  /* oops. */
+       } LsarSidType;
+
+       typedef struct {
+               LsarSidType sid_type;
+               uint32_t rid;
+               uint32_t sid_index;
+       } LsarTranslatedSid;
+
+       typedef struct {
+               [range(0,1000)] uint32_t count;
+               [size_is(count)] LsarTranslatedSid *sids;
+       } LsarTransSidArray;
+
+       typedef struct {
+               unicode_string name;
+               sid_t *sid;
+       } LsarTrustInformation;
+
+       typedef struct {
+               [range(0,1000)] uint32_t count;
+               [size_is(count)] LsarTrustInformation *domains;
+               uint32_t max_count;
+       } LsarRefDomainList;
+
+       typedef struct {
+               uint16_t sid_type;
+               unicode_string name;
+               uint32_t sid_index;
+       } LsarTranslatedName;
+
+       typedef struct {
+               [range(0,1000)] uint32_t count;
+               [size_is(count)] LsarTranslatedName *names;
+       } LsarTransNameArray;
+
+       [op(0x00)]
+       int LsarClose([in,out] policy_handle *handle);
+
+       [op(0x07)]
+       int LsarQueryInformationPolicy([in] policy_handle *handle,
+                       [in] uint16_t level,
+                       [out,switch_is(level),unique] LsarPolicyInfo *info);
+
+       [op(0x0f)]
+       int LsarLookupSids([in] policy_handle *handle,
+                       [in] LsarSidArray *sids,
+                       [out,unique] LsarRefDomainList *domains,
+                       [in,out] LsarTransNameArray *names,
+                       [in] uint16_t level,
+                       [in,out] uint32_t *count);
+
+       [op(0x2c)]
+       int LsarOpenPolicy2([in,string,unique] wchar_t *system_name,
+                       [in] LsarObjectAttributes *object_attributes,
+                       [in] uint32_t desired_access,
+                       [out] policy_handle *policy_handle);
+
+       [op(0x2e)]
+       int LsarQueryInformationPolicy2([in] policy_handle *handle,
+                       [in] uint16_t level,
+                       [out,switch_is(level),unique] LsarPolicyInfo *info);
+}
diff --git a/src/jcifs/dcerpc/msrpc/lsarpc.java b/src/jcifs/dcerpc/msrpc/lsarpc.java
new file mode 100644 (file)
index 0000000..b6de2c1
--- /dev/null
@@ -0,0 +1,914 @@
+package jcifs.dcerpc.msrpc;
+
+import jcifs.dcerpc.*;
+import jcifs.dcerpc.ndr.*;
+
+public class lsarpc {
+
+    public static String getSyntax() {
+        return "12345778-1234-abcd-ef00-0123456789ab:0.0";
+    }
+
+    public static class LsarQosInfo extends NdrObject {
+
+        public int length;
+        public short impersonation_level;
+        public byte context_mode;
+        public byte effective_only;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(length);
+            _dst.enc_ndr_short(impersonation_level);
+            _dst.enc_ndr_small(context_mode);
+            _dst.enc_ndr_small(effective_only);
+
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            length = (int)_src.dec_ndr_long();
+            impersonation_level = (short)_src.dec_ndr_short();
+            context_mode = (byte)_src.dec_ndr_small();
+            effective_only = (byte)_src.dec_ndr_small();
+
+        }
+    }
+    public static class LsarObjectAttributes extends NdrObject {
+
+        public int length;
+        public NdrSmall root_directory;
+        public rpc.unicode_string object_name;
+        public int attributes;
+        public int security_descriptor;
+        public LsarQosInfo security_quality_of_service;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(length);
+            _dst.enc_ndr_referent(root_directory, 1);
+            _dst.enc_ndr_referent(object_name, 1);
+            _dst.enc_ndr_long(attributes);
+            _dst.enc_ndr_long(security_descriptor);
+            _dst.enc_ndr_referent(security_quality_of_service, 1);
+
+            if (root_directory != null) {
+                _dst = _dst.deferred;
+                root_directory.encode(_dst);
+
+            }
+            if (object_name != null) {
+                _dst = _dst.deferred;
+                object_name.encode(_dst);
+
+            }
+            if (security_quality_of_service != null) {
+                _dst = _dst.deferred;
+                security_quality_of_service.encode(_dst);
+
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            length = (int)_src.dec_ndr_long();
+            int _root_directoryp = _src.dec_ndr_long();
+            int _object_namep = _src.dec_ndr_long();
+            attributes = (int)_src.dec_ndr_long();
+            security_descriptor = (int)_src.dec_ndr_long();
+            int _security_quality_of_servicep = _src.dec_ndr_long();
+
+            if (_root_directoryp != 0) {
+                _src = _src.deferred;
+                root_directory.decode(_src);
+
+            }
+            if (_object_namep != 0) {
+                if (object_name == null) { /* YOYOYO */
+                    object_name = new rpc.unicode_string();
+                }
+                _src = _src.deferred;
+                object_name.decode(_src);
+
+            }
+            if (_security_quality_of_servicep != 0) {
+                if (security_quality_of_service == null) { /* YOYOYO */
+                    security_quality_of_service = new LsarQosInfo();
+                }
+                _src = _src.deferred;
+                security_quality_of_service.decode(_src);
+
+            }
+        }
+    }
+    public static class LsarDomainInfo extends NdrObject {
+
+        public rpc.unicode_string name;
+        public rpc.sid_t sid;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_short(name.length);
+            _dst.enc_ndr_short(name.maximum_length);
+            _dst.enc_ndr_referent(name.buffer, 1);
+            _dst.enc_ndr_referent(sid, 1);
+
+            if (name.buffer != null) {
+                _dst = _dst.deferred;
+                int _name_bufferl = name.length / 2;
+                int _name_buffers = name.maximum_length / 2;
+                _dst.enc_ndr_long(_name_buffers);
+                _dst.enc_ndr_long(0);
+                _dst.enc_ndr_long(_name_bufferl);
+                int _name_bufferi = _dst.index;
+                _dst.advance(2 * _name_bufferl);
+
+                _dst = _dst.derive(_name_bufferi);
+                for (int _i = 0; _i < _name_bufferl; _i++) {
+                    _dst.enc_ndr_short(name.buffer[_i]);
+                }
+            }
+            if (sid != null) {
+                _dst = _dst.deferred;
+                sid.encode(_dst);
+
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            _src.align(4);
+            if (name == null) {
+                name = new rpc.unicode_string();
+            }
+            name.length = (short)_src.dec_ndr_short();
+            name.maximum_length = (short)_src.dec_ndr_short();
+            int _name_bufferp = _src.dec_ndr_long();
+            int _sidp = _src.dec_ndr_long();
+
+            if (_name_bufferp != 0) {
+                _src = _src.deferred;
+                int _name_buffers = _src.dec_ndr_long();
+                _src.dec_ndr_long();
+                int _name_bufferl = _src.dec_ndr_long();
+                int _name_bufferi = _src.index;
+                _src.advance(2 * _name_bufferl);
+
+                if (name.buffer == null) {
+                    if (_name_buffers < 0 || _name_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    name.buffer = new short[_name_buffers];
+                }
+                _src = _src.derive(_name_bufferi);
+                for (int _i = 0; _i < _name_bufferl; _i++) {
+                    name.buffer[_i] = (short)_src.dec_ndr_short();
+                }
+            }
+            if (_sidp != 0) {
+                if (sid == null) { /* YOYOYO */
+                    sid = new rpc.sid_t();
+                }
+                _src = _src.deferred;
+                sid.decode(_src);
+
+            }
+        }
+    }
+    public static class LsarDnsDomainInfo extends NdrObject {
+
+        public rpc.unicode_string name;
+        public rpc.unicode_string dns_domain;
+        public rpc.unicode_string dns_forest;
+        public rpc.uuid_t domain_guid;
+        public rpc.sid_t sid;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_short(name.length);
+            _dst.enc_ndr_short(name.maximum_length);
+            _dst.enc_ndr_referent(name.buffer, 1);
+            _dst.enc_ndr_short(dns_domain.length);
+            _dst.enc_ndr_short(dns_domain.maximum_length);
+            _dst.enc_ndr_referent(dns_domain.buffer, 1);
+            _dst.enc_ndr_short(dns_forest.length);
+            _dst.enc_ndr_short(dns_forest.maximum_length);
+            _dst.enc_ndr_referent(dns_forest.buffer, 1);
+            _dst.enc_ndr_long(domain_guid.time_low);
+            _dst.enc_ndr_short(domain_guid.time_mid);
+            _dst.enc_ndr_short(domain_guid.time_hi_and_version);
+            _dst.enc_ndr_small(domain_guid.clock_seq_hi_and_reserved);
+            _dst.enc_ndr_small(domain_guid.clock_seq_low);
+            int _domain_guid_nodes = 6;
+            int _domain_guid_nodei = _dst.index;
+            _dst.advance(1 * _domain_guid_nodes);
+            _dst.enc_ndr_referent(sid, 1);
+
+            if (name.buffer != null) {
+                _dst = _dst.deferred;
+                int _name_bufferl = name.length / 2;
+                int _name_buffers = name.maximum_length / 2;
+                _dst.enc_ndr_long(_name_buffers);
+                _dst.enc_ndr_long(0);
+                _dst.enc_ndr_long(_name_bufferl);
+                int _name_bufferi = _dst.index;
+                _dst.advance(2 * _name_bufferl);
+
+                _dst = _dst.derive(_name_bufferi);
+                for (int _i = 0; _i < _name_bufferl; _i++) {
+                    _dst.enc_ndr_short(name.buffer[_i]);
+                }
+            }
+            if (dns_domain.buffer != null) {
+                _dst = _dst.deferred;
+                int _dns_domain_bufferl = dns_domain.length / 2;
+                int _dns_domain_buffers = dns_domain.maximum_length / 2;
+                _dst.enc_ndr_long(_dns_domain_buffers);
+                _dst.enc_ndr_long(0);
+                _dst.enc_ndr_long(_dns_domain_bufferl);
+                int _dns_domain_bufferi = _dst.index;
+                _dst.advance(2 * _dns_domain_bufferl);
+
+                _dst = _dst.derive(_dns_domain_bufferi);
+                for (int _i = 0; _i < _dns_domain_bufferl; _i++) {
+                    _dst.enc_ndr_short(dns_domain.buffer[_i]);
+                }
+            }
+            if (dns_forest.buffer != null) {
+                _dst = _dst.deferred;
+                int _dns_forest_bufferl = dns_forest.length / 2;
+                int _dns_forest_buffers = dns_forest.maximum_length / 2;
+                _dst.enc_ndr_long(_dns_forest_buffers);
+                _dst.enc_ndr_long(0);
+                _dst.enc_ndr_long(_dns_forest_bufferl);
+                int _dns_forest_bufferi = _dst.index;
+                _dst.advance(2 * _dns_forest_bufferl);
+
+                _dst = _dst.derive(_dns_forest_bufferi);
+                for (int _i = 0; _i < _dns_forest_bufferl; _i++) {
+                    _dst.enc_ndr_short(dns_forest.buffer[_i]);
+                }
+            }
+            _dst = _dst.derive(_domain_guid_nodei);
+            for (int _i = 0; _i < _domain_guid_nodes; _i++) {
+                _dst.enc_ndr_small(domain_guid.node[_i]);
+            }
+            if (sid != null) {
+                _dst = _dst.deferred;
+                sid.encode(_dst);
+
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            _src.align(4);
+            if (name == null) {
+                name = new rpc.unicode_string();
+            }
+            name.length = (short)_src.dec_ndr_short();
+            name.maximum_length = (short)_src.dec_ndr_short();
+            int _name_bufferp = _src.dec_ndr_long();
+            _src.align(4);
+            if (dns_domain == null) {
+                dns_domain = new rpc.unicode_string();
+            }
+            dns_domain.length = (short)_src.dec_ndr_short();
+            dns_domain.maximum_length = (short)_src.dec_ndr_short();
+            int _dns_domain_bufferp = _src.dec_ndr_long();
+            _src.align(4);
+            if (dns_forest == null) {
+                dns_forest = new rpc.unicode_string();
+            }
+            dns_forest.length = (short)_src.dec_ndr_short();
+            dns_forest.maximum_length = (short)_src.dec_ndr_short();
+            int _dns_forest_bufferp = _src.dec_ndr_long();
+            _src.align(4);
+            if (domain_guid == null) {
+                domain_guid = new rpc.uuid_t();
+            }
+            domain_guid.time_low = (int)_src.dec_ndr_long();
+            domain_guid.time_mid = (short)_src.dec_ndr_short();
+            domain_guid.time_hi_and_version = (short)_src.dec_ndr_short();
+            domain_guid.clock_seq_hi_and_reserved = (byte)_src.dec_ndr_small();
+            domain_guid.clock_seq_low = (byte)_src.dec_ndr_small();
+            int _domain_guid_nodes = 6;
+            int _domain_guid_nodei = _src.index;
+            _src.advance(1 * _domain_guid_nodes);
+            int _sidp = _src.dec_ndr_long();
+
+            if (_name_bufferp != 0) {
+                _src = _src.deferred;
+                int _name_buffers = _src.dec_ndr_long();
+                _src.dec_ndr_long();
+                int _name_bufferl = _src.dec_ndr_long();
+                int _name_bufferi = _src.index;
+                _src.advance(2 * _name_bufferl);
+
+                if (name.buffer == null) {
+                    if (_name_buffers < 0 || _name_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    name.buffer = new short[_name_buffers];
+                }
+                _src = _src.derive(_name_bufferi);
+                for (int _i = 0; _i < _name_bufferl; _i++) {
+                    name.buffer[_i] = (short)_src.dec_ndr_short();
+                }
+            }
+            if (_dns_domain_bufferp != 0) {
+                _src = _src.deferred;
+                int _dns_domain_buffers = _src.dec_ndr_long();
+                _src.dec_ndr_long();
+                int _dns_domain_bufferl = _src.dec_ndr_long();
+                int _dns_domain_bufferi = _src.index;
+                _src.advance(2 * _dns_domain_bufferl);
+
+                if (dns_domain.buffer == null) {
+                    if (_dns_domain_buffers < 0 || _dns_domain_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    dns_domain.buffer = new short[_dns_domain_buffers];
+                }
+                _src = _src.derive(_dns_domain_bufferi);
+                for (int _i = 0; _i < _dns_domain_bufferl; _i++) {
+                    dns_domain.buffer[_i] = (short)_src.dec_ndr_short();
+                }
+            }
+            if (_dns_forest_bufferp != 0) {
+                _src = _src.deferred;
+                int _dns_forest_buffers = _src.dec_ndr_long();
+                _src.dec_ndr_long();
+                int _dns_forest_bufferl = _src.dec_ndr_long();
+                int _dns_forest_bufferi = _src.index;
+                _src.advance(2 * _dns_forest_bufferl);
+
+                if (dns_forest.buffer == null) {
+                    if (_dns_forest_buffers < 0 || _dns_forest_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    dns_forest.buffer = new short[_dns_forest_buffers];
+                }
+                _src = _src.derive(_dns_forest_bufferi);
+                for (int _i = 0; _i < _dns_forest_bufferl; _i++) {
+                    dns_forest.buffer[_i] = (short)_src.dec_ndr_short();
+                }
+            }
+            if (domain_guid.node == null) {
+                if (_domain_guid_nodes < 0 || _domain_guid_nodes > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                domain_guid.node = new byte[_domain_guid_nodes];
+            }
+            _src = _src.derive(_domain_guid_nodei);
+            for (int _i = 0; _i < _domain_guid_nodes; _i++) {
+                domain_guid.node[_i] = (byte)_src.dec_ndr_small();
+            }
+            if (_sidp != 0) {
+                if (sid == null) { /* YOYOYO */
+                    sid = new rpc.sid_t();
+                }
+                _src = _src.deferred;
+                sid.decode(_src);
+
+            }
+        }
+    }
+    public static final int POLICY_INFO_AUDIT_EVENTS = 2;
+    public static final int POLICY_INFO_PRIMARY_DOMAIN = 3;
+    public static final int POLICY_INFO_ACCOUNT_DOMAIN = 5;
+    public static final int POLICY_INFO_SERVER_ROLE = 6;
+    public static final int POLICY_INFO_MODIFICATION = 9;
+    public static final int POLICY_INFO_DNS_DOMAIN = 12;
+
+    public static class LsarSidPtr extends NdrObject {
+
+        public rpc.sid_t sid;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_referent(sid, 1);
+
+            if (sid != null) {
+                _dst = _dst.deferred;
+                sid.encode(_dst);
+
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            int _sidp = _src.dec_ndr_long();
+
+            if (_sidp != 0) {
+                if (sid == null) { /* YOYOYO */
+                    sid = new rpc.sid_t();
+                }
+                _src = _src.deferred;
+                sid.decode(_src);
+
+            }
+        }
+    }
+    public static class LsarSidArray extends NdrObject {
+
+        public int num_sids;
+        public LsarSidPtr[] sids;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(num_sids);
+            _dst.enc_ndr_referent(sids, 1);
+
+            if (sids != null) {
+                _dst = _dst.deferred;
+                int _sidss = num_sids;
+                _dst.enc_ndr_long(_sidss);
+                int _sidsi = _dst.index;
+                _dst.advance(4 * _sidss);
+
+                _dst = _dst.derive(_sidsi);
+                for (int _i = 0; _i < _sidss; _i++) {
+                    sids[_i].encode(_dst);
+                }
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            num_sids = (int)_src.dec_ndr_long();
+            int _sidsp = _src.dec_ndr_long();
+
+            if (_sidsp != 0) {
+                _src = _src.deferred;
+                int _sidss = _src.dec_ndr_long();
+                int _sidsi = _src.index;
+                _src.advance(4 * _sidss);
+
+                if (sids == null) {
+                    if (_sidss < 0 || _sidss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    sids = new LsarSidPtr[_sidss];
+                }
+                _src = _src.derive(_sidsi);
+                for (int _i = 0; _i < _sidss; _i++) {
+                    if (sids[_i] == null) {
+                        sids[_i] = new LsarSidPtr();
+                    }
+                    sids[_i].decode(_src);
+                }
+            }
+        }
+    }
+    public static final int SID_NAME_USE_NONE = 0;
+    public static final int SID_NAME_USER = 1;
+    public static final int SID_NAME_DOM_GRP = 2;
+    public static final int SID_NAME_DOMAIN = 3;
+    public static final int SID_NAME_ALIAS = 4;
+    public static final int SID_NAME_WKN_GRP = 5;
+    public static final int SID_NAME_DELETED = 6;
+    public static final int SID_NAME_INVALID = 7;
+    public static final int SID_NAME_UNKNOWN = 8;
+
+    public static class LsarTranslatedSid extends NdrObject {
+
+        public int sid_type;
+        public int rid;
+        public int sid_index;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_short(sid_type);
+            _dst.enc_ndr_long(rid);
+            _dst.enc_ndr_long(sid_index);
+
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            sid_type = (int)_src.dec_ndr_short();
+            rid = (int)_src.dec_ndr_long();
+            sid_index = (int)_src.dec_ndr_long();
+
+        }
+    }
+    public static class LsarTransSidArray extends NdrObject {
+
+        public int count;
+        public LsarTranslatedSid[] sids;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(count);
+            _dst.enc_ndr_referent(sids, 1);
+
+            if (sids != null) {
+                _dst = _dst.deferred;
+                int _sidss = count;
+                _dst.enc_ndr_long(_sidss);
+                int _sidsi = _dst.index;
+                _dst.advance(12 * _sidss);
+
+                _dst = _dst.derive(_sidsi);
+                for (int _i = 0; _i < _sidss; _i++) {
+                    sids[_i].encode(_dst);
+                }
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            count = (int)_src.dec_ndr_long();
+            int _sidsp = _src.dec_ndr_long();
+
+            if (_sidsp != 0) {
+                _src = _src.deferred;
+                int _sidss = _src.dec_ndr_long();
+                int _sidsi = _src.index;
+                _src.advance(12 * _sidss);
+
+                if (sids == null) {
+                    if (_sidss < 0 || _sidss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    sids = new LsarTranslatedSid[_sidss];
+                }
+                _src = _src.derive(_sidsi);
+                for (int _i = 0; _i < _sidss; _i++) {
+                    if (sids[_i] == null) {
+                        sids[_i] = new LsarTranslatedSid();
+                    }
+                    sids[_i].decode(_src);
+                }
+            }
+        }
+    }
+    public static class LsarTrustInformation extends NdrObject {
+
+        public rpc.unicode_string name;
+        public rpc.sid_t sid;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_short(name.length);
+            _dst.enc_ndr_short(name.maximum_length);
+            _dst.enc_ndr_referent(name.buffer, 1);
+            _dst.enc_ndr_referent(sid, 1);
+
+            if (name.buffer != null) {
+                _dst = _dst.deferred;
+                int _name_bufferl = name.length / 2;
+                int _name_buffers = name.maximum_length / 2;
+                _dst.enc_ndr_long(_name_buffers);
+                _dst.enc_ndr_long(0);
+                _dst.enc_ndr_long(_name_bufferl);
+                int _name_bufferi = _dst.index;
+                _dst.advance(2 * _name_bufferl);
+
+                _dst = _dst.derive(_name_bufferi);
+                for (int _i = 0; _i < _name_bufferl; _i++) {
+                    _dst.enc_ndr_short(name.buffer[_i]);
+                }
+            }
+            if (sid != null) {
+                _dst = _dst.deferred;
+                sid.encode(_dst);
+
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            _src.align(4);
+            if (name == null) {
+                name = new rpc.unicode_string();
+            }
+            name.length = (short)_src.dec_ndr_short();
+            name.maximum_length = (short)_src.dec_ndr_short();
+            int _name_bufferp = _src.dec_ndr_long();
+            int _sidp = _src.dec_ndr_long();
+
+            if (_name_bufferp != 0) {
+                _src = _src.deferred;
+                int _name_buffers = _src.dec_ndr_long();
+                _src.dec_ndr_long();
+                int _name_bufferl = _src.dec_ndr_long();
+                int _name_bufferi = _src.index;
+                _src.advance(2 * _name_bufferl);
+
+                if (name.buffer == null) {
+                    if (_name_buffers < 0 || _name_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    name.buffer = new short[_name_buffers];
+                }
+                _src = _src.derive(_name_bufferi);
+                for (int _i = 0; _i < _name_bufferl; _i++) {
+                    name.buffer[_i] = (short)_src.dec_ndr_short();
+                }
+            }
+            if (_sidp != 0) {
+                if (sid == null) { /* YOYOYO */
+                    sid = new rpc.sid_t();
+                }
+                _src = _src.deferred;
+                sid.decode(_src);
+
+            }
+        }
+    }
+    public static class LsarRefDomainList extends NdrObject {
+
+        public int count;
+        public LsarTrustInformation[] domains;
+        public int max_count;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(count);
+            _dst.enc_ndr_referent(domains, 1);
+            _dst.enc_ndr_long(max_count);
+
+            if (domains != null) {
+                _dst = _dst.deferred;
+                int _domainss = count;
+                _dst.enc_ndr_long(_domainss);
+                int _domainsi = _dst.index;
+                _dst.advance(12 * _domainss);
+
+                _dst = _dst.derive(_domainsi);
+                for (int _i = 0; _i < _domainss; _i++) {
+                    domains[_i].encode(_dst);
+                }
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            count = (int)_src.dec_ndr_long();
+            int _domainsp = _src.dec_ndr_long();
+            max_count = (int)_src.dec_ndr_long();
+
+            if (_domainsp != 0) {
+                _src = _src.deferred;
+                int _domainss = _src.dec_ndr_long();
+                int _domainsi = _src.index;
+                _src.advance(12 * _domainss);
+
+                if (domains == null) {
+                    if (_domainss < 0 || _domainss > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    domains = new LsarTrustInformation[_domainss];
+                }
+                _src = _src.derive(_domainsi);
+                for (int _i = 0; _i < _domainss; _i++) {
+                    if (domains[_i] == null) {
+                        domains[_i] = new LsarTrustInformation();
+                    }
+                    domains[_i].decode(_src);
+                }
+            }
+        }
+    }
+    public static class LsarTranslatedName extends NdrObject {
+
+        public short sid_type;
+        public rpc.unicode_string name;
+        public int sid_index;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_short(sid_type);
+            _dst.enc_ndr_short(name.length);
+            _dst.enc_ndr_short(name.maximum_length);
+            _dst.enc_ndr_referent(name.buffer, 1);
+            _dst.enc_ndr_long(sid_index);
+
+            if (name.buffer != null) {
+                _dst = _dst.deferred;
+                int _name_bufferl = name.length / 2;
+                int _name_buffers = name.maximum_length / 2;
+                _dst.enc_ndr_long(_name_buffers);
+                _dst.enc_ndr_long(0);
+                _dst.enc_ndr_long(_name_bufferl);
+                int _name_bufferi = _dst.index;
+                _dst.advance(2 * _name_bufferl);
+
+                _dst = _dst.derive(_name_bufferi);
+                for (int _i = 0; _i < _name_bufferl; _i++) {
+                    _dst.enc_ndr_short(name.buffer[_i]);
+                }
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            sid_type = (short)_src.dec_ndr_short();
+            _src.align(4);
+            if (name == null) {
+                name = new rpc.unicode_string();
+            }
+            name.length = (short)_src.dec_ndr_short();
+            name.maximum_length = (short)_src.dec_ndr_short();
+            int _name_bufferp = _src.dec_ndr_long();
+            sid_index = (int)_src.dec_ndr_long();
+
+            if (_name_bufferp != 0) {
+                _src = _src.deferred;
+                int _name_buffers = _src.dec_ndr_long();
+                _src.dec_ndr_long();
+                int _name_bufferl = _src.dec_ndr_long();
+                int _name_bufferi = _src.index;
+                _src.advance(2 * _name_bufferl);
+
+                if (name.buffer == null) {
+                    if (_name_buffers < 0 || _name_buffers > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    name.buffer = new short[_name_buffers];
+                }
+                _src = _src.derive(_name_bufferi);
+                for (int _i = 0; _i < _name_bufferl; _i++) {
+                    name.buffer[_i] = (short)_src.dec_ndr_short();
+                }
+            }
+        }
+    }
+    public static class LsarTransNameArray extends NdrObject {
+
+        public int count;
+        public LsarTranslatedName[] names;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(count);
+            _dst.enc_ndr_referent(names, 1);
+
+            if (names != null) {
+                _dst = _dst.deferred;
+                int _namess = count;
+                _dst.enc_ndr_long(_namess);
+                int _namesi = _dst.index;
+                _dst.advance(16 * _namess);
+
+                _dst = _dst.derive(_namesi);
+                for (int _i = 0; _i < _namess; _i++) {
+                    names[_i].encode(_dst);
+                }
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            count = (int)_src.dec_ndr_long();
+            int _namesp = _src.dec_ndr_long();
+
+            if (_namesp != 0) {
+                _src = _src.deferred;
+                int _namess = _src.dec_ndr_long();
+                int _namesi = _src.index;
+                _src.advance(16 * _namess);
+
+                if (names == null) {
+                    if (_namess < 0 || _namess > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    names = new LsarTranslatedName[_namess];
+                }
+                _src = _src.derive(_namesi);
+                for (int _i = 0; _i < _namess; _i++) {
+                    if (names[_i] == null) {
+                        names[_i] = new LsarTranslatedName();
+                    }
+                    names[_i].decode(_src);
+                }
+            }
+        }
+    }
+    public static class LsarClose extends DcerpcMessage {
+
+        public int getOpnum() { return 0x00; }
+
+        public int retval;
+        public rpc.policy_handle handle;
+
+        public LsarClose(rpc.policy_handle handle) {
+            this.handle = handle;
+        }
+
+        public void encode_in(NdrBuffer _dst) throws NdrException {
+            handle.encode(_dst);
+        }
+        public void decode_out(NdrBuffer _src) throws NdrException {
+            handle.decode(_src);
+            retval = (int)_src.dec_ndr_long();
+        }
+    }
+    public static class LsarQueryInformationPolicy extends DcerpcMessage {
+
+        public int getOpnum() { return 0x07; }
+
+        public int retval;
+        public rpc.policy_handle handle;
+        public short level;
+        public NdrObject info;
+
+        public LsarQueryInformationPolicy(rpc.policy_handle handle, short level, NdrObject info) {
+            this.handle = handle;
+            this.level = level;
+            this.info = info;
+        }
+
+        public void encode_in(NdrBuffer _dst) throws NdrException {
+            handle.encode(_dst);
+            _dst.enc_ndr_short(level);
+        }
+        public void decode_out(NdrBuffer _src) throws NdrException {
+            int _infop = _src.dec_ndr_long();
+            if (_infop != 0) {
+                _src.dec_ndr_short(); /* union discriminant */
+                info.decode(_src);
+
+            }
+            retval = (int)_src.dec_ndr_long();
+        }
+    }
+    public static class LsarLookupSids extends DcerpcMessage {
+
+        public int getOpnum() { return 0x0f; }
+
+        public int retval;
+        public rpc.policy_handle handle;
+        public LsarSidArray sids;
+        public LsarRefDomainList domains;
+        public LsarTransNameArray names;
+        public short level;
+        public int count;
+
+        public LsarLookupSids(rpc.policy_handle handle,
+                    LsarSidArray sids,
+                    LsarRefDomainList domains,
+                    LsarTransNameArray names,
+                    short level,
+                    int count) {
+            this.handle = handle;
+            this.sids = sids;
+            this.domains = domains;
+            this.names = names;
+            this.level = level;
+            this.count = count;
+        }
+
+        public void encode_in(NdrBuffer _dst) throws NdrException {
+            handle.encode(_dst);
+            sids.encode(_dst);
+            names.encode(_dst);
+            _dst.enc_ndr_short(level);
+            _dst.enc_ndr_long(count);
+        }
+        public void decode_out(NdrBuffer _src) throws NdrException {
+            int _domainsp = _src.dec_ndr_long();
+            if (_domainsp != 0) {
+                if (domains == null) { /* YOYOYO */
+                    domains = new LsarRefDomainList();
+                }
+                domains.decode(_src);
+
+            }
+            names.decode(_src);
+            count = (int)_src.dec_ndr_long();
+            retval = (int)_src.dec_ndr_long();
+        }
+    }
+    public static class LsarOpenPolicy2 extends DcerpcMessage {
+
+        public int getOpnum() { return 0x2c; }
+
+        public int retval;
+        public String system_name;
+        public LsarObjectAttributes object_attributes;
+        public int desired_access;
+        public rpc.policy_handle policy_handle;
+
+        public LsarOpenPolicy2(String system_name,
+                    LsarObjectAttributes object_attributes,
+                    int desired_access,
+                    rpc.policy_handle policy_handle) {
+            this.system_name = system_name;
+            this.object_attributes = object_attributes;
+            this.desired_access = desired_access;
+            this.policy_handle = policy_handle;
+        }
+
+        public void encode_in(NdrBuffer _dst) throws NdrException {
+            _dst.enc_ndr_referent(system_name, 1);
+            if (system_name != null) {
+                _dst.enc_ndr_string(system_name);
+
+            }
+            object_attributes.encode(_dst);
+            _dst.enc_ndr_long(desired_access);
+        }
+        public void decode_out(NdrBuffer _src) throws NdrException {
+            policy_handle.decode(_src);
+            retval = (int)_src.dec_ndr_long();
+        }
+    }
+    public static class LsarQueryInformationPolicy2 extends DcerpcMessage {
+
+        public int getOpnum() { return 0x2e; }
+
+        public int retval;
+        public rpc.policy_handle handle;
+        public short level;
+        public NdrObject info;
+
+        public LsarQueryInformationPolicy2(rpc.policy_handle handle, short level, NdrObject info) {
+            this.handle = handle;
+            this.level = level;
+            this.info = info;
+        }
+
+        public void encode_in(NdrBuffer _dst) throws NdrException {
+            handle.encode(_dst);
+            _dst.enc_ndr_short(level);
+        }
+        public void decode_out(NdrBuffer _src) throws NdrException {
+            int _infop = _src.dec_ndr_long();
+            if (_infop != 0) {
+                _src.dec_ndr_short(); /* union discriminant */
+                info.decode(_src);
+
+            }
+            retval = (int)_src.dec_ndr_long();
+        }
+    }
+}
index 7f28ee2..96ae42d 100644 (file)
@@ -4,7 +4,7 @@
 ]
 interface srvsvc
 {
-       import "rpc.idl";
+       import "../rpc.idl";
 
        typedef struct {
                [string] wchar_t *netname;
index c9c3f72..789688e 100644 (file)
@@ -2,6 +2,48 @@ package jcifs.smb;
 
 import jcifs.util.Hexdump;
 
+/**
+ * An Access Control Entry (ACE) is an element in a security descriptor
+ * such as those associated with files and directories. The Windows OS
+ * determines which users have the necessary permissions to access objects
+ * based on these entries.
+ * <p>
+ * To fully understand the information exposed by this class a description
+ * of the access check algorithm used by Windows is required. The following
+ * is a basic description of the algorithm. For a more complete description
+ * we recommend reading the section on Access Control in Keith Brown's
+ * "The .NET Developer's Guide to Windows Security" (which is also
+ * available online).
+ * <p>
+ * Direct ACEs are evaluated first in order. The SID of the user performing
+ * the operation and the desired access bits are compared to the SID
+ * and access mask of each ACE. If the SID matches, the allow/deny flags
+ * and access mask are considered. If the ACE is a "deny"
+ * ACE and <i>any</i> of the desired access bits match bits in the access
+ * mask of the ACE, the whole access check fails. If the ACE is an "allow"
+ * ACE and <i>all</i> of the bits in the desired access bits match bits in
+ * the access mask of the ACE, the access check is successful. Otherwise,
+ * more ACEs are evaluated until all desired access bits (combined)
+ * are "allowed". If all of the desired access bits are not "allowed"
+ * the then same process is repeated for inherited ACEs.
+ * <p>
+ * For example, if user <tt>WNET\alice</tt> tries to open a file
+ * with desired access bits <tt>0x00000003</tt> (<tt>FILE_READ_DATA |
+ * FILE_WRITE_DATA</tt>) and the target file has the following security
+ * descriptor ACEs:
+ * <pre>
+ * Allow WNET\alice     0x001200A9  Direct
+ * Allow Administrators 0x001F01FF  Inherited
+ * Allow SYSTEM         0x001F01FF  Inherited
+ * </pre>
+ * the access check would fail because the direct ACE has an access mask
+ * of <tt>0x001200A9</tt> which doesn't have the
+ * <tt>FILE_WRITE_DATA</tt> bit on (bit <tt>0x00000002</tt>). Actually, this isn't quite correct. If
+ * <tt>WNET\alice</tt> is in the local <tt>Administrators</tt> group the access check
+ * will succeed because the inherited ACE allows local <tt>Administrators</tt>
+ * both <tt>FILE_READ_DATA</tt> and <tt>FILE_WRITE_DATA</tt> access.
+ */
+
 public class ACE {
 
     public static final int FILE_READ_DATA        = 0x00000001; // 1
@@ -23,20 +65,78 @@ public class ACE {
     public static final int GENERIC_WRITE         = 0x40000000; // 30
     public static final int GENERIC_READ          = 0x80000000; // 31
 
+    public static final int FLAGS_OBJECT_INHERIT    = 0x01;
+    public static final int FLAGS_CONTAINER_INHERIT = 0x02;
+    public static final int FLAGS_NO_PROPAGATE      = 0x04;
+    public static final int FLAGS_INHERIT_ONLY      = 0x08;
+    public static final int FLAGS_INHERITED         = 0x10;
+
     boolean allow;
     int flags;
     int access;
     SID sid;
 
+    /**
+     * Returns true if this ACE is an allow ACE and false if it is a deny ACE.
+     */
     public boolean isAllow() {
         return allow;
     }
+    /**
+     * Returns true if this ACE is an inherited ACE and false if it is a direct ACE.
+     * <p>
+     * Note: For reasons not fully understood, <tt>FLAGS_INHERITED</tt> may
+     * not be set within all security descriptors even though the ACE was in
+     * face inherited. If an inherited ACE is added to a parent the Windows
+     * ACL editor will rebuild all children ACEs and set this flag accordingly.
+     */
     public boolean isInherited() {
-        return (flags & 0x10) != 0;
+        return (flags & FLAGS_INHERITED) != 0;
+    }
+    /**
+     * Returns the flags for this ACE. The </tt>isInherited()</tt>
+     * method checks the <tt>FLAGS_INHERITED</tt> bit in these flags.
+     */
+    public int getFlags() {
+        return flags;
+    }
+    /**
+     * Returns the 'Apply To' text for inheritance of ACEs on
+     * directories such as 'This folder, subfolder and files'. For
+     * files the text is always 'This object only'.
+     */
+    public String getApplyToText() {
+        switch (flags & (FLAGS_OBJECT_INHERIT | FLAGS_CONTAINER_INHERIT | FLAGS_INHERIT_ONLY)) {
+            case 0x00:
+                return "This folder only";
+            case 0x03:
+                return "This folder, subfolders and files";
+            case 0x0B:
+                return "Subfolders and files only";
+            case 0x02:
+                return "This folder and subfolders";
+            case 0x0A:
+                return "Subfolders only";
+            case 0x01:
+                return "This folder and files";
+            case 0x09:
+                return "Files only";
+        }
+        return "Invalid";
     }
+    /**
+     * Returns the access mask accociated with this ACE. Use the
+     * constants for <tt>FILE_READ_DATA</tt>, <tt>FILE_WRITE_DATA</tt>,
+     * <tt>READ_CONTROL</tt>, <tt>GENERIC_ALL</tt>, etc with bitwise
+     * operators to determine which bits of the mask are on or off.
+     */
     public int getAccessMask() {
         return access;
     }
+
+    /**
+     * Return the SID associated with this ACE.
+     */
     public SID getSID() {
         return sid;
     }
@@ -52,12 +152,29 @@ public class ACE {
         return size;
     }
 
+    void appendCol(StringBuffer sb, String str, int width) {
+        sb.append(str);
+        int count = width - str.length();
+        for (int i = 0; i < count; i++) {
+            sb.append(' ');
+        }
+    }
+    /**
+     * Return a string represeting this ACE.
+     * <p>
+     * Note: This function should probably be changed to return SDDL
+     * fragments but currently it does not.
+     */
     public String toString() {
+        int count, i;
+        String str;
+
         StringBuffer sb = new StringBuffer();
-        sb.append( isInherited() ? "inherited " : "direct    " );
-        sb.append( isAllow() ? "allow " : "deny  " );
-        sb.append( "0x" ).append( Hexdump.toHexString( access, 8 ));
-        sb.append( " " ).append( sid.toString() );
+        sb.append( isAllow() ? "Allow " : "Deny  " );
+        appendCol(sb, sid.toString(), 25);
+        sb.append( " 0x" ).append( Hexdump.toHexString( access, 8 )).append(' ');
+        sb.append(isInherited() ? "Inherited " : "Direct    ");
+        appendCol(sb, getApplyToText(), 34);
         return sb.toString();
     }
 }
index 9dcc74a..17f97bf 100644 (file)
@@ -20,7 +20,7 @@ package jcifs.smb;
 
 import jcifs.Config;
 
-class BufferCache {
+public class BufferCache {
 
     private static final int MAX_BUFFERS = Config.getInt( "jcifs.smb.maxBuffers", 16 );
 
@@ -28,7 +28,7 @@ class BufferCache {
     private static int numBuffers = 0;
     private static int freeBuffers = 0;
 
-    private static byte[] getBuffer() {
+    private static byte[] getBuffer0() {
         byte[] buf;
 
         if (freeBuffers > 0) {
@@ -54,14 +54,25 @@ class BufferCache {
                 while ((freeBuffers + (MAX_BUFFERS - numBuffers)) < 2) {
                     cache.wait();
                 }
-                req.txn_buf = getBuffer();
-                rsp.txn_buf = getBuffer();
+                req.txn_buf = getBuffer0();
+                rsp.txn_buf = getBuffer0();
             } catch( InterruptedException ie ) {
                 ie.printStackTrace();
             }
         }
     }
-    static void releaseBuffer( byte[] buf ) {
+    static public byte[] getBuffer() {
+        synchronized( cache ) {
+            while ((freeBuffers + (MAX_BUFFERS - numBuffers)) < 1) {
+                try {
+                    cache.wait();
+                } catch(InterruptedException ie) {
+                }
+            }
+            return getBuffer0();
+        }
+    }
+    static public void releaseBuffer( byte[] buf ) {
         synchronized( cache ) {
             for (int i = 0; i < MAX_BUFFERS; i++) {
                 if (cache[i] == null) {
index 7f15c24..14197e3 100644 (file)
@@ -50,6 +50,8 @@ public interface NtStatus {
     public static final int NT_STATUS_INVALID_WORKSTATION = 0xC0000070;
     public static final int NT_STATUS_PASSWORD_EXPIRED = 0xC0000071;
     public static final int NT_STATUS_ACCOUNT_DISABLED = 0xC0000072;
+    public static final int NT_STATUS_NONE_MAPPED = 0xC0000073;
+    public static final int NT_STATUS_INVALID_SID = 0xC0000078;
     public static final int NT_STATUS_INSTANCE_NOT_AVAILABLE = 0xC00000ab;
     public static final int NT_STATUS_PIPE_NOT_AVAILABLE = 0xC00000ac;
     public static final int NT_STATUS_INVALID_PIPE_STATE = 0xC00000ad;
@@ -62,11 +64,13 @@ public interface NtStatus {
     public static final int NT_STATUS_NETWORK_NAME_DELETED = 0xC00000c9;
     public static final int NT_STATUS_NETWORK_ACCESS_DENIED = 0xC00000ca;
     public static final int NT_STATUS_BAD_NETWORK_NAME = 0xC00000cc;
+    public static final int NT_STATUS_REQUEST_NOT_ACCEPTED = 0xC00000d0;
     public static final int NT_STATUS_NOT_A_DIRECTORY = 0xC0000103;
     public static final int NT_STATUS_CANNOT_DELETE = 0xC0000121;
     public static final int NT_STATUS_PIPE_BROKEN = 0xC000014b;
     public static final int NT_STATUS_LOGON_TYPE_NOT_GRANTED = 0xC000015b;
     public static final int NT_STATUS_TRUSTED_DOMAIN_FAILURE = 0xC000018c;
+    public static final int NT_STATUS_PASSWORD_MUST_CHANGE = 0xC0000224;
     public static final int NT_STATUS_NOT_FOUND = 0xC0000225;
     public static final int NT_STATUS_ACCOUNT_LOCKED_OUT = 0xC0000234;
     public static final int NT_STATUS_PATH_NOT_COVERED = 0xC0000257;
@@ -98,6 +102,8 @@ public interface NtStatus {
         NT_STATUS_INVALID_WORKSTATION,
         NT_STATUS_PASSWORD_EXPIRED,
         NT_STATUS_ACCOUNT_DISABLED,
+        NT_STATUS_NONE_MAPPED,
+        NT_STATUS_INVALID_SID,
         NT_STATUS_INSTANCE_NOT_AVAILABLE,
         NT_STATUS_PIPE_NOT_AVAILABLE,
         NT_STATUS_INVALID_PIPE_STATE,
@@ -110,11 +116,13 @@ public interface NtStatus {
         NT_STATUS_NETWORK_NAME_DELETED,
         NT_STATUS_NETWORK_ACCESS_DENIED,
         NT_STATUS_BAD_NETWORK_NAME,
+        NT_STATUS_REQUEST_NOT_ACCEPTED,
         NT_STATUS_NOT_A_DIRECTORY,
         NT_STATUS_CANNOT_DELETE,
         NT_STATUS_PIPE_BROKEN,
         NT_STATUS_LOGON_TYPE_NOT_GRANTED,
         NT_STATUS_TRUSTED_DOMAIN_FAILURE,
+        NT_STATUS_PASSWORD_MUST_CHANGE,
         NT_STATUS_NOT_FOUND,
         NT_STATUS_ACCOUNT_LOCKED_OUT,
         NT_STATUS_PATH_NOT_COVERED,
@@ -147,6 +155,8 @@ public interface NtStatus {
         "Logon failure: user not allowed to log on to this computer.",
         "Logon failure: the specified account password has expired.",
         "Logon failure: account currently disabled.",
+        "No mapping between account names and security IDs was done.",
+        "The security ID structure is invalid.",
         "All pipe instances are busy.",
         "All pipe instances are busy.",
         "The pipe state is invalid.",
@@ -159,11 +169,13 @@ public interface NtStatus {
         "The specified network name is no longer available.",
         "Network access is denied.",
         "The network name cannot be found.",
+        "No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept.",
         "The directory name is invalid.",
         "Access is denied.",
         "The pipe has been ended.",
         "Logon failure: the user has not been granted the requested logon type at this computer.",
         "The trust relationship between the primary domain and the trusted domain failed.",
+        "The user must change his password before he logs on the first time.",
         "NT_STATUS_NOT_FOUND",
         "The referenced account is currently locked out and may not be logged on to.",
         "The remote system is not reachable by the transport.",
index 38b6380..bb3f55c 100644 (file)
+/* jcifs smb client library in Java
+ * Copyright (C) 2006  "Michael B. Allen" <jcifs at samba dot org>
+ *                     "Eric Glass" <jcifs at samba dot org>
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
 package jcifs.smb;
 
 import java.util.*;
+import java.io.IOException;
 import jcifs.util.Hexdump;
+import jcifs.dcerpc.*;
+import jcifs.dcerpc.msrpc.*;
+
+/**
+ * A Windows SID is a numeric identifier used to represent Windows
+ * accounts. SIDs are commonly represented using a textual format such as
+ * <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt> but they may
+ * also be resolved to yield the name of the associated Windows account
+ * such as <tt>Administrators</tt> or <tt>MYDOM\alice</tt>.
+ * <p>
+ * Consider the following output of <tt>examples/SidLookup.java</tt>:
+ * <pre>
+ *       toString: WNET\Domain Admins
+ *    toSidString: S-1-5-21-4133388617-793952518-2001621813-512
+ *        getType: 2
+ *    getTypeText: Domain group
+ *  getDomainName: WNET
+ * getAccountName: Domain Admins
+ * </pre>
+ */
+
+public class SID extends rpc.sid_t {
+
+    public static final int SID_TYPE_USE_NONE = lsarpc.SID_NAME_USE_NONE;
+    public static final int SID_TYPE_USER    = lsarpc.SID_NAME_USER;
+    public static final int SID_TYPE_DOM_GRP = lsarpc.SID_NAME_DOM_GRP;
+    public static final int SID_TYPE_DOMAIN  = lsarpc.SID_NAME_DOMAIN;
+    public static final int SID_TYPE_ALIAS   = lsarpc.SID_NAME_ALIAS;
+    public static final int SID_TYPE_WKN_GRP = lsarpc.SID_NAME_WKN_GRP;
+    public static final int SID_TYPE_DELETED = lsarpc.SID_NAME_DELETED;
+    public static final int SID_TYPE_INVALID = lsarpc.SID_NAME_INVALID;
+    public static final int SID_TYPE_UNKNOWN = lsarpc.SID_NAME_UNKNOWN;
+
+    static final String[] SID_TYPE_NAMES = {
+        "0",
+        "User",
+        "Domain group",
+        "Domain",
+        "Local group",
+        "Builtin group",
+        "Deleted",
+        "Invalid",
+        "Unknown"
+    };
+
+    static Map sid_cache = Collections.synchronizedMap(new HashMap());
+
+    static void resolveSids(DcerpcHandle handle,
+                LsaPolicyHandle policyHandle,
+                SID[] sids) throws IOException {
+        MsrpcLookupSids rpc = new MsrpcLookupSids(policyHandle, sids);
+        handle.sendrecv(rpc);
+        switch (rpc.retval) {
+            case 0:
+            case NtStatus.NT_STATUS_NONE_MAPPED:
+            case 0x00000107: // NT_STATUS_SOME_NOT_MAPPED
+                break;
+            default:
+                throw new SmbException(rpc.retval, false);
+        }
+
+        for (int si = 0; si < sids.length; si++) {
+            sids[si].type = rpc.names.names[si].sid_type;
+            sids[si].domainName = null;
 
-public class SID {
+            switch (sids[si].type) {
+                case SID_TYPE_USER:
+                case SID_TYPE_DOM_GRP:
+                case SID_TYPE_DOMAIN:
+                case SID_TYPE_ALIAS:
+                case SID_TYPE_WKN_GRP:
+                    int sid_index = rpc.names.names[si].sid_index;
+                    rpc.unicode_string ustr = rpc.domains.domains[sid_index].name;
+                    sids[si].domainName = (new UnicodeString(ustr, false)).toString();
+                    break;
+            }
+
+            sids[si].acctName = (new UnicodeString(rpc.names.names[si].name, false)).toString();
+        }
+    }
+    static void resolveSids0(String authorityServerName,
+                NtlmPasswordAuthentication auth,
+                SID[] sids) throws IOException {
+        DcerpcHandle handle = null;
+        LsaPolicyHandle policyHandle = null;
+
+        try {
+            handle = DcerpcHandle.getHandle("ncacn_np:" + authorityServerName +
+                    "[\\PIPE\\lsarpc]", auth);
+            policyHandle = new LsaPolicyHandle(handle, null, 0x00000800);
+            SID.resolveSids(handle, policyHandle, sids);
+        } finally {
+            if (handle != null) {
+                if (policyHandle != null) {
+                    policyHandle.close();
+                }
+                handle.close();
+            }
+        }
+    }
 
-    int revision;
-    int sub_authority_count;
-    byte[] identifier_authority = new byte[6];
-    int[] sub_authority;
+    /**
+     * Resolve an array of SIDs using a cache and at most one MSRPC request.
+     * <p>
+     * This method will attempt
+     * to resolve SIDs using a cache and cache the results of any SIDs that
+     * required resolving with the authority. SID cache entries are currently not
+     * expired because under normal circumstances SID information never changes.
+     *
+     * @param authorityServerName The hostname of the server that should be queried. For maximum efficiency this should be the hostname of a domain controller however a member server will work as well and a domain controller may not return names for SIDs corresponding to local accounts for which the domain controller is not an authority.
+     * @param auth The credentials that should be used to communicate with the named server. As usual, <tt>null</tt> indicates that default credentials should be used.
+     * @param sids The SIDs that should be resolved. After this function is called, the names associated with the SIDs may be queried with the <tt>toString</tt>, <tt>getDomainName</tt>, and <tt>getAccountName</tt> methods.
+     */
+    static public void resolveSids(String authorityServerName,
+                NtlmPasswordAuthentication auth,
+                SID[] sids) throws IOException {
+        ArrayList list = new ArrayList(sids.length);
+        int si;
 
-    public SID( byte[] src, int si ) {
+        for (si = 0; si < sids.length; si++) {
+            SID sid = (SID)sid_cache.get(sids[si]);
+            if (sid != null) {
+                sids[si].type = sid.type;
+                sids[si].domainName = sid.domainName;
+                sids[si].acctName = sid.acctName;
+            } else {
+                list.add(sids[si]);
+            }
+        }
+
+        if (list.size() > 0) {
+            sids = (SID[])list.toArray(new SID[0]);
+            SID.resolveSids0(authorityServerName, auth, sids);
+            for (si = 0; si < sids.length; si++) {
+                sid_cache.put(sids[si], sids[si]);
+            }
+        }
+    }
+
+    int type;
+    String domainName = null;
+    String acctName = null;
+    String origin_server = null;
+    NtlmPasswordAuthentication origin_auth = null;
+
+    /**
+     * Construct a SID from it's binary representation.
+     */
+    public SID(byte[] src, int si) {
         revision = src[si++];
         sub_authority_count = src[si++];
+        identifier_authority = new byte[6];
         System.arraycopy(src, si, identifier_authority, 0, 6);
         si += 6;
         if (sub_authority_count > 100)
@@ -24,8 +185,157 @@ public class SID {
         }
     }
 
-    public String toString() {
-        String ret = "S-" + revision + "-";
+    /**
+     * Construct a SID from it's textual representation such as
+     * <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>.
+     */
+    public SID(String textual) throws SmbException {
+        StringTokenizer st = new StringTokenizer(textual, "-");
+        if (st.countTokens() < 3 || !st.nextToken().equals("S"))
+            // need S-N-M
+            throw new SmbException("Bad textual SID format: " + textual);
+
+        this.revision = Byte.parseByte(st.nextToken());
+        String tmp = st.nextToken();
+        long id = 0;
+        if (tmp.startsWith("0x"))
+            id = Long.parseLong(tmp.substring(2), 16);
+        else
+            id = Long.parseLong(tmp);
+
+        this.identifier_authority = new byte[6];
+        for (int i = 5; id > 0;  i--) {
+            this.identifier_authority[i] = (byte) (id % 256);
+            id >>= 8;
+        }
+
+        this.sub_authority_count = (byte) st.countTokens();
+        if (this.sub_authority_count > 0) {
+            this.sub_authority = new int[this.sub_authority_count];
+            for (int i = 0; i < this.sub_authority_count; i++)
+                this.sub_authority[i] = (int)(Long.parseLong(st.nextToken()) & 0xFFFFFFFFL);
+        }
+    }
+
+    /**
+     * Construct a SID from a domain SID and an RID
+     * (relative identifier). For example, a domain SID
+     * <tt>S-1-5-21-1496946806-2192648263-3843101252</tt> and RID <tt>1029</tt> would
+     * yield the SID <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>.
+     */
+    public SID(SID domsid, int rid) {
+        this.revision = domsid.revision;
+        this.identifier_authority = domsid.identifier_authority;
+        this.sub_authority_count = (byte)(domsid.sub_authority_count + 1);
+        this.sub_authority = new int[this.sub_authority_count];
+        int i;
+        for (i = 0; i < domsid.sub_authority_count; i++) {
+            this.sub_authority[i] = domsid.sub_authority[i];
+        }
+        this.sub_authority[i] = rid;
+    }
+
+    /**
+     * Returns the type of this SID indicating the state or type of account.
+     * <p>
+     * SID types are described in the following table.
+     * <tt>
+     * <table>
+     * <tr><th>Type</th><th>Name</th></tr>
+     * <tr><td>SID_TYPE_USE_NONE</td><td>0</td></tr>
+     * <tr><td>SID_TYPE_USER</td><td>User</td></tr>
+     * <tr><td>SID_TYPE_DOM_GRP</td><td>Domain group</td></tr>
+     * <tr><td>SID_TYPE_DOMAIN</td><td>Domain</td></tr>
+     * <tr><td>SID_TYPE_ALIAS</td><td>Local group</td></tr>
+     * <tr><td>SID_TYPE_WKN_GRP</td><td>Builtin group</td></tr>
+     * <tr><td>SID_TYPE_DELETED</td><td>Deleted</td></tr>
+     * <tr><td>SID_TYPE_INVALID</td><td>Invalid</td></tr>
+     * <tr><td>SID_TYPE_UNKNOWN</td><td>Unknown</td></tr>
+     * </table>
+     * </tt>
+     */
+    public int getType() {
+        if (origin_server != null)
+            resolveWeak();
+        return type;
+    }
+
+    /**
+     * Return text represeting the SID type suitable for display to
+     * users. Text includes 'User', 'Domain group', 'Local group', etc.
+     */
+    public String getTypeText() {
+        if (origin_server != null)
+            resolveWeak();
+        return SID_TYPE_NAMES[type];
+    }
+
+    /**
+     * Return the domain name of this SID unless it could not be
+     * resolved in which case the numeric representation is returned.
+     */
+    public String getDomainName() {
+        if (origin_server != null)
+            resolveWeak();
+        if (type == SID_TYPE_UNKNOWN) {
+            String full = toSidString();
+            return full.substring(0, full.length() - getAccountName().length() - 1);
+        }
+        return domainName;
+    }
+
+    /**
+     * Return the sAMAccountName of this SID unless it could not
+     * be resolved in which case the numeric RID is returned. If this
+     * SID is a domain SID, this method will return an empty String.
+     */
+    public String getAccountName() {
+        if (origin_server != null)
+            resolveWeak();
+        if (type == SID_TYPE_UNKNOWN)
+            return "" + sub_authority[sub_authority_count - 1];
+        if (type == SID_TYPE_DOMAIN)
+            return "";
+        return acctName;
+    }
+
+    public int hashCode() {
+        int hcode = identifier_authority[5];
+        for (int i = 0; i < sub_authority_count; i++) {
+            hcode += 65599 * sub_authority[i];
+        }
+        return hcode;
+    }
+    public boolean equals(Object obj) {
+        if (obj instanceof SID) {
+            SID sid = (SID)obj;
+            if (sid == this)
+                return true;
+            if (sid.sub_authority_count == sub_authority_count) {
+                int i = sub_authority_count;
+                while (i-- > 0) {
+                    if (sid.sub_authority[i] != sub_authority[i]) {
+                        return false;
+                    }
+                }
+                for (i = 0; i < 6; i++) {
+                    if (sid.identifier_authority[i] != identifier_authority[i]) {
+                        return false;
+                    }
+                }
+
+                return sid.revision == revision;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return the numeric representation of this sid such as
+     * <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>.
+     */
+    public String toSidString() {
+        String ret = "S-" + (revision & 0xFF) + "-";
 
         if (identifier_authority[0] != (byte)0 || identifier_authority[1] != (byte)0) {
             ret += "0x";
@@ -45,5 +355,65 @@ public class SID {
 
         return ret;
     }
+
+    /**
+     * Return a String representing this SID ideal for display to
+     * users. This method should return the same text that the ACL
+     * editor in Windows would display.
+     * <p>
+     * Specifically, if the SID has
+     * been resolved and it is not a domain SID or builtin account,
+     * the full DOMAIN\name form of the account will be
+     * returned (e.g. MYDOM\alice or MYDOM\Domain Users).
+     * If the SID has been resolved but it is is a domain SID,
+     * only the domain name will be returned (e.g. MYDOM).
+     * If the SID has been resolved but it is a builtin account,
+     * only the name component will be returned (e.g. SYSTEM).
+     * If the sid cannot be resolved the numeric representation from
+     * toSidString() is returned.
+     */
+    public String toString() {
+        if (origin_server != null)
+            resolveWeak();
+        if (domainName != null) {
+            String str;
+
+            if (type == SID_TYPE_DOMAIN) {
+                str = domainName;
+            } else if (domainName == null ||
+                        type == SID_TYPE_WKN_GRP ||
+                        domainName.equals("BUILTIN")) {
+                if (type == SID_TYPE_UNKNOWN) {
+                    str = toSidString();
+                } else {
+                    str = acctName;
+                }
+            } else {
+                str = domainName + "\\" + acctName;
+            }
+
+            return str;
+        }
+        return toSidString();
+    }
+
+    void resolve(String authorityServerName,
+                NtlmPasswordAuthentication auth) throws IOException {
+        SID[] sids = new SID[1];
+        sids[0] = this;
+        SID.resolveSids(authorityServerName, auth, sids);
+    }
+
+    void resolveWeak() {
+        if (origin_server != null) {
+            try {
+                resolve(origin_server, origin_auth);
+            } catch (IOException ioe) {
+            } finally {
+                origin_server = null;
+                origin_auth = null;
+            }
+        }
+    }
 }
 
index 54fbf9d..9b26b17 100644 (file)
@@ -32,7 +32,7 @@ import jcifs.util.LogStream;
 import jcifs.UniAddress;
 import jcifs.netbios.NbtAddress;
 import jcifs.dcerpc.*;
-import jcifs.dcerpc.msrpc.MsrpcShareEnum;
+import jcifs.dcerpc.msrpc.*;
 
 import java.util.Date;
 
@@ -413,12 +413,12 @@ public class SmbFile extends URLConnection implements SmbConstants {
     private long attrExpiration;
     private long size;
     private long sizeExpiration;
-    private NtlmPasswordAuthentication auth; // Cannot be null
     private boolean isExists;
     private int shareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
     private SmbComBlankResponse blank_resp = null;
     private DfsReferral dfsReferral = null;  // Only used by getDfsPath()
 
+    NtlmPasswordAuthentication auth; // Cannot be null
     SmbTree tree = null;             // Initially null; may be !tree.treeConnected
     String unc;                      // Initially null; set by getUncPath; never ends with '/'
     int fid;                         // Initially 0; set by open()
@@ -1643,32 +1643,29 @@ public class SmbFile extends URLConnection implements SmbConstants {
         handle = DcerpcHandle.getHandle("ncacn_np:" + url.getHost() + "[\\PIPE\\srvsvc]", auth);
 
         try {
-            boolean more = false;
-            do {
-                handle.sendrecv(rpc);
-
-                FileEntry[] entries = rpc.getEntries();
-                for( int i = 0; i < entries.length; i++ ) {
-                    FileEntry e = entries[i];
-                    String name = e.getName();
-                    if( fnf != null && fnf.accept( this, name ) == false ) {
+            handle.sendrecv(rpc);
+
+            FileEntry[] entries = rpc.getEntries();
+            for( int i = 0; i < entries.length; i++ ) {
+                FileEntry e = entries[i];
+                String name = e.getName();
+                if( fnf != null && fnf.accept( this, name ) == false ) {
+                    continue;
+                }
+                if( name.length() > 0 ) {
+                    SmbFile f = new SmbFile( this, name,
+                                e.getType(),
+                                ATTR_READONLY | ATTR_DIRECTORY, 0L, 0L, 0L );
+                    if( ff != null && ff.accept( f ) == false ) {
                         continue;
                     }
-                    if( name.length() > 0 ) {
-                        SmbFile f = new SmbFile( this, name,
-                                    e.getType(),
-                                    ATTR_READONLY | ATTR_DIRECTORY, 0L, 0L, 0L );
-                        if( ff != null && ff.accept( f ) == false ) {
-                            continue;
-                        }
-                        if( files ) {
-                            list.add( f );
-                        } else {
-                            list.add( name );
-                        }
+                    if( files ) {
+                        list.add( f );
+                    } else {
+                        list.add( name );
                     }
                 }
-            } while(more);
+            }
         } finally {
             try {
                 handle.close();
@@ -2600,8 +2597,16 @@ public class SmbFile extends URLConnection implements SmbConstants {
         return new SmbFileOutputStream( this );
     }
 
-    public ACE[] getSecurity() throws IOException {
+/**
+ * Return an array of Access Control Entry (ACE) objects representing
+ * the security descriptor associated with this file or directory.
+ * @param resolveSids Attempt to resolve the SIDs within each ACE form
+ * their numeric representation to their corresponding account names.
+ */
+    public ACE[] getSecurity(boolean resolveSids) throws IOException {
         int f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 );
+        int ai;
+        ACE[] aces;
 
         /*
          * NtTrans Query Security Desc Request / Response
@@ -2612,6 +2617,41 @@ public class SmbFile extends URLConnection implements SmbConstants {
         send( request, response );
 
         close( f, 0L );
-        return response.aces;
+
+        aces = response.aces;
+        if (resolveSids) {
+            SID[] sids = new SID[aces.length];
+            String[] names = null;
+
+            for (ai = 0; ai < aces.length; ai++) {
+                sids[ai] = aces[ai].sid;
+            }
+
+            SID.resolveSids(getServer(), auth, sids);
+        } else {
+            for (ai = 0; ai < aces.length; ai++) {
+                aces[ai].sid.origin_server = getServer();
+                aces[ai].sid.origin_auth = auth;
+            }
+        }
+
+        return aces;
+    }
+/**
+ * Return an array of Access Control Entry (ACE) objects representing
+ * the security descriptor associated with this file or directory.
+ * <p>
+ * Initially, the SIDs within each ACE will not be resolved however when
+ * <tt>getType()</tt>, <tt>getDomainName()</tt>, <tt>getAccountName()</tt>,
+ * or <tt>toString()</tt> is called, the names will attempt to be
+ * resolved. If the names cannot be resolved (e.g. due to temporary
+ * network failure), the said methods will return default values (usually
+ * <tt>S-X-Y-Z</tt> strings of fragments of).
+ * <p>
+ * Alternatively <tt>getSecurity(true)</tt> may be used to resolve all
+ * SIDs together and detect network failures.
+ */
+    public ACE[] getSecurity() throws IOException {
+        return getSecurity(false);
     }
 }