Set permissions for directorys/subdirectorys/files - c#

I want to be able to set the persmissions for subfolders and files inside a targeted folder for a specific user.
Up until now i found out how to set the permissions for a specific folder. But not for subfolders and files inside the original folder.
After extensive internet search i could not find any clue on how to tackle this problem. Also the windows doku just shows how to set permission for only a directory.
class DirectoryPermissions
{
public static void DirectoryPermissionsMain(string Directory, string Account, string Rights, int Takeaway, string Domain)
{
try
{
string DirectoryName = Directory;
Console.WriteLine("Adding access control entry for " + DirectoryName);
if(Takeaway == 0 && Rights.Equals("Read")){
AddDirectorySecurity(DirectoryName, Domain + #"\" + Account, FileSystemRights.ReadData, AccessControlType.Allow);
Console.WriteLine("Removing access control entry from " + DirectoryName);
}
MessageBox.Show("Done");
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadLine();
}
// 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);
}
}
I hope one of you can point me in the right direction.

You have to add another AccessRule with InheritanceFlags set to ContainerInherit AND ObjectInherit.
To get the permissions to propgate to child folders, the PropagationFlag is set to Inherit only.
Here's an example below
public void PropogateSecurity(string userid,string directory)
{
var myDirectoryInfo = new DirectoryInfo(directory);
var myDirectorySecurity = myDirectoryInfo.GetAccessControl();
myDirectorySecurity.AddAccessRule(new FileSystemAccessRule(userid, FileSystemRights.Modify, InheritanceFlags.ContainerInherit, PropagationFlags.InheritOnly, AccessControlType.Allow));
myDirectorySecurity.AddAccessRule(new FileSystemAccessRule(userid, FileSystemRights.Modify, InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly, AccessControlType.Allow));
myDirectoryInfo.SetAccessControl(myDirectorySecurity);
}
You can also do this with recursion, but the above would be my preferred method as cleaning up permissions would be annoying.

Related

C# File/Directory Permissions for local share

I need a file to be editable by all local users. The application saves common information to all users in its own folder under ProgramData. I need to guarantee reading and writing to all users, it is so little information that it does not merit the use of a database.
I get the path to the folder from:Path.Combine(Application.CommonAppDataPath, "InfoConfig");
All users can read, write and create in this folder. Except the files that are created by the other users.
I already tried to remove Creator Owner without success. So my last attempt was not to inherit from the container folder and create the permissions from scratch for SYSTEM, Administrators and Users. But it didn't work either, here is my code.
string sharedFolder = Path.Combine(Application.CommonAppDataPath, "InfoConfig");
if (!Directory.Exists(sharedFolder))
{
DirectoryInfo directoryInfo = Directory.CreateDirectory(sharedFolder);
DirectorySecurity directorySecurity = directoryInfo.GetAccessControl();
directorySecurity.SetAccessRuleProtection(true, false);
FileSystemRights fileSystemRights =
FileSystemRights.FullControl |
FileSystemRights.Modify |
FileSystemRights.Read |
FileSystemRights.Delete;
SecurityIdentifier usersSid =
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
SecurityIdentifier systemSid =
new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
SecurityIdentifier adminsSid =
new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
FileSystemAccessRule rule =
new FileSystemAccessRule(systemSid, fileSystemRights, AccessControlType.Allow);
directorySecurity.AddAccessRule(rule);
rule = new FileSystemAccessRule(adminsSid, fileSystemRights, AccessControlType.Allow);
directorySecurity.AddAccessRule(rule);
rule = new FileSystemAccessRule(usersSid, FileSystemRights.Read
| FileSystemRights.Write
| FileSystemRights.Modify,
AccessControlType.Allow);
directorySecurity.AddAccessRule(rule);
directoryInfo.SetAccessControl(directorySecurity);
}
It still doesn't work. What am I doing wrong?
I have only considered the below snippet for usersSid, you can tweak it for the other userTypes as well
Have added ObjectSecurity.ModifyAccessRule(AccessControlModification, AccessRule, Boolean) which applies the specified modification to the Discretionary Access Control List (DACL) associated with this ObjectSecurity object (directorySecurity in our instance).
string sharedFolder = Path.Combine(Application.CommonAppDataPath, "InfoConfig");
if (!Directory.Exists(sharedFolder))
{
DirectoryInfo directoryInfo = Directory.CreateDirectory(sharedFolder);
DirectorySecurity directorySecurity = directoryInfo.GetAccessControl();
directorySecurity.SetAccessRuleProtection(true, false);
FileSystemRights fileSystemRights =
FileSystemRights.FullControl |
FileSystemRights.Modify |
FileSystemRights.Read |
FileSystemRights.Delete;
SecurityIdentifier usersSid =
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
FileSystemAccessRule rule = new FileSystemAccessRule(usersSid, fileSystemRights,InheritanceFlags.None, PropagationFlags.NoPropagateInherit, AccessControlType.Allow);
directorySecurity.AddAccessRule(rule);
bool result;
directorySecurity.ModifyAccessRule(AccessControlModification.Set, rule, out result);
if (!result)
{
throw new InvalidOperationException("Failed to give full-control permission to all users for path " + path);
}
FileSystemAccessRule inheritedRule = new FileSystemAccessRule(
usersSid,
fileSystemRights,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.InheritOnly,
AccessControlType.Allow);
bool inheritedResult;
directorySecurity.ModifyAccessRule(AccessControlModification.Add, inheritedRule, out inheritedResult);
if (!inheritedResult)
{
throw new InvalidOperationException("Failed to give full-control permission inheritance to all users for " + path);
}
directoryInfo.SetAccessControl(directorySecurity);
}

How to check the 'Advanced Share' permissions on a folder using C#?

Hi I want to check if a particular folder is shared with a user.
for the normal share rights, I can the info by
DirectoryInfo di = new DirectoryInfo(path);
DirectorySecurity acl = di.GetAccessControl(AccessControlSections.All);
AuthorizationRuleCollection rules = acl.GetAccessRules(true, true, typeof(NTAccount));
//Go through the rules returned from the DirectorySecurity
foreach (AuthorizationRule rule in rules)
{
//If we find one that matches the identity we are looking for
if (rule.IdentityReference.Value.Equals(NtAccountName, StringComparison.CurrentCultureIgnoreCase))
{
//Cast to a FileSystemAccessRule to check for access rights
if ((((FileSystemAccessRule)rule).FileSystemRights & FileSystemRights.WriteData) > 0)
{
Console.WriteLine(string.Format("{0} has write access to {1}", NtAccountName, path));
}
else
{
Console.WriteLine(string.Format("{0} does not have write access to {1}", NtAccountName, path));
}
}
}
But the problem with this approach is that the if shared the folder using the "Advanced Share" option, as shown in image, it doesn't show any entry into the log.
How to calculate it?

Restrict acces to a folder(and all its files and subdirectories) stored on a sd card C#

Hy,
is there any posibillities to restrict acces to a folder stored on an sd card?
I tried this but it doesn't work...Any ideas are welcome.
Thanks...
public static void setRight(string dirName,string account, FileSystemRights rights, AccessControlType controlType)
{
DirectoryInfo dir = new DirectoryInfo(dirName);
DirectorySecurity dSecurity = new DirectorySecurity();// Directory.GetAccessControl(dirName);
// Add the FileSystemAccessRule to the security settings.
dSecurity.AddAccessRule(new FileSystemAccessRule(account, rights, controlType));
// Set the new access settings.
dir.SetAccessControl(dSecurity);
Directory.SetAccessControl(dirName, dSecurity);
}
Try using the File.Encrypt and File.Decrypt methods. You can use recursion to encrypt directories, by encrypting all files in them.

Change permissions of folders

I want to change some folder permissions (set to Read-Only) to ReadWriteExecute!
I wrote this code, but the folder permission is still Read-Only:
private void ChangePermissions(string folder)
{
string userName = Environment.UserName;
FileSystemAccessRule accessRule = new FileSystemAccessRule(userName, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit
| InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow);
DirectoryInfo directoryInfo = new DirectoryInfo(folder);
DirectorySecurity directorySec = directoryInfo.GetAccessControl();
directorySec.AddAccessRule(accessRule);
directoryInfo.SetAccessControl(directorySec);
}
If I want delete this directory with Directory.Delete(folder, true) I get this error message:
"Access to the path 'entries' is denied."
Sure, the permissions are still Read-Only!
What is wrong here?
You could try something like this:
var dirInfo = new DirectoryInfo(folder);
dirInfo.Attributes &= ~FileAttributes.ReadOnly;
This uses the bitwise logical AND operator (&=) to append to the existing Attributes property the inverse of FileAttributes.ReadOnly (because ~ is bitwise NOT).

folder permissions: Full control granted to all users

I'm working on an application which stores some files in the CommonApplicationData folder. My application has to modify these files. I managed to create a custom action to grant fullcontrol rights to my application folder in the CommonApplicationData folder. But this didn't solve the problem for non-admin users. When I log on as a user and try to modify one of these files, I get the "Access Denied" message.
How can I solve this problem? Thanks.
Here is the code which I used in the Custom Action:
public void GetUsers()
{
SelectQuery sQuery = new SelectQuery("Win32_UserAccount", "Domain='" + System.Environment.UserDomainName.ToString() + "'");
try
{
ManagementObjectSearcher mSearcher = new ManagementObjectSearcher(sQuery);
foreach (ManagementObject mObject in mSearcher.Get())
{
Permission(mObject["Name"].ToString());
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void Permission(string user)
{
string directory = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
string CompanyFolderPath = Path.Combine(directory, "naseelco\\lms2004");
DirectoryInfo myDirectoryInfo = new DirectoryInfo(CompanyFolderPath);
DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl();
string User = System.Environment.UserDomainName + "\\" + user;
myDirectorySecurity.AddAccessRule(new FileSystemAccessRule(User, FileSystemRights.FullControl, AccessControlType.Allow));
myDirectoryInfo.SetAccessControl(myDirectorySecurity);
}
EDIT:
For those who would like to know the solution for this problem:
Instead of granting Access Rights to the parent folder, the individual files int that folder are granted Access Rights for each user. The Permission method in the code above has been modified as follows:
private void Permission(string user)
{
string directory = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
string filePath = Path.Combine(directory, "naseelco\\lms2004\\fms.txt");
FileSecurity fSecurity = File.GetAccessControl(filePath);
FileSystemAccessRule rule = new FileSystemAccessRule(user, FileSystemRights.FullControl, AccessControlType.Allow);
fSecurity.SetAccessRule(rule);
File.SetAccessControl(filePath, fSecurity);
}
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.

Categories