From 811840c2147ebeeeaf5abf1c42c66ecbd1b6afd5 Mon Sep 17 00:00:00 2001 From: Felix Schumacher Date: Wed, 6 Aug 2008 16:46:26 +0200 Subject: [PATCH] jcifs-1.2.20 from tgz Tue May 27 16:06:13 EDT 2008 jcifs-1.2.20 The Dfs cache was not thread safe. This has been fixed. The trusted domains are now looked up with <1C> NetBIOS lookups to speed discovery. Wed Apr 16 17:45:52 EDT 2008 jcifs-1.2.20b EMC could return "Access denied" for the SMB_COM_FIND_CLOSE2 on a read-only share. A try catch was added to ignore errors for that request since it otherwise has no logical importance. Examining a capture of XP with EMC reveals that no SMB_COM_FIND_CLOSE2 is sent at all. The read logic could error on the special 0x80000005 status used by named pipes to indicate more data should be read. This caused SmbFile.getShareSecurity() to fail on large ACLs. This issue has been fixed. The getShareSecurity() method would previously fail to resolve more than about 110 SIDs in one call because of a limitation in JCIFS' ability to emit multi-fragment request PDUs. The getShareSecurity() method has been modified to process SIDs in chunks of 64 to work-around this issue. --- README.txt | 22 ++ build.xml | 4 +- patches/jcifs_1.2.20c+LsaLookupNames.patch | 328 +++++++++++++++++++++++++ patches/midl-upton.patch | 106 ++++++++ src/jcifs/Config.java | 3 + src/jcifs/UniAddress.java | 4 +- src/jcifs/dcerpc/msrpc/srvsvc.java.bak | 380 ----------------------------- src/jcifs/netbios/NameServiceClient.java | 5 + src/jcifs/smb/ACE.java | 1 + src/jcifs/smb/Dfs.java | 8 +- src/jcifs/smb/SID.java | 29 ++- src/jcifs/smb/SecurityDescriptor.java | 2 + src/jcifs/smb/SmbFile.java | 14 +- src/jcifs/smb/SmbTransport.java | 24 +- 14 files changed, 537 insertions(+), 393 deletions(-) create mode 100644 patches/jcifs_1.2.20c+LsaLookupNames.patch create mode 100644 patches/midl-upton.patch delete mode 100644 src/jcifs/dcerpc/msrpc/srvsvc.java.bak diff --git a/README.txt b/README.txt index 6d56016..4f920cb 100644 --- a/README.txt +++ b/README.txt @@ -1,3 +1,25 @@ +Tue May 27 16:06:13 EDT 2008 +jcifs-1.2.20 + +The Dfs cache was not thread safe. This has been fixed. The trusted +domains are now looked up with <1C> NetBIOS lookups to speed discovery. + +Wed Apr 16 17:45:52 EDT 2008 +jcifs-1.2.20b + +EMC could return "Access denied" for the SMB_COM_FIND_CLOSE2 on a +read-only share. A try catch was added to ignore errors for that request +since it otherwise has no logical importance. Examining a capture of XP +with EMC reveals that no SMB_COM_FIND_CLOSE2 is sent at all. + +The read logic could error on the special 0x80000005 status used +by named pipes to indicate more data should be read. This caused +SmbFile.getShareSecurity() to fail on large ACLs. This issue has been +fixed. The getShareSecurity() method would previously fail to resolve more +than about 110 SIDs in one call because of a limitation in JCIFS' ability +to emit multi-fragment request PDUs. The getShareSecurity() method has +been modified to process SIDs in chunks of 64 to work-around this issue. + Sun Apr 6 19:46:47 EDT 2008 jcifs-1.2.19 released diff --git a/build.xml b/build.xml index aa09a50..172f2b9 100644 --- a/build.xml +++ b/build.xml @@ -1,7 +1,7 @@ - - + + diff --git a/patches/jcifs_1.2.20c+LsaLookupNames.patch b/patches/jcifs_1.2.20c+LsaLookupNames.patch new file mode 100644 index 0000000..71303f1 --- /dev/null +++ b/patches/jcifs_1.2.20c+LsaLookupNames.patch @@ -0,0 +1,328 @@ +diff -ruNd --strip-trailing-cr jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java +--- jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java 1970-01-01 01:00:00.000000000 +0100 ++++ jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/MsrpcLookupNames.java 2008-04-21 23:54:24.000000000 +0200 +@@ -0,0 +1,16 @@ ++package jcifs.dcerpc.msrpc; ++ ++ ++public class MsrpcLookupNames extends lsarpc.LsarLookupNames { ++ public MsrpcLookupNames(LsaPolicyHandle policyHandle, String names[]) { ++ super( ++ policyHandle, ++ names, ++ (short)1, ++ 0 ++ ); ++ ++ ptype = 0; ++ flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; ++ } ++} +diff -ruNd --strip-trailing-cr jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/lsarpc.java jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/lsarpc.java +--- jcifs_1.2.20c/src/jcifs/dcerpc/msrpc/lsarpc.java 2008-04-25 19:34:39.000000000 +0200 ++++ jcifs_1.2.20c+LsaLookupNames/src/jcifs/dcerpc/msrpc/lsarpc.java 2008-05-23 16:44:42.000000000 +0200 +@@ -1,5 +1,7 @@ + package jcifs.dcerpc.msrpc; + ++import java.nio.charset.Charset; ++ + import jcifs.dcerpc.*; + import jcifs.dcerpc.ndr.*; + +@@ -848,6 +850,93 @@ + retval = (int)_src.dec_ndr_long(); + } + } ++ public static class LsarLookupNames extends DcerpcMessage { ++ protected static final Charset csULU = Charset.forName("UnicodeLittleUnmarked"); ++ ++ public int getOpnum() { return 0x0e; } ++ ++ public int retval; ++ public rpc.policy_handle handle; ++ public String names[]; ++ public LsarRefDomainList domains; ++ public LsarTransSidArray sids; ++ public short level; ++ public int count; ++ ++ public LsarLookupNames( ++ rpc.policy_handle handle, ++ String names[], ++ short level, ++ int count ++ ) { ++ this.handle = handle; ++ this.names = names; ++ this.level = level; ++ this.count = count; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ handle.encode(_dst); ++ ++ _dst.align(4); ++ ++ _dst.enc_ndr_long(names.length); ++ _dst.enc_ndr_long(names.length); ++ ++ for(int i = 0; i < names.length; ++i) { ++ int wlen = 2 * names[i].length(); ++ ++ _dst.enc_ndr_short(wlen); ++ _dst.enc_ndr_short(wlen); ++ _dst.enc_ndr_long(1); ++ } ++ ++ // Encode names ++ for(int i = 0; i < names.length; ++i) { ++ String name = names[i]; ++ int len = name.length(); ++ ++ _dst.enc_ndr_long(len); ++ _dst.enc_ndr_long(0); ++ _dst.enc_ndr_long(len); ++ ++ System.arraycopy( ++ name.getBytes(csULU), 0, ++ _dst.buf, _dst.index, ++ 2 * len ++ ); ++ _dst.advance(2 * len); ++ ++ _dst.align(4); ++ } ++ ++ _dst.enc_ndr_long(0); // num_trans_entries ++ _dst.enc_ndr_long(0); // ptr_trans_sids ++ ++ _dst.enc_ndr_short(level); // lookup_level ++ _dst.align(4); ++ ++ _dst.enc_ndr_long(count); // mapped_count ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ _src.align(4); ++ ++ int _domainsp = _src.dec_ndr_long(); ++ if(_domainsp != 0) { ++ if(domains == null) /* YOYOYO */ ++ domains = new LsarRefDomainList(); ++ domains.decode(_src); ++ } ++ ++ if(sids == null) ++ sids = new LsarTransSidArray(); ++ sids.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; } +diff -ruNd --strip-trailing-cr jcifs_1.2.20c/src/jcifs/smb/SID.java jcifs_1.2.20c+LsaLookupNames/src/jcifs/smb/SID.java +--- jcifs_1.2.20c/src/jcifs/smb/SID.java 2008-04-25 19:34:39.000000000 +0200 ++++ jcifs_1.2.20c+LsaLookupNames/src/jcifs/smb/SID.java 2008-05-23 16:42:24.000000000 +0200 +@@ -696,5 +696,198 @@ + } + } + } +-} + ++ /** ++ *

This function maps the array of domain object names names to their ++ * equivalent SIDs.

++ * ++ *

Note that the LsaPolicyHandle passed to this function must be created at least ++ * with access 0x00000800 (POLICY_LOOKUP_NAMES), otherwise it will throw an ++ * IOException.

++ * ++ *

On success, the returned SIDs are named according the content of the ++ * names array. Thereby, the case of their acctName fields may ++ * be incorrect since names are mapped ignoring their case. If you want to ++ * obtain the acctName exactly as it is stored in the server, you need ++ * to issue a resolve() call on the SID, or use one of the ++ * various resolveSids() variants. However, the domain part of the names ++ * is always correct, since the server communicates it in its response.

++ * ++ *

Also note that any unresolved name will map to a null value in the related ++ * entry in the returned SIDs array. No exception will be thrown.

++ * ++ * @param handle The DcerpcHandle object to use to communicate with the ++ * LSA service ++ * @param policyHandle The LsaPolicyHandle to use in order to get ++ * authorized by the LSA service. ++ * @param names An array of strings containing the domain's object names to map. ++ * @return An array of SIDs one-to-one related with the given names. ++ * @throws IOException if anything goes wrong ++ * @author Giampaolo Tomassoni <giampaolo at tomassoni dot biz> ++ */ ++ public static SID[] getFromNames( ++ DcerpcHandle handle, ++ LsaPolicyHandle policyHandle, ++ String names[] ++ ) throws IOException { ++ SID outputSids[] = new SID[names.length]; ++ if(names.length > 0) { ++ MsrpcLookupNames rpc = new MsrpcLookupNames(policyHandle, names); ++ 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); ++ } ++ ++ SID domainSids[] = new SID[rpc.domains.count]; ++ for(int i = 0; i < domainSids.length; ++i) { ++ SID domainSid = new SID( ++ rpc.domains.domains[i].sid, ++ SID_TYPE_DOMAIN, ++ (new UnicodeString(rpc.domains.domains[i].name, false)).toString(), ++ null, ++ false ++ ); ++ ++ domainSids[i] = domainSid; ++ } ++ ++ for(int i = 0; i < rpc.sids.count; ++i) { ++ SID sid; ++ switch(rpc.sids.sids[i].sid_type) { ++ case SID_TYPE_DOMAIN: ++ sid = domainSids[rpc.sids.sids[i].sid_index]; ++ break; ++ ++ case SID_TYPE_INVALID: ++ case SID_TYPE_UNKNOWN: ++ // Probably the result of an attempt to resolve an ++ // not existent or bad name ++ sid = null; ++ break; ++ ++ default: ++ SID domainSid = domainSids[rpc.sids.sids[i].sid_index]; ++ sid = new SID(domainSid, rpc.sids.sids[i].rid); ++ sid.type = rpc.sids.sids[i].sid_type; ++ sid.domainName = domainSid.domainName; ++ ++ // If the specified name includes domain data, this must be ++ // removed from acctName. ++ sid.acctName = names[i].substring(names[i].indexOf('\\') + 1); ++ } ++ ++ outputSids[i] = sid; ++ } ++ } ++ ++ return(outputSids); ++ } ++ ++ /** ++ *

This function maps the array of domain object names names to their ++ * equivalent SIDs.

++ * ++ *

On success, the returned SIDs are named according the content of the ++ * names array. Thereby, the case of their acctName fields may ++ * be incorrect since names are mapped ignoring their case. If you want to ++ * obtain the acctName exactly as it is stored in the server, you need ++ * to issue a resolve() call on the SID, or use one of the ++ * various resolveSids() variants. However, the domain part of the names ++ * is always correct, since the server communicates it in its response.

++ * ++ *

Also note that any unresolved name will map to a null value in the related ++ * entry in the returned SIDs array. No exception will be thrown.

++ * ++ * @param authorityServerName The name or address of the authority server to ++ * contact to resolve the names. ++ * @param auth The NtlmPasswordAuthentication to use in order to get ++ * authorized by the server. ++ * @param names An array of strings containing the domain's object names to map. ++ * @return An array of SIDs one-to-one related with the given names. ++ * @throws IOException if anything goes wrong ++ * @author Giampaolo Tomassoni <giampaolo at tomassoni dot biz> ++ */ ++ public static SID[] getFromNames( ++ String authorityServerName, ++ NtlmPasswordAuthentication auth, ++ String names[] ++ ) throws IOException { ++ DcerpcHandle handle = DcerpcHandle.getHandle( ++ "ncacn_np:" + authorityServerName + "[\\PIPE\\lsarpc]", ++ auth ++ ); ++ try { ++ int dot = authorityServerName.indexOf('.'); ++ ++ String serverName; ++ if(dot > 0 && !Character.isDigit(authorityServerName.charAt(0))) ++ serverName = authorityServerName.substring(0, dot); ++ else ++ serverName = authorityServerName; ++ ++ LsaPolicyHandle policyHandle = new LsaPolicyHandle( ++ handle, ++ "\\\\" + serverName, ++ 0x00000800 // POLICY_LOOKUP_NAMES ++ ); ++ try { return(getFromNames(handle, policyHandle, names)); } ++ finally { policyHandle.close(); } ++ } finally { handle.close(); } ++ } ++ ++ /** ++ *

This function is like the getFromNames() one, except that it maps a ++ * single name to its SID equivalent.

++ * ++ *

If you have more than one name to map, getFromNames() is much more ++ * efficient.

++ * ++ * @param handle The DcerpcHandle object to use to communicate with the ++ * LSA service ++ * @param policyHandle The LsaPolicyHandle to use in order to get ++ * authorized by the LSA service. ++ * @param name A string containing the domain's object name to map. ++ * @return The SIDs mapped to the given name. ++ * @throws IOException if anything goes wrong ++ * @author Giampaolo Tomassoni <giampaolo at tomassoni dot biz> ++ */ ++ public static SID getFromName( ++ DcerpcHandle handle, ++ LsaPolicyHandle policyHandle, ++ String name ++ ) throws IOException { ++ SID sids[] = getFromNames(handle, policyHandle, new String[] { name }); ++ return(sids == null || sids.length == 0 ? null : sids[0]); ++ } ++ ++ /** ++ *

This function is like the getFromNames() one, except that it maps a ++ * single name to its SID equivalent.

++ * ++ *

If you have more than one name to map, getFromNames() is much more ++ * efficient.

++ * ++ * @param authorityServerName The name or address of the authority server to ++ * contact to resolve the names. ++ * @param auth The NtlmPasswordAuthentication to use in order to get ++ * authorized by the server. ++ * @param name A string containing the domain's object name to map. ++ * @return The SIDs mapped to the given name. ++ * @throws IOException if anything goes wrong ++ * @author Giampaolo Tomassoni <giampaolo at tomassoni dot biz> ++ */ ++ public static SID getFromName( ++ String authorityServerName, ++ NtlmPasswordAuthentication auth, ++ String name ++ ) throws IOException { ++ SID sids[] = getFromNames(authorityServerName, auth, new String[] { name }); ++ return(sids == null || sids.length == 0 ? null : sids[0]); ++ } ++} diff --git a/patches/midl-upton.patch b/patches/midl-upton.patch new file mode 100644 index 0000000..12dc5ee --- /dev/null +++ b/patches/midl-upton.patch @@ -0,0 +1,106 @@ +diff -wNaur origsrc/emit_dec_java.c src/emit_dec_java.c +--- origsrc/emit_dec_java.c 2008-05-01 11:06:13.000000000 -0700 ++++ src/emit_dec_java.c 2008-05-01 12:13:17.000000000 -0700 +@@ -114,8 +114,8 @@ + if (!is_ref) { + print(idl, indent, "if (_%sp != 0) {\n", name); + if (!IS_PRIMATIVE(sym) && !IS_ARRAY(sym) && !IS_UNION(sym)) { +- print(idl, indent + 4, "if (%s == null) { /* YOYOYO */\n", name); +- print(idl, indent + 8, "%s = new %s();\n", name, sym->out_type); ++ print(idl, indent + 4, "if (%s == null) { /* YOYOYO */\n", sym->name); ++ print(idl, indent + 8, "%s = new %s();\n", sym->name, sym->out_type); + print(idl, indent + 4, "}\n"); + } + } +diff -wNaur origsrc/emit_enc_java.c src/emit_enc_java.c +--- origsrc/emit_enc_java.c 2008-05-01 11:06:13.000000000 -0700 ++++ src/emit_enc_java.c 2008-05-01 12:13:43.000000000 -0700 +@@ -76,7 +76,7 @@ + linkedlist_iterate(siblings, &iter); + while ((mem = linkedlist_next(siblings, &iter))) { + if (strcmp(mem->name, tmp) == 0) { +- if (memcmp(mem->out_type, "Ndr", 3) == 0) { ++ if (mem->out_type != NULL && memcmp(mem->out_type, "Ndr", 3) == 0) { + bp += sprintf(bp, ".value"); + } + break; +@@ -151,7 +151,15 @@ + + buf[0] = '\0'; + if (strcmp(sym->name, sym->orig->name) != 0) { +- sprintf(buf, "%s.", sym->parent->name); ++ sprintf(buf, "%s.", sym->name); ++ int i; ++ // Remove the last component of the name ++ for (i = strlen(buf) - 2; i >= 0; i--) { ++ if (buf[i] == '.') { ++ buf[i+1] = 0; ++ break; ++ } ++ } + } + + if (length_is) { +--- origsrc/parse.c 2008-05-01 11:06:13.000000000 -0700 ++++ src/parse.c 2008-05-01 09:50:45.000000000 -0700 +@@ -39,7 +39,7 @@ + for ( ;; ) { + if (!retok) { + if ((n = tokget(in, tok, tok + TOKMAX)) == -1) { +- AMSG(""); ++ AMSG("Unexpected end of file"); + return -1; + } else if (n == 0) { + break; +@@ -75,8 +75,16 @@ + } + } else if (ch == '(') { + int i; ++ // Count the open we already saw ++ int nestedOpen = 1; + +- for (i = 0; (ch = fgetc(in->in)) != ')' && ch != EOF; i++) { ++ for (i = 0; (ch = fgetc(in->in)) != EOF; i++) { ++ if (ch == '(') { ++ nestedOpen++; ++ } else if (ch == ')') { ++ if (--nestedOpen == 0) ++ break; ++ } + tok[i] = ch; + } + tok[i] = '\0'; +@@ -117,11 +125,11 @@ + s->idl_type = "import"; + s->name = dupstr(tok, idl->al); + s->noemit = 1; +- symaddmem(sym->parent, s); ++ symaddmem(sym, s); + } + + if (idl_process_file(idl, dupstr(buf, idl->al), &iface) == -1) { +- AMSG(""); ++ AMSG("Failed to process import file %s", sym->filename); + return -1; + } + } +@@ -291,7 +299,7 @@ + s->parent = sym; + n = parse(idl, in, s); + if (n == -1) { +- AMSG(""); ++ AMSG("Recursive parse failed"); + return -1; + } else if (n == 0 || n == 3) { + symdel(s); +@@ -305,7 +313,7 @@ + + do { + if ((m = tokget(in, stok, stok + TOKMAX)) < 1) { +- AMSG(""); ++ AMSG("Unexpected end of tokens"); + return m; + } + sch = stok[0]; + + diff --git a/src/jcifs/Config.java b/src/jcifs/Config.java index dd22499..ef4f388 100644 --- a/src/jcifs/Config.java +++ b/src/jcifs/Config.java @@ -45,6 +45,8 @@ import jcifs.util.LogStream; public class Config { +public static int socketCount = 0; + /** * The static Properties. */ @@ -66,6 +68,7 @@ public class Config { in = new FileInputStream( filename ); } Config.load( in ); + in.close(); } catch( IOException ioe ) { if( log.level > 0 ) ioe.printStackTrace( log ); diff --git a/src/jcifs/UniAddress.java b/src/jcifs/UniAddress.java index 2ce79b0..a6f021b 100644 --- a/src/jcifs/UniAddress.java +++ b/src/jcifs/UniAddress.java @@ -25,8 +25,6 @@ import java.util.StringTokenizer; import jcifs.netbios.NbtAddress; import jcifs.netbios.Lmhosts; import jcifs.util.LogStream; -import javax.naming.*; -import javax.naming.directory.*; /** *

Under normal conditions it is not necessary to use @@ -320,6 +318,8 @@ public class UniAddress { /** * Perform DNS SRV lookup on successively shorter suffixes of name * and return successful suffix or throw an UnknownHostException. +import javax.naming.*; +import javax.naming.directory.*; public static String getDomainByName(String name) throws UnknownHostException { DirContext context; UnknownHostException uhe = null; diff --git a/src/jcifs/dcerpc/msrpc/srvsvc.java.bak b/src/jcifs/dcerpc/msrpc/srvsvc.java.bak deleted file mode 100644 index 179e1b6..0000000 --- a/src/jcifs/dcerpc/msrpc/srvsvc.java.bak +++ /dev/null @@ -1,380 +0,0 @@ -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(); - } - } -} diff --git a/src/jcifs/netbios/NameServiceClient.java b/src/jcifs/netbios/NameServiceClient.java index 93cf76c..bc3bdf2 100644 --- a/src/jcifs/netbios/NameServiceClient.java +++ b/src/jcifs/netbios/NameServiceClient.java @@ -145,6 +145,8 @@ class NameServiceClient implements Runnable { // be ignored; see tryClose comment. if( socket == null ) { socket = new DatagramSocket( lport, laddr ); +jcifs.Config.socketCount++; +log.println(jcifs.Config.socketCount + ": new Socket: " + socket); thread = new Thread( this, "JCIFS-NameServiceClient" ); thread.setDaemon( true ); thread.start(); @@ -162,7 +164,10 @@ class NameServiceClient implements Runnable { */ if( socket != null ) { +String s = socket.toString(); socket.close(); +jcifs.Config.socketCount--; +log.println(jcifs.Config.socketCount + ": socket closed: " + s); socket = null; } thread = null; diff --git a/src/jcifs/smb/ACE.java b/src/jcifs/smb/ACE.java index 3b305c4..a601d54 100644 --- a/src/jcifs/smb/ACE.java +++ b/src/jcifs/smb/ACE.java @@ -1,6 +1,7 @@ package jcifs.smb; import jcifs.util.Hexdump; +import java.io.IOException; /** * An Access Control Entry (ACE) is an element in a security descriptor diff --git a/src/jcifs/smb/Dfs.java b/src/jcifs/smb/Dfs.java index b486181..825dc94 100644 --- a/src/jcifs/smb/Dfs.java +++ b/src/jcifs/smb/Dfs.java @@ -55,7 +55,7 @@ public class Dfs { if (_domains != null) return _domains.map; try { - UniAddress addr = UniAddress.getByName(auth.domain); + UniAddress addr = UniAddress.getByName(auth.domain, true); SmbTransport trans = SmbTransport.getSmbTransport(addr, 0); DfsReferral[] dr = trans.getDfsReferrals(auth, "", 0); CacheEntry entry = new CacheEntry(Dfs.TTL * 10L); @@ -86,7 +86,7 @@ public class Dfs { public SmbTransport getDc(String domain, NtlmPasswordAuthentication auth) throws SmbAuthException { try { - UniAddress addr = UniAddress.getByName(domain); + UniAddress addr = UniAddress.getByName(domain, true); SmbTransport trans = SmbTransport.getSmbTransport(addr, 0); DfsReferral[] dr = trans.getDfsReferrals(auth, "\\" + domain, 1); if (dr.length == 1) { @@ -123,7 +123,7 @@ public class Dfs { } return null; } - public DfsReferral resolve(String domain, + public synchronized DfsReferral resolve(String domain, String root, String path, NtlmPasswordAuthentication auth) throws SmbAuthException { @@ -213,7 +213,7 @@ public class Dfs { return dr; } - void insert(String path, DfsReferral dr) { + synchronized void insert(String path, DfsReferral dr) { int s1, s2; String server, share, key; diff --git a/src/jcifs/smb/SID.java b/src/jcifs/smb/SID.java index 8be869c..cbb8020 100644 --- a/src/jcifs/smb/SID.java +++ b/src/jcifs/smb/SID.java @@ -145,6 +145,33 @@ public class SID extends rpc.sid_t { } } + static public void resolveSids(String authorityServerName, + NtlmPasswordAuthentication auth, + SID[] sids, + int offset, + int length) throws IOException { + ArrayList list = new ArrayList(sids.length); + int si; + + for (si = 0; si < length; si++) { + SID sid = (SID)sid_cache.get(sids[offset + si]); + if (sid != null) { + sids[offset + si].type = sid.type; + sids[offset + si].domainName = sid.domainName; + sids[offset + si].acctName = sid.acctName; + } else { + list.add(sids[offset + 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]); + } + } + } /** * Resolve an array of SIDs using a cache and at most one MSRPC request. *

@@ -232,7 +259,7 @@ public class SID extends rpc.sid_t { System.arraycopy(src, si, identifier_authority, 0, 6); si += 6; if (sub_authority_count > 100) - throw new RuntimeException( "Invalid SID" ); + throw new RuntimeException( "Invalid SID sub_authority_count" ); sub_authority = new int[sub_authority_count]; for (int i = 0; i < sub_authority_count; i++) { sub_authority[i] = ServerMessageBlock.readInt4( src, si ); diff --git a/src/jcifs/smb/SecurityDescriptor.java b/src/jcifs/smb/SecurityDescriptor.java index 4b35b63..f40b86e 100644 --- a/src/jcifs/smb/SecurityDescriptor.java +++ b/src/jcifs/smb/SecurityDescriptor.java @@ -18,6 +18,8 @@ package jcifs.smb; +import java.io.IOException; + public class SecurityDescriptor { public int type; diff --git a/src/jcifs/smb/SmbFile.java b/src/jcifs/smb/SmbFile.java index f027fed..20ff7a9 100644 --- a/src/jcifs/smb/SmbFile.java +++ b/src/jcifs/smb/SmbFile.java @@ -1964,7 +1964,12 @@ if (this instanceof SmbNamedPipe) { send( req, resp ); } - send( new SmbComFindClose2( sid ), blank_resp() ); + try { + send( new SmbComFindClose2( sid ), blank_resp() ); + } catch (SmbException se) { + if( log.level >= 4 ) + se.printStackTrace( log ); + } } /** @@ -2786,7 +2791,12 @@ if (this instanceof SmbNamedPipe) { sids[ai] = aces[ai].sid; } - SID.resolveSids(server, auth, sids); + for (int off = 0; off < sids.length; off += 10) { + int len = sids.length - off; + if (len > 64) + len = 64; + SID.resolveSids(server, auth, sids, off, len); + } } else { for (ai = 0; ai < aces.length; ai++) { aces[ai].sid.origin_server = server; diff --git a/src/jcifs/smb/SmbTransport.java b/src/jcifs/smb/SmbTransport.java index e394950..270ef07 100644 --- a/src/jcifs/smb/SmbTransport.java +++ b/src/jcifs/smb/SmbTransport.java @@ -182,6 +182,8 @@ public class SmbTransport extends Transport implements SmbConstants { } else { socket = new Socket( address.getHostAddress(), 139, localAddr, localPort ); } +jcifs.Config.socketCount++; +log.println(jcifs.Config.socketCount + ": new Socket: " + socket); socket.setSoTimeout( SO_TIMEOUT ); out = socket.getOutputStream(); in = socket.getInputStream(); @@ -190,7 +192,15 @@ public class SmbTransport extends Transport implements SmbConstants { NbtAddress.getLocalName() ); out.write( sbuf, 0, ssp.writeWireFormat( sbuf, 0 )); if (readn( in, sbuf, 0, 4 ) < 4) { - try { socket.close(); } catch(IOException ioe) {}; + try { +String s = socket.toString(); + socket.close(); +jcifs.Config.socketCount--; +log.println(jcifs.Config.socketCount + ": socket closed: " + s); + } catch(IOException ioe) { +log.println(jcifs.Config.socketCount + ": socket close exception:"); +ioe.printStackTrace(log); + } throw new SmbException( "EOF during NetBIOS session request" ); } switch( sbuf[0] & 0xFF ) { @@ -203,7 +213,10 @@ public class SmbTransport extends Transport implements SmbConstants { switch (errorCode) { case NbtException.CALLED_NOT_PRESENT: case NbtException.NOT_LISTENING_CALLED: +String s = socket.toString(); socket.close(); +jcifs.Config.socketCount--; +log.println(jcifs.Config.socketCount + ": socket closed: " + s); break; default: disconnect( true ); @@ -246,6 +259,8 @@ public class SmbTransport extends Transport implements SmbConstants { } else { socket = new Socket( address.getHostAddress(), port, localAddr, localPort ); } +jcifs.Config.socketCount++; +log.println(jcifs.Config.socketCount + ": new Socket: " + socket); socket.setSoTimeout( SO_TIMEOUT ); out = socket.getOutputStream(); in = socket.getInputStream(); @@ -346,7 +361,10 @@ public class SmbTransport extends Transport implements SmbConstants { socket.shutdownOutput(); out.close(); in.close(); +String s = socket.toString(); socket.close(); +jcifs.Config.socketCount--; +log.println(jcifs.Config.socketCount + ": socket closed: " + s); digest = null; } @@ -449,7 +467,9 @@ public class SmbTransport extends Transport implements SmbConstants { throw new IOException( "Invalid payload size: " + size ); } int errorCode = Encdec.dec_uint32le( BUF, 9 ) & 0xFFFFFFFF; - if (resp.command == ServerMessageBlock.SMB_COM_READ_ANDX && errorCode == 0) { + if (resp.command == ServerMessageBlock.SMB_COM_READ_ANDX && + (errorCode == 0 || + errorCode == 0x80000005)) { // overflow indicator normal for pipe SmbComReadAndXResponse r = (SmbComReadAndXResponse)resp; int off = HEADER_LENGTH; /* WordCount thru dataOffset always 27 */ -- 2.11.0