Posted by: Christian Wimmer in: JEDI Windows Security Code Lib
Sometimes it is necessary to change the security settings of a file or folder for getting or denying write access. With JWSCL this task is made very easy. However there are some pitfalls to avoid.
The following code will also be available in the example section of the source code. The application gets a file or folder name as parameter and tries to add the user with full access control. It even tries to get ownership if it can’t change the access control list.
First of all we need some JWSCL classes:
These classes are stored in the JWSCL units. We use the following ones:
The units above are necessary and contain all the classes described earlier Of course we have to declare the classes:
This example also shows how we can add well known Security Identifiers (SID) to a secured object. We have to initialize them. The variable JwWorldSID will then contain the correct SID for group Everyone. If we didn’t call it, we would get nil instead.
The next steps are creating the classes. We get the user name through her token and save the SID into Owner.
Later we will use the Owner instance to add it into the security information of the object.
The actual class which does all the work on the file/folder is TJwSecureFileObject. We just apply the first parameter.
Notice: A user can only change security information of an object if she has the right to do it. There are two options to allow it.
We can check both version in one call.
This call is very easy. If we can’t change the DACL, we can try to become the owner. The only way to become an owner is to enable a privilege called SE_TAKE_OWNERSHIP_NAME. It is usually only granted to Administrators.
JwEnablePrivilege will fail, if it can’t activate the privilege. Otherwise we can set the file/folder’s owner to the token user.
The main work is done here. We get the default DACL from the existing object and adapt it.
Adaption is done by adding the user to the DACL with full control. We additionally allow the Everyone group to demonstrate the well known Sids initialized by JwInitWellKnownSIDs. The last parameters (false) define that we don’t want the list to free the given SIDs (Owner and JwWorldSid) automatically.
And finally we reset the DACL.
The DACL of the file or folder will receive the newly created control entries in addition to its existing ones. If it contains inherited entries (entries from a parent folder) they will be conserved. However if you don’t retrieve the DACL and just use an empty one, all previously existing entries which are not inherited will be removed. Of course the inherited entries will still remain intact.
And of course we free all allocated resources
Since I cut the source code into pieces, I’ll show it here in full glory
UserToken : TJwSecurityToken;
SD : TJwSecurityDescriptor;
FileObject : TJwSecureFileObject;
Owner : TJwSecurityId;
DACL : TJwDAccessControlList;
if not FileExists(ParamStr(1)) then
UserToken := TJwSecurityToken.CreateTokenEffective(MAXIMUM_ALLOWED);
Owner := UserToken.GetTokenOwner;
FileObject := TJwSecureFileObject.Create(ParamStr(1));
//Make me owner if we cant access DACL
if not FileObject.AccessCheck(WRITE_DAC) then
//try to become owner
FileObject.Owner := Owner;
DACL := FileObject.DACL;
DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil, , GENERIC_ALL, Owner, false));
DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil, , GENERIC_READ, JwWorldSID, false));