public void EmptyBinaryFormDSOK() { DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0); byte[] buffer = new byte[8]; dacl.GetBinaryForm (buffer, 0); Assert.AreEqual (4, buffer [0]); // Revision Assert.AreEqual (8, ToUInt16 (buffer, 2)); // ACL Size Assert.AreEqual (0, ToUInt16 (buffer, 4)); // ACE Count }
public void BinaryRoundtrip () { RawAcl acl = GetRemovesMeaninglessAcesAcl (); DiscretionaryAcl dacl1 = new DiscretionaryAcl (false, false, acl); byte[] binaryForm1 = new byte[dacl1.BinaryLength]; dacl1.GetBinaryForm (binaryForm1, 0); DiscretionaryAcl dacl2 = new DiscretionaryAcl (false, false, new RawAcl (binaryForm1, 0)); byte[] binaryForm2 = new byte[dacl2.BinaryLength]; dacl2.GetBinaryForm (binaryForm2, 0); Assert.AreEqual (binaryForm1.Length, binaryForm2.Length); for (int i = 0; i < binaryForm1.Length; i ++) Assert.AreEqual (binaryForm1 [i], binaryForm2 [i]); }
public static bool SetAcl(this ServiceController controller, Action<DiscretionaryAcl> fn) { // from http://pinvoke.net/default.aspx/advapi32/QueryServiceObjectSecurity.html (thx!) using (SafeHandle handle = controller.ServiceHandle) { var psd = new byte[0]; uint bufSizeNeeded; bool success = QueryServiceObjectSecurity(handle, SecurityInfos.DiscretionaryAcl, psd, 0, out bufSizeNeeded); if (!success) { int error = Marshal.GetLastWin32Error(); if (error == ErrorInsufficientBuffer) { psd = new byte[bufSizeNeeded]; success = QueryServiceObjectSecurity(handle, SecurityInfos.DiscretionaryAcl, psd, bufSizeNeeded, out bufSizeNeeded); } else { return false; } } if (!success) { return false; } // get security descriptor via raw into DACL form so ACE // ordering checks are done for us. var rsd = new RawSecurityDescriptor(psd, 0); var dacl = new DiscretionaryAcl(false, false, rsd.DiscretionaryAcl); fn(dacl); // convert discretionary ACL back to raw form; looks like via byte[] is only way var rawdacl = new byte[dacl.BinaryLength]; dacl.GetBinaryForm(rawdacl, 0); rsd.DiscretionaryAcl = new RawAcl(rawdacl, 0); // set raw security descriptor on service again var rawsd = new byte[rsd.BinaryLength]; rsd.GetBinaryForm(rawsd, 0); success = SetServiceObjectSecurity(handle, SecurityInfos.DiscretionaryAcl, rawsd); return success; } }
internal static void EnsureServiceAclsCorrect() { var psd = new byte[0]; uint bufSizeNeeded; var ok = Advapi32.QueryServiceObjectSecurity(Controller.Value.ServiceHandle, SecurityInfos.DiscretionaryAcl, psd, 0, out bufSizeNeeded); if (!ok) { int err = Marshal.GetLastWin32Error(); if (err == 122) { // ERROR_INSUFFICIENT_BUFFER // expected; now we know bufsize psd = new byte[bufSizeNeeded]; ok = Advapi32.QueryServiceObjectSecurity( Controller.Value.ServiceHandle, SecurityInfos.DiscretionaryAcl, psd, bufSizeNeeded, out bufSizeNeeded); } else { throw new ApplicationException("error calling QueryServiceObjectSecurity() to get DACL for Service: error code=" + err); } } if (!ok) { throw new ApplicationException("error calling QueryServiceObjectSecurity(2) to get DACL for Service: error code=" + Marshal.GetLastWin32Error()); } // get security descriptor via raw into DACL form so ACE // ordering checks are done for us. var rsd = new RawSecurityDescriptor(psd, 0); var dacl = new DiscretionaryAcl(false, false, rsd.DiscretionaryAcl); dacl.AddAccess(AccessControlType.Allow, new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), (int)ServiceAccess.ServiceCoapp, InheritanceFlags.None, PropagationFlags.None); // convert discretionary ACL back to raw form; looks like via byte[] is only way var rawdacl = new byte[dacl.BinaryLength]; dacl.GetBinaryForm(rawdacl, 0); rsd.DiscretionaryAcl = new RawAcl(rawdacl, 0); // set raw security descriptor on service again var rawsd = new byte[rsd.BinaryLength]; rsd.GetBinaryForm(rawsd, 0); ok = Advapi32.SetServiceObjectSecurity(Controller.Value.ServiceHandle, SecurityInfos.DiscretionaryAcl, rawsd); if (!ok) { throw new ApplicationException("error calling SetServiceObjectSecurity(); error code=" + Marshal.GetLastWin32Error()); } }