diff options
Diffstat (limited to 'Emby.Common.Implementations/IO/SharpCifs/Smb/SID.cs')
| -rw-r--r-- | Emby.Common.Implementations/IO/SharpCifs/Smb/SID.cs | 1777 |
1 files changed, 909 insertions, 868 deletions
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Smb/SID.cs b/Emby.Common.Implementations/IO/SharpCifs/Smb/SID.cs index a6ad59fb1..577337d6f 100644 --- a/Emby.Common.Implementations/IO/SharpCifs/Smb/SID.cs +++ b/Emby.Common.Implementations/IO/SharpCifs/Smb/SID.cs @@ -26,875 +26,916 @@ using Hashtable = SharpCifs.Util.Sharpen.Hashtable; //not System.Collections.Has namespace SharpCifs.Smb { - /// <summary> - /// A Windows SID is a numeric identifier used to represent Windows - /// accounts. - /// </summary> - /// <remarks> - /// A Windows SID is a numeric identifier used to represent Windows - /// accounts. SIDs are commonly represented using a textual format such as - /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt> but they may - /// also be resolved to yield the name of the associated Windows account - /// such as <tt>Administrators</tt> or <tt>MYDOM\alice</tt>. - /// <p> - /// Consider the following output of <tt>examples/SidLookup.java</tt>: - /// <pre> - /// toString: S-1-5-21-4133388617-793952518-2001621813-512 - /// toDisplayString: WNET\Domain Admins - /// getType: 2 - /// getTypeText: Domain group - /// getDomainName: WNET - /// getAccountName: Domain Admins - /// </pre> - /// </remarks> - public class Sid : Rpc.SidT - { - public const int SidTypeUseNone = Lsarpc.SidNameUseNone; - - public const int SidTypeUser = Lsarpc.SidNameUser; - - public const int SidTypeDomGrp = Lsarpc.SidNameDomGrp; - - public const int SidTypeDomain = Lsarpc.SidNameDomain; - - public const int SidTypeAlias = Lsarpc.SidNameAlias; - - public const int SidTypeWknGrp = Lsarpc.SidNameWknGrp; - - public const int SidTypeDeleted = Lsarpc.SidNameDeleted; - - public const int SidTypeInvalid = Lsarpc.SidNameInvalid; - - public const int SidTypeUnknown = Lsarpc.SidNameUnknown; - - internal static readonly string[] SidTypeNames = { "0", "User", "Domain group" - , "Domain", "Local group", "Builtin group", "Deleted", "Invalid", "Unknown" }; - - public const int SidFlagResolveSids = unchecked(0x0001); - - public static Sid Everyone; - - public static Sid CreatorOwner; - - public static Sid SYSTEM; - - static Sid() - { - try - { - Everyone = new Sid("S-1-1-0"); - CreatorOwner = new Sid("S-1-3-0"); - SYSTEM = new Sid("S-1-5-18"); - } - catch (SmbException) - { - } - } - - internal static Hashtable SidCache = new Hashtable(); - - /// <exception cref="System.IO.IOException"></exception> - internal static void ResolveSids(DcerpcHandle handle, LsaPolicyHandle policyHandle - , Sid[] sids) - { - MsrpcLookupSids rpc = new MsrpcLookupSids(policyHandle, sids); - handle.Sendrecv(rpc); - switch (rpc.Retval) - { - case 0: - case NtStatus.NtStatusNoneMapped: - case unchecked(0x00000107): - { - // NT_STATUS_SOME_NOT_MAPPED - break; - } - - default: - { - throw new SmbException(rpc.Retval, false); - } - } - for (int si = 0; si < sids.Length; si++) - { - sids[si].Type = rpc.Names.Names[si].SidType; - sids[si].DomainName = null; - switch (sids[si].Type) - { - case SidTypeUser: - case SidTypeDomGrp: - case SidTypeDomain: - case SidTypeAlias: - case SidTypeWknGrp: - { - int sidIndex = rpc.Names.Names[si].SidIndex; - Rpc.Unicode_string ustr = rpc.Domains.Domains[sidIndex].Name; - sids[si].DomainName = (new UnicodeString(ustr, false)).ToString(); - break; - } - } - sids[si].AcctName = (new UnicodeString(rpc.Names.Names[si].Name, false)).ToString - (); - sids[si].OriginServer = null; - sids[si].OriginAuth = null; - } - } - - /// <exception cref="System.IO.IOException"></exception> - internal static void ResolveSids0(string authorityServerName, NtlmPasswordAuthentication - auth, Sid[] sids) - { - DcerpcHandle handle = null; - LsaPolicyHandle policyHandle = null; - lock (SidCache) - { - try - { - handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName + "[\\PIPE\\lsarpc]" - , auth); - string server = authorityServerName; - int dot = server.IndexOf('.'); - if (dot > 0 && char.IsDigit(server[0]) == false) - { - server = Runtime.Substring(server, 0, dot); - } - policyHandle = new LsaPolicyHandle(handle, "\\\\" + server, unchecked(0x00000800)); - ResolveSids(handle, policyHandle, sids); - } - finally - { - if (handle != null) - { - if (policyHandle != null) - { - policyHandle.Close(); - } - handle.Close(); - } - } - } - } - - /// <exception cref="System.IO.IOException"></exception> - public static void ResolveSids(string authorityServerName, NtlmPasswordAuthentication - auth, Sid[] sids, int offset, int length) - { - List<object> list = new List<object>();//new List<object>(sids.Length); - int si; - lock (SidCache) - { - for (si = 0; si < length; si++) - { - Sid sid = (Sid)SidCache.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.Count > 0) - { - //sids = (Jcifs.Smb.SID[])Sharpen.Collections.ToArray(list, new Jcifs.Smb.SID[0]); + /// <summary> + /// A Windows SID is a numeric identifier used to represent Windows + /// accounts. + /// </summary> + /// <remarks> + /// A Windows SID is a numeric identifier used to represent Windows + /// accounts. SIDs are commonly represented using a textual format such as + /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt> but they may + /// also be resolved to yield the name of the associated Windows account + /// such as <tt>Administrators</tt> or <tt>MYDOM\alice</tt>. + /// <p> + /// Consider the following output of <tt>examples/SidLookup.java</tt>: + /// <pre> + /// toString: S-1-5-21-4133388617-793952518-2001621813-512 + /// toDisplayString: WNET\Domain Admins + /// getType: 2 + /// getTypeText: Domain group + /// getDomainName: WNET + /// getAccountName: Domain Admins + /// </pre> + /// </remarks> + public class Sid : Rpc.SidT + { + public const int SidTypeUseNone = Lsarpc.SidNameUseNone; + + public const int SidTypeUser = Lsarpc.SidNameUser; + + public const int SidTypeDomGrp = Lsarpc.SidNameDomGrp; + + public const int SidTypeDomain = Lsarpc.SidNameDomain; + + public const int SidTypeAlias = Lsarpc.SidNameAlias; + + public const int SidTypeWknGrp = Lsarpc.SidNameWknGrp; + + public const int SidTypeDeleted = Lsarpc.SidNameDeleted; + + public const int SidTypeInvalid = Lsarpc.SidNameInvalid; + + public const int SidTypeUnknown = Lsarpc.SidNameUnknown; + + internal static readonly string[] SidTypeNames = + { + "0", "User", "Domain group", "Domain", "Local group", + "Builtin group", "Deleted", "Invalid", "Unknown" + }; + + public const int SidFlagResolveSids = unchecked(0x0001); + + public static Sid Everyone; + + public static Sid CreatorOwner; + + public static Sid SYSTEM; + + static Sid() + { + try + { + Everyone = new Sid("S-1-1-0"); + CreatorOwner = new Sid("S-1-3-0"); + SYSTEM = new Sid("S-1-5-18"); + } + catch (SmbException) + { + } + } + + internal static Hashtable SidCache = new Hashtable(); + + /// <exception cref="System.IO.IOException"></exception> + internal static void ResolveSids(DcerpcHandle handle, + LsaPolicyHandle policyHandle, + Sid[] sids) + { + MsrpcLookupSids rpc = new MsrpcLookupSids(policyHandle, sids); + handle.Sendrecv(rpc); + switch (rpc.Retval) + { + case 0: + case NtStatus.NtStatusNoneMapped: + case unchecked(0x00000107): + { + // NT_STATUS_SOME_NOT_MAPPED + break; + } + + default: + { + throw new SmbException(rpc.Retval, false); + } + } + for (int si = 0; si < sids.Length; si++) + { + sids[si].Type = rpc.Names.Names[si].SidType; + sids[si].DomainName = null; + switch (sids[si].Type) + { + case SidTypeUser: + case SidTypeDomGrp: + case SidTypeDomain: + case SidTypeAlias: + case SidTypeWknGrp: + { + int sidIndex = rpc.Names.Names[si].SidIndex; + Rpc.Unicode_string ustr = rpc.Domains.Domains[sidIndex].Name; + sids[si].DomainName = (new UnicodeString(ustr, false)).ToString(); + break; + } + } + sids[si].AcctName = (new UnicodeString(rpc.Names.Names[si].Name, false)).ToString(); + sids[si].OriginServer = null; + sids[si].OriginAuth = null; + } + } + + /// <exception cref="System.IO.IOException"></exception> + internal static void ResolveSids0(string authorityServerName, + NtlmPasswordAuthentication auth, + Sid[] sids) + { + DcerpcHandle handle = null; + LsaPolicyHandle policyHandle = null; + lock (SidCache) + { + try + { + handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName + + "[\\PIPE\\lsarpc]", auth); + string server = authorityServerName; + int dot = server.IndexOf('.'); + if (dot > 0 && char.IsDigit(server[0]) == false) + { + server = Runtime.Substring(server, 0, dot); + } + policyHandle = new LsaPolicyHandle(handle, "\\\\" + server, unchecked(0x00000800)); + ResolveSids(handle, policyHandle, sids); + } + finally + { + if (handle != null) + { + if (policyHandle != null) + { + policyHandle.Close(); + } + handle.Close(); + } + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + public static void ResolveSids(string authorityServerName, + NtlmPasswordAuthentication auth, + Sid[] sids, + int offset, + int length) + { + List<object> list = new List<object>(); //new List<object>(sids.Length); + int si; + lock (SidCache) + { + for (si = 0; si < length; si++) + { + Sid sid = (Sid)SidCache.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.Count > 0) + { + //sids = (Jcifs.Smb.SID[])Sharpen.Collections.ToArray(list, new Jcifs.Smb.SID[0]); sids = (Sid[])list.ToArray(); - ResolveSids0(authorityServerName, auth, sids); - for (si = 0; si < sids.Length; si++) - { - SidCache.Put(sids[si], sids[si]); - } - } - } - } - - /// <summary>Resolve an array of SIDs using a cache and at most one MSRPC request.</summary> - /// <remarks> - /// Resolve an array of SIDs using a cache and at most one MSRPC request. - /// <p> - /// This method will attempt - /// to resolve SIDs using a cache and cache the results of any SIDs that - /// required resolving with the authority. SID cache entries are currently not - /// expired because under normal circumstances SID information never changes. - /// </remarks> - /// <param name="authorityServerName">The hostname of the server that should be queried. For maximum efficiency this should be the hostname of a domain controller however a member server will work as well and a domain controller may not return names for SIDs corresponding to local accounts for which the domain controller is not an authority. - /// </param> - /// <param name="auth">The credentials that should be used to communicate with the named server. As usual, <tt>null</tt> indicates that default credentials should be used. - /// </param> - /// <param name="sids">The SIDs that should be resolved. After this function is called, the names associated with the SIDs may be queried with the <tt>toDisplayString</tt>, <tt>getDomainName</tt>, and <tt>getAccountName</tt> methods. - /// </param> - /// <exception cref="System.IO.IOException"></exception> - public static void ResolveSids(string authorityServerName, NtlmPasswordAuthentication - auth, Sid[] sids) - { - List<object> list = new List<object>();//new List<object>(sids.Length); - int si; - lock (SidCache) - { - for (si = 0; si < sids.Length; si++) - { - Sid sid = (Sid)SidCache.Get(sids[si]); - if (sid != null) - { - sids[si].Type = sid.Type; - sids[si].DomainName = sid.DomainName; - sids[si].AcctName = sid.AcctName; - } - else - { - list.Add(sids[si]); - } - } - if (list.Count > 0) - { - //sids = (Jcifs.Smb.SID[])Sharpen.Collections.ToArray(list, new Jcifs.Smb.SID[0]); - sids = (Sid[]) list.ToArray(); - ResolveSids0(authorityServerName, auth, sids); - for (si = 0; si < sids.Length; si++) - { - SidCache.Put(sids[si], sids[si]); - } - } - } - } - - /// <exception cref="System.IO.IOException"></exception> - public static Sid GetServerSid(string server, NtlmPasswordAuthentication - auth) - { - DcerpcHandle handle = null; - LsaPolicyHandle policyHandle = null; - Lsarpc.LsarDomainInfo info = new Lsarpc.LsarDomainInfo(); - MsrpcQueryInformationPolicy rpc; - lock (SidCache) - { - try - { - handle = DcerpcHandle.GetHandle("ncacn_np:" + server + "[\\PIPE\\lsarpc]", auth); - // NetApp doesn't like the 'generic' access mask values - policyHandle = new LsaPolicyHandle(handle, null, unchecked(0x00000001)); - rpc = new MsrpcQueryInformationPolicy(policyHandle, Lsarpc.PolicyInfoAccountDomain - , info); - handle.Sendrecv(rpc); - if (rpc.Retval != 0) - { - throw new SmbException(rpc.Retval, false); - } - return new Sid(info.Sid, SidTypeDomain, (new UnicodeString - (info.Name, false)).ToString(), null, false); - } - finally - { - if (handle != null) - { - if (policyHandle != null) - { - policyHandle.Close(); - } - handle.Close(); - } - } - } - } - - public static byte[] ToByteArray(Rpc.SidT sid) - { - byte[] dst = new byte[1 + 1 + 6 + sid.SubAuthorityCount * 4]; - int di = 0; - dst[di++] = sid.Revision; - dst[di++] = sid.SubAuthorityCount; - Array.Copy(sid.IdentifierAuthority, 0, dst, di, 6); - di += 6; - for (int ii = 0; ii < sid.SubAuthorityCount; ii++) - { - Encdec.Enc_uint32le(sid.SubAuthority[ii], dst, di); - di += 4; - } - return dst; - } - - internal int Type; - - internal string DomainName; - - internal string AcctName; - - internal string OriginServer; - - internal NtlmPasswordAuthentication OriginAuth; - - public Sid(byte[] src, int si) - { - Revision = src[si++]; - SubAuthorityCount = src[si++]; - IdentifierAuthority = new byte[6]; - Array.Copy(src, si, IdentifierAuthority, 0, 6); - si += 6; - if (SubAuthorityCount > 100) - { - throw new RuntimeException("Invalid SID sub_authority_count"); - } - SubAuthority = new int[SubAuthorityCount]; - for (int i = 0; i < SubAuthorityCount; i++) - { - SubAuthority[i] = ServerMessageBlock.ReadInt4(src, si); - si += 4; - } - } - - /// <summary> - /// Construct a SID from it's textual representation such as - /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. - /// </summary> - /// <remarks> - /// Construct a SID from it's textual representation such as - /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. - /// </remarks> - /// <exception cref="SharpCifs.Smb.SmbException"></exception> - public Sid(string textual) - { - StringTokenizer st = new StringTokenizer(textual, "-"); - if (st.CountTokens() < 3 || !st.NextToken().Equals("S")) - { - // need S-N-M - throw new SmbException("Bad textual SID format: " + textual); - } - Revision = byte.Parse(st.NextToken()); - string tmp = st.NextToken(); - long id = 0; - if (tmp.StartsWith("0x")) - { - //id = long.Parse(Sharpen.Runtime.Substring(tmp, 2), 16); + ResolveSids0(authorityServerName, auth, sids); + for (si = 0; si < sids.Length; si++) + { + SidCache.Put(sids[si], sids[si]); + } + } + } + } + + /// <summary>Resolve an array of SIDs using a cache and at most one MSRPC request.</summary> + /// <remarks> + /// Resolve an array of SIDs using a cache and at most one MSRPC request. + /// + /// This method will attempt + /// to resolve SIDs using a cache and cache the results of any SIDs that + /// required resolving with the authority. SID cache entries are currently not + /// expired because under normal circumstances SID information never changes. + /// </remarks> + /// <param name="authorityServerName"> + /// The hostname of the server that should be queried. For maximum efficiency this should be the hostname of a domain controller however a member server will work as well and a domain controller may not return names for SIDs corresponding to local accounts for which the domain controller is not an authority. + /// </param> + /// <param name="auth"> + /// The credentials that should be used to communicate with the named server. As usual, <tt>null</tt> indicates that default credentials should be used. + /// </param> + /// <param name="sids"> + /// The SIDs that should be resolved. After this function is called, the names associated with the SIDs may be queried with the <tt>toDisplayString</tt>, <tt>getDomainName</tt>, and <tt>getAccountName</tt> methods. + /// </param> + /// <exception cref="System.IO.IOException"></exception> + public static void ResolveSids(string authorityServerName, + NtlmPasswordAuthentication auth, + Sid[] sids) + { + List<object> list = new List<object>(); //new List<object>(sids.Length); + int si; + lock (SidCache) + { + for (si = 0; si < sids.Length; si++) + { + Sid sid = (Sid)SidCache.Get(sids[si]); + if (sid != null) + { + sids[si].Type = sid.Type; + sids[si].DomainName = sid.DomainName; + sids[si].AcctName = sid.AcctName; + } + else + { + list.Add(sids[si]); + } + } + if (list.Count > 0) + { + //sids = (Jcifs.Smb.SID[])Sharpen.Collections.ToArray(list, new Jcifs.Smb.SID[0]); + sids = (Sid[])list.ToArray(); + ResolveSids0(authorityServerName, auth, sids); + for (si = 0; si < sids.Length; si++) + { + SidCache.Put(sids[si], sids[si]); + } + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + public static Sid GetServerSid(string server, + NtlmPasswordAuthentication auth) + { + DcerpcHandle handle = null; + LsaPolicyHandle policyHandle = null; + Lsarpc.LsarDomainInfo info = new Lsarpc.LsarDomainInfo(); + MsrpcQueryInformationPolicy rpc; + lock (SidCache) + { + try + { + handle = DcerpcHandle.GetHandle("ncacn_np:" + server + "[\\PIPE\\lsarpc]", auth); + // NetApp doesn't like the 'generic' access mask values + policyHandle = new LsaPolicyHandle(handle, null, unchecked(0x00000001)); + rpc = new MsrpcQueryInformationPolicy(policyHandle, + Lsarpc.PolicyInfoAccountDomain, + info); + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, false); + } + return new Sid(info.Sid, + SidTypeDomain, + (new UnicodeString(info.Name, false)).ToString(), + null, + false); + } + finally + { + if (handle != null) + { + if (policyHandle != null) + { + policyHandle.Close(); + } + handle.Close(); + } + } + } + } + + public static byte[] ToByteArray(Rpc.SidT sid) + { + byte[] dst = new byte[1 + 1 + 6 + sid.SubAuthorityCount * 4]; + int di = 0; + dst[di++] = sid.Revision; + dst[di++] = sid.SubAuthorityCount; + Array.Copy(sid.IdentifierAuthority, 0, dst, di, 6); + di += 6; + for (int ii = 0; ii < sid.SubAuthorityCount; ii++) + { + Encdec.Enc_uint32le(sid.SubAuthority[ii], dst, di); + di += 4; + } + return dst; + } + + internal int Type; + + internal string DomainName; + + internal string AcctName; + + internal string OriginServer; + + internal NtlmPasswordAuthentication OriginAuth; + + public Sid(byte[] src, int si) + { + Revision = src[si++]; + SubAuthorityCount = src[si++]; + IdentifierAuthority = new byte[6]; + Array.Copy(src, si, IdentifierAuthority, 0, 6); + si += 6; + if (SubAuthorityCount > 100) + { + throw new RuntimeException("Invalid SID sub_authority_count"); + } + SubAuthority = new int[SubAuthorityCount]; + for (int i = 0; i < SubAuthorityCount; i++) + { + SubAuthority[i] = ServerMessageBlock.ReadInt4(src, si); + si += 4; + } + } + + /// <summary> + /// Construct a SID from it's textual representation such as + /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. + /// </summary> + /// <remarks> + /// Construct a SID from it's textual representation such as + /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. + /// </remarks> + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + public Sid(string textual) + { + StringTokenizer st = new StringTokenizer(textual, "-"); + if (st.CountTokens() < 3 || !st.NextToken().Equals("S")) + { + // need S-N-M + throw new SmbException("Bad textual SID format: " + textual); + } + Revision = byte.Parse(st.NextToken()); + string tmp = st.NextToken(); + long id = 0; + if (tmp.StartsWith("0x")) + { + //id = long.Parse(Sharpen.Runtime.Substring(tmp, 2), 16); id = long.Parse(Runtime.Substring(tmp, 2)); - } - else - { - id = long.Parse(tmp); - } - IdentifierAuthority = new byte[6]; - for (int i = 5; id > 0; i--) - { - IdentifierAuthority[i] = unchecked((byte)(id % 256)); - id >>= 8; - } - SubAuthorityCount = unchecked((byte)st.CountTokens()); - if (SubAuthorityCount > 0) - { - SubAuthority = new int[SubAuthorityCount]; - for (int i1 = 0; i1 < SubAuthorityCount; i1++) - { - SubAuthority[i1] = (int)(long.Parse(st.NextToken()) & unchecked(0xFFFFFFFFL)); - } - } - } - - /// <summary> - /// Construct a SID from a domain SID and an RID - /// (relative identifier). - /// </summary> - /// <remarks> - /// Construct a SID from a domain SID and an RID - /// (relative identifier). For example, a domain SID - /// <tt>S-1-5-21-1496946806-2192648263-3843101252</tt> and RID <tt>1029</tt> would - /// yield the SID <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. - /// </remarks> - public Sid(Sid domsid, int rid) - { - Revision = domsid.Revision; - IdentifierAuthority = domsid.IdentifierAuthority; - SubAuthorityCount = unchecked((byte)(domsid.SubAuthorityCount + 1)); - SubAuthority = new int[SubAuthorityCount]; - int i; - for (i = 0; i < domsid.SubAuthorityCount; i++) - { - SubAuthority[i] = domsid.SubAuthority[i]; - } - SubAuthority[i] = rid; - } - - public Sid(Rpc.SidT sid, int type, string domainName, string acctName, bool decrementAuthority - ) - { - Revision = sid.Revision; - SubAuthorityCount = sid.SubAuthorityCount; - IdentifierAuthority = sid.IdentifierAuthority; - SubAuthority = sid.SubAuthority; - this.Type = type; - this.DomainName = domainName; - this.AcctName = acctName; - if (decrementAuthority) - { - SubAuthorityCount--; - SubAuthority = new int[SubAuthorityCount]; - for (int i = 0; i < SubAuthorityCount; i++) - { - SubAuthority[i] = sid.SubAuthority[i]; - } - } - } - - public virtual Sid GetDomainSid() - { - return new Sid(this, SidTypeDomain, DomainName, null, GetType() - != SidTypeDomain); - } - - public virtual int GetRid() - { - if (GetType() == SidTypeDomain) - { - throw new ArgumentException("This SID is a domain sid"); - } - return SubAuthority[SubAuthorityCount - 1]; - } - - /// <summary>Returns the type of this SID indicating the state or type of account.</summary> - /// <remarks> - /// Returns the type of this SID indicating the state or type of account. - /// <p> - /// SID types are described in the following table. - /// <tt> - /// <table> - /// <tr><th>Type</th><th>Name</th></tr> - /// <tr><td>SID_TYPE_USE_NONE</td><td>0</td></tr> - /// <tr><td>SID_TYPE_USER</td><td>User</td></tr> - /// <tr><td>SID_TYPE_DOM_GRP</td><td>Domain group</td></tr> - /// <tr><td>SID_TYPE_DOMAIN</td><td>Domain</td></tr> - /// <tr><td>SID_TYPE_ALIAS</td><td>Local group</td></tr> - /// <tr><td>SID_TYPE_WKN_GRP</td><td>Builtin group</td></tr> - /// <tr><td>SID_TYPE_DELETED</td><td>Deleted</td></tr> - /// <tr><td>SID_TYPE_INVALID</td><td>Invalid</td></tr> - /// <tr><td>SID_TYPE_UNKNOWN</td><td>Unknown</td></tr> - /// </table> - /// </tt> - /// </remarks> - public virtual int GetType() - { - if (OriginServer != null) - { - ResolveWeak(); - } - return Type; - } - - /// <summary> - /// Return text represeting the SID type suitable for display to - /// users. - /// </summary> - /// <remarks> - /// Return text represeting the SID type suitable for display to - /// users. Text includes 'User', 'Domain group', 'Local group', etc. - /// </remarks> - public virtual string GetTypeText() - { - if (OriginServer != null) - { - ResolveWeak(); - } - return SidTypeNames[Type]; - } - - /// <summary> - /// Return the domain name of this SID unless it could not be - /// resolved in which case the numeric representation is returned. - /// </summary> - /// <remarks> - /// Return the domain name of this SID unless it could not be - /// resolved in which case the numeric representation is returned. - /// </remarks> - public virtual string GetDomainName() - { - if (OriginServer != null) - { - ResolveWeak(); - } - if (Type == SidTypeUnknown) - { - string full = ToString(); - return Runtime.Substring(full, 0, full.Length - GetAccountName().Length - - 1); - } - return DomainName; - } - - /// <summary> - /// Return the sAMAccountName of this SID unless it could not - /// be resolved in which case the numeric RID is returned. - /// </summary> - /// <remarks> - /// Return the sAMAccountName of this SID unless it could not - /// be resolved in which case the numeric RID is returned. If this - /// SID is a domain SID, this method will return an empty String. - /// </remarks> - public virtual string GetAccountName() - { - if (OriginServer != null) - { - ResolveWeak(); - } - if (Type == SidTypeUnknown) - { - return string.Empty + SubAuthority[SubAuthorityCount - 1]; - } - if (Type == SidTypeDomain) - { - return string.Empty; - } - return AcctName; - } - - public override int GetHashCode() - { - int hcode = IdentifierAuthority[5]; - for (int i = 0; i < SubAuthorityCount; i++) - { - hcode += 65599 * SubAuthority[i]; - } - return hcode; - } - - public override bool Equals(object obj) - { - if (obj is Sid) - { - Sid sid = (Sid)obj; - if (sid == this) - { - return true; - } - if (sid.SubAuthorityCount == SubAuthorityCount) - { - int i = SubAuthorityCount; - while (i-- > 0) - { - if (sid.SubAuthority[i] != SubAuthority[i]) - { - return false; - } - } - for (i = 0; i < 6; i++) - { - if (sid.IdentifierAuthority[i] != IdentifierAuthority[i]) - { - return false; - } - } - return sid.Revision == Revision; - } - } - return false; - } - - /// <summary> - /// Return the numeric representation of this sid such as - /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. - /// </summary> - /// <remarks> - /// Return the numeric representation of this sid such as - /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. - /// </remarks> - public override string ToString() - { - string ret = "S-" + (Revision & unchecked(0xFF)) + "-"; - if (IdentifierAuthority[0] != unchecked(0) || IdentifierAuthority[1] != unchecked( - 0)) - { - ret += "0x"; - ret += Hexdump.ToHexString(IdentifierAuthority, 0, 6); - } - else - { - int shift = 0; - long id = 0; - for (int i = 5; i > 1; i--) - { - id += (IdentifierAuthority[i] & unchecked(0xFFL)) << shift; - shift += 8; - } - ret += id; - } - for (int i1 = 0; i1 < SubAuthorityCount; i1++) - { - ret += "-" + (SubAuthority[i1] & unchecked(0xFFFFFFFFL)); - } - return ret; - } - - /// <summary> - /// Return a String representing this SID ideal for display to - /// users. - /// </summary> - /// <remarks> - /// Return a String representing this SID ideal for display to - /// users. This method should return the same text that the ACL - /// editor in Windows would display. - /// <p> - /// Specifically, if the SID has - /// been resolved and it is not a domain SID or builtin account, - /// the full DOMAIN\name form of the account will be - /// returned (e.g. MYDOM\alice or MYDOM\Domain Users). - /// If the SID has been resolved but it is is a domain SID, - /// only the domain name will be returned (e.g. MYDOM). - /// If the SID has been resolved but it is a builtin account, - /// only the name component will be returned (e.g. SYSTEM). - /// If the sid cannot be resolved the numeric representation from - /// toString() is returned. - /// </remarks> - public virtual string ToDisplayString() - { - if (OriginServer != null) - { - ResolveWeak(); - } - if (DomainName != null) - { - string str; - if (Type == SidTypeDomain) - { - str = DomainName; - } - else - { - if (Type == SidTypeWknGrp || DomainName.Equals("BUILTIN")) - { - if (Type == SidTypeUnknown) - { - str = ToString(); - } - else - { - str = AcctName; - } - } - else - { - str = DomainName + "\\" + AcctName; - } - } - return str; - } - return ToString(); - } - - /// <summary>Manually resolve this SID.</summary> - /// <remarks> - /// 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. - /// </remarks> - /// <param name="authorityServerName">The FQDN of the server that is an authority for the SID. - /// </param> - /// <param name="auth">Credentials suitable for accessing the SID's information.</param> - /// <exception cref="System.IO.IOException"></exception> - public virtual void Resolve(string authorityServerName, NtlmPasswordAuthentication - auth) - { - Sid[] sids = new Sid[1]; - sids[0] = this; - ResolveSids(authorityServerName, auth, sids); - } - - internal virtual void ResolveWeak() - { - if (OriginServer != null) - { - try - { - Resolve(OriginServer, OriginAuth); - } - catch (IOException) - { - } - finally - { - OriginServer = null; - OriginAuth = null; - } - } - } - - /// <exception cref="System.IO.IOException"></exception> - internal static Sid[] GetGroupMemberSids0(DcerpcHandle handle, SamrDomainHandle - domainHandle, Sid domsid, int rid, int flags) - { - SamrAliasHandle aliasHandle = null; - Lsarpc.LsarSidArray sidarray = new Lsarpc.LsarSidArray(); - MsrpcGetMembersInAlias rpc = null; - try - { - aliasHandle = new SamrAliasHandle(handle, domainHandle, unchecked(0x0002000c), 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.NumSids]; - string originServer = handle.GetServer(); - NtlmPasswordAuthentication originAuth = (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].OriginServer = originServer; - sids[i].OriginAuth = originAuth; - } - if (sids.Length > 0 && (flags & SidFlagResolveSids) != 0) - { - ResolveSids(originServer, originAuth, sids); - } - return sids; - } - finally - { - if (aliasHandle != null) - { - aliasHandle.Close(); - } - } - } - - /// <exception cref="System.IO.IOException"></exception> - public virtual Sid[] GetGroupMemberSids(string authorityServerName, NtlmPasswordAuthentication - auth, int flags) - { - if (Type != SidTypeDomGrp && Type != SidTypeAlias) - { - return new Sid[0]; - } - DcerpcHandle handle = null; - SamrPolicyHandle policyHandle = null; - SamrDomainHandle domainHandle = null; - Sid domsid = GetDomainSid(); - lock (SidCache) - { - try - { - handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName + "[\\PIPE\\samr]" - , auth); - policyHandle = new SamrPolicyHandle(handle, authorityServerName, unchecked(0x00000030)); - domainHandle = new SamrDomainHandle(handle, policyHandle, unchecked(0x00000200), domsid); - return GetGroupMemberSids0(handle, domainHandle, domsid, GetRid(), - flags); - } - finally - { - if (handle != null) - { - if (policyHandle != null) - { - if (domainHandle != null) - { - domainHandle.Close(); - } - policyHandle.Close(); - } - handle.Close(); - } - } - } - } - - /// <summary> - /// 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 List<object> of SIDs represents the local groups that the account is - /// a member of. - /// </summary> - /// <remarks> - /// 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 List<object> of SIDs represents the local groups that the account is - /// a member of. - /// <p/> - /// 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). - /// <p/> - /// 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. - /// </remarks> - /// <param name="authorityServerName">The server from which the local groups will be queried. - /// </param> - /// <param name="auth">The credentials required to query groups and group members.</param> - /// <param name="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. - /// </param> - /// <exception cref="System.IO.IOException"></exception> - internal static Hashtable GetLocalGroupsMap(string authorityServerName, NtlmPasswordAuthentication - auth, int flags) - { - Sid domsid = GetServerSid(authorityServerName, auth); - DcerpcHandle handle = null; - SamrPolicyHandle policyHandle = null; - SamrDomainHandle domainHandle = null; - Samr.SamrSamArray sam = new Samr.SamrSamArray(); - MsrpcEnumerateAliasesInDomain rpc; - lock (SidCache) - { - try - { - handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName + "[\\PIPE\\samr]" - , auth); - policyHandle = new SamrPolicyHandle(handle, authorityServerName, unchecked(0x02000000)); - domainHandle = new SamrDomainHandle(handle, policyHandle, unchecked(0x02000000), domsid); - rpc = new MsrpcEnumerateAliasesInDomain(domainHandle, unchecked(0xFFFF), sam - ); - handle.Sendrecv(rpc); - if (rpc.Retval != 0) - { - throw new SmbException(rpc.Retval, false); - } + } + else + { + id = long.Parse(tmp); + } + IdentifierAuthority = new byte[6]; + for (int i = 5; id > 0; i--) + { + IdentifierAuthority[i] = unchecked((byte)(id % 256)); + id >>= 8; + } + SubAuthorityCount = unchecked((byte)st.CountTokens()); + if (SubAuthorityCount > 0) + { + SubAuthority = new int[SubAuthorityCount]; + for (int i1 = 0; i1 < SubAuthorityCount; i1++) + { + SubAuthority[i1] = (int)(long.Parse(st.NextToken()) & unchecked(0xFFFFFFFFL)); + } + } + } + + /// <summary> + /// Construct a SID from a domain SID and an RID + /// (relative identifier). + /// </summary> + /// <remarks> + /// Construct a SID from a domain SID and an RID + /// (relative identifier). For example, a domain SID + /// <tt>S-1-5-21-1496946806-2192648263-3843101252</tt> and RID <tt>1029</tt> would + /// yield the SID <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. + /// </remarks> + public Sid(Sid domsid, int rid) + { + Revision = domsid.Revision; + IdentifierAuthority = domsid.IdentifierAuthority; + SubAuthorityCount = unchecked((byte)(domsid.SubAuthorityCount + 1)); + SubAuthority = new int[SubAuthorityCount]; + int i; + for (i = 0; i < domsid.SubAuthorityCount; i++) + { + SubAuthority[i] = domsid.SubAuthority[i]; + } + SubAuthority[i] = rid; + } + + public Sid(Rpc.SidT sid, + int type, + string domainName, + string acctName, + bool decrementAuthority) + { + Revision = sid.Revision; + SubAuthorityCount = sid.SubAuthorityCount; + IdentifierAuthority = sid.IdentifierAuthority; + SubAuthority = sid.SubAuthority; + this.Type = type; + this.DomainName = domainName; + this.AcctName = acctName; + if (decrementAuthority) + { + SubAuthorityCount--; + SubAuthority = new int[SubAuthorityCount]; + for (int i = 0; i < SubAuthorityCount; i++) + { + SubAuthority[i] = sid.SubAuthority[i]; + } + } + } + + public virtual Sid GetDomainSid() + { + return new Sid(this, + SidTypeDomain, + DomainName, + null, + GetType() != SidTypeDomain); + } + + public virtual int GetRid() + { + if (GetType() == SidTypeDomain) + { + throw new ArgumentException("This SID is a domain sid"); + } + return SubAuthority[SubAuthorityCount - 1]; + } + + /// <summary>Returns the type of this SID indicating the state or type of account.</summary> + /// <remarks> + /// Returns the type of this SID indicating the state or type of account. + /// <p> + /// SID types are described in the following table. + /// <tt> + /// <table> + /// <tr><th>Type</th><th>Name</th></tr> + /// <tr><td>SID_TYPE_USE_NONE</td><td>0</td></tr> + /// <tr><td>SID_TYPE_USER</td><td>User</td></tr> + /// <tr><td>SID_TYPE_DOM_GRP</td><td>Domain group</td></tr> + /// <tr><td>SID_TYPE_DOMAIN</td><td>Domain</td></tr> + /// <tr><td>SID_TYPE_ALIAS</td><td>Local group</td></tr> + /// <tr><td>SID_TYPE_WKN_GRP</td><td>Builtin group</td></tr> + /// <tr><td>SID_TYPE_DELETED</td><td>Deleted</td></tr> + /// <tr><td>SID_TYPE_INVALID</td><td>Invalid</td></tr> + /// <tr><td>SID_TYPE_UNKNOWN</td><td>Unknown</td></tr> + /// </table> + /// </tt> + /// </remarks> + public virtual int GetType() + { + if (OriginServer != null) + { + ResolveWeak(); + } + return Type; + } + + /// <summary> + /// Return text represeting the SID type suitable for display to + /// users. + /// </summary> + /// <remarks> + /// Return text represeting the SID type suitable for display to + /// users. Text includes 'User', 'Domain group', 'Local group', etc. + /// </remarks> + public virtual string GetTypeText() + { + if (OriginServer != null) + { + ResolveWeak(); + } + return SidTypeNames[Type]; + } + + /// <summary> + /// Return the domain name of this SID unless it could not be + /// resolved in which case the numeric representation is returned. + /// </summary> + /// <remarks> + /// Return the domain name of this SID unless it could not be + /// resolved in which case the numeric representation is returned. + /// </remarks> + public virtual string GetDomainName() + { + if (OriginServer != null) + { + ResolveWeak(); + } + if (Type == SidTypeUnknown) + { + string full = ToString(); + return Runtime.Substring(full, 0, full.Length - GetAccountName().Length - 1); + } + return DomainName; + } + + /// <summary> + /// Return the sAMAccountName of this SID unless it could not + /// be resolved in which case the numeric RID is returned. + /// </summary> + /// <remarks> + /// Return the sAMAccountName of this SID unless it could not + /// be resolved in which case the numeric RID is returned. If this + /// SID is a domain SID, this method will return an empty String. + /// </remarks> + public virtual string GetAccountName() + { + if (OriginServer != null) + { + ResolveWeak(); + } + if (Type == SidTypeUnknown) + { + return string.Empty + SubAuthority[SubAuthorityCount - 1]; + } + if (Type == SidTypeDomain) + { + return string.Empty; + } + return AcctName; + } + + public override int GetHashCode() + { + int hcode = IdentifierAuthority[5]; + for (int i = 0; i < SubAuthorityCount; i++) + { + hcode += 65599 * SubAuthority[i]; + } + return hcode; + } + + public override bool Equals(object obj) + { + if (obj is Sid) + { + Sid sid = (Sid)obj; + if (sid == this) + { + return true; + } + if (sid.SubAuthorityCount == SubAuthorityCount) + { + int i = SubAuthorityCount; + while (i-- > 0) + { + if (sid.SubAuthority[i] != SubAuthority[i]) + { + return false; + } + } + for (i = 0; i < 6; i++) + { + if (sid.IdentifierAuthority[i] != IdentifierAuthority[i]) + { + return false; + } + } + return sid.Revision == Revision; + } + } + return false; + } + + /// <summary> + /// Return the numeric representation of this sid such as + /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. + /// </summary> + /// <remarks> + /// Return the numeric representation of this sid such as + /// <tt>S-1-5-21-1496946806-2192648263-3843101252-1029</tt>. + /// </remarks> + public override string ToString() + { + string ret = "S-" + (Revision & unchecked(0xFF)) + "-"; + if (IdentifierAuthority[0] != unchecked(0) + || IdentifierAuthority[1] != unchecked(0)) + { + ret += "0x"; + ret += Hexdump.ToHexString(IdentifierAuthority, 0, 6); + } + else + { + int shift = 0; + long id = 0; + for (int i = 5; i > 1; i--) + { + id += (IdentifierAuthority[i] & unchecked(0xFFL)) << shift; + shift += 8; + } + ret += id; + } + for (int i1 = 0; i1 < SubAuthorityCount; i1++) + { + ret += "-" + (SubAuthority[i1] & unchecked(0xFFFFFFFFL)); + } + return ret; + } + + /// <summary> + /// Return a String representing this SID ideal for display to + /// users. + /// </summary> + /// <remarks> + /// Return a String representing this SID ideal for display to + /// users. This method should return the same text that the ACL + /// editor in Windows would display. + /// <p> + /// Specifically, if the SID has + /// been resolved and it is not a domain SID or builtin account, + /// the full DOMAIN\name form of the account will be + /// returned (e.g. MYDOM\alice or MYDOM\Domain Users). + /// If the SID has been resolved but it is is a domain SID, + /// only the domain name will be returned (e.g. MYDOM). + /// If the SID has been resolved but it is a builtin account, + /// only the name component will be returned (e.g. SYSTEM). + /// If the sid cannot be resolved the numeric representation from + /// toString() is returned. + /// </remarks> + public virtual string ToDisplayString() + { + if (OriginServer != null) + { + ResolveWeak(); + } + if (DomainName != null) + { + string str; + if (Type == SidTypeDomain) + { + str = DomainName; + } + else + { + if (Type == SidTypeWknGrp || DomainName.Equals("BUILTIN")) + { + if (Type == SidTypeUnknown) + { + str = ToString(); + } + else + { + str = AcctName; + } + } + else + { + str = DomainName + "\\" + AcctName; + } + } + return str; + } + return ToString(); + } + + /// <summary>Manually resolve this SID.</summary> + /// <remarks> + /// 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. + /// </remarks> + /// <param name="authorityServerName">The FQDN of the server that is an authority for the SID. + /// </param> + /// <param name="auth">Credentials suitable for accessing the SID's information.</param> + /// <exception cref="System.IO.IOException"></exception> + public virtual void Resolve(string authorityServerName, + NtlmPasswordAuthentication auth) + { + Sid[] sids = new Sid[1]; + sids[0] = this; + ResolveSids(authorityServerName, auth, sids); + } + + internal virtual void ResolveWeak() + { + if (OriginServer != null) + { + try + { + Resolve(OriginServer, OriginAuth); + } + catch (IOException) + { + } + finally + { + OriginServer = null; + OriginAuth = null; + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + internal static Sid[] GetGroupMemberSids0(DcerpcHandle handle, + SamrDomainHandle domainHandle, + Sid domsid, + int rid, + int flags) + { + SamrAliasHandle aliasHandle = null; + Lsarpc.LsarSidArray sidarray = new Lsarpc.LsarSidArray(); + MsrpcGetMembersInAlias rpc = null; + try + { + aliasHandle = new SamrAliasHandle(handle, domainHandle, unchecked(0x0002000c), 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.NumSids]; + string originServer = handle.GetServer(); + NtlmPasswordAuthentication originAuth + = (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].OriginServer = originServer; + sids[i].OriginAuth = originAuth; + } + if (sids.Length > 0 && (flags & SidFlagResolveSids) != 0) + { + ResolveSids(originServer, originAuth, sids); + } + return sids; + } + finally + { + if (aliasHandle != null) + { + aliasHandle.Close(); + } + } + } + + /// <exception cref="System.IO.IOException"></exception> + public virtual Sid[] GetGroupMemberSids(string authorityServerName, + NtlmPasswordAuthentication auth, + int flags) + { + if (Type != SidTypeDomGrp && Type != SidTypeAlias) + { + return new Sid[0]; + } + DcerpcHandle handle = null; + SamrPolicyHandle policyHandle = null; + SamrDomainHandle domainHandle = null; + Sid domsid = GetDomainSid(); + lock (SidCache) + { + try + { + handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName + + "[\\PIPE\\samr]", auth); + policyHandle = new SamrPolicyHandle(handle, + authorityServerName, + unchecked(0x00000030)); + domainHandle = new SamrDomainHandle(handle, + policyHandle, + unchecked(0x00000200), + domsid); + return GetGroupMemberSids0(handle, + domainHandle, + domsid, + GetRid(), + flags); + } + finally + { + if (handle != null) + { + if (policyHandle != null) + { + if (domainHandle != null) + { + domainHandle.Close(); + } + policyHandle.Close(); + } + handle.Close(); + } + } + } + } + + /// <summary> + /// 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 List<object> of SIDs represents the local groups that the account is + /// a member of. + /// </summary> + /// <remarks> + /// 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 List<object> of SIDs represents the local groups that the account is + /// a member of. + /// <p/> + /// 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). + /// <p/> + /// 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. + /// </remarks> + /// <param name="authorityServerName">The server from which the local groups will be queried. + /// </param> + /// <param name="auth">The credentials required to query groups and group members.</param> + /// <param name="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. + /// </param> + /// <exception cref="System.IO.IOException"></exception> + internal static Hashtable GetLocalGroupsMap(string authorityServerName, NtlmPasswordAuthentication + auth, int flags) + { + Sid domsid = GetServerSid(authorityServerName, auth); + DcerpcHandle handle = null; + SamrPolicyHandle policyHandle = null; + SamrDomainHandle domainHandle = null; + Samr.SamrSamArray sam = new Samr.SamrSamArray(); + MsrpcEnumerateAliasesInDomain rpc; + lock (SidCache) + { + try + { + handle = DcerpcHandle.GetHandle("ncacn_np:" + authorityServerName + + "[\\PIPE\\samr]", auth); + policyHandle = new SamrPolicyHandle(handle, + authorityServerName, + unchecked(0x02000000)); + domainHandle = new SamrDomainHandle(handle, + policyHandle, + unchecked(0x02000000), + domsid); + rpc = new MsrpcEnumerateAliasesInDomain(domainHandle, + unchecked(0xFFFF), + sam); + handle.Sendrecv(rpc); + if (rpc.Retval != 0) + { + throw new SmbException(rpc.Retval, false); + } Hashtable map = new Hashtable(); - for (int ei = 0; ei < rpc.Sam.Count; ei++) - { - Samr.SamrSamEntry entry = rpc.Sam.Entries[ei]; - Sid[] mems = GetGroupMemberSids0(handle, domainHandle, domsid - , entry.Idx, flags); - Sid groupSid = new Sid(domsid, entry.Idx); - groupSid.Type = SidTypeAlias; - groupSid.DomainName = domsid.GetDomainName(); - groupSid.AcctName = (new UnicodeString(entry.Name, false)).ToString(); - for (int mi = 0; mi < mems.Length; mi++) - { - List<object> groups = (List<object>)map.Get(mems[mi]); - if (groups == null) - { - groups = new List<object>(); - 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(); - } - } - } - } - } + for (int ei = 0; ei < rpc.Sam.Count; ei++) + { + Samr.SamrSamEntry entry = rpc.Sam.Entries[ei]; + Sid[] mems = GetGroupMemberSids0(handle, + domainHandle, + domsid, + entry.Idx, + flags); + Sid groupSid = new Sid(domsid, entry.Idx); + groupSid.Type = SidTypeAlias; + groupSid.DomainName = domsid.GetDomainName(); + groupSid.AcctName = (new UnicodeString(entry.Name, false)).ToString(); + for (int mi = 0; mi < mems.Length; mi++) + { + List<object> groups = (List<object>)map.Get(mems[mi]); + if (groups == null) + { + groups = new List<object>(); + 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(); + } + } + } + } + } } |
