Which user started that program?

Started by Theo Gottwald, April 14, 2012, 08:26:13 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Theo Gottwald

Here is another thing in C that would be worth a translation, if somebody wants to take that challenge.

char *get_owner_username_from_pid ( DWORD pid)
{
    HANDLE          hToken = NULL;
    LPBYTE lpBytes = NULL;
LPTSTR  lpszAccountName = NULL;
    PTOKEN_USER   lpTokenUser = NULL;
    DWORD           dwSize = 0;
    BOOL            bSuccess = FALSE;
HANDLE  hProcess = NULL;
DWORD   
dwSize01 = 0;
   DWORD   
dwSize02 = 0;
   SID_NAME_USE
sid_name_use = {0};
hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess)
{
   if (OpenProcessToken ( hProcess, TOKEN_QUERY, &hToken ) && hToken )
   {
       GetTokenInformation (hToken, TokenUser, (LPVOID)NULL, 0, &dwSize);
if (dwSize > 0)
{
lpBytes = allocmem (dwSize, 1);
   
lpTokenUser = (PTOKEN_USER)lpBytes;
bSuccess = GetTokenInformation (hToken, TokenUser, (LPVOID)lpTokenUser, dwSize, &dwSize);
if (bSuccess)
{
LookupAccountSid (NULL, (PSID)((lpTokenUser -> User).Sid), NULL,
       (LPDWORD)&dwSize01, NULL,(LPDWORD)&dwSize02,
     
(PSID_NAME_USE)&sid_name_use);
if (dwSize01 > 0)
{
lpszAccountName = allocmem (dwSize01, 1);
bSuccess = LookupAccountSid (NULL, (PSID)(lpTokenUser->User.Sid), lpszAccountName,
       (LPDWORD)&dwSize01, NULL,(LPDWORD)&dwSize02,
     
(PSID_NAME_USE)&sid_name_use);
}
   
}
freemem (lpBytes);
if (bSuccess && lpszAccountName)
{
return (char*) lpszAccountName;
}
}
   }
}
   return NULL; 
}

José Roca

#1
This is similar:


' ========================================================================================
' Looks up the user name and domain name for the user account associated with the specified
' process identifier.
' ========================================================================================
FUNCTION AfxGetUserNameAndDomainFromPid (BYVAL pid AS DWORD, BYREF bstrUser AS WSTRING, BYREF bstrDomain AS WSTRING) AS LONG

   LOCAL hProcess AS DWORD
   LOCAL hToken AS DWORD
   LOCAL ptiUser AS TOKEN_USER PTR
   LOCAL cbti AS DWORD
   LOCAL snu AS LONG  ' SID_NAME_USE enumeration
   LOCAL wszUser AS WSTRINGZ * 256
   LOCAL wszDomain AS WSTRINGZ * %MAX_PATH

   ' // Open the local process
   hProcess = OpenProcess(%PROCESS_ALL_ACCESS, %FALSE, pid)
   IF hProcess = %NULL THEN
      FUNCTION = GetLastError
      EXIT FUNCTION
   END IF
   ' // Get the access token associated with the process
   IF ISFALSE OpenProcessToken(hProcess, %TOKEN_QUERY, hToken) THEN
      FUNCTION = GetLastError
      GOTO LExit
   END IF
   ' // Obtain the size of the user information in the token
   IF GetTokenInformation(hToken, %TokenUser, BYVAL %NULL, 0, cbti) <> 0 THEN
      FUNCTION = GetLastError
      GOTO LExit
   END IF
   ' // Call should have failed due to zero-length buffer
   IF GetLastError <> %ERROR_INSUFFICIENT_BUFFER THEN
      FUNCTION = GetLastError
      GOTO LExit
   END IF
   ' // Allocate buffer for user information in the token
   ptiUser = HeapAlloc(GetProcessHeap, %HEAP_GENERATE_EXCEPTIONS, cbti)
   IF ptiUser = %NULL THEN
      FUNCTION = %E_OUTOFMEMORY
      GOTO LExit
   END IF
   ' // Retrieve the user information from the token
   IF ISFALSE GetTokenInformation(hToken, %TokenUser, BYVAL ptiUser, cbti, cbti) THEN
      FUNCTION = GetLastError
      GOTO LExit
   END IF
   ' // Retrieve user name and domain name based on user's SID.
   IF ISFALSE LookupAccountSidW(BYVAL %NULL, BYVAL @ptiUser.User.Sid, wszUser, SIZEOF(wszUser), _
              wszDomain, SIZEOF(wszDomain), snu) <> 0 THEN
      FUNCTION = GetLastError
      GOTO LExit
      EXIT FUNCTION
   END IF
   bstrUser = wszUser
   bstrDomain = wszDomain

LExit:

   ' // Free resources
   IF hProcess THEN CloseHandle(hProcess)
   IF hToken THEN CloseHandle(hToken)
   IF ptiUser THEN HeapFree(GetProcessHeap, 0, ptiUser)

END FUNCTION
' ========================================================================================


Theo Gottwald

#2
Thanks, Jose. Your code looks even better then the one from MS.
I'll try yours, its another master-piece i can learn from, how to do such things.
I compiled it (using the proper includes!) and it works.

José Roca

That function and the following one are new additions to AfxSid.inc, where there are some useful functions more.



' ========================================================================================
' Tests whether the current user is a member of the Administrator's group.
' Caller is NOT expected to be impersonating anyone and is expected to be able to
' open its own process and process token.
' See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa376389%28v=vs.85%29.aspx
' Return Value:
'   TRUE - Caller has Administrators local group.
'   FALSE - Caller does not have Administrators local group.
' Note: Replacement for the Windows API function IsUserAnAdmin because Microsoft warns
' about the use of this function and advices to call CheckTokenMembership directly.
' ========================================================================================
FUNCTION AfxIsUserAnAdmin () AS LONG

   LOCAL IsMember AS LONG
   LOCAL NtAuthority AS SID_IDENTIFIER_AUTHORITY
   LOCAL AdministratorsGroup AS DWORD

   NtAuthority.Value = $SECURITY_NT_AUTHORITY
   IF AllocateAndInitializeSid(NtAuthority, 2, %SECURITY_BUILTIN_DOMAIN_RID, _
         %DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, AdministratorsGroup) = 0 THEN EXIT FUNCTION
   IF CheckTokenMembership(%NULL, BYVAL AdministratorsGroup, IsMember) <> 0 THEN
      FUNCTION = IsMember
   END IF
   FreeSid(BYVAL AdministratorsGroup)

END FUNCTION
' ========================================================================================


Theo Gottwald

"AfxSid.inc" another Goodie! I'll take a look.