9/11/2008

Get Process Owner

When investigating with access control and security problems, you may want to get process owner pragmatically.

Since security mechanism on windows is far more complex and trivial than those in *nix world, I will list the steps to accomplish this task here:
1. Get access token associated with the target process
2. Get user info(SID of the user) from access token
3. Get domain\user info from AD using SID

code for querying process owner
1 // open the access token associated with the process
2 HANDLE tokenHandle = NULL;
3 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tokenHandle))
4 {
5     Log(LogLevel_Error, "Failed to get process token, LastError=%u", GetLastError());
6     return;
7 }
8
9 // retrieve user security info(SID) about this access token
10 DWORD dwRequireSize = 0;
11 char userInfo[128];
12 if (!GetTokenInformation(
13     tokenHandle,
14     TokenUser,
15     &userInfo,
16     sizeof(userInfo),
17     &dwRequireSize))
18 {
19     Log(LogLevel_Error, "Failed to get process owner SID, LastError=%u", GetLastError());
20     return;
21 }
22
23 // retrieve the domain\name of the account for this SID
24 TOKEN_USER* userToken = (TOKEN_USER*)userInfo;
25 char name[MAX_PATH];
26 char domain[MAX_PATH];
27 DWORD nameSize = MAX_PATH;
28 DWORD domainSize = MAX_PATH;
29 SID_NAME_USE nu;
30 if (!LookupAccountSidA(NULL,
31     userToken->User.Sid,
32     name,
33     &nameSize,
34     domain,
35     &domainSize,
36     &nu))
37 {
38     Log(LogLevel_Error, "Failed to lookup user info from SID. LastError=%u", GetLastError());
39 }
40 else
41 {
42     Log(LogLevel_Info, "Current Process is using domain=%s, user=%s", domain, name);
43 }


Note:
- I pass a 128 char array, rather than a pointer to struct TOKEN_USER, to the 3-th parameter of GetTokenInformation() function at line 15. It's because this API needs more space than TOKEN_USER. On my dev machine, it requires 44 bytes, so I enlarge it to 128 to make it more flexible. But the beginning memory are of this buffer is always a TOKEN_USER structure, so I convert the start addr of this buffer to TOKEN_USER pointer at line 24.

No comments: