/*-------------------------------------------------------------------------
*
* win32security . c
* Microsoft Windows Win32 Security Support Functions
*
* Portions Copyright ( c ) 1996 - 2025 , PostgreSQL Global Development Group
*
* IDENTIFICATION
* src / port / win32security . c
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif
static void log_error(const char *fmt,...) pg_attribute_printf(1 , 2 );
/*
* Utility wrapper for frontend and backend when reporting an error
* message .
*/
static void
log_error(const char *fmt,...)
{
va_list ap;
va_start(ap, fmt);
#ifndef FRONTEND
vwrite_stderr(fmt, ap);
#else
vfprintf(stderr, fmt, ap);
#endif
va_end(ap);
}
/*
* Returns nonzero if the current user has administrative privileges ,
* or zero if not .
*
* Note : this cannot use ereport ( ) because it ' s called too early during
* startup .
*/
int
pgwin32_is_admin(void )
{
PSID AdministratorsSid;
PSID PowerUsersSid;
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
BOOL IsAdministrators;
BOOL IsPowerUsers;
if (!AllocateAndInitializeSid(&NtAuthority, 2 ,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0 , 0 , 0 , 0 , 0 ,
0 , &AdministratorsSid))
{
log_error(_("could not get SID for Administrators group: error code %lu\n" ),
GetLastError());
exit (1 );
}
if (!AllocateAndInitializeSid(&NtAuthority, 2 ,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_POWER_USERS, 0 , 0 , 0 , 0 , 0 ,
0 , &PowerUsersSid))
{
log_error(_("could not get SID for PowerUsers group: error code %lu\n" ),
GetLastError());
exit (1 );
}
if (!CheckTokenMembership(NULL, AdministratorsSid, &IsAdministrators) ||
!CheckTokenMembership(NULL, PowerUsersSid, &IsPowerUsers))
{
log_error(_("could not check access token membership: error code %lu\n" ),
GetLastError());
exit (1 );
}
FreeSid(AdministratorsSid);
FreeSid(PowerUsersSid);
if (IsAdministrators || IsPowerUsers)
return 1 ;
else
return 0 ;
}
/*
* We consider ourselves running as a service if one of the following is
* true :
*
* 1 ) Standard error is not valid ( always the case for services , and pg_ctl
* running as a service " passes " that down to postgres ,
* c . f . CreateRestrictedProcess ( ) )
* 2 ) We are running as LocalSystem ( only used by services )
* 3 ) 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
* - 1 = Error
*
* Note : we can ' t report errors via either ereport ( we ' re called too early
* in the backend ) or write_stderr ( because that calls this ) . We are
* therefore reduced to writing directly on stderr , which sucks , but we
* have few alternatives .
*/
int
pgwin32_is_service(void )
{
static int _is_service = -1 ;
BOOL IsMember;
PSID ServiceSid;
PSID LocalSystemSid;
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
HANDLE stderr_handle;
/* Only check the first time */
if (_is_service != -1 )
return _is_service;
/* Check if standard error is not valid */
stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
if (stderr_handle != INVALID_HANDLE_VALUE && stderr_handle != NULL)
{
_is_service = 0 ;
return _is_service;
}
/* Check if running as 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" );
return -1 ;
}
if (!CheckTokenMembership(NULL, LocalSystemSid, &IsMember))
{
fprintf(stderr, "could not check access token membership: error code %lu\n" ,
GetLastError());
FreeSid(LocalSystemSid);
return -1 ;
}
FreeSid(LocalSystemSid);
if (IsMember)
{
_is_service = 1 ;
return _is_service;
}
/* 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: error code %lu\n" ,
GetLastError());
return -1 ;
}
if (!CheckTokenMembership(NULL, ServiceSid, &IsMember))
{
fprintf(stderr, "could not check access token membership: error code %lu\n" ,
GetLastError());
FreeSid(ServiceSid);
return -1 ;
}
FreeSid(ServiceSid);
if (IsMember)
_is_service = 1 ;
else
_is_service = 0 ;
return _is_service;
}
Messung V0.5 in Prozent C=96 H=100 G=97
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-08-08)
¤
*© Formatika GbR, Deutschland