2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / corlib / System.Security.Principal / WindowsIdentity.cs
blob26d4b84f6c5459a0c21dc0ee219294ba10b2cef6
1 //
2 // System.Security.Principal.WindowsIdentity
3 //
4 // Authors:
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 // Sebastien Pouliot (sebastien@ximian.com)
7 //
8 // (C) 2002 Ximian, Inc (http://www.ximian.com)
9 // Portions (C) 2003 Motus Technologies Inc. (http://www.motus.com)
10 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Runtime.CompilerServices;
33 using System.Runtime.InteropServices;
34 using System.Runtime.Serialization;
35 using System.Security.Permissions;
37 namespace System.Security.Principal {
39 [Serializable]
40 [ComVisible (true)]
41 public class WindowsIdentity : IIdentity, IDeserializationCallback, ISerializable, IDisposable {
42 private IntPtr _token;
43 private string _type;
44 private WindowsAccountType _account;
45 private bool _authenticated;
46 private string _name;
47 private SerializationInfo _info;
49 static private IntPtr invalidWindows = IntPtr.Zero;
51 [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
52 public WindowsIdentity (IntPtr userToken)
53 : this (userToken, null, WindowsAccountType.Normal, false)
57 [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
58 public WindowsIdentity (IntPtr userToken, string type)
59 : this (userToken, type, WindowsAccountType.Normal, false)
63 [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
64 public WindowsIdentity (IntPtr userToken, string type, WindowsAccountType acctType)
65 : this (userToken, type, acctType, false)
69 [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
70 public WindowsIdentity (IntPtr userToken, string type, WindowsAccountType acctType, bool isAuthenticated)
72 _type = type;
73 _account = acctType;
74 _authenticated = isAuthenticated;
75 _name = null;
76 // last - as it can override some fields
77 SetToken (userToken);
79 #if !NET_1_0
80 [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
81 public WindowsIdentity (string sUserPrincipalName)
82 : this (sUserPrincipalName, null)
86 [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
87 public WindowsIdentity (string sUserPrincipalName, string type)
89 if (sUserPrincipalName == null)
90 throw new NullReferenceException ("sUserPrincipalName");
92 // TODO: Windows 2003 compatibility should be done in runtime
93 IntPtr token = GetUserToken (sUserPrincipalName);
94 if ((!Environment.IsUnix) && (token == IntPtr.Zero)) {
95 throw new ArgumentException ("only for Windows Server 2003 +");
98 _authenticated = true;
99 _account = WindowsAccountType.Normal;
100 _type = type;
101 // last - as it can override some fields
102 SetToken (token);
105 [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
106 public WindowsIdentity (SerializationInfo info, StreamingContext context)
108 _info = info;
110 #endif
112 [ComVisible (false)]
113 public void Dispose ()
115 _token = IntPtr.Zero;
118 [ComVisible (false)]
119 protected virtual void Dispose (bool disposing)
121 _token = IntPtr.Zero;
123 // static methods
125 public static WindowsIdentity GetAnonymous ()
127 WindowsIdentity id = null;
128 if (Environment.IsUnix) {
129 id = new WindowsIdentity ("nobody");
130 // special case
131 id._account = WindowsAccountType.Anonymous;
132 id._authenticated = false;
133 id._type = String.Empty;
135 else {
136 id = new WindowsIdentity (IntPtr.Zero, String.Empty, WindowsAccountType.Anonymous, false);
137 // special case (don't try to resolve the name)
138 id._name = String.Empty;
140 return id;
143 public static WindowsIdentity GetCurrent ()
145 return new WindowsIdentity (GetCurrentToken (), null, WindowsAccountType.Normal, true);
147 [MonoTODO ("need icall changes")]
148 public static WindowsIdentity GetCurrent (bool ifImpersonating)
150 throw new NotImplementedException ();
153 [MonoTODO ("need icall changes")]
154 public static WindowsIdentity GetCurrent (TokenAccessLevels desiredAccess)
156 throw new NotImplementedException ();
158 // methods
160 public virtual WindowsImpersonationContext Impersonate ()
162 return new WindowsImpersonationContext (_token);
165 [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
166 public static WindowsImpersonationContext Impersonate (IntPtr userToken)
168 return new WindowsImpersonationContext (userToken);
171 // properties
173 public string AuthenticationType {
174 get { return _type; }
177 public virtual bool IsAnonymous
179 get { return (_account == WindowsAccountType.Anonymous); }
182 public virtual bool IsAuthenticated
184 get { return _authenticated; }
187 public virtual bool IsGuest
189 get { return (_account == WindowsAccountType.Guest); }
192 public virtual bool IsSystem
194 get { return (_account == WindowsAccountType.System); }
197 public virtual string Name
199 get {
200 if (_name == null) {
201 // revolve name (runtime)
202 _name = GetTokenName (_token);
204 return _name;
208 public virtual IntPtr Token
210 get { return _token; }
212 [MonoTODO ("not implemented")]
213 public IdentityReferenceCollection Groups {
214 get { throw new NotImplementedException (); }
217 [MonoTODO ("not implemented")]
218 [ComVisible (false)]
219 public TokenImpersonationLevel ImpersonationLevel {
220 get { throw new NotImplementedException (); }
223 [MonoTODO ("not implemented")]
224 [ComVisible (false)]
225 public SecurityIdentifier Owner {
226 get { throw new NotImplementedException (); }
229 [MonoTODO ("not implemented")]
230 [ComVisible (false)]
231 public SecurityIdentifier User {
232 get { throw new NotImplementedException (); }
234 void IDeserializationCallback.OnDeserialization (object sender)
236 _token = (IntPtr) _info.GetValue ("m_userToken", typeof (IntPtr));
237 // can't trust this alone - we must validate the token
238 _name = _info.GetString ("m_name");
239 if (_name != null) {
240 // validate token by comparing names
241 string name = GetTokenName (_token);
242 if (name != _name)
243 throw new SerializationException ("Token-Name mismatch.");
245 else {
246 // validate token by getting name
247 _name = GetTokenName (_token);
248 if ((_name == String.Empty) || (_name == null))
249 throw new SerializationException ("Token doesn't match a user.");
251 _type = _info.GetString ("m_type");
252 _account = (WindowsAccountType) _info.GetValue ("m_acctType", typeof (WindowsAccountType));
253 _authenticated = _info.GetBoolean ("m_isAuthenticated");
255 #if !NET_1_0
256 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
258 info.AddValue ("m_userToken", _token);
259 // can be null when not resolved
260 info.AddValue ("m_name", _name);
261 info.AddValue ("m_type", _type);
262 info.AddValue ("m_acctType", _account);
263 info.AddValue ("m_isAuthenticated", _authenticated);
265 #endif
266 private void SetToken (IntPtr token)
268 if (Environment.IsUnix) {
270 _token = token;
271 // apply defaults
272 if (_type == null)
273 _type = "POSIX";
274 // override user choice in this specific case
275 if (_token == IntPtr.Zero)
276 _account = WindowsAccountType.System;
278 else {
279 if ((token == invalidWindows) && (_account != WindowsAccountType.Anonymous))
280 throw new ArgumentException ("Invalid token");
282 _token = token;
283 // apply defaults
284 if (_type == null)
285 _type = "NTLM";
289 // see mono/mono/metadata/security.c for implementation
291 // Many people use reflection to get a user's roles - so many
292 // that's it's hard to say it's an "undocumented" feature -
293 // so we also implement it in Mono :-/
294 // http://www.dotnet247.com/247reference/msgs/39/195403.aspx
295 [MethodImplAttribute (MethodImplOptions.InternalCall)]
296 internal extern static string[] _GetRoles (IntPtr token);
298 [MethodImplAttribute (MethodImplOptions.InternalCall)]
299 internal extern static IntPtr GetCurrentToken ();
301 [MethodImplAttribute (MethodImplOptions.InternalCall)]
302 private extern static string GetTokenName (IntPtr token);
304 [MethodImplAttribute (MethodImplOptions.InternalCall)]
305 private extern static IntPtr GetUserToken (string username);