Set directory access rule - c#

I want to block the option to delete a specific folder.
I am using AccessControl:
if (Directory.Exists("D:\\folder"))
{
currentUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
DirectoryInfo dInfo = new DirectoryInfo("D:\\folder");
DirectorySecurity dSecurity = dInfo.GetAccessControl();
dSecurity.AddAccessRule(new FileSystemAccessRule(currentUser, FileSystemRights.Delete, AccessControlType.Deny));
dInfo.SetAccessControl(dSecurity);
}
But when I try to delete D:\\folder, it is deleted.
I checked the current user in the delete event, and it was the same as the currentUser that got the access rule.
What is the problem here?

It looks like you'll need to call dInfo.SetAccessControl(dSecurity); to persist the change.
http://msdn.microsoft.com/en-us/library/d49cww7f(v=vs.110).aspx
(See: "Remarks")

Related

Windows Worker Service Folder Permissions (C#)

Quick question if anyone happens to know. I'm working on a Worker app in dotnet6 that is intended to be made into a service and I need to store a json file somewhere. Doing some research it seems like CommonApplicationData(ex: "C:/ProgramData") is the place to go. My question is, I can't seem to write a file to that folder. I am able to create a directory just fine. But my access is denied to creating an actual file.
This service will be used on servers in the field right now and cannot answer UAC prompts. I'm unsure what else to do. I can have the file created manually and access, edit it. That seems to work fine. But I'd like to have a logs files dynamically created and more.
Heres the code("its pretty basic")
var dirPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "MyServerService");
var path = dirPath + "\\service.json";
var doesDirExist = Directory.Exists(dirPath);
var doesFileExist = File.Exists(path);
if (!doesDirExist || !doesFileExist)
{
Directory.CreateDirectory(dirPath); //<- directory is created just fine
using var file = File.Create(dirPath); // <- fails here (access is denied)
//do stuff
}
This bit of code worked for me. It was indeed a permission issue with the directory being created.
public static bool CreateDirWithAccess(string fullPath, bool readOnly)
{
var dInfo = Directory.CreateDirectory(fullPath);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), readOnly ? FileSystemRights.Read : FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
dInfo.SetAccessControl(dSecurity);
return true;
}

how to give permission to file rather than directory

I'm using below code to give permission to a directory
static void SetPermission(string path)
{
if (Directory.Exists(path))
{
var directoryInfo = new DirectoryInfo(path);
// get the ACL of the directory
var directorySecurity = directoryInfo.GetAccessControl();
// remove inheritance, copying all entries so that they are direct ACEs
directorySecurity.SetAccessRuleProtection(true, true);
// do the operation on the directory
directoryInfo.SetAccessControl(directorySecurity);
// re-read the ACL
directorySecurity = directoryInfo.GetAccessControl();
// get the well known SID for "Users"
var sid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
// loop through every ACE in the ACL
foreach (FileSystemAccessRule rule in directorySecurity.GetAccessRules(true, false, typeof(SecurityIdentifier)))
{
// if the current entry is one with the identity of "Users", remove it
if (rule.IdentityReference == sid)
directorySecurity.RemoveAccessRule(rule);
}
var ntVirtaulUserName = #"NT Service\ServiceName";
// Add the FileSystemAccessRule to the security settings. give full control for user 'NT Service\ServiceName'
directorySecurity.AddAccessRule(new FileSystemAccessRule(ntVirtaulUserName.Replace(#".\", ""), FileSystemRights.FullControl, AccessControlType.Allow));
// do the operation on the directory
directoryInfo.SetAccessControl(directorySecurity);
}
}
This is working when giving permission to a directory (Test),
SetPermission(#"C:\Test");
Now I would like to give permission a file under the Test directory (log.txt), how to do that?
You can use FileInfo Class to handle permission on files. It's usage is like DirectoryInfo. Here is Microsoft document.
public static void AddFileSecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType)
{
FileInfo fInfo = new FileInfo(FileName);
FileSecurity fSecurity = fInfo.GetAccessControl();
fSecurity.AddAccessRule(newFileSystemAccessRule(Account,Rights,ControlType));
fInfo.SetAccessControl(fSecurity);
}
Is below code is fine?
var ntVirtaulUserName = #"NT Service\ServiceName";
// Get a FileSecurity object that represents the
// current security settings.
FileSecurity fSecurity = File.GetAccessControl(#"C:\Test\log.txt");
// Add the FileSystemAccessRule to the security settings.
fSecurity.AddAccessRule(new FileSystemAccessRule(ntVirtaulUserName.Replace(#".\", ""), FileSystemRights.FullControl, AccessControlType.Allow));
// Set the new access settings.
File.SetAccessControl(#"C:\Test\log.txt", fSecurity);

Give specific local Windows user group read access to a folder and its subfolders

I want to programmatically give the local user group <MachineName>\IIS_IUSRS access to a folder and its subfolders.
My current code is looking like this:
DirectoryInfo directoryInfo = new DirectoryInfo(path);
DirectorySecurity directorySecurity = directoryInfo.GetAccessControl();
var groupName = Environment.MachineName + #"\IIS_IUSRS";
directorySecurity.AddAccessRule(
new FileSystemAccessRule(groupName,
FileSystemRights.Read,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None,
AccessControlType.Allow));
directoryInfo.SetAccessControl(directorySecurity);
But this is throwing a System.Security.Principal.IdentityNotMappedException. Replacing groupName with the SID for new SecurityIdentifier(WellKnownSidType.WorldSid, null); is working.
Do I need to get a SecurityIdenfier for a group and if yes how do I do that? Or do I need to do it completely different for groups?
Edit: BUILTIN\IIS_IUSRS didn't work either as I'm using Windows with German locale.
You don't need to use the SID, I wrote a program for work once which used "DOMAIN\GroupName" and it worked fine. Instead of:
var groupName = Environment.MachineName + #"\IIS_IUSRS";
Try:
var groupName = #".\IIS_IUSRS";

Directory.SetAccessControl set unnecessary permissions

I am trying to set program's installation folder permissions restricted only to Administrators.
There are two scenarios: the folder needs creation and folder already exists.
Here is my code:
public static void CreatePrivateFolder(string path)
{
SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
DirectorySecurity securityRules = new DirectorySecurity();
FileSystemAccessRule fsRule =
new FileSystemAccessRule(sid, FileSystemRights.FullControl,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None, AccessControlType.Allow);
securityRules.SetAccessRule(fsRule);
if (Directory.Exists(path))
{
Directory.SetAccessControl(path, securityRules);
}
else
{
Directory.CreateDirectory(path, securityRules);
}
}
When the folder needs creation, the CreateDirectory works fine, the folder's permissions restricted only to Administrators.
The strange thing is when I am re-run this code and flow to SetAccessControl - the folder's permissions being reset to regular folder with no restricted access.
What do I'm doing wrong?
Folder security results (for path c:\\folderCheck) :
Update
anrei solution answering my question.
However, it seem to be the same problem in a different way:
If the folder already exists with unrestricted permissions, anrei's code don't seem to be work.
The folder's permissions remain unrestricted.
Thanks!
Use this instead of your if (Directory.Exists(path)) block.
// what is
var existingACL = Directory.GetAccessControl(path);
// remove everything from what is
foreach (FileSystemAccessRule rule in existingACL.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)))
existingACL.RemoveAccessRuleAll(rule);
// add yours to what is
existingACL.AddAccessRule (fsRule);
// set again
Directory.SetAccessControl(path, existingACL);

How we can use DirectorySecurity class for getting write access to a directory?

How we can use DirectorySecurity class for getting write access to a directory?
Method call:
// Add the access control entry to the directory.
AddDirectorySecurity(DirectoryName, #"MYDOMAIN\MyAccount", FileSystemRights.ReadData, AccessControlType.Allow);
Method definition:
// Adds an ACL entry on the specified directory for the specified account.
public static void AddDirectorySecurity(string FileName, string Account, FileSystemRights Rights, AccessControlType ControlType)
{
// Create a new DirectoryInfo object.
DirectoryInfo dInfo = new DirectoryInfo(FileName);
// Get a DirectorySecurity object that represents the
// current security settings.
DirectorySecurity dSecurity = dInfo.GetAccessControl();
// Add the FileSystemAccessRule to the security settings.
dSecurity.AddAccessRule(new FileSystemAccessRule(Account,
Rights,
ControlType));
// Set the new access settings.
dInfo.SetAccessControl(dSecurity);
}
(Taken from MSDN)

Categories

Resources