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

Commit0904eb3

Browse files
committed
Run pg_upgrade and pg_resetxlog with restricted token on Windows
As with initdb these programs need to run with a restricted token, andif they don't pg_upgrade will fail when run as a user with Adminstratorprivileges.Backpatch to all live branches. On the development branch the code isreorganized so that the restricted token code is now in a singlelocation. On the stable bramches a less invasive change is made bysimply copying the relevant code to pg_upgrade.c and pg_resetxlog.c.Patches and bug report from Muhammad Asif Naeem, reviewed by MichaelPaquier, slightly edited by me.
1 parent246bbf6 commit0904eb3

File tree

2 files changed

+331
-0
lines changed

2 files changed

+331
-0
lines changed

‎contrib/pg_upgrade/pg_upgrade.c

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ static void copy_clog_xlog_xid(void);
5050
staticvoidset_frozenxids(boolminmxid_only);
5151
staticvoidsetup(char*argv0,bool*live_check);
5252
staticvoidcleanup(void);
53+
staticvoidget_restricted_token(constchar*progname);
54+
55+
#ifdefWIN32
56+
staticintCreateRestrictedProcess(char*cmd,PROCESS_INFORMATION*processInfo,constchar*progname);
57+
#endif
5358

5459
ClusterInfoold_cluster,
5560
new_cluster;
@@ -66,6 +71,9 @@ char *output_files[] = {
6671
NULL
6772
};
6873

74+
#ifdefWIN32
75+
staticchar*restrict_env;
76+
#endif
6977

7078
int
7179
main(intargc,char**argv)
@@ -77,6 +85,8 @@ main(int argc, char **argv)
7785

7886
parseCommandLine(argc,argv);
7987

88+
get_restricted_token(os_info.progname);
89+
8090
adjust_data_dir(&old_cluster);
8191
adjust_data_dir(&new_cluster);
8292

@@ -175,6 +185,162 @@ main(int argc, char **argv)
175185
return0;
176186
}
177187

188+
#ifdefWIN32
189+
typedefBOOL(WINAPI*__CreateRestrictedToken) (HANDLE,DWORD,DWORD,PSID_AND_ATTRIBUTES,DWORD,PLUID_AND_ATTRIBUTES,DWORD,PSID_AND_ATTRIBUTES,PHANDLE);
190+
191+
/* Windows API define missing from some versions of MingW headers */
192+
#ifndefDISABLE_MAX_PRIVILEGE
193+
#defineDISABLE_MAX_PRIVILEGE0x1
194+
#endif
195+
196+
/*
197+
* Create a restricted token and execute the specified process with it.
198+
*
199+
* Returns 0 on failure, non-zero on success, same as CreateProcess().
200+
*
201+
* On NT4, or any other system not containing the required functions, will
202+
* NOT execute anything.
203+
*/
204+
staticint
205+
CreateRestrictedProcess(char*cmd,PROCESS_INFORMATION*processInfo,constchar*progname)
206+
{
207+
BOOLb;
208+
STARTUPINFOsi;
209+
HANDLEorigToken;
210+
HANDLErestrictedToken;
211+
SID_IDENTIFIER_AUTHORITYNtAuthority= {SECURITY_NT_AUTHORITY };
212+
SID_AND_ATTRIBUTESdropSids[2];
213+
__CreateRestrictedToken_CreateRestrictedToken=NULL;
214+
HANDLEAdvapi32Handle;
215+
216+
ZeroMemory(&si,sizeof(si));
217+
si.cb=sizeof(si);
218+
219+
Advapi32Handle=LoadLibrary("ADVAPI32.DLL");
220+
if (Advapi32Handle!=NULL)
221+
{
222+
_CreateRestrictedToken= (__CreateRestrictedToken)GetProcAddress(Advapi32Handle,"CreateRestrictedToken");
223+
}
224+
225+
if (_CreateRestrictedToken==NULL)
226+
{
227+
fprintf(stderr,_("%s: WARNING: cannot create restricted tokens on this platform\n"),progname);
228+
if (Advapi32Handle!=NULL)
229+
FreeLibrary(Advapi32Handle);
230+
return0;
231+
}
232+
233+
/* Open the current token to use as a base for the restricted one */
234+
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&origToken))
235+
{
236+
fprintf(stderr,_("%s: could not open process token: error code %lu\n"),progname,GetLastError());
237+
return0;
238+
}
239+
240+
/* Allocate list of SIDs to remove */
241+
ZeroMemory(&dropSids,sizeof(dropSids));
242+
if (!AllocateAndInitializeSid(&NtAuthority,2,
243+
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,
244+
0,&dropSids[0].Sid)||
245+
!AllocateAndInitializeSid(&NtAuthority,2,
246+
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_POWER_USERS,0,0,0,0,0,
247+
0,&dropSids[1].Sid))
248+
{
249+
fprintf(stderr,_("%s: could not to allocate SIDs: error code %lu\n"),progname,GetLastError());
250+
return0;
251+
}
252+
253+
b=_CreateRestrictedToken(origToken,
254+
DISABLE_MAX_PRIVILEGE,
255+
sizeof(dropSids) /sizeof(dropSids[0]),
256+
dropSids,
257+
0,NULL,
258+
0,NULL,
259+
&restrictedToken);
260+
261+
FreeSid(dropSids[1].Sid);
262+
FreeSid(dropSids[0].Sid);
263+
CloseHandle(origToken);
264+
FreeLibrary(Advapi32Handle);
265+
266+
if (!b)
267+
{
268+
fprintf(stderr,_("%s: could not create restricted token: error code %lu\n"),progname,GetLastError());
269+
return0;
270+
}
271+
272+
#ifndef__CYGWIN__
273+
AddUserToTokenDacl(restrictedToken);
274+
#endif
275+
276+
if (!CreateProcessAsUser(restrictedToken,
277+
NULL,
278+
cmd,
279+
NULL,
280+
NULL,
281+
TRUE,
282+
CREATE_SUSPENDED,
283+
NULL,
284+
NULL,
285+
&si,
286+
processInfo))
287+
288+
{
289+
fprintf(stderr,_("%s: could not start process for command \"%s\": error code %lu\n"),progname,cmd,GetLastError());
290+
return0;
291+
}
292+
293+
returnResumeThread(processInfo->hThread);
294+
}
295+
#endif
296+
297+
void
298+
get_restricted_token(constchar*progname)
299+
{
300+
#ifdefWIN32
301+
302+
/*
303+
* Before we execute another program, make sure that we are running with a
304+
* restricted token. If not, re-execute ourselves with one.
305+
*/
306+
307+
if ((restrict_env=getenv("PG_RESTRICT_EXEC"))==NULL
308+
||strcmp(restrict_env,"1")!=0)
309+
{
310+
PROCESS_INFORMATIONpi;
311+
char*cmdline;
312+
313+
ZeroMemory(&pi,sizeof(pi));
314+
315+
cmdline=pg_strdup(GetCommandLine());
316+
317+
putenv("PG_RESTRICT_EXEC=1");
318+
319+
if (!CreateRestrictedProcess(cmdline,&pi,progname))
320+
{
321+
fprintf(stderr,_("%s: could not re-execute with restricted token: error code %lu\n"),progname,GetLastError());
322+
}
323+
else
324+
{
325+
/*
326+
* Successfully re-execed. Now wait for child process to capture
327+
* exitcode.
328+
*/
329+
DWORDx;
330+
331+
CloseHandle(pi.hThread);
332+
WaitForSingleObject(pi.hProcess,INFINITE);
333+
334+
if (!GetExitCodeProcess(pi.hProcess,&x))
335+
{
336+
fprintf(stderr,_("%s: could not get exit code from subprocess: error code %lu\n"),progname,GetLastError());
337+
exit(1);
338+
}
339+
exit(x);
340+
}
341+
}
342+
#endif
343+
}
178344

179345
staticvoid
180346
setup(char*argv0,bool*live_check)

‎src/bin/pg_resetxlog/pg_resetxlog.c

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ static XLogSegNo newXlogSegNo;/* new XLOG segment # */
6565
staticboolguessed= false;/* T if we had to guess at any values */
6666
staticconstchar*progname;
6767

68+
#ifdefWIN32
69+
staticchar*restrict_env;
70+
#endif
71+
6872
staticboolReadControlFile(void);
6973
staticvoidGuessControlValues(void);
7074
staticvoidPrintControlValues(boolguessed);
@@ -74,7 +78,11 @@ static void KillExistingXLOG(void);
7478
staticvoidKillExistingArchiveStatus(void);
7579
staticvoidWriteEmptyXLOG(void);
7680
staticvoidusage(void);
81+
staticvoidget_restricted_token(constchar*progname);
7782

83+
#ifdefWIN32
84+
staticintCreateRestrictedProcess(char*cmd,PROCESS_INFORMATION*processInfo,constchar*progname);
85+
#endif
7886

7987
int
8088
main(intargc,char*argv[])
@@ -260,6 +268,7 @@ main(int argc, char *argv[])
260268
}
261269
#endif
262270

271+
get_restricted_token(progname);
263272
DataDir=argv[optind];
264273

265274
if (chdir(DataDir)<0)
@@ -1029,6 +1038,162 @@ WriteEmptyXLOG(void)
10291038
close(fd);
10301039
}
10311040

1041+
#ifdefWIN32
1042+
typedefBOOL(WINAPI*__CreateRestrictedToken) (HANDLE,DWORD,DWORD,PSID_AND_ATTRIBUTES,DWORD,PLUID_AND_ATTRIBUTES,DWORD,PSID_AND_ATTRIBUTES,PHANDLE);
1043+
1044+
/* Windows API define missing from some versions of MingW headers */
1045+
#ifndefDISABLE_MAX_PRIVILEGE
1046+
#defineDISABLE_MAX_PRIVILEGE0x1
1047+
#endif
1048+
1049+
/*
1050+
* Create a restricted token and execute the specified process with it.
1051+
*
1052+
* Returns 0 on failure, non-zero on success, same as CreateProcess().
1053+
*
1054+
* On NT4, or any other system not containing the required functions, will
1055+
* NOT execute anything.
1056+
*/
1057+
staticint
1058+
CreateRestrictedProcess(char*cmd,PROCESS_INFORMATION*processInfo,constchar*progname)
1059+
{
1060+
BOOLb;
1061+
STARTUPINFOsi;
1062+
HANDLEorigToken;
1063+
HANDLErestrictedToken;
1064+
SID_IDENTIFIER_AUTHORITYNtAuthority= {SECURITY_NT_AUTHORITY };
1065+
SID_AND_ATTRIBUTESdropSids[2];
1066+
__CreateRestrictedToken_CreateRestrictedToken=NULL;
1067+
HANDLEAdvapi32Handle;
1068+
1069+
ZeroMemory(&si,sizeof(si));
1070+
si.cb=sizeof(si);
1071+
1072+
Advapi32Handle=LoadLibrary("ADVAPI32.DLL");
1073+
if (Advapi32Handle!=NULL)
1074+
{
1075+
_CreateRestrictedToken= (__CreateRestrictedToken)GetProcAddress(Advapi32Handle,"CreateRestrictedToken");
1076+
}
1077+
1078+
if (_CreateRestrictedToken==NULL)
1079+
{
1080+
fprintf(stderr,_("%s: WARNING: cannot create restricted tokens on this platform\n"),progname);
1081+
if (Advapi32Handle!=NULL)
1082+
FreeLibrary(Advapi32Handle);
1083+
return0;
1084+
}
1085+
1086+
/* Open the current token to use as a base for the restricted one */
1087+
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&origToken))
1088+
{
1089+
fprintf(stderr,_("%s: could not open process token: error code %lu\n"),progname,GetLastError());
1090+
return0;
1091+
}
1092+
1093+
/* Allocate list of SIDs to remove */
1094+
ZeroMemory(&dropSids,sizeof(dropSids));
1095+
if (!AllocateAndInitializeSid(&NtAuthority,2,
1096+
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,
1097+
0,&dropSids[0].Sid)||
1098+
!AllocateAndInitializeSid(&NtAuthority,2,
1099+
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_POWER_USERS,0,0,0,0,0,
1100+
0,&dropSids[1].Sid))
1101+
{
1102+
fprintf(stderr,_("%s: could not to allocate SIDs: error code %lu\n"),progname,GetLastError());
1103+
return0;
1104+
}
1105+
1106+
b=_CreateRestrictedToken(origToken,
1107+
DISABLE_MAX_PRIVILEGE,
1108+
sizeof(dropSids) /sizeof(dropSids[0]),
1109+
dropSids,
1110+
0,NULL,
1111+
0,NULL,
1112+
&restrictedToken);
1113+
1114+
FreeSid(dropSids[1].Sid);
1115+
FreeSid(dropSids[0].Sid);
1116+
CloseHandle(origToken);
1117+
FreeLibrary(Advapi32Handle);
1118+
1119+
if (!b)
1120+
{
1121+
fprintf(stderr,_("%s: could not create restricted token: error code %lu\n"),progname,GetLastError());
1122+
return0;
1123+
}
1124+
1125+
#ifndef__CYGWIN__
1126+
AddUserToTokenDacl(restrictedToken);
1127+
#endif
1128+
1129+
if (!CreateProcessAsUser(restrictedToken,
1130+
NULL,
1131+
cmd,
1132+
NULL,
1133+
NULL,
1134+
TRUE,
1135+
CREATE_SUSPENDED,
1136+
NULL,
1137+
NULL,
1138+
&si,
1139+
processInfo))
1140+
1141+
{
1142+
fprintf(stderr,_("%s: could not start process for command \"%s\": error code %lu\n"),progname,cmd,GetLastError());
1143+
return0;
1144+
}
1145+
1146+
returnResumeThread(processInfo->hThread);
1147+
}
1148+
#endif
1149+
1150+
void
1151+
get_restricted_token(constchar*progname)
1152+
{
1153+
#ifdefWIN32
1154+
1155+
/*
1156+
* Before we execute another program, make sure that we are running with a
1157+
* restricted token. If not, re-execute ourselves with one.
1158+
*/
1159+
1160+
if ((restrict_env=getenv("PG_RESTRICT_EXEC"))==NULL
1161+
||strcmp(restrict_env,"1")!=0)
1162+
{
1163+
PROCESS_INFORMATIONpi;
1164+
char*cmdline;
1165+
1166+
ZeroMemory(&pi,sizeof(pi));
1167+
1168+
cmdline=pg_strdup(GetCommandLine());
1169+
1170+
putenv("PG_RESTRICT_EXEC=1");
1171+
1172+
if (!CreateRestrictedProcess(cmdline,&pi,progname))
1173+
{
1174+
fprintf(stderr,_("%s: could not re-execute with restricted token: error code %lu\n"),progname,GetLastError());
1175+
}
1176+
else
1177+
{
1178+
/*
1179+
* Successfully re-execed. Now wait for child process to capture
1180+
* exitcode.
1181+
*/
1182+
DWORDx;
1183+
1184+
CloseHandle(pi.hThread);
1185+
WaitForSingleObject(pi.hProcess,INFINITE);
1186+
1187+
if (!GetExitCodeProcess(pi.hProcess,&x))
1188+
{
1189+
fprintf(stderr,_("%s: could not get exit code from subprocess: error code %lu\n"),progname,GetLastError());
1190+
exit(1);
1191+
}
1192+
exit(x);
1193+
}
1194+
}
1195+
#endif
1196+
}
10321197

10331198
staticvoid
10341199
usage(void)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp