jcifs-1.2.13b4 from tgz
authorFelix Schumacher <p0354740@isib001.(none)>
Wed, 6 Aug 2008 14:41:23 +0000 (16:41 +0200)
committerFelix Schumacher <p0354740@isib001.(none)>
Wed, 6 Aug 2008 14:41:23 +0000 (16:41 +0200)
Mon Jan 15 15:47:47 EST 2007
jcifs-1.2.13b4 released

When trying to connect to port 445 some environments can generate a
NoRouteToHostException as opposed to a ConnectException even though
falling back to port 139 would have worked. The SmbTransport class has
been modifed to also catch the NoRouteToHostException and retry with
port 139.

Mon Jan  8 02:26:56 EST 2007
jcifs-1.2.13b3 released

Two DFS bugs introduced after recent changes have been repaired. The
getDfsPath method would return a path with an extra slash (/) if the
directory referred to the DFS root. The listFiles methods could return
the directory itself as a child. Both issues have been fixed.

Fri Jan  5 16:24:27 EST 2007
jcifs-1.2.13b2 released

The DcerpcHandle.sendrecv() code did not properly buffer fragmented
response PDUs. This resulted in an "invalid array conformance" exception
in the NDR routines. This error has been fixed.

Thu Jan  4 18:12:34 EST 2007
jcifs-1.2.13b1 released

A new SmbFile.getShareSecurity() method that uses a new
MsrpcShareGetInfo/ShareInfo502 RPC has been added. See the API
documentation for details. Also, DFS issues have been identified and
fixed.

15 files changed:
README.txt
build.xml
examples/FileInfo.java
examples/GetShareSecurity.java [new file with mode: 0644]
src/jcifs/dcerpc/DcerpcHandle.java
src/jcifs/dcerpc/msrpc/MsrpcShareGetInfo.java [new file with mode: 0644]
src/jcifs/dcerpc/msrpc/srvsvc.idl
src/jcifs/dcerpc/msrpc/srvsvc.java
src/jcifs/dcerpc/msrpc/srvsvc.java.bak [new file with mode: 0644]
src/jcifs/smb/NtTransQuerySecurityDescResponse.java
src/jcifs/smb/SID.java
src/jcifs/smb/SecurityDescriptor.java [new file with mode: 0644]
src/jcifs/smb/SmbFile.java
src/jcifs/smb/SmbTransport.java
src/jcifs/smb/WinError.java

index 417f94b..bba3e4f 100644 (file)
@@ -1,3 +1,40 @@
+Mon Jan 15 15:47:47 EST 2007
+jcifs-1.2.13b4 released
+
+When trying to connect to port 445 some environments can generate a
+NoRouteToHostException as opposed to a ConnectException even though
+falling back to port 139 would have worked. The SmbTransport class has
+been modifed to also catch the NoRouteToHostException and retry with
+port 139.
+
+Mon Jan  8 02:26:56 EST 2007
+jcifs-1.2.13b3 released
+
+Two DFS bugs introduced after recent changes have been repaired. The
+getDfsPath method would return a path with an extra slash (/) if the
+directory referred to the DFS root. The listFiles methods could return
+the directory itself as a child. Both issues have been fixed.
+
+Fri Jan  5 16:24:27 EST 2007
+jcifs-1.2.13b2 released
+
+The DcerpcHandle.sendrecv() code did not properly buffer fragmented
+response PDUs. This resulted in an "invalid array conformance" exception
+in the NDR routines. This error has been fixed.
+
+Thu Jan  4 18:12:34 EST 2007
+jcifs-1.2.13b1 released
+
+A new SmbFile.getShareSecurity() method that uses a new
+MsrpcShareGetInfo/ShareInfo502 RPC has been added. See the API
+documentation for details. Also, DFS issues have been identified and
+fixed.
+
+Wed Dec 27 19:15:27 EST 2006
+jcifs-1.2.12 released
+
+Just made 1.2.12b2 final.
+
 Thu Dec 21 12:20:14 EST 2006
 jcifs-1.2.12b2 released / getSecurity Bugfix
 
index 2bea7a4..8f8ccac 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -1,7 +1,7 @@
 <project name="jcifs" default="usage" basedir=".">
 
-    <property name="version" value="1.2.12"/>
-    <property name="reldate" value="Dec 27, 2006"/>
+    <property name="version" value="1.2.13b4"/>
+    <property name="reldate" value="Jan 15, 2007"/>
 
     <target name="usage">
         <echo>
index 34320eb..4756dfc 100644 (file)
@@ -1,7 +1,7 @@
 import java.util.*;
 import java.text.*;
 import java.net.*;
-import jcifs.smb.SmbFile;
+import jcifs.smb.*;
 
 public class FileInfo {
 
@@ -108,9 +108,24 @@ public class FileInfo {
                 case 22:
                     System.out.println( "        canWrite: " + f.canWrite() );
                     break;
+                case 23:
+                    ACE[] security = f.getSecurity(true);
+                    System.out.println( "        Security:" );
+                    for (int ai = 0; ai < security.length; ai++) {
+                        System.out.println(security[ai].toString());
+                    }
+                    System.out.println("       Share Perm:");
+                    security = f.getShareSecurity(true);
+                    for (int ai = 0; ai < security.length; ai++) {
+                        System.out.println(security[ai].toString());
+                    }
+                    break;
+                case 24:
+                    System.out.println( "      getDfsPath: " + f.getDfsPath() );
+                    break;
             }
             i++;
-            if( i == 23 ) {
+            if( i == 25 ) {
                 i = 0;
             }
         } while( i != end );
diff --git a/examples/GetShareSecurity.java b/examples/GetShareSecurity.java
new file mode 100644 (file)
index 0000000..1b72cca
--- /dev/null
@@ -0,0 +1,20 @@
+import jcifs.smb.*;
+
+public class GetShareSecurity {
+
+    public static void main( String[] argv ) throws Exception {
+        SmbFile file = new SmbFile( argv[0] );
+        ACE[] security;
+
+        security = file.getShareSecurity(true);
+        System.out.println("Share Permissions:");
+        for (int ai = 0; ai < security.length; ai++) {
+            System.out.println(security[ai].toString());
+        }
+        System.out.println("Security:");
+        security = file.getSecurity(true);
+        for (int ai = 0; ai < security.length; ai++) {
+            System.out.println(security[ai].toString());
+        }
+    }
+}
index bc2c018..cb07581 100644 (file)
@@ -117,8 +117,8 @@ public abstract class DcerpcHandle implements DcerpcConstants {
     }
 
     public void sendrecv(DcerpcMessage msg) throws DcerpcException, IOException {
-        byte[] frag, stub;
-        NdrBuffer buf;
+        byte[] stub, frag;
+        NdrBuffer buf, fbuf;
         boolean isLast;
         DcerpcException de;
 
@@ -128,7 +128,7 @@ public abstract class DcerpcHandle implements DcerpcConstants {
             sendrecv(bind);
         }
 
-        stub = frag = jcifs.smb.BufferCache.getBuffer();
+        stub = jcifs.smb.BufferCache.getBuffer();
         try {
             int off, tot, n;
 
@@ -162,41 +162,41 @@ public abstract class DcerpcHandle implements DcerpcConstants {
                 off += n;
             }
 
-            doReceiveFragment(frag);
+            doReceiveFragment(stub);
             buf.reset();
             msg.decode_header(buf);
-    
+
             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);
-                }
+            if (msg.ptype == 2 && msg.isFlagSet(DCERPC_LAST_FRAG) == false)
                 off = msg.length;
-            }
-    
+
+            frag = null;
+            fbuf = null;
             while (msg.isFlagSet(DCERPC_LAST_FRAG) == false) {
                 int stub_frag_len;
-    
+
+                if (frag == null) {
+                    frag = new byte[max_recv];
+                    fbuf = new NdrBuffer(frag, 0);
+                }
+
                 doReceiveFragment(frag);
-                buf.reset();
-                msg.decode_header(buf);
+                fbuf.reset();
+                msg.decode_header(fbuf);
                 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);
-    
+
+            buf.reset();
             msg.decode(buf);
         } finally {
             jcifs.smb.BufferCache.releaseBuffer(stub);
diff --git a/src/jcifs/dcerpc/msrpc/MsrpcShareGetInfo.java b/src/jcifs/dcerpc/msrpc/MsrpcShareGetInfo.java
new file mode 100644 (file)
index 0000000..a795a12
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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;
+
+public class MsrpcShareGetInfo extends srvsvc.ShareGetInfo {
+
+    public MsrpcShareGetInfo(String server, String sharename) {
+        super(server, sharename, 502, new srvsvc.ShareInfo502());
+        ptype = 0;
+        flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG;
+    }
+
+    public ACE[] getSecurity() {
+        srvsvc.ShareInfo502 info502 = (srvsvc.ShareInfo502)info;
+        if (info502.security_descriptor != null) {
+            SecurityDescriptor sd;
+            sd = new SecurityDescriptor(info502.security_descriptor, 0, info502.sd_size);
+            return sd.aces;
+        }
+        return new ACE[0];
+    }
+}
index 96ae42d..3e692fb 100644 (file)
@@ -26,9 +26,34 @@ interface srvsvc
                [size_is(count)] ShareInfo1 *array;
        } ShareInfoCtr1;
 
+       typedef struct {
+               [string] wchar_t *netname;
+               int type;
+               [string] wchar_t *remark;
+               uint32_t permissions;
+               uint32_t max_uses;
+               uint32_t current_uses;
+               [string] wchar_t *path;
+               [string] wchar_t *password;
+               uint32_t sd_size;
+               [size_is(sd_size)] uint8_t *security_descriptor;
+       } ShareInfo502;
+
+       typedef struct {
+               int count;
+               [size_is(count)] ShareInfo502 *array;
+       } ShareInfoCtr502;
+
+       typedef [switch_type(int)] union {
+               [case(0)] ShareInfo0 *info0;
+               [case(1)] ShareInfo1 *info1;
+               [case(502)] ShareInfo502 *info1;
+       } ShareInfo;
+
        typedef [switch_type(int)] union {
                [case(0)] ShareInfoCtr0 *info0;
                [case(1)] ShareInfoCtr1 *info1;
+               [case(502)] ShareInfoCtr502 *info1;
        } ShareCtr;
 
        [op(0x0f)]
@@ -39,6 +64,12 @@ interface srvsvc
                        [out] unsigned long *totalentries,
                        [in,out] unsigned long *resume_handle);
 
+       [op(0x10)]
+       int ShareGetInfo([in,string,unique] wchar_t *servername,
+                       [in,string] wchar_t *sharename,
+                       [in] int level,
+                       [out,switch_is(level)] ShareInfo *info);
+
        typedef struct {
                unsigned long platform_id;
                [string] wchar_t *name;
index 179e1b6..980bae6 100644 (file)
@@ -3,6 +3,8 @@ package jcifs.dcerpc.msrpc;
 import jcifs.dcerpc.*;
 import jcifs.dcerpc.ndr.*;
 
+import jcifs.util.Hexdump;
+
 public class srvsvc {
 
     public static String getSyntax() {
@@ -171,6 +173,163 @@ public class srvsvc {
             }
         }
     }
+    public static class ShareInfo502 extends NdrObject {
+
+        public String netname;
+        public int type;
+        public String remark;
+        public int permissions;
+        public int max_uses;
+        public int current_uses;
+        public String path;
+        public String password;
+        public int sd_size;
+        public byte[] security_descriptor;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_referent(netname, 1);
+            _dst.enc_ndr_long(type);
+            _dst.enc_ndr_referent(remark, 1);
+            _dst.enc_ndr_long(permissions);
+            _dst.enc_ndr_long(max_uses);
+            _dst.enc_ndr_long(current_uses);
+            _dst.enc_ndr_referent(path, 1);
+            _dst.enc_ndr_referent(password, 1);
+            _dst.enc_ndr_long(sd_size);
+            _dst.enc_ndr_referent(security_descriptor, 1);
+
+            if (netname != null) {
+                _dst = _dst.deferred;
+                _dst.enc_ndr_string(netname);
+
+            }
+            if (remark != null) {
+                _dst = _dst.deferred;
+                _dst.enc_ndr_string(remark);
+
+            }
+            if (path != null) {
+                _dst = _dst.deferred;
+                _dst.enc_ndr_string(path);
+
+            }
+            if (password != null) {
+                _dst = _dst.deferred;
+                _dst.enc_ndr_string(password);
+
+            }
+            if (security_descriptor != null) {
+                _dst = _dst.deferred;
+                int _security_descriptors = sd_size;
+                _dst.enc_ndr_long(_security_descriptors);
+                int _security_descriptori = _dst.index;
+                _dst.advance(1 * _security_descriptors);
+
+                _dst = _dst.derive(_security_descriptori);
+                for (int _i = 0; _i < _security_descriptors; _i++) {
+                    _dst.enc_ndr_small(security_descriptor[_i]);
+                }
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            int _netnamep = _src.dec_ndr_long();
+            type = (int)_src.dec_ndr_long();
+            int _remarkp = _src.dec_ndr_long();
+            permissions = (int)_src.dec_ndr_long();
+            max_uses = (int)_src.dec_ndr_long();
+            current_uses = (int)_src.dec_ndr_long();
+            int _pathp = _src.dec_ndr_long();
+            int _passwordp = _src.dec_ndr_long();
+            sd_size = (int)_src.dec_ndr_long();
+            int _security_descriptorp = _src.dec_ndr_long();
+
+            if (_netnamep != 0) {
+                _src = _src.deferred;
+                netname = _src.dec_ndr_string();
+
+            }
+            if (_remarkp != 0) {
+                _src = _src.deferred;
+                remark = _src.dec_ndr_string();
+
+            }
+            if (_pathp != 0) {
+                _src = _src.deferred;
+                path = _src.dec_ndr_string();
+
+            }
+            if (_passwordp != 0) {
+                _src = _src.deferred;
+                password = _src.dec_ndr_string();
+
+            }
+            if (_security_descriptorp != 0) {
+                _src = _src.deferred;
+                int _security_descriptors = _src.dec_ndr_long();
+                int _security_descriptori = _src.index;
+                _src.advance(1 * _security_descriptors);
+
+                if (security_descriptor == null) {
+                    if (_security_descriptors < 0 || _security_descriptors > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    security_descriptor = new byte[_security_descriptors];
+                }
+                _src = _src.derive(_security_descriptori);
+                for (int _i = 0; _i < _security_descriptors; _i++) {
+                    security_descriptor[_i] = (byte)_src.dec_ndr_small();
+                }
+            }
+        }
+    }
+    public static class ShareInfoCtr502 extends NdrObject {
+
+        public int count;
+        public ShareInfo502[] array;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(count);
+            _dst.enc_ndr_referent(array, 1);
+
+            if (array != null) {
+                _dst = _dst.deferred;
+                int _arrays = count;
+                _dst.enc_ndr_long(_arrays);
+                int _arrayi = _dst.index;
+                _dst.advance(40 * _arrays);
+
+                _dst = _dst.derive(_arrayi);
+                for (int _i = 0; _i < _arrays; _i++) {
+                    array[_i].encode(_dst);
+                }
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            count = (int)_src.dec_ndr_long();
+            int _arrayp = _src.dec_ndr_long();
+
+            if (_arrayp != 0) {
+                _src = _src.deferred;
+                int _arrays = _src.dec_ndr_long();
+                int _arrayi = _src.index;
+                _src.advance(40 * _arrays);
+
+                if (array == null) {
+                    if (_arrays < 0 || _arrays > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    array = new ShareInfo502[_arrays];
+                }
+                _src = _src.derive(_arrayi);
+                for (int _i = 0; _i < _arrays; _i++) {
+                    if (array[_i] == null) {
+                        array[_i] = new ShareInfo502();
+                    }
+                    array[_i].decode(_src);
+                }
+            }
+        }
+    }
     public static class ShareEnumAll extends DcerpcMessage {
 
         public int getOpnum() { return 0x0f; }
@@ -232,6 +391,49 @@ public class srvsvc {
             retval = (int)_src.dec_ndr_long();
         }
     }
+    public static class ShareGetInfo extends DcerpcMessage {
+
+        public int getOpnum() { return 0x10; }
+
+        public int retval;
+        public String servername;
+        public String sharename;
+        public int level;
+        public NdrObject info;
+
+        public ShareGetInfo(String servername,
+                    String sharename,
+                    int level,
+                    NdrObject info) {
+            this.servername = servername;
+            this.sharename = sharename;
+            this.level = level;
+            this.info = info;
+        }
+
+        public void encode_in(NdrBuffer _dst) throws NdrException {
+            _dst.enc_ndr_referent(servername, 1);
+            if (servername != null) {
+                _dst.enc_ndr_string(servername);
+
+            }
+            _dst.enc_ndr_string(sharename);
+            _dst.enc_ndr_long(level);
+        }
+        public void decode_out(NdrBuffer _src) throws NdrException {
+            _src.dec_ndr_long(); /* union discriminant */
+            int _infop = _src.dec_ndr_long();
+            if (_infop != 0) {
+                if (info == null) { /* YOYOYO */
+                    info = new ShareInfo0();
+                }
+                _src = _src.deferred;
+                info.decode(_src);
+
+            }
+            retval = (int)_src.dec_ndr_long();
+        }
+    }
     public static class ServerInfo100 extends NdrObject {
 
         public int platform_id;
diff --git a/src/jcifs/dcerpc/msrpc/srvsvc.java.bak b/src/jcifs/dcerpc/msrpc/srvsvc.java.bak
new file mode 100644 (file)
index 0000000..179e1b6
--- /dev/null
@@ -0,0 +1,380 @@
+package jcifs.dcerpc.msrpc;
+
+import jcifs.dcerpc.*;
+import jcifs.dcerpc.ndr.*;
+
+public class srvsvc {
+
+    public static String getSyntax() {
+        return "4b324fc8-1670-01d3-1278-5a47bf6ee188:3.0";
+    }
+
+    public static class ShareInfo0 extends NdrObject {
+
+        public String netname;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_referent(netname, 1);
+
+            if (netname != null) {
+                _dst = _dst.deferred;
+                _dst.enc_ndr_string(netname);
+
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            int _netnamep = _src.dec_ndr_long();
+
+            if (_netnamep != 0) {
+                _src = _src.deferred;
+                netname = _src.dec_ndr_string();
+
+            }
+        }
+    }
+    public static class ShareInfoCtr0 extends NdrObject {
+
+        public int count;
+        public ShareInfo0[] array;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(count);
+            _dst.enc_ndr_referent(array, 1);
+
+            if (array != null) {
+                _dst = _dst.deferred;
+                int _arrays = count;
+                _dst.enc_ndr_long(_arrays);
+                int _arrayi = _dst.index;
+                _dst.advance(4 * _arrays);
+
+                _dst = _dst.derive(_arrayi);
+                for (int _i = 0; _i < _arrays; _i++) {
+                    array[_i].encode(_dst);
+                }
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            count = (int)_src.dec_ndr_long();
+            int _arrayp = _src.dec_ndr_long();
+
+            if (_arrayp != 0) {
+                _src = _src.deferred;
+                int _arrays = _src.dec_ndr_long();
+                int _arrayi = _src.index;
+                _src.advance(4 * _arrays);
+
+                if (array == null) {
+                    if (_arrays < 0 || _arrays > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    array = new ShareInfo0[_arrays];
+                }
+                _src = _src.derive(_arrayi);
+                for (int _i = 0; _i < _arrays; _i++) {
+                    if (array[_i] == null) {
+                        array[_i] = new ShareInfo0();
+                    }
+                    array[_i].decode(_src);
+                }
+            }
+        }
+    }
+    public static class ShareInfo1 extends NdrObject {
+
+        public String netname;
+        public int type;
+        public String remark;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_referent(netname, 1);
+            _dst.enc_ndr_long(type);
+            _dst.enc_ndr_referent(remark, 1);
+
+            if (netname != null) {
+                _dst = _dst.deferred;
+                _dst.enc_ndr_string(netname);
+
+            }
+            if (remark != null) {
+                _dst = _dst.deferred;
+                _dst.enc_ndr_string(remark);
+
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            int _netnamep = _src.dec_ndr_long();
+            type = (int)_src.dec_ndr_long();
+            int _remarkp = _src.dec_ndr_long();
+
+            if (_netnamep != 0) {
+                _src = _src.deferred;
+                netname = _src.dec_ndr_string();
+
+            }
+            if (_remarkp != 0) {
+                _src = _src.deferred;
+                remark = _src.dec_ndr_string();
+
+            }
+        }
+    }
+    public static class ShareInfoCtr1 extends NdrObject {
+
+        public int count;
+        public ShareInfo1[] array;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(count);
+            _dst.enc_ndr_referent(array, 1);
+
+            if (array != null) {
+                _dst = _dst.deferred;
+                int _arrays = count;
+                _dst.enc_ndr_long(_arrays);
+                int _arrayi = _dst.index;
+                _dst.advance(12 * _arrays);
+
+                _dst = _dst.derive(_arrayi);
+                for (int _i = 0; _i < _arrays; _i++) {
+                    array[_i].encode(_dst);
+                }
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            count = (int)_src.dec_ndr_long();
+            int _arrayp = _src.dec_ndr_long();
+
+            if (_arrayp != 0) {
+                _src = _src.deferred;
+                int _arrays = _src.dec_ndr_long();
+                int _arrayi = _src.index;
+                _src.advance(12 * _arrays);
+
+                if (array == null) {
+                    if (_arrays < 0 || _arrays > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE );
+                    array = new ShareInfo1[_arrays];
+                }
+                _src = _src.derive(_arrayi);
+                for (int _i = 0; _i < _arrays; _i++) {
+                    if (array[_i] == null) {
+                        array[_i] = new ShareInfo1();
+                    }
+                    array[_i].decode(_src);
+                }
+            }
+        }
+    }
+    public static class ShareEnumAll extends DcerpcMessage {
+
+        public int getOpnum() { return 0x0f; }
+
+        public int retval;
+        public String servername;
+        public int level;
+        public NdrObject info;
+        public int prefmaxlen;
+        public int totalentries;
+        public int resume_handle;
+
+        public ShareEnumAll(String servername,
+                    int level,
+                    NdrObject info,
+                    int prefmaxlen,
+                    int totalentries,
+                    int resume_handle) {
+            this.servername = servername;
+            this.level = level;
+            this.info = info;
+            this.prefmaxlen = prefmaxlen;
+            this.totalentries = totalentries;
+            this.resume_handle = resume_handle;
+        }
+
+        public void encode_in(NdrBuffer _dst) throws NdrException {
+            _dst.enc_ndr_referent(servername, 1);
+            if (servername != null) {
+                _dst.enc_ndr_string(servername);
+
+            }
+            _dst.enc_ndr_long(level);
+            int _descr = level;
+            _dst.enc_ndr_long(_descr);
+            _dst.enc_ndr_referent(info, 1);
+            if (info != null) {
+                _dst = _dst.deferred;
+                info.encode(_dst);
+
+            }
+            _dst.enc_ndr_long(prefmaxlen);
+            _dst.enc_ndr_long(resume_handle);
+        }
+        public void decode_out(NdrBuffer _src) throws NdrException {
+            level = (int)_src.dec_ndr_long();
+            _src.dec_ndr_long(); /* union discriminant */
+            int _infop = _src.dec_ndr_long();
+            if (_infop != 0) {
+                if (info == null) { /* YOYOYO */
+                    info = new ShareInfoCtr0();
+                }
+                _src = _src.deferred;
+                info.decode(_src);
+
+            }
+            totalentries = (int)_src.dec_ndr_long();
+            resume_handle = (int)_src.dec_ndr_long();
+            retval = (int)_src.dec_ndr_long();
+        }
+    }
+    public static class ServerInfo100 extends NdrObject {
+
+        public int platform_id;
+        public String name;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(platform_id);
+            _dst.enc_ndr_referent(name, 1);
+
+            if (name != null) {
+                _dst = _dst.deferred;
+                _dst.enc_ndr_string(name);
+
+            }
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            platform_id = (int)_src.dec_ndr_long();
+            int _namep = _src.dec_ndr_long();
+
+            if (_namep != 0) {
+                _src = _src.deferred;
+                name = _src.dec_ndr_string();
+
+            }
+        }
+    }
+    public static class ServerGetInfo extends DcerpcMessage {
+
+        public int getOpnum() { return 0x15; }
+
+        public int retval;
+        public String servername;
+        public int level;
+        public NdrObject info;
+
+        public ServerGetInfo(String servername, int level, NdrObject info) {
+            this.servername = servername;
+            this.level = level;
+            this.info = info;
+        }
+
+        public void encode_in(NdrBuffer _dst) throws NdrException {
+            _dst.enc_ndr_referent(servername, 1);
+            if (servername != null) {
+                _dst.enc_ndr_string(servername);
+
+            }
+            _dst.enc_ndr_long(level);
+        }
+        public void decode_out(NdrBuffer _src) throws NdrException {
+            _src.dec_ndr_long(); /* union discriminant */
+            int _infop = _src.dec_ndr_long();
+            if (_infop != 0) {
+                if (info == null) { /* YOYOYO */
+                    info = new ServerInfo100();
+                }
+                _src = _src.deferred;
+                info.decode(_src);
+
+            }
+            retval = (int)_src.dec_ndr_long();
+        }
+    }
+    public static class TimeOfDayInfo extends NdrObject {
+
+        public int elapsedt;
+        public int msecs;
+        public int hours;
+        public int mins;
+        public int secs;
+        public int hunds;
+        public int timezone;
+        public int tinterval;
+        public int day;
+        public int month;
+        public int year;
+        public int weekday;
+
+        public void encode(NdrBuffer _dst) throws NdrException {
+            _dst.align(4);
+            _dst.enc_ndr_long(elapsedt);
+            _dst.enc_ndr_long(msecs);
+            _dst.enc_ndr_long(hours);
+            _dst.enc_ndr_long(mins);
+            _dst.enc_ndr_long(secs);
+            _dst.enc_ndr_long(hunds);
+            _dst.enc_ndr_long(timezone);
+            _dst.enc_ndr_long(tinterval);
+            _dst.enc_ndr_long(day);
+            _dst.enc_ndr_long(month);
+            _dst.enc_ndr_long(year);
+            _dst.enc_ndr_long(weekday);
+
+        }
+        public void decode(NdrBuffer _src) throws NdrException {
+            _src.align(4);
+            elapsedt = (int)_src.dec_ndr_long();
+            msecs = (int)_src.dec_ndr_long();
+            hours = (int)_src.dec_ndr_long();
+            mins = (int)_src.dec_ndr_long();
+            secs = (int)_src.dec_ndr_long();
+            hunds = (int)_src.dec_ndr_long();
+            timezone = (int)_src.dec_ndr_long();
+            tinterval = (int)_src.dec_ndr_long();
+            day = (int)_src.dec_ndr_long();
+            month = (int)_src.dec_ndr_long();
+            year = (int)_src.dec_ndr_long();
+            weekday = (int)_src.dec_ndr_long();
+
+        }
+    }
+    public static class RemoteTOD extends DcerpcMessage {
+
+        public int getOpnum() { return 0x1c; }
+
+        public int retval;
+        public String servername;
+        public TimeOfDayInfo info;
+
+        public RemoteTOD(String servername, TimeOfDayInfo info) {
+            this.servername = servername;
+            this.info = info;
+        }
+
+        public void encode_in(NdrBuffer _dst) throws NdrException {
+            _dst.enc_ndr_referent(servername, 1);
+            if (servername != null) {
+                _dst.enc_ndr_string(servername);
+
+            }
+        }
+        public void decode_out(NdrBuffer _src) throws NdrException {
+            int _infop = _src.dec_ndr_long();
+            if (_infop != 0) {
+                if (info == null) { /* YOYOYO */
+                    info = new TimeOfDayInfo();
+                }
+                info.decode(_src);
+
+            }
+            retval = (int)_src.dec_ndr_long();
+        }
+    }
+}
index 92e03b1..3700805 100644 (file)
@@ -20,8 +20,7 @@ package jcifs.smb;
 
 class NtTransQuerySecurityDescResponse extends SmbComNtTransactionResponse {
 
-    int type;
-    ACE[] aces;
+    SecurityDescriptor securityDescriptor;
 
     NtTransQuerySecurityDescResponse() {
         super();
@@ -49,35 +48,8 @@ class NtTransQuerySecurityDescResponse extends SmbComNtTransactionResponse {
         if (errorCode != 0)
             return 4;
 
-        bufferIndex++; // revision
-        bufferIndex++;
-        type = readInt2(buffer, bufferIndex);
-        bufferIndex += 2;
-        readInt4(buffer, bufferIndex); // offset to owner sid
-        bufferIndex += 4;
-        readInt4(buffer, bufferIndex); // offset to group sid
-        bufferIndex += 4;
-        readInt4(buffer, bufferIndex); // offset to sacl
-        bufferIndex += 4;
-        int daclOffset = readInt4(buffer, bufferIndex);
-
-        bufferIndex = start + daclOffset;
-
-        bufferIndex++; // revision
-        bufferIndex++;
-        int size = readInt2(buffer, bufferIndex);
-        bufferIndex += 2;
-        int numAces = readInt4(buffer, bufferIndex);
-        bufferIndex += 4;
-
-        if (numAces > 4096)
-            throw new RuntimeException( "Invalid SecurityDescriptor" );
-
-        aces = new ACE[numAces];
-        for (int i = 0; i < numAces; i++) {
-            aces[i] = new ACE();
-            bufferIndex += aces[i].decode(buffer, bufferIndex);
-        }
+        securityDescriptor = new SecurityDescriptor();
+        bufferIndex += securityDescriptor.decode(buffer, bufferIndex, len);
 
         return bufferIndex - start;
     }
index cb65b28..372a495 100644 (file)
@@ -167,7 +167,7 @@ public class SID extends rpc.sid_t {
     String origin_server = null;
     NtlmPasswordAuthentication origin_auth = null;
 
-    /**
+    /*
      * Construct a SID from it's binary representation.
      */
     public SID(byte[] src, int si) {
diff --git a/src/jcifs/smb/SecurityDescriptor.java b/src/jcifs/smb/SecurityDescriptor.java
new file mode 100644 (file)
index 0000000..4b35b63
--- /dev/null
@@ -0,0 +1,73 @@
+/* jcifs smb client library in Java
+ * Copyright (C) 2005  "Michael B. Allen" <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;
+
+public class SecurityDescriptor {
+
+    public int type;
+    public ACE[] aces;
+
+    public SecurityDescriptor() {
+    }
+    public SecurityDescriptor(byte[] buffer, int bufferIndex, int len) {
+        this.decode(buffer, bufferIndex, len);
+    }
+    public int decode(byte[] buffer, int bufferIndex, int len) {
+        int start = bufferIndex;
+
+        bufferIndex++; // revision
+        bufferIndex++;
+        type = ServerMessageBlock.readInt2(buffer, bufferIndex);
+        bufferIndex += 2;
+        ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to owner sid
+        bufferIndex += 4;
+        ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to group sid
+        bufferIndex += 4;
+        ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to sacl
+        bufferIndex += 4;
+        int daclOffset = ServerMessageBlock.readInt4(buffer, bufferIndex);
+
+        bufferIndex = start + daclOffset;
+
+        bufferIndex++; // revision
+        bufferIndex++;
+        int size = ServerMessageBlock.readInt2(buffer, bufferIndex);
+        bufferIndex += 2;
+        int numAces = ServerMessageBlock.readInt4(buffer, bufferIndex);
+        bufferIndex += 4;
+
+        if (numAces > 4096)
+            throw new RuntimeException( "Invalid SecurityDescriptor" );
+
+        aces = new ACE[numAces];
+        for (int i = 0; i < numAces; i++) {
+            aces[i] = new ACE();
+            bufferIndex += aces[i].decode(buffer, bufferIndex);
+        }
+
+        return bufferIndex - start;
+    }
+    public String toString() {
+        String ret = "SecurityDescriptor:\n";
+        for (int ai = 0; ai < aces.length; ai++) {
+            ret += aces[ai].toString() + "\n";
+        }
+        return ret;
+    }
+}
index 5f09ced..6b9f24c 100644 (file)
@@ -680,7 +680,11 @@ public class SmbFile extends URLConnection implements SmbConstants {
                         log.println( dr );
 
                     dfsReferral = dr;
-                    request.path = unc = getDfsUncPath0();
+                    String dunc = dfsReferral.nodepath + unc.substring( dfsReferral.path.length() );
+                    unc = dunc;
+                    if (request.path.endsWith("\\") && dunc.endsWith("\\") == false)
+                        dunc += "\\";
+                    request.path = dunc;
                 }
                 request.flags2 |= ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS;
             } else {
@@ -1085,6 +1089,27 @@ public class SmbFile extends URLConnection implements SmbConstants {
         return share;
     }
 
+    String getServerWithDfs() {
+        if (dfsReferral != null) {
+            /* Don't use dfsReferral.server because vers 1 referrals don't have it
+             */
+            char[] server = dfsReferral.node.toCharArray();
+            int start, end;
+
+            start = 0;
+            while (start < server.length && server[start] == '\\') {
+                start++;
+            }
+            end = start;
+            while (end < server.length && server[end] != '\\') {
+                end++;
+            }
+
+            return new String(server, start, end - start);
+        }
+
+        return getServer();
+    }
 /** 
  * Retrieve the hostname of the server for this SMB resource. If this
  * <code>SmbFile</code> references a workgroup, the name of the workgroup
@@ -1169,10 +1194,6 @@ public class SmbFile extends URLConnection implements SmbConstants {
     Info queryPath( String path, int infoLevel ) throws SmbException {
         connect0();
 
-        if (dfsReferral != null) {
-            path = dfsReferral.nodepath + path.substring( dfsReferral.path.length() );
-        }
-
         if (log.level >= 3)
             log.println( "queryPath: " + path );
 
@@ -1365,14 +1386,6 @@ public class SmbFile extends URLConnection implements SmbConstants {
         return ( attributes & ATTR_HIDDEN ) == ATTR_HIDDEN;
     }
 
-    String getDfsUncPath0() throws SmbException {
-        getUncPath0();
-        if( dfsReferral == null ) {
-            return null;
-        }
-        String dunc = dfsReferral.nodepath + unc.substring( dfsReferral.path.length() );
-        return "".equals( dunc ) ? "\\" : dunc;
-    }
 /**
  * If the path of this <code>SmbFile</code> falls within a DFS volume,
  * this method will return the referral path to which it maps. Otherwise
@@ -1387,7 +1400,7 @@ public class SmbFile extends URLConnection implements SmbConstants {
         if( dfsReferral == null ) {
             return null;
         }
-        String path = "smb:/" + dfsReferral.node + getDfsUncPath0();
+        String path = "smb:/" + dfsReferral.node + unc;
         path = path.replace( '\\', '/' );
         if (isDirectory()) {
             path += '/';
@@ -1644,7 +1657,8 @@ public class SmbFile extends URLConnection implements SmbConstants {
 
         try {
             handle.sendrecv(rpc);
-
+            if (rpc.retval != 0)
+                throw new SmbException(rpc.retval, true);
             FileEntry[] entries = rpc.getEntries();
             for( int i = 0; i < entries.length; i++ ) {
                 FileEntry e = entries[i];
@@ -2597,6 +2611,26 @@ public class SmbFile extends URLConnection implements SmbConstants {
         return new SmbFileOutputStream( this );
     }
 
+    private void processAces(ACE[] aces, boolean resolveSids) throws IOException {
+        String server = getServerWithDfs();
+        int ai;
+
+        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(server, auth, sids);
+        } else {
+            for (ai = 0; ai < aces.length; ai++) {
+                aces[ai].sid.origin_server = server;
+                aces[ai].sid.origin_auth = auth;
+            }
+        }
+    }
 /**
  * Return an array of Access Control Entry (ACE) objects representing
  * the security descriptor associated with this file or directory.
@@ -2605,7 +2639,6 @@ public class SmbFile extends URLConnection implements SmbConstants {
  */
     public ACE[] getSecurity(boolean resolveSids) throws IOException {
         int f;
-        int ai;
         ACE[] aces;
 
         f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 );
@@ -2616,24 +2649,55 @@ public class SmbFile extends URLConnection implements SmbConstants {
 
         NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( f, 0x04 );
         NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse();
-        send( request, response );
 
-        close( f, 0L );
+        try {
+            send( request, response );
+        } finally {
+            close( f, 0L );
+        }
 
-        aces = response.aces;
-        if (resolveSids) {
-            SID[] sids = new SID[aces.length];
-            String[] names = null;
+        aces = response.securityDescriptor.aces;
+        processAces(aces, resolveSids);
 
-            for (ai = 0; ai < aces.length; ai++) {
-                sids[ai] = aces[ai].sid;
-            }
+        return aces;
+    }
+/**
+ * Return an array of Access Control Entry (ACE) objects representing
+ * the share permissions on the share exporting this file or directory.
+ * <p>
+ * Note that this is different from calling <tt>getSecurity</tt> on a
+ * share. There are actually two different ACLs for shares - the ACL on
+ * the share and the ACL on the folder being shared.
+ * Go to <i>Computer Management</i>
+ * &gt; <i>System Tools</i> &gt; <i>Shared Folders</i> &gt <i>Shares</i> and
+ * look at the <i>Properties</i> for a share. You will see two tabs - one
+ * for "Share Permissions" and another for "Security". These correspond to
+ * the ACLs returned by <tt>getShareSecurity</tt> and <tt>getSecurity</tt>
+ * respectively.
+ * @param resolveSids Attempt to resolve the SIDs within each ACE form
+ * their numeric representation to their corresponding account names.
+ */
+    public ACE[] getShareSecurity(boolean resolveSids) throws IOException {
+        String p = url.getPath();
+        MsrpcShareGetInfo rpc;
+        DcerpcHandle handle;
+        ACE[] aces;
 
-            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;
+        rpc = new MsrpcShareGetInfo(url.getHost(), getShare());
+        handle = DcerpcHandle.getHandle("ncacn_np:" + url.getHost() + "[\\PIPE\\srvsvc]", auth);
+
+        try {
+            handle.sendrecv(rpc);
+            if (rpc.retval != 0)
+                throw new SmbException(rpc.retval, true);
+            aces = rpc.getSecurity();
+            processAces(aces, resolveSids);
+        } finally {
+            try {
+                handle.close();
+            } catch(IOException ioe) {
+                if (log.level >= 1)
+                    ioe.printStackTrace(log);
             }
         }
 
index 88206de..9712b43 100644 (file)
@@ -300,6 +300,9 @@ public class SmbTransport extends Transport implements SmbConstants {
         } catch( ConnectException ce ) {
             port = (port == 0 || port == DEFAULT_PORT) ? 139 : DEFAULT_PORT;
             negotiate( port, resp );
+        } catch( NoRouteToHostException nr ) {
+            port = (port == 0 || port == DEFAULT_PORT) ? 139 : DEFAULT_PORT;
+            negotiate( port, resp );
         }
 
         if( resp.dialectIndex > 10 ) {
index c154fc2..586cf6c 100644 (file)
@@ -25,6 +25,7 @@ public interface WinError {
      */
 
     public static final int ERROR_SUCCESS = 0;
+    public static final int ERROR_ACCESS_DENIED = 5;
     public static final int ERROR_REQ_NOT_ACCEP = 71;
     public static final int ERROR_BAD_PIPE = 230;
     public static final int ERROR_PIPE_BUSY = 231;
@@ -35,24 +36,26 @@ public interface WinError {
 
     static final int[] WINERR_CODES = {
         ERROR_SUCCESS,
+        ERROR_ACCESS_DENIED,
         ERROR_REQ_NOT_ACCEP,
         ERROR_BAD_PIPE,
         ERROR_PIPE_BUSY,
         ERROR_NO_DATA,
         ERROR_PIPE_NOT_CONNECTED,
         ERROR_MORE_DATA,
-        ERROR_NO_BROWSER_SERVERS_FOUND
+        ERROR_NO_BROWSER_SERVERS_FOUND,
     };
 
     static final String[] WINERR_MESSAGES = {
         "The operation completed successfully.",
+        "Access is denied.",
         "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 pipe state is invalid.",
         "All pipe instances are busy.",
         "The pipe is being closed.",
         "No process is on the other end of the pipe.",
         "More data is available.",
-        "The list of servers for this workgroup is not currently available."
+        "The list of servers for this workgroup is not currently available.",
     };
 }