3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 // PrincipalPermission.cs
8 // <OWNER>Microsoft</OWNER>
11 namespace System.Security.Permissions
14 using SecurityElement = System.Security.SecurityElement;
15 using System.Security.Util;
17 using System.Collections;
18 using System.Collections.Generic;
19 using System.Security.Principal;
21 using System.Threading;
22 using System.Globalization;
23 using System.Reflection;
24 using System.Diagnostics.Contracts;
29 internal bool m_authenticated;
31 internal String m_role;
34 // cache the translation from name to Sid for the case of WindowsPrincipal.
36 private SecurityIdentifier m_sid = null;
37 internal SecurityIdentifier Sid {
38 [System.Security.SecurityCritical] // auto-generated
40 if (String.IsNullOrEmpty(m_role))
44 NTAccount ntAccount = new NTAccount(m_role);
45 IdentityReferenceCollection source = new IdentityReferenceCollection(1);
46 source.Add(ntAccount);
47 IdentityReferenceCollection target = NTAccount.Translate(source, typeof(SecurityIdentifier), false);
48 m_sid = target[0] as SecurityIdentifier;
54 #endif // !FEATURE_PAL
56 #if FEATURE_CAS_POLICY
57 internal SecurityElement ToXml()
59 SecurityElement root = new SecurityElement( "Identity" );
62 root.AddAttribute( "Authenticated", "true" );
66 root.AddAttribute( "ID", SecurityElement.Escape( m_id ) );
71 root.AddAttribute( "Role", SecurityElement.Escape( m_role ) );
77 internal void FromXml( SecurityElement e )
79 String elAuth = e.Attribute( "Authenticated" );
82 m_authenticated = String.Compare( elAuth, "true", StringComparison.OrdinalIgnoreCase) == 0;
86 m_authenticated = false;
89 String elID = e.Attribute( "ID" );
99 String elRole = e.Attribute( "Role" );
109 #endif // FEATURE_CAS_POLICY
111 public override int GetHashCode()
113 return ((m_authenticated ? 0 : 101) +
114 (m_id == null ? 0 : m_id.GetHashCode()) +
115 (m_role == null? 0 : m_role.GetHashCode()));
120 [System.Runtime.InteropServices.ComVisible(true)]
122 sealed public class PrincipalPermission : IPermission, IUnrestrictedPermission, ISecurityEncodable, IBuiltInPermission
124 private IDRole[] m_array;
126 public PrincipalPermission( PermissionState state )
128 if (state == PermissionState.Unrestricted)
130 m_array = new IDRole[1];
131 m_array[0] = new IDRole();
132 m_array[0].m_authenticated = true;
133 m_array[0].m_id = null;
134 m_array[0].m_role = null;
136 else if (state == PermissionState.None)
138 m_array = new IDRole[1];
139 m_array[0] = new IDRole();
140 m_array[0].m_authenticated = false;
141 m_array[0].m_id = "";
142 m_array[0].m_role = "";
145 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPermissionState"));
148 public PrincipalPermission( String name, String role )
150 m_array = new IDRole[1];
151 m_array[0] = new IDRole();
152 m_array[0].m_authenticated = true;
153 m_array[0].m_id = name;
154 m_array[0].m_role = role;
157 public PrincipalPermission( String name, String role, bool isAuthenticated )
159 m_array = new IDRole[1];
160 m_array[0] = new IDRole();
161 m_array[0].m_authenticated = isAuthenticated;
162 m_array[0].m_id = name;
163 m_array[0].m_role = role;
166 private PrincipalPermission( IDRole[] array )
171 private bool IsEmpty()
173 for (int i = 0; i < m_array.Length; ++i)
175 if ((m_array[i].m_id == null || !m_array[i].m_id.Equals( "" )) ||
176 (m_array[i].m_role == null || !m_array[i].m_role.Equals( "" )) ||
177 m_array[i].m_authenticated)
185 private bool VerifyType(IPermission perm)
187 // if perm is null, then obviously not of the same type
188 if ((perm == null) || (perm.GetType() != this.GetType())) {
196 public bool IsUnrestricted()
198 for (int i = 0; i < m_array.Length; ++i)
200 if (m_array[i].m_id != null || m_array[i].m_role != null || !m_array[i].m_authenticated)
209 //------------------------------------------------------
211 // IPERMISSION IMPLEMENTATION
213 //------------------------------------------------------
215 public bool IsSubsetOf(IPermission target)
219 return this.IsEmpty();
224 PrincipalPermission operand = (PrincipalPermission)target;
226 if (operand.IsUnrestricted())
228 else if (this.IsUnrestricted())
232 for (int i = 0; i < this.m_array.Length; ++i)
234 bool foundMatch = false;
236 for (int j = 0; j < operand.m_array.Length; ++j)
238 if (operand.m_array[j].m_authenticated == this.m_array[i].m_authenticated &&
239 (operand.m_array[j].m_id == null ||
240 (this.m_array[i].m_id != null && this.m_array[i].m_id.Equals( operand.m_array[j].m_id ))) &&
241 (operand.m_array[j].m_role == null ||
242 (this.m_array[i].m_role != null && this.m_array[i].m_role.Equals( operand.m_array[j].m_role ))))
256 catch (InvalidCastException)
260 Environment.GetResourceString("Argument_WrongType", this.GetType().FullName)
267 public IPermission Intersect(IPermission target)
273 else if (!VerifyType(target))
277 Environment.GetResourceString("Argument_WrongType", this.GetType().FullName)
280 else if (this.IsUnrestricted())
282 return target.Copy();
285 PrincipalPermission operand = (PrincipalPermission)target;
287 if (operand.IsUnrestricted())
292 List<IDRole> idroles = null;
294 for (int i = 0; i < this.m_array.Length; ++i)
296 for (int j = 0; j < operand.m_array.Length; ++j)
298 if (operand.m_array[j].m_authenticated == this.m_array[i].m_authenticated)
300 if (operand.m_array[j].m_id == null ||
301 this.m_array[i].m_id == null ||
302 this.m_array[i].m_id.Equals( operand.m_array[j].m_id ))
306 idroles = new List<IDRole>();
309 IDRole idrole = new IDRole();
311 idrole.m_id = operand.m_array[j].m_id == null ? this.m_array[i].m_id : operand.m_array[j].m_id;
313 if (operand.m_array[j].m_role == null ||
314 this.m_array[i].m_role == null ||
315 this.m_array[i].m_role.Equals( operand.m_array[j].m_role))
317 idrole.m_role = operand.m_array[j].m_role == null ? this.m_array[i].m_role : operand.m_array[j].m_role;
324 idrole.m_authenticated = operand.m_array[j].m_authenticated;
326 idroles.Add( idrole );
328 else if (operand.m_array[j].m_role == null ||
329 this.m_array[i].m_role == null ||
330 this.m_array[i].m_role.Equals( operand.m_array[j].m_role))
334 idroles = new List<IDRole>();
337 IDRole idrole = new IDRole();
340 idrole.m_role = operand.m_array[j].m_role == null ? this.m_array[i].m_role : operand.m_array[j].m_role;
341 idrole.m_authenticated = operand.m_array[j].m_authenticated;
343 idroles.Add( idrole );
355 IDRole[] idrolesArray = new IDRole[idroles.Count];
357 IEnumerator idrolesEnumerator = idroles.GetEnumerator();
360 while (idrolesEnumerator.MoveNext())
362 idrolesArray[index++] = (IDRole)idrolesEnumerator.Current;
365 return new PrincipalPermission( idrolesArray );
369 public IPermission Union(IPermission other)
375 else if (!VerifyType(other))
379 Environment.GetResourceString("Argument_WrongType", this.GetType().FullName)
383 PrincipalPermission operand = (PrincipalPermission)other;
385 if (this.IsUnrestricted() || operand.IsUnrestricted())
387 return new PrincipalPermission( PermissionState.Unrestricted );
390 // Now we have to do a real union
392 int combinedLength = this.m_array.Length + operand.m_array.Length;
393 IDRole[] idrolesArray = new IDRole[combinedLength];
396 for (i = 0; i < this.m_array.Length; ++i)
398 idrolesArray[i] = this.m_array[i];
401 for (j = 0; j < operand.m_array.Length; ++j)
403 idrolesArray[i+j] = operand.m_array[j];
406 return new PrincipalPermission( idrolesArray );
410 [System.Runtime.InteropServices.ComVisible(false)]
411 public override bool Equals(Object obj)
413 IPermission perm = obj as IPermission;
414 if(obj != null && perm == null)
416 if(!this.IsSubsetOf(perm))
418 if(perm != null && !perm.IsSubsetOf(this))
423 [System.Runtime.InteropServices.ComVisible(false)]
424 public override int GetHashCode()
428 for(i = 0; i < m_array.Length; i++)
429 hash += m_array[i].GetHashCode();
433 public IPermission Copy()
435 return new PrincipalPermission( m_array );
438 [System.Security.SecurityCritical] // auto-generated
439 private void ThrowSecurityException()
441 System.Reflection.AssemblyName name = null;
442 System.Security.Policy.Evidence evid = null;
443 PermissionSet.s_fullTrust.Assert();
446 System.Reflection.Assembly asm = Reflection.Assembly.GetCallingAssembly();
447 name = asm.GetName();
448 #if FEATURE_CAS_POLICY
449 if(asm != Assembly.GetExecutingAssembly()) // this condition is to avoid having to marshal mscorlib's evidence (which is always in teh default domain) to the current domain
451 #endif // FEATURE_CAS_POLICY
456 PermissionSet.RevertAssert();
457 throw new SecurityException(Environment.GetResourceString("Security_PrincipalPermission"), name, null, null, null, SecurityAction.Demand, this, this, evid);
460 [System.Security.SecuritySafeCritical] // auto-generated
463 IPrincipal principal = null;
464 #if FEATURE_IMPERSONATION
465 new SecurityPermission(SecurityPermissionFlag.ControlPrincipal).Assert();
466 principal = Thread.CurrentPrincipal;
467 #endif // FEATURE_IMPERSONATION
469 if (principal == null)
470 ThrowSecurityException();
475 // A demand passes when the grant satisfies all entries.
477 int count = this.m_array.Length;
478 bool foundMatch = false;
479 for (int i = 0; i < count; ++i)
481 // If the demand is authenticated, we need to check the identity and role
483 if (m_array[i].m_authenticated)
485 IIdentity identity = principal.Identity;
487 if ((identity.IsAuthenticated &&
488 (m_array[i].m_id == null || String.Compare( identity.Name, m_array[i].m_id, StringComparison.OrdinalIgnoreCase) == 0)))
490 if (m_array[i].m_role == null) {
494 #if !FEATURE_PAL && FEATURE_IMPERSONATION
495 WindowsPrincipal wp = principal as WindowsPrincipal;
496 if (wp != null && m_array[i].Sid != null)
497 foundMatch = wp.IsInRole(m_array[i].Sid);
499 #endif // !FEATURE_PAL && FEATURE_IMPERSONATION
500 foundMatch = principal.IsInRole(m_array[i].m_role);
515 ThrowSecurityException();
518 #if FEATURE_CAS_POLICY
519 public SecurityElement ToXml()
521 SecurityElement root = new SecurityElement( "IPermission" );
523 XMLUtil.AddClassAttribute( root, this.GetType(), "System.Security.Permissions.PrincipalPermission" );
524 // If you hit this assert then most likely you are trying to change the name of this class.
525 // This is ok as long as you change the hard coded string above and change the assert below.
526 Contract.Assert( this.GetType().FullName.Equals( "System.Security.Permissions.PrincipalPermission" ), "Class name changed!" );
528 root.AddAttribute( "version", "1" );
530 int count = m_array.Length;
531 for (int i = 0; i < count; ++i)
533 root.AddChild( m_array[i].ToXml() );
539 public void FromXml(SecurityElement elem)
541 CodeAccessPermission.ValidateElement( elem, this );
543 if (elem.InternalChildren != null && elem.InternalChildren.Count != 0)
545 int numChildren = elem.InternalChildren.Count;
548 m_array = new IDRole[numChildren];
550 IEnumerator enumerator = elem.Children.GetEnumerator();
552 while (enumerator.MoveNext())
554 IDRole idrole = new IDRole();
556 idrole.FromXml( (SecurityElement)enumerator.Current );
558 m_array[count++] = idrole;
562 m_array = new IDRole[0];
565 public override String ToString()
567 return ToXml().ToString();
569 #endif // FEATURE_CAS_POLICY
572 int IBuiltInPermission.GetTokenIndex()
574 return PrincipalPermission.GetTokenIndex();
577 internal static int GetTokenIndex()
579 return BuiltInPermissionIndex.PrincipalPermissionIndex;