Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

security.c File Reference

#include "postgres.h"
Include dependency graph for security.c:

Go to the source code of this file.

Functions

static BOOL pgwin32_get_dynamic_tokeninfo (HANDLE token, TOKEN_INFORMATION_CLASS class, char **InfoBuffer, char *errbuf, int errsize)
int pgwin32_is_admin (void)
int pgwin32_is_service (void)

Function Documentation

static BOOL pgwin32_get_dynamic_tokeninfo ( HANDLE  token,
TOKEN_INFORMATION_CLASS  class,
char **  InfoBuffer,
char *  errbuf,
int  errsize 
) [static]

Definition at line 213 of file security.c.

References malloc, NULL, and snprintf().

Referenced by pgwin32_is_admin(), and pgwin32_is_service().

{
    DWORD       InfoBufferSize;

    if (GetTokenInformation(token, class, NULL, 0, &InfoBufferSize))
    {
        snprintf(errbuf, errsize, "could not get token information: got zero size\n");
        return FALSE;
    }

    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    {
        snprintf(errbuf, errsize, "could not get token information: 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;
}

int pgwin32_is_admin ( void   ) 

Definition at line 29 of file security.c.

References BOOL(), free, pgwin32_get_dynamic_tokeninfo(), and write_stderr.

Referenced by check_root().

{
    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))
    {
        write_stderr("could not open process token: error code %lu\n",
                     GetLastError());
        exit(1);
    }

    if (!pgwin32_get_dynamic_tokeninfo(AccessToken, TokenGroups,
                                       &InfoBuffer, errbuf, sizeof(errbuf)))
    {
        write_stderr("%s", errbuf);
        exit(1);
    }

    Groups = (PTOKEN_GROUPS) InfoBuffer;

    CloseHandle(AccessToken);

    if (!AllocateAndInitializeSid(&NtAuthority, 2,
         SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
                                  0, &AdministratorsSid))
    {
        write_stderr("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))
    {
        write_stderr("could not get SID for PowerUsers group: error code %lu\n",
                     GetLastError());
        exit(1);
    }

    success = FALSE;

    for (x = 0; x < Groups->GroupCount; x++)
    {
        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;
        }
    }

    free(InfoBuffer);
    FreeSid(AdministratorsSid);
    FreeSid(PowerUsersSid);
    return success;
}

int pgwin32_is_service ( void   ) 

Definition at line 113 of file security.c.

References free, and pgwin32_get_dynamic_tokeninfo().

Referenced by send_message_to_server_log(), and write_stderr().

{
    static int  _is_service = -1;
    HANDLE      AccessToken;
    char       *InfoBuffer = NULL;
    char        errbuf[256];
    PTOKEN_GROUPS Groups;
    PTOKEN_USER User;
    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;

    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))
    {
        FreeSid(LocalSystemSid);
        free(InfoBuffer);
        CloseHandle(AccessToken);
        _is_service = 1;
        return _is_service;
    }

    FreeSid(LocalSystemSid);
    free(InfoBuffer);

    /* Now check for group SID */
    if (!pgwin32_get_dynamic_tokeninfo(AccessToken, TokenGroups, &InfoBuffer,
                                       errbuf, sizeof(errbuf)))
    {
        fprintf(stderr, "%s", errbuf);
        return -1;
    }

    Groups = (PTOKEN_GROUPS) InfoBuffer;

    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);
        return -1;
    }

    _is_service = 0;
    for (x = 0; x < Groups->GroupCount; x++)
    {
        if (EqualSid(ServiceSid, Groups->Groups[x].Sid))
        {
            _is_service = 1;
            break;
        }
    }

    free(InfoBuffer);
    FreeSid(ServiceSid);

    CloseHandle(AccessToken);

    return _is_service;
}