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