// (c) 2006 Richard Grimes // www.grimes.demon.co.uk using System; using System.Threading; using System.Security.Principal; using System.Security.Permissions; class App { static void Main() { AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); Thread.CurrentPrincipal = new MyPrincipal("Richard", "NTLM", true); try { Console.WriteLine("called OnlyAdministrators"); OnlyAdministrators(); } catch (Exception e) { Console.WriteLine("failed " + e.Message); } } [PrincipalPermission(SecurityAction.Demand, Role=@"BUILTIN\Administrators")] static void OnlyAdministrators() { Type type = typeof(App); System.Reflection.MethodInfo mi = type.GetMethod("OnlyAdministrators", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic); object[] attributes = mi.GetCustomAttributes(typeof(PrincipalPermissionAttribute), false); if (attributes == null) { throw new System.Security.SecurityException("Principal permission denied"); } bool found = false; foreach (object attribute in attributes) { PrincipalPermissionAttribute perm = attribute as PrincipalPermissionAttribute; if (perm.Role.IndexOf(@"BUILTIN\") == -1) continue; found = IsInRole(perm.Role.Substring(8)); if (found) break; } if (!found) { throw new System.Security.SecurityException("Principal permission denied"); } Console.WriteLine("OnlyAdministrators called"); } static bool IsInRole(string group) { WindowsIdentity identity = WindowsIdentity.GetCurrent(); foreach (SecurityIdentifier sid in identity.Groups) { NTAccount account = (NTAccount)sid.Translate(typeof(NTAccount)); if (account.Value == group) return true; } return false; } } class MyPrincipal : IPrincipal, IIdentity { string name; string auth; bool isAuth; public MyPrincipal(string name, string auth, bool isAuth) { this.name = name; this.auth = auth; this.isAuth = isAuth; } public IIdentity Identity { get { return this; } } public bool IsInRole(string role) { return true; } public string AuthenticationType { get { return auth; } } public bool IsAuthenticated { get { return isAuth; } } public string Name { get { return name; } } }