1818#endif
1919
2020
21- static BOOL pgwin32_get_dynamic_tokeninfo (HANDLE token ,
22- TOKEN_INFORMATION_CLASS class ,
23- char * * InfoBuffer , char * errbuf , int errsize );
24-
25-
2621/*
2722 * Utility wrapper for frontend and backend when reporting an error
2823 * message.
@@ -53,33 +48,11 @@ log_error(const char *fmt,...)
5348int
5449pgwin32_is_admin (void )
5550{
56- HANDLE AccessToken ;
57- char * InfoBuffer = NULL ;
58- char errbuf [256 ];
59- PTOKEN_GROUPS Groups ;
6051 PSID AdministratorsSid ;
6152 PSID PowerUsersSid ;
6253 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY };
63- UINT x ;
64- BOOL success ;
65-
66- if (!OpenProcessToken (GetCurrentProcess (), TOKEN_READ , & AccessToken ))
67- {
68- log_error (_ ("could not open process token: error code %lu\n" ),
69- GetLastError ());
70- exit (1 );
71- }
72-
73- if (!pgwin32_get_dynamic_tokeninfo (AccessToken , TokenGroups ,
74- & InfoBuffer , errbuf , sizeof (errbuf )))
75- {
76- log_error ("%s" , errbuf );
77- exit (1 );
78- }
79-
80- Groups = (PTOKEN_GROUPS ) InfoBuffer ;
81-
82- CloseHandle (AccessToken );
54+ BOOL IsAdministrators ;
55+ BOOL IsPowerUsers ;
8356
8457 if (!AllocateAndInitializeSid (& NtAuthority , 2 ,
8558 SECURITY_BUILTIN_DOMAIN_RID ,
@@ -101,34 +74,35 @@ pgwin32_is_admin(void)
10174 exit (1 );
10275 }
10376
104- success = FALSE;
105-
106- for (x = 0 ; x < Groups -> GroupCount ; x ++ )
77+ if (!CheckTokenMembership (NULL , AdministratorsSid , & IsAdministrators ) ||
78+ !CheckTokenMembership (NULL , PowerUsersSid , & IsPowerUsers ))
10779 {
108- if ((EqualSid (AdministratorsSid , Groups -> Groups [x ].Sid ) &&
109- (Groups -> Groups [x ].Attributes & SE_GROUP_ENABLED )) ||
110- (EqualSid (PowerUsersSid , Groups -> Groups [x ].Sid ) &&
111- (Groups -> Groups [x ].Attributes & SE_GROUP_ENABLED )))
112- {
113- success = TRUE;
114- break ;
115- }
80+ log_error (_ ("could not check access token membership: error code %lu\n" ),
81+ GetLastError ());
82+ exit (1 );
11683 }
11784
118- free (InfoBuffer );
11985 FreeSid (AdministratorsSid );
12086 FreeSid (PowerUsersSid );
121- return success ;
87+
88+ if (IsAdministrators || IsPowerUsers )
89+ return 1 ;
90+ else
91+ return 0 ;
12292}
12393
12494/*
12595 * We consider ourselves running as a service if one of the following is
12696 * true:
12797 *
128- * 1) We are running as Local System (only used by services)
98+ * 1) We are running as LocalSystem (only used by services)
12999 * 2) Our token contains SECURITY_SERVICE_RID (automatically added to the
130100 * process token by the SCM when starting a service)
131101 *
102+ * The check for LocalSystem is needed, because surprisingly, if a service
103+ * is running as LocalSystem, it does not have SECURITY_SERVICE_RID in its
104+ * process token.
105+ *
132106 * Return values:
133107 * 0 = Not service
134108 * 1 = Service
@@ -143,140 +117,62 @@ int
143117pgwin32_is_service (void )
144118{
145119 static int _is_service = -1 ;
146- HANDLE AccessToken ;
147- char * InfoBuffer = NULL ;
148- char errbuf [256 ];
149- PTOKEN_GROUPS Groups ;
150- PTOKEN_USER User ;
120+ BOOL IsMember ;
151121 PSID ServiceSid ;
152122 PSID LocalSystemSid ;
153123 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY };
154- UINT x ;
155124
156125 /* Only check the first time */
157126 if (_is_service != -1 )
158127 return _is_service ;
159128
160- if (!OpenProcessToken (GetCurrentProcess (), TOKEN_READ , & AccessToken ))
161- {
162- fprintf (stderr , "could not open process token: error code %lu\n" ,
163- GetLastError ());
164- return -1 ;
165- }
166-
167- /* First check for local system */
168- if (!pgwin32_get_dynamic_tokeninfo (AccessToken , TokenUser , & InfoBuffer ,
169- errbuf , sizeof (errbuf )))
170- {
171- fprintf (stderr , "%s" , errbuf );
172- return -1 ;
173- }
174-
175- User = (PTOKEN_USER ) InfoBuffer ;
176-
129+ /* First check for LocalSystem */
177130 if (!AllocateAndInitializeSid (& NtAuthority , 1 ,
178131 SECURITY_LOCAL_SYSTEM_RID , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
179132 & LocalSystemSid ))
180133 {
181134 fprintf (stderr , "could not get SID for local system account\n" );
182- CloseHandle (AccessToken );
183135 return -1 ;
184136 }
185137
186- if (EqualSid ( LocalSystemSid , User -> User . Sid ))
138+ if (! CheckTokenMembership ( NULL , LocalSystemSid , & IsMember ))
187139 {
140+ fprintf (stderr , "could not check access token membership: error code %lu\n" ,
141+ GetLastError ());
188142 FreeSid (LocalSystemSid );
189- free (InfoBuffer );
190- CloseHandle (AccessToken );
191- _is_service = 1 ;
192- return _is_service ;
143+ return -1 ;
193144 }
194-
195145 FreeSid (LocalSystemSid );
196- free (InfoBuffer );
197146
198- /* Now check for group SID */
199- if (!pgwin32_get_dynamic_tokeninfo (AccessToken , TokenGroups , & InfoBuffer ,
200- errbuf , sizeof (errbuf )))
147+ if (IsMember )
201148 {
202- fprintf ( stderr , "%s" , errbuf ) ;
203- return -1 ;
149+ _is_service = 1 ;
150+ return _is_service ;
204151 }
205152
206- Groups = (PTOKEN_GROUPS ) InfoBuffer ;
207-
153+ /* Check for service group membership */
208154 if (!AllocateAndInitializeSid (& NtAuthority , 1 ,
209155 SECURITY_SERVICE_RID , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
210156 & ServiceSid ))
211157 {
212- fprintf (stderr , "could not get SID for service group\n" );
213- free (InfoBuffer );
214- CloseHandle (AccessToken );
158+ fprintf (stderr , "could not get SID for service group: error code %lu\n" ,
159+ GetLastError ());
215160 return -1 ;
216161 }
217162
218- _is_service = 0 ;
219- for (x = 0 ; x < Groups -> GroupCount ; x ++ )
163+ if (!CheckTokenMembership (NULL , ServiceSid , & IsMember ))
220164 {
221- if (EqualSid (ServiceSid , Groups -> Groups [x ].Sid ))
222- {
223- _is_service = 1 ;
224- break ;
225- }
165+ fprintf (stderr , "could not check access token membership: error code %lu\n" ,
166+ GetLastError ());
167+ FreeSid (ServiceSid );
168+ return -1 ;
226169 }
227-
228- free (InfoBuffer );
229170 FreeSid (ServiceSid );
230171
231- CloseHandle (AccessToken );
172+ if (IsMember )
173+ _is_service = 1 ;
174+ else
175+ _is_service = 0 ;
232176
233177 return _is_service ;
234178}
235-
236-
237- /*
238- * Call GetTokenInformation() on a token and return a dynamically sized
239- * buffer with the information in it. This buffer must be free():d by
240- * the calling function!
241- */
242- static BOOL
243- pgwin32_get_dynamic_tokeninfo (HANDLE token , TOKEN_INFORMATION_CLASS class ,
244- char * * InfoBuffer , char * errbuf , int errsize )
245- {
246- DWORD InfoBufferSize ;
247-
248- if (GetTokenInformation (token , class , NULL , 0 , & InfoBufferSize ))
249- {
250- snprintf (errbuf , errsize ,
251- "could not get token information buffer size: got zero size\n" );
252- return FALSE;
253- }
254-
255- if (GetLastError () != ERROR_INSUFFICIENT_BUFFER )
256- {
257- snprintf (errbuf , errsize ,
258- "could not get token information buffer size: error code %lu\n" ,
259- GetLastError ());
260- return FALSE;
261- }
262-
263- * InfoBuffer = malloc (InfoBufferSize );
264- if (* InfoBuffer == NULL )
265- {
266- snprintf (errbuf , errsize ,
267- "could not allocate %d bytes for token information\n" ,
268- (int ) InfoBufferSize );
269- return FALSE;
270- }
271-
272- if (!GetTokenInformation (token , class , * InfoBuffer ,
273- InfoBufferSize , & InfoBufferSize ))
274- {
275- snprintf (errbuf , errsize ,
276- "could not get token information: error code %lu\n" ,
277- GetLastError ());
278- return FALSE;
279- }
280-
281- return TRUE;
282- }
0 commit comments