1 // ==++== 2 // 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // 5 // ==--== 6 // <OWNER>Microsoft</OWNER> 7 // 8 9 // 10 // WindowsIdentity.cs 11 // 12 // Representation of a process/thread token. 13 // 14 15 namespace System.Security.Principal 16 { 17 using System.Diagnostics.Contracts; 18 using System.Reflection; 19 using System.Runtime.CompilerServices; 20 #if FEATURE_CORRUPTING_EXCEPTIONS 21 using System.Runtime.ExceptionServices; 22 #endif // FEATURE_CORRUPTING_EXCEPTIONS 23 using System.Runtime.InteropServices; 24 using System.Runtime.Serialization; 25 using System.Runtime.Versioning; 26 using System.Security.AccessControl; 27 using System.Security.Permissions; 28 using System.Text; 29 using System.Threading; 30 using Microsoft.Win32; 31 using Microsoft.Win32.SafeHandles; 32 33 #if !FEATURE_CORECLR 34 using System.Security.Claims; 35 using System.Collections.ObjectModel; 36 using System.Collections.Generic; 37 using System.Globalization; 38 #endif 39 40 [Serializable] 41 [System.Runtime.InteropServices.ComVisible(true)] 42 public enum WindowsAccountType { 43 Normal = 0, 44 Guest = 1, 45 System = 2, 46 Anonymous = 3 47 } 48 49 // Keep in sync with vm\comprincipal.h 50 internal enum WinSecurityContext { 51 Thread = 1, // OpenAsSelf = false 52 Process = 2, // OpenAsSelf = true 53 Both = 3 // OpenAsSelf = true, then OpenAsSelf = false 54 } 55 56 internal enum ImpersonationQueryResult { 57 Impersonated = 0, // current thread is impersonated 58 NotImpersonated = 1, // current thread is not impersonated 59 Failed = 2 // failed to query 60 } 61 62 [Serializable] 63 [System.Runtime.InteropServices.ComVisible(true)] 64 #if !FEATURE_CORECLR 65 public class WindowsIdentity : ClaimsIdentity, ISerializable, IDeserializationCallback, IDisposable { 66 #else 67 public class WindowsIdentity : IIdentity, ISerializable, IDeserializationCallback, IDisposable { 68 #endif 69 [System.Security.SecurityCritical] // auto-generated 70 static SafeAccessTokenHandle s_invalidTokenHandle = SafeAccessTokenHandle.InvalidHandle; 71 private string m_name = null; 72 private SecurityIdentifier m_owner = null; 73 private SecurityIdentifier m_user = null; 74 private object m_groups = null; 75 [System.Security.SecurityCritical] // auto-generated 76 private SafeAccessTokenHandle m_safeTokenHandle = SafeAccessTokenHandle.InvalidHandle; 77 private string m_authType = null; 78 private int m_isAuthenticated = -1; 79 private volatile TokenImpersonationLevel m_impersonationLevel; 80 private volatile bool m_impersonationLevelInitialized; 81 private static RuntimeConstructorInfo s_specialSerializationCtor; 82 83 #if !FEATURE_CORECLR 84 85 [NonSerialized] 86 public new const string DefaultIssuer = @"AD AUTHORITY"; 87 88 [NonSerialized] 89 string m_issuerName = DefaultIssuer; 90 91 [NonSerialized] 92 private object m_claimsIntiailizedLock = new object(); 93 94 [NonSerialized] 95 volatile bool m_claimsInitialized; 96 97 [NonSerialized] 98 List<Claim> m_deviceClaims; 99 100 [NonSerialized] 101 List<Claim> m_userClaims; 102 103 #endif 104 105 // 106 // Constructors. 107 // 108 109 [System.Security.SecuritySafeCritical] // auto-generated WindowsIdentity()110 static WindowsIdentity() 111 { 112 s_specialSerializationCtor = typeof(WindowsIdentity).GetConstructor( 113 BindingFlags.Instance | BindingFlags.NonPublic, 114 null, 115 new Type[] { typeof(SerializationInfo) }, 116 null) as RuntimeConstructorInfo; 117 } 118 119 [System.Security.SecurityCritical] // auto-generated 120 #if !FEATURE_CORECLR WindowsIdentity()121 private WindowsIdentity () 122 : base( null, null, null, ClaimTypes.Name, ClaimTypes.GroupSid ) {} 123 #else WindowsIdentity()124 private WindowsIdentity () {} 125 #endif 126 127 [System.Security.SecurityCritical] // auto-generated WindowsIdentity(SafeAccessTokenHandle safeTokenHandle)128 internal WindowsIdentity (SafeAccessTokenHandle safeTokenHandle) : this (safeTokenHandle.DangerousGetHandle(), null, -1) { 129 GC.KeepAlive(safeTokenHandle); 130 } 131 132 [System.Security.SecuritySafeCritical] // auto-generated 133 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] 134 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] WindowsIdentity(IntPtr userToken)135 public WindowsIdentity (IntPtr userToken) : this (userToken, null, -1) {} 136 137 [System.Security.SecuritySafeCritical] // auto-generated 138 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] 139 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] WindowsIdentity(IntPtr userToken, string type)140 public WindowsIdentity (IntPtr userToken, string type) : this (userToken, type, -1) {} 141 142 [System.Security.SecuritySafeCritical] // auto-generated 143 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] 144 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] WindowsIdentity(IntPtr userToken, string type, WindowsAccountType acctType)145 public WindowsIdentity (IntPtr userToken, string type, WindowsAccountType acctType) : this (userToken, type, -1) {} 146 147 [System.Security.SecuritySafeCritical] // auto-generated 148 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] 149 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] WindowsIdentity(IntPtr userToken, string type, WindowsAccountType acctType, bool isAuthenticated)150 public WindowsIdentity (IntPtr userToken, string type, WindowsAccountType acctType, bool isAuthenticated) 151 : this (userToken, type, isAuthenticated ? 1 : 0) {} 152 153 [System.Security.SecurityCritical] // auto-generated 154 155 WindowsIdentity(IntPtr userToken, string authType, int isAuthenticated )156 private WindowsIdentity (IntPtr userToken, string authType, int isAuthenticated ) 157 #if !FEATURE_CORECLR 158 : base(null, null, null, ClaimTypes.Name, ClaimTypes.GroupSid) 159 #endif 160 { 161 CreateFromToken(userToken); 162 m_authType = authType; 163 m_isAuthenticated = isAuthenticated; 164 } 165 166 [System.Security.SecurityCritical] // auto-generated 167 [ResourceExposure(ResourceScope.None)] 168 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] CreateFromToken(IntPtr userToken)169 private void CreateFromToken (IntPtr userToken) { 170 if (userToken == IntPtr.Zero) 171 throw new ArgumentException(Environment.GetResourceString("Argument_TokenZero")); 172 Contract.EndContractBlock(); 173 174 // Find out if the specified token is a valid. 175 uint dwLength = (uint) Marshal.SizeOf(typeof(uint)); 176 bool result = Win32Native.GetTokenInformation(userToken, (uint) TokenInformationClass.TokenType, 177 SafeLocalAllocHandle.InvalidHandle, 0, out dwLength); 178 if (Marshal.GetLastWin32Error() == Win32Native.ERROR_INVALID_HANDLE) 179 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidImpersonationToken")); 180 181 if (!Win32Native.DuplicateHandle(Win32Native.GetCurrentProcess(), 182 userToken, 183 Win32Native.GetCurrentProcess(), 184 ref m_safeTokenHandle, 185 0, 186 true, 187 Win32Native.DUPLICATE_SAME_ACCESS)) 188 throw new SecurityException(Win32Native.GetMessage(Marshal.GetLastWin32Error())); 189 } 190 191 [System.Security.SecuritySafeCritical] // auto-generated 192 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] WindowsIdentity(string sUserPrincipalName)193 public WindowsIdentity (string sUserPrincipalName) : this (sUserPrincipalName, null) {} 194 195 [System.Security.SecuritySafeCritical] // auto-generated 196 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] 197 198 WindowsIdentity(string sUserPrincipalName, string type )199 public WindowsIdentity (string sUserPrincipalName, string type ) 200 #if !FEATURE_CORECLR 201 : base( null, null, null, ClaimTypes.Name, ClaimTypes.GroupSid ) 202 #endif 203 { 204 KerbS4ULogon(sUserPrincipalName, ref m_safeTokenHandle); 205 } 206 207 // 208 // We cannot make sure the token will stay alive 209 // until it is being deserialized in another AppDomain. We do not have a way to capture 210 // the state of a token (just a pointer to kernel memory) and re-construct it later 211 // and even if we did (via calling NtQueryInformationToken and relying on the token undocumented 212 // format), constructing a token requires TCB privilege. We need to address the "serializable" 213 // nature of WindowsIdentity since it is not obvious that can be achieved at all. 214 // 215 216 [System.Security.SecuritySafeCritical] // auto-generated 217 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] 218 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.SerializationFormatter )] WindowsIdentity(SerializationInfo info, StreamingContext context)219 public WindowsIdentity (SerializationInfo info, StreamingContext context) : this(info) 220 { 221 } 222 223 // This is a copy of the serialization constructor above but without the 224 // security demand that's slow and breaks partial trust scenarios 225 // without an expensive assert in place in the remoting code. Instead we 226 // special case this class and call the private constructor directly 227 // (changing the demand above is considered a breaking change, even 228 // though nobody else should have been using a serialization constructor 229 // directly). 230 [System.Security.SecurityCritical] // auto-generated WindowsIdentity(SerializationInfo info)231 private WindowsIdentity(SerializationInfo info) 232 #if !FEATURE_CORECLR 233 : base(info) 234 #endif 235 { 236 237 #if !FEATURE_CORECLR 238 m_claimsInitialized = false; 239 #endif 240 241 IntPtr userToken = (IntPtr) info.GetValue("m_userToken", typeof(IntPtr)); 242 if (userToken != IntPtr.Zero) 243 CreateFromToken(userToken); 244 } 245 246 /// <internalonly/> 247 [System.Security.SecurityCritical] // auto-generated_required ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)248 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context) { 249 #if !FEATURE_CORECLR 250 base.GetObjectData(info, context); 251 #endif 252 info.AddValue("m_userToken", m_safeTokenHandle.DangerousGetHandle()); 253 } 254 255 /// <internalonly/> IDeserializationCallback.OnDeserialization(Object sender)256 void IDeserializationCallback.OnDeserialization (Object sender) {} 257 258 // 259 // Factory methods. 260 // 261 262 263 [System.Security.SecuritySafeCritical] // auto-generated 264 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] GetCurrent()265 public static WindowsIdentity GetCurrent () { 266 return GetCurrentInternal(TokenAccessLevels.MaximumAllowed, false); 267 } 268 269 [System.Security.SecuritySafeCritical] // auto-generated 270 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] GetCurrent(bool ifImpersonating)271 public static WindowsIdentity GetCurrent (bool ifImpersonating) { 272 return GetCurrentInternal(TokenAccessLevels.MaximumAllowed, ifImpersonating); 273 } 274 275 [System.Security.SecuritySafeCritical] // auto-generated 276 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)] GetCurrent(TokenAccessLevels desiredAccess)277 public static WindowsIdentity GetCurrent (TokenAccessLevels desiredAccess) { 278 return GetCurrentInternal(desiredAccess, false); 279 } 280 281 // GetAnonymous() is used heavily in ASP.NET requests as a dummy identity to indicate 282 // the request is anonymous. It does not represent a real process or thread token so 283 // it cannot impersonate or do anything useful. Note this identity does not represent the 284 // usual concept of an anonymous token, and the name is simply misleading but we cannot change it now. 285 286 [System.Security.SecuritySafeCritical] // auto-generated GetAnonymous()287 public static WindowsIdentity GetAnonymous () { 288 return new WindowsIdentity(); 289 } 290 291 // 292 // Properties. 293 // 294 // this is defined 'override sealed' for back compat. Il generated is 'virtual final' and this needs to be the same. 295 #if !FEATURE_CORECLR 296 public override sealed string AuthenticationType { 297 #else 298 public string AuthenticationType { 299 #endif 300 [System.Security.SecuritySafeCritical] // auto-generated 301 get { 302 // If this is an anonymous identity, return an empty string 303 if (m_safeTokenHandle.IsInvalid) 304 return String.Empty; 305 306 if (m_authType == null) { 307 Win32Native.LUID authId = GetLogonAuthId(m_safeTokenHandle); 308 if (authId.LowPart == Win32Native.ANONYMOUS_LOGON_LUID) 309 return String.Empty; // no authentication, just return an empty string 310 311 SafeLsaReturnBufferHandle pLogonSessionData = SafeLsaReturnBufferHandle.InvalidHandle; 312 try { 313 int status = Win32Native.LsaGetLogonSessionData(ref authId, ref pLogonSessionData); 314 if (status < 0) // non-negative numbers indicate success 315 throw GetExceptionFromNtStatus(status); 316 317 pLogonSessionData.Initialize((uint)Marshal.SizeOf(typeof(Win32Native.SECURITY_LOGON_SESSION_DATA))); 318 319 Win32Native.SECURITY_LOGON_SESSION_DATA logonSessionData = pLogonSessionData.Read<Win32Native.SECURITY_LOGON_SESSION_DATA>(0); 320 return Marshal.PtrToStringUni(logonSessionData.AuthenticationPackage.Buffer); 321 } 322 finally { 323 if (!pLogonSessionData.IsInvalid) 324 pLogonSessionData.Dispose(); 325 } 326 } 327 328 return m_authType; 329 } 330 } 331 332 333 [ComVisible(false)] 334 public TokenImpersonationLevel ImpersonationLevel { 335 [System.Security.SecuritySafeCritical] // auto-generated 336 get { 337 // If two threads ---- here, they'll both set m_impersonationLevel to the same value, 338 // which is ok. 339 if (!m_impersonationLevelInitialized) { 340 TokenImpersonationLevel impersonationLevel = TokenImpersonationLevel.None; 341 // If this is an anonymous identity 342 if (m_safeTokenHandle.IsInvalid) { 343 impersonationLevel = TokenImpersonationLevel.Anonymous; 344 } 345 else { 346 TokenType tokenType = (TokenType)GetTokenInformation<int>(TokenInformationClass.TokenType); 347 if (tokenType == TokenType.TokenPrimary) { 348 impersonationLevel = TokenImpersonationLevel.None; // primary token; 349 } 350 else { 351 /// This is an impersonation token, get the impersonation level 352 int level = GetTokenInformation<int>(TokenInformationClass.TokenImpersonationLevel); 353 impersonationLevel = (TokenImpersonationLevel)level + 1; 354 } 355 } 356 357 m_impersonationLevel = impersonationLevel; 358 m_impersonationLevelInitialized = true; 359 } 360 361 return m_impersonationLevel; 362 } 363 } 364 365 #if !FEATURE_CORECLR 366 public override bool IsAuthenticated { 367 #else 368 public virtual bool IsAuthenticated { 369 #endif 370 371 get { 372 if (m_isAuthenticated == -1) { 373 // There is a known bug where this approach will not work correctly for domain guests (will return false 374 // instead of true). But this is a corner-case that is not very interesting. 375 #if !FEATURE_CORECLR 376 m_isAuthenticated = CheckNtTokenForSid(new SecurityIdentifier(IdentifierAuthority.NTAuthority, 377 new int[] { Win32Native.SECURITY_AUTHENTICATED_USER_RID })) ? 1 : 0; 378 #else 379 WindowsPrincipal wp = new WindowsPrincipal(this); 380 SecurityIdentifier sid = new SecurityIdentifier(IdentifierAuthority.NTAuthority, 381 new int[] {Win32Native.SECURITY_AUTHENTICATED_USER_RID}); 382 m_isAuthenticated = wp.IsInRole(sid) ? 1 : 0; 383 #endif 384 385 } 386 387 return m_isAuthenticated == 1; 388 } 389 } 390 391 #if !FEATURE_CORECLR 392 [System.Security.SecuritySafeCritical] 393 [ComVisible(false)] CheckNtTokenForSid(SecurityIdentifier sid)394 bool CheckNtTokenForSid (SecurityIdentifier sid) { 395 396 Contract.EndContractBlock(); 397 398 // special case the anonymous identity. 399 if (m_safeTokenHandle.IsInvalid) 400 return false; 401 402 // CheckTokenMembership expects an impersonation token 403 SafeAccessTokenHandle token = SafeAccessTokenHandle.InvalidHandle; 404 TokenImpersonationLevel til = ImpersonationLevel; 405 bool isMember = false; 406 407 try { 408 if (til == TokenImpersonationLevel.None) { 409 if (!Win32Native.DuplicateTokenEx(m_safeTokenHandle, 410 (uint) TokenAccessLevels.Query, 411 IntPtr.Zero, 412 (uint) TokenImpersonationLevel.Identification, 413 (uint) TokenType.TokenImpersonation, 414 ref token)) 415 throw new SecurityException(Win32Native.GetMessage(Marshal.GetLastWin32Error())); 416 } 417 418 419 // CheckTokenMembership will check if the SID is both present and enabled in the access token. 420 if (!Win32Native.CheckTokenMembership((til != TokenImpersonationLevel.None ? m_safeTokenHandle : token), 421 sid.BinaryForm, 422 ref isMember)) 423 throw new SecurityException(Win32Native.GetMessage(Marshal.GetLastWin32Error())); 424 } 425 finally { 426 if (token != SafeAccessTokenHandle.InvalidHandle) { 427 token.Dispose(); 428 } 429 } 430 431 return isMember; 432 } 433 #endif 434 435 // 436 // IsGuest, IsSystem and IsAnonymous are maintained for compatibility reasons. It is always 437 // possible to extract this same information from the User SID property and the new 438 // (and more general) methods defined in the SID class (IsWellKnown, etc...). 439 // 440 441 public virtual bool IsGuest { 442 [System.Security.SecuritySafeCritical] // auto-generated 443 get { 444 // special case the anonymous identity. 445 if (m_safeTokenHandle.IsInvalid) 446 return false; 447 448 #if !FEATURE_CORECLR 449 return CheckNtTokenForSid(new SecurityIdentifier(IdentifierAuthority.NTAuthority, 450 new int[] { Win32Native.SECURITY_BUILTIN_DOMAIN_RID, (int)WindowsBuiltInRole.Guest })); 451 #else 452 WindowsPrincipal principal = new WindowsPrincipal(this); 453 return principal.IsInRole(WindowsBuiltInRole.Guest); 454 #endif 455 456 } 457 } 458 459 public virtual bool IsSystem { 460 [System.Security.SecuritySafeCritical] // auto-generated 461 get { 462 // special case the anonymous identity. 463 if (m_safeTokenHandle.IsInvalid) 464 return false; 465 SecurityIdentifier sid = new SecurityIdentifier(IdentifierAuthority.NTAuthority, 466 new int[] {Win32Native.SECURITY_LOCAL_SYSTEM_RID}); 467 return (this.User == sid); 468 } 469 } 470 471 public virtual bool IsAnonymous { 472 [System.Security.SecuritySafeCritical] // auto-generated 473 get { 474 // special case the anonymous identity. 475 if (m_safeTokenHandle.IsInvalid) 476 return true; 477 SecurityIdentifier sid = new SecurityIdentifier(IdentifierAuthority.NTAuthority, 478 new int[] {Win32Native.SECURITY_ANONYMOUS_LOGON_RID}); 479 return (this.User == sid); 480 } 481 } 482 483 #if !FEATURE_CORECLR 484 public override string Name { 485 #else 486 public virtual string Name { 487 #endif 488 [System.Security.SecuritySafeCritical] // auto-generated 489 get { 490 return GetName(); 491 } 492 } 493 494 [System.Security.SecurityCritical] // auto-generated 495 [DynamicSecurityMethodAttribute()] 496 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable GetName()497 internal String GetName() 498 { 499 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 500 // special case the anonymous identity. 501 if (m_safeTokenHandle.IsInvalid) 502 return String.Empty; 503 504 if (m_name == null) 505 { 506 // revert thread impersonation for the duration of the call to get the name. 507 using (SafeRevertToSelf(ref stackMark)) 508 { 509 NTAccount ntAccount = this.User.Translate(typeof(NTAccount)) as NTAccount; 510 m_name = ntAccount.ToString(); 511 } 512 } 513 514 return m_name; 515 } 516 517 [ComVisible(false)] 518 public SecurityIdentifier Owner { 519 [System.Security.SecuritySafeCritical] // auto-generated 520 get { 521 // special case the anonymous identity. 522 if (m_safeTokenHandle.IsInvalid) 523 return null; 524 525 if (m_owner == null) { 526 using (SafeLocalAllocHandle tokenOwner = GetTokenInformation(m_safeTokenHandle, TokenInformationClass.TokenOwner)) { 527 m_owner = new SecurityIdentifier(tokenOwner.Read<IntPtr>(0), true); 528 } 529 } 530 531 return m_owner; 532 } 533 } 534 535 [ComVisible(false)] 536 public SecurityIdentifier User { 537 [System.Security.SecuritySafeCritical] // auto-generated 538 get { 539 // special case the anonymous identity. 540 if (m_safeTokenHandle.IsInvalid) 541 return null; 542 543 if (m_user == null) { 544 using (SafeLocalAllocHandle tokenUser = GetTokenInformation(m_safeTokenHandle, TokenInformationClass.TokenUser)) { 545 m_user = new SecurityIdentifier(tokenUser.Read<IntPtr>(0), true); 546 } 547 } 548 549 return m_user; 550 } 551 } 552 553 public IdentityReferenceCollection Groups { 554 [System.Security.SecuritySafeCritical] // auto-generated 555 get { 556 // special case the anonymous identity. 557 if (m_safeTokenHandle.IsInvalid) 558 return null; 559 560 if (m_groups == null) { 561 IdentityReferenceCollection groups = new IdentityReferenceCollection(); 562 using (SafeLocalAllocHandle pGroups = GetTokenInformation(m_safeTokenHandle, TokenInformationClass.TokenGroups)) { 563 564 uint groupCount = pGroups.Read<uint>(0); 565 // Work-around bug on WS03 that only populates the GroupCount field of TOKEN_GROUPS if the count is 0 566 // In that situation, attempting to read the entire TOKEN_GROUPS structure will lead to InsufficientBuffer exception 567 // since the field is only 4 bytes long (uint only, for GroupCount), but we try to read more (including the pointer to GroupDetails). 568 if (groupCount != 0) 569 { 570 571 Win32Native.TOKEN_GROUPS tokenGroups = pGroups.Read<Win32Native.TOKEN_GROUPS>(0); 572 Win32Native.SID_AND_ATTRIBUTES[] groupDetails = new Win32Native.SID_AND_ATTRIBUTES[tokenGroups.GroupCount]; 573 574 pGroups.ReadArray((uint)Marshal.OffsetOf(typeof(Win32Native.TOKEN_GROUPS), "Groups").ToInt32(), 575 groupDetails, 576 0, 577 groupDetails.Length); 578 579 foreach (Win32Native.SID_AND_ATTRIBUTES group in groupDetails) 580 { 581 // Ignore disabled, logon ID, and deny-only groups. 582 uint mask = Win32Native.SE_GROUP_ENABLED | Win32Native.SE_GROUP_LOGON_ID | Win32Native.SE_GROUP_USE_FOR_DENY_ONLY; 583 if ((group.Attributes & mask) == Win32Native.SE_GROUP_ENABLED) { 584 groups.Add(new SecurityIdentifier(group.Sid, true )); 585 } 586 } 587 } 588 } 589 Interlocked.CompareExchange(ref m_groups, groups, null); 590 } 591 592 return m_groups as IdentityReferenceCollection; 593 } 594 } 595 596 // 597 // Note this property does not duplicate the token. This is also the same as V1/Everett behaviour. 598 // 599 600 public virtual IntPtr Token { 601 [System.Security.SecuritySafeCritical] // auto-generated 602 [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] 603 get { 604 return m_safeTokenHandle.DangerousGetHandle(); 605 } 606 } 607 608 // 609 // Public methods. 610 // 611 [SecuritySafeCritical] 612 [DynamicSecurityMethodAttribute()] 613 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable RunImpersonated(SafeAccessTokenHandle safeAccessTokenHandle, Action action)614 public static void RunImpersonated(SafeAccessTokenHandle safeAccessTokenHandle, Action action) 615 { 616 if (action == null) 617 throw new ArgumentNullException("action"); 618 619 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 620 621 WindowsIdentity wi = null; 622 if (!safeAccessTokenHandle.IsInvalid) 623 wi = new WindowsIdentity(safeAccessTokenHandle); 624 625 using (WindowsImpersonationContext wiContext = SafeImpersonate(safeAccessTokenHandle, wi, ref stackMark)) 626 { 627 action(); 628 } 629 } 630 631 [SecuritySafeCritical] 632 [DynamicSecurityMethodAttribute()] 633 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable RunImpersonated(SafeAccessTokenHandle safeAccessTokenHandle, Func<T> func)634 public static T RunImpersonated<T>(SafeAccessTokenHandle safeAccessTokenHandle, Func<T> func) 635 { 636 if (func == null) 637 throw new ArgumentNullException("func"); 638 639 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 640 641 WindowsIdentity wi = null; 642 if (!safeAccessTokenHandle.IsInvalid) 643 wi = new WindowsIdentity(safeAccessTokenHandle); 644 645 T result = default(T); 646 using (WindowsImpersonationContext wiContext = SafeImpersonate(safeAccessTokenHandle, wi, ref stackMark)) 647 { 648 result = func(); 649 } 650 651 return result; 652 } 653 654 [System.Security.SecuritySafeCritical] // auto-generated 655 [DynamicSecurityMethodAttribute()] 656 [ResourceExposure(ResourceScope.Process)] // Call from within a CER, or use a RunAsUser helper. 657 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable Impersonate()658 public virtual WindowsImpersonationContext Impersonate () 659 { 660 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 661 return Impersonate(ref stackMark); 662 } 663 664 [System.Security.SecuritySafeCritical] // auto-generated 665 [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPrincipal | SecurityPermissionFlag.UnmanagedCode)] 666 [DynamicSecurityMethodAttribute()] 667 [ResourceExposure(ResourceScope.Process)] // Call from within a CER, or use a RunAsUser helper. 668 [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable Impersonate(IntPtr userToken)669 public static WindowsImpersonationContext Impersonate (IntPtr userToken) 670 { 671 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 672 if (userToken == IntPtr.Zero) 673 return SafeRevertToSelf(ref stackMark); 674 675 WindowsIdentity wi = new WindowsIdentity(userToken, null, -1); 676 return wi.Impersonate(ref stackMark); 677 } 678 679 [System.Security.SecurityCritical] // auto-generated Impersonate(ref StackCrawlMark stackMark)680 internal WindowsImpersonationContext Impersonate (ref StackCrawlMark stackMark) { 681 if (m_safeTokenHandle.IsInvalid) 682 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AnonymousCannotImpersonate")); 683 684 return SafeImpersonate(m_safeTokenHandle, this, ref stackMark); 685 } 686 687 [System.Security.SecuritySafeCritical] // auto-generated 688 [ComVisible(false)] Dispose(bool disposing)689 protected virtual void Dispose(bool disposing) { 690 if (disposing) { 691 if (m_safeTokenHandle != null && !m_safeTokenHandle.IsClosed) 692 m_safeTokenHandle.Dispose(); 693 } 694 m_name = null; 695 m_owner = null; 696 m_user = null; 697 } 698 699 [ComVisible(false)] Dispose()700 public void Dispose() { 701 Dispose(true); 702 } 703 704 public SafeAccessTokenHandle AccessToken { 705 [System.Security.SecurityCritical] // auto-generated 706 get { 707 return m_safeTokenHandle; 708 } 709 } 710 711 // 712 // internal. 713 // 714 715 [System.Security.SecurityCritical] // auto-generated 716 [ResourceExposure(ResourceScope.None)] 717 [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] SafeRevertToSelf(ref StackCrawlMark stackMark)718 internal static WindowsImpersonationContext SafeRevertToSelf(ref StackCrawlMark stackMark) 719 { 720 return SafeImpersonate(s_invalidTokenHandle, null, ref stackMark); 721 } 722 723 [System.Security.SecurityCritical] // auto-generated 724 [ResourceExposure(ResourceScope.Process)] 725 [ResourceConsumption(ResourceScope.Process)] SafeImpersonate(SafeAccessTokenHandle userToken, WindowsIdentity wi, ref StackCrawlMark stackMark)726 internal static WindowsImpersonationContext SafeImpersonate (SafeAccessTokenHandle userToken, WindowsIdentity wi, ref StackCrawlMark stackMark) 727 { 728 bool isImpersonating; 729 int hr = 0; 730 SafeAccessTokenHandle safeTokenHandle = GetCurrentToken(TokenAccessLevels.MaximumAllowed, false, out isImpersonating, out hr); 731 if (safeTokenHandle == null || safeTokenHandle.IsInvalid) 732 throw new SecurityException(Win32Native.GetMessage(hr)); 733 734 // Set the SafeAccessTokenHandle on the FSD: 735 FrameSecurityDescriptor secObj = SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true); 736 if (secObj == null) 737 { 738 // Security: REQ_SQ flag is missing. Bad compiler ? 739 // This can happen when you create delegates over functions that need the REQ_SQ 740 throw new SecurityException(Environment.GetResourceString( "ExecutionEngine_MissingSecurityDescriptor" ) ); 741 } 742 743 WindowsImpersonationContext context = new WindowsImpersonationContext(safeTokenHandle, GetCurrentThreadWI(), isImpersonating, secObj); 744 745 if (userToken.IsInvalid) { // impersonating a zero token means clear the token on the thread 746 hr = Win32.RevertToSelf(); 747 if (hr < 0) 748 Environment.FailFast(Win32Native.GetMessage(hr)); 749 // update identity on the thread 750 UpdateThreadWI(wi); 751 secObj.SetTokenHandles(safeTokenHandle, (wi == null?null:wi.AccessToken)); 752 } else { 753 hr = Win32.RevertToSelf(); 754 if (hr < 0) 755 Environment.FailFast(Win32Native.GetMessage(hr)); 756 hr = Win32.ImpersonateLoggedOnUser(userToken); 757 if (hr < 0) { 758 context.Undo(); 759 throw new SecurityException(Environment.GetResourceString("Argument_ImpersonateUser")); 760 } 761 UpdateThreadWI(wi); 762 secObj.SetTokenHandles(safeTokenHandle, (wi == null?null:wi.AccessToken)); 763 } 764 765 return context; 766 } 767 768 [System.Security.SecurityCritical] // auto-generated GetCurrentThreadWI()769 internal static WindowsIdentity GetCurrentThreadWI() 770 { 771 return SecurityContext.GetCurrentWI(Thread.CurrentThread.GetExecutionContextReader()); 772 } 773 774 [SecurityCritical] UpdateThreadWI(WindowsIdentity wi)775 internal static void UpdateThreadWI(WindowsIdentity wi) 776 { 777 // Set WI on Thread.CurrentThread.ExecutionContext.SecurityContext 778 Thread currentThread = Thread.CurrentThread; 779 if (currentThread.GetExecutionContextReader().SecurityContext.WindowsIdentity != wi) 780 { 781 ExecutionContext ec = currentThread.GetMutableExecutionContext(); 782 SecurityContext sc = ec.SecurityContext; 783 if (wi != null && sc == null) 784 { 785 // create a new security context on the thread 786 sc = new SecurityContext(); 787 ec.SecurityContext = sc; 788 } 789 790 if (sc != null) // null-check needed here since we will not create an sc if wi is null 791 { 792 sc.WindowsIdentity = wi; 793 } 794 } 795 } 796 797 798 [System.Security.SecurityCritical] // auto-generated 799 [ResourceExposure(ResourceScope.None)] 800 [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] GetCurrentInternal(TokenAccessLevels desiredAccess, bool threadOnly)801 internal static WindowsIdentity GetCurrentInternal (TokenAccessLevels desiredAccess, bool threadOnly) { 802 int hr = 0; 803 bool isImpersonating; 804 SafeAccessTokenHandle safeTokenHandle = GetCurrentToken(desiredAccess, threadOnly, out isImpersonating, out hr); 805 if (safeTokenHandle == null || safeTokenHandle.IsInvalid) { 806 // either we wanted only ThreadToken - return null 807 if (threadOnly && !isImpersonating) 808 return null; 809 // or there was an error 810 throw new SecurityException(Win32Native.GetMessage(hr)); 811 } 812 WindowsIdentity wi = new WindowsIdentity(); 813 wi.m_safeTokenHandle.Dispose(); 814 wi.m_safeTokenHandle = safeTokenHandle; 815 return wi; 816 } 817 GetSpecialSerializationCtor()818 internal static RuntimeConstructorInfo GetSpecialSerializationCtor() 819 { 820 return s_specialSerializationCtor; 821 } 822 823 // 824 // private. 825 // 826 GetHRForWin32Error(int dwLastError)827 private static int GetHRForWin32Error (int dwLastError) { 828 if ((dwLastError & 0x80000000) == 0x80000000) 829 return dwLastError; 830 else 831 return (dwLastError & 0x0000FFFF) | unchecked((int)0x80070000); 832 } 833 834 [System.Security.SecurityCritical] // auto-generated GetExceptionFromNtStatus(int status)835 private static Exception GetExceptionFromNtStatus (int status) { 836 if ((uint) status == Win32Native.STATUS_ACCESS_DENIED) 837 return new UnauthorizedAccessException(); 838 839 if ((uint) status == Win32Native.STATUS_INSUFFICIENT_RESOURCES || (uint) status == Win32Native.STATUS_NO_MEMORY) 840 return new OutOfMemoryException(); 841 842 int win32ErrorCode = Win32Native.LsaNtStatusToWinError(status); 843 return new SecurityException(Win32Native.GetMessage(win32ErrorCode)); 844 } 845 846 [System.Security.SecurityCritical] // auto-generated 847 [ResourceExposure(ResourceScope.Process)] 848 [ResourceConsumption(ResourceScope.Process)] GetCurrentToken(TokenAccessLevels desiredAccess, bool threadOnly, out bool isImpersonating, out int hr)849 private static SafeAccessTokenHandle GetCurrentToken(TokenAccessLevels desiredAccess, bool threadOnly, out bool isImpersonating, out int hr) { 850 isImpersonating = true; 851 SafeAccessTokenHandle safeTokenHandle = GetCurrentThreadToken(desiredAccess, out hr); 852 if (safeTokenHandle == null && hr == GetHRForWin32Error(Win32Native.ERROR_NO_TOKEN)) { 853 // No impersonation 854 isImpersonating = false; 855 if (!threadOnly) 856 safeTokenHandle = GetCurrentProcessToken(desiredAccess, out hr); 857 } 858 return safeTokenHandle; 859 } 860 861 [System.Security.SecurityCritical] // auto-generated 862 [ResourceExposure(ResourceScope.Process)] 863 [ResourceConsumption(ResourceScope.Process)] GetCurrentProcessToken(TokenAccessLevels desiredAccess, out int hr)864 private static SafeAccessTokenHandle GetCurrentProcessToken (TokenAccessLevels desiredAccess, out int hr) { 865 hr = 0; 866 SafeAccessTokenHandle safeTokenHandle; 867 if (!Win32Native.OpenProcessToken(Win32Native.GetCurrentProcess(), desiredAccess, out safeTokenHandle)) 868 hr = GetHRForWin32Error(Marshal.GetLastWin32Error()); 869 return safeTokenHandle; 870 } 871 872 [System.Security.SecurityCritical] // auto-generated 873 [ResourceExposure(ResourceScope.Process)] 874 [ResourceConsumption(ResourceScope.Process)] GetCurrentThreadToken(TokenAccessLevels desiredAccess, out int hr)875 internal static SafeAccessTokenHandle GetCurrentThreadToken(TokenAccessLevels desiredAccess, out int hr) { 876 SafeAccessTokenHandle safeTokenHandle; 877 hr = Win32.OpenThreadToken(desiredAccess, WinSecurityContext.Both, out safeTokenHandle); 878 return safeTokenHandle; 879 } 880 881 /// <summary> 882 /// Get a property from the current token 883 /// </summary> 884 [System.Security.SecurityCritical] // auto-generated 885 private T GetTokenInformation<T>(TokenInformationClass tokenInformationClass) where T : struct{ 886 Contract.Assert(!m_safeTokenHandle.IsInvalid && !m_safeTokenHandle.IsClosed, "!m_safeTokenHandle.IsInvalid && !m_safeTokenHandle.IsClosed"); 887 888 using (SafeLocalAllocHandle information = GetTokenInformation(m_safeTokenHandle, tokenInformationClass)) { 889 Contract.Assert(information.ByteLength >= (ulong)Marshal.SizeOf(typeof(T)), 890 "information.ByteLength >= (ulong)Marshal.SizeOf(typeof(T))"); 891 892 return information.Read<T>(0); 893 } 894 } 895 896 // 897 // QueryImpersonation used to test if the current thread is impersonated. 898 // This method doesn't return the thread token (WindowsIdentity). 899 // Although GetCurrentInternal can be used to perform the same test but 900 // QueryImpersonation is optimized for the perf. 901 // 902 [System.Security.SecurityCritical] // auto-generated 903 [ResourceExposure(ResourceScope.Process)] 904 [ResourceConsumption(ResourceScope.Process)] QueryImpersonation()905 internal static ImpersonationQueryResult QueryImpersonation() { 906 SafeAccessTokenHandle safeTokenHandle = null; 907 int hr = Win32.OpenThreadToken(TokenAccessLevels.Query, WinSecurityContext.Thread, out safeTokenHandle); 908 909 if (safeTokenHandle != null) { 910 Contract.Assert(hr == 0, "[WindowsIdentity..QueryImpersonation] - hr == 0"); 911 safeTokenHandle.Close(); 912 return ImpersonationQueryResult.Impersonated; 913 } 914 915 if (hr == GetHRForWin32Error(Win32Native.ERROR_ACCESS_DENIED)) { 916 // thread is impersonated because the thread was there (and we failed to open it). 917 return ImpersonationQueryResult.Impersonated; 918 } 919 920 if (hr == GetHRForWin32Error(Win32Native.ERROR_NO_TOKEN)) { 921 // definitely not impersonating 922 return ImpersonationQueryResult.NotImpersonated; 923 } 924 925 // Unexpected failure. 926 return ImpersonationQueryResult.Failed; 927 } 928 929 [System.Security.SecurityCritical] // auto-generated GetLogonAuthId(SafeAccessTokenHandle safeTokenHandle)930 private static Win32Native.LUID GetLogonAuthId (SafeAccessTokenHandle safeTokenHandle) { 931 using (SafeLocalAllocHandle pStatistics = GetTokenInformation(safeTokenHandle, TokenInformationClass.TokenStatistics)) { 932 Win32Native.TOKEN_STATISTICS statistics = pStatistics.Read<Win32Native.TOKEN_STATISTICS>(0); 933 return statistics.AuthenticationId; 934 } 935 } 936 937 [System.Security.SecurityCritical] GetTokenInformation(SafeAccessTokenHandle tokenHandle, TokenInformationClass tokenInformationClass)938 private static SafeLocalAllocHandle GetTokenInformation (SafeAccessTokenHandle tokenHandle, TokenInformationClass tokenInformationClass) { 939 SafeLocalAllocHandle safeLocalAllocHandle = SafeLocalAllocHandle.InvalidHandle; 940 uint dwLength = (uint) Marshal.SizeOf(typeof(uint)); 941 bool result = Win32Native.GetTokenInformation(tokenHandle, 942 (uint) tokenInformationClass, 943 safeLocalAllocHandle, 944 0, 945 out dwLength); 946 int dwErrorCode = Marshal.GetLastWin32Error(); 947 switch (dwErrorCode) { 948 case Win32Native.ERROR_BAD_LENGTH: 949 // special case for TokenSessionId. Falling through 950 case Win32Native.ERROR_INSUFFICIENT_BUFFER: 951 // ptrLength is an [In] param to LocalAlloc 952 UIntPtr ptrLength = new UIntPtr(dwLength); 953 safeLocalAllocHandle.Dispose(); 954 safeLocalAllocHandle = Win32Native.LocalAlloc(Win32Native.LMEM_FIXED, ptrLength); 955 if (safeLocalAllocHandle == null || safeLocalAllocHandle.IsInvalid) 956 throw new OutOfMemoryException(); 957 safeLocalAllocHandle.Initialize(dwLength); 958 959 result = Win32Native.GetTokenInformation(tokenHandle, 960 (uint) tokenInformationClass, 961 safeLocalAllocHandle, 962 dwLength, 963 out dwLength); 964 if (!result) 965 throw new SecurityException(Win32Native.GetMessage(Marshal.GetLastWin32Error())); 966 break; 967 case Win32Native.ERROR_INVALID_HANDLE: 968 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidImpersonationToken")); 969 default: 970 throw new SecurityException(Win32Native.GetMessage(dwErrorCode)); 971 } 972 return safeLocalAllocHandle; 973 } 974 975 [System.Security.SecurityCritical] // auto-generated 976 #if FEATURE_CORRUPTING_EXCEPTIONS 977 [HandleProcessCorruptedStateExceptions] // 978 #endif // FEATURE_CORRUPTING_EXCEPTIONS KerbS4ULogon(string upn, ref SafeAccessTokenHandle safeTokenHandle)979 private unsafe static SafeAccessTokenHandle KerbS4ULogon (string upn, ref SafeAccessTokenHandle safeTokenHandle) 980 { 981 // source name 982 byte[] sourceName = new byte[] { (byte)'C', (byte)'L', (byte)'R' }; // we set the source name to "CLR". 983 984 // ptrLength is an [In] param to LocalAlloc 985 UIntPtr ptrLength = new UIntPtr((uint)(sourceName.Length + 1)); 986 987 using (SafeLocalAllocHandle pSourceName = Win32Native.LocalAlloc(Win32Native.LPTR, ptrLength)) { 988 if (pSourceName == null || pSourceName.IsInvalid) 989 throw new OutOfMemoryException(); 990 991 pSourceName.Initialize((ulong)sourceName.Length + 1); 992 pSourceName.WriteArray(0, sourceName, 0, sourceName.Length); 993 Win32Native.UNICODE_INTPTR_STRING Name = new Win32Native.UNICODE_INTPTR_STRING(sourceName.Length, 994 pSourceName); 995 996 int status; 997 SafeLsaLogonProcessHandle logonHandle = SafeLsaLogonProcessHandle.InvalidHandle; 998 SafeLsaReturnBufferHandle profile = SafeLsaReturnBufferHandle.InvalidHandle; 999 try { 1000 Privilege privilege = null; 1001 1002 RuntimeHelpers.PrepareConstrainedRegions(); 1003 // Try to get an impersonation token. 1004 try { 1005 // Try to enable the TCB privilege if possible 1006 try { 1007 privilege = new Privilege("SeTcbPrivilege"); 1008 privilege.Enable(); 1009 } 1010 catch (PrivilegeNotHeldException) { } 1011 1012 IntPtr dummy = IntPtr.Zero; 1013 status = Win32Native.LsaRegisterLogonProcess(ref Name, ref logonHandle, ref dummy); 1014 if (Win32Native.ERROR_ACCESS_DENIED == Win32Native.LsaNtStatusToWinError(status)) { 1015 // We don't have the Tcb privilege. The best we can hope for is to get an Identification token. 1016 status = Win32Native.LsaConnectUntrusted(ref logonHandle); 1017 } 1018 } 1019 catch { 1020 // protect against exception filter-based luring attacks 1021 if (privilege != null) 1022 privilege.Revert(); 1023 throw; 1024 } 1025 finally { 1026 if (privilege != null) 1027 privilege.Revert(); 1028 } 1029 if (status < 0) // non-negative numbers indicate success 1030 throw GetExceptionFromNtStatus(status); 1031 1032 // package name ("Kerberos") 1033 byte[] arrayPackageName = new byte[Win32Native.MICROSOFT_KERBEROS_NAME.Length + 1]; 1034 Encoding.ASCII.GetBytes(Win32Native.MICROSOFT_KERBEROS_NAME, 0, Win32Native.MICROSOFT_KERBEROS_NAME.Length, arrayPackageName, 0); 1035 1036 // ptrLength is an [In] param to LocalAlloc 1037 ptrLength = new UIntPtr((uint)arrayPackageName.Length); 1038 using (SafeLocalAllocHandle pPackageName = Win32Native.LocalAlloc(Win32Native.LMEM_FIXED, ptrLength)) { 1039 if (pPackageName == null || pPackageName.IsInvalid) 1040 throw new OutOfMemoryException(); 1041 pPackageName.Initialize((ulong)(uint)arrayPackageName.Length); 1042 1043 pPackageName.WriteArray(0, arrayPackageName, 0, arrayPackageName.Length); 1044 Win32Native.UNICODE_INTPTR_STRING PackageName = new Win32Native.UNICODE_INTPTR_STRING(Win32Native.MICROSOFT_KERBEROS_NAME.Length, 1045 pPackageName); 1046 uint packageId = 0; 1047 status = Win32Native.LsaLookupAuthenticationPackage(logonHandle, ref PackageName, ref packageId); 1048 if (status < 0) // non-negative numbers indicate success 1049 throw GetExceptionFromNtStatus(status); 1050 1051 // source context 1052 Win32Native.TOKEN_SOURCE sourceContext = new Win32Native.TOKEN_SOURCE(); 1053 if (!Win32Native.AllocateLocallyUniqueId(ref sourceContext.SourceIdentifier)) 1054 throw new SecurityException(Win32Native.GetMessage(Marshal.GetLastWin32Error())); 1055 sourceContext.Name = new char[8]; 1056 sourceContext.Name[0] = 'C'; sourceContext.Name[1] = 'L'; sourceContext.Name[2] = 'R'; 1057 1058 uint profileSize = 0; 1059 Win32Native.LUID logonId = new Win32Native.LUID(); 1060 Win32Native.QUOTA_LIMITS quotas = new Win32Native.QUOTA_LIMITS(); 1061 int subStatus = 0; 1062 1063 // 1064 // Build the KERB_S4U_LOGON structure. Note that the LSA expects this entire 1065 // structure to be contained within the same block of memory, so we need to allocate 1066 // enough room for both the structure itself and the UPN string in a single buffer 1067 // and do the marshalling into this buffer by hand. 1068 // 1069 1070 byte[] upnBytes = Encoding.Unicode.GetBytes(upn); 1071 1072 Contract.Assert(Marshal.SizeOf(typeof(Win32Native.KERB_S4U_LOGON)) % IntPtr.Size == 0, "Potential allignment issue setting up S4U logon buffer"); 1073 uint logonInfoSize = (uint) (Marshal.SizeOf(typeof(Win32Native.KERB_S4U_LOGON)) + upnBytes.Length); 1074 using (SafeLocalAllocHandle logonInfoBuffer = Win32Native.LocalAlloc(Win32Native.LPTR, new UIntPtr(logonInfoSize))) { 1075 if (logonInfoBuffer == null || logonInfoBuffer.IsInvalid) { 1076 throw new OutOfMemoryException(); 1077 } 1078 1079 logonInfoBuffer.Initialize((ulong)logonInfoSize); 1080 1081 // Write the UPN to the end of the serialized buffer 1082 ulong upnOffset = (ulong)Marshal.SizeOf(typeof(Win32Native.KERB_S4U_LOGON)); 1083 logonInfoBuffer.WriteArray(upnOffset, 1084 upnBytes, 1085 0, 1086 upnBytes.Length); 1087 1088 unsafe { 1089 byte* pLogonInfoBuffer = null; 1090 1091 RuntimeHelpers.PrepareConstrainedRegions(); 1092 try { 1093 logonInfoBuffer.AcquirePointer(ref pLogonInfoBuffer); 1094 1095 // Setup the KERB_S4U_LOGON structure 1096 Win32Native.KERB_S4U_LOGON logonInfo = new Win32Native.KERB_S4U_LOGON(); 1097 logonInfo.MessageType = (uint)KerbLogonSubmitType.KerbS4ULogon; 1098 logonInfo.Flags = 0; 1099 1100 // Point the ClientUpn at the UPN written at the end of this buffer 1101 logonInfo.ClientUpn = new Win32Native.UNICODE_INTPTR_STRING(upnBytes.Length, 1102 new IntPtr(pLogonInfoBuffer + upnOffset)); 1103 1104 logonInfoBuffer.Write(0, logonInfo); 1105 1106 // logon user 1107 status = Win32Native.LsaLogonUser(logonHandle, 1108 ref Name, 1109 (uint)SecurityLogonType.Network, 1110 packageId, 1111 new IntPtr(pLogonInfoBuffer), 1112 (uint)logonInfoBuffer.ByteLength, 1113 IntPtr.Zero, 1114 ref sourceContext, 1115 ref profile, 1116 ref profileSize, 1117 ref logonId, 1118 ref safeTokenHandle, 1119 ref quotas, 1120 ref subStatus); 1121 1122 // If both status and substatus are < 0, substatus is preferred. 1123 if (status == Win32Native.STATUS_ACCOUNT_RESTRICTION && subStatus < 0) 1124 status = subStatus; 1125 if (status < 0) // non-negative numbers indicate success 1126 throw GetExceptionFromNtStatus(status); 1127 if (subStatus < 0) // non-negative numbers indicate success 1128 throw GetExceptionFromNtStatus(subStatus); 1129 } 1130 finally { 1131 if (pLogonInfoBuffer != null) { 1132 logonInfoBuffer.ReleasePointer(); 1133 } 1134 } 1135 } 1136 } 1137 1138 return safeTokenHandle; 1139 } 1140 } 1141 finally { 1142 if (!logonHandle.IsInvalid) 1143 logonHandle.Dispose(); 1144 if (!profile.IsInvalid) 1145 profile.Dispose(); 1146 } 1147 } 1148 } 1149 1150 #if !FEATURE_CORECLR 1151 1152 [SecuritySafeCritical] WindowsIdentity(WindowsIdentity identity)1153 protected WindowsIdentity (WindowsIdentity identity) 1154 : base( identity, null, identity.m_authType, null, null, false ) 1155 { 1156 if (identity == null) 1157 throw new ArgumentNullException("identity"); 1158 1159 Contract.EndContractBlock(); 1160 1161 bool mustDecrement = false; 1162 RuntimeHelpers.PrepareConstrainedRegions(); 1163 try 1164 { 1165 if (!identity.m_safeTokenHandle.IsInvalid && identity.m_safeTokenHandle != SafeAccessTokenHandle.InvalidHandle && identity.m_safeTokenHandle.DangerousGetHandle() != IntPtr.Zero) 1166 { 1167 identity.m_safeTokenHandle.DangerousAddRef(ref mustDecrement); 1168 1169 if (!identity.m_safeTokenHandle.IsInvalid && identity.m_safeTokenHandle.DangerousGetHandle() != IntPtr.Zero) 1170 CreateFromToken(identity.m_safeTokenHandle.DangerousGetHandle()); 1171 1172 m_authType = identity.m_authType; 1173 m_isAuthenticated = identity.m_isAuthenticated; 1174 } 1175 } 1176 finally 1177 { 1178 if (mustDecrement) 1179 identity.m_safeTokenHandle.DangerousRelease(); 1180 } 1181 } 1182 1183 [SecurityCritical] GetTokenInternal()1184 internal IntPtr GetTokenInternal() 1185 { 1186 return m_safeTokenHandle.DangerousGetHandle(); 1187 } 1188 1189 [SecurityCritical] WindowsIdentity(ClaimsIdentity claimsIdentity, IntPtr userToken)1190 internal WindowsIdentity(ClaimsIdentity claimsIdentity, IntPtr userToken) 1191 : base(claimsIdentity) 1192 { 1193 if (userToken != IntPtr.Zero && userToken.ToInt64() > 0) 1194 { 1195 CreateFromToken(userToken); 1196 } 1197 } 1198 1199 /// <summary> 1200 /// Returns a new instance of the base, used when serializing the WindowsIdentity. 1201 /// </summary> CloneAsBase()1202 internal ClaimsIdentity CloneAsBase() 1203 { 1204 return base.Clone(); 1205 } 1206 1207 /// <summary> 1208 /// Returns a new instance of <see cref="WindowsIdentity"/> with values copied from this object. 1209 /// </summary> Clone()1210 public override ClaimsIdentity Clone() 1211 { 1212 return new WindowsIdentity(this); 1213 } 1214 1215 /// <summary> 1216 /// Gets the 'User Claims' from the NTToken that represents this identity 1217 /// </summary> 1218 public virtual IEnumerable<Claim> UserClaims 1219 { 1220 get 1221 { 1222 InitializeClaims(); 1223 1224 return m_userClaims.AsReadOnly(); 1225 } 1226 } 1227 1228 /// <summary> 1229 /// Gets the 'Device Claims' from the NTToken that represents the device the identity is using 1230 /// </summary> 1231 public virtual IEnumerable<Claim> DeviceClaims 1232 { 1233 get 1234 { 1235 InitializeClaims(); 1236 1237 return m_deviceClaims.AsReadOnly(); 1238 } 1239 } 1240 1241 /// <summary> 1242 /// Gets the claims as <see cref="IEnumerable{Claim}"/>, associated with this <see cref="WindowsIdentity"/>. 1243 /// Includes UserClaims and DeviceClaims. 1244 /// </summary> 1245 public override IEnumerable<Claim> Claims 1246 { 1247 get 1248 { 1249 if (!m_claimsInitialized) 1250 { 1251 InitializeClaims(); 1252 } 1253 1254 foreach (Claim claim in base.Claims) 1255 yield return claim; 1256 1257 foreach (Claim claim in m_userClaims) 1258 yield return claim; 1259 1260 foreach (Claim claim in m_deviceClaims) 1261 yield return claim; 1262 } 1263 } 1264 1265 /// <summary> 1266 /// Intenal method to initialize the claim collection. 1267 /// Lazy init is used so claims are not initialzed until needed 1268 /// </summary> 1269 [SecuritySafeCritical] InitializeClaims()1270 void InitializeClaims() 1271 { 1272 if (!m_claimsInitialized) 1273 { 1274 lock (m_claimsIntiailizedLock) 1275 { 1276 if (!m_claimsInitialized) 1277 { 1278 m_userClaims = new List<Claim>(); 1279 m_deviceClaims = new List<Claim>(); 1280 1281 if (!String.IsNullOrEmpty(Name)) 1282 { 1283 // 1284 // Add the name claim only if the WindowsIdentity.Name is populated 1285 // WindowsIdentity.Name will be null when it is the fake anonymous user 1286 // with a token value of IntPtr.Zero 1287 // 1288 m_userClaims.Add(new Claim(NameClaimType, Name, ClaimValueTypes.String, m_issuerName, m_issuerName, this)); 1289 } 1290 1291 // primary sid 1292 AddPrimarySidClaim(m_userClaims); 1293 1294 // group sids 1295 AddGroupSidClaims(m_userClaims); 1296 1297 // The following TokenInformationClass's were part of the Win8 release 1298 if (Environment.IsWindows8OrAbove) 1299 { 1300 // Device group sids 1301 AddDeviceGroupSidClaims(m_deviceClaims, TokenInformationClass.TokenDeviceGroups); 1302 1303 // User token claims 1304 AddTokenClaims(m_userClaims, TokenInformationClass.TokenUserClaimAttributes, ClaimTypes.WindowsUserClaim); 1305 1306 // Device token claims 1307 AddTokenClaims(m_deviceClaims, TokenInformationClass.TokenDeviceClaimAttributes, ClaimTypes.WindowsDeviceClaim); 1308 } 1309 1310 m_claimsInitialized = true; 1311 } 1312 } 1313 } 1314 } 1315 1316 /// <summary> 1317 /// Creates a collection of SID claims that represent the DeviceSidGroups. 1318 /// </summary> 1319 /// this is SafeCritical as it accesss the NT token. 1320 [SecurityCritical] AddDeviceGroupSidClaims(List<Claim> instanceClaims, TokenInformationClass tokenInformationClass)1321 void AddDeviceGroupSidClaims(List<Claim> instanceClaims, TokenInformationClass tokenInformationClass) 1322 { 1323 // special case the anonymous identity. 1324 if (m_safeTokenHandle.IsInvalid) 1325 return; 1326 1327 SafeLocalAllocHandle safeAllocHandle = SafeLocalAllocHandle.InvalidHandle; 1328 try 1329 { 1330 // Retrieve all group sids 1331 1332 safeAllocHandle = GetTokenInformation(m_safeTokenHandle, tokenInformationClass); 1333 int count = Marshal.ReadInt32(safeAllocHandle.DangerousGetHandle()); 1334 IntPtr pSidAndAttributes = new IntPtr((long)safeAllocHandle.DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(Win32Native.TOKEN_GROUPS), "Groups")); 1335 string claimType = null; 1336 1337 for (int i = 0; i < count; ++i) 1338 { 1339 Win32Native.SID_AND_ATTRIBUTES group = (Win32Native.SID_AND_ATTRIBUTES)Marshal.PtrToStructure(pSidAndAttributes, typeof(Win32Native.SID_AND_ATTRIBUTES)); 1340 uint mask = Win32Native.SE_GROUP_ENABLED | Win32Native.SE_GROUP_LOGON_ID | Win32Native.SE_GROUP_USE_FOR_DENY_ONLY; 1341 SecurityIdentifier groupSid = new SecurityIdentifier(group.Sid, true); 1342 if ((group.Attributes & mask) == Win32Native.SE_GROUP_ENABLED) 1343 { 1344 claimType = ClaimTypes.WindowsDeviceGroup; 1345 Claim claim = new Claim(claimType, groupSid.Value, ClaimValueTypes.String, m_issuerName, m_issuerName, this, ClaimTypes.WindowsSubAuthority, Convert.ToString(groupSid.IdentifierAuthority, CultureInfo.InvariantCulture)); 1346 claim.Properties.Add(claimType, ""); 1347 instanceClaims.Add(claim); 1348 } 1349 else if ((group.Attributes & mask) == Win32Native.SE_GROUP_USE_FOR_DENY_ONLY) 1350 { 1351 claimType = ClaimTypes.DenyOnlyWindowsDeviceGroup; 1352 Claim claim = new Claim(claimType, groupSid.Value, ClaimValueTypes.String, m_issuerName, m_issuerName, this, ClaimTypes.WindowsSubAuthority, Convert.ToString(groupSid.IdentifierAuthority, CultureInfo.InvariantCulture)); 1353 claim.Properties.Add(claimType, ""); 1354 instanceClaims.Add(claim); 1355 } 1356 1357 pSidAndAttributes = new IntPtr((long)pSidAndAttributes + Win32Native.SID_AND_ATTRIBUTES.SizeOf); 1358 } 1359 } 1360 finally 1361 { 1362 safeAllocHandle.Close(); 1363 } 1364 } 1365 1366 /// <summary> 1367 /// Creates a collection of SID claims that represent the users groups. 1368 /// </summary> 1369 /// this is SafeCritical as it accesss the NT token. 1370 [SecurityCritical] AddGroupSidClaims(List<Claim> instanceClaims)1371 void AddGroupSidClaims(List<Claim> instanceClaims) 1372 { 1373 // special case the anonymous identity. 1374 if (m_safeTokenHandle.IsInvalid) 1375 return; 1376 1377 SafeLocalAllocHandle safeAllocHandle = SafeLocalAllocHandle.InvalidHandle; 1378 SafeLocalAllocHandle safeAllocHandlePrimaryGroup = SafeLocalAllocHandle.InvalidHandle; 1379 try 1380 { 1381 // Retrieve the primary group sid 1382 safeAllocHandlePrimaryGroup = GetTokenInformation(m_safeTokenHandle, TokenInformationClass.TokenPrimaryGroup); 1383 Win32Native.TOKEN_PRIMARY_GROUP primaryGroup = (Win32Native.TOKEN_PRIMARY_GROUP)Marshal.PtrToStructure(safeAllocHandlePrimaryGroup.DangerousGetHandle(), typeof(Win32Native.TOKEN_PRIMARY_GROUP)); 1384 SecurityIdentifier primaryGroupSid = new SecurityIdentifier(primaryGroup.PrimaryGroup, true); 1385 1386 // only add one primary group sid 1387 bool foundPrimaryGroupSid = false; 1388 1389 // Retrieve all group sids, primary group sid is one of them 1390 safeAllocHandle = GetTokenInformation(m_safeTokenHandle, TokenInformationClass.TokenGroups); 1391 int count = Marshal.ReadInt32(safeAllocHandle.DangerousGetHandle()); 1392 IntPtr pSidAndAttributes = new IntPtr((long)safeAllocHandle.DangerousGetHandle() + (long)Marshal.OffsetOf(typeof(Win32Native.TOKEN_GROUPS), "Groups")); 1393 for (int i = 0; i < count; ++i) 1394 { 1395 Win32Native.SID_AND_ATTRIBUTES group = (Win32Native.SID_AND_ATTRIBUTES)Marshal.PtrToStructure(pSidAndAttributes, typeof(Win32Native.SID_AND_ATTRIBUTES)); 1396 uint mask = Win32Native.SE_GROUP_ENABLED | Win32Native.SE_GROUP_LOGON_ID | Win32Native.SE_GROUP_USE_FOR_DENY_ONLY; 1397 SecurityIdentifier groupSid = new SecurityIdentifier(group.Sid, true); 1398 1399 if ((group.Attributes & mask) == Win32Native.SE_GROUP_ENABLED) 1400 { 1401 if (!foundPrimaryGroupSid && StringComparer.Ordinal.Equals( groupSid.Value, primaryGroupSid.Value)) 1402 { 1403 instanceClaims.Add(new Claim(ClaimTypes.PrimaryGroupSid, groupSid.Value, ClaimValueTypes.String, m_issuerName, m_issuerName, this, ClaimTypes.WindowsSubAuthority, Convert.ToString(groupSid.IdentifierAuthority, CultureInfo.InvariantCulture))); 1404 foundPrimaryGroupSid = true; 1405 } 1406 //Primary group sid generates both regular groupsid claim and primary groupsid claim 1407 instanceClaims.Add(new Claim(ClaimTypes.GroupSid, groupSid.Value, ClaimValueTypes.String, m_issuerName, m_issuerName, this, ClaimTypes.WindowsSubAuthority, Convert.ToString(groupSid.IdentifierAuthority, CultureInfo.InvariantCulture))); 1408 1409 } 1410 else if ((group.Attributes & mask) == Win32Native.SE_GROUP_USE_FOR_DENY_ONLY) 1411 { 1412 if (!foundPrimaryGroupSid && StringComparer.Ordinal.Equals( groupSid.Value, primaryGroupSid.Value)) 1413 { 1414 instanceClaims.Add(new Claim(ClaimTypes.DenyOnlyPrimaryGroupSid, groupSid.Value, ClaimValueTypes.String, m_issuerName, m_issuerName, this, ClaimTypes.WindowsSubAuthority, Convert.ToString(groupSid.IdentifierAuthority, CultureInfo.InvariantCulture))); 1415 foundPrimaryGroupSid = true; 1416 } 1417 //Primary group sid generates both regular groupsid claim and primary groupsid claim 1418 instanceClaims.Add(new Claim(ClaimTypes.DenyOnlySid, groupSid.Value, ClaimValueTypes.String, m_issuerName, m_issuerName, this, ClaimTypes.WindowsSubAuthority, Convert.ToString(groupSid.IdentifierAuthority, CultureInfo.InvariantCulture))); 1419 } 1420 pSidAndAttributes = new IntPtr((long)pSidAndAttributes + Win32Native.SID_AND_ATTRIBUTES.SizeOf); 1421 } 1422 } 1423 finally 1424 { 1425 safeAllocHandle.Close(); 1426 safeAllocHandlePrimaryGroup.Close(); 1427 } 1428 } 1429 1430 /// <summary> 1431 /// Creates a Windows SID Claim and adds to collection of claims. 1432 /// </summary> 1433 /// this is SafeCritical as it accesss the NT token. 1434 [SecurityCritical] AddPrimarySidClaim(List<Claim> instanceClaims)1435 void AddPrimarySidClaim(List<Claim> instanceClaims) 1436 { 1437 // special case the anonymous identity. 1438 if (m_safeTokenHandle.IsInvalid) 1439 return; 1440 1441 SafeLocalAllocHandle safeAllocHandle = SafeLocalAllocHandle.InvalidHandle; 1442 try 1443 { 1444 safeAllocHandle = GetTokenInformation(m_safeTokenHandle, TokenInformationClass.TokenUser); 1445 Win32Native.SID_AND_ATTRIBUTES user = (Win32Native.SID_AND_ATTRIBUTES)Marshal.PtrToStructure(safeAllocHandle.DangerousGetHandle(), typeof(Win32Native.SID_AND_ATTRIBUTES)); 1446 uint mask = Win32Native.SE_GROUP_USE_FOR_DENY_ONLY; 1447 1448 SecurityIdentifier sid = new SecurityIdentifier(user.Sid, true); 1449 1450 if (user.Attributes == 0) 1451 { 1452 instanceClaims.Add(new Claim(ClaimTypes.PrimarySid, sid.Value, ClaimValueTypes.String, m_issuerName, m_issuerName, this, ClaimTypes.WindowsSubAuthority, Convert.ToString(sid.IdentifierAuthority, CultureInfo.InvariantCulture))); 1453 } 1454 else if ((user.Attributes & mask) == Win32Native.SE_GROUP_USE_FOR_DENY_ONLY) 1455 { 1456 instanceClaims.Add(new Claim(ClaimTypes.DenyOnlyPrimarySid, sid.Value, ClaimValueTypes.String, m_issuerName, m_issuerName, this, ClaimTypes.WindowsSubAuthority, Convert.ToString(sid.IdentifierAuthority, CultureInfo.InvariantCulture))); 1457 } 1458 } 1459 finally 1460 { 1461 safeAllocHandle.Close(); 1462 } 1463 } 1464 1465 [SecurityCritical] AddTokenClaims(List<Claim> instanceClaims, TokenInformationClass tokenInformationClass, string propertyValue)1466 void AddTokenClaims(List<Claim> instanceClaims, TokenInformationClass tokenInformationClass, string propertyValue) 1467 { 1468 // special case the anonymous identity. 1469 if (m_safeTokenHandle.IsInvalid) 1470 return; 1471 1472 SafeLocalAllocHandle safeAllocHandle = SafeLocalAllocHandle.InvalidHandle; 1473 1474 try 1475 { 1476 SafeLocalAllocHandle safeLocalAllocHandle = SafeLocalAllocHandle.InvalidHandle; 1477 safeAllocHandle = GetTokenInformation(m_safeTokenHandle, tokenInformationClass); 1478 1479 Win32Native.CLAIM_SECURITY_ATTRIBUTES_INFORMATION claimAttributes = (Win32Native.CLAIM_SECURITY_ATTRIBUTES_INFORMATION)Marshal.PtrToStructure(safeAllocHandle.DangerousGetHandle(), typeof(Win32Native.CLAIM_SECURITY_ATTRIBUTES_INFORMATION)); 1480 // An attribute represents a collection of claims. Inside each attribute a claim can be multivalued, we create a claim for each value. 1481 // It is a ragged multi-dimentional array, where each cell can be of different lenghts. 1482 1483 // index into array of claims. 1484 long offset = 0; 1485 1486 for (int attribute = 0; attribute < claimAttributes.AttributeCount; attribute++) 1487 { 1488 IntPtr pAttribute = new IntPtr(claimAttributes.Attribute.pAttributeV1.ToInt64() + offset); 1489 Win32Native.CLAIM_SECURITY_ATTRIBUTE_V1 windowsClaim = (Win32Native.CLAIM_SECURITY_ATTRIBUTE_V1)Marshal.PtrToStructure(pAttribute, typeof(Win32Native.CLAIM_SECURITY_ATTRIBUTE_V1)); 1490 1491 // the switch was written this way, which appears to have multiple for loops, because each item in the ValueCount is of the same ValueType. This saves the type check each item. 1492 switch (windowsClaim.ValueType) 1493 { 1494 case Win32Native.CLAIM_SECURITY_ATTRIBUTE_TYPE_STRING: 1495 IntPtr[] stringPointers = new IntPtr[windowsClaim.ValueCount]; 1496 Marshal.Copy(windowsClaim.Values.ppString, stringPointers, 0, (int)windowsClaim.ValueCount); 1497 1498 for (int item = 0; item < windowsClaim.ValueCount; item++) 1499 { 1500 instanceClaims.Add( new Claim(windowsClaim.Name, Marshal.PtrToStringAuto(stringPointers[item]), ClaimValueTypes.String, m_issuerName, m_issuerName, this, propertyValue, string.Empty)); 1501 } 1502 break; 1503 1504 case Win32Native.CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64: 1505 Int64[] intValues = new Int64[windowsClaim.ValueCount]; 1506 Marshal.Copy(windowsClaim.Values.pInt64, intValues, 0, (int)windowsClaim.ValueCount); 1507 1508 for (int item = 0; item < windowsClaim.ValueCount; item++) 1509 { 1510 instanceClaims.Add(new Claim(windowsClaim.Name, Convert.ToString(intValues[item], CultureInfo.InvariantCulture), ClaimValueTypes.Integer64, m_issuerName, m_issuerName, this, propertyValue, string.Empty)); 1511 } 1512 break; 1513 1514 1515 case Win32Native.CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64: 1516 Int64[] uintValues = new Int64[windowsClaim.ValueCount]; 1517 Marshal.Copy(windowsClaim.Values.pUint64, uintValues, 0, (int)windowsClaim.ValueCount); 1518 1519 for (int item = 0; item < windowsClaim.ValueCount; item++) 1520 { 1521 instanceClaims.Add( new Claim(windowsClaim.Name, Convert.ToString((UInt64)uintValues[item], CultureInfo.InvariantCulture), ClaimValueTypes.UInteger64, m_issuerName, m_issuerName, this, propertyValue, string.Empty)); 1522 } 1523 break; 1524 1525 case Win32Native.CLAIM_SECURITY_ATTRIBUTE_TYPE_BOOLEAN: 1526 Int64[] boolValues = new Int64[windowsClaim.ValueCount]; 1527 Marshal.Copy(windowsClaim.Values.pUint64, boolValues, 0, (int)windowsClaim.ValueCount); 1528 1529 for (int item = 0; item < windowsClaim.ValueCount; item++) 1530 { 1531 instanceClaims.Add(new Claim(windowsClaim.Name, 1532 ((UInt64)boolValues[item] == 0 ? Convert.ToString(false, CultureInfo.InvariantCulture) : Convert.ToString(true, CultureInfo.InvariantCulture)), 1533 ClaimValueTypes.Boolean, 1534 m_issuerName, 1535 m_issuerName, 1536 this, 1537 propertyValue, 1538 string.Empty)); 1539 } 1540 break; 1541 1542 1543 // These claim types are defined in the structure found in winnt.h, but I haven't received confirmation (may 2011) that they are supported and are not enabled. 1544 1545 //case Win32Native.CLAIM_SECURITY_ATTRIBUTE_TYPE_FQBN: 1546 // break; 1547 1548 //case Win32Native.CLAIM_SECURITY_ATTRIBUTE_TYPE_SID: 1549 // break; 1550 1551 //case Win32Native.CLAIM_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING: 1552 // break; 1553 1554 } 1555 1556 offset += Marshal.SizeOf(windowsClaim); 1557 } 1558 } 1559 finally 1560 { 1561 safeAllocHandle.Close(); 1562 } 1563 } 1564 1565 } 1566 #endif 1567 1568 [Serializable] 1569 internal enum KerbLogonSubmitType : int { 1570 KerbInteractiveLogon = 2, 1571 KerbSmartCardLogon = 6, 1572 KerbWorkstationUnlockLogon = 7, 1573 KerbSmartCardUnlockLogon = 8, 1574 KerbProxyLogon = 9, 1575 KerbTicketLogon = 10, 1576 KerbTicketUnlockLogon = 11, 1577 KerbS4ULogon = 12 1578 } 1579 1580 [Serializable] 1581 internal enum SecurityLogonType : int { 1582 Interactive = 2, 1583 Network, 1584 Batch, 1585 Service, 1586 Proxy, 1587 Unlock 1588 } 1589 1590 [Serializable] 1591 internal enum TokenType : int { 1592 TokenPrimary = 1, 1593 TokenImpersonation 1594 } 1595 1596 [Serializable] 1597 internal enum TokenInformationClass : int { 1598 TokenUser = 1, 1599 TokenGroups, 1600 TokenPrivileges, 1601 TokenOwner, 1602 TokenPrimaryGroup, 1603 TokenDefaultDacl, 1604 TokenSource, 1605 TokenType, 1606 TokenImpersonationLevel, 1607 TokenStatistics, 1608 TokenRestrictedSids, 1609 TokenSessionId, 1610 TokenGroupsAndPrivileges, 1611 TokenSessionReference, 1612 TokenSandBoxInert, 1613 TokenAuditPolicy, 1614 TokenOrigin, 1615 TokenElevationType, 1616 TokenLinkedToken, 1617 TokenElevation, 1618 TokenHasRestrictions, 1619 TokenAccessInformation, 1620 TokenVirtualizationAllowed, 1621 TokenVirtualizationEnabled, 1622 TokenIntegrityLevel, 1623 TokenUIAccess, 1624 TokenMandatoryPolicy, 1625 TokenLogonSid, 1626 TokenIsAppContainer, 1627 TokenCapabilities, 1628 TokenAppContainerSid, 1629 TokenAppContainerNumber, 1630 TokenUserClaimAttributes, 1631 TokenDeviceClaimAttributes, 1632 TokenRestrictedUserClaimAttributes, 1633 TokenRestrictedDeviceClaimAttributes, 1634 TokenDeviceGroups, 1635 TokenRestrictedDeviceGroups, 1636 MaxTokenInfoClass // MaxTokenInfoClass should always be the last enum 1637 } 1638 } 1639