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

Commitbf22a8e

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 parent8f3c577 commitbf22a8e

File tree

2 files changed

+364
-0
lines changed

2 files changed

+364
-0
lines changed

‎contrib/pg_upgrade/pg_upgrade.c

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,16 @@ static void copy_clog_xlog_xid(migratorContext *ctx);
2121
staticvoidset_frozenxids(migratorContext*ctx);
2222
staticvoidsetup(migratorContext*ctx,char*argv0,boollive_check);
2323
staticvoidcleanup(migratorContext*ctx);
24+
staticvoidget_restricted_token(constchar*progname);
2425

26+
#ifdefWIN32
27+
staticchar*pg_strdupn(constchar*str);
28+
staticintCreateRestrictedProcess(char*cmd,PROCESS_INFORMATION*processInfo,constchar*progname);
29+
#endif
30+
31+
#ifdefWIN32
32+
staticchar*restrict_env;
33+
#endif
2534

2635
int
2736
main(intargc,char**argv)
@@ -35,6 +44,8 @@ main(int argc, char **argv)
3544

3645
parseCommandLine(&ctx,argc,argv);
3746

47+
get_restricted_token(ctx.progname);
48+
3849
output_check_banner(&ctx,&live_check);
3950

4051
setup(&ctx,argv[0],live_check);
@@ -103,6 +114,162 @@ main(int argc, char **argv)
103114
return0;
104115
}
105116

117+
#ifdefWIN32
118+
typedefBOOL(WINAPI*__CreateRestrictedToken) (HANDLE,DWORD,DWORD,PSID_AND_ATTRIBUTES,DWORD,PLUID_AND_ATTRIBUTES,DWORD,PSID_AND_ATTRIBUTES,PHANDLE);
119+
120+
/* Windows API define missing from some versions of MingW headers */
121+
#ifndefDISABLE_MAX_PRIVILEGE
122+
#defineDISABLE_MAX_PRIVILEGE0x1
123+
#endif
124+
125+
/*
126+
* Create a restricted token and execute the specified process with it.
127+
*
128+
* Returns 0 on failure, non-zero on success, same as CreateProcess().
129+
*
130+
* On NT4, or any other system not containing the required functions, will
131+
* NOT execute anything.
132+
*/
133+
staticint
134+
CreateRestrictedProcess(char*cmd,PROCESS_INFORMATION*processInfo,constchar*progname)
135+
{
136+
BOOLb;
137+
STARTUPINFOsi;
138+
HANDLEorigToken;
139+
HANDLErestrictedToken;
140+
SID_IDENTIFIER_AUTHORITYNtAuthority= {SECURITY_NT_AUTHORITY };
141+
SID_AND_ATTRIBUTESdropSids[2];
142+
__CreateRestrictedToken_CreateRestrictedToken=NULL;
143+
HANDLEAdvapi32Handle;
144+
145+
ZeroMemory(&si,sizeof(si));
146+
si.cb=sizeof(si);
147+
148+
Advapi32Handle=LoadLibrary("ADVAPI32.DLL");
149+
if (Advapi32Handle!=NULL)
150+
{
151+
_CreateRestrictedToken= (__CreateRestrictedToken)GetProcAddress(Advapi32Handle,"CreateRestrictedToken");
152+
}
153+
154+
if (_CreateRestrictedToken==NULL)
155+
{
156+
fprintf(stderr,_("%s: WARNING: cannot create restricted tokens on this platform\n"),progname);
157+
if (Advapi32Handle!=NULL)
158+
FreeLibrary(Advapi32Handle);
159+
return0;
160+
}
161+
162+
/* Open the current token to use as a base for the restricted one */
163+
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&origToken))
164+
{
165+
fprintf(stderr,_("%s: could not open process token: error code %lu\n"),progname,GetLastError());
166+
return0;
167+
}
168+
169+
/* Allocate list of SIDs to remove */
170+
ZeroMemory(&dropSids,sizeof(dropSids));
171+
if (!AllocateAndInitializeSid(&NtAuthority,2,
172+
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,
173+
0,&dropSids[0].Sid)||
174+
!AllocateAndInitializeSid(&NtAuthority,2,
175+
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_POWER_USERS,0,0,0,0,0,
176+
0,&dropSids[1].Sid))
177+
{
178+
fprintf(stderr,_("%s: could not to allocate SIDs: error code %lu\n"),progname,GetLastError());
179+
return0;
180+
}
181+
182+
b=_CreateRestrictedToken(origToken,
183+
DISABLE_MAX_PRIVILEGE,
184+
sizeof(dropSids) /sizeof(dropSids[0]),
185+
dropSids,
186+
0,NULL,
187+
0,NULL,
188+
&restrictedToken);
189+
190+
FreeSid(dropSids[1].Sid);
191+
FreeSid(dropSids[0].Sid);
192+
CloseHandle(origToken);
193+
FreeLibrary(Advapi32Handle);
194+
195+
if (!b)
196+
{
197+
fprintf(stderr,_("%s: could not create restricted token: error code %lu\n"),progname,GetLastError());
198+
return0;
199+
}
200+
201+
#ifndef__CYGWIN__
202+
AddUserToTokenDacl(restrictedToken);
203+
#endif
204+
205+
if (!CreateProcessAsUser(restrictedToken,
206+
NULL,
207+
cmd,
208+
NULL,
209+
NULL,
210+
TRUE,
211+
CREATE_SUSPENDED,
212+
NULL,
213+
NULL,
214+
&si,
215+
processInfo))
216+
217+
{
218+
fprintf(stderr,_("%s: could not start process for command \"%s\": error code %lu\n"),progname,cmd,GetLastError());
219+
return0;
220+
}
221+
222+
returnResumeThread(processInfo->hThread);
223+
}
224+
#endif
225+
226+
void
227+
get_restricted_token(constchar*progname)
228+
{
229+
#ifdefWIN32
230+
231+
/*
232+
* Before we execute another program, make sure that we are running with a
233+
* restricted token. If not, re-execute ourselves with one.
234+
*/
235+
236+
if ((restrict_env=getenv("PG_RESTRICT_EXEC"))==NULL
237+
||strcmp(restrict_env,"1")!=0)
238+
{
239+
PROCESS_INFORMATIONpi;
240+
char*cmdline;
241+
242+
ZeroMemory(&pi,sizeof(pi));
243+
244+
cmdline=pg_strdupn(GetCommandLine());
245+
246+
putenv("PG_RESTRICT_EXEC=1");
247+
248+
if (!CreateRestrictedProcess(cmdline,&pi,progname))
249+
{
250+
fprintf(stderr,_("%s: could not re-execute with restricted token: error code %lu\n"),progname,GetLastError());
251+
}
252+
else
253+
{
254+
/*
255+
* Successfully re-execed. Now wait for child process to capture
256+
* exitcode.
257+
*/
258+
DWORDx;
259+
260+
CloseHandle(pi.hThread);
261+
WaitForSingleObject(pi.hProcess,INFINITE);
262+
263+
if (!GetExitCodeProcess(pi.hProcess,&x))
264+
{
265+
fprintf(stderr,_("%s: could not get exit code from subprocess: error code %lu\n"),progname,GetLastError());
266+
exit(1);
267+
}
268+
exit(x);
269+
}
270+
}
271+
#endif
272+
}
106273

107274
staticvoid
108275
setup(migratorContext*ctx,char*argv0,boollive_check)
@@ -443,3 +610,18 @@ cleanup(migratorContext *ctx)
443610
snprintf(filename,sizeof(filename),"%s/%s",ctx->cwd,DB_DUMP_FILE);
444611
unlink(filename);
445612
}
613+
614+
#ifdefWIN32
615+
staticchar*
616+
pg_strdupn(constchar*str)
617+
{
618+
char*result=strdup(str);
619+
620+
if (!result)
621+
{
622+
fprintf(stderr,_("out of memory\n"));
623+
exit(1);
624+
}
625+
returnresult;
626+
}
627+
#endif

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp