my problem is, I want to create a new folder and make it impossible (or reasonably hard) for the user to change its name or to delete it. The thing is, the user must be able to access the files contained within that folder and change them in any way he pleases. Using the examples I've been finding in the net all I get is making it impossible to change the files INSIDE the folder, and not the folder itself.
Thanks in advance ;)
As long as that folder is created by the user's account (assuming that you're creating the folder programmatically by your application), the user will be able to edit the folder. The best way to protect that folder from tampering would be to write a very small windows service that keeps that folder always open, thus preventing deletion/renaming.
This might be helpful.
http://technet.microsoft.com/en-us/library/cc732880.aspx
It seems you want to allow the "Create Files/Write Data" permission but not allow "control" of the parent folder.
You should be able to set up an ACL to do this. Give them "List folder contents" rights and then selectively give them additional extended rights without giving them modify attributes rights.
The service answer is a bad idea. I might work, but is not the best way to do it. The key with windows directory and folder security is the "owner" of a folder. As an administrator you can always take ownership of a folder or file. BUT if the file has a different owner and that owner has granted you rights you won't have any other rights until you go in and take ownership.
What you want to do is create a special account on the machine (often called a service account) which is the identity the program runs under. This account has admin rights and is the owner of any files it creates. Then it can allow whatever access it wants to grant to users of files and folders it creates.
The admin will always be able to take ownership if they want to, but most users don't even know how to do this.
Related
I have an Application that needs to store User Info such as their Username and there score and etc...
I have selected LocalApplicationData of the Environment.SpecialFolder Enumeration.
but I can access the directory for my application manually using file explorer and can edit or delete the file that can prove as a weak spot for the application and the users may be able to mess with my application.
So, Is there any directory that I can write to using code that the user will not be able to access it.
tnx
Is there any directory that I can write to using code that the user will not be able to access it.
No. An application run by a user account has the same privileges and permissions as that user. Therefore, there is no way that the application could do something the user couldn't do on his own.
If the data you need to store is intended to be browsed or modified by the user, it should go in Environment.SpecialFolder.Personal.
Otherwise, data should be stored in either Environment.SpecialFolder.ApplicationData (if it should roam with the user account) or Environment.SpecialFolder.LocalApplicationData (if it should not roam with the user, and instead should be limited to the local machine).
Yes, the user can get into these folders and destroy the data. By doing so, they run the risk of breaking your application. You can't secure yourself from yourself.
Develop a "repair" utility that can recover from the damage by recreating the necessary files on startup of your application if necessary.
As your application is running with your users privileges, there is no place your application can access that your user would not be able to access.
Your only option is to use encryption so your user cannot tamper with the file easily once it's written. But even then... what you did with the user's privileges can be undone by the user with the same privileges. You can only make it hard enough so he or she won't bother.
You can not prevent use open the file, but have some method to check if a file is being modified by user.
You can save it at Registry, or if your data is big, you can encrypt it before save to file. When you encrypt data, user can not know which infomartion it contains, and if user open the file and modify it, the data become invalid and you can know it is modified.
I have a WPF application that stores resource files locally. The resources files are kept up-to-date using by a process that runs when the application starts. The resource files are updated often and are common for every user running the application, so CommonApplicationData is the best place to store these resource files.
I have 2 questions regarding the use and development of the CommonApplicationData special folder. First, if I am developing the application in Visual Studio, what will it use for the CommonApplicationData path? I don't want the resource files to be stored in CommonApplicationData because that's not the right place to store the files when the app is under development. The solution that I thought of is to have anything in the app reference the |DataDirectory| and then if the configuration is set to Debug, set the DataDirectory to the bin directory of the app. If the configuration is set to Release, set the DataDirectory to the CommonApplicationData\Company\AppName directory. Is this the recommended way to handle this?
Second, the CommonApplicationData directory needs to be writable by all users that run the application. Is this directory writable to all users? Looking at the folder security on my local machine, it looks like there is only read/execute permissions for users (windows 8.1). Do I need to set permissions to to the CommonApplicationData\Company\AppName directory when the application is installed using the windows installer (WIX)?
I tried searching for the recommended practices to use CommonApplicationData, but couldn't come up with the answers to my question.
During installation, you should create a folder in CommonApplicationData. Usually the preferred folder structure goes something like this:
c:\programdata\Company\Product\MyApp.config
This contains the Applications DEFAULT settings. It is written to during install and normally is NOT written to again by a user. It is managed by IT or some other admin. So the user NOT being able to write to this is correct.
Your application should actually use the ApplicationData for writing.
C:\Users\john\AppData\Roaming\Company\Product\MyApp.config
So if the default in a config is true and a user sets this value to false. The code will write to the user's config but the Common or Default config is not changed.
Your application should load the the configuration from ApplicationData first and if ApplicationData doesn't exist, load the config from CommonApplicationData.
Now, if you have a file that you want all users to change and all users to share, and one user changing it changes it for another user, I would simply make that file reside in CommonApplicationData and make it writeable by setting the permissions during your installation process.
You claim you searched for answers and yet the second result on Bing (sixth on Google) when I searched for CommonApplicationData was an article on Code Project which in first sentence mentions that Microsoft recommends storing data common to all users in CommonApplicationData special folder and create a CompanyName/ProductName subfolder for your data... The author proceeds to provide a class that can be used to set read/write permissions to all users for the CompanyName folder.
When you need to store data common to all users of an application
locally, Microsoft recommend using
System.Environment.SpecialFolder.CommonApplicationData.
In addition they also suggest creating a sub folder here with your CompanyName and
a sub folder in that of ApplicationName.
The issue with this is the folders and files you create only have read/execute
permissions for other users other than the creator. This means that they cannot be
appended to or replaced by another user without UAC elevation.
Whilst I understand the reasoning for this, in reality it creates a
problem for a shared dynamic data store.
The class below addresses
this by setting read/write permissions to all users on the CompanyName
folder and optionally setting read/write permissions of the
ApplicationName folder on creation and sub folders/files inherit these
permissions.
The situation I'm trying to address is this: I'm writing an application which multiple users will have access to. Access is restricted based on Windows permissions for folders - users will be granted access to the folder containing the application if needed.
For better or worse, the application stores its data in files on the same network as the application. I don't want users to be able to edit the data directly, so I plan to restrict access to the data files.
The approach I've been trying to use is then to have a 'service user' which does have read/write access to the data, and to use impersonation within the application to 'login' as the service user, perform required read/write, and return to the original user.
I've had a few different attempts at this without luck. Perhaps the simplest/most promising is based on Mark Johnson's answer here:
How do you do Impersonation in .NET?
I use it as follows:
using (new Impersonation(serviceAccount.Domain, serviceAccount.UserName, serviceAccount.Password))
{
DoImport(app);
}
where 'DoImport(app)' performs the reading of the data.
However, this gives an error 'Access to the path '...' is denied'. I'm trying to run this locally (the path is C:...) where I've restricted access to the path for the user I'm logged into but the user I'm trying to impersonate with has access.
Is there something I'm doing wrong here? Is there a better way to achieve what I'm after?
Thanks,
Andrew
The code at the below link seems to do what I'm after:
http://www.codeproject.com/Articles/10090/A-small-C-Class-for-impersonating-a-User
I think the token duplication is the important part, but I'm not exactly sure why.
I did have a further issue doing this - any assemblies that needed to be loaded for the 'DoImport(...)' function couldn't be loaded after the impersonation, access was denied for some reason (sorry for the vagueness, I didn't have time to look into this). Ensuring they're loaded before doing the impersonation, either through some dummy function calls or code to force load (see e.g. Is there a way to force all referenced assemblies to be loaded into the app domain?) did the trick.
The fact the user, which is logged on (or which you try to impersonate) has access rights to the files, does NOT imply, that the application, that you are running, has the rights.
Have you considered running the application under administrator rights? (You got to grant the access to the files to the application!)
Or, if you use debugging and are running it from VisualStuido (or other IDE), try running the IDE under administrator rights first.
This can do the trick in most cases, however, storing the data on a drive, where the users have physical access to it is by no means something I would recommend, have you thought about different ways of storing and accessing your data? Or what are the reasons for having it this way?
You can't gain acces to other useraccounts without Administrator rights, but have you considered to put the files in a shared folder? If you want to identify the creater/owner of the file you could use getowner. Or you could use subfolders in the shared folder. I hope this will help.
I am trying to create a Directory in .NET using Directory.CreateDirectory, I followed the directions here to give access permission but I am still getting an UnauthorizedAccessException. Does anyone have any advice? Note, this is a web application that uses the IIS7 server.
In the directory you are attempting to create a new directory, make sure that your app pool user has Read/Write permissions for that directory. You have to specifically do that in addition to adding the user to the user groups.
2 more potential issues (+1 to user959729):
you are creating directory at different place than you think you are (i.e. you building path wrong)
the code runs under impersonated account (user's or anonymous) and such user does not have permissions to create folder (to verify try check System.Environment.UserName before creating directory). To fix you need to run code as process account.
I want to copy the permissions of a user and to another user. I know i can do it by creating a group with required permissions and adding the users will do it. But i dont want to create a group. Is there a way to copy the permissions of a user to another user directly?
NLV
You need to write code that will;
Check if the current site inherits permissions or sets its own
From the site that sets permissions (self or ancestor, depending on 1) go over the RoleAssignments collections
For each role assignment check if your source user is specified
If so, create a role assignment for the target user
This code must run under administrative privileges (RunWithElevatedPrivilegese will suffice if written as web part)
There is no way to copy permissions between users through SharePoint itself, you will have to write a script to do it for you.
There is no OOTB way to clone SharePoint user permissions. You should either use 3rd party tools such as ShareGate, Axceler ControlPont, Boost Solutions's Permission manager or Use this PowerShell script way: Copy Permissions from One User to Another in SharePoint using PowerShell
Copy Permissions from One User to Another in SharePoint using PowerShell