public MsrpcLookupSids(LsaPolicyHandle policyHandle, Sid[] sids) : base(policyHandle , new LsarSidArrayX(sids), new Lsarpc.LsarRefDomainList(), new Lsarpc.LsarTransNameArray (), 1, sids.Length) { this.sids = sids; Ptype = 0; Flags = DcerpcConstants.DcerpcFirstFrag | DcerpcConstants.DcerpcLastFrag; }
internal LsarSidArrayX(Sid[] sids) { NumSids = sids.Length; this.Sids = new Lsarpc.LsarSidPtr[sids.Length]; for (int si = 0; si < sids.Length; si++) { this.Sids[si] = new Lsarpc.LsarSidPtr(); this.Sids[si].Sid = sids[si]; } }
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) { } }
/// <exception cref="System.IO.IOException"></exception> private void ProcessAces(Ace[] aces, bool resolveSids) { string server = GetServerWithDfs(); int ai; if (resolveSids) { Sid[] sids = new Sid[aces.Length]; string[] names = null; for (ai = 0; ai < aces.Length; ai++) { sids[ai] = aces[ai].Sid; } for (int off = 0; off < sids.Length; off += 64) { int len = sids.Length - off; if (len > 64) { len = 64; } Sid.ResolveSids(server, Auth, sids, off, len); } } else { for (ai = 0; ai < aces.Length; ai++) { aces[ai].Sid.OriginServer = server; aces[ai].Sid.OriginAuth = Auth; } } }
/// <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> 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; } }
/// <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(); } } } }
/// <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(); } } }
/// <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); }
/// <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]); } } } }
/// <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; }
internal virtual int Decode(byte[] buf, int bi) { Allow = buf[bi++] == unchecked(unchecked(0x00)); Flags = buf[bi++] & unchecked(0xFF); int size = ServerMessageBlock.ReadInt2(buf, bi); bi += 2; Access = ServerMessageBlock.ReadInt4(buf, bi); bi += 4; Sid = new Sid(buf, bi); return size; }