static ACCESS_ALLOWED_ACE GetAce(IntPtr pDacl, string sid) { var AclSize = new ACL_SIZE_INFORMATION(); GetAclInformation(pDacl, ref AclSize, (uint)Marshal.SizeOf(typeof(ACL_SIZE_INFORMATION)), ACL_INFORMATION_CLASS.AclSizeInformation); for (var i = 0; i < AclSize.AceCount; i++) { IntPtr pAce; GetAce(pDacl, i, out pAce); var ace = (ACCESS_ALLOWED_ACE)Marshal.PtrToStructure(pAce, typeof(ACCESS_ALLOWED_ACE)); var iter = (IntPtr)((long)pAce + (long)Marshal.OffsetOf(typeof(ACCESS_ALLOWED_ACE), "SidStart")); var size = GetLengthSid(iter); var bSID = new byte[size]; Marshal.Copy(iter, bSID, 0, size); IntPtr ptrSid; ConvertSidToStringSid(bSID, out ptrSid); var strSID = Marshal.PtrToStringAuto(ptrSid); if (strSID == sid) { return(ace); } } throw new Exception($"No ACE for SID {sid} found in security descriptor"); }
public static ACL_SIZE_INFORMATION GetAclInfo(PACL pAcl) { var si = new ACL_SIZE_INFORMATION(); if (!GetAclInformation(pAcl, ref si, (uint)Marshal.SizeOf(si), ACL_INFORMATION_CLASS.AclSizeInformation)) { throw new System.ComponentModel.Win32Exception(); } return(si); }
public static ACL_SIZE_INFORMATION GetAclInfo(IntPtr pAcl) { ACL_SIZE_INFORMATION si = new ACL_SIZE_INFORMATION(); if (!GetAclInformation(pAcl, ref si, (uint)Marshal.SizeOf(si), 2)) { throw new System.ComponentModel.Win32Exception(); } return(si); }
public void GetAceTest(bool validUser, bool validCred, string urn, string dn, string dc, string domain, string username, string password, string notes) { var fun = $"{domain}\\{username}"; var pSD = GetSD(fn); var b = GetSecurityDescriptorDacl(pSD, out var daclPresent, out var pAcl, out var defaulted); Assert.That(b, Is.True); Assert.That(daclPresent, Is.True); Assert.That(pAcl, Is.Not.EqualTo(IntPtr.Zero)); var hardAcl = ((IntPtr)pAcl).ToStructure <ACL>(); var ari = new ACL_REVISION_INFORMATION(); b = GetAclInformation(pAcl, ref ari, (uint)Marshal.SizeOf(typeof(ACL_REVISION_INFORMATION)), ACL_INFORMATION_CLASS.AclRevisionInformation); Assert.That(b, Is.True); Assert.That(ari.AclRevision, Is.EqualTo(hardAcl.AclRevision)); var asi = new ACL_SIZE_INFORMATION(); b = GetAclInformation(pAcl, ref asi, (uint)Marshal.SizeOf(typeof(ACL_SIZE_INFORMATION)), ACL_INFORMATION_CLASS.AclSizeInformation); Assert.That(b, Is.True); Assert.That(asi.AceCount, Is.EqualTo(hardAcl.AceCount)); for (var i = 0U; i < asi.AceCount; i++) { b = GetAce(pAcl, i, out var pAce); Assert.That(b, Is.True); var accountSize = 1024; var domainSize = 1024; var outuser = new StringBuilder(accountSize, accountSize); var outdomain = new StringBuilder(domainSize, domainSize); b = LookupAccountSid(null, pAce.GetSid(), outuser, ref accountSize, outdomain, ref domainSize, out _); Assert.That(b, Is.True); TestContext.WriteLine($"Ace{i}: {pAce.GetHeader().AceType}={outdomain}\\{outuser}; {pAce.GetMask()}"); } BuildTrusteeWithName(out var pTrustee, fun); Assert.That(GetEffectiveRightsFromAcl(pAcl, pTrustee, out var accessRights), Is.EqualTo(Win32Error.ERROR_NONE_MAPPED).Or.Zero); var map = new GENERIC_MAPPING((uint)Kernel32.FileAccess.FILE_GENERIC_READ, (uint)Kernel32.FileAccess.FILE_GENERIC_WRITE, (uint)Kernel32.FileAccess.FILE_GENERIC_EXECUTE, (uint)Kernel32.FileAccess.FILE_ALL_ACCESS); var ifArray = new SafeInheritedFromArray(hardAcl.AceCount); var err = GetInheritanceSource(fn, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, false, null, 0, pAcl, IntPtr.Zero, map, ifArray); Assert.That(err, Is.EqualTo(0)); TestContext.WriteLine($"{hardAcl.AceCount}: {string.Join("; ", ifArray.Results.Select(i => i.ToString()))}"); Assert.That(() => ifArray.Dispose(), Throws.Nothing); }
private static ACCESS_ALLOWED_ACE GetAce(IntPtr pSecurityDescriptor, string sid) { bool daclPresent; bool daclDefaulted; IntPtr pAcl = IntPtr.Zero; MSMQSecurity.GetSecurityDescriptorDacl(pSecurityDescriptor, out daclPresent, ref pAcl, out daclDefaulted); if (daclPresent) { ACL_SIZE_INFORMATION AclSize = new ACL_SIZE_INFORMATION(); MSMQSecurity.GetAclInformation(pAcl, ref AclSize, (uint)Marshal.SizeOf(typeof(ACL_SIZE_INFORMATION)), ACL_INFORMATION_CLASS.AclSizeInformation); for (int i = 0; i < AclSize.AceCount; i++) { IntPtr pAce; var err = MSMQSecurity.GetAce(pAcl, i, out pAce); ACCESS_ALLOWED_ACE ace = (ACCESS_ALLOWED_ACE)Marshal.PtrToStructure(pAce, typeof(ACCESS_ALLOWED_ACE)); IntPtr iter = (IntPtr)((long)pAce + (long)Marshal.OffsetOf(typeof(ACCESS_ALLOWED_ACE), "SidStart")); byte[] bSID = null; int size = (int)MSMQSecurity.GetLengthSid(iter); bSID = new byte[size]; Marshal.Copy(iter, bSID, 0, size); IntPtr ptrSid; MSMQSecurity.ConvertSidToStringSid(bSID, out ptrSid); string strSID = Marshal.PtrToStringAuto(ptrSid); if (strSID == sid) { return ace; } } throw new Exception(string.Format("No ACE for SID {0} found in security descriptor", sid)); } else { throw new Exception("No DACL found for security descriptor"); } }
public void GetAceTest(bool validUser, bool validCred, string urn, string dn, string dc, string domain, string username, string password, string notes) { var fun = $"{domain}\\{username}"; var pSD = GetSD(fn); var b = GetSecurityDescriptorDacl(pSD, out bool daclPresent, out IntPtr pAcl, out bool defaulted); Assert.That(b, Is.True); Assert.That(daclPresent, Is.True); Assert.That(pAcl, Is.Not.EqualTo(IntPtr.Zero)); var hardAcl = pAcl.ToStructure <ACL>(); var ari = new ACL_REVISION_INFORMATION(); b = GetAclInformation(pAcl, ref ari, (uint)Marshal.SizeOf(typeof(ACL_REVISION_INFORMATION)), ACL_INFORMATION_CLASS.AclRevisionInformation); Assert.That(b, Is.True); Assert.That(ari.AclRevision, Is.EqualTo(hardAcl.AclRevision)); var asi = new ACL_SIZE_INFORMATION(); b = GetAclInformation(pAcl, ref asi, (uint)Marshal.SizeOf(typeof(ACL_SIZE_INFORMATION)), ACL_INFORMATION_CLASS.AclSizeInformation); Assert.That(b, Is.True); Assert.That(asi.AceCount, Is.GreaterThan(0)); Assert.That(asi.AceCount, Is.EqualTo(hardAcl.AceCount)); b = GetAce(pAcl, 0, out IntPtr pAce); Assert.That(b, Is.True); var accessRights = 0U; var pTrustee = new TRUSTEE(fun); Assert.That(GetEffectiveRightsFromAcl(pAcl, pTrustee, ref accessRights), Is.EqualTo(Win32Error.ERROR_NONE_MAPPED).Or.Zero); var map = new GENERIC_MAPPING((uint)Kernel32.FileAccess.FILE_GENERIC_READ, (uint)Kernel32.FileAccess.FILE_GENERIC_WRITE, (uint)Kernel32.FileAccess.FILE_GENERIC_EXECUTE, (uint)Kernel32.FileAccess.FILE_ALL_ACCESS); var ifArray = new SafeInheritedFromArray(hardAcl.AceCount); var err = GetInheritanceSource(fn, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, false, null, 0, pAcl, IntPtr.Zero, ref map, ifArray); Assert.That(err, Is.EqualTo(0)); TestContext.WriteLine($"{hardAcl.AceCount}: {string.Join("; ", ifArray.Results.Select(i => i.ToString()))}"); Assert.That(() => ifArray.Dispose(), Throws.Nothing); }
static extern bool GetAclInformation(IntPtr pAcl, ref ACL_SIZE_INFORMATION pAclInformation, uint nAclInformationLength, ACL_INFORMATION_CLASS dwAclInformationClass);
bool CreateKeyDescriptor(IntPtr pOldSD, ACCOUNT_PERM Account, ref MEM_DATA MemData) { // reconstruct security descriptor bool bDefault = false; bool bPresent = false; int iControlBits = 0; int iControlSet = 0; int iDomain = 0; int iFlag = 0; int iLength = 0; int iRevision = 0; int iSidLen = 0; int iTotal = 0; int iUse = 0; StringBuilder sDomain = new StringBuilder(256); IntPtr pNewACL = IntPtr.Zero; IntPtr pAcl = IntPtr.Zero; IntPtr pSid = IntPtr.Zero; IntPtr pPnt = IntPtr.Zero; ACL_SIZE_INFORMATION tAclSize = new ACL_SIZE_INFORMATION(); ACL tTempACL = new ACL(); ACE tTempAce = new ACE(); try { MemData.pAcl = IntPtr.Zero; MemData.pSd = IntPtr.Zero; // get size pSid = LocalAlloc(LMEM_INITIALIZED, SECURITY_DESCRIPTOR_MIN_LENGTH); if (pSid == IntPtr.Zero) { return false; } // store pointer MemData.pSd = pSid; // init descriptor if (InitializeSecurityDescriptor(pSid, SECURITY_DESCRIPTOR_REVISION) == 0) { return false; } // check for existing sd if (pOldSD != IntPtr.Zero) { if (GetSecurityDescriptorDacl(pOldSD, out bPresent, ref pAcl, out bDefault) == true) { // extract dacl if ((bPresent == true) && (pAcl != IntPtr.Zero)) { if (GetAclInformation(pAcl, ref tAclSize, Marshal.SizeOf(tAclSize), ACL_INFORMATION_CLASS.AclSizeInformation) == false) { return false; } else { iTotal = tAclSize.AclBytesInUse; } } else { iTotal = Marshal.SizeOf(tTempACL); } } else { return false; } } // allocate sid // // get callers sid if (Account.pSid == IntPtr.Zero) { iDomain = 256; // get size LookupAccountName(null, Account.AccountName, IntPtr.Zero, ref iSidLen, sDomain, ref iDomain, out iUse); Account.pSid = LocalAlloc(LMEM_INITIALIZED, iSidLen); if (Account.pSid == IntPtr.Zero) { return false; } // get the sid if (LookupAccountName(null, Account.AccountName, Account.pSid, ref iSidLen, sDomain, ref iDomain, out iUse) == false) { return false; } } // ace buffer iLength = (Marshal.SizeOf(tTempAce) + GetLengthSid(Account.pSid)) - 4; iTotal += iLength; pNewACL = LocalAlloc(LMEM_INITIALIZED, iTotal); if (pNewACL == IntPtr.Zero) { return false; } // store pointer MemData.pAcl = pNewACL; // init acl if (InitializeAcl(pNewACL, iTotal, ACL_REVISION) == false) { return false; } // build dacl in sequence if (Account.AceType == ACCESS_DENIED_ACE_TYPE) { if (BuildACE(pNewACL, Account.AceType, Account.AceFlags, Account.AccessMask, Account.pSid) == false) { return false; } } // copy non-inherited ace if ((bPresent == true) && (pAcl != IntPtr.Zero) && (tAclSize.AceCount > 0)) { // combine old and new ACE entries for (int count = 0; count < tAclSize.AceCount; count++) { // next ace GetAce(pAcl, count, out pPnt); if (pPnt == IntPtr.Zero) { return false; } RtlMoveMemory(ref tTempAce, pPnt, Marshal.SizeOf(tTempAce)); // exit on inherited ace if (((int)tTempAce.Header.AceFlags & INHERITED_ACE) == INHERITED_ACE) { break; } int x = (int)pPnt + 8; IntPtr pPt = new IntPtr(x); // check ace value if (!SidIsEqual(Account.pSid, pPt)) { // add ace AddAce(pNewACL, ACL_REVISION, MAXDWORD, pPnt, tTempAce.Header.AceSize); } } } // add explicit permit if (Account.AceType == ACCESS_ALLOWED_ACE_TYPE) { BuildACE(pNewACL, Account.AceType, Account.AceFlags, Account.AccessMask, Account.pSid); } // enties with inheritence flag if ((bPresent == true) && (pAcl != IntPtr.Zero) && (tAclSize.AceCount > 0)) { for (int count = 0; count < tAclSize.AceCount; count++) { GetAce(pAcl, count, out pPnt); RtlMoveMemory(ref tTempAce, pPnt, Marshal.SizeOf(tTempAce)); AddAce(pNewACL, ACL_REVISION, MAXDWORD, pPnt, tTempAce.Header.AceSize); } } // descriptor flags if (pOldSD != IntPtr.Zero) { if (GetSecurityDescriptorControl(pOldSD, out iFlag, out iRevision) != 0) { if ((iFlag & SE_DACL_AUTO_INHERITED) == SE_DACL_AUTO_INHERITED) { iControlBits = SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED; iControlSet = iControlBits; } else if ((iFlag & SE_DACL_PROTECTED) == SE_DACL_PROTECTED) { iControlBits = SE_DACL_PROTECTED; iControlSet = iControlBits; } if (iControlSet != 0) { SetSecurityDescriptorControl(pSid, iControlBits, iControlSet); } } } // add dacl return SetSecurityDescriptorDacl(pSid, 1, pNewACL, 0); } finally { if (Account.pSid != IntPtr.Zero) { LocalFree(Account.pSid); Account.pSid = IntPtr.Zero; } } }
static extern bool GetAclInformation(IntPtr pAcl, ref ACL_SIZE_INFORMATION pAclInformation, int nAclInformationLength, ACL_INFORMATION_CLASS dwAclInformationClass);
static void Main(string[] args) { IntPtr bufptr = IntPtr.Zero; int err = NetShareGetInfo("ServerName", "ShareName", 502, out bufptr); if (0 == err) { SHARE_INFO_502 shareInfo = (SHARE_INFO_502)Marshal.PtrToStructure(bufptr, typeof(SHARE_INFO_502)); bool bDaclPresent; bool bDaclDefaulted; IntPtr pAcl = IntPtr.Zero; GetSecurityDescriptorDacl(shareInfo.shi502_security_descriptor, out bDaclPresent, ref pAcl, out bDaclDefaulted); if (bDaclPresent) { ACL_SIZE_INFORMATION AclSize = new ACL_SIZE_INFORMATION(); GetAclInformation(pAcl, ref AclSize, (uint)Marshal.SizeOf(typeof(ACL_SIZE_INFORMATION)), ACL_INFORMATION_CLASS.AclSizeInformation); for (int i = 0; i < AclSize.AceCount; i++) { IntPtr pAce; err = GetAce(pAcl, i, out pAce); ACCESS_ALLOWED_ACE ace = (ACCESS_ALLOWED_ACE)Marshal.PtrToStructure(pAce, typeof(ACCESS_ALLOWED_ACE)); IntPtr iter = (IntPtr)((long)pAce + (long)Marshal.OffsetOf(typeof(ACCESS_ALLOWED_ACE), "SidStart")); byte[] bSID = null; int size = (int)GetLengthSid(iter); bSID = new byte[size]; Marshal.Copy(iter, bSID, 0, size); IntPtr ptrSid; ConvertSidToStringSid(bSID, out ptrSid); string strSID = Marshal.PtrToStringAuto(ptrSid); Console.WriteLine("The details of ACE number {0} are: ", i + 1); StringBuilder name = new StringBuilder(); uint cchName = (uint)name.Capacity; StringBuilder referencedDomainName = new StringBuilder(); uint cchReferencedDomainName = (uint)referencedDomainName.Capacity; SID_NAME_USE sidUse; LookupAccountSid(null, bSID, name, ref cchName, referencedDomainName, ref cchReferencedDomainName, out sidUse); Console.WriteLine("Trustee Name: " + name); Console.WriteLine("Domain Name: " + referencedDomainName); if ((ace.Mask & 0x1F01FF) == 0x1F01FF) { Console.WriteLine("Permission: Full Control"); } else if ((ace.Mask & 0x1301BF) == 0x1301BF) { Console.WriteLine("Permission: READ and CHANGE"); } else if ((ace.Mask & 0x1200A9) == 0x1200A9) { Console.WriteLine("Permission: READ only"); } Console.WriteLine("SID: {0} \nHeader AceType: {1} \nAccess Mask: {2} \nHeader AceFlag: {3}", strSID, ace.Header.AceType.ToString(), ace.Mask.ToString(), ace.Header.AceFlags.ToString()); Console.WriteLine("\n"); } } err = NetApiBufferFree(bufptr); } }
protected unsafe static extern int GetAclInformation( ACL *pAcl, out ACL_SIZE_INFORMATION pAclInformation, uint nAclInformationLength, ACL_INFORMATION_CLASS dwAclInformationClass);
static ACCESS_ALLOWED_ACE GetAce(IntPtr pDacl, string sid) { var AclSize = new ACL_SIZE_INFORMATION(); GetAclInformation(pDacl, ref AclSize, (uint) Marshal.SizeOf(typeof(ACL_SIZE_INFORMATION)), ACL_INFORMATION_CLASS.AclSizeInformation); for (var i = 0; i < AclSize.AceCount; i++) { IntPtr pAce; GetAce(pDacl, i, out pAce); var ace = (ACCESS_ALLOWED_ACE) Marshal.PtrToStructure(pAce, typeof(ACCESS_ALLOWED_ACE)); var iter = (IntPtr) ((long) pAce + (long) Marshal.OffsetOf(typeof(ACCESS_ALLOWED_ACE), "SidStart")); var size = GetLengthSid(iter); var bSID = new byte[size]; Marshal.Copy(iter, bSID, 0, size); IntPtr ptrSid; ConvertSidToStringSid(bSID, out ptrSid); var strSID = Marshal.PtrToStringAuto(ptrSid); if (strSID == sid) { return ace; } } throw new Exception($"No ACE for SID {sid} found in security descriptor"); }
// ACLQueue: // - Local System - Full Control // - Administrators - Full Control internal unsafe static bool ACLQueue(string messageQueue) { messageQueue = @messageQueue; ACL_SIZE_INFORMATION si = new ACL_SIZE_INFORMATION(); uint size = (uint)sizeof(ACL_SIZE_INFORMATION); uint cb = si.AclBytesInUse + _maxVersion2AceSize; // Files and Folders inherit all ACE's uint grfInherit = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; SID * pAdminSID = null; SID * pSystemSID = null; ACL * pdacl = null; void *pSD = null; try { SID_IDENTIFIER_AUTHORITY SIDAuthNT = new SID_IDENTIFIER_AUTHORITY(); // Defined in winnt.h (&SIDAuthNT.Value_6)[0] = 0; (&SIDAuthNT.Value_6)[1] = 0; (&SIDAuthNT.Value_6)[2] = 0; (&SIDAuthNT.Value_6)[3] = 0; (&SIDAuthNT.Value_6)[4] = 0; (&SIDAuthNT.Value_6)[5] = 5; uint SECURITY_BUILTIN_DOMAIN_RID = 0x00000020; //defined in winnt.h uint DOMAIN_ALIAS_RID_ADMINS = 0x00000220; // defined in winnt.h uint SECURITY_LOCAL_SYSTEM_RID = 0x00000012; // defined in winnt.h ACL *pdaclNew = (ACL *)LocalAlloc(0, cb); InitializeAcl(ref (*pdaclNew), cb, ACL_REVISION); // Administrators Full Control if (AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, out pAdminSID)) { if (IsValidSid(pAdminSID)) { if (!AddAccessAllowedAceEx(pdaclNew, ACL_REVISION, grfInherit, MQSEC_QUEUE_GENERIC_ALL, pAdminSID)) { throw new Exception(); } } } // Local System Full Control if (AllocateAndInitializeSid(&SIDAuthNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, out pSystemSID)) { if (IsValidSid(pSystemSID)) { if (!AddAccessAllowedAceEx(pdaclNew, ACL_REVISION, grfInherit, MQSEC_QUEUE_GENERIC_ALL, pSystemSID)) { throw new Exception(); } } } pSD = (void *)LocalAlloc(0, 200); if (!InitializeSecurityDescriptor(pSD, 1)) { throw new Exception(); } if (!SetSecurityDescriptorDacl(pSD, true, pdaclNew, false)) { throw new Exception(); } if (!IsValidSecurityDescriptor(pSD)) { throw new Exception(); } MessageQueue mq = new MessageQueue(messageQueue); if (MQSetQueueSecurity(mq.FormatName, DACL_SECURITY_INFORMATION, pSD) != 0) { throw new Exception(); } } catch { return(false); } finally { if (pSD != null) { LocalFree(pSD); } if (pdacl != null) { LocalFree(pdacl); } if (pAdminSID != null) { LocalFree(pAdminSID); } if (pSystemSID != null) { LocalFree(pSystemSID); } } return(true); }