added NET_2_0 strongly typed overrides
[mono.git] / mcs / class / corlib / System.Security.Principal / WindowsPrincipal.cs
old mode 100755 (executable)
new mode 100644 (file)
index b74206a..e6f2b86
@@ -2,19 +2,49 @@
 // WindowsPrincipal.cs: Windows IPrincipal implementation
 //
 // Author:
-//     Sebastien Pouliot (spouliot@motus.com)
+//     Sebastien Pouliot (sebastien@ximian.com)
 //
 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
+using System.Collections;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 
 namespace System.Security.Principal {
 
        [Serializable]
+#if NET_2_0
+       [ComVisible (true)]
+#endif
        public class WindowsPrincipal : IPrincipal {
 
                private WindowsIdentity _identity;
+               // http://groups.google.ca/groups?q=WindowsPrincipal+m_roles&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=OghXf4OgCHA.4228%40tkmsftngp08&rnum=4
+               private string [] m_roles;
+
+               // case sensitivity versus number of groups
+               // http://groups.google.ca/groups?q=WindowsPrincipal+m_roles&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=%23JEMHsMQCHA.1916%40tkmsftngp13&rnum=5
 
                public WindowsPrincipal (WindowsIdentity ntIdentity)
                {
@@ -32,26 +62,122 @@ namespace System.Security.Principal {
 
                // methods
 
-               [MonoTODO]
                public virtual bool IsInRole (int rid) 
                {
-                       throw new NotImplementedException ();
+                       if (IsPosix) {
+                               return IsMemberOfGroupId (Token, (IntPtr) rid);
+                       }
+                       else {
+                               string role = null;
+                               switch (rid) {
+                                       case 544: // Administrator
+                                               role = "BUILTIN\\Administrators";
+                                               break;
+                                       case 545: // User
+                                               role = "BUILTIN\\Users";
+                                               break;
+                                       case 546: // Guest
+                                               role = "BUILTIN\\Guests";
+                                               break;
+                                       case 547: // PowerUser
+                                               role = "BUILTIN\\Power Users";
+                                               break;
+                                       case 548: // AccountOperator
+                                               role = "BUILTIN\\Account Operators";
+                                               break;
+                                       case 549: // SystemOperator
+                                               role = "BUILTIN\\System Operators";
+                                               break;
+                                       case 550: // PrintOperator
+                                               role = "BUILTIN\\Print Operators";
+                                               break;
+                                       case 551: // BackupOperator
+                                               role = "BUILTIN\\Backup Operators";
+                                               break;
+                                       case 552: // Replicator
+                                               role = "BUILTIN\\Replicator";
+                                               break;
+                                       default:
+                                               return false;
+                               }
+                               return IsInRole (role);
+                       }
                }
 
-               [MonoTODO]
                public virtual bool IsInRole (string role)
                {
+                       if (role == null)
+                               return false;   // ArgumentNullException
+
+                       if (IsPosix) {
+                               // note: Posix is always case-sensitive
+                               return IsMemberOfGroupName (Token, role);
+                       }
+                       else {
+                               // Windows specific code that
+                               // (a) build the role cache like the MS framework (for compatibility)
+                               // (b) case sensitive (for Fx 1.0) and case insensitive (later Fx)
+                               if (m_roles == null) {
+                                       m_roles = WindowsIdentity._GetRoles (Token);
+                               }
+#if !NET_1_0
+                               role = role.ToUpperInvariant ();
+#endif
+                               foreach (string check in m_roles) {
 #if NET_1_0
-                       // case sensitive (for 1.0)
+                                       if (role == check)
+                                               return true;
 #else
-                       // case insensitive (for 1.1 and later)
+                                       if ((check != null) && (role == check.ToUpperInvariant ()))
+                                               return true;
 #endif
-                       throw new NotImplementedException ();
+                               }
+                               return false;
+                       }
                }
 
                public virtual bool IsInRole (WindowsBuiltInRole role)
                {
-                       return IsInRole ((int)role);
+                       if (IsPosix) {
+                               // right now we only map Administrator == root
+                               string group = null;
+                               switch (role) {
+                                       case WindowsBuiltInRole.Administrator:
+                                               group = "root";
+                                               break;
+                                       default:
+                                               return false;
+                               }
+                               return IsInRole (group);
+                       }
+                       else {
+                               return IsInRole ((int) role);
+                       }
                }
+#if NET_2_0
+               [MonoTODO ("not implemented")]
+               [ComVisible (false)]
+               public virtual bool IsInRole (SecurityIdentifier sid)
+               {
+                       throw new NotImplementedException ();
+               }
+#endif
+               private static bool IsPosix {
+                       get { return ((int) Environment.Platform == 128); }
+               }
+
+               private IntPtr Token {
+                       get { return (_identity as WindowsIdentity).Token; }
+               }
+
+               // see mono/mono/metadata/security.c for implementation
+
+               // note: never called by Win32 code (i.e. always return false)
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern static bool IsMemberOfGroupId (IntPtr user, IntPtr group);
+
+               // note: never called by Win32 code (i.e. always return false)
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern static bool IsMemberOfGroupName (IntPtr user, string group);
        }
 }