Programmatically adding Write permissions to files in WPF - c#

In my WPF MVVM application,I have a XML file to modify.
It is successfully working In Visual Studio.
But It showing error, while running the installed application.
How can i set the Permissions Through code..
me used this code ,
// current security settings.
FileSecurity fSecurity = File.GetAccessControl(FilePath);
// Add the FileSystemAccessRule to the security settings.
string rr = WindowsIdentity.GetCurrent().Name;
fSecurity.AddAccessRule(new FileSystemAccessRule(WindowsIdentity.GetCurrent().Name,
FileSystemRights.FullControl, AccessControlType.Allow));
// Set the new access settings.
File.SetAccessControl(FilePath, fSecurity);
Still cant solve the Problem...,
Thanks in advance..
see the exception...
System.UnauthorizedAccessException: Attempted to perform an
unauthorized operation. at
System.Security.AccessControl.Win32.SetSecurityInfo(ResourceType type,
String name, SafeHandle handle, SecurityInfos securityInformation,
SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl,
GenericAcl dacl) at
System.Security.AccessControl.NativeObjectSecurity.Persist(String
name, SafeHandle handle, AccessControlSections includeSections, Object
exceptionContext) at
System.Security.AccessControl.NativeObjectSecurity.Persist(String
name, AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String
name, AccessControlSections includeSections) at
System.Security.AccessControl.FileSystemSecurity.Persist(String
fullPath) at System.IO.File.SetAccessControl(String path,
FileSecurity fileSecurity)

To set permissions mostly it requires power user rights(assuming your are running windows 7).
To verify above, launch the Visual studio as "Run as Administrator" and debug the your code.
What is exact exception message?
Here is working example: It sets full permissions for user group EveryOne
private static void WriteAcl ( string filename )
{
//Set security for EveryOne Group
SecurityIdentifier sid =new SecurityIdentifier(WellKnownSidType.WorldSid, null);
IdentityReference userIdentity =sid.Translate (typeof(NTAccount));
var AccessRule_AllowEveryOne = new FileSystemAccessRule ( userIdentity, FileSystemRights.FullControl, AccessControlType.Allow );
var securityDescriptor = new FileSecurity ();
securityDescriptor.SetAccessRule ( AccessRule_AllowEveryOne );
File.SetAccessControl ( filename, securityDescriptor );
}
This code works only if User Account Settings are set to Never notify. Looks its turned on at your computer?
A workaround is to launch your application as power user using Application Manifest.
http://msdn.microsoft.com/en-us/library/bb756929.aspx

Related

How to give Folder Permission for IIS User in C#?

I need to give Folder Permission for IIS User.
Actually I wrote code like this..
public static void AddDirectorySecurity(string FileName, string Account, FileSystemRights Rights,AccessControlType ControlType)
{
DirectoryInfo dInfo = new DirectoryInfo(FileName);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
dSecurity.AddAccessRule(
new System.Security.AccessControl.FileSystemAccessRule(objUser, Rights, ControlType));
dInfo.SetAccessControl(dSecurity);
}
I calling this above method like this...
void givepermission()
{
DirectoryInfo a = new DirectoryInfo(Server.MapPath("~/resources"));
AddDirectorySecurity(Server.MapPath("~/"), "IUSR", FileSystemRights.FullControl,AccessControlType.Allow);
}
But Locally its working. When going server not working.
Instead of IUSR I tried following Account Names but that also not working ..
IIS_IUSRS
IIS_WPG
Network Service
Everyone
etc..
Instead IIS_IUSRS. I Tried like this also...
System.Environment.MachineName + "\\IIS_IUSRS"
IIS_IUSRS_System.Environment.MachineName
System.Environment.UserDomainName + "\\IIS_IUSRS"
etc..
but this also not working, but it's throwing
"Some or all identity references could not be translated"
Note:I Don't want to set the Permission Manually
Please can some one help me with this..?
public static void FolderPermission(String accountName, String folderPath)
{
try
{
FileSystemRights Rights;
//What rights are we setting? Here accountName is == "IIS_IUSRS"
Rights = FileSystemRights.FullControl;
bool modified;
var none = new InheritanceFlags();
none = InheritanceFlags.None;
//set on dir itself
var accessRule = new FileSystemAccessRule(accountName, Rights, none, PropagationFlags.NoPropagateInherit, AccessControlType.Allow);
var dInfo = new DirectoryInfo(folderPath);
var dSecurity = dInfo.GetAccessControl();
dSecurity.ModifyAccessRule(AccessControlModification.Set, accessRule, out modified);
//Always allow objects to inherit on a directory
var iFlags = new InheritanceFlags();
iFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
//Add Access rule for the inheritance
var accessRule2 = new FileSystemAccessRule(accountName, Rights, iFlags, PropagationFlags.InheritOnly, AccessControlType.Allow);
dSecurity.ModifyAccessRule(AccessControlModification.Add, accessRule2, out modified);
dInfo.SetAccessControl(dSecurity);
}
catch (Exception ex)
{
MessageBox.Show("Error");
}
}
Based on the Application Pool Identities article:
IIS introduces a new security feature in Service Pack 2 (SP2) of
Windows Server 2008 and Windows Vista. It's called Application Pool
Identities. Application Pool Identities allow you to run Application
Pools under a unique account without having to create and manage
domain or local accounts. The name of the Application Pool account
corresponds to the name of the Application Pool.
Here's a good explanation of what happens:
In Windows 7, IIS application pool isolation was taken yet to a
different level. The new change introduced in IIS7 (Windows Server
2008) was a new option to run your application pool as AppPoolIdentiy.
However, the default for an application pool identity in IIS7 remained
the same – NetworkService. In IIS7.5, AppPoolIdentiy becomes a
default. Thus, scripts previously expecting permissions for their
application pool identity to be set to “NT Service\NetworkService”
will now have to set permissions (ACLs) for “IIS AppPool\” – the user account created for each new application pool.
Thus, to set permissions for the DefaultAppPool, the scripts will
need to set ACLs for “IIS AppPool\DefaultAppPool”.

Changing Folder permissions with C# doesn't seem to be working

I'm really out of my comfort zone when it comes to permisions. But I want to create a folder and give all users Full Control over it.
DirectoryInfo NewDir = Directory.CreateDirectory(#"C:\Test");
DirectorySecurity dSecur = NewDir.GetAccessControl();
FileSystemAccessRule fAccess =
new FileSystemAccessRule("Users", FileSystemRights.FullControl,AccessControlType.Allow);
dSecur.AddAccessRule(fAccess);
NewDir.SetAccessControl(dSecur);
But the pic below shows that Users Still doesn't have Full Control.
Am I missing something? Thanks!
If you want full control then you need to pass both ContainerInherit and ObjectInherit for the InheritanceFlags.
new FileSystemAccessRule(
User,
FileSystemRights.FullControl,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.InheritOnly,
AccessControlType.Allow
)
And be sure that run under a user with enough rights to grant full control the other user.

C# code to set a remote share to inherit permissions from its parent directory

I have two machines, call them client and server, in a Windows domain. The server has a shared directory which can be accessed from the client machine. I want to run a C# application on the client which sets the permission on this share to inherit the permissions of the share's parent directory on the server. How do I do this?
I have tried code along the following lines, but I don't think it has the right effect:
DirectoryInfo shareDirectoryInfo = new DirectoryInfo("\\server\share");
DirectorySecurity directorySecurity = shareDirectoryInfo.GetAccessControl();
directorySecurity.SetAccessRuleProtection(false, false);
InheritanceFlags iFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
FileSystemAccessRule accessRule = new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, iFlags, PropagationFlags.InheritOnly, AccessControlType.Allow);
bool modified;
directorySecurity.ModifyAccessRule(AccessControlModification.Set, accessRule, out modified);
if (modified)
{
Directory.SetAccessControl(name, directorySecurity);
}
I guess I don't understand why I have to create a FileSystemAccessRule for the directory - how can I just say inherit from parent?
Thanks for any help! Martin
You can set the folder to inherit from parent by using SetAccessRuleProtection
DirectoryInfo targetFolder = new DirectoryInfo(#"\\server\share");
DirectorySecurity folderSecurity = targetFolder.GetAccessControl(); // Existing security
folderSecurity.SetAccessRuleProtection(false, true); // This sets the folder to inherit
targetFolder.SetAccessControl(folderSecurity);
EDIT: The msdn document explains that if false is sent as the first argument, then the second argument is ignored.

C# Storing Folder Permissions

I'm having a little trouble with storing Folder Permissions. I was able to find a some documentation on writing them and reading them. What I'm trying to do is read the permissions on a folder for a specific user > Store it > change the permissions > after installer program finishes, change the permissions back.
I have all of it down (only due to code from many others) EXCEPT how to store the original folder permissions and set it back. I'll gladly read any material that you suggest, we receive several fatal errors with the software and this is one step to resolving many of them. All help is welcome and appreciated.
Below is an example of how I'm setting the permissions. Yes I know that I have everyone, but it is just for testing right now
public void setPermDir()
{
try
{
string DirectoryName = "C:\\Temp1\\";
Console.WriteLine("Adding access control entry for " + DirectoryName);
// Add the access control entry to the directory.
AddDirectorySecurity(DirectoryName, #"Everyone", FileSystemRights.FullControl, AccessControlType.Allow);
Console.WriteLine("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);
}
If you return the DirectorySecurity dSecurity from AddDirectorySecurity then you could just call Directory.SetAccessControl(directoryName, dSecurity); once you were done with the modified access rules.
Update
If just SetAccessControl doesn't work the next step might be to explicitly remove the permissions you have granted using FileSystemSecurity.RemoveAccessRule.
Just keep a reference to the FileSystemAccessRule you create:
FileSystemAccessRule toRemoveWhenDone = new FileSystemAccessRule(Account, Rights, ControlType);

How to set Registry Access Rule on a remote machine using c#

I'm trying to set an registry access rule on a remote machine:
using (RegistryKey localMachineKey = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, serverName))
{
RegistrySecurity rs = new RegistrySecurity();
rs.AddAccessRule(new RegistryAccessRule(userName, RegistryRights.FullControl, AccessControlType.Allow));
using (RegistryKey subKey = localMachineKey.CreateSubKey(registryKey))
{
subKey.SetValue(name, value);
subKey.SetAccessControl(rs);
}
}
this produces the following exception:
System.NotSupportedException: The supplied handle is invalid. This can happen when trying to set an ACL on an anonymous kernel object.
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.RegistrySecurity.Persist(SafeRegistryHandle hKey, String keyName)...
Does anyone know how to make this working?
Thanks!
Using WinRM might be an option.
How to access WinRM in C#
This link suggests that along with a bit more information:
http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/0beee366-ee8d-4052-b1b9-8ad9bf0f8ff0/
Part of the link suggests that it is not possible set this remotely. However, at the bottom, Shaka_01 mentions calling.SetAccessRuleProtection.
RegistryKey rk = RegistryKey.OpenRemoteBaseKey(...);
RegistrySecurity rs = rk.GetAccessControl(AccessControlSections.All);
rs.SetAccessRuleProtection(true, true); //this line you need to set ACL on a remote machines registry key.

Categories