folder permissions: Full control granted to all users - c#

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.

Related

How to copy file from a specific folder to a shared folder in C#?

I am trying to copy existing file from a specific folder to a shared folder. So this is the code:
if (!System.IO.File.Exists(fullPath))
{
using (WindowsIdentity.GetCurrent().Impersonate())
{
try
{
image.Save(fullPath);
System.Security.AccessControl.DirectorySecurity sec = System.IO.Directory.GetAccessControl(originalDocumentFolderPath);
FileSystemAccessRule accRule = new FileSystemAccessRule(originalDocumentFolderPath, FileSystemRights.FullControl, AccessControlType.Allow);
sec.AddAccessRule(accRule);
string sharedFolderPath = "\\" + Path.Combine(Environment.MachineName, "Users");
sharedFolderPath = Path.Combine(sharedFolderPath, username);
sharedFolderPath = Path.Combine(sharedFolderPath, "Desktop");
sharedFolderPath = Path.Combine(sharedFolderPath, "SharedFolder");
System.IO.File.Copy(originalDocumentFolderPath, sharedFolderPath);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
And I get this error:
System.Security.Principal.IdentityNotMappedException: 'Some or all
identity references could not be translated.'
at this line:
sec.AddAccessRule(accRule);
What am I doing wrong? If you need more data, please let me know...
EDIT:
Also, the final goal is that this should actually save files into a shared folder on a specific computer in LAN network, but I am currently trying to save it in the shared folder, on the same computer, where program runs.
EDIT 2:
So I tried what suggested by #PaulKaram but I still getting the next error:
From the picture, it can be seen the folder in the Documents where I firstly save image. That goes without problems. When i try to copy it on the specific shared folder on a Desktop, the error above (access denied) arises for the folder already created in Documents.
The error Some or all identity references could not be translated means that the identity/account you're using is not found. Taking a deeper look, we can see that
you have a problem with this line:
FileSystemAccessRule accRule = new FileSystemAccessRule(originalDocumentFolderPath, FileSystemRights.FullControl, AccessControlType.Allow);
Take a look at the FileSystemAccessRule constructor that you're using. Here's the signature:
public FileSystemAccessRule (string identity, System.Security.AccessControl.FileSystemRights fileSystemRights, System.Security.AccessControl.AccessControlType type);
The first argument that should be sent is the identity, as taken from the documentation:
The name of a user account.
I am not sure what you're sending there in originalDocumentFolderPath.
Assuming username hold the identity you're impersonating, that line should be changed to:
FileSystemAccessRule accRule = new FileSystemAccessRule(username, FileSystemRights.FullControl, AccessControlType.Allow);
Two other things that you should be aware of:
First of all, you're working with a shared folder on a network, therefore you need to fix this line:
string sharedFolderPath = "\\" + Path.Combine(Environment.MachineName, "Users");
into this:
string sharedFolderPath = "\\\\" + Path.Combine(Environment.MachineName, "Users");
When you're working with a network folder, you need double back slash at the start, and since in C# a back slash escapes characters, you'll need to write it as \\\\.
Second, you should also note, that you're trying to copy the file and giving it the folder name as destination. To fix this you should add at the end of combining the path of the shared folder this:
sharedFolderPath = Path.Combine(sharedFolderPath, "file.extension");
At the end, here's your full code that should work as intended:
if (!System.IO.File.Exists(fullPath))
{
using (WindowsIdentity.GetCurrent().Impersonate())
{
try
{
image.Save(fullPath);
System.Security.AccessControl.DirectorySecurity sec = System.IO.Directory.GetAccessControl(originalDocumentFolderPath);
FileSystemAccessRule accRule = new FileSystemAccessRule(username, FileSystemRights.FullControl, AccessControlType.Allow);
sec.AddAccessRule(accRule);
string sharedFolderPath = "\\\\" + Path.Combine(Environment.MachineName, "Users");
sharedFolderPath = Path.Combine(sharedFolderPath, username);
sharedFolderPath = Path.Combine(sharedFolderPath, "Desktop");
sharedFolderPath = Path.Combine(sharedFolderPath, "SharedFolder");
sharedFolderPath = Path.Combine(sharedFolderPath, "file.extension");
System.IO.File.Copy(originalDocumentFolderPath, sharedFolderPath);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

Set permissions for directorys/subdirectorys/files

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.

C# - Modify File Permission ASP.NET MVC

I want modify the file's permission, and I am talking about permission like 666 / 777 etc.
In other words how tio change the permission of file from ANY to 666.
The goal is changing the permission of uploaded file on my ASP.NET MVC Web App.
public string Uploadfile(HttpRequestBase currentRequest)
{
string fileName = "";
for (int i = 0; i < currentRequest.Files.Count; i++)
{
if (currentRequest.Files[i].ContentLength > 0)
{
string strFileName = Guid.NewGuid().ToString() +
Path.GetExtension(currentRequest.Files[i].FileName);
currentRequest.Files[i].SaveAs(HttpContext.Current.Server.MapPath("/Upload/Task/" + strFileName));
fileName = strFileName;
}
}
return fileName;
}
}
You should look at File.SetAccessControl Method
public static void SetAccessControl(
string path,
FileSecurity fileSecurity
)
For example this is how you get the FileSecurity's of a file
FileSecurity fSecurity = File.GetAccessControl(filePath);
Then you create a FileSystemAccessRule
FileSystemAccessRule rule = new FileSystemAccessRule(SPECIFIC_USER, FileSystemRights.FullControl, AccessControlType.Allow);
And you add this Rule to the file's FileSecurity
File.SetAccessControl(filePath, fSecurity);
List of FileSystemRights possible values
http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesystemrights(v=vs.110).aspx
Windows file security works differently to Unix, and there is no direct equivalent to chmod 666.
The method you're looking for is File.SetAccessControl, which takes the path to the file, and a FileSecurity object. The closest equivalent to '666' is probably to assign read/write permissions to the 'Everyone' user account.
To do this, you would use File.GetAccessControl to retrieve the current permissions for the file, add in the new read/write permissions to the FileSecurity object you just retrieved, and then use SetAccessControl to write the new permissions.
More information is available on MSDN here: http://msdn.microsoft.com/en-us/library/system.io.file.setaccesscontrol%28v=vs.110%29.aspx

Remove permissions from a windows folder

I have a widows folder on a remote server from which I wish to remove permissions for a specific user. I've tried numerous methods and nothing seems to work.
I get no errors with the following code but the permission remains intact. Am I not using the correct objects or missing some step with these objects? Any assistance would be greatly appreciated.
The dirName is passed as a share, e.g. \myserver\myfolder
private void removePermissions(string dirName, string username)
{
string user = System.Environment.UserDomainName + "\\" + username;
DirectoryInfo dirinfo = new DirectoryInfo(dirName);
DirectorySecurity dsec = dirinfo.GetAccessControl(AccessControlSections.All);
AuthorizationRuleCollection rules = dsec.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
foreach (AccessRule rule in rules)
{
if (rule.IdentityReference.Value == user)
{
bool value;
dsec.PurgeAccessRules(rule.IdentityReference);
dsec.ModifyAccessRule(AccessControlModification.RemoveAll, rule, out value);
MessageBox.Show("Removed permission from " + dirName + " for " + user);
}
}
}
Once you have created the new ACL you need to apply it to the folder.
Add
dirinfo.SetAccessControl(dsec);
after the loop.

How to Set File Access Permission for Scanning All Files in C#

I am Trying to write a Functionality where i could get the Complete List of All File Name in all Drives,but I am stuck in a place where its giving me security exception to read all files.
I went through many of the articles in this site and the other, but unable to figure out how to set complete access rights
this post was much useful but i am getting an Exception which was unanswered in that thread
How to grant read access to all files in a folder and subfolders using c#?
Now My code looks like this
[FileIOPermission(SecurityAction.LinkDemand, Read = "C:\\")]
public void GetAllFilesFromPhysicalDrives()
{
List<DriveInfo> allphydrives = GetListofPhysicalDrivesOnly(); //Gets All Physical DrivesCollection
try
{
foreach (DriveInfo dr in allphydrives)
{
DirectoryInfo dir = new DirectoryInfo(dr.Name);
DirectorySecurity dirSecurity = dir.GetAccessControl();
dirSecurity.AddAccessRule(new FileSystemAccessRule(Environment.UserName, FileSystemRights.Read, AccessControlType.Allow));
dir.SetAccessControl(dirSecurity);
FileSystemAccessRule faRule;
FileSystemRights fsrRights;
DirectorySecurity dirsec;
fsrRights = FileSystemRights.FullControl;
faRule = new FileSystemAccessRule(new System.Security.Principal.NTAccount("my-pc\\me"),fsrRights,InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,PropagationFlags.InheritOnly, AccessControlType.Allow);
System.Security.Principal.NTAccount account = new System.Security.Principal.NTAccount("me\\me");
dirsec = Directory.GetAccessControl("C:\\");
dirsec.SetOwner(account);
dirsec.AddAccessRule(faRule);
Directory.SetAccessControl("C:\\", dirsec);
}
}
catch(Exception ex)
{
}
}
so when the code to set the access executes i am getting an "Attempt to Perform UnAuthorized Operation" Exception
I don't want to set Permission for files one by one because its a tedious task so help me which would happen dynamically via code for All folders so that i could iterate and get all file names .(I don't intend to get windows related files or kernal files ,just the user created files is enough)

Categories