From 4ecaaf937bf9b3489f98f6eeb456cc466d29dff8 Mon Sep 17 00:00:00 2001 From: Felix Schumacher Date: Wed, 6 Aug 2008 16:42:34 +0200 Subject: [PATCH] jcifs-1.2.14 from tgz Wed Jun 20 13:09:10 EDT 2007 jcifs-1.2.14 released A new SID.getGroupMemberSids() method has been added that will return the local group membership of SID (aka aliases). This release adds the SAMR interface to the dcerpc code with the SamrEnumerateAliasesInDomain RPC and numerous other calls to negotiate the necessary policy handles. --- README.txt | 10 +- build.xml | 4 +- examples/GetGroupMemberSids.java | 25 + examples/GetLocalGroupsMap.java | 30 + examples/LargeListFiles.java | 39 + patches/Eventlog.patch | 834 +++++++++++++++++++++ patches/GetOwnerSid.patch | 91 +++ patches/README.txt | 14 + patches/backup-domain-controllers-1.2.13.patch | 69 ++ src/jcifs/dcerpc/DcerpcBinding.java | 1 + src/jcifs/dcerpc/DcerpcHandle.java | 12 + .../msrpc/MsrpcEnumerateAliasesInDomain.java | 34 + src/jcifs/dcerpc/msrpc/MsrpcGetMembersInAlias.java | 32 + .../dcerpc/msrpc/MsrpcQueryInformationPolicy2.java | 34 + src/jcifs/dcerpc/msrpc/MsrpcSamrConnect4.java | 28 + src/jcifs/dcerpc/msrpc/MsrpcSamrOpenAlias.java | 33 + src/jcifs/dcerpc/msrpc/MsrpcSamrOpenDomain.java | 33 + src/jcifs/dcerpc/msrpc/SamrAliasHandle.java | 42 ++ src/jcifs/dcerpc/msrpc/SamrDomainHandle.java | 42 ++ src/jcifs/dcerpc/msrpc/SamrPolicyHandle.java | 37 + src/jcifs/dcerpc/msrpc/samr.idl | 51 ++ src/jcifs/dcerpc/msrpc/samr.java | 293 ++++++++ src/jcifs/smb/NtStatus.java | 6 + src/jcifs/smb/SID.java | 245 +++++- src/jcifs/smb/SmbException.java | 2 +- src/jcifs/smb/SmbFile.java | 4 +- 26 files changed, 2033 insertions(+), 12 deletions(-) create mode 100644 examples/GetGroupMemberSids.java create mode 100644 examples/GetLocalGroupsMap.java create mode 100644 examples/LargeListFiles.java create mode 100644 patches/Eventlog.patch create mode 100644 patches/GetOwnerSid.patch create mode 100644 patches/backup-domain-controllers-1.2.13.patch create mode 100644 src/jcifs/dcerpc/msrpc/MsrpcEnumerateAliasesInDomain.java create mode 100644 src/jcifs/dcerpc/msrpc/MsrpcGetMembersInAlias.java create mode 100644 src/jcifs/dcerpc/msrpc/MsrpcQueryInformationPolicy2.java create mode 100644 src/jcifs/dcerpc/msrpc/MsrpcSamrConnect4.java create mode 100644 src/jcifs/dcerpc/msrpc/MsrpcSamrOpenAlias.java create mode 100644 src/jcifs/dcerpc/msrpc/MsrpcSamrOpenDomain.java create mode 100644 src/jcifs/dcerpc/msrpc/SamrAliasHandle.java create mode 100644 src/jcifs/dcerpc/msrpc/SamrDomainHandle.java create mode 100644 src/jcifs/dcerpc/msrpc/SamrPolicyHandle.java create mode 100644 src/jcifs/dcerpc/msrpc/samr.idl create mode 100644 src/jcifs/dcerpc/msrpc/samr.java diff --git a/README.txt b/README.txt index 0f9fb33..d1e88e7 100644 --- a/README.txt +++ b/README.txt @@ -1,5 +1,13 @@ +Wed Jun 20 13:09:10 EDT 2007 +jcifs-1.2.14 released + +A new SID.getGroupMemberSids() method has been added that will return +the local group membership of SID (aka aliases). This release adds the +SAMR interface to the dcerpc code with the SamrEnumerateAliasesInDomain +RPC and numerous other calls to negotiate the necessary policy handles. + Mon Jan 22 15:26:01 EST 2007 -jcifs-1.2.13 released. +jcifs-1.2.13 released A new SmbFile.getShareSecurity() method that uses a new MsrpcShareGetInfo/ShareInfo502 RPC has been added. This will return the diff --git a/build.xml b/build.xml index 7a65afe..f047973 100644 --- a/build.xml +++ b/build.xml @@ -1,7 +1,7 @@ - - + + diff --git a/examples/GetGroupMemberSids.java b/examples/GetGroupMemberSids.java new file mode 100644 index 0000000..fe416f1 --- /dev/null +++ b/examples/GetGroupMemberSids.java @@ -0,0 +1,25 @@ +import java.util.*; +import jcifs.smb.*; + +public class GetGroupMemberSids { + + public static void main( String[] argv ) throws Exception { + if (argv.length < 2) { + System.err.println("usage: GetGroupMemberSids "); + System.exit(1); + } + + SmbFile file = new SmbFile(argv[0]); + SID sid = new SID(argv[1]); + + String server = file.getServer(); + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)file.getPrincipal(); + + SID[] mems = sid.getGroupMemberSids(server, auth, SID.SID_FLAG_RESOLVE_SIDS); + + for (int mi = 0; mi < mems.length; mi++) { + SID mem = mems[mi]; + System.out.println(mem.getType() + " " + mem.toDisplayString()); + } + } +} diff --git a/examples/GetLocalGroupsMap.java b/examples/GetLocalGroupsMap.java new file mode 100644 index 0000000..355bd7e --- /dev/null +++ b/examples/GetLocalGroupsMap.java @@ -0,0 +1,30 @@ +import java.util.*; +import jcifs.smb.*; + +public class GetLocalGroupsMap { + + public static void main( String[] argv ) throws Exception { + + SmbFile file = new SmbFile(argv[0]); + String server = file.getServer(); + NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)file.getPrincipal(); + Map map = SID.getLocalGroupsMap(server, + auth, + SID.SID_FLAG_RESOLVE_SIDS); + + + Iterator kiter = map.keySet().iterator(); + while (kiter.hasNext()) { + SID userSid = (SID)kiter.next(); + + System.out.println(userSid.getType() + " " + userSid.toDisplayString() + ":"); + + ArrayList groupSids = (ArrayList)map.get(userSid); + Iterator giter = groupSids.iterator(); + while (giter.hasNext()) { + SID group = (SID)giter.next(); + System.out.println(" " + group.getType() + " " + group.toDisplayString()); + } + } + } +} diff --git a/examples/LargeListFiles.java b/examples/LargeListFiles.java new file mode 100644 index 0000000..bd79cb2 --- /dev/null +++ b/examples/LargeListFiles.java @@ -0,0 +1,39 @@ +import jcifs.netbios.NbtAddress; +import jcifs.smb.*; +import java.util.Date; + +public class LargeListFiles extends DosFileFilter { + + int count = 0; + + public LargeListFiles() { + super("*", 0xFFFF); + } + public LargeListFiles(String wildcard, int attributes) { + super(wildcard, attributes); + } + + public boolean accept(SmbFile file) throws SmbException { + System.out.print( " " + file.getName() ); + count++; + return false; /* file processed here, tell listFiles() to discard */ + } + + public static void main( String[] argv ) throws Exception { + if (argv.length < 1) { + System.err.println("usage: LargeListFiles \n"); + System.exit(1); + } + + SmbFile file = new SmbFile( argv[0] ); + LargeListFiles llf = new LargeListFiles(); + + long t1 = System.currentTimeMillis(); + file.listFiles(llf); + long t2 = System.currentTimeMillis() - t1; + + System.out.println(); + System.out.println( llf.count + " files in " + t2 + "ms" ); + } +} + diff --git a/patches/Eventlog.patch b/patches/Eventlog.patch new file mode 100644 index 0000000..6a16417 --- /dev/null +++ b/patches/Eventlog.patch @@ -0,0 +1,834 @@ +diff -Naur old-src/jcifs/dcerpc/DcerpcBinding.java src/jcifs/dcerpc/DcerpcBinding.java +--- old-src/jcifs/dcerpc/DcerpcBinding.java 2007-01-22 17:21:18.000000000 -0800 ++++ src/jcifs/dcerpc/DcerpcBinding.java 2007-03-20 10:33:47.000000000 -0700 +@@ -32,6 +32,7 @@ + INTERFACES = new HashMap(); + INTERFACES.put("srvsvc", srvsvc.getSyntax()); + INTERFACES.put("lsarpc", lsarpc.getSyntax()); ++ INTERFACES.put("eventlog", eventlog.getSyntax()); + } + + String proto; +diff -Naur old-src/jcifs/dcerpc/msrpc/eventlog.idl src/jcifs/dcerpc/msrpc/eventlog.idl +--- old-src/jcifs/dcerpc/msrpc/eventlog.idl 1969-12-31 16:00:00.000000000 -0800 ++++ src/jcifs/dcerpc/msrpc/eventlog.idl 2007-03-20 10:33:47.000000000 -0700 +@@ -0,0 +1,148 @@ ++[ ++ uuid("82273fdc-e32a-18c3-3f78-827929dc23ea"), ++ version(0.0), ++] ++interface eventlog ++{ ++ typedef bitmap { ++ EVENTLOG_SEQUENTIAL_READ = 0x0001, ++ EVENTLOG_SEEK_READ = 0x0002, ++ EVENTLOG_FORWARDS_READ = 0x0004, ++ EVENTLOG_BACKWARDS_READ = 0x0008 ++ } EventlogReadFlags; ++ ++ typedef bitmap { ++ EVENTLOG_SUCCESS = 0x0000, ++ EVENTLOG_ERROR_TYPE = 0x0001, ++ EVENTLOG_WARNING_TYPE = 0x0002, ++ EVENTLOG_INFORMATION_TYPE = 0x0004, ++ EVENTLOG_AUDIT_SUCCESS = 0x0008, ++ EVENTLOG_AUDIT_FAILURE = 0x0010 ++ } EventlogEventTypes; ++ ++ typedef struct { ++ uint16 unknown0; ++ uint16 unknown1; ++ } EventlogOpenUnknown0; ++ ++ typedef [public] struct { ++ uint32 size; ++ uint32 reserved; ++ uint32 record_number; ++ uint32 time_generated; ++ uint32 time_written; ++ uint32 event_id; ++ uint16 event_type; ++ uint16 num_of_strings; ++ uint16 event_category; ++ uint16 reserved_flags; ++ uint32 closing_record_number; ++ uint32 stringoffset; ++ uint32 sid_length; ++ uint32 sid_offset; ++ uint32 data_length; ++ uint32 data_offset; ++ nstring source_name; ++ nstring computer_name; ++ nstring strings[num_of_strings]; ++ astring raw_data; ++ } EventlogRecord; ++ ++ [op(0x00)] ++ NTSTATUS eventlog_ClearEventLogW( ++ [in] policy_handle *handle, ++ [in,unique] lsa_String *unknown ++ ); ++ ++ [op(0x01)] ++ NTSTATUS eventlog_BackupEventLogW(); ++ ++ [op(0x02)] ++ NTSTATUS eventlog_CloseEventLog( ++ [in,out] policy_handle *handle ++ ); ++ ++ [op(0x03)] ++ NTSTATUS eventlog_DeregisterEventSource(); ++ ++ [op(0x04)] ++ NTSTATUS eventlog_GetNumRecords( ++ [in] policy_handle *handle, ++ [out] uint32 *number ++ ); ++ ++ [op(0x05)] ++ NTSTATUS eventlog_GetOldestRecord(); ++ ++ [op(0x06)] ++ NTSTATUS eventlog_ChangeNotify(); ++ ++ [op(0x07)] ++ NTSTATUS eventlog_OpenEventLogW( ++ [in,unique] eventlog_OpenUnknown0 *unknown0, ++ [in] lsa_String logname, ++ [in] lsa_String servername, ++ [in] uint32 unknown2, ++ [in] uint32 unknown3, ++ [out] policy_handle *handle ++ ); ++ ++ [op(0x08)] ++ NTSTATUS eventlog_RegisterEventSourceW(); ++ ++ [op(0x09)] ++ NTSTATUS eventlog_OpenBackupEventLogW(); ++ ++ [op(0x0a)] ++ NTSTATUS eventlog_ReadEventLogW( ++ [in] policy_handle *handle, ++ [in] uint32 flags, ++ [in] uint32 offset, ++ [in] uint32 number_of_bytes, ++ [out,size_is(number_of_bytes)] uint8 *data, ++ [out] uint32 *sent_size, ++ [out] uint32 *real_size ++ ); ++ ++ [op(0x0b)] ++ NTSTATUS eventlog_ReportEventW(); ++ ++ [op(0x0c)] ++ NTSTATUS eventlog_ClearEventLogA(); ++ ++ [op(0x0d)] ++ NTSTATUS eventlog_BackupEventLogA(); ++ ++ [op(0x0e)] ++ NTSTATUS eventlog_OpenEventLogA(); ++ ++ [op(0x0f)] ++ NTSTATUS eventlog_RegisterEventSourceA(); ++ ++ [op(0x10)] ++ NTSTATUS eventlog_OpenBackupEventLogA(); ++ ++ [op(0x11)] ++ NTSTATUS eventlog_ReadEventLogA(); ++ ++ [op(0x12)] ++ NTSTATUS eventlog_ReportEventA(); ++ ++ [op(0x13)] ++ NTSTATUS eventlog_RegisterClusterSvc(); ++ ++ [op(0x14)] ++ NTSTATUS eventlog_DeregisterClusterSvc(); ++ ++ [op(0x15)] ++ NTSTATUS eventlog_WriteClusterEvents(); ++ ++ [op(0x16)] ++ NTSTATUS eventlog_GetLogIntormation(); ++ ++ [op(0x17)] ++ NTSTATUS eventlog_FlushEventLog( ++ [in] policy_handle *handle ++ ); ++} ++ +diff -Naur old-src/jcifs/dcerpc/msrpc/eventlog.java src/jcifs/dcerpc/msrpc/eventlog.java +--- old-src/jcifs/dcerpc/msrpc/eventlog.java 1969-12-31 16:00:00.000000000 -0800 ++++ src/jcifs/dcerpc/msrpc/eventlog.java 2007-03-20 10:33:47.000000000 -0700 +@@ -0,0 +1,464 @@ ++package jcifs.dcerpc.msrpc; ++ ++import java.util.ArrayList; ++import java.util.Date; ++import java.util.List; ++ ++import jcifs.dcerpc.DcerpcMessage; ++import jcifs.dcerpc.rpc; ++import jcifs.dcerpc.ndr.NdrBuffer; ++import jcifs.dcerpc.ndr.NdrException; ++import jcifs.dcerpc.ndr.NdrObject; ++ ++public class eventlog { ++ ++ public static String getSyntax() { ++ return "82273fdc-e32a-18c3-3f78-827929dc23ea:0.0"; ++ } ++ ++ public static final int EVENTLOG_SEQUENTIAL_READ = 0x0001; ++ ++ public static final int EVENTLOG_SEEK_READ = 0x0002; ++ ++ public static final int EVENTLOG_FORWARDS_READ = 0x0004; ++ ++ public static final int EVENTLOG_BACKWARDS_READ = 0x0008; ++ ++ public static final int EVENTLOG_SUCCESS = 0x0000; ++ ++ public static final int EVENTLOG_ERROR_TYPE = 0x0001; ++ ++ public static final int EVENTLOG_WARNING_TYPE = 0x0002; ++ ++ public static final int EVENTLOG_INFORMATION_TYPE = 0x0004; ++ ++ public static final int EVENTLOG_AUDIT_SUCCESS = 0x0008; ++ ++ public static final int EVENTLOG_AUDIT_FAILURE = 0x0010; ++ ++ public static class EventlogOpenUnknown0 extends NdrObject { ++ ++ public short unknown0; ++ ++ public short unknown1; ++ ++ public void encode(NdrBuffer _dst) throws NdrException { ++ _dst.align(4); ++ _dst.enc_ndr_short(unknown0); ++ _dst.enc_ndr_short(unknown1); ++ } ++ ++ public void decode(NdrBuffer _src) throws NdrException { ++ _src.align(4); ++ unknown0 = (short) _src.dec_ndr_short(); ++ unknown1 = (short) _src.dec_ndr_short(); ++ } ++ } ++ ++ public static class sid_t extends NdrObject { ++ ++ public byte revision; ++ ++ public byte[] identifier_authority; ++ ++ public int[] sub_authority; ++ ++ public void encode(NdrBuffer _dst) throws NdrException { ++ _dst.enc_ndr_small(revision); ++ _dst.enc_ndr_small(sub_authority.length); ++ for (int i = 0; i < 6; i++) { ++ _dst.enc_ndr_small(identifier_authority[i]); ++ } ++ for (int i = 0; i < sub_authority.length; i++) { ++ _dst.enc_ndr_long_noalign(sub_authority[i]); ++ } ++ } ++ ++ public void decode(NdrBuffer _src) throws NdrException { ++ revision = (byte) _src.dec_ndr_small(); ++ int sub_authority_count = (byte) _src.dec_ndr_small(); ++ ++ identifier_authority = new byte[6]; ++ for (int i = 0; i < 6; i++) { ++ identifier_authority[i] = (byte) _src.dec_ndr_small(); ++ } ++ sub_authority = new int[sub_authority_count]; ++ for (int i = 0; i < sub_authority_count; i++) { ++ sub_authority[i] = (int) _src.dec_ndr_long_noalign(); ++ } ++ } ++ ++ public String toString() { ++ StringBuffer sb = new StringBuffer(); ++ long ia; ++ ia = (identifier_authority[5]) + (identifier_authority[4] << 8) ++ + (identifier_authority[3] << 16) ++ + (identifier_authority[2] << 24); ++ sb.append("S-").append(revision).append("-").append(ia); ++ for (int i = 0; i < sub_authority.length; i++) { ++ sb.append("-").append(sub_authority[i]); ++ } ++ return sb.toString(); ++ } ++ } ++ ++ public static class EventlogRecord extends NdrObject { ++ public int size; ++ ++ public int reserved; ++ ++ public int record_number; ++ ++ public Date time_generated; ++ ++ public Date time_written; ++ ++ public int event_id; ++ ++ public short event_type; ++ ++ public short event_category; ++ ++ public short reserved_flags; ++ ++ public int closing_record_number; ++ ++ public eventlog.sid_t sid; ++ ++ public String source_name; ++ ++ public String computer_name; ++ ++ public String[] strings; ++ ++ public byte[] raw_data; ++ ++ public void encode(NdrBuffer _dst) throws NdrException { ++ int size = 0, size_offset = 0, size_offset2 = 0; ++ int stringoffset = 0, stringoffset_offset = 0; ++ int sid_length = 0, sid_length_offset = 0; ++ int sid_offset = 0, sid_offset_offset = 0; ++ int data_offset = 0, data_offset_offset = 0; ++ size_offset = _dst.getIndex(); ++ _dst.enc_ndr_long(size); ++ _dst.enc_ndr_long(reserved); ++ _dst.enc_ndr_long(record_number); ++ _dst.enc_ndr_long(time_generated == null ? 0 ++ : (int) (time_generated.getTime() / 1000)); ++ _dst.enc_ndr_long(time_written == null ? 0 : (int) (time_written ++ .getTime() / 1000)); ++ _dst.enc_ndr_long(event_id); ++ _dst.enc_ndr_short(event_type); ++ _dst.enc_ndr_short(strings == null ? 0 : strings.length); ++ _dst.enc_ndr_short(event_category); ++ _dst.enc_ndr_short(reserved_flags); ++ _dst.enc_ndr_long(closing_record_number); ++ stringoffset_offset = _dst.getIndex(); ++ _dst.enc_ndr_long(stringoffset); ++ sid_length_offset = _dst.getIndex(); ++ _dst.enc_ndr_long(sid_length); ++ sid_offset_offset = _dst.getIndex(); ++ _dst.enc_ndr_long(sid_offset); ++ _dst.enc_ndr_long(raw_data == null ? 0 : raw_data.length); ++ data_offset_offset = _dst.getIndex(); ++ _dst.enc_ndr_long(data_offset); ++ _dst.enc_ndr_string(source_name); ++ _dst.enc_ndr_string(computer_name); ++ sid_offset = _dst.getIndex(); ++ if (sid != null) { ++ sid.encode(_dst); ++ sid_length = _dst.getIndex() - sid_offset; ++ } ++ stringoffset = _dst.getIndex(); ++ if (strings != null && strings.length > 0) { ++ for (int i = 0; i < strings.length; i++) { ++ _dst.enc_ndr_string(strings[i]); ++ } ++ } ++ data_offset = _dst.getIndex(); ++ if (raw_data != null && raw_data.length > 0) { ++ _dst.writeOctetArray(raw_data, 0, raw_data.length); ++ } ++ size_offset2 = _dst.getIndex(); ++ _dst.enc_ndr_long(size); ++ size = _dst.getIndex() - size_offset; ++ // Write information back. ++ _dst.setIndex(size_offset); ++ _dst.enc_ndr_long(size); ++ _dst.setIndex(stringoffset_offset); ++ _dst.enc_ndr_long(stringoffset); ++ _dst.setIndex(sid_length_offset); ++ _dst.enc_ndr_long(sid_length); ++ _dst.setIndex(sid_offset_offset); ++ _dst.enc_ndr_long(sid_offset); ++ _dst.setIndex(data_offset_offset); ++ _dst.enc_ndr_long(data_offset); ++ _dst.setIndex(size_offset2); ++ _dst.enc_ndr_long(size); ++ } ++ ++ public void decode(NdrBuffer _src) throws NdrException { ++ int cur_offset = _src.getIndex(); ++ size = _src.dec_ndr_long(); ++ reserved = _src.dec_ndr_long(); ++ record_number = _src.dec_ndr_long(); ++ long tmp = 0; ++ tmp = _src.dec_ndr_long(); ++ time_generated = new Date(tmp * 1000); ++ tmp = _src.dec_ndr_long(); ++ time_written = new Date(tmp * 1000); ++ event_id = _src.dec_ndr_long(); ++ event_type = (short) _src.dec_ndr_short(); ++ int num_of_strings = _src.dec_ndr_short(); ++ event_category = (short) _src.dec_ndr_short(); ++ reserved_flags = (short) _src.dec_ndr_short(); ++ closing_record_number = _src.dec_ndr_long(); ++ int stringoffset = _src.dec_ndr_long(); ++ int sid_length = _src.dec_ndr_long(); ++ int sid_offset = _src.dec_ndr_long(); ++ int data_length = _src.dec_ndr_long(); ++ int data_offset = _src.dec_ndr_long(); ++ source_name = _src.dec_ndr_unistring(); ++ computer_name = _src.dec_ndr_unistring(); ++ if (sid_length > 0) { ++ _src.setIndex(cur_offset + sid_offset); ++ if (sid == null) { ++ sid = new eventlog.sid_t(); ++ } ++ sid.decode(_src); ++ } else { ++ sid = null; ++ } ++ if (num_of_strings > 0) { ++ _src.setIndex(cur_offset + stringoffset); ++ strings = new String[num_of_strings]; ++ for (int i = 0; i < strings.length; i++) { ++ strings[i] = _src.dec_ndr_unistring(); ++ } ++ } else { ++ strings = new String[0]; ++ } ++ if (data_length > 0) { ++ _src.setIndex(cur_offset + data_offset); ++ raw_data = new byte[data_length]; ++ _src.readOctetArray(raw_data, 0, data_length); ++ } else { ++ raw_data = new byte[0]; ++ } ++ _src.setIndex(cur_offset + size); ++ } ++ } ++ ++ public static class EventlogClearEventLog extends DcerpcMessage { ++ ++ public int getOpnum() { ++ return 0x00; ++ } ++ ++ public int retval; ++ ++ public rpc.policy_handle handle; ++ ++ public rpc.unicode_string backupFile; ++ ++ public EventlogClearEventLog(rpc.policy_handle handle, ++ rpc.unicode_string backupfile) { ++ this.handle = handle; ++ this.backupFile = backupfile; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ handle.encode(_dst); ++ backupFile.encode(_dst); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ retval = (int) _src.dec_ndr_long(); ++ } ++ } ++ ++ public static class EventLogCloseEventLog extends DcerpcMessage { ++ public int getOpnum() { ++ return 0x02; ++ } ++ ++ public int retval; ++ ++ public rpc.policy_handle handle; ++ ++ public EventLogCloseEventLog(rpc.policy_handle handle) { ++ this.handle = handle; ++ ptype = 0; ++ retval = -1; ++ } ++ ++ 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 EventLogGetNumRecords extends DcerpcMessage { ++ public int getOpnum() { ++ return 0x04; ++ } ++ ++ public int numberOfRecords; ++ ++ public int retval; ++ ++ public rpc.policy_handle handle; ++ ++ public EventLogGetNumRecords(rpc.policy_handle handle) { ++ this.handle = handle; ++ ptype = 0; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ handle.encode(_dst); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ numberOfRecords = (int) _src.dec_ndr_long(); ++ retval = (int) _src.dec_ndr_long(); ++ } ++ } ++ ++ public static class EventLogGetOldestEntry extends DcerpcMessage { ++ public int getOpnum() { ++ return 0x05; ++ } ++ ++ public int oldestEntryNumber; ++ ++ public int retval; ++ ++ public rpc.policy_handle handle; ++ ++ public EventLogGetOldestEntry(rpc.policy_handle handle) { ++ this.handle = handle; ++ ptype = 0; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ handle.encode(_dst); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ oldestEntryNumber = (int) _src.dec_ndr_long(); ++ retval = (int) _src.dec_ndr_long(); ++ } ++ } ++ ++ public static class EventLogOpenEventLog extends DcerpcMessage { ++ public int getOpnum() { ++ return 0x07; ++ } ++ ++ public rpc.unicode_string logname; ++ ++ public rpc.unicode_string servername; ++ ++ public int retval; ++ ++ public rpc.policy_handle handle; ++ ++ public EventLogOpenEventLog(rpc.unicode_string logname, ++ rpc.unicode_string servername) { ++ this.logname = logname; ++ this.servername = servername; ++ ptype = 0; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ _dst.align(8); ++ _dst.enc_ndr_long(0xf000baaa); ++ _dst.enc_ndr_short(0x64); ++ _dst.enc_ndr_short(0x01); ++ logname.encode(_dst); ++ servername.encode(_dst); ++ // _dst.align(4); ++ _dst.enc_ndr_long(0x01); ++ _dst.enc_ndr_long(0x01); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ if (handle == null) { ++ handle = new rpc.policy_handle(); ++ } ++ handle.decode(_src); ++ retval = (int) _src.dec_ndr_long(); ++ } ++ } ++ ++ public static class EventLogReadEventLog extends DcerpcMessage { ++ public int getOpnum() { ++ return 0x0a; ++ } ++ ++ public int retval; ++ ++ public int flags; ++ ++ public int offset; ++ ++ public int maxReadSize; ++ ++ public int bytesInNextRecords; ++ ++ public List entries; ++ ++ public int sent_size; ++ ++ public int real_size; ++ ++ public rpc.policy_handle handle; ++ ++ public EventLogReadEventLog(rpc.policy_handle handle, int flags, ++ int offset, int maxReadSize) { ++ this.handle = handle; ++ this.flags = flags; ++ this.offset = offset; ++ this.maxReadSize = maxReadSize; ++ ptype = 0; ++ retval = -1; ++ } ++ ++ public void encode_in(NdrBuffer _dst) throws NdrException { ++ _dst.align(8); ++ handle.encode(_dst); ++ _dst.enc_ndr_long(flags); ++ _dst.enc_ndr_long(offset); ++ _dst.enc_ndr_long(maxReadSize); ++ } ++ ++ public void decode_out(NdrBuffer _src) throws NdrException { ++ int bytesInResponse = 0, curOffset = 0, bytesTotal = 0; ++ bytesInResponse = _src.dec_ndr_long(); ++ curOffset = _src.getIndex(); ++ _src.setIndex(curOffset + bytesInResponse); ++ sent_size = _src.dec_ndr_long(); ++ real_size = _src.dec_ndr_long(); ++ retval = (int) _src.dec_ndr_long(); ++ _src.setIndex(curOffset); ++ while (bytesTotal < sent_size) { ++ if (entries == null) { ++ entries = new ArrayList(); ++ } ++ EventlogRecord entry = new EventlogRecord(); ++ entry.decode(_src); ++ entries.add(entry); ++ bytesTotal += entry.size; ++ } ++ } ++ } ++} ++ +diff -Naur old-src/jcifs/dcerpc/ndr/NdrBuffer.java src/jcifs/dcerpc/ndr/NdrBuffer.java +--- old-src/jcifs/dcerpc/ndr/NdrBuffer.java 2007-01-22 17:21:18.000000000 -0800 ++++ src/jcifs/dcerpc/ndr/NdrBuffer.java 2007-03-20 10:41:37.000000000 -0700 +@@ -120,33 +120,51 @@ + } + public void enc_ndr_short(int s) { + align(2); ++ enc_ndr_small_noalign(s); ++ } ++ public void enc_ndr_small_noalign(int s) { + Encdec.enc_uint16le((short)s, buf, index); + advance(2); + } + public int dec_ndr_short() { + align(2); ++ return dec_ndr_short_noalign(); ++ } ++ public int dec_ndr_short_noalign() { + int val = Encdec.dec_uint16le(buf, index); + advance(2); + return val; + } + public void enc_ndr_long(int l) { + align(4); ++ enc_ndr_long_noalign(l); ++ } ++ public void enc_ndr_long_noalign(int l) { + Encdec.enc_uint32le(l, buf, index); + advance(4); + } + public int dec_ndr_long() { + align(4); ++ return dec_ndr_long_noalign(); ++ } ++ public int dec_ndr_long_noalign() { + int val = Encdec.dec_uint32le(buf, index); + advance(4); + return val; + } + public void enc_ndr_hyper(long h) { + align(8); ++ enc_ndr_hyper_noalign(h); ++ } ++ public void enc_ndr_hyper_noalign(long h) { + Encdec.enc_uint64le(h, buf, index); + advance(8); + } + public long dec_ndr_hyper() { + align(8); ++ return dec_ndr_hyper_noalign(); ++ } ++ public long dec_ndr_hyper_noalign() { + long val = Encdec.dec_uint64le(buf, index); + advance(8); + return val; +@@ -155,6 +173,9 @@ + /* double */ + public void enc_ndr_string(String s) { + align(4); ++ enc_ndr_string_noalign(s); ++ } ++ public void enc_ndr_string_noalign(String s) { + int i = index; + int len = s.length(); + Encdec.enc_uint32le(len + 1, buf, i); i += 4; +@@ -171,6 +192,9 @@ + } + public String dec_ndr_string() throws NdrException { + align(4); ++ return dec_ndr_string_noalign(); ++ } ++ public String dec_ndr_string_noalign() throws NdrException { + int i = index; + String val = null; + int len = Encdec.dec_uint32le(buf, i); +@@ -188,6 +212,67 @@ + advance(i - index); + return val; + } ++ ++ /** ++ * Encode a string into unicode format. It's not UNISTR2 format, doesn't ++ * include length and so on. Just string in UnicodeLittleUnmarked format. ++ * Been used by eventlog APIs. ++ * ++ * @param s ++ * The string that need to encode. ++ */ ++ public void enc_ndr_unistring(String s) { ++ align(2); ++ enc_ndr_unistring_noalign(s); ++ } ++ public void enc_ndr_unistring_noalign(String s) { ++ int i = index; ++ int len = s.length(); ++ try { ++ System.arraycopy(s.getBytes("UnicodeLittleUnmarked"), 0, buf, i, ++ len * 2); ++ } catch (UnsupportedEncodingException uee) { ++ } ++ i += len * 2; ++ buf[i++] = (byte) '\0'; ++ buf[i++] = (byte) '\0'; ++ advance(i - index); ++ } ++ ++ /** ++ * Decode a unicode string. It's not UNISTR2 format, doesn't include length ++ * and so on. Just string in UnicodeLittleUnmarked format. Been used by ++ * eventlog APIs. ++ * ++ * @return decoded java string object. ++ */ ++ public String dec_ndr_unistring() throws NdrException { ++ align(2); ++ return dec_ndr_unistring_noalign(); ++ } ++ public String dec_ndr_unistring_noalign() throws NdrException { ++ int i = index; ++ String val = null; ++ int tmp; ++ int len = 0; ++ do { ++ tmp = dec_ndr_short(); ++ len++; ++ } while (tmp != 0); ++ if (len != 0) { ++ len--; ++ int size = len * 2; ++ try { ++ if (size < 0 || size > 0xFFFF) ++ throw new NdrException(NdrException.INVALID_CONFORMANCE); ++ val = new String(buf, i, size, "UnicodeLittleUnmarked"); ++ i += size + 2; ++ } catch (UnsupportedEncodingException uee) { ++ } ++ } ++ advance(i - index); ++ return val; ++ } + private int getDceReferent(Object obj) { + Entry e; + +diff -Naur old-src/jcifs/dcerpc/UnicodeString.java src/jcifs/dcerpc/UnicodeString.java +--- old-src/jcifs/dcerpc/UnicodeString.java 2007-01-22 17:21:18.000000000 -0800 ++++ src/jcifs/dcerpc/UnicodeString.java 2007-03-20 10:33:47.000000000 -0700 +@@ -27,20 +27,24 @@ + 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.length = rus == null ? 0 : rus.length; ++ this.maximum_length = rus == null ? 0 : rus.maximum_length; ++ this.buffer = rus == null ? null : rus.buffer; + this.zterm = zterm; + } + + public UnicodeString(String str, boolean zterm) { + this.zterm = zterm; + +- int len = str.length(); ++ int len = str == null ? 0 : str.length(); + int zt = zterm ? 1 : 0; + + length = maximum_length = (short)((len + zt) * 2); +- buffer = new short[len + zt]; ++ if (str != null) { ++ buffer = new short[len + zt]; ++ } else { ++ buffer = null; ++ } + + int i; + for (i = 0; i < len; i++) { +diff -Naur old-src/jcifs/smb/NtStatus.java src/jcifs/smb/NtStatus.java +--- old-src/jcifs/smb/NtStatus.java 2007-01-22 17:21:18.000000000 -0800 ++++ src/jcifs/smb/NtStatus.java 2007-03-20 10:33:47.000000000 -0700 +@@ -33,6 +33,7 @@ + public static final int NT_STATUS_INVALID_PARAMETER = 0xC000000d; + public static final int NT_STATUS_NO_SUCH_DEVICE = 0xC000000e; + public static final int NT_STATUS_NO_SUCH_FILE = 0xC000000f; ++ public static final int NT_STATUS_END_OF_FILE = 0xC0000011; + public static final int NT_STATUS_ACCESS_DENIED = 0xC0000022; + public static final int NT_STATUS_BUFFER_TOO_SMALL = 0xC0000023; + public static final int NT_STATUS_OBJECT_NAME_INVALID = 0xC0000033; +@@ -87,6 +88,7 @@ + NT_STATUS_INVALID_PARAMETER, + NT_STATUS_NO_SUCH_DEVICE, + NT_STATUS_NO_SUCH_FILE, ++ NT_STATUS_END_OF_FILE, + NT_STATUS_ACCESS_DENIED, + NT_STATUS_BUFFER_TOO_SMALL, + NT_STATUS_OBJECT_NAME_INVALID, +@@ -142,6 +144,7 @@ + "The parameter is incorrect.", + "The system cannot find the file specified.", + "The system cannot find the file specified.", ++ "Reached end of file.", + "Access is denied.", + "The data area passed to a system call is too small.", + "The filename, directory name, or volume label syntax is incorrect.", diff --git a/patches/GetOwnerSid.patch b/patches/GetOwnerSid.patch new file mode 100644 index 0000000..3379710 --- /dev/null +++ b/patches/GetOwnerSid.patch @@ -0,0 +1,91 @@ +diff -r temp/jcifs_1.2.13/src/jcifs/smb/SecurityDescriptor.java workspace/jcifs/src/jcifs/smb/SecurityDescriptor.java +24a25 +> SID owner_user, owner_group; +38c39 +< ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to owner sid +--- +> int ownerUOffset = ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to owner sid +40c41 +< ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to group sid +--- +> int ownerGOffset = ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to group sid +42c43 +< ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to sacl +--- +> int saclOffset = ServerMessageBlock.readInt4(buffer, bufferIndex); // offset to sacl +48,56c49,70 +< 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" ); +--- +> if ( ownerUOffset > 0 ) { +> bufferIndex = start + ownerUOffset; +> owner_user = new SID ( buffer, bufferIndex ); +> bufferIndex += 28; // ??? +> } +> +> if ( ownerGOffset > 0 ) { +> bufferIndex = start + ownerGOffset; +> owner_group = new SID ( buffer, bufferIndex ); +> bufferIndex += 28; // ??? +> } +> +> if ( daclOffset > 0 ) { +> 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" ); +58,59c72,73 +< aces = new ACE[numAces]; +< for (int i = 0; i < numAces; i++) { +--- +> aces = new ACE[numAces]; +> for (int i = 0; i < numAces; i++) { +61a76 +> } +63d77 +< +Only in workspace/jcifs/src/jcifs/smb: SecurityDescriptor.java~ +diff -r temp/jcifs_1.2.13/src/jcifs/smb/SmbFile.java workspace/jcifs/src/jcifs/smb/SmbFile.java +2722a2723,2752 +> +> public SID getOwnerUser() throws IOException { +> int f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 ); +> +> /* +> * NtTrans Query Security Desc Request / Response +> */ +> +> NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( f, 0x01 ); +> NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse(); +> send( request, response ); +> +> close( f, 0L ); +> return response.securityDescriptor.owner_user; +> } +> +> public SID getOwnerGroup() throws IOException { +> int f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 ); +> +> /* +> * NtTrans Query Security Desc Request / Response +> */ +> +> NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( f, 0x02 ); +> NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse(); +> send( request, response ); +> +> close( f, 0L ); +> return response.securityDescriptor.owner_group; +> } diff --git a/patches/README.txt b/patches/README.txt index f99d203..7d36f14 100644 --- a/patches/README.txt +++ b/patches/README.txt @@ -2,6 +2,20 @@ These patches are not supported. They are provided here only for your conveinience. If you port a patch to a newer version of jCIFS please resubmit it to the mailing list. +GetOwnerSid.patch + +This patch adds methods to SmbFile to retrieve the owner SID of the file. + +backup-domain-controllers-1.2.13.patch + +This patch allows multiple comma separated domain controllers to be +specified using the jcifs.http.domainController property. If one is not +'active' another will be tried. + +Eventlog.patch + +This patch adds the necessary MSRPCs to remotely read an event log. + Print.patch This minor patch and example program demonstrates how to emit diff --git a/patches/backup-domain-controllers-1.2.13.patch b/patches/backup-domain-controllers-1.2.13.patch new file mode 100644 index 0000000..3ca92fb --- /dev/null +++ b/patches/backup-domain-controllers-1.2.13.patch @@ -0,0 +1,69 @@ +diff -Nuarw old/src/jcifs/http/NtlmHttpFilter.java new/src/jcifs/http/NtlmHttpFilter.java +--- old/src/jcifs/http/NtlmHttpFilter.java 2006-12-12 15:00:14.000000000 -0800 ++++ new/src/jcifs/http/NtlmHttpFilter.java 2007-04-03 14:37:25.000000000 -0700 +@@ -24,7 +24,7 @@ + + import java.io.*; + import java.util.Enumeration; +-import java.net.UnknownHostException; ++import java.net.*; + import javax.servlet.*; + import javax.servlet.http.*; + import jcifs.*; +@@ -72,8 +72,26 @@ + Config.setProperty( name, filterConfig.getInitParameter( name )); + } + } ++ + defaultDomain = Config.getProperty("jcifs.smb.client.domain"); + domainController = Config.getProperty( "jcifs.http.domainController" ); ++ if (domainController != null) { ++ String[] domainControllerList = domainController.split(","); ++ ++ if (domainControllerList.length > 1) { ++ String controllerTimeout = Config.getProperty( "jcifs.http.controllerTimeout"); ++ String controllerPort = Config.getProperty("jcifs.http.controllerPort"); ++ int controllerPortInt = controllerPort == null ? 139 : Integer.parseInt(controllerPort); ++ ++ domainController = findActiveController( ++ domainControllerList, ++ Integer.parseInt(controllerTimeout), ++ controllerPortInt); ++ } else { ++ domainController = domainControllerList[0]; ++ } ++ } ++ + if( domainController == null ) { + domainController = defaultDomain; + loadBalance = Config.getBoolean( "jcifs.http.loadBalance", true ); +@@ -118,6 +136,28 @@ + chain.doFilter( new NtlmHttpServletRequest( req, ntlm ), response ); + } + ++ protected String findActiveController( String[] controllerList, ++ int controllerTimeout, ++ int controllerPort) { ++ String activeController = ""; ++ ++ for (int x = 0; x < controllerList.length; x++) { ++ try { ++ activeController = controllerList[x]; ++ InetSocketAddress addr = new InetSocketAddress(activeController, controllerPort); ++ Socket controller = new Socket(); ++ controller.connect(addr, controllerTimeout); ++ controller.setSoLinger(true,1); ++ controller.close(); ++ break; ++ } catch (Exception e) { ++ continue; ++ } ++ } ++ ++ return activeController; ++ } ++ + /** + * Negotiate password hashes with MSIE clients using NTLM SSP + * @param req The servlet request + diff --git a/src/jcifs/dcerpc/DcerpcBinding.java b/src/jcifs/dcerpc/DcerpcBinding.java index 240ffc3..17ae43b 100644 --- a/src/jcifs/dcerpc/DcerpcBinding.java +++ b/src/jcifs/dcerpc/DcerpcBinding.java @@ -32,6 +32,7 @@ class DcerpcBinding { INTERFACES = new HashMap(); INTERFACES.put("srvsvc", srvsvc.getSyntax()); INTERFACES.put("lsarpc", lsarpc.getSyntax()); + INTERFACES.put("samr", samr.getSyntax()); } String proto; diff --git a/src/jcifs/dcerpc/DcerpcHandle.java b/src/jcifs/dcerpc/DcerpcHandle.java index cb07581..449946f 100644 --- a/src/jcifs/dcerpc/DcerpcHandle.java +++ b/src/jcifs/dcerpc/DcerpcHandle.java @@ -21,6 +21,7 @@ package jcifs.dcerpc; import java.io.*; import java.net.*; +import java.security.Principal; import jcifs.smb.NtlmPasswordAuthentication; import jcifs.util.Hexdump; @@ -205,6 +206,17 @@ public abstract class DcerpcHandle implements DcerpcConstants { if ((de = msg.getResult()) != null) throw de; } + + public String getServer() { + if (this instanceof DcerpcPipeHandle) + return ((DcerpcPipeHandle)this).pipe.getServer(); + return null; + } + public Principal getPrincipal() { + if (this instanceof DcerpcPipeHandle) + return ((DcerpcPipeHandle)this).pipe.getPrincipal(); + return null; + } public String toString() { return binding.toString(); } diff --git a/src/jcifs/dcerpc/msrpc/MsrpcEnumerateAliasesInDomain.java b/src/jcifs/dcerpc/msrpc/MsrpcEnumerateAliasesInDomain.java new file mode 100644 index 0000000..eff03fb --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcEnumerateAliasesInDomain.java @@ -0,0 +1,34 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * 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.dcerpc.*; + +public class MsrpcEnumerateAliasesInDomain extends samr.SamrEnumerateAliasesInDomain { + + public MsrpcEnumerateAliasesInDomain(SamrDomainHandle domainHandle, + int acct_flags, + samr.SamrSamArray sam) { + super(domainHandle, 0, acct_flags, null, 0); + this.sam = sam; + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcGetMembersInAlias.java b/src/jcifs/dcerpc/msrpc/MsrpcGetMembersInAlias.java new file mode 100644 index 0000000..5241bba --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcGetMembersInAlias.java @@ -0,0 +1,32 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * 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.dcerpc.*; + +public class MsrpcGetMembersInAlias extends samr.SamrGetMembersInAlias { + + public MsrpcGetMembersInAlias(SamrAliasHandle aliasHandle, lsarpc.LsarSidArray sids) { + super(aliasHandle, sids); + this.sids = sids; + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcQueryInformationPolicy2.java b/src/jcifs/dcerpc/msrpc/MsrpcQueryInformationPolicy2.java new file mode 100644 index 0000000..7fe1919 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcQueryInformationPolicy2.java @@ -0,0 +1,34 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * 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.dcerpc.*; +import jcifs.dcerpc.ndr.*; + +public class MsrpcQueryInformationPolicy2 extends lsarpc.LsarQueryInformationPolicy2 { + + public MsrpcQueryInformationPolicy2(LsaPolicyHandle policyHandle, + short level, + NdrObject info) { + super(policyHandle, level, info); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcSamrConnect4.java b/src/jcifs/dcerpc/msrpc/MsrpcSamrConnect4.java new file mode 100644 index 0000000..df4dbef --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcSamrConnect4.java @@ -0,0 +1,28 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * 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 MsrpcSamrConnect4 extends samr.SamrConnect4 { + + public MsrpcSamrConnect4(String server, int access, SamrPolicyHandle policyHandle) { + super(server, 2, access, policyHandle); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenAlias.java b/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenAlias.java new file mode 100644 index 0000000..836e647 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenAlias.java @@ -0,0 +1,33 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * 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.dcerpc.*; + +public class MsrpcSamrOpenAlias extends samr.SamrOpenAlias { + + public MsrpcSamrOpenAlias(SamrDomainHandle handle, + int access, + int rid, + SamrAliasHandle aliasHandle) { + super(handle, access, rid, aliasHandle); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenDomain.java b/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenDomain.java new file mode 100644 index 0000000..1751bab --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/MsrpcSamrOpenDomain.java @@ -0,0 +1,33 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * 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.dcerpc.*; + +public class MsrpcSamrOpenDomain extends samr.SamrOpenDomain { + + public MsrpcSamrOpenDomain(SamrPolicyHandle handle, + int access, + rpc.sid_t sid, + SamrDomainHandle domainHandle) { + super(handle, access, sid, domainHandle); + ptype = 0; + flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; + } +} diff --git a/src/jcifs/dcerpc/msrpc/SamrAliasHandle.java b/src/jcifs/dcerpc/msrpc/SamrAliasHandle.java new file mode 100644 index 0000000..a34a0f5 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/SamrAliasHandle.java @@ -0,0 +1,42 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * 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.smb.SmbException; + +import jcifs.dcerpc.*; + +public class SamrAliasHandle extends rpc.policy_handle { + + public SamrAliasHandle(DcerpcHandle handle, + SamrDomainHandle domainHandle, + int access, + int rid) throws IOException { + MsrpcSamrOpenAlias rpc = new MsrpcSamrOpenAlias(domainHandle, access, rid, this); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + } + + public void close() throws IOException { + } +} + diff --git a/src/jcifs/dcerpc/msrpc/SamrDomainHandle.java b/src/jcifs/dcerpc/msrpc/SamrDomainHandle.java new file mode 100644 index 0000000..67f5e94 --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/SamrDomainHandle.java @@ -0,0 +1,42 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * 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.smb.SmbException; + +import jcifs.dcerpc.*; + +public class SamrDomainHandle extends rpc.policy_handle { + + public SamrDomainHandle(DcerpcHandle handle, + SamrPolicyHandle policyHandle, + int access, + rpc.sid_t sid) throws IOException { + MsrpcSamrOpenDomain rpc = new MsrpcSamrOpenDomain(policyHandle, access, sid, this); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + } + + public void close() throws IOException { + } +} + diff --git a/src/jcifs/dcerpc/msrpc/SamrPolicyHandle.java b/src/jcifs/dcerpc/msrpc/SamrPolicyHandle.java new file mode 100644 index 0000000..a0e0b4e --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/SamrPolicyHandle.java @@ -0,0 +1,37 @@ +/* jcifs msrpc client library in Java + * Copyright (C) 2007 "Michael B. Allen" + * + * 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 SamrPolicyHandle extends rpc.policy_handle { + + public SamrPolicyHandle(DcerpcHandle handle, String server, int access) throws IOException { + if (server == null) + server = "\\\\"; + MsrpcSamrConnect4 rpc = new MsrpcSamrConnect4(server, access, this); + handle.sendrecv(rpc); + } + + public void close() throws IOException { + } +} + diff --git a/src/jcifs/dcerpc/msrpc/samr.idl b/src/jcifs/dcerpc/msrpc/samr.idl new file mode 100644 index 0000000..065950f --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/samr.idl @@ -0,0 +1,51 @@ +[ + uuid(12345778-1234-abcd-ef00-0123456789ac), + version(1.0) +] +interface samr +{ + import "../rpc.idl"; + import "lsarpc.idl"; + + [op(0x01)] + int SamrCloseHandle([in] policy_handle *handle); + + [op(0x3e)] + int SamrConnect4([in,string,unique] wchar_t *system_name, + [in] uint32_t unknown, + [in] uint32_t access_mask, + [out] policy_handle *handle); + + [op(0x07)] + int SamrOpenDomain([in] policy_handle *handle, + [in] uint32_t access_mask, + [in] sid_t *sid, + [out] policy_handle *domain_handle); + + typedef struct { + uint32_t idx; + unicode_string name; + } SamrSamEntry; + + typedef struct { + uint32_t count; + [size_is(count)] SamrSamEntry *entries; + } SamrSamArray; + + [op(0x0f)] + int SamrEnumerateAliasesInDomain([in] policy_handle *domain_handle, + [in,out] uint32_t *resume_handle, + [in] uint32_t acct_flags, + [out,unique] SamrSamArray *sam, + [out] uint32_t num_entries); + + [op(0x1b)] + int SamrOpenAlias([in] policy_handle *domain_handle, + [in] uint32_t access_mask, + [in] uint32_t rid, + [out] policy_handle *alias_handle); + + [op(0x21)] + int SamrGetMembersInAlias([in] policy_handle *alias_handle, + [out] LsarSidArray *sids); +} diff --git a/src/jcifs/dcerpc/msrpc/samr.java b/src/jcifs/dcerpc/msrpc/samr.java new file mode 100644 index 0000000..7b355db --- /dev/null +++ b/src/jcifs/dcerpc/msrpc/samr.java @@ -0,0 +1,293 @@ +package jcifs.dcerpc.msrpc; + +import jcifs.dcerpc.*; +import jcifs.dcerpc.ndr.*; + +public class samr { + + public static String getSyntax() { + return "12345778-1234-abcd-ef00-0123456789ac:1.0"; + } + + public static class SamrCloseHandle extends DcerpcMessage { + + public int getOpnum() { return 0x01; } + + public int retval; + public rpc.policy_handle handle; + + public SamrCloseHandle(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 { + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrConnect4 extends DcerpcMessage { + + public int getOpnum() { return 0x3e; } + + public int retval; + public String system_name; + public int unknown; + public int access_mask; + public rpc.policy_handle handle; + + public SamrConnect4(String system_name, + int unknown, + int access_mask, + rpc.policy_handle handle) { + this.system_name = system_name; + this.unknown = unknown; + this.access_mask = access_mask; + this.handle = 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); + + } + _dst.enc_ndr_long(unknown); + _dst.enc_ndr_long(access_mask); + } + public void decode_out(NdrBuffer _src) throws NdrException { + handle.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrOpenDomain extends DcerpcMessage { + + public int getOpnum() { return 0x07; } + + public int retval; + public rpc.policy_handle handle; + public int access_mask; + public rpc.sid_t sid; + public rpc.policy_handle domain_handle; + + public SamrOpenDomain(rpc.policy_handle handle, + int access_mask, + rpc.sid_t sid, + rpc.policy_handle domain_handle) { + this.handle = handle; + this.access_mask = access_mask; + this.sid = sid; + this.domain_handle = domain_handle; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + handle.encode(_dst); + _dst.enc_ndr_long(access_mask); + sid.encode(_dst); + } + public void decode_out(NdrBuffer _src) throws NdrException { + domain_handle.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrSamEntry extends NdrObject { + + public int idx; + public rpc.unicode_string name; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(idx); + _dst.enc_ndr_short(name.length); + _dst.enc_ndr_short(name.maximum_length); + _dst.enc_ndr_referent(name.buffer, 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]); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + idx = (int)_src.dec_ndr_long(); + _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(); + + 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 SamrSamArray extends NdrObject { + + public int count; + public SamrSamEntry[] entries; + + public void encode(NdrBuffer _dst) throws NdrException { + _dst.align(4); + _dst.enc_ndr_long(count); + _dst.enc_ndr_referent(entries, 1); + + if (entries != null) { + _dst = _dst.deferred; + int _entriess = count; + _dst.enc_ndr_long(_entriess); + int _entriesi = _dst.index; + _dst.advance(12 * _entriess); + + _dst = _dst.derive(_entriesi); + for (int _i = 0; _i < _entriess; _i++) { + entries[_i].encode(_dst); + } + } + } + public void decode(NdrBuffer _src) throws NdrException { + _src.align(4); + count = (int)_src.dec_ndr_long(); + int _entriesp = _src.dec_ndr_long(); + + if (_entriesp != 0) { + _src = _src.deferred; + int _entriess = _src.dec_ndr_long(); + int _entriesi = _src.index; + _src.advance(12 * _entriess); + + if (entries == null) { + if (_entriess < 0 || _entriess > 0xFFFF) throw new NdrException( NdrException.INVALID_CONFORMANCE ); + entries = new SamrSamEntry[_entriess]; + } + _src = _src.derive(_entriesi); + for (int _i = 0; _i < _entriess; _i++) { + if (entries[_i] == null) { + entries[_i] = new SamrSamEntry(); + } + entries[_i].decode(_src); + } + } + } + } + public static class SamrEnumerateAliasesInDomain extends DcerpcMessage { + + public int getOpnum() { return 0x0f; } + + public int retval; + public rpc.policy_handle domain_handle; + public int resume_handle; + public int acct_flags; + public SamrSamArray sam; + public int num_entries; + + public SamrEnumerateAliasesInDomain(rpc.policy_handle domain_handle, + int resume_handle, + int acct_flags, + SamrSamArray sam, + int num_entries) { + this.domain_handle = domain_handle; + this.resume_handle = resume_handle; + this.acct_flags = acct_flags; + this.sam = sam; + this.num_entries = num_entries; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + domain_handle.encode(_dst); + _dst.enc_ndr_long(resume_handle); + _dst.enc_ndr_long(acct_flags); + } + public void decode_out(NdrBuffer _src) throws NdrException { + resume_handle = (int)_src.dec_ndr_long(); + int _samp = _src.dec_ndr_long(); + if (_samp != 0) { + if (sam == null) { /* YOYOYO */ + sam = new SamrSamArray(); + } + sam.decode(_src); + + } + num_entries = (int)_src.dec_ndr_long(); + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrOpenAlias extends DcerpcMessage { + + public int getOpnum() { return 0x1b; } + + public int retval; + public rpc.policy_handle domain_handle; + public int access_mask; + public int rid; + public rpc.policy_handle alias_handle; + + public SamrOpenAlias(rpc.policy_handle domain_handle, + int access_mask, + int rid, + rpc.policy_handle alias_handle) { + this.domain_handle = domain_handle; + this.access_mask = access_mask; + this.rid = rid; + this.alias_handle = alias_handle; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + domain_handle.encode(_dst); + _dst.enc_ndr_long(access_mask); + _dst.enc_ndr_long(rid); + } + public void decode_out(NdrBuffer _src) throws NdrException { + alias_handle.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } + public static class SamrGetMembersInAlias extends DcerpcMessage { + + public int getOpnum() { return 0x21; } + + public int retval; + public rpc.policy_handle alias_handle; + public lsarpc.LsarSidArray sids; + + public SamrGetMembersInAlias(rpc.policy_handle alias_handle, lsarpc.LsarSidArray sids) { + this.alias_handle = alias_handle; + this.sids = sids; + } + + public void encode_in(NdrBuffer _dst) throws NdrException { + alias_handle.encode(_dst); + } + public void decode_out(NdrBuffer _src) throws NdrException { + sids.decode(_src); + retval = (int)_src.dec_ndr_long(); + } + } +} diff --git a/src/jcifs/smb/NtStatus.java b/src/jcifs/smb/NtStatus.java index 83274a5..f3da6f6 100644 --- a/src/jcifs/smb/NtStatus.java +++ b/src/jcifs/smb/NtStatus.java @@ -43,6 +43,7 @@ public interface NtStatus { public static final int NT_STATUS_OBJECT_PATH_SYNTAX_BAD = 0xC000003b; public static final int NT_STATUS_SHARING_VIOLATION = 0xC0000043; public static final int NT_STATUS_DELETE_PENDING = 0xC0000056; + public static final int NT_STATUS_NO_LOGON_SERVERS = 0xC000005e; public static final int NT_STATUS_NO_SUCH_USER = 0xC0000064; public static final int NT_STATUS_WRONG_PASSWORD = 0xC000006a; public static final int NT_STATUS_LOGON_FAILURE = 0xC000006d; @@ -67,6 +68,7 @@ public interface NtStatus { 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_CANT_ACCESS_DOMAIN_INFO = 0xC00000da; + public static final int NT_STATUS_NO_SUCH_DOMAIN = 0xC00000df; 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; @@ -97,6 +99,7 @@ public interface NtStatus { NT_STATUS_OBJECT_PATH_SYNTAX_BAD, NT_STATUS_SHARING_VIOLATION, NT_STATUS_DELETE_PENDING, + NT_STATUS_NO_LOGON_SERVERS, NT_STATUS_NO_SUCH_USER, NT_STATUS_WRONG_PASSWORD, NT_STATUS_LOGON_FAILURE, @@ -121,6 +124,7 @@ public interface NtStatus { NT_STATUS_BAD_NETWORK_NAME, NT_STATUS_REQUEST_NOT_ACCEPTED, NT_STATUS_CANT_ACCESS_DOMAIN_INFO, + NT_STATUS_NO_SUCH_DOMAIN, NT_STATUS_NOT_A_DIRECTORY, NT_STATUS_CANNOT_DELETE, NT_STATUS_PIPE_BROKEN, @@ -152,6 +156,7 @@ public interface NtStatus { "The specified path is invalid.", "The process cannot access the file because it is being used by another process.", "Access is denied.", + "There are currently no logon servers available to service the logon request.", "The specified user does not exist.", "The specified network password is not correct.", "Logon failure: unknown user name or bad password.", @@ -176,6 +181,7 @@ public interface NtStatus { "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.", "Indicates a Windows NT Server could not be contacted or that objects within the domain are protected such that necessary information could not be retrieved.", + "The specified domain did not exist.", "The directory name is invalid.", "Access is denied.", "The pipe has been ended.", diff --git a/src/jcifs/smb/SID.java b/src/jcifs/smb/SID.java index 372a495..3102e93 100644 --- a/src/jcifs/smb/SID.java +++ b/src/jcifs/smb/SID.java @@ -21,6 +21,7 @@ package jcifs.smb; import java.util.*; import java.io.IOException; + import jcifs.util.Hexdump; import jcifs.dcerpc.*; import jcifs.dcerpc.msrpc.*; @@ -67,6 +68,8 @@ public class SID extends rpc.sid_t { "Unknown" }; + public static final int SID_FLAG_RESOLVE_SIDS = 0x0001; + static Map sid_cache = Collections.synchronizedMap(new HashMap()); static void resolveSids(DcerpcHandle handle, @@ -100,6 +103,8 @@ public class SID extends rpc.sid_t { } sids[si].acctName = (new UnicodeString(rpc.names.names[si].name, false)).toString(); + sids[si].origin_server = null; + sids[si].origin_auth = null; } } static void resolveSids0(String authorityServerName, @@ -160,6 +165,38 @@ public class SID extends rpc.sid_t { } } } + public static SID getServerSid(String server, + NtlmPasswordAuthentication auth) throws IOException { + DcerpcHandle handle = null; + LsaPolicyHandle policyHandle = null; + lsarpc.LsarDomainInfo info = new lsarpc.LsarDomainInfo(); + MsrpcQueryInformationPolicy2 rpc; + + try { + handle = DcerpcHandle.getHandle("ncacn_np:" + server + + "[\\PIPE\\lsarpc]", auth); + policyHandle = new LsaPolicyHandle(handle, null, 0x02000000); + rpc = new MsrpcQueryInformationPolicy2(policyHandle, + (short)lsarpc.POLICY_INFO_ACCOUNT_DOMAIN, + info); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + + return new SID(info.sid, + SID.SID_TYPE_DOMAIN, + (new UnicodeString(info.name, false)).toString(), + null, + false); + } finally { + if (handle != null) { + if (policyHandle != null) { + policyHandle.close(); + } + handle.close(); + } + } + } int type; String domainName = null; @@ -184,7 +221,6 @@ public class SID extends rpc.sid_t { si += 4; } } - /** * Construct a SID from it's textual representation such as * S-1-5-21-1496946806-2192648263-3843101252-1029. @@ -234,6 +270,40 @@ public class SID extends rpc.sid_t { } this.sub_authority[i] = rid; } + SID(rpc.sid_t sid, + int type, + String domainName, + String acctName, + boolean decrementAuthority) { + this.revision = sid.revision; + this.sub_authority_count = sid.sub_authority_count; + this.identifier_authority = sid.identifier_authority; + this.sub_authority = sid.sub_authority; + this.type = type; + this.domainName = domainName; + this.acctName = acctName; + + if (decrementAuthority) { + this.sub_authority_count--; + this.sub_authority = new int[sub_authority_count]; + for (int i = 0; i < this.sub_authority_count; i++) { + this.sub_authority[i] = sid.sub_authority[i]; + } + } + } + + public SID getDomainSid() { + return new SID(this, + SID_TYPE_DOMAIN, + this.domainName, + null, + getType() != SID_TYPE_DOMAIN); + } + public int getRid() { + if (getType() == SID_TYPE_DOMAIN) + throw new IllegalArgumentException("This SID is a domain sid"); + return sub_authority[sub_authority_count - 1]; + } /** * Returns the type of this SID indicating the state or type of account. @@ -380,8 +450,7 @@ public class SID extends rpc.sid_t { if (type == SID_TYPE_DOMAIN) { str = domainName; - } else if (domainName == null || - type == SID_TYPE_WKN_GRP || + } else if (type == SID_TYPE_WKN_GRP || domainName.equals("BUILTIN")) { if (type == SID_TYPE_UNKNOWN) { str = toString(); @@ -397,8 +466,18 @@ public class SID extends rpc.sid_t { return toString(); } - void resolve(String authorityServerName, - NtlmPasswordAuthentication auth) throws IOException { + /** + * Manually resolve this SID. Normally SIDs are automatically + * resolved. However, if a SID is constructed explicitly using a SID + * constructor, JCIFS will have no knowledge of the server that created the + * SID and therefore cannot possibly resolve it automatically. In this case, + * this method will be necessary. + * + * @param authorityServerName The FQDN of the server that is an authority for the SID. + * @param auth Credentials suitable for accessing the SID's information. + */ + public void resolve(String authorityServerName, + NtlmPasswordAuthentication auth) throws IOException { SID[] sids = new SID[1]; sids[0] = this; SID.resolveSids(authorityServerName, auth, sids); @@ -408,12 +487,166 @@ public class SID extends rpc.sid_t { if (origin_server != null) { try { resolve(origin_server, origin_auth); - } catch (IOException ioe) { + } catch(IOException ioe) { } finally { origin_server = null; origin_auth = null; } } } + + static SID[] getGroupMemberSids0(DcerpcHandle handle, + SamrDomainHandle domainHandle, + SID domsid, + int rid, + int flags) throws IOException { + SamrAliasHandle aliasHandle = null; + lsarpc.LsarSidArray sidarray = new lsarpc.LsarSidArray(); + MsrpcGetMembersInAlias rpc = null; + + try { + aliasHandle = new SamrAliasHandle(handle, domainHandle, 0x02000000, rid); + rpc = new MsrpcGetMembersInAlias(aliasHandle, sidarray); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + SID[] sids = new SID[rpc.sids.num_sids]; + + String origin_server = handle.getServer(); + NtlmPasswordAuthentication origin_auth = + (NtlmPasswordAuthentication)handle.getPrincipal(); + + for (int i = 0; i < sids.length; i++) { + sids[i] = new SID(rpc.sids.sids[i].sid, + 0, + null, + null, + false); + sids[i].origin_server = origin_server; + sids[i].origin_auth = origin_auth; + } + if (sids.length > 0 && (flags & SID_FLAG_RESOLVE_SIDS) != 0) { + SID.resolveSids(origin_server, origin_auth, sids); + } + return sids; + } finally { + if (aliasHandle != null) { + aliasHandle.close(); + } + } + } + + public SID[] getGroupMemberSids(String authorityServerName, + NtlmPasswordAuthentication auth, + int flags) throws IOException { + DcerpcHandle handle = null; + SamrPolicyHandle policyHandle = null; + SamrDomainHandle domainHandle = null; + SID domsid = getDomainSid(); + + try { + handle = DcerpcHandle.getHandle("ncacn_np:" + authorityServerName + + "[\\PIPE\\samr]", auth); + policyHandle = new SamrPolicyHandle(handle, authorityServerName, 0x02000000); + domainHandle = new SamrDomainHandle(handle, policyHandle, 0x02000000, domsid); + return SID.getGroupMemberSids0(handle, + domainHandle, + domsid, + getRid(), + flags); + } finally { + if (handle != null) { + if (policyHandle != null) { + if (domainHandle != null) { + domainHandle.close(); + } + policyHandle.close(); + } + handle.close(); + } + } + } + + /** + * This specialized method returns a Map of users and local groups for the + * target server where keys are SIDs representing an account and each value + * is an ArrayList of SIDs represents the local groups that the account is + * a member of. + *

+ * This method is designed to assist with computing access control for a + * given user when the target object's ACL has local groups. Local groups + * are not listed in a user's group membership (e.g. as represented by the + * tokenGroups constructed attribute retrived via LDAP). + *

+ * Domain groups nested inside a local group are currently not expanded. In + * this case the key (SID) type will be SID_TYPE_DOM_GRP rather than + * SID_TYPE_USER. + * + * @param authorityServerName The server from which the local groups will be queried. + * @param auth The credentials required to query groups and group members. + * @param flags Flags that control the behavior of the operation. When all + * name associated with SIDs will be required, the SID_FLAG_RESOLVE_SIDS + * flag should be used which causes all group member SIDs to be resolved + * together in a single more efficient operation. + */ + static Map getLocalGroupsMap(String authorityServerName, + NtlmPasswordAuthentication auth, + int flags) throws IOException { + SID domsid = SID.getServerSid(authorityServerName, auth); + DcerpcHandle handle = null; + SamrPolicyHandle policyHandle = null; + SamrDomainHandle domainHandle = null; + samr.SamrSamArray sam = new samr.SamrSamArray(); + MsrpcEnumerateAliasesInDomain rpc; + + try { + handle = DcerpcHandle.getHandle("ncacn_np:" + authorityServerName + + "[\\PIPE\\samr]", auth); + policyHandle = new SamrPolicyHandle(handle, authorityServerName, 0x02000000); + domainHandle = new SamrDomainHandle(handle, policyHandle, 0x02000000, domsid); + rpc = new MsrpcEnumerateAliasesInDomain(domainHandle, 0xFFFF, sam); + handle.sendrecv(rpc); + if (rpc.retval != 0) + throw new SmbException(rpc.retval, false); + + Map map = new HashMap(); + + for (int ei = 0; ei < rpc.sam.count; ei++) { + samr.SamrSamEntry entry = rpc.sam.entries[ei]; + + SID[] mems = SID.getGroupMemberSids0(handle, + domainHandle, + domsid, + entry.idx, + flags); + SID groupSid = new SID(domsid, entry.idx); + groupSid.type = SID_TYPE_ALIAS; + groupSid.domainName = domsid.getDomainName(); + groupSid.acctName = (new UnicodeString(entry.name, false)).toString(); + + for (int mi = 0; mi < mems.length; mi++) { + ArrayList groups = (ArrayList)map.get(mems[mi]); + if (groups == null) { + groups = new ArrayList(); + map.put(mems[mi], groups); + } + if (!groups.contains(groupSid)) + groups.add(groupSid); + } + } + + return map; + } finally { + if (handle != null) { + if (policyHandle != null) { + if (domainHandle != null) { + domainHandle.close(); + } + policyHandle.close(); + } + handle.close(); + } + } + } } diff --git a/src/jcifs/smb/SmbException.java b/src/jcifs/smb/SmbException.java index ac1975a..090f193 100644 --- a/src/jcifs/smb/SmbException.java +++ b/src/jcifs/smb/SmbException.java @@ -135,7 +135,7 @@ public class SmbException extends IOException implements NtStatus, DosError, Win this.rootCause = rootCause; status = NT_STATUS_UNSUCCESSFUL; } - SmbException( int errcode, boolean winerr ) { + public SmbException( int errcode, boolean winerr ) { super( winerr ? getMessageByWinerrCode( errcode ) : getMessageByCode( errcode )); status = winerr ? errcode : getStatusByCode( errcode ); } diff --git a/src/jcifs/smb/SmbFile.java b/src/jcifs/smb/SmbFile.java index 6b9f24c..ec5a9d7 100644 --- a/src/jcifs/smb/SmbFile.java +++ b/src/jcifs/smb/SmbFile.java @@ -617,7 +617,6 @@ public class SmbFile extends URLConnection implements SmbConstants { new URL( null, "smb://" + name + "/", Handler.SMB_HANDLER ) : new URL( context.url, name + (( attributes & ATTR_DIRECTORY ) > 0 ? "/" : "" ))); - /* why was this removed before? DFS? copyTo? Am I going around in circles? */ auth = context.auth; @@ -1805,7 +1804,8 @@ public class SmbFile extends URLConnection implements SmbConstants { if( name.length() < 3 ) { int h = name.hashCode(); if( h == HASH_DOT || h == HASH_DOT_DOT ) { - continue; + if (name.equals(".") || name.equals("..")) + continue; } } if( fnf != null && fnf.accept( this, name ) == false ) { -- 2.11.0