@ -18,11 +18,6 @@
# endif
static BOOL pgwin32_get_dynamic_tokeninfo ( HANDLE token ,
TOKEN_INFORMATION_CLASS class ,
char * * InfoBuffer , char * errbuf , int errsize ) ;
/*
* Utility wrapper for frontend and backend when reporting an error
* message .
@ -53,33 +48,11 @@ log_error(const char *fmt,...)
int
pgwin32_is_admin ( void )
{
HANDLE AccessToken ;
char * InfoBuffer = NULL ;
char errbuf [ 256 ] ;
PTOKEN_GROUPS Groups ;
PSID AdministratorsSid ;
PSID PowerUsersSid ;
SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY } ;
UINT x ;
BOOL success ;
if ( ! OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_READ , & AccessToken ) )
{
log_error ( _ ( " could not open process token: error code %lu \n " ) ,
GetLastError ( ) ) ;
exit ( 1 ) ;
}
if ( ! pgwin32_get_dynamic_tokeninfo ( AccessToken , TokenGroups ,
& InfoBuffer , errbuf , sizeof ( errbuf ) ) )
{
log_error ( " %s " , errbuf ) ;
exit ( 1 ) ;
}
Groups = ( PTOKEN_GROUPS ) InfoBuffer ;
CloseHandle ( AccessToken ) ;
BOOL IsAdministrators ;
BOOL IsPowerUsers ;
if ( ! AllocateAndInitializeSid ( & NtAuthority , 2 ,
SECURITY_BUILTIN_DOMAIN_RID ,
@ -101,34 +74,35 @@ pgwin32_is_admin(void)
exit ( 1 ) ;
}
success = FALSE ;
for ( x = 0 ; x < Groups - > GroupCount ; x + + )
if ( ! CheckTokenMembership ( NULL , AdministratorsSid , & IsAdministrators ) | |
! CheckTokenMembership ( NULL , PowerUsersSid , & IsPowerUsers ) )
{
if ( ( EqualSid ( AdministratorsSid , Groups - > Groups [ x ] . Sid ) & &
( Groups - > Groups [ x ] . Attributes & SE_GROUP_ENABLED ) ) | |
( EqualSid ( PowerUsersSid , Groups - > Groups [ x ] . Sid ) & &
( Groups - > Groups [ x ] . Attributes & SE_GROUP_ENABLED ) ) )
{
success = TRUE ;
break ;
}
log_error ( _ ( " could not check access token membership: error code %lu \n " ) ,
GetLastError ( ) ) ;
exit ( 1 ) ;
}
free ( InfoBuffer ) ;
FreeSid ( AdministratorsSid ) ;
FreeSid ( PowerUsersSid ) ;
return success ;
if ( IsAdministrators | | IsPowerUsers )
return 1 ;
else
return 0 ;
}
/*
* We consider ourselves running as a service if one of the following is
* true :
*
* 1 ) We are running as Local System ( only used by services )
* 1 ) We are running as LocalSystem ( only used by services )
* 2 ) Our token contains SECURITY_SERVICE_RID ( automatically added to the
* process token by the SCM when starting a service )
*
* The check for LocalSystem is needed , because surprisingly , if a service
* is running as LocalSystem , it does not have SECURITY_SERVICE_RID in its
* process token .
*
* Return values :
* 0 = Not service
* 1 = Service
@ -143,140 +117,62 @@ int
pgwin32_is_service ( void )
{
static int _is_service = - 1 ;
HANDLE AccessToken ;
char * InfoBuffer = NULL ;
char errbuf [ 256 ] ;
PTOKEN_GROUPS Groups ;
PTOKEN_USER User ;
BOOL IsMember ;
PSID ServiceSid ;
PSID LocalSystemSid ;
SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY } ;
UINT x ;
/* Only check the first time */
if ( _is_service ! = - 1 )
return _is_service ;
if ( ! OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_READ , & AccessToken ) )
{
fprintf ( stderr , " could not open process token: error code %lu \n " ,
GetLastError ( ) ) ;
return - 1 ;
}
/* First check for local system */
if ( ! pgwin32_get_dynamic_tokeninfo ( AccessToken , TokenUser , & InfoBuffer ,
errbuf , sizeof ( errbuf ) ) )
{
fprintf ( stderr , " %s " , errbuf ) ;
return - 1 ;
}
User = ( PTOKEN_USER ) InfoBuffer ;
/* First check for LocalSystem */
if ( ! AllocateAndInitializeSid ( & NtAuthority , 1 ,
SECURITY_LOCAL_SYSTEM_RID , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& LocalSystemSid ) )
{
fprintf ( stderr , " could not get SID for local system account \n " ) ;
CloseHandle ( AccessToken ) ;
return - 1 ;
}
if ( EqualSid ( LocalSystemSid , User - > User . Sid ) )
if ( ! CheckTokenMembership ( NULL , LocalSystemSid , & IsMember ) )
{
fprintf ( stderr , " could not check access token membership: error code %lu \n " ,
GetLastError ( ) ) ;
FreeSid ( LocalSystemSid ) ;
free ( InfoBuffer ) ;
CloseHandle ( AccessToken ) ;
_is_service = 1 ;
return _is_service ;
return - 1 ;
}
FreeSid ( LocalSystemSid ) ;
free ( InfoBuffer ) ;
/* Now check for group SID */
if ( ! pgwin32_get_dynamic_tokeninfo ( AccessToken , TokenGroups , & InfoBuffer ,
errbuf , sizeof ( errbuf ) ) )
if ( IsMember )
{
fprintf ( stderr , " %s " , errbuf ) ;
return - 1 ;
_is_service = 1 ;
return _is_service ;
}
Groups = ( PTOKEN_GROUPS ) InfoBuffer ;
/* Check for service group membership */
if ( ! AllocateAndInitializeSid ( & NtAuthority , 1 ,
SECURITY_SERVICE_RID , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& ServiceSid ) )
{
fprintf ( stderr , " could not get SID for service group \n " ) ;
free ( InfoBuffer ) ;
CloseHandle ( AccessToken ) ;
fprintf ( stderr , " could not get SID for service group: error code %lu \n " ,
GetLastError ( ) ) ;
return - 1 ;
}
_is_service = 0 ;
for ( x = 0 ; x < Groups - > GroupCount ; x + + )
if ( ! CheckTokenMembership ( NULL , ServiceSid , & IsMember ) )
{
if ( EqualSid ( ServiceSid , Groups - > Groups [ x ] . Sid ) )
{
_is_service = 1 ;
break ;
}
fprintf ( stderr , " could not check access token membership: error code %lu \n " ,
GetLastError ( ) ) ;
FreeSid ( ServiceSid ) ;
return - 1 ;
}
free ( InfoBuffer ) ;
FreeSid ( ServiceSid ) ;
CloseHandle ( AccessToken ) ;
if ( IsMember )
_is_service = 1 ;
else
_is_service = 0 ;
return _is_service ;
}
/*
* Call GetTokenInformation ( ) on a token and return a dynamically sized
* buffer with the information in it . This buffer must be free ( ) : d by
* the calling function !
*/
static BOOL
pgwin32_get_dynamic_tokeninfo ( HANDLE token , TOKEN_INFORMATION_CLASS class ,
char * * InfoBuffer , char * errbuf , int errsize )
{
DWORD InfoBufferSize ;
if ( GetTokenInformation ( token , class , NULL , 0 , & InfoBufferSize ) )
{
snprintf ( errbuf , errsize ,
" could not get token information buffer size: got zero size \n " ) ;
return FALSE ;
}
if ( GetLastError ( ) ! = ERROR_INSUFFICIENT_BUFFER )
{
snprintf ( errbuf , errsize ,
" could not get token information buffer size: error code %lu \n " ,
GetLastError ( ) ) ;
return FALSE ;
}
* InfoBuffer = malloc ( InfoBufferSize ) ;
if ( * InfoBuffer = = NULL )
{
snprintf ( errbuf , errsize ,
" could not allocate %d bytes for token information \n " ,
( int ) InfoBufferSize ) ;
return FALSE ;
}
if ( ! GetTokenInformation ( token , class , * InfoBuffer ,
InfoBufferSize , & InfoBufferSize ) )
{
snprintf ( errbuf , errsize ,
" could not get token information: error code %lu \n " ,
GetLastError ( ) ) ;
return FALSE ;
}
return TRUE ;
}