2005-08-02 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / corlib / System.Security.Principal / WindowsPrincipal.cs
1 //
2 // WindowsPrincipal.cs: Windows IPrincipal implementation
3 //
4 // Author:
5 //      Sebastien Pouliot (sebastien@ximian.com)
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System.Collections;
31 using System.Runtime.CompilerServices;
32 using System.Runtime.InteropServices;
33
34 namespace System.Security.Principal {
35
36         [Serializable]
37 #if NET_2_0
38         [ComVisible (true)]
39 #endif
40         public class WindowsPrincipal : IPrincipal {
41
42                 private WindowsIdentity _identity;
43                 // http://groups.google.ca/groups?q=WindowsPrincipal+m_roles&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=OghXf4OgCHA.4228%40tkmsftngp08&rnum=4
44                 private string [] m_roles;
45
46                 // case sensitivity versus number of groups
47                 // http://groups.google.ca/groups?q=WindowsPrincipal+m_roles&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=%23JEMHsMQCHA.1916%40tkmsftngp13&rnum=5
48
49                 public WindowsPrincipal (WindowsIdentity ntIdentity)
50                 {
51                         if (ntIdentity == null)
52                                 throw new ArgumentNullException ("ntIdentity");
53
54                         _identity = ntIdentity;
55                 }
56
57                 // properties
58
59                 public virtual IIdentity Identity {
60                         get { return _identity; }
61                 }
62
63                 // methods
64
65                 public virtual bool IsInRole (int rid) 
66                 {
67                         if (IsPosix) {
68                                 return IsMemberOfGroupId (Token, (IntPtr) rid);
69                         }
70                         else {
71                                 string role = null;
72                                 switch (rid) {
73                                         case 544: // Administrator
74                                                 role = "BUILTIN\\Administrators";
75                                                 break;
76                                         case 545: // User
77                                                 role = "BUILTIN\\Users";
78                                                 break;
79                                         case 546: // Guest
80                                                 role = "BUILTIN\\Guests";
81                                                 break;
82                                         case 547: // PowerUser
83                                                 role = "BUILTIN\\Power Users";
84                                                 break;
85                                         case 548: // AccountOperator
86                                                 role = "BUILTIN\\Account Operators";
87                                                 break;
88                                         case 549: // SystemOperator
89                                                 role = "BUILTIN\\System Operators";
90                                                 break;
91                                         case 550: // PrintOperator
92                                                 role = "BUILTIN\\Print Operators";
93                                                 break;
94                                         case 551: // BackupOperator
95                                                 role = "BUILTIN\\Backup Operators";
96                                                 break;
97                                         case 552: // Replicator
98                                                 role = "BUILTIN\\Replicator";
99                                                 break;
100                                         default:
101                                                 return false;
102                                 }
103                                 return IsInRole (role);
104                         }
105                 }
106
107                 public virtual bool IsInRole (string role)
108                 {
109                         if (role == null)
110                                 return false;   // ArgumentNullException
111
112                         if (IsPosix) {
113                                 // note: Posix is always case-sensitive
114                                 return IsMemberOfGroupName (Token, role);
115                         }
116                         else {
117                                 // Windows specific code that
118                                 // (a) build the role cache like the MS framework (for compatibility)
119                                 // (b) case sensitive (for Fx 1.0) and case insensitive (later Fx)
120                                 if (m_roles == null) {
121                                         m_roles = WindowsIdentity._GetRoles (Token);
122                                 }
123 #if !NET_1_0
124                                 role = role.ToUpperInvariant ();
125 #endif
126                                 foreach (string check in m_roles) {
127 #if NET_1_0
128                                         if (role == check)
129                                                 return true;
130 #else
131                                         if ((check != null) && (role == check.ToUpperInvariant ()))
132                                                 return true;
133 #endif
134                                 }
135                                 return false;
136                         }
137                 }
138
139                 public virtual bool IsInRole (WindowsBuiltInRole role)
140                 {
141                         if (IsPosix) {
142                                 // right now we only map Administrator == root
143                                 string group = null;
144                                 switch (role) {
145                                         case WindowsBuiltInRole.Administrator:
146                                                 group = "root";
147                                                 break;
148                                         default:
149                                                 return false;
150                                 }
151                                 return IsInRole (group);
152                         }
153                         else {
154                                 return IsInRole ((int) role);
155                         }
156                 }
157 #if NET_2_0
158                 [MonoTODO ("not implemented")]
159                 [ComVisible (false)]
160                 public virtual bool IsInRole (SecurityIdentifier sid)
161                 {
162                         throw new NotImplementedException ();
163                 }
164 #endif
165                 private static bool IsPosix {
166                         get { return ((int) Environment.Platform == 128); }
167                 }
168
169                 private IntPtr Token {
170                         get { return (_identity as WindowsIdentity).Token; }
171                 }
172
173                 // see mono/mono/metadata/security.c for implementation
174
175                 // note: never called by Win32 code (i.e. always return false)
176                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
177                 private extern static bool IsMemberOfGroupId (IntPtr user, IntPtr group);
178
179                 // note: never called by Win32 code (i.e. always return false)
180                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
181                 private extern static bool IsMemberOfGroupName (IntPtr user, string group);
182         }
183 }