| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- //
- // System.Security.Principal.WindowsIdentity
- //
- // Authors:
- // Gonzalo Paniagua Javier ([email protected])
- // Sebastien Pouliot ([email protected])
- //
- // (C) 2002 Ximian, Inc (http://www.ximian.com)
- // Portions (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.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Security.Permissions;
- namespace System.Security.Principal {
- [Serializable]
- #if NET_1_0
- public class WindowsIdentity : IIdentity, IDeserializationCallback {
- #elif NET_2_0
- [ComVisible (true)]
- public class WindowsIdentity : IIdentity, IDeserializationCallback, ISerializable, IDisposable {
- #else
- public class WindowsIdentity : IIdentity, IDeserializationCallback, ISerializable {
- #endif
- private IntPtr _token;
- private string _type;
- private WindowsAccountType _account;
- private bool _authenticated;
- private string _name;
- private SerializationInfo _info;
- static private IntPtr invalidWindows = IntPtr.Zero;
- // that seems to be the value used for (at least) AIX and MacOSX
- static private IntPtr invalidPosix = (IntPtr) unchecked (-2);
- [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
- public WindowsIdentity (IntPtr userToken)
- : this (userToken, null, WindowsAccountType.Normal, false)
- {
- }
- [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
- public WindowsIdentity (IntPtr userToken, string type)
- : this (userToken, type, WindowsAccountType.Normal, false)
- {
- }
- [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
- public WindowsIdentity (IntPtr userToken, string type, WindowsAccountType acctType)
- : this (userToken, type, acctType, false)
- {
- }
- [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
- public WindowsIdentity (IntPtr userToken, string type, WindowsAccountType acctType, bool isAuthenticated)
- {
- _type = type;
- _account = acctType;
- _authenticated = isAuthenticated;
- _name = null;
- // last - as it can override some fields
- SetToken (userToken);
- }
- #if !NET_1_0
- [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
- public WindowsIdentity (string sUserPrincipalName)
- : this (sUserPrincipalName, null)
- {
- }
- [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
- public WindowsIdentity (string sUserPrincipalName, string type)
- {
- if (sUserPrincipalName == null)
- throw new NullReferenceException ("sUserPrincipalName");
- // TODO: Windows 2003 compatibility should be done in runtime
- IntPtr token = GetUserToken (sUserPrincipalName);
- if ((!IsPosix) && (token == IntPtr.Zero)) {
- throw new ArgumentException ("only for Windows Server 2003 +");
- }
- _authenticated = true;
- _account = WindowsAccountType.Normal;
- _type = type;
- // last - as it can override some fields
- SetToken (token);
- }
- [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
- public WindowsIdentity (SerializationInfo info, StreamingContext context)
- {
- _info = info;
- }
- #endif
- #if NET_2_0
- [ComVisible (false)]
- public void Dispose ()
- {
- _token = IntPtr.Zero;
- }
-
- [ComVisible (false)]
- protected virtual void Dispose (bool disposing)
- {
- _token = IntPtr.Zero;
- }
- #else
- ~WindowsIdentity ()
- {
- // clear our copy but don't close it
- // http://www.develop.com/kbrown/book/html/whatis_windowsprincipal.html
- _token = IntPtr.Zero;
- }
- #endif
- // static methods
- public static WindowsIdentity GetAnonymous ()
- {
- WindowsIdentity id = null;
- if (IsPosix) {
- id = new WindowsIdentity ("nobody");
- // special case
- id._account = WindowsAccountType.Anonymous;
- id._authenticated = false;
- id._type = String.Empty;
- }
- else {
- id = new WindowsIdentity (IntPtr.Zero, String.Empty, WindowsAccountType.Anonymous, false);
- // special case (don't try to resolve the name)
- id._name = String.Empty;
- }
- return id;
- }
- public static WindowsIdentity GetCurrent ()
- {
- return new WindowsIdentity (GetCurrentToken (), null, WindowsAccountType.Normal, true);
- }
- #if NET_2_0
- [MonoTODO ("need icall changes")]
- public static WindowsIdentity GetCurrent (bool ifImpersonating)
- {
- throw new NotImplementedException ();
- }
- [MonoTODO ("need icall changes")]
- public static WindowsIdentity GetCurrent (TokenAccessLevels desiredAccess)
- {
- throw new NotImplementedException ();
- }
- #endif
- // methods
- public virtual WindowsImpersonationContext Impersonate ()
- {
- return new WindowsImpersonationContext (_token);
- }
- [SecurityPermission (SecurityAction.Demand, ControlPrincipal=true)]
- public static WindowsImpersonationContext Impersonate (IntPtr userToken)
- {
- return new WindowsImpersonationContext (userToken);
- }
- // properties
- #if NET_2_0
- public string AuthenticationType {
- #else
- public virtual string AuthenticationType {
- #endif
- get { return _type; }
- }
- public virtual bool IsAnonymous
- {
- get { return (_account == WindowsAccountType.Anonymous); }
- }
- public virtual bool IsAuthenticated
- {
- get { return _authenticated; }
- }
- public virtual bool IsGuest
- {
- get { return (_account == WindowsAccountType.Guest); }
- }
- public virtual bool IsSystem
- {
- get { return (_account == WindowsAccountType.System); }
- }
- public virtual string Name
- {
- get {
- if (_name == null) {
- // revolve name (runtime)
- _name = GetTokenName (_token);
- }
- return _name;
- }
- }
- public virtual IntPtr Token
- {
- get { return _token; }
- }
- #if NET_2_0
- [MonoTODO ("not implemented")]
- public IdentityReferenceCollection Groups {
- get { throw new NotImplementedException (); }
- }
- [MonoTODO ("not implemented")]
- [ComVisible (false)]
- public TokenImpersonationLevel ImpersonationLevel {
- get { throw new NotImplementedException (); }
- }
- [MonoTODO ("not implemented")]
- [ComVisible (false)]
- public SecurityIdentifier Owner {
- get { throw new NotImplementedException (); }
- }
- [MonoTODO ("not implemented")]
- [ComVisible (false)]
- public SecurityIdentifier User {
- get { throw new NotImplementedException (); }
- }
- #endif
- void IDeserializationCallback.OnDeserialization (object sender)
- {
- _token = (IntPtr) _info.GetValue ("m_userToken", typeof (IntPtr));
- // can't trust this alone - we must validate the token
- _name = _info.GetString ("m_name");
- if (_name != null) {
- // validate token by comparing names
- string name = GetTokenName (_token);
- if (name != _name)
- throw new SerializationException ("Token-Name mismatch.");
- }
- else {
- // validate token by getting name
- _name = GetTokenName (_token);
- if ((_name == String.Empty) || (_name == null))
- throw new SerializationException ("Token doesn't match a user.");
- }
- _type = _info.GetString ("m_type");
- _account = (WindowsAccountType) _info.GetValue ("m_acctType", typeof (WindowsAccountType));
- _authenticated = _info.GetBoolean ("m_isAuthenticated");
- }
- #if !NET_1_0
- void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
- {
- info.AddValue ("m_userToken", _token);
- // can be null when not resolved
- info.AddValue ("m_name", _name);
- info.AddValue ("m_type", _type);
- info.AddValue ("m_acctType", _account);
- info.AddValue ("m_isAuthenticated", _authenticated);
- }
- #endif
- private static bool IsPosix {
- get { return ((int) Environment.Platform == 128); }
- }
- private void SetToken (IntPtr token)
- {
- if (IsPosix) {
- if (token == invalidPosix)
- throw new ArgumentException ("Invalid token");
- _token = token;
- // apply defaults
- if (_type == null)
- _type = "POSIX";
- // override user choice in this specific case
- if (_token == IntPtr.Zero)
- _account = WindowsAccountType.System;
- }
- else {
- if ((token == invalidWindows) && (_account != WindowsAccountType.Anonymous))
- throw new ArgumentException ("Invalid token");
- _token = token;
- // apply defaults
- if (_type == null)
- _type = "NTLM";
- }
- }
- // see mono/mono/metadata/security.c for implementation
- // Many people use reflection to get a user's roles - so many
- // that's it's hard to say it's an "undocumented" feature -
- // so we also implement it in Mono :-/
- // http://www.dotnet247.com/247reference/msgs/39/195403.aspx
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static string[] _GetRoles (IntPtr token);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- internal extern static IntPtr GetCurrentToken ();
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- private extern static string GetTokenName (IntPtr token);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- private extern static IntPtr GetUserToken (string username);
- }
- }
|