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

Commitfc9c20e

Browse files
committed
Make it possible to run initdb from an admin account on Windows,
by giving up admin privileges (only works if newer than NT4).Magnus
1 parenta25cd81 commitfc9c20e

File tree

1 file changed

+138
-1
lines changed

1 file changed

+138
-1
lines changed

‎src/bin/initdb/initdb.c

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
* Portions Copyright (c) 1994, Regents of the University of California
4343
* Portions taken from FreeBSD.
4444
*
45-
* $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.107 2006/01/27 19:01:15 tgl Exp $
45+
* $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.108 2006/02/10 22:05:42 tgl Exp $
4646
*
4747
*-------------------------------------------------------------------------
4848
*/
@@ -95,6 +95,9 @@ static char *authmethod = "";
9595
staticbooldebug= false;
9696
staticboolnoclean= false;
9797
staticboolshow_setting= false;
98+
#ifdefWIN32
99+
staticboolrestricted_exec= false;
100+
#endif
98101

99102

100103
/* internal vars */
@@ -192,6 +195,9 @@ static intlocale_date_order(const char *locale);
192195
staticboolchklocale(constchar*locale);
193196
staticvoidsetlocales(void);
194197
staticvoidusage(constchar*progname);
198+
#ifdefWIN32
199+
staticintCreateRestrictedProcess(char*cmd,PROCESS_INFORMATION*processInfo);
200+
#endif
195201

196202

197203
/*
@@ -2239,6 +2245,91 @@ setlocales(void)
22392245

22402246
}
22412247

2248+
#ifdefWIN32
2249+
/* MingW headers are incomplete */
2250+
typedefWINAPIBOOL (*__CreateRestrictedToken)(HANDLE,DWORD,DWORD,PSID_AND_ATTRIBUTES,DWORD,PLUID_AND_ATTRIBUTES,DWORD,PSID_AND_ATTRIBUTES,PHANDLE);
2251+
#defineDISABLE_MAX_PRIVILEGE 0x1
2252+
2253+
/*
2254+
* Create a restricted token and execute the specified process with it.
2255+
*
2256+
* Returns 0 on failure, non-zero on success, same as CreateProcess().
2257+
*
2258+
* On NT4, or any other system not containing the required functions, will
2259+
* NOT execute anything.
2260+
*/
2261+
staticint
2262+
CreateRestrictedProcess(char*cmd,PROCESS_INFORMATION*processInfo)
2263+
{
2264+
BOOLb;
2265+
STARTUPINFOsi;
2266+
HANDLEorigToken;
2267+
HANDLErestrictedToken;
2268+
SID_IDENTIFIER_AUTHORITYNtAuthority= {SECURITY_NT_AUTHORITY};
2269+
SID_AND_ATTRIBUTESdropSids[2];
2270+
__CreateRestrictedToken_CreateRestrictedToken=NULL;
2271+
HANDLEAdvapi32Handle;
2272+
2273+
ZeroMemory(&si,sizeof(si));
2274+
si.cb=sizeof(si);
2275+
2276+
Advapi32Handle=LoadLibrary("ADVAPI32.DLL");
2277+
if (Advapi32Handle!=NULL)
2278+
{
2279+
_CreateRestrictedToken= (__CreateRestrictedToken)GetProcAddress(Advapi32Handle,"CreateRestrictedToken");
2280+
}
2281+
2282+
if (_CreateRestrictedToken==NULL)
2283+
{
2284+
fprintf(stderr,"WARNING: Unable to create restricted tokens on this platform\n");
2285+
if (Advapi32Handle!=NULL)
2286+
FreeLibrary(Advapi32Handle);
2287+
return0;
2288+
}
2289+
2290+
/* Open the current token to use as a base for the restricted one */
2291+
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&origToken))
2292+
{
2293+
fprintf(stderr,"Failed to open process token: %lu\n",GetLastError());
2294+
return0;
2295+
}
2296+
2297+
/* Allocate list of SIDs to remove */
2298+
ZeroMemory(&dropSids,sizeof(dropSids));
2299+
if (!AllocateAndInitializeSid(&NtAuthority,2,
2300+
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,
2301+
0,&dropSids[0].Sid)||
2302+
!AllocateAndInitializeSid(&NtAuthority,2,
2303+
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_POWER_USERS,0,0,0,0,0,
2304+
0,&dropSids[1].Sid))
2305+
{
2306+
fprintf(stderr,"Failed to allocate SIDs: %lu\n",GetLastError());
2307+
return0;
2308+
}
2309+
2310+
b=_CreateRestrictedToken(origToken,
2311+
DISABLE_MAX_PRIVILEGE,
2312+
sizeof(dropSids)/sizeof(dropSids[0]),
2313+
dropSids,
2314+
0,NULL,
2315+
0,NULL,
2316+
&restrictedToken);
2317+
2318+
FreeSid(dropSids[1].Sid);
2319+
FreeSid(dropSids[0].Sid);
2320+
CloseHandle(origToken);
2321+
FreeLibrary(Advapi32Handle);
2322+
2323+
if (!b)
2324+
{
2325+
fprintf(stderr,"Failed to create restricted token: %lu\n",GetLastError());
2326+
return0;
2327+
}
2328+
2329+
returnCreateProcessAsUser(restrictedToken,NULL,cmd,NULL,NULL, TRUE,0,NULL,NULL,&si,processInfo);
2330+
}
2331+
#endif
2332+
22422333
/*
22432334
* print help text
22442335
*/
@@ -2295,6 +2386,9 @@ main(int argc, char *argv[])
22952386
{"auth",required_argument,NULL,'A'},
22962387
{"pwprompt",no_argument,NULL,'W'},
22972388
{"pwfile",required_argument,NULL,9},
2389+
#ifdefWIN32
2390+
{"restrictedexec",no_argument,NULL,10},
2391+
#endif
22982392
{"username",required_argument,NULL,'U'},
22992393
{"help",no_argument,NULL,'?'},
23002394
{"version",no_argument,NULL,'V'},
@@ -2403,6 +2497,11 @@ main(int argc, char *argv[])
24032497
case9:
24042498
pwfilename=xstrdup(optarg);
24052499
break;
2500+
#ifdefWIN32
2501+
case10:
2502+
restricted_exec= true;
2503+
break;
2504+
#endif
24062505
case's':
24072506
show_setting= true;
24082507
break;
@@ -2497,6 +2596,44 @@ main(int argc, char *argv[])
24972596
pg_data_native=pg_data;
24982597
canonicalize_path(pg_data);
24992598

2599+
#ifdefWIN32
2600+
/*
2601+
* Before we execute another program, make sure that we are running with a
2602+
* restricted token. If not, re-execute ourselves with one.
2603+
*/
2604+
if (!restricted_exec)
2605+
{
2606+
PROCESS_INFORMATIONpi;
2607+
char*cmdline;
2608+
2609+
ZeroMemory(&pi,sizeof(pi));
2610+
2611+
cmdline=pg_malloc(strlen(GetCommandLine())+19);
2612+
strcpy(cmdline,GetCommandLine());
2613+
strcat(cmdline," --restrictedexec");
2614+
2615+
if (!CreateRestrictedProcess(cmdline,&pi))
2616+
{
2617+
fprintf(stderr,"Failed to re-exec with restricted token: %lu.\n",GetLastError());
2618+
}
2619+
else
2620+
{
2621+
/* Successfully re-execed. Now wait for child process to capture exitcode. */
2622+
DWORDx;
2623+
2624+
CloseHandle(pi.hThread);
2625+
WaitForSingleObject(pi.hProcess,INFINITE);
2626+
2627+
if (!GetExitCodeProcess(pi.hProcess,&x))
2628+
{
2629+
fprintf(stderr,"Failed to get exit code from subprocess: %lu\n",GetLastError());
2630+
exit(1);
2631+
}
2632+
exit(x);
2633+
}
2634+
}
2635+
#endif
2636+
25002637
/*
25012638
* we have to set PGDATA for postgres rather than pass it on the command
25022639
* line to avoid dumb quoting problems on Windows, and we would especially

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp