passed 70-487 today
Now onto Sharepoint 2013
Tuesday, April 29, 2014
Monday, April 7, 2014
How to find a user's effective rights on a file
A client wanted a handler to figure out the current user's effective rights. I could not impersonate the user, so we needed to check the user's rights. Here is the class I am using to do it.
public static class FileSystemRightsEx
{
public static bool HasRights(this FileSystemRights rights, FileSystemRights testRights)
{
return (rights & testRights) == testRights;
}
}
public static class FileSystemEffectiveRights
{
public static FileSystemRights GetRights(string userName, string path)
{
ULSLoggingService.LogUITrace("Trying to get rights for the path.");
if (string.IsNullOrEmpty(userName))
{
throw new ArgumentException("userName");
}
if (!Directory.Exists(path) && !File.Exists(path))
{
throw new ArgumentException(string.Format("path: {0}", path));
}
return GetEffectiveRights(userName, path);
}
/// <summary>
/// based on the rules retrieved figure out if the user has acces
/// </summary>
/// <param name="userName">user name no domain</param>
/// <param name="path">file share path</param>
/// <returns></returns>
private static FileSystemRights GetEffectiveRights(string userName, string path)
{
FileSystemAccessRule[] accessRules = GetAccessRulesArray(userName, path);
FileSystemRights denyRights = 0;
FileSystemRights allowRights = 0;
for (int index = 0, total = accessRules.Length; index < total; index++)
{
FileSystemAccessRule rule = accessRules[index];
if (rule.AccessControlType == AccessControlType.Deny)
{
denyRights |= rule.FileSystemRights;
}
else
{
allowRights |= rule.FileSystemRights;
}
}
return (allowRights | denyRights) ^ denyRights;
}
/// <summary>
/// Compare the file system access rules with the sids comming from the user
/// if we might have a deny rule or an allow rule
/// </summary>
/// <param name="userName">user name without domain</param>
/// <param name="path">path to file</param>
/// <returns></returns>
private static FileSystemAccessRule[] GetAccessRulesArray(string userName, string path)
{
ULSLoggingService.LogUITrace(string.Format("Trying to get access rules array for user '{0}' and path '{1}'.", userName, path));
// get all access rules for the path - this works for a directory path as well as a file path
AuthorizationRuleCollection authorizationRules = (new FileInfo(path)).GetAccessControl().GetAccessRules(true, true, typeof(SecurityIdentifier));
foreach (AuthorizationRule rule in authorizationRules)
{
ULSLoggingService.LogUITrace(string.Format("FileSystem Rule name: '{0}'",rule.IdentityReference.Translate(typeof(NTAccount)).Value));
}
// get the user's sids
string[] sids = GetSecurityIdentifierArray(userName);
// get the access rules filtered by the user's sids
return (from rule in authorizationRules.Cast<FileSystemAccessRule>()
where sids.Contains(rule.IdentityReference.Value)
select rule).ToArray();
}
/// <summary>
/// Get the group SIDS of the current user
/// assumption: that users are unique within the domain
/// </summary>
/// <param name="userName">user's name without the domain</param>
/// <returns>array of sids</returns>
private static string[] GetSecurityIdentifierArray(string userName)
{
// connect to the domain
PrincipalContext pc = new PrincipalContext(ContextType.Domain);
// search for the domain user
UserPrincipal user = new UserPrincipal(pc) { SamAccountName = userName };
PrincipalSearcher searcher = new PrincipalSearcher { QueryFilter = user };
user = searcher.FindOne() as UserPrincipal;
if (user == null)
{
throw new ApplicationException(string.Format("Invalid User Name: {0}", userName));
}
// use WindowsIdentity to get the user's groups
WindowsIdentity windowsIdentity = new WindowsIdentity(user.UserPrincipalName);
string[] sids = new string[windowsIdentity.Groups.Count + 1];
sids[0] = windowsIdentity.User.Value;
for (int index = 1, total = windowsIdentity.Groups.Count; index < total; index++)
{
sids[index] = windowsIdentity.Groups[index].Value;
try
{
ULSLoggingService.LogUITrace("User:" + userName + "User Group:" + windowsIdentity.Groups[index].Translate(typeof(NTAccount)).Value);
}
catch (Exception ex)
{
ULSLoggingService.LogUIException("proplem with logging", ex);
}
}
return sids;
}
} CodeProject
public static class FileSystemRightsEx
{
public static bool HasRights(this FileSystemRights rights, FileSystemRights testRights)
{
return (rights & testRights) == testRights;
}
}
public static class FileSystemEffectiveRights
{
public static FileSystemRights GetRights(string userName, string path)
{
ULSLoggingService.LogUITrace("Trying to get rights for the path.");
if (string.IsNullOrEmpty(userName))
{
throw new ArgumentException("userName");
}
if (!Directory.Exists(path) && !File.Exists(path))
{
throw new ArgumentException(string.Format("path: {0}", path));
}
return GetEffectiveRights(userName, path);
}
/// <summary>
/// based on the rules retrieved figure out if the user has acces
/// </summary>
/// <param name="userName">user name no domain</param>
/// <param name="path">file share path</param>
/// <returns></returns>
private static FileSystemRights GetEffectiveRights(string userName, string path)
{
FileSystemAccessRule[] accessRules = GetAccessRulesArray(userName, path);
FileSystemRights denyRights = 0;
FileSystemRights allowRights = 0;
for (int index = 0, total = accessRules.Length; index < total; index++)
{
FileSystemAccessRule rule = accessRules[index];
if (rule.AccessControlType == AccessControlType.Deny)
{
denyRights |= rule.FileSystemRights;
}
else
{
allowRights |= rule.FileSystemRights;
}
}
return (allowRights | denyRights) ^ denyRights;
}
/// <summary>
/// Compare the file system access rules with the sids comming from the user
/// if we might have a deny rule or an allow rule
/// </summary>
/// <param name="userName">user name without domain</param>
/// <param name="path">path to file</param>
/// <returns></returns>
private static FileSystemAccessRule[] GetAccessRulesArray(string userName, string path)
{
ULSLoggingService.LogUITrace(string.Format("Trying to get access rules array for user '{0}' and path '{1}'.", userName, path));
// get all access rules for the path - this works for a directory path as well as a file path
AuthorizationRuleCollection authorizationRules = (new FileInfo(path)).GetAccessControl().GetAccessRules(true, true, typeof(SecurityIdentifier));
foreach (AuthorizationRule rule in authorizationRules)
{
ULSLoggingService.LogUITrace(string.Format("FileSystem Rule name: '{0}'",rule.IdentityReference.Translate(typeof(NTAccount)).Value));
}
// get the user's sids
string[] sids = GetSecurityIdentifierArray(userName);
// get the access rules filtered by the user's sids
return (from rule in authorizationRules.Cast<FileSystemAccessRule>()
where sids.Contains(rule.IdentityReference.Value)
select rule).ToArray();
}
/// <summary>
/// Get the group SIDS of the current user
/// assumption: that users are unique within the domain
/// </summary>
/// <param name="userName">user's name without the domain</param>
/// <returns>array of sids</returns>
private static string[] GetSecurityIdentifierArray(string userName)
{
// connect to the domain
PrincipalContext pc = new PrincipalContext(ContextType.Domain);
// search for the domain user
UserPrincipal user = new UserPrincipal(pc) { SamAccountName = userName };
PrincipalSearcher searcher = new PrincipalSearcher { QueryFilter = user };
user = searcher.FindOne() as UserPrincipal;
if (user == null)
{
throw new ApplicationException(string.Format("Invalid User Name: {0}", userName));
}
// use WindowsIdentity to get the user's groups
WindowsIdentity windowsIdentity = new WindowsIdentity(user.UserPrincipalName);
string[] sids = new string[windowsIdentity.Groups.Count + 1];
sids[0] = windowsIdentity.User.Value;
for (int index = 1, total = windowsIdentity.Groups.Count; index < total; index++)
{
sids[index] = windowsIdentity.Groups[index].Value;
try
{
ULSLoggingService.LogUITrace("User:" + userName + "User Group:" + windowsIdentity.Groups[index].Translate(typeof(NTAccount)).Value);
}
catch (Exception ex)
{
ULSLoggingService.LogUIException("proplem with logging", ex);
}
}
return sids;
}
} CodeProject
Subscribe to:
Posts (Atom)