// FUNCTION: GetPrinterDACL // // PURPOSE: Obtains DACL from specified printer // // RETURN VALUE: true or false // // COMMENTS: unsafe static bool GetPrinterDACL(string szPrinterName, out SafePACL ppACL) { ppACL = default; if (!OpenPrinter(szPrinterName, out var hPrinter, new PRINTER_DEFAULTS { DesiredAccess = ACCESS_MASK.READ_CONTROL })) { return(false); } using (hPrinter) { // Call GetPrinter twice to get size of printer info structure. var PrnInfo3 = GetPrinter <PRINTER_INFO_3>(hPrinter); if (!GetSecurityDescriptorDacl(PrnInfo3.pSecurityDescriptor, out var bDaclPres, out var pACL, out var bDef)) { return(false); } ppACL = new SafePACL(pACL); } return(true); }
public void AddResourceAttributeAceTest() { using (var pNewSacl = new SafePACL(256)) { using (var capId = new SafePSID("S-1-17-22")) Assert.That(AddScopedPolicyIDAce(pNewSacl, ACL_REVISION, 0, 0, capId), ResultIs.Successful); var attrValues = new[] { 12L, 32L }; using (var pattrValues = SafeHGlobalHandle.CreateFromList(attrValues)) { var csattr = new CLAIM_SECURITY_ATTRIBUTE_V1 { Name = "Int", ValueType = CLAIM_SECURITY_ATTRIBUTE_TYPE.CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64, ValueCount = (uint)attrValues.Length, Values = new CLAIM_SECURITY_ATTRIBUTE_V1.VALUESUNION { pInt64 = (IntPtr)pattrValues } }; var attr = new[] { csattr }; using (var pattr = SafeHGlobalHandle.CreateFromList(attr)) { var csi = CLAIM_SECURITY_ATTRIBUTES_INFORMATION.Default; csi.AttributeCount = (uint)attr.Length; csi.Attribute.pAttributeV1 = (IntPtr)pattr; var len = 0U; Assert.That(AddResourceAttributeAce(pNewSacl, ACL_REVISION, 0, 0, SafePSID.Everyone, csi, ref len), ResultIs.Successful); } } } }
// FUNCTION: AddAccessRights // // PURPOSE: Applies ACE for access to specified object DACL // // RETURN VALUE: true or false // // COMMENTS: unsafe static bool AddAccessRights(string szPrinterName, uint dwAccessMask, AceFlags bAceFlags, string szUserName, byte bType) { // ACL variables ACL_SIZE_INFORMATION?AclInfo = null; uint dwNewAceCount = 0; // New ACL variables int dwNewACLSize; // Temporary ACE ACCESS_ALLOWED_ACE *pTempAce; // structure is same for access denied ace uint CurrentAceIndex; try { // Call LookupAccountName if (!LookupAccountName(null, szUserName, out var pSid, out var szDomainName, out var SidType)) { Console.WriteLine("Error {0} - LookupAccountName", Win32Error.GetLastError()); return(false); } Console.Write("Adding ACE for {0}\n", szUserName); // Get security DACL for printer if (!GetPrinterDACL(szPrinterName, out var pACL)) { Console.Write("Error {0} getting printer DACL\n", Win32Error.GetLastError()); return(false); } // Compute size needed for the new ACL using (pACL) { if (!pACL.IsInvalid) // Get size of old ACL { AclInfo = ((PACL)pACL).GetAclInformation <ACL_SIZE_INFORMATION>(); } if (!pACL.IsInvalid) // Add room for new ACEs { dwNewACLSize = (int)AclInfo.Value.AclBytesInUse + Marshal.SizeOf(typeof(ACCESS_ALLOWED_ACE)) + GetLengthSid(pSid) - sizeof(uint); } else { dwNewACLSize = Marshal.SizeOf(typeof(ACCESS_ALLOWED_ACE)) + Marshal.SizeOf(typeof(ACL)) + GetLengthSid(pSid) - sizeof(uint); } } // Allocate and setup ACL. using var pNewACL = new SafePACL(dwNewACLSize); if (pNewACL.IsInvalid) { Console.Write("LocalAlloc failed.\n"); throw new Exception(); } // If new ACE is Access Denied ACE add it to front of new ACL if (bType == ACCESS_DENY) { // Add the access-denied ACE to the new DACL if (!AddAccessDeniedAce(pNewACL, 2, dwAccessMask, pSid)) { Console.Write("Error %d: AddAccessDeniedAce\n", Win32Error.GetLastError()); throw new Exception(); } dwNewAceCount++; // get pointer to ace we just added, so we can change the AceFlags if (!GetAce(pNewACL, 0, out var mTempAce)) { Console.Write("Error %d: GetAce\n", Win32Error.GetLastError()); throw new Exception(); } pTempAce = (ACCESS_ALLOWED_ACE *)(void *)mTempAce.DangerousGetHandle(); pTempAce->Header.AceFlags = bAceFlags; } // If a DACL was present, copy the resident ACEs to the new DACL if (!pACL.IsInvalid) { // Copy the file's old ACEs to our new ACL if (AclInfo.Value.AceCount > 0) { for (CurrentAceIndex = 0; CurrentAceIndex < AclInfo.Value.AceCount; CurrentAceIndex++) { // Get an ACE if (!GetAce(pACL, CurrentAceIndex, out var mTempAce)) { Console.Write("Error %d: GetAce\n", Win32Error.GetLastError()); throw new Exception(); } pTempAce = (ACCESS_ALLOWED_ACE *)(void *)mTempAce.DangerousGetHandle(); // Check to see if this ACE is identical to one were adding. If it is identical don't copy it over. if (!EqualSid((IntPtr)(void *)&(pTempAce->SidStart), pSid) || (pTempAce->Mask != dwAccessMask) || (pTempAce->Header.AceFlags != bAceFlags)) { // ACE is distinct, add it to the new ACL if (!AddAce(pNewACL, 2, uint.MaxValue, (IntPtr)pTempAce, ((ACE_HEADER *)pTempAce)->AceSize)) { Console.Write("Error %d: AddAce\n", Win32Error.GetLastError()); throw new Exception(); } dwNewAceCount++; } } } } // If the new ACE is an Access allowed ACE add it at the end. if (bType == ACCESS_ALLOW) { // Add the access-allowed ACE to the new DACL if (!AddAccessAllowedAce(pNewACL, 2, dwAccessMask, pSid)) { Console.Write("Error %d: AddAccessAllowedAce\n", Win32Error.GetLastError()); throw new Exception(); } // Get pointer to ACE we just added, so we can change the AceFlags if (!GetAce(pNewACL, dwNewAceCount, // Zero based position of the last ace out var mTempAce)) { Console.Write("Error %d: GetAce\n", Win32Error.GetLastError()); throw new Exception(); } pTempAce = (ACCESS_ALLOWED_ACE *)(void *)mTempAce.DangerousGetHandle(); pTempAce->Header.AceFlags = bAceFlags; } // Set the DACL to the object if (!SetPrinterDACL(szPrinterName, pNewACL)) { Console.Write("Error %d setting printer DACL\n", Win32Error.GetLastError()); throw new Exception(); } } finally { } return(true); }