00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "postgres.h"
00015
00016
00017 static BOOL pgwin32_get_dynamic_tokeninfo(HANDLE token,
00018 TOKEN_INFORMATION_CLASS class, char **InfoBuffer,
00019 char *errbuf, int errsize);
00020
00021
00022
00023
00024
00025
00026
00027
00028 int
00029 pgwin32_is_admin(void)
00030 {
00031 HANDLE AccessToken;
00032 char *InfoBuffer = NULL;
00033 char errbuf[256];
00034 PTOKEN_GROUPS Groups;
00035 PSID AdministratorsSid;
00036 PSID PowerUsersSid;
00037 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
00038 UINT x;
00039 BOOL success;
00040
00041 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &AccessToken))
00042 {
00043 write_stderr("could not open process token: error code %lu\n",
00044 GetLastError());
00045 exit(1);
00046 }
00047
00048 if (!pgwin32_get_dynamic_tokeninfo(AccessToken, TokenGroups,
00049 &InfoBuffer, errbuf, sizeof(errbuf)))
00050 {
00051 write_stderr("%s", errbuf);
00052 exit(1);
00053 }
00054
00055 Groups = (PTOKEN_GROUPS) InfoBuffer;
00056
00057 CloseHandle(AccessToken);
00058
00059 if (!AllocateAndInitializeSid(&NtAuthority, 2,
00060 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
00061 0, &AdministratorsSid))
00062 {
00063 write_stderr("could not get SID for Administrators group: error code %lu\n",
00064 GetLastError());
00065 exit(1);
00066 }
00067
00068 if (!AllocateAndInitializeSid(&NtAuthority, 2,
00069 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
00070 0, &PowerUsersSid))
00071 {
00072 write_stderr("could not get SID for PowerUsers group: error code %lu\n",
00073 GetLastError());
00074 exit(1);
00075 }
00076
00077 success = FALSE;
00078
00079 for (x = 0; x < Groups->GroupCount; x++)
00080 {
00081 if ((EqualSid(AdministratorsSid, Groups->Groups[x].Sid) && (Groups->Groups[x].Attributes & SE_GROUP_ENABLED)) ||
00082 (EqualSid(PowerUsersSid, Groups->Groups[x].Sid) && (Groups->Groups[x].Attributes & SE_GROUP_ENABLED)))
00083 {
00084 success = TRUE;
00085 break;
00086 }
00087 }
00088
00089 free(InfoBuffer);
00090 FreeSid(AdministratorsSid);
00091 FreeSid(PowerUsersSid);
00092 return success;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 int
00113 pgwin32_is_service(void)
00114 {
00115 static int _is_service = -1;
00116 HANDLE AccessToken;
00117 char *InfoBuffer = NULL;
00118 char errbuf[256];
00119 PTOKEN_GROUPS Groups;
00120 PTOKEN_USER User;
00121 PSID ServiceSid;
00122 PSID LocalSystemSid;
00123 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
00124 UINT x;
00125
00126
00127 if (_is_service != -1)
00128 return _is_service;
00129
00130 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &AccessToken))
00131 {
00132 fprintf(stderr, "could not open process token: error code %lu\n",
00133 GetLastError());
00134 return -1;
00135 }
00136
00137
00138 if (!pgwin32_get_dynamic_tokeninfo(AccessToken, TokenUser, &InfoBuffer,
00139 errbuf, sizeof(errbuf)))
00140 {
00141 fprintf(stderr, "%s", errbuf);
00142 return -1;
00143 }
00144
00145 User = (PTOKEN_USER) InfoBuffer;
00146
00147 if (!AllocateAndInitializeSid(&NtAuthority, 1,
00148 SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0,
00149 &LocalSystemSid))
00150 {
00151 fprintf(stderr, "could not get SID for local system account\n");
00152 CloseHandle(AccessToken);
00153 return -1;
00154 }
00155
00156 if (EqualSid(LocalSystemSid, User->User.Sid))
00157 {
00158 FreeSid(LocalSystemSid);
00159 free(InfoBuffer);
00160 CloseHandle(AccessToken);
00161 _is_service = 1;
00162 return _is_service;
00163 }
00164
00165 FreeSid(LocalSystemSid);
00166 free(InfoBuffer);
00167
00168
00169 if (!pgwin32_get_dynamic_tokeninfo(AccessToken, TokenGroups, &InfoBuffer,
00170 errbuf, sizeof(errbuf)))
00171 {
00172 fprintf(stderr, "%s", errbuf);
00173 return -1;
00174 }
00175
00176 Groups = (PTOKEN_GROUPS) InfoBuffer;
00177
00178 if (!AllocateAndInitializeSid(&NtAuthority, 1,
00179 SECURITY_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0,
00180 &ServiceSid))
00181 {
00182 fprintf(stderr, "could not get SID for service group\n");
00183 free(InfoBuffer);
00184 CloseHandle(AccessToken);
00185 return -1;
00186 }
00187
00188 _is_service = 0;
00189 for (x = 0; x < Groups->GroupCount; x++)
00190 {
00191 if (EqualSid(ServiceSid, Groups->Groups[x].Sid))
00192 {
00193 _is_service = 1;
00194 break;
00195 }
00196 }
00197
00198 free(InfoBuffer);
00199 FreeSid(ServiceSid);
00200
00201 CloseHandle(AccessToken);
00202
00203 return _is_service;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212 static BOOL
00213 pgwin32_get_dynamic_tokeninfo(HANDLE token, TOKEN_INFORMATION_CLASS class,
00214 char **InfoBuffer, char *errbuf, int errsize)
00215 {
00216 DWORD InfoBufferSize;
00217
00218 if (GetTokenInformation(token, class, NULL, 0, &InfoBufferSize))
00219 {
00220 snprintf(errbuf, errsize, "could not get token information: got zero size\n");
00221 return FALSE;
00222 }
00223
00224 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
00225 {
00226 snprintf(errbuf, errsize, "could not get token information: error code %lu\n",
00227 GetLastError());
00228 return FALSE;
00229 }
00230
00231 *InfoBuffer = malloc(InfoBufferSize);
00232 if (*InfoBuffer == NULL)
00233 {
00234 snprintf(errbuf, errsize, "could not allocate %d bytes for token information\n",
00235 (int) InfoBufferSize);
00236 return FALSE;
00237 }
00238
00239 if (!GetTokenInformation(token, class, *InfoBuffer,
00240 InfoBufferSize, &InfoBufferSize))
00241 {
00242 snprintf(errbuf, errsize, "could not get token information: error code %lu\n",
00243 GetLastError());
00244 return FALSE;
00245 }
00246
00247 return TRUE;
00248 }