Create read only undeletable file - c++

I tried to create file that will not be deletable and read only. (Its an exe, so maybe I need execute too.)
I tried to achieve it with this:
SetFileAttributes(My_File_Path,FILE_ATTRIBUTE_READONLY);
but it only protected against writes (it lets read it but not write to it), while against delete it's doing nothing, even though according to MSDN it's supposed to protect from deletion also:
A file that is read-only. Applications can read the file, but cannot write to it or delete it. This attribute is not honored on directories. For more information, see "You cannot view or change the Read-only or the System attributes of folders in Windows Server 2003, in Windows XP, or in Windows Vista
How can I prevent the file from being deleted?
The file system is NTFS.
It's for protection. The files are for kids' use, and I want to prevent them from deleting the file. (Or, make deleting hard as possible.)
I am looking for a programmatic solution

Deleting a file is a directory change, actually, not a file change. And as noted you can't use attributes, you need full-blown NTFS Access Control Lists (ACL) for that. In particular, what you need is an Access Control Entry (ACE) that
Denies
To Everyone
The right to modify the entire directory
You may optionally prefix another ACE to the ACL with the properties
Allows
To yourself
The right to modify the entire directory
ACE's on an ACL are processed in order, so this prevents you from locking yourself out.

Related

Completely restricting all types of access to a folder

I am making a cocoa application, which creates some folders at my specified location in the user's environment. Now i want to protect these folders from any type of read, write, copy, drag access from all type of users(i.e Not accessible for admin and non-admin users).Is there a way to protect these folders from any type of access.
Can we use, NSFileManager method -setAttributes:OfItemAtPath:error:
But i am not sure on attributes dictionary of this method.
Basically i want to provide trail of some files to the user (let's say 1 day trial), and removing those files as soon as the trail expires, and all those files are placed inside a certain folder in the user's environment. What should be the best approach i should use to protect those files?
You could use NSFileManager setAttributes:OfItemAtPath:error: with the attributes key NSFilePosixPermissions. With this, you can set the Unix file permissions of your folder by specifying them with an integer value that represents the permission bit pattern. Setting it to zero would mean no access at all to that directory:
NSDictionary *attribs = [NSDictionary dictionaryWithObjectsAndKeys:
NSFilePosixPermissions, [NSNumber numberWithInt:0], nil];
However, it would still be possible to move or rename that directory.
Short answer: No. Someone with elevated privileges can do just about anything. No playing with permissions will get you there and still allow your application to access the files.
If you could just turn off all access rights how would you expect your own application to access the files? Turning on the access rights is itself an access right...
Longer answer: Maybe. This depends on what you are trying to achieve. Do you really want to stop the files being copied, or just their contents accessed?
Encryption can be used to protect content (e.g. at the file level, using an encrypted sparsebundle image, etc.), storing identification information in a file can alert you that you’re using a copy (e.g. see what happens if you move/copy a VMWare virtual machine or recreate a Google Drive folder), etc.
And you can always implement your own filesystem using FUSE; and prevent copying, access, etc. by your own mechanism, however the filesystem as a whole could still be copied (i.e. effectively implement your own equivalent of an encrypted sparsebundle via FUSE and implement your own access mechanism).
What are you trying to achieve? If you spell that out folk might be able to suggest alternative solutions.
See also this question on preventing root from writing to files.

C:\ file scan with C++, access denied to specific files

Ok so I have written a code with recursive function that scans my (or any other) C:\ disc.
Using chdir() I'm changing the active directory to C:\ and using system("dir >> C:\Test\"filename") to get the files in that directory written in .txt and then reading it to know what I have. After that I'm checking for additional directories with temp.substr("<DIR>") and calling the function again just with longer path for that specific directory.
The code itself works as it should but I've ran to some directories that I can't access such as Administrator or specific folders in Windows. The only way I've found around them is by adding exeptions to the code so that it just avoids those folders. I'd like to know if there is a way to get a list of folders/files that I don't have access to from cmd since it would make my code a lot more precise or a way to access those directories.
While C++ file API does not have any idea about file permissions and such other than you'll fall when you try to read a file you don't have permissions to, C++ do have access to the Windows API. The Windows API are system calls that gives you access to native OS functionalities, such as calls to GetFileSecurity.
Note that using Windows API means your code would need to take extra steps to ensure portability if you want to run it on non Windows platforms.
The process (your program) runs with certain privileges, normally the users one. The access rights in Windows aren't as simple as "Administrator is god". Even if your user account is member of the "Administrators" group, you can not simply access everything. It usually depends if the OWNER of a file system object grants privileges to other groups and users.
A member of the "Administrators" group might be able to gain access by overriding security settings, but I would advise against that.
You might need elevated privileges and even might need to run your application under a SYSTEM account, it very much depends on what you are trying to achieve.
For more details I suggest to read the "Best practices for Security API" here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms717796(v=vs.85).aspx
and especially the chapter "Running with Special Privileges".

How to detect if a file exists w/o getting derailed by permissions issues?

There are at least three techniques for detecting if a file exists:
Query the file attributes
Use FindFile() with a specific filename instead of a search pattern
Open the file in read mode and look at any resulting error
All of the above seem to suffer from false negatives. That is, I am told that the file doesn't exist when it actually does due to either glitches in how file-io over a network works, or due to file permissions issues.
I have a customer who can see that a file exists in explorer, delete that file, but is given "access denied" if they try to view that file.
I have been unsuccessful at replicating this exact behavior. But what I can create is a situation where the file exists, but due to restricting permissions on it, I cannot see the file in that folder under my user credentials. That is, GetFileAttributes(), FindFile(), and fopen() return failure, i.e. file not found for that file (but if I look in that same folder under a different account - say a network admin, I can see that the file most certainly exists).
As to how my end user (or anyone) would end up in such situations is opaque to me. I have no concrete ideas - maybe power failure while the file was previously opened, maybe some sort of network glitch causing the file handle to remain locked to a dead process on a foreign PC, ...? I'm just making stuff up because I have no idea what might cause such situations to arise.
However, what I really don't have is the ability to query Windows and know for a fact "does file X exist, or not"
Does anyone know of a technique that will honestly answer that question regardless of the user's permissions (assuming that they're allowed to query the contents of the folder itself - I'm not asking for an unauthorized access scenario - just a "normal" user X can't edit file Y, but still wants to know if file Y exists or not.
Hokay - this is getting bizarre.
Using any of the file detection techniques works so long as I ask twice. The first time always tells me "does not exist". Second+ tells me "yup, it's there, but you can't open it."
The file in question is on a shared folder on a Windows Server 2008 NTFS drive. It is shared for everyone full control. I have manually added an "Everyone Deny Read" ACL to the file, in order to simulate my customers problem. So I have denied read, but no other access, and only to the file, not to the share, or the folder in which this file lives.
(I used Explorer to make this modification, not my own software or a command line utility).
I can see that the file exists from the local admin account on that server. I cannot see that it even exists from my local workstation, logged in as a standard user under Windows 7, UAC enabled, non-elevated explorer / application.
It would appear that if a file's read-access is explicitly denied, that the file is not visible any longer (except to account for which that deny doesn't apply, or to the local admin which has some back-door way to see the file despite that deny ACL).
I have tried FindFirstFile, GetAttributes, CreateFile, _taccess_s, and PathFileExists. In every case, the first attempt to access the file indicates "file not found", but the second attempt in a row results in no-error (file found).
I cannot begin to explain these results. I think at this point I need to run all of my tests locally, to remove network file sharing from the mix. These results just don't make a whole heckuva lot of sense (to me).
fltmc output for the folder, from local admin account on the server:
Filter Name Num Instances Altitude Frame
------------------------------ ------------- ------------ -----
aksdf 8 145900 0
luafv 1 135000 0
There's a POSIX function named access that does this. It looks like there's a Windows equivalent _access: http://msdn.microsoft.com/en-us/library/1w06ktdy(v=vs.80).aspx
have You trie WinAPI call to CreateFile with second parameter set to 0 ? Here's description: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx and part I point You to is: "If this parameter is zero, the application can query certain metadata such as file, directory, or device attributes without accessing that file or device, even if GENERIC_READ access would have been denied."
If permissions are set up to say "you're not allowed to even look at the name of this file" (e.g., denied you access to the directory it's in), any ability to "see" that file, even to the extent of just confirming or denying its existence is a clear security hole.
As such, there are only a few possibilities that I can see. The most obvious would be to use an Administrator account to search for the file. This will probably annoy the user, as they'll most likely need to enter credentials for that administrative account to use it. For users who don't have access to an Administrator account (most, you'd hope) it simply won't work at all.
Another possibility would be to find and exploit a security hole that lets you do what you want, even though you're really not supposed to be able to. This is (at least) equally problematic -- nearly any hotfix, service pack, etc., might "plug" the security hole you're exploiting, and your code will quit working. Likewise, there's at least a reasonable chance that some sort of anti-malware software might decide (more or less correctly) that your code is being naughty, and tell the user it's doing bad things.
Use the shell function PathFileExists.
An alternative is to mimic what FileExists in Delphi/BCB does, which is to employ FindFirstFile to get the WIN32_FIND_DATA of the file and thus check whether it exists or not.
And by the way, the situation you refer to is completely artificial. It relates to SeChangeNotifyPrivilege which every default installation assigns to even unprivileged users. The user right is called "bypass traverse checking" (in secpol.msc under Security Settings -> Local Policies -> User Rights Assignment) :)
It means that for all practical purposes you should be able to find out if a file exists if you know its path and name.
And yes, Jerry is right, this is a security hole. But a calculated one. Privileges ("user rights") are exactly that: a way to ignore certain permission issues. It's the very purpose of privileges in Windows.

How can I correctly check for effective read/write access to a file using Windows API?

I've attempted to do this using GetEffectiveRightsFromAcl, but it's not returning the correct access mask for files that are denied to me due to a group I'm part of.
For example, I have a file, unreadable.txt. If I deny write access to unreadable.txt for my current user, the access mask correctly shows that I don't have write access. However, if I instead deny write access for the 'Authenticated Users' group, the access mask implies that I have full access (which I don't).
My alternative was to manually iterate the Ace list and compare my SID with each entry, but I'm unable to find a clean or easy way to check if the Ace is for a group, and if the current user is part of that group.
As an extension, the file may not exist (i.e. it's a new file, about to be written), in which case the access to the directory needs to be checked.
Is there any good solution to this? It seems like there should exist an easier way to do this, without actually trying to read/write to the file in question.
Use AccessCheck instead, as recommended by the knowledge base article on the Limitations of the GetEffectiveRightsFromAcl API.
Just try to open the file with the desired mode using CreateFile - if it succeeds you know you have the access rights. You don't actually have to write anything to the file, just close it right away.

Win32: Prevent folder modification?

I want to make sure no other process changes the contents of a particular folder. I'd like to stop other processes from creating, deleting, or modifying files within a folder. Further, I'd like this restriction to nest down into subfolders.
I can get close to what I want by enumerating the contents of the folder and calling CreateFile on each file. This has problems in that it doesn't stop new files from being created and requires I acquire lots of handles.
Is there an easier way to get what I want?
Update: Addressing some comments, what I want to do is to prevent modification while my program is running. It's OK if the file get modified between runs.
In terms of ACLS, the app has read access to all files within the folder.
ACLs would be the best way to go but if you can't get that to work for whatever reason (you're fairly thin on the details) then use a file system filter driver. Note that this isn't very straightforward. Not rocket science either, but you have to be extra careful with driver development.
http://www.microsoft.com/whdc/driver/filterdrv/default.mspx