Click here to Skip to main content
15,881,898 members
Articles / Programming Languages / C#
Tip/Trick

Resetting User Access Permission in Windows

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
13 Aug 2017CPOL1 min read 6.8K   115   5  
A command line program that resets user access permission in windows

Introduction

With the introduction of User Account Control (UAC) since Windows Vista, access to some system folders has been limited. Modifications to these folders are not permitted without administrator privileges. While UAC is essential for security, in some cases, we want to grant our users full access to certain folders (e.g. C:\ProgramData\[CompanyName]\[AppName], though not recommended by Microsoft). This simple command line program is designed to handle this issue.

Details

To reset access permission, first, we need to make sure that the program always runs as administrator. This can be achieved simply by adding an application manifest file, and add <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> as described in comment UAC Manifest Options.

Next, we need to make sure that access permission is properly inherited by all the subfolders and files in the folder that we want to reset. This is done by methods TraverseDirectory, SetFileInheritance, and SetDirectoryInheritance.

In the end, let's check method SetDirectoryAccess. Note that we use InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit and PropagationFlags.None, as we want our access rule to be applied to not only this folder, but also the subfolders and files. This article explains the relationship between the scope of our access rule and the corresponding flags.

C#
?using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;

namespace PermitAccess
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (var arg in args)
            {
                var success = ResetDirectory(arg);

                var msg = success ?
                    string.Format("Access permission has been reset for 
                                   all subfolders and files in directory {0}", arg) :
                    string.Format("Unable to reset access permission for directory {0}", arg);
                
                Console.WriteLine(msg);
            }

            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }

        public static bool ResetDirectory(string path)
        {
            bool accessSet = false;

            try
            {
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                TraverseDirectory(path);

                accessSet = SetDirectoryAccess(path);
            }
            catch (IOException ex)
            {
                Console.WriteLine("An unexpected exception just occurred. Details:");
                Console.WriteLine(ex.Message);

                return false;
            }

            return accessSet;
        }

        private static void TraverseDirectory(string path)
        {
            // First set inheritance for the dir itself
            SetDirectoryInheritance(path);

            var files = Directory.GetFiles(path);

            foreach (var f in files)
            {
                // Then set inheritance for each file in this dir
                SetFileInheritance(f);
            }

            var directories = Directory.GetDirectories(path);

            foreach (var d in directories)
            {
                // Recursively call this method
                TraverseDirectory(d);
            }
        }

        private static void SetFileInheritance(string path)
        {
            var fileInfo = new FileInfo(path);
            var fileSecurity = fileInfo.GetAccessControl();
            fileSecurity.SetAccessRuleProtection(false, true);
            fileInfo.SetAccessControl(fileSecurity);
        }

        private static void SetDirectoryInheritance(string path)
        {
            var directoryInfo = new DirectoryInfo(path);
            var directorySecurity = directoryInfo.GetAccessControl();
            directorySecurity.SetAccessRuleProtection(false, true);
            directoryInfo.SetAccessControl(directorySecurity);
        }

        private static bool SetDirectoryAccess(string path)
        {
            var directoryInfo = new DirectoryInfo(path);
            var directorySecurity = directoryInfo.GetAccessControl();
            var securityIdentifier = new SecurityIdentifier
                (WellKnownSidType.BuiltinUsersSid,
                null);
            var rule = new FileSystemAccessRule(
                    securityIdentifier,
                    FileSystemRights.FullControl,
                    InheritanceFlags.ContainerInherit |
                    InheritanceFlags.ObjectInherit,
                    PropagationFlags.None,
                    AccessControlType.Allow);
            bool modified;

            directorySecurity.ModifyAccessRule(AccessControlModification.Add, rule, out modified);
            directoryInfo.SetAccessControl(directorySecurity);

            return modified;
        }
    }
}

Using the Code

To use the code, you may first build this project, and copy PermitAccess.exe to the output folder of your own program. Inside your program, call:

C#
Process uacProcess = new Process();
uacProcess.StartInfo.FileName = "PermitAccess.exe";
uacProcess.StartInfo.Arguments = @"[Directory to reset]";
uacProcess.Start();

Note that you don't need to force your program to be run as administrator. PermitAccess.exe itself will ask the user for administrator privileges.

You may also run PermitAccess.exe in Windows Command Prompt. Navigate to the folder where PermitAccess.exe is located, and call PermitAccess [Directory to reset].

History

  • Version 1.0. July 30, 2017

License

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --