Create File and unable users to delete it C# - c#

I am creating a file like this:
System.IO.File.Create("file.dat").Close();
I want to set the file's permissions to disallow users from removing it. I tried the following, but it didn't work:
System.Security.AccessControl.FileSecurity fSecurity = File.GetAccessControl(dirPath + "\\" + fileName);
fSecurity.AddAccessRule(new System.Security.AccessControl.FileSystemAccessRule("Administrators",
System.Security.AccessControl.FileSystemRights.Delete, System.Security.AccessControl.AccessControlType.Allow));
File.SetAccessControl(dirPath + "\\" + fileName, fSecurity);

File permissions can be set using System.IO.File.SetAccessControl
See documentation and examples on MSDN: http://msdn.microsoft.com/en-us/library/system.io.file.setaccesscontrol.aspx
To deny delete permissons to all users but administrators you can use this code
FileSecurity fSecurity = File.GetAccessControl(fileName);
AuthorizationRuleCollection rules = fSecurity.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
foreach (AuthorizationRule rule in rules)
{
System.Security.Principal.NTAccount account =
(System.Security.Principal.NTAccount)rule.IdentityReference.Translate(typeof(System.Security.Principal.NTAccount));
if (account.Value != "BUILTIN\\Administrators")
{
fSecurity.AddAccessRule(new FileSystemAccessRule(account.Value, FileSystemRights.Delete, AccessControlType.Deny));
}
}
File.SetAccessControl(fileName, fSecurity);

Related

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);

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 to check if "Everyone" has full control permissions to a file in c#

I am writing a utility to help with changing file permissions on a certain file to allow/disallow access to it for the "Everyone" group on a Windows machine. So far I have been able to set and remove the Full Control permissions for "Everyone" to the file by using this code:
void AddFullControl()
{
FileSecurity fsFile = File.GetAccessControl("file.tmp");
fsFile.SetAccessRule( new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow));
File.SetAccessControl("file.tmp", fsFile);
}
void RemoveFullControl()
{
FileSecurity fsFile = File.GetAccessControl("file.tmp");
fsFile.SetAccessRule( new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Deny));
File.SetAccessControl("file.tmp", fsFile);
}
However, I want to check to see if "Everyone" already has the Full Control permission or not and have not been able to find a way to do this. I have spent several days scouring through Google search after Google search and have not been able to find a way to do this. Can someone point me in the right direction or give me an example of how to do this please?
Update:
This was answered very quickly and I was able to come up with c# code that works. The code I created is as follows:
void CheckAccess()
{
AuthorizationRuleCollection arcFile = File.GetAccessControl("file.tmp").GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
foreach (AuthorizationRule arFile in arcFile)
{
if (arFile.IdentityReference.Value == "Everyone")
{
FileSystemAccessRule fasrFile = (FileSystemAccessRule)arFile;
if (fasrFile.AccessControlType == AccessControlType.Allow && fasrFile.FileSystemRights.HasFlag(FileSystemRights.FullControl))
{
MessageBox.Show("file.tmp already has Full Control permissions granted to Everyone");
}
}
}
}
var everyone = fsFile.GetAccessRules(true, true, typeof(SecurityIdentifier))
.Cast<FileSystemAccessRule>()
.SingleOrDefault(x => x.IdentityReference.Value == "S-1-1-0");
bool fullControlAllowed = everyone != null
&& everyone.AccessControlType == AccessControlType.Allow
&& everyone.FileSystemRights.HasFlag(FileSystemRights.FullControl);
If permissions might include both Allow and Deny entries for Everyone, you will have to use code like the following. It has slightly different semantics, since you don't get the details on everyone Deny entries.
var everyone = fsFile.GetAccessRules(true, true, typeof(SecurityIdentifier))
.Cast<FileSystemAccessRule>()
.SingleOrDefault(x => x.IdentityReference.Value == "S-1-1-0"
&& x.AccessControlType == AccessControlType.Allow);
bool fullControlAllowed = everyone != null
&& everyone.FileSystemRights.HasFlag(FileSystemRights.FullControl)
You have to get the authorization rules for the file and check to see if there's a rule for the "Everyone" account. Then you can check the FileSystemRights for the rule to see if it has FullControl.
var account = #"Everyone";
var hasFullControl = rules.OfType<FileSystemAccessRule>()
.Where(rule => rule.IdentityReference.Value == account && rule.AccessControlType == AccessControlType.Allow)
.Select(rule => (bool?)rule.FileSystemRights.HasFlag(FileSystemRights.FullControl))
.SingleOrDefault();
A file which is restricted to 'Everyone' which otherwise cannot be recognized through the command if(Directory.Exists(pathfile)) because the file is access protected, the compiler wouldn't recognize its presence in the specified Directory and it will always hit the !Directory.Exists(pathfile) command.
If you want to write new data every time, then this may help,
string pathfile = #"C:\\Users\\Public\\Documents\\Filepath.txt";
if (!Directory.Exists(pathfile))
{
File.SetAttributes(pathfile, FileAttributes.Normal);
File.Delete(pathfile);
using (FileStream fs = File.Create(pathfile))
{
Byte[] info = new UTF8Encoding(true).GetBytes("What Ever Your Text is");
fs.Write(info, 0, info.Length);
File.SetAttributes(pathfile, FileAttributes.ReadOnly);
FileSecurity fsec = File.GetAccessControl(pathfile);
fsec.AddAccessRule(new FileSystemAccessRule("Everyone",
FileSystemRights.ReadData, AccessControlType.Allow));
File.SetAccessControl(pathfile, fsec);
}
}

Remove all default file permissions

I have an C# network application that prompts admins for network proxy authentication information. I ask the user if they want to save this information, which if they choose yes, I encrypt in a unique local file for the user. I would then like to remove all file permissions except the user that created it, but all other users to have the ability to delete the file.
Now, I found MS article below, but it's not helping if I don't know the default users that were setup on the file in the first place. Is there a remove all file permissions? I can then add the individual rights I'm wanting to setup for full access by current user and delete permissions for "All Users" or "Authenticated Users", which looks to be different depending on version of Windows.
http://msdn.microsoft.com/en-us/library/system.io.file.setaccesscontrol.aspx
I figured it out..
public void SetFileSecurity(String filePath, String domainName, String userName)
{
//get file info
FileInfo fi = new FileInfo(filePath);
//get security access
FileSecurity fs = fi.GetAccessControl();
//remove any inherited access
fs.SetAccessRuleProtection(true, false);
//get any special user access
AuthorizationRuleCollection rules = fs.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
//remove any special access
foreach (FileSystemAccessRule rule in rules)
fs.RemoveAccessRule(rule);
//add current user with full control.
fs.AddAccessRule(new FileSystemAccessRule(domainName + "\\" + userName, FileSystemRights.FullControl, AccessControlType.Allow));
//add all other users delete only permissions.
fs.AddAccessRule(new FileSystemAccessRule("Authenticated Users", FileSystemRights.Delete, AccessControlType.Allow));
//flush security access.
File.SetAccessControl(filePath, fs);
}
If you need to remove for the specific group , you can use this method ;
public static void RemoveGroupPermission(string path, string group_name)
{
long begin = Datetime.Now.Ticks;
DirectoryInfo dirInfo = new DirectoryInfo(path);
DirectorySecurity dirSecurity = dirInfo.GetAccessControl();
dirSecurity.RemoveAccessRuleAll(new FileSystemAccessRule(Environment.UserDomainName +
#"\" + group_name, 0, 0));
dirInfo.SetAccessControl(dirSecurity);
long end = DateTime.Now.Ticks;
Console.WriteLine("Tick : " + (end - begin));
}
Impersonation may be help you to solve this out.
The term "Impersonation" in a programming context refers to a technique that executes the code under another user context than the user who originally started an application, i.e. the user context is temporarily changed once or multiple times during the execution of an application.
click Here to see implimentation

Changing registry permission

I want to change the permission of a registry key, and I want to set it as a read only. How can I do this?
I tried this way, but it doesn't change anything:
RegistryPermission rp = new RegistryPermission(
RegistryPermissionAccess.Read,
"HKEY_LOCAL_MACHINE\\SOFTWARE\\paci_1\\identity\\ASPNET_SETREG"
);
rp.AddPathList(
RegistryPermissionAccess.Read,
"HKEY_LOCAL_MACHINE\\SOFTWARE\\paci_1\\identity\\ASPNET_SETREG"
);
Also, how can I do it for a user or administrator or owner etc?
I think the class you want is RegistrySecurity. It's documented here.
It should look something like this:
using(RegistryKey rk =
Registry.LocalMachine.OpenSubKey(#"SOFTWARE\paci_1\identity\ASPNET_SETREG") )
{
string gname = Environment.UserDomainName + #"\" + Environment.UserName;
RegistrySecurity rs = new RegistrySecurity();
rs.AddAccessRule(new RegistryAccessRule(gname, RegistryRights.ReadKey, AccessControlType.Allow));
rk.SetAccessControl(rs);
}
Of course, you would replace gname with the domain-qualified username of your choice.

Categories

Resources