Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

How to find a user's effective rights on a file

, 12 May 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
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 right

The current file handler used the application pool account to access file shares on the network. However, the client waned to extend the file handler to use the share's effective rights with the current logged in user. The application would construct the url's on the page in the following format

http://sharepointsite/site1/filehandler.ashx?\\networkshare\sharename\1.pdf


Since I could not impersonate the current logged in user, I had to figure out if the user had access to the share or not within the file handler.

The helper class would take a string of the current user in the format of "domain\username" and a string of the share name. It would then find all the SIDs of the user and store them in a string array. Next it would find all the grant and deny SIDs on the file share. Finally it will compare the two and send a bool back if the user could see the file or not.




 
 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;
        }
    }  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

bradcurtis74
Software Developer (Senior) Microlink LLC
United States United States
No Biography provided
Follow on   Google+

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web03 | 2.8.141015.1 | Last Updated 12 May 2014
Article Copyright 2014 by bradcurtis74
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid