Index: backend/port/win32/security.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/port/win32/security.c,v retrieving revision 1.6 diff -c -r1.6 security.c *** backend/port/win32/security.c 9 Nov 2004 13:01:25 -0000 1.6 --- backend/port/win32/security.c 14 Nov 2004 13:49:02 -0000 *************** *** 14,19 **** --- 14,21 ---- #include "postgres.h" + static BOOL pgwin32_get_dynamic_tokeninfo(HANDLE token, TOKEN_INFORMATION_CLASS class, char **InfoBuffer, char *errbuf, int errsize); + /* * Returns nonzero if the current user has administrative privileges, * or zero if not. *************** *** 26,33 **** { HANDLE AccessToken; char *InfoBuffer = NULL; PTOKEN_GROUPS Groups; - DWORD InfoBufferSize; PSID AdministratorsSid; PSID PowerUsersSid; SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; --- 28,35 ---- { HANDLE AccessToken; char *InfoBuffer = NULL; + char errbuf[256]; PTOKEN_GROUPS Groups; PSID AdministratorsSid; PSID PowerUsersSid; SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; *************** *** 41,76 **** exit(1); } ! if (GetTokenInformation(AccessToken, TokenGroups, NULL, 0, &InfoBufferSize)) { ! write_stderr("could not get token information: got zero size\n"); exit(1); } - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - { - write_stderr("could not get token information: error code %d\n", - (int) GetLastError()); - exit(1); - } - - InfoBuffer = malloc(InfoBufferSize); - if (!InfoBuffer) - { - write_stderr("could not allocate %i bytes for token information\n", - (int) InfoBufferSize); - exit(1); - } Groups = (PTOKEN_GROUPS) InfoBuffer; - if (!GetTokenInformation(AccessToken, TokenGroups, InfoBuffer, - InfoBufferSize, &InfoBufferSize)) - { - write_stderr("could not get token information: error code %d\n", - (int) GetLastError()); - exit(1); - } - CloseHandle(AccessToken); if (!AllocateAndInitializeSid(&NtAuthority, 2, --- 43,57 ---- exit(1); } ! if (!pgwin32_get_dynamic_tokeninfo(AccessToken, TokenGroups, ! &InfoBuffer, errbuf, sizeof(errbuf))) { ! write_stderr(errbuf); exit(1); } Groups = (PTOKEN_GROUPS) InfoBuffer; CloseHandle(AccessToken); if (!AllocateAndInitializeSid(&NtAuthority, 2, *************** *** 131,140 **** { static int _is_service = -1; HANDLE AccessToken; ! UCHAR InfoBuffer[1024]; ! PTOKEN_GROUPS Groups = (PTOKEN_GROUPS) InfoBuffer; ! PTOKEN_USER User = (PTOKEN_USER) InfoBuffer; ! DWORD InfoBufferSize; PSID ServiceSid; PSID LocalSystemSid; SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; --- 112,121 ---- { 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}; *************** *** 152,164 **** } /* First check for local system */ ! if (!GetTokenInformation(AccessToken, TokenUser, InfoBuffer, 1024, &InfoBufferSize)) { ! fprintf(stderr, "could not get token information: error code %d\n", ! (int) GetLastError()); return -1; } if (!AllocateAndInitializeSid(&NtAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &LocalSystemSid)) --- 133,147 ---- } /* First check for local system */ ! if (!pgwin32_get_dynamic_tokeninfo(AccessToken, TokenUser, &InfoBuffer, ! errbuf, sizeof(errbuf))) { ! fprintf(stderr,errbuf); return -1; } + User = (PTOKEN_USER) InfoBuffer; + if (!AllocateAndInitializeSid(&NtAuthority, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &LocalSystemSid)) *************** *** 171,196 **** if (EqualSid(LocalSystemSid, User->User.Sid)) { FreeSid(LocalSystemSid); CloseHandle(AccessToken); _is_service = 1; return _is_service; } FreeSid(LocalSystemSid); /* Now check for group SID */ ! if (!GetTokenInformation(AccessToken, TokenGroups, InfoBuffer, 1024, &InfoBufferSize)) { ! fprintf(stderr, "could not get token information: error code %d\n", ! (int) GetLastError()); return -1; } 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"); CloseHandle(AccessToken); return -1; } --- 154,184 ---- 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,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; } *************** *** 205,213 **** --- 193,244 ---- } } + free(InfoBuffer); FreeSid(ServiceSid); CloseHandle(AccessToken); 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)) + { + strncpy(errbuf,"could not get token information: got zero size\n",errsize); + return FALSE; + } + + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + snprintf(errbuf,errsize,"could not get token information: error code %d\n", + (int) GetLastError()); + return FALSE; + } + + *InfoBuffer = malloc(InfoBufferSize); + if (*InfoBuffer == NULL) + { + snprintf(errbuf,errsize,"could not allocate %i 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 %d\n", + (int) GetLastError()); + return FALSE; + } + + return TRUE; + }