How to Grant Full Permission to a File Created by My Application for All Users

How to grant full permission to a file created by my application for ALL users?

Note to people using this.

When using literal strings for the FileSystemAccessRule, it should be WellKnownSidType.WorldSid instead of "everyone".

The reason is because there are multiple Window languages and Everyone only applies to EN ones, so for Spanish, it might be "Todos" (or something else).

using System.Security.AccessControl;
using System.Security.Principal;
using System.IO;

private void GrantAccess(string fullPath)
{
DirectoryInfo dInfo = new DirectoryInfo(fullPath);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
dInfo.SetAccessControl(dSecurity);
}

How to give Create, Read and Modify permissions to all users for a file created by my application in C:\ProgramData?

I would use a folder in the Environment.SpecialFolder enum.

Example:

var path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

folder permissions: Full control granted to all users

A good solution is to grant full control to Everyone using xcacls.exe or any other ACL tool. This tool can be added as a custom action in your setup project.

Granting privileges to each user is not recommended because future accounts will not be covered. Also, doing this through custom code doesn't always work. Windows permissions are a bit tricky when it comes to controlling them through code.

How to grant permission to users for a directory using command line in Windows?

As of Vista, cacls is deprecated. Here's the first couple of help lines:

C:\>cacls
NOTE: Cacls is now deprecated, please use Icacls.

Displays or modifies access control lists (ACLs) of files

You should use icacls instead. This is how you grant John full control over D:\test folder and all its subfolders:

C:\>icacls "D:\test" /grant John:(OI)(CI)F /T

According do MS documentation:

  • F = Full Control
  • CI = Container Inherit - This flag indicates that subordinate containers will inherit this ACE.
  • OI = Object Inherit - This flag indicates that subordinate files will inherit the ACE.
  • /T = Apply recursively to existing files and sub-folders. (OI and CI only apply to new files and sub-folders). Credit: comment by @AlexSpence.

For complete documentation, you may run "icacls" with no arguments or see the Microsoft documentation here and here

How to programatically grant a virtual user permission to a folder (or file)

After sitting on this for a bit, I found a solution. It may not be the most elegant, but it should work for my purposes. I had all of the "parts", but was just doing things in the wrong order.

Previously, I was trying to change the user during the install process, which wasn't working. What I ended up doing was allow the service to install as the LOCAL SYSTEM account, and then change to the virtual account user during the OnStart method of the actual program.

So:

    protected override void OnStart(string[] args)
{
string alhadminPath = System.IO.Path.Combine(pathToFolder, alohadmin);

try
{
// Update the service state to start pending
ServiceStatus serviceStatus = new ServiceStatus
{
dwCurrentState = ServiceState.SERVICE_START_PENDING,
dwWaitHint = 100000
};
SetServiceStatus(this.ServiceHandle, ref serviceStatus);

// Update the logs
eventLog1.WriteEntry("Starting Service", EventLogEntryType.Information, eventId++);
SimpleLog.Info("RAL Config Update Service started");

serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);

// Change the user to the virutal user
using (ManagementObject service = new ManagementObject(new ManagementPath("Win32_Service.Name='RalConfigUpdate'")))
{
object[] wmiParams = new object[11];
wmiParams[6] = serviceUser;
service.InvokeMethod("Change", wmiParams);
}
GiveDirectoryAccess(alhadminPath, serviceUser);
}
catch (Exception e)
{
eventLog1.WriteEntry("Service failed to start", EventLogEntryType.Error, eventId++);
SimpleLog.Log(e);
throw;
}
}

This is working the way it should, and should also satisfy the security procedures. Thanks everyone.

C# - Set Directory Permissions for All Users in Windows 7

You also need to call SetAccessControl to apply the changes.

ds = di.GetAccessControl();
ds.AddAccessRule(fsar);
di.SetAccessControl(ds); // nothing happens until you do this

It seems that the examples on MSDN are sorely lacking in detail, as discussed here. I hacked the code from this article to get the following which behaves well:

static bool SetAcl()
{
FileSystemRights Rights = (FileSystemRights)0;
Rights = FileSystemRights.FullControl;

// *** Add Access Rule to the actual directory itself
FileSystemAccessRule AccessRule = new FileSystemAccessRule("Users", Rights,
InheritanceFlags.None,
PropagationFlags.NoPropagateInherit,
AccessControlType.Allow);

DirectoryInfo Info = new DirectoryInfo(destinationDirectory);
DirectorySecurity Security = Info.GetAccessControl(AccessControlSections.Access);

bool Result = false;
Security.ModifyAccessRule(AccessControlModification.Set, AccessRule, out Result);

if (!Result)
return false;

// *** Always allow objects to inherit on a directory
InheritanceFlags iFlags = InheritanceFlags.ObjectInherit;
iFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;

// *** Add Access rule for the inheritance
AccessRule = new FileSystemAccessRule("Users", Rights,
iFlags,
PropagationFlags.InheritOnly,
AccessControlType.Allow);
Result = false;
Security.ModifyAccessRule(AccessControlModification.Add, AccessRule, out Result);

if (!Result)
return false;

Info.SetAccessControl(Security);

return true;
}


Related Topics



Leave a reply



Submit