Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitff30aec

Browse files
committed
Fix and simplify check for whether we're running as Windows service.
If the process token contains SECURITY_SERVICE_RID, but it has beendisabled by the SE_GROUP_USE_FOR_DENY_ONLY attribute, win32_is_service()would incorrectly report that we're running as a service. That situationarises, e.g. if postmaster is launched with a restricted security token,with the "Log in as Service" privilege explicitly removed.Replace the broken code with CheckProcessTokenMembership(), which doesthis correctly. Also replace similar code in win32_is_admin(), eventhough it got this right, for simplicity and consistency.Per bug #13755, reported by Breen Hagan. Back-patch to all supportedversions. Patch by Takayuki Tsunakawa, reviewed by Michael Paquier.Discussion:https://www.postgresql.org/message-id/20151104062315.2745.67143%40wrigleys.postgresql.org
1 parentb4ff860 commitff30aec

File tree

1 file changed

+38
-142
lines changed

1 file changed

+38
-142
lines changed

‎src/port/win32security.c

Lines changed: 38 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@
1818
#endif
1919

2020

21-
staticBOOLpgwin32_get_dynamic_tokeninfo(HANDLEtoken,
22-
TOKEN_INFORMATION_CLASSclass,
23-
char**InfoBuffer,char*errbuf,interrsize);
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,...)
5348
int
5449
pgwin32_is_admin(void)
5550
{
56-
HANDLEAccessToken;
57-
char*InfoBuffer=NULL;
58-
charerrbuf[256];
59-
PTOKEN_GROUPSGroups;
6051
PSIDAdministratorsSid;
6152
PSIDPowerUsersSid;
6253
SID_IDENTIFIER_AUTHORITYNtAuthority= {SECURITY_NT_AUTHORITY};
63-
UINTx;
64-
BOOLsuccess;
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+
BOOLIsAdministrators;
55+
BOOLIsPowerUsers;
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-
returnsuccess;
87+
88+
if (IsAdministrators||IsPowerUsers)
89+
return1;
90+
else
91+
return0;
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
143117
pgwin32_is_service(void)
144118
{
145119
staticint_is_service=-1;
146-
HANDLEAccessToken;
147-
char*InfoBuffer=NULL;
148-
charerrbuf[256];
149-
PTOKEN_GROUPSGroups;
150-
PTOKEN_USERUser;
120+
BOOLIsMember;
151121
PSIDServiceSid;
152122
PSIDLocalSystemSid;
153123
SID_IDENTIFIER_AUTHORITYNtAuthority= {SECURITY_NT_AUTHORITY};
154-
UINTx;
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-
staticBOOL
243-
pgwin32_get_dynamic_tokeninfo(HANDLEtoken,TOKEN_INFORMATION_CLASSclass,
244-
char**InfoBuffer,char*errbuf,interrsize)
245-
{
246-
DWORDInfoBufferSize;
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

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp