Ver código fonte

CreateSafeDirectory change.

Martijn Laan 1 ano atrás
pai
commit
ba9bdedad7

+ 1 - 1
Projects/SetupLdr.dpr

@@ -445,7 +445,7 @@ begin
         { Create a temporary directory, and extract the embedded setup program
         { Create a temporary directory, and extract the embedded setup program
           there }
           there }
         Randomize;
         Randomize;
-        TempDir := CreateTempDir;
+        TempDir := CreateTempDir(IsAdminLoggedOn);
         S := AddBackslash(TempDir) + PathChangeExt(PathExtractName(SelfFilename), '.tmp');
         S := AddBackslash(TempDir) + PathChangeExt(PathExtractName(SelfFilename), '.tmp');
         TempFile := S;  { assign only if string was successfully constructed }
         TempFile := S;  { assign only if string was successfully constructed }
 
 

+ 31 - 15
Projects/Src/InstFunc.pas

@@ -49,7 +49,7 @@ type
 
 
 function CheckForMutexes(const Mutexes: String): Boolean;
 function CheckForMutexes(const Mutexes: String): Boolean;
 procedure CreateMutexes(const Mutexes: String);
 procedure CreateMutexes(const Mutexes: String);
-function CreateTempDir: String;
+function CreateTempDir(const IsAdminAndNotDebugging: Boolean): String;
 function DecrementSharedCount(const RegView: TRegView; const Filename: String): Boolean;
 function DecrementSharedCount(const RegView: TRegView; const Filename: String): Boolean;
 procedure DelayDeleteFile(const DisableFsRedir: Boolean; const Filename: String;
 procedure DelayDeleteFile(const DisableFsRedir: Boolean; const Filename: String;
   const MaxTries, FirstRetryDelayMS, SubsequentRetryDelayMS: Integer);
   const MaxTries, FirstRetryDelayMS, SubsequentRetryDelayMS: Integer);
@@ -62,7 +62,8 @@ function DetermineDefaultLanguage(const GetLanguageEntryProc: TGetLanguageEntryP
   var ResultIndex: Integer): TDetermineDefaultLanguageResult;
   var ResultIndex: Integer): TDetermineDefaultLanguageResult;
 procedure EnumFileReplaceOperationsFilenames(const EnumFunc: TEnumFROFilenamesProc;
 procedure EnumFileReplaceOperationsFilenames(const EnumFunc: TEnumFROFilenamesProc;
   Param: Pointer);
   Param: Pointer);
-function GenerateNonRandomUniqueTempDir(Path: String; var TempDir: String): Boolean;
+function GenerateNonRandomUniqueTempDir(const IsAdminAndNotDebugging: Boolean;
+  Path: String; var TempDir: String): Boolean;
 function GenerateUniqueName(const DisableFsRedir: Boolean; Path: String;
 function GenerateUniqueName(const DisableFsRedir: Boolean; Path: String;
   const Extension: String): String;
   const Extension: String): String;
 function GetComputerNameString: String;
 function GetComputerNameString: String;
@@ -173,8 +174,11 @@ function ConvertStringSecurityDescriptorToSecurityDescriptorW(
   StringSDRevision: DWORD; var ppSecurityDescriptor: Pointer;
   StringSDRevision: DWORD; var ppSecurityDescriptor: Pointer;
   dummy: Pointer): BOOL; stdcall; external advapi32;
   dummy: Pointer): BOOL; stdcall; external advapi32;
 
 
-function CreateSafeDirectory(Path: PWideChar; var ErrorCode: DWORD): Boolean;
-{ Creates a protected directory if it's a subdirectory of c:\WINDOWS\TEMP,
+function CreateSafeDirectory(const IsAdminAndNotDebugging: Boolean; Path: PWideChar;
+  var ErrorCode: DWORD): Boolean;
+{ Creates a protected directory if
+  -it's a subdirectory of c:\WINDOWS\TEMP, or
+  -it's on a local drive, we have administrative privileges, and debugging is not active,
   otherwise creates a normal directory. }
   otherwise creates a normal directory. }
 const
 const
   SDDL_REVISION_1 = 1;
   SDDL_REVISION_1 = 1;
@@ -183,26 +187,37 @@ var
   pSecurityDescriptor: Pointer;
   pSecurityDescriptor: Pointer;
   SecurityAttr: TSecurityAttributes;
   SecurityAttr: TSecurityAttributes;
 begin
 begin
-  if Pos(PathLowercase(AddBackslash(GetSystemWinDir) + 'TEMP\'),
-     PathLowercase(PathExpand(Path))) <> 1 then begin
+  var IsUnderWindowsTemp := Pos(PathLowercase(AddBackslash(GetSystemWinDir) + 'TEMP\'),
+    PathLowercase(PathExpand(Path))) = 1;
+  var Drive := PathExtractDrive(Path);
+  var IsAdminAndIsLocalTemp := IsAdminAndNotDebugging and (Drive <> '') and
+    not PathCharIsSlash(Drive[1]) and
+    (GetDriveType(PChar(AddBackslash(Drive))) = DRIVE_FIXED);
+
+  if not IsUnderWindowsTemp and not IsAdminAndIsLocalTemp then begin
     Result := CreateDirectoryW(Path, nil);
     Result := CreateDirectoryW(Path, nil);
     if not Result then
     if not Result then
       ErrorCode := GetLastError;
       ErrorCode := GetLastError;
     Exit;
     Exit;
   end;
   end;
-  CurrentUserSid := GetCurrentUserSid;
-  if CurrentUserSid = '' then
-    CurrentUserSid := 'OW'; // OW: owner rights
+
   StringSecurityDescriptor :=
   StringSecurityDescriptor :=
     // D: adds a Discretionary ACL ("DACL", i.e. access control via SIDs)
     // D: adds a Discretionary ACL ("DACL", i.e. access control via SIDs)
     // P: prevents DACL from being modified by inherited ACLs
     // P: prevents DACL from being modified by inherited ACLs
-    'D:P' +
+    'D:P';
+  if IsUnderWindowsTemp then begin
+    CurrentUserSid := GetCurrentUserSid;
+    if CurrentUserSid = '' then
+      CurrentUserSid := 'OW'; // OW: owner rights
     // A: "allow"
     // A: "allow"
     // OICI: "object and container inherit",
     // OICI: "object and container inherit",
     //    i.e. files and directories created within the new directory
     //    i.e. files and directories created within the new directory
     //    inherit these permissions
     //    inherit these permissions
     // 0x001F01FF: corresponds to `FILE_ALL_ACCESS`
     // 0x001F01FF: corresponds to `FILE_ALL_ACCESS`
-    '(A;OICI;0x001F01FF;;;' + CurrentUserSid + ')' + // current user
+    StringSecurityDescriptor := StringSecurityDescriptor +
+      '(A;OICI;0x001F01FF;;;' + CurrentUserSid + ')'; // current user
+  end;
+  StringSecurityDescriptor := StringSecurityDescriptor +
     '(A;OICI;0x001F01FF;;;BA)' + // BA: built-in administrator
     '(A;OICI;0x001F01FF;;;BA)' + // BA: built-in administrator
     '(A;OICI;0x001F01FF;;;SY)'; // SY: local SYSTEM account
     '(A;OICI;0x001F01FF;;;SY)'; // SY: local SYSTEM account
   if not ConvertStringSecurityDescriptorToSecurityDescriptorW(
   if not ConvertStringSecurityDescriptorToSecurityDescriptorW(
@@ -260,7 +275,8 @@ begin
   Result := Filename;
   Result := Filename;
 end;
 end;
 
 
-function GenerateNonRandomUniqueTempDir(Path: String; var TempDir: String): Boolean;
+function GenerateNonRandomUniqueTempDir(const IsAdminAndNotDebugging: Boolean;
+  Path: String; var TempDir: String): Boolean;
 { Creates a new temporary directory with a non-random name. Returns True if an
 { Creates a new temporary directory with a non-random name. Returns True if an
   existing directory was re-created. This is called by Uninstall. }
   existing directory was re-created. This is called by Uninstall. }
 var
 var
@@ -287,7 +303,7 @@ begin
     end else if NewFileExists(TempDir) then
     end else if NewFileExists(TempDir) then
       if not DeleteFile(TempDir) then Continue;
       if not DeleteFile(TempDir) then Continue;
 
 
-    if CreateSafeDirectory(PChar(TempDir), ErrorCode) then Break;
+    if CreateSafeDirectory(IsAdminAndNotDebugging, PChar(TempDir), ErrorCode) then Break;
     if ErrorCode <> ERROR_ALREADY_EXISTS then
     if ErrorCode <> ERROR_ALREADY_EXISTS then
       raise Exception.Create(FmtSetupMessage(msgLastErrorMessage,
       raise Exception.Create(FmtSetupMessage(msgLastErrorMessage,
         [FmtSetupMessage1(msgErrorCreatingDir, TempDir), IntToStr(ErrorCode),
         [FmtSetupMessage1(msgErrorCreatingDir, TempDir), IntToStr(ErrorCode),
@@ -295,7 +311,7 @@ begin
   until False; // continue until a new directory was created
   until False; // continue until a new directory was created
 end;
 end;
 
 
-function CreateTempDir: String;
+function CreateTempDir(const IsAdminAndNotDebugging: Boolean): String;
 { This is called by SetupLdr, Setup, and Uninstall. }
 { This is called by SetupLdr, Setup, and Uninstall. }
 var
 var
   Dir: String;
   Dir: String;
@@ -303,7 +319,7 @@ var
 begin
 begin
   while True do begin
   while True do begin
     Dir := GenerateUniqueName(False, GetTempDir, '.tmp');
     Dir := GenerateUniqueName(False, GetTempDir, '.tmp');
-    if CreateSafeDirectory(PChar(Dir), ErrorCode) then
+    if CreateSafeDirectory(IsAdminAndNotDebugging, PChar(Dir), ErrorCode) then
       Break;
       Break;
     if ErrorCode <> ERROR_ALREADY_EXISTS then
     if ErrorCode <> ERROR_ALREADY_EXISTS then
       raise Exception.Create(FmtSetupMessage(msgLastErrorMessage,
       raise Exception.Create(FmtSetupMessage(msgLastErrorMessage,

+ 1 - 1
Projects/Src/Main.pas

@@ -1454,7 +1454,7 @@ var
   Subdir, ResName, Filename: String;
   Subdir, ResName, Filename: String;
   ErrorCode: DWORD;
   ErrorCode: DWORD;
 begin
 begin
-  TempInstallDir := CreateTempDir;
+  TempInstallDir := CreateTempDir(IsAdmin and not Debugging);
   Log('Created temporary directory: ' + TempInstallDir);
   Log('Created temporary directory: ' + TempInstallDir);
   if Debugging then
   if Debugging then
     DebugNotifyTempDir(TempInstallDir);
     DebugNotifyTempDir(TempInstallDir);

+ 1 - 1
Projects/Src/Uninstall.pas

@@ -375,7 +375,7 @@ begin
     _iu14D2N.tmp. The actual uninstallation process must be done from
     _iu14D2N.tmp. The actual uninstallation process must be done from
     somewhere outside the application directory since EXE's can't delete
     somewhere outside the application directory since EXE's can't delete
     themselves while they are running. }
     themselves while they are running. }
-  TempDirExisted := GenerateNonRandomUniqueTempDir(GetTempDir, TempDir);
+  TempDirExisted := GenerateNonRandomUniqueTempDir(IsAdmin, GetTempDir, TempDir);
   TempFile := AddBackslash(TempDir) + '_unins.tmp';
   TempFile := AddBackslash(TempDir) + '_unins.tmp';
   if not TempDirExisted then
   if not TempDirExisted then
     try
     try