Posted by: Christian Wimmer in: JEDI Windows Security Code Lib
Some functions (like ExitWindowsEx) need a privilege (SE_SHUTDOWN_NAME) to be enabled to work properly.
With the help of JWSCL this task is made very easy.
JWSCL provides several ways to enable and disable privileges.
1. Use the methods of TJwSecurityToken
You can use TJwSecurityToken to enable, disable or test a privilege. However there are some tool functions that do it for you already in only a single call. They are called
2.Use the function JwEnablePrivilege and friends
A very convienient way to enable and disable a privilege is to use the function JwEnablePrivilege.
function JwEnablePrivilege (const Index : string;
const Query : JwPrivilegeSetType): boolean;
There are two ways to enabe a privilege and one way to disable it.
You should check for the exception EJwsclPrivilegeException because if the flag pst_Enable is used, the function raises the exception when the privilege does not exist.
The code above may or may not enable the privilege depending on its availability. This is sometimes useful if you do not really need a privilege, but it might come handy if available. For example you could use SE_DEBUG_NAME privilege in a call to OpenProcess to open a foreign process. In the worst case that happens without the process is that OpenProcess will fail on processes that were not executed by the same user. However in each case you have to check the result of OpenProcess.
To find out whether a special privilege is available use JwIsPrivilegeSet.
The following code illustrates how to use JwIsPrivilegeSet.
if JwIsPrivilegeSet(SE_DEBUG_NAME, pqt_Available) then
if JwIsPrivilegeSet(SE_DEBUG_NAME, pqt_Enabled) then
With this helper function JwEnablePrivilege won’t throw the exception EJwsclPrivilegeException if the privilege is not available.
A handy function is JwGetPrivilegesText, which returns a string of available privileges and their status. You also can define which privileges are shown.
JwGetPrivilegesText comes in two versions. The first version does not have any parameters and just returns a string with privilege names and their status. Each privilege is separated by a line break.
The output may look like depending on your status. The following privileges are from a standard user in Vista:
The second version of JwGetPrivilegesText receives a list of privileges you want to be displayed:
The output may look like this:
SeDebugPrivilege [not available]
Multipe threads and privileges:
You should always use a thread token when you work with several threads. Enabling and disabling privileges on a process token is very problematic. The reason is that you enable or disable a privilege for all threads. If a single thread enables a privilege and another one disables it, the first thread will fail to call a function that depends on that privilege.
It is possible to introduce lock mechanisms like semaphores. But this is not necessary because each thread can (and should) have its own token: An impersonated token or in other words : a thread token.
To use a thread token properly you have to add this code to your main thread function.
//do your thread stuff here
Token := nil;
ImpersonateLoggedOnUser has a lot of possible exception handlers. This is because there are several ways how the call can fail. You should make sure that your main thread code is not executed without an assigned thread token.
Additionally you should also never call TerminateThread or ExitThread because in this case the finally Block would not be executed (memory leak).
3. Use the interface IJwPrivilegeScope
It is always a good thing to disable a privilege after it was used. The only way to do it safe is to use a try finally catch. If something happens the privilege is disabled at least.
//do your stuff here
JwEnablePrivilege ( SE_SHUTDOWN_NAME , pst_Disable);
This codes needs a lot of work to write if several other privileges are necessary. Fortunately there is a way to accomplish this task much more convenient. We use COM and the unit JwsclPrivileges which implements the interface IJwPrivilegeScope.
IJwPrivilegeScope allows to enable several privileges at once and also disable them as soon as the internal reference counter drops to zero. A huge advantage is that Delphi helps a lot with the reference counting. It automatically increases or decreases the reference counter for several actions like passing the interface to another function. Find out more about scopes and Delphi’s reference counting for interfaces here.
The automatic privilege mangagment can be used in the following way:
//SE_SHUTDOWN_NAME, SE_TCB_NAME, SE_SECURITY_NAME are disabled.
The interface Privs will run out of scope as soon as the method FooMethod exits. In this last step the activated privileges are disabled automatically.
If you combine this mechanism with the thread token shown in “procedure TYourThread.Execute;” you can easily play with privileges without disturbing other thread tokens. However you need a thread token only if you run several threads. In a single thread application the effort isn’t usually necessary for the discussed task (but there may be exceptions).
var PrivScope : IJwPrivilegeScope ;
// Privilege is only active in this procedure
PrivScope := JwGetPrivilegeScope ([ SE_SHUTDOWN_NAME ],
Text := JwGetPrivilegesText ([ SE_SHUTDOWN_NAME ]); // enabled
var ImpToken : TJwSecurityToken;
// create thread token from the process token
ImpToken := TJwSecurityToken . CreateTokenByProcess (0,
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY or TOKEN_READ or
TOKEN_IMPERSONATE or TOKEN_DUPLICATE );
ImpToken . ImpersonateLoggedOnUser ;
//exception handling left out
Be warned that using these mechanisms incorrectly may create a security hole.
Tell me how you liked this blog entry by adding a comment.