Implement SemaphoreSecurity.
authorJames Bellinger <jfb@zer7.com>
Sun, 8 Jul 2012 11:46:43 +0000 (07:46 -0400)
committerJames Bellinger <jfb@zer7.com>
Sun, 8 Jul 2012 19:13:51 +0000 (15:13 -0400)
mcs/class/System/System.Security.AccessControl/SemaphoreSecurity.cs
mcs/class/System/System.Threading/Semaphore.cs
mcs/class/System/System_test.dll.sources
mcs/class/System/Test/System.Security.AccessControl/SemaphoreSecurityTest.cs [new file with mode: 0644]

index b344a8d9f3b3ce9f8c9c75eff14a8f8f58a882df..7cbd008a45e916afef59b58ceb001f7d98a63bdd 100644 (file)
@@ -47,6 +47,11 @@ namespace System.Security.AccessControl
                {
                }
                
+               internal SemaphoreSecurity (SafeHandle handle, AccessControlSections includeSections)
+                       : base (false, ResourceType.KernelObject, handle, includeSections)
+               {
+               }
+               
                public override Type AccessRightType {
                        get { return typeof (SemaphoreRights); }
                }
@@ -127,6 +132,19 @@ namespace System.Security.AccessControl
                {
                        SetAuditRule((AuditRule)rule);
                }
+               
+               internal void PersistModifications (SafeHandle handle)
+               {
+                       WriteLock();
+                       try {
+                               Persist (handle, (AccessRulesModified ? AccessControlSections.Access : 0) |
+                                                (AuditRulesModified  ? AccessControlSections.Audit  : 0) |
+                                                (OwnerModified       ? AccessControlSections.Owner  : 0) |
+                                                (GroupModified       ? AccessControlSections.Group  : 0), null);
+                       } finally {
+                               WriteUnlock ();
+                       }
+               }
        }
 }
 
index d39cb280b427d50ce71de533f36f4e88814521f9..1e197fca87f8748426320a7f95071e0776f486fb 100644 (file)
@@ -80,7 +80,7 @@ namespace System.Threading {
                {
                }
 
-               [MonoTODO ("Does not support access control, semaphoreSecurity is ignored")]
+               [MonoTODO ("CreateSemaphore_internal does not support access control, semaphoreSecurity is ignored")]
                public Semaphore (int initialCount, int maximumCount, string name, out bool createdNew, 
                        SemaphoreSecurity semaphoreSecurity)
                {
@@ -96,10 +96,12 @@ namespace System.Threading {
                                                           out createdNew);
                }
 
-               [MonoTODO]
                public SemaphoreSecurity GetAccessControl ()
                {
-                       throw new NotImplementedException ();
+                       return new SemaphoreSecurity (SafeWaitHandle,
+                                                     AccessControlSections.Owner |
+                                                     AccessControlSections.Group |
+                                                     AccessControlSections.Access);
                }
 
                [PrePrepareMethod]
@@ -128,13 +130,12 @@ namespace System.Threading {
                        return (ret);
                }
 
-               [MonoTODO]
                public void SetAccessControl (SemaphoreSecurity semaphoreSecurity)
                {
                        if (semaphoreSecurity == null)
                                throw new ArgumentNullException ("semaphoreSecurity");
-
-                       throw new NotImplementedException ();
+                               
+                       semaphoreSecurity.PersistModifications (SafeWaitHandle);
                }
 
                // static methods
index d71cdcf5992c7845c189ee4336881ded5d4cc33d..994b2d01890665ba812128e00946b2b236636da9 100644 (file)
@@ -268,6 +268,7 @@ System.Net.Mime/ContentTypeTest.cs
 System.Net.NetworkInformation/PhysicalAddressTest.cs
 System.Net.Security/SslStreamTest.cs
 System.Runtime.Versioning/FrameworkNameTest.cs
+System.Security.AccessControl/SemaphoreSecurityTest.cs
 System.Security.Cryptography/AsnEncodedDataTest.cs
 System.Security.Cryptography/OidCollectionTest.cs
 System.Security.Cryptography/OidEnumeratorTest.cs
diff --git a/mcs/class/System/Test/System.Security.AccessControl/SemaphoreSecurityTest.cs b/mcs/class/System/Test/System.Security.AccessControl/SemaphoreSecurityTest.cs
new file mode 100644 (file)
index 0000000..1c8a999
--- /dev/null
@@ -0,0 +1,66 @@
+// SemaphoreSecurityTest.cs - NUnit Test Cases for SemaphoreSecurity
+//
+// Authors:
+//     James Bellinger  <jfb@zer7.com>
+//
+// Copyright (C) 2012 James Bellinger
+
+using System;
+using System.Collections.Generic;
+using System.Security.AccessControl;
+using System.Security.Principal;
+using System.Threading;
+using NUnit.Framework;
+
+namespace MonoTests.System.Security.AccessControl
+{
+       [TestFixture]
+       public class SemaphoreSecurityTest
+       {
+               // TODO: Mono System.Threading.Semaphore does not throw exceptions on failure (except in OpenExisting).
+               [Test, ExpectedExceptionAttribute (typeof (UnauthorizedAccessException))]
+               public void PermissionsActuallyWork ()
+               {
+                       if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
+                               Assert.Ignore (); return;
+                       }
+
+                       bool createdNew; SemaphoreSecurity security;
+                       string name = @"Local\MonoTestSemaphore";
+
+                       using (Semaphore semaphore = new Semaphore (1, 1, name, out createdNew)) {
+                               Assert.IsFalse (semaphore.SafeWaitHandle.IsInvalid);
+                               Assert.IsTrue (createdNew);
+
+                               // Make sure our later error will be due to permissions and not some sharing bug.
+                               bool createdAnotherNew;
+                               using (Semaphore anotherSemaphore = new Semaphore (1, 1, name, out createdAnotherNew)) {
+                                       Assert.IsFalse (anotherSemaphore.SafeWaitHandle.IsInvalid);
+                                       Assert.IsFalse (createdAnotherNew);
+                               }
+
+                               // Let's make a deny all.
+                               security = semaphore.GetAccessControl ();
+
+                               foreach (SemaphoreAccessRule rule in security.GetAccessRules
+                                        (true, false, typeof (SecurityIdentifier))) {
+                                       security.RemoveAccessRuleSpecific (rule);
+                               }
+
+                               Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
+                               semaphore.SetAccessControl (security);
+
+                               security = semaphore.GetAccessControl ();
+                               Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
+
+                               // MS.NET will throw on the first line below.
+                               // For Mono testing the latter verifies the rest until the Semaphore bug is fixed.
+                               // Also, NUnit 2.4 appears to lacks Assert.Pass ().
+                               Semaphore badSemaphore = new Semaphore (1, 1, name);
+                               if (badSemaphore.SafeWaitHandle.IsInvalid)
+                                       throw new UnauthorizedAccessException ();
+                       }
+               }
+       }
+}
+