Windows Registry Commander

Home Commercial Tools Free Downloads Contact

v. 5.2:
 - Added a new switch to ENABLE inheritance of any permissions to the key you are working with from its parent.
 - Fixed a Windows NT4 compatibility issue: "GetNamedSecurityInfo" call to a remote system was generating an "Error 1332 : No mapping between account names and security IDs was done."
 - Optimised the process flow: it is not doing redundant checks anymore, hence better performance.
 - Fixed a GPF when there were no existing ACE's on the key.

I have received a few e-mails lately about some peculiarities to do with inheritance under NT4: the issue is that the inheritance is handled differently under NT4, namely, it is not enabled by default from top to bottom and even if you enable it at some intermediate level, it will not reset this flag on the child keys, thus only affecting this one level.

Luckily, because the inheritance flag under NT4 is copied by the child from the parent at the time when the child is created, if the inheritance is enabled (with RSC52) at some level, anything that is created under this key in the future will have inheritance enabled, making it consistent with W2K behaviour. If this has been done, any rights granted subsequently to such parent key will immediately affect all of its children.

For example, if some software is creating a key "HKLM\Software\XXX" with a bunch of sub-keys, changing security on the key under NT4 will have no effect on its sub-keys, even if you enable the inheritance, but if you:

 - create the "HKLM\Software\XXX" key manually, before the software is installed, then
 - apply any security to it with a "-e" flag (to enable inheritance - it can be a dummy command, e.g. to REVOKE access from INTERACTIVE user which is usually not there, which only effect will be to enable the inheritance) and then
 - install the software,

then what you will end up with will be a whole hierarchy of sub-keys under "HKLM\Software\XXX" with inheritance enabled on all levels. If now you were to change any access rights at the "HKLM\Software\XXX" level, it will immediately affect all the sub-keys. Again: this happens by default under W2K and XP, hence no such action is necessary.

v. 5.1:
I have added a check for attempts to modify inherited ACE's (which are useless, although not exactly errors), fixed the last bug ;-) and added some more descriptions to the command-line parameters. Overall, I'm very satisfied with it now and will probably stop changing it at least for quite a while.

v. 5.0:
I have re-designed this version combining the best parts from the original version 1.0 (which was using low-level Windows
® security API's) and the latest version 4.0 (which was using high-level Windows® security API's) plus fixed a few bugs and implemented new features to deal with the permissions inherited from the parent keys (as opposed to the inheritance by the sub-keys).

This version works exactly the same as REGEDT32.

Some of the changes:

 * Verbose mode is back and so is the default implementation of SET action.
 * The ACE's set on a key and inherited by its sub-keys are not "Special" anymore.
 * There are new options to handle inheritance.

For the curious:
I ended up using a mixture of "SetNamedSecurityInfo" (which propagates the key's permissions to its sub-keys correctly, but cannot handle the key's inherited permissions) and "RegSetKeySecurity" (which can modify the key's inherited permissions, but appears to have problems propagating the key's permissions to its sub-keys) API calls to handle both sides of the inheritance correctly.

I found "SetSecurityInfo" to be very similar to "RegSetKeySecurity" except that it cannot work with a remote registry key (strangely enough, because it's close relative "GetSecurityInfo" can).

In v. 4.0 I changed the API I use from "SetSecurityInfo" to "SetNamedSecurityInfo" - the former would not set security on a remote computer (it produced a "handle is invalid" error). Thanks to the user who discovered this bug and notified me.

In my v. 3.0 I used "RegSetKeySecurity" API call and it did not propagate inheritance as I expected it to. V. 3.1 uses "SetSecurityInfo" API and it appears to work as I've just explained ("SetNamedSecurityInfo" worked identically).

Originally, I also implemented the set/erase owner/group functionality because it sounded like something people might want to use, but then I found that the owner can only be either "administrator" or "administrators" and hence not very useful, so I removed it from the final executable.

Note: Due to the Registry structure and the fact that some keys (namely: HKCU/HKCR/HKCC) are, in fact, nothing more but only symbolic links to sub-keys of other keys, for remote registry access (that is if you supply the "-m MACHINE_NAME" parameter) the KEY parameter can only be a sub-key of HKLM (HKEY_LOCAL_MACHINE) or HKU (HKEY_USERS): to access on a remote machine what would be HKCU/HKCR/HKCC locally, use the sub-keys of HKLM (HKCR will become HKLM\SOFTWARE\Classes and HKCC - HKLM\SYSTEM\CurrentControlSet\Hardware Profiles\Current) or HKU (it will become HKU\<USER'S_SID>).

Account names are resolved using Windows default mechanism (that is: if a name is not prefixed with a domain name, all well-known names are searched first, local names next and the domain names last) on the target system (because the name you want to grant access to may be known on the target machine, but not on the workstation where you are running it from).

Due to the Windows naming conventions, a name such as "Administrators" on a machine named "MYCOMPUTER" will not, contrary to the popular believe, appear as "MYCOMPUTER\Administrators", but as "BUILTIN\Administrators" instead and "INTERACTIVE" will appear as "NT AUTHORITY\INTERACTIVE". Such names are best supplied without a prefix - don't worry, the target machine will resolve them properly. Generally speaking, a prefix should only be used if the same name exists in a few different domains (like "Administrator": a local user on every workstation and a domain account when used on a DC) and the default name resolution picks up the wrong one.

Scripting Example:
A sample script which can be used to remotely assign access rights to certain registry sub-keys on a number of computers in your network. Create 3 files similar to the following:

bulletFile DoOne.CMD (it will set GRANT ALL access rights on the specified 9 subkeys to the members of the local USERS group on a remote computer, which name it receives as the only parameter, using you current logon credentials to connect to this computer):

rsc52 -m\\%1 -aUSERS -rA -tGRANT -kHKLM\SOFTWARE\Classes\CLSID\{6592F973-989A-11CF-B262-400019901877} -c -v
rsc52 -m\\%1 -aPARK\KennyM -rC -tSET -kHKLM\system\CurrentControlSet\Control -c -v
rsc52 -m\\%1 -aHELL\DEVELOPERS -rA -t GRANT -kHKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug -c -v
 

bulletFile All.TXT (this is a list of names of your remote computers for the registry security to be set on. Note: a ";" as a first character on a line is a comment character and such lines will be ignored):

PC001
PC002
;PC003
SERVER01
;SERVER02
 

bulletFile DoAll.CMD (this is the one you run: it executes the DoOne.CMD for each un-commented machine name from the All.TXT file):

for /f "eol=; tokens=*" %%i in (All.TXT) do @start DoOne.CMD %%i
 

(in the text above, "start" makes the DoOne.CMD file to run asynchronously for each of the target machines at the same time: this speeds the whole process up, but if you have more than a handful of computer names in the All.TXT it can kill your workstation by spawning hundreds of command prompt windows. In such a case, you can try to add a "/LOW" and/or a "/MIN" switch(es) to the "start" command, or just replace the "start" with a "call" and it will run the DoOne.CMD for each of the target machines one by one:

for /f "eol=; tokens=*" %%i in (All.TXT) do @call DoOne.CMD %%i

NOTE: Parameters that contain spaces must be enclosed in ""

Download Page: Registry Security Commander (v. 5.2)