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

Commit2d2b022

Browse files
committed
Fix handling of restricted processes for Windows Vista (mainly),
by explicitly adding back the user to the DACL of the new process.This fixes the failure case when executing as the Administratoruser, which had no permissions left at all after we dropped theAdministrators group.Dave Page with some modifications from me
1 parent4db0d87 commit2d2b022

File tree

4 files changed

+249
-5
lines changed

4 files changed

+249
-5
lines changed

‎src/bin/initdb/initdb.c

Lines changed: 21 additions & 2 deletions
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.153 2008/02/20 22:46:24 tgl Exp $
45+
* $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.154 2008/02/29 15:31:33 mha Exp $
4646
*
4747
*-------------------------------------------------------------------------
4848
*/
@@ -2329,7 +2329,26 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo)
23292329
return0;
23302330
}
23312331

2332-
returnCreateProcessAsUser(restrictedToken,NULL,cmd,NULL,NULL, TRUE,0,NULL,NULL,&si,processInfo);
2332+
if (!CreateProcessAsUser(restrictedToken,
2333+
NULL,
2334+
cmd,
2335+
NULL,
2336+
NULL,
2337+
TRUE,
2338+
CREATE_SUSPENDED,
2339+
NULL,
2340+
NULL,
2341+
&si,
2342+
processInfo))
2343+
2344+
{
2345+
fprintf(stderr,"CreateProcessAsUser failed: %lu\n",GetLastError());
2346+
return0;
2347+
}
2348+
2349+
AddUserToDacl(processInfo->hProcess);
2350+
2351+
returnResumeThread(processInfo->hThread);
23332352
}
23342353
#endif
23352354

‎src/bin/pg_ctl/pg_ctl.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
66
*
7-
* $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.94 2008/02/20 22:46:24 tgl Exp $
7+
* $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.95 2008/02/29 15:31:33 mha Exp $
88
*
99
*-------------------------------------------------------------------------
1010
*/
@@ -1469,6 +1469,8 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo)
14691469
}
14701470
}
14711471

1472+
AddUserToDacl(processInfo->hProcess);
1473+
14721474
CloseHandle(restrictedToken);
14731475

14741476
ResumeThread(processInfo->hThread);

‎src/include/port.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/port.h,v 1.117 2008/02/18 14:51:48 petere Exp $
9+
* $PostgreSQL: pgsql/src/include/port.h,v 1.118 2008/02/29 15:31:33 mha Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -79,6 +79,12 @@ extern intfind_my_exec(const char *argv0, char *retpath);
7979
externintfind_other_exec(constchar*argv0,constchar*target,
8080
constchar*versionstr,char*retpath);
8181

82+
/* Windows security token manipulation (in exec.c) */
83+
#ifdefWIN32
84+
externBOOLAddUserToDacl(HANDLEhProcess);
85+
#endif
86+
87+
8288
#if defined(WIN32)|| defined(__CYGWIN__)
8389
#defineEXE ".exe"
8490
#else

‎src/port/exec.c

Lines changed: 218 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/port/exec.c,v 1.57 2008/01/01 19:46:00 momjian Exp $
12+
* $PostgreSQL: pgsql/src/port/exec.c,v 1.58 2008/02/29 15:31:33 mha Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -55,6 +55,9 @@ static intvalidate_exec(const char *path);
5555
staticintresolve_symlinks(char*path);
5656
staticchar*pipe_read_line(char*cmd,char*line,intmaxsize);
5757

58+
#ifdefWIN32
59+
staticBOOLGetUserSid(PSID*ppSidUser,HANDLEhToken);
60+
#endif
5861

5962
/*
6063
* validate_exec -- validate "path" as an executable file
@@ -657,3 +660,217 @@ set_pglocale_pgservice(const char *argv0, const char *app)
657660
putenv(strdup(env_path));
658661
}
659662
}
663+
664+
#ifdefWIN32
665+
666+
/*
667+
* AddUserToDacl(HANDLE hProcess)
668+
*
669+
* This function adds the current user account to the default DACL
670+
* which gets attached to the restricted token used when we create
671+
* a restricted process.
672+
*
673+
* This is required because of some security changes in Windows
674+
* that appeared in patches to XP/2K3 and in Vista/2008.
675+
*
676+
* On these machines, the Administrator account is not included in
677+
* the default DACL - you just get Administrators + System. For
678+
* regular users you get User + System. Because we strip Administrators
679+
* when we create the restricted token, we are left with only System
680+
* in the DACL which leads to access denied errors for later CreatePipe()
681+
* and CreateProcess() calls when running as Administrator.
682+
*
683+
* This function fixes this problem by modifying the DACL of the
684+
* specified process and explicitly re-adding the current user account.
685+
* This is still secure because the Administrator account inherits it's
686+
* privileges from the Administrators group - it doesn't have any of
687+
* it's own.
688+
*/
689+
BOOL
690+
AddUserToDacl(HANDLEhProcess)
691+
{
692+
inti;
693+
ACL_SIZE_INFORMATIONasi;
694+
ACCESS_ALLOWED_ACE*pace;
695+
DWORDdwNewAclSize;
696+
DWORDdwSize=0;
697+
DWORDdwTokenInfoLength=0;
698+
DWORDdwResult=0;
699+
HANDLEhToken=NULL;
700+
PACLpacl=NULL;
701+
PSIDpsidUser=NULL;
702+
TOKEN_DEFAULT_DACLtddNew;
703+
TOKEN_DEFAULT_DACL*ptdd=NULL;
704+
TOKEN_INFORMATION_CLASStic=TokenDefaultDacl;
705+
BOOLret= FALSE;
706+
707+
/* Get the token for the process */
708+
if (!OpenProcessToken(hProcess,TOKEN_QUERY |TOKEN_ADJUST_DEFAULT,&hToken))
709+
{
710+
log_error("could not open process token: %ui",GetLastError());
711+
gotocleanup;
712+
}
713+
714+
/* Figure out the buffer size for the DACL info */
715+
if (!GetTokenInformation(hToken,tic, (LPVOID)NULL,dwTokenInfoLength,&dwSize))
716+
{
717+
if (GetLastError()==ERROR_INSUFFICIENT_BUFFER)
718+
{
719+
ptdd= (TOKEN_DEFAULT_DACL*)LocalAlloc(LPTR,dwSize);
720+
if (ptdd==NULL)
721+
{
722+
log_error("could not allocate %i bytes of memory",dwSize);
723+
gotocleanup;
724+
}
725+
726+
if (!GetTokenInformation(hToken,tic, (LPVOID)ptdd,dwSize,&dwSize))
727+
{
728+
log_error("could not get token information: %ui",GetLastError());
729+
gotocleanup;
730+
}
731+
}
732+
else
733+
{
734+
log_error("could not get token information buffer size: %ui",GetLastError());
735+
gotocleanup;
736+
}
737+
}
738+
739+
/* Get the ACL info */
740+
if (!GetAclInformation(ptdd->DefaultDacl, (LPVOID)&asi,
741+
(DWORD)sizeof(ACL_SIZE_INFORMATION),
742+
AclSizeInformation))
743+
{
744+
log_error("could not get ACL information: %ui",GetLastError());
745+
gotocleanup;
746+
}
747+
748+
/* Get the SID for the current user. We need to add this to the ACL. */
749+
if (!GetUserSid(&psidUser,hToken))
750+
{
751+
log_error("could not get user SID: %ui",GetLastError());
752+
gotocleanup;
753+
}
754+
755+
/* Figure out the size of the new ACL */
756+
dwNewAclSize=asi.AclBytesInUse+sizeof(ACCESS_ALLOWED_ACE)+GetLengthSid(psidUser)-sizeof(DWORD);
757+
758+
/* Allocate the ACL buffer & initialize it */
759+
pacl= (PACL)LocalAlloc(LPTR,dwNewAclSize);
760+
if (pacl==NULL)
761+
{
762+
log_error("could not allocate %i bytes of memory",dwNewAclSize);
763+
gotocleanup;
764+
}
765+
766+
if (!InitializeAcl(pacl,dwNewAclSize,ACL_REVISION))
767+
{
768+
log_error("could not initialize ACL: %ui",GetLastError());
769+
gotocleanup;
770+
}
771+
772+
/* Loop through the existing ACEs, and build the new ACL */
773+
for (i=0;i< (int)asi.AceCount;i++)
774+
{
775+
if (!GetAce(ptdd->DefaultDacl,i, (LPVOID*)&pace))
776+
{
777+
log_error("could not get ACE: %ui",GetLastError());
778+
gotocleanup;
779+
}
780+
781+
if (!AddAce(pacl,ACL_REVISION,MAXDWORD,pace, ((PACE_HEADER)pace)->AceSize))
782+
{
783+
log_error("could not add ACE: %ui",GetLastError());
784+
gotocleanup;
785+
}
786+
}
787+
788+
/* Add the new ACE for the current user */
789+
if (!AddAccessAllowedAce(pacl,ACL_REVISION,GENERIC_ALL,psidUser))
790+
{
791+
log_error("could not add access allowed ACE: %ui",GetLastError());
792+
gotocleanup;
793+
}
794+
795+
/* Set the new DACL in the token */
796+
tddNew.DefaultDacl=pacl;
797+
798+
if (!SetTokenInformation(hToken,tic, (LPVOID)&tddNew,dwNewAclSize))
799+
{
800+
log_error("could not set token information: %ui",GetLastError());
801+
gotocleanup;
802+
}
803+
804+
ret= TRUE;
805+
806+
cleanup:
807+
if (psidUser)
808+
FreeSid(psidUser);
809+
810+
if (pacl)
811+
LocalFree((HLOCAL)pacl);
812+
813+
if (ptdd)
814+
LocalFree((HLOCAL)ptdd);
815+
816+
if (hToken)
817+
CloseHandle(hToken);
818+
819+
returnret;
820+
}
821+
822+
/*
823+
* GetUserSid*PSID *ppSidUser, HANDLE hToken)
824+
*
825+
* Get the SID for the current user
826+
*/
827+
staticBOOL
828+
GetUserSid(PSID*ppSidUser,HANDLEhToken)
829+
{
830+
DWORDdwLength;
831+
DWORDcbName=250;
832+
DWORDcbDomainName=250;
833+
PTOKEN_USERpTokenUser=NULL;
834+
835+
836+
if (!GetTokenInformation(hToken,
837+
TokenUser,
838+
pTokenUser,
839+
0,
840+
&dwLength))
841+
{
842+
if (GetLastError()==ERROR_INSUFFICIENT_BUFFER)
843+
{
844+
pTokenUser= (PTOKEN_USER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwLength);
845+
846+
if (pTokenUser==NULL)
847+
{
848+
log_error("could not allocate %ui bytes of memory",dwLength);
849+
return FALSE;
850+
}
851+
}
852+
else
853+
{
854+
log_error("could not get token information buffer size: %ui",GetLastError());
855+
return FALSE;
856+
}
857+
}
858+
859+
if (!GetTokenInformation(hToken,
860+
TokenUser,
861+
pTokenUser,
862+
dwLength,
863+
&dwLength))
864+
{
865+
HeapFree(GetProcessHeap(),0,pTokenUser);
866+
pTokenUser=NULL;
867+
868+
log_error("could not get token information: %ui",GetLastError());
869+
return FALSE;
870+
}
871+
872+
*ppSidUser=pTokenUser->User.Sid;
873+
return TRUE;
874+
}
875+
876+
#endif

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp