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 ;
6051PSID AdministratorsSid ;
6152PSID PowerUsersSid ;
6253SID_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
8457if (!AllocateAndInitializeSid (& NtAuthority ,2 ,
8558SECURITY_BUILTIN_DOMAIN_RID ,
@@ -101,34 +74,35 @@ pgwin32_is_admin(void)
10174exit (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 );
11985FreeSid (AdministratorsSid );
12086FreeSid (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 asLocal System (only used by services)
98+ * 1) We are running asLocalSystem (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{
145119static 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 ;
151121PSID ServiceSid ;
152122PSID LocalSystemSid ;
153123SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY };
154- UINT x ;
155124
156125/* Only check the first time */
157126if (_is_service != -1 )
158127return _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 */
177130if (!AllocateAndInitializeSid (& NtAuthority ,1 ,
178131SECURITY_LOCAL_SYSTEM_RID ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,
179132& LocalSystemSid ))
180133{
181134fprintf (stderr ,"could not get SID for local system account\n" );
182- CloseHandle (AccessToken );
183135return -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 ());
188142FreeSid (LocalSystemSid );
189- free (InfoBuffer );
190- CloseHandle (AccessToken );
191- _is_service = 1 ;
192- return _is_service ;
143+ return -1 ;
193144}
194-
195145FreeSid (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 */
208154if (!AllocateAndInitializeSid (& NtAuthority ,1 ,
209155SECURITY_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 ());
215160return -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 );
229170FreeSid (ServiceSid );
230171
231- CloseHandle (AccessToken );
172+ if (IsMember )
173+ _is_service = 1 ;
174+ else
175+ _is_service = 0 ;
232176
233177return _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- }