icacls adding additional explicit entry - windows

I'm running this command on a folder structure in order for all files and folders to recursively inherit the SYSTEM account with full control (and correct inheritance):
icacls V:\path\*.* /T /C /Q /grant SYSTEM:(OI)(CI)F
This appears to work as expected, but when I go into the advanced permissions settings, there are two permission entries for SYSTEM: One is inherited (as I'd expect), but then there is an additional entry which says "not inherited"..
Is it possible to add a flag so that only the inherited permission entry gets applied?
I'm confused as to why two entries need to be added to each file and folder.
I've thoroughly read the icacls /? documentation and attempted many different combinations to no avail.
Many thanks for any suggestions.

If you inherit permissions from parent and add specific permissions for an account that is already inherited, you will always have 2 (or more) entries for that account.
If you want just the 1 entry, you'll have to either remove the account from parent, or stop inheriting from parent and specifically set permissions.

Related

Icacls permissions not applying as I expect

I am running a batch file as part of a larger application.
If certain conditions are met, a folder is created and permissions applied to the folder using icacls.
I have permission inheritance disabled on the parent folder, and I want to add to the ACL full permissions for the user "testuser".
I tried the following command...
icacls "V:\debugging\test" /grant testuser:F
The command completes successfully, however when logging in to the folder via CIFS, I do not have full permissions.
I can create files and folders but not modify them.
I cannot even rename a text file during creation, so I end up with a new file called 'New text document' and i have no permission to edit this.
What I need to happen is for the permissions to be applied to "V:\debugging\test" that allow me to read, modify and and write without exception and If possible I need those permissions to be inherited by any child folders that may be created.
Can anyone point me in the right direction?

What is the right way to store a path relative to My Documents

I need to write code to handle the following scenario:
Prompt the user for a path to a file.
The user may enter a path that is beneath her "My Documents" folder. The path might also be to a location unrelated to her "My Documents" folder.
Store the path for later lookup.
Sometime later, read the stored path to her file and load her file.
Many months later, the user decides to relocate her "My Documents" folder. Windows provides a way to do this. She naturally expects my application to continue functioning normally.
The code in step 4 should still work. There should be a clever way to remember whether the path is a normal path or relative to My Documents and fetch the file accordingly.
Does the Windows API have this functionality build-in?
What is the right way to do this?
Also, is there any kind of special syntax the user can enter when typing the path so that the Windows API can automatically reference the location relative to My Documents?
Use SHGetFolderPath(CSIDL_MYDOCUMENTS) or
SHGetKnownFolderPath(FOLDERID_Documents) to get the path to the Documents folder, then check if the user's input starts with that path, and if so then use PathRelativePathTo() to create a relative path from it. Later, you can retrieve the current Documents folder path again and use PathCombine() to append the relative path to it.
In the API, there's ShGetKnownFolderPath, using a KNOWNFOLDERID of FOLDERID_Documents.
Depending on what you are coding on, there might be predefined functions for it. For example, in .NET, you could use Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) (links to MSDN for GetFolderPath and Environment.SpecialFolder)
So if you store a relative path to My Documents as the filename, you can always create an absolute path using those functions.
Answering my own question. It turns out, programmatic tricks are unnecessary.
See also:
MSDN,
sevenforums
I discovered the root cause of the problem. The "My Documents" junction was not pointing to the new location. I expected Windows7 to automatically change the "My Documents" junction to the new location, but it did not. I was able to fix the problem by running the following bit of cmd code at the command line.
:: Run this as admin
:: Delete the wrong junction which points to "C:\Users\{username}\Documents"
rmdir "My Documents"
:: Create a new junction to the new My Documents folder
mklink /J "My Documents" "D:\MyData\Documents"
:: Change the attributes of the junction, not the folder it points to
attrib +H +S +I "My Documents" /L
icacls "My Documents" /setowner SYSTEM /L
icacls "My Documents" /deny Everyone:(RD) /L
The right way to store the path is just:
"C:\Users{username}\My Documents..."
If this does not work, it is probably caused by an incorrect junction created by Windows7. The Junction can be fixed with the cmd code above.

Deny all folders permission from all users/administrators via CMD/Batch in Windows 7/8/10

I need to deny all folder permissions for all users, include administrators and others groups via batch file.
I found two topics about this, but i can't solve my problem
icacls Deny Everyone Directory Delete Permission
How to grant permission to users for a directory using command line in Windows?
This command works
icacls D:\Desktop\test /deny Administrator:(OI)(CI)(DE,DC)
, but this command affects only special permissions:
But I need to deny all others permissions like image:
I need to deny all permissions to all all users (administrators, system, and others) via batch, so that nobody can access this folder, not even the system, or the creator of the folder.
Try this code
cacls D:\Desktop\Test /e /c /d %username%
I hope I have helped you, This will change the permissions to ALL deny. To undeny it simply do this code
cacls D:\Desktop\Test /e /c /g %username%:f
I think you should learn more about NTFS permissions (technically, the Discretionary Access Control Lists (DACL)) before complaining the appearances of the GUI.
The Security tab in files' Properties dialog box have limited control over what permissions you can allow, and what you can deny. You should also ideas about the purposes of the built-in user groups, because specifically, the groups that appear in the GUI are never the only groups your system has (it only shows users or groups that have permission entries applied on the files).
For now, I will assume that you want to deny access to Everyone.
First: simply clicking Deny on Full control on all the users on the list is not enough.
You need to Deny two groups for this: the Everyone group and the Anonymous Logon group. (Because "Everyone" no longer includes anonymous logon since Windows XP)
After everyone is denied, it might be a good idea to remove inherited permission entries as well, since they no longer apply and waste your system a little time processing those entries.
With the guide above, I think you can teach yourself to operate all these on the GUI. The result should look something like this:
If you still have no idea what to do, here is the command-line equivalent (using icacls command - you need Windows Vista SP1 or later because of /inheritance option):
rem /inheritance:r - Remove all inherited entries
rem /deny - Set denial of permissions
rem (OI) - "Object inherit" - Also applies to files within the folder
rem (CI) - "Container inherit" - Also applies to subfolders
rem (F) - "Full control"
icacls /inheritance:r /deny "Everyone:(OI)(CI)(F)" "ANONYMOUS LOGON:(OI)(CI)(F)"
If the names "Everyone" or "Anonymous Logon" don't work for you...
icacls /inheritance:r /deny "*S-1-1-0:(OI)(CI)(F)" "*S-1-5-7:(OI)(CI)(F)"
(Yes, it's the same thing, but with SIDs specified in place of user names.)
Here is one caveat though: The owner of the files can change permissions whenever they want. And the Administrators can change the owner of the files at least to themselves. These are special privileges granted by the system that you can't deny, so with a bit of effort, all process of setting this DACL are reversible by Administrators.

Are file level delete permissions enforced in Windows?

Someone recently raised a bug against a filter driver I've been working on. They said that I'd made it possible for a limited user to delete Windows files even if they remove the permissions on the file for the user to be able to do that.
I've been looking at it and it's nothing to do with my driver, even a fresh install of Windows allows this. If you:
Logon as a user called "limiteduser" who's a non admin.
Create a text file
Edit the security for the file
Remove inherited permissions and remove "limiteduser" from having any rights to the file.
Once you've done this you find that:
You can't changed the contents of the file.
You can't rename/move the file or send it to the recycle bin
However you can:
Delete the file in explorer with shift-delete
Delete the file with cmd.exe (del myfile.txt)
Why is this? Is deleting files always a property of the parent folder? And if so why isn't renaming files?
I know this answer isn't complete at all, but I hope it will be helpful nonetheless.
You didn't mention which version of Windows you are using, but as the ones that use any version of the NTFS file system should behave the same I believe it doesn't matter.
The documentation on "File and Folder Permissions" in Windows 2008 Server states that:
Groups or users that are granted Full Control on a folder can delete any files in that folder, regardless of the permissions protecting the file.
So it would appear that part of the answer to your question:
Why is this? Is deleting files always a property of the parent folder? And if so why isn't renaming files?
would be that deleting is indeed a property of the parent folder - it looks to me that it's the Delete Subfolders and Filesspecial permission that allows you to override the permissions on the file.
Why the "Full Control" permission on the folder won't give rename permission is unclear to me, but my guess is that it's actually only Delete Subfolders and Filesthat has the power to override; to rename a file you would have to have permissions to write too.
I'm guessing that the reason that "Shift-Del" in Explorer and "del" in cmd works and not "Recycle" would be that recycling is a move/change operation.
See this Technet article for reference: How Permissions Work

Windows 7 file extension association

I am referring specifically to windows 7.
I have code that associates a certain extension with my application as proposed by webJose on the following page:
What registry keys are responsible for file extension association?
(However i correctly write to HKEY_CURRENT_USER\Software\Classes instead of HKEY_CLASSES_ROOT as suggested)
The above works initially, or if there are no other programs associated with the extension. However after using the Windows 7 built-in "Choose default program..." (found under the file-right-click context menu under "Open with") it re-associates the extension with whatever new program you choose.
What happens at this point is that "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\\UserChoice" is changed by the system, and so the newly selected program takes over.
Running the above code, to regain control over the extension will not work. The only way to regain control, is by either:
Editing the UserChoice -> Progid value, which is not allowed (neither programmatically nor using regedit.exe - access denied).
Or deleting the UserChoice value and making sure your application is the first in the MRUList value under \OpenWithList (this can be achieved using regedit.exe but not programmatically)
My question is: Is there a way to achieve this programmatically? What registry values can be changed to regain control of an extension, after is associated with another program?
I know it might seem obvious that if a user through explorer sets the associated application to an extension, that it would be expected to do it the same way again to re-associate the extension to a different application.
The problem however is I have a button in my application that uses the above mentioned code to check for extension association with my application. Unfortunately with the above situation, my application displays a message confirming that the extension is already successfully associated when its not! So is there a way around this?
Deleting UserChoice should revert the default program to the standard file association keys (which starts with the ProgID in HKCU). Barring that you could also delete OpenWithList, which would be reverting with extreme prejudice.
Edit:
Check out Registry Key Security and Access Rights on MSDN, particularly the RegSetKeySecurity function. Remember that you'll need to grant yourself administrative control to the key before you can delete it.
Well regarding file assoc in Window 7 a new 'problem' araised.
It's one of this: You've to fight for your rights.
Assuming you like to run
REG.exe DELETE "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.mov\UserChoice" /f /va
You'll get ACCESS DENYED.
When you check security setting of the key in Regedit 'UserChoice' you'll see that there's a setting windows made for you, to deny 'set' for the current user. Well you maybe change/delete this setting in regedit and now you can delete UserChoice.
However for programmer/scripters that setting is a little bitchy since there are now real tools to set ACLs in the registry. However here some workaround that at allows to delete keys with ACCESS DENYED (of course this only works incase you've the right to change permissions):
ResetMovAssoc.cmd
::create 'empty.hiv'
REG ADD "HKCU\emptyKey" /f
REG SAVE "HKCU\emptyKey" empty.hiv /y
#REG DELETE "HKCU\emptyKey" /f >nul
::^-note you can add #[...] >nul to the other entries as well to run them quite
:: Delete Reg key by replacing it with an empty hiv
REG RESTORE "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.mov" empty.hiv
del empty.hiv
To summarize this the major thing here is REG RESTORE + Registry hive file containing just and empty key.
In Regedit that'll equivalent to Import' with a just an empty registry structure file (Note: that's a hive file and not a *.reg file).
My solution was not to try to delete the UserChoice key (only administrators can do it), but to delete the key the ProgId is pointing to. If the user made a choice in the past the ProgId has a value like Applications\*.exe. The non-admin can delete the key in a batch:
REG DELETE HKCR\Applications\*.exe /f
This might be a bit of a hack, but worked for me.
Also on Windows 10, this command can't work:
Reg.exe delete "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.m4v" /f
The solution is to delete the SID key by running a BAT file under TrustedInstaller (with NSudo, PowerRun, etc):
for /f "delims=\ tokens=2" %%A in ('reg query hku ^| findstr /i "S-1-5-21-" ^| findstr /v /i "_Classes"') do set SID=%%A
Reg.exe delete "HKU\%SID%\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.m4v" /f
P.S.: Thanks to #SecurityAndPrivacyGuru for sharing the SID detection command.

Resources