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

Commit2366761

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 parenta6a8bf5 commit2366761

File tree

2 files changed

+332
-0
lines changed

2 files changed

+332
-0
lines changed

‎contrib/pg_upgrade/pg_upgrade.c

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

5358
ClusterInfoold_cluster,
5459
new_cluster;
@@ -65,6 +70,9 @@ char *output_files[] = {
6570
NULL
6671
};
6772

73+
#ifdefWIN32
74+
staticchar*restrict_env;
75+
#endif
6876

6977
int
7078
main(intargc,char**argv)
@@ -76,6 +84,8 @@ main(int argc, char **argv)
7684

7785
parseCommandLine(argc,argv);
7886

87+
get_restricted_token(os_info.progname);
88+
7989
adjust_data_dir(&old_cluster);
8090
adjust_data_dir(&new_cluster);
8191

@@ -174,6 +184,162 @@ main(int argc, char **argv)
174184
return0;
175185
}
176186

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

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

‎src/bin/pg_resetxlog/pg_resetxlog.c

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ static MultiXactOffset set_mxoff = (MultiXactOffset) -1;
6868
staticuint32minXlogTli=0;
6969
staticXLogSegNominXlogSegNo=0;
7070

71+
#ifdefWIN32
72+
staticchar*restrict_env;
73+
#endif
74+
7175
staticboolReadControlFile(void);
7276
staticvoidGuessControlValues(void);
7377
staticvoidPrintControlValues(boolguessed);
@@ -78,6 +82,11 @@ static void KillExistingXLOG(void);
7882
staticvoidKillExistingArchiveStatus(void);
7983
staticvoidWriteEmptyXLOG(void);
8084
staticvoidusage(void);
85+
staticvoidget_restricted_token(constchar*progname);
86+
87+
#ifdefWIN32
88+
staticintCreateRestrictedProcess(char*cmd,PROCESS_INFORMATION*processInfo,constchar*progname);
89+
#endif
8190

8291

8392
int
@@ -257,6 +266,7 @@ main(int argc, char *argv[])
257266
}
258267
#endif
259268

269+
get_restricted_token(progname);
260270
DataDir=argv[optind];
261271

262272
if (chdir(DataDir)<0)
@@ -1072,6 +1082,162 @@ WriteEmptyXLOG(void)
10721082
close(fd);
10731083
}
10741084

1085+
#ifdefWIN32
1086+
typedefBOOL(WINAPI*__CreateRestrictedToken) (HANDLE,DWORD,DWORD,PSID_AND_ATTRIBUTES,DWORD,PLUID_AND_ATTRIBUTES,DWORD,PSID_AND_ATTRIBUTES,PHANDLE);
1087+
1088+
/* Windows API define missing from some versions of MingW headers */
1089+
#ifndefDISABLE_MAX_PRIVILEGE
1090+
#defineDISABLE_MAX_PRIVILEGE0x1
1091+
#endif
1092+
1093+
/*
1094+
* Create a restricted token and execute the specified process with it.
1095+
*
1096+
* Returns 0 on failure, non-zero on success, same as CreateProcess().
1097+
*
1098+
* On NT4, or any other system not containing the required functions, will
1099+
* NOT execute anything.
1100+
*/
1101+
staticint
1102+
CreateRestrictedProcess(char*cmd,PROCESS_INFORMATION*processInfo,constchar*progname)
1103+
{
1104+
BOOLb;
1105+
STARTUPINFOsi;
1106+
HANDLEorigToken;
1107+
HANDLErestrictedToken;
1108+
SID_IDENTIFIER_AUTHORITYNtAuthority= {SECURITY_NT_AUTHORITY };
1109+
SID_AND_ATTRIBUTESdropSids[2];
1110+
__CreateRestrictedToken_CreateRestrictedToken=NULL;
1111+
HANDLEAdvapi32Handle;
1112+
1113+
ZeroMemory(&si,sizeof(si));
1114+
si.cb=sizeof(si);
1115+
1116+
Advapi32Handle=LoadLibrary("ADVAPI32.DLL");
1117+
if (Advapi32Handle!=NULL)
1118+
{
1119+
_CreateRestrictedToken= (__CreateRestrictedToken)GetProcAddress(Advapi32Handle,"CreateRestrictedToken");
1120+
}
1121+
1122+
if (_CreateRestrictedToken==NULL)
1123+
{
1124+
fprintf(stderr,_("%s: WARNING: cannot create restricted tokens on this platform\n"),progname);
1125+
if (Advapi32Handle!=NULL)
1126+
FreeLibrary(Advapi32Handle);
1127+
return0;
1128+
}
1129+
1130+
/* Open the current token to use as a base for the restricted one */
1131+
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&origToken))
1132+
{
1133+
fprintf(stderr,_("%s: could not open process token: error code %lu\n"),progname,GetLastError());
1134+
return0;
1135+
}
1136+
1137+
/* Allocate list of SIDs to remove */
1138+
ZeroMemory(&dropSids,sizeof(dropSids));
1139+
if (!AllocateAndInitializeSid(&NtAuthority,2,
1140+
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,
1141+
0,&dropSids[0].Sid)||
1142+
!AllocateAndInitializeSid(&NtAuthority,2,
1143+
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_POWER_USERS,0,0,0,0,0,
1144+
0,&dropSids[1].Sid))
1145+
{
1146+
fprintf(stderr,_("%s: could not to allocate SIDs: error code %lu\n"),progname,GetLastError());
1147+
return0;
1148+
}
1149+
1150+
b=_CreateRestrictedToken(origToken,
1151+
DISABLE_MAX_PRIVILEGE,
1152+
sizeof(dropSids) /sizeof(dropSids[0]),
1153+
dropSids,
1154+
0,NULL,
1155+
0,NULL,
1156+
&restrictedToken);
1157+
1158+
FreeSid(dropSids[1].Sid);
1159+
FreeSid(dropSids[0].Sid);
1160+
CloseHandle(origToken);
1161+
FreeLibrary(Advapi32Handle);
1162+
1163+
if (!b)
1164+
{
1165+
fprintf(stderr,_("%s: could not create restricted token: error code %lu\n"),progname,GetLastError());
1166+
return0;
1167+
}
1168+
1169+
#ifndef__CYGWIN__
1170+
AddUserToTokenDacl(restrictedToken);
1171+
#endif
1172+
1173+
if (!CreateProcessAsUser(restrictedToken,
1174+
NULL,
1175+
cmd,
1176+
NULL,
1177+
NULL,
1178+
TRUE,
1179+
CREATE_SUSPENDED,
1180+
NULL,
1181+
NULL,
1182+
&si,
1183+
processInfo))
1184+
1185+
{
1186+
fprintf(stderr,_("%s: could not start process for command \"%s\": error code %lu\n"),progname,cmd,GetLastError());
1187+
return0;
1188+
}
1189+
1190+
returnResumeThread(processInfo->hThread);
1191+
}
1192+
#endif
1193+
1194+
void
1195+
get_restricted_token(constchar*progname)
1196+
{
1197+
#ifdefWIN32
1198+
1199+
/*
1200+
* Before we execute another program, make sure that we are running with a
1201+
* restricted token. If not, re-execute ourselves with one.
1202+
*/
1203+
1204+
if ((restrict_env=getenv("PG_RESTRICT_EXEC"))==NULL
1205+
||strcmp(restrict_env,"1")!=0)
1206+
{
1207+
PROCESS_INFORMATIONpi;
1208+
char*cmdline;
1209+
1210+
ZeroMemory(&pi,sizeof(pi));
1211+
1212+
cmdline=pg_strdup(GetCommandLine());
1213+
1214+
putenv("PG_RESTRICT_EXEC=1");
1215+
1216+
if (!CreateRestrictedProcess(cmdline,&pi,progname))
1217+
{
1218+
fprintf(stderr,_("%s: could not re-execute with restricted token: error code %lu\n"),progname,GetLastError());
1219+
}
1220+
else
1221+
{
1222+
/*
1223+
* Successfully re-execed. Now wait for child process to capture
1224+
* exitcode.
1225+
*/
1226+
DWORDx;
1227+
1228+
CloseHandle(pi.hThread);
1229+
WaitForSingleObject(pi.hProcess,INFINITE);
1230+
1231+
if (!GetExitCodeProcess(pi.hProcess,&x))
1232+
{
1233+
fprintf(stderr,_("%s: could not get exit code from subprocess: error code %lu\n"),progname,GetLastError());
1234+
exit(1);
1235+
}
1236+
exit(x);
1237+
}
1238+
}
1239+
#endif
1240+
}
10751241

10761242
staticvoid
10771243
usage(void)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp