mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: Use sudo if pkexec is not available
This commit is contained in:
parent
ad490e48c1
commit
c7f1e99dce
2 changed files with 140 additions and 5 deletions
|
|
@ -17,7 +17,7 @@ uses
|
|||
{$IF DEFINED(MSWINDOWS)}
|
||||
, Types, Windows, DCOSUtils, ShellApi, uMyWindows
|
||||
{$ELSEIF DEFINED(UNIX)}
|
||||
, Unix, BaseUnix, DCUnix
|
||||
, Classes, Unix, BaseUnix, DCUnix, Dialogs, SyncObjs, Process, un_process
|
||||
{$IF DEFINED(DARWIN)}
|
||||
, DCStrUtils
|
||||
{$ENDIF}
|
||||
|
|
@ -74,6 +74,40 @@ end;
|
|||
|
||||
{$IF DEFINED(UNIX)}
|
||||
|
||||
const
|
||||
PATH_SUDO = '/usr/bin/sudo';
|
||||
PATH_PKEXEC = '/usr/bin/pkexec';
|
||||
|
||||
resourcestring
|
||||
rsMsgPasswordEnter = 'Please enter the password:';
|
||||
|
||||
type
|
||||
TSuperProgram = (spNone, spSudo, spPkexec);
|
||||
|
||||
{ TSuperUser }
|
||||
|
||||
TSuperUser = class(TThread)
|
||||
private
|
||||
FPrompt: String;
|
||||
FCtl: TExProcess;
|
||||
FMessage: String;
|
||||
FArgs: TStringArray;
|
||||
FEvent: TSimpleEvent;
|
||||
private
|
||||
procedure Ready;
|
||||
procedure RequestPassword;
|
||||
procedure OnReadLn(Str: String);
|
||||
procedure OnQueryString(Str: String);
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
constructor Create(Args: TStringArray; const StartPath: String);
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
var
|
||||
SuperProgram: TSuperProgram;
|
||||
|
||||
function ExecuteCommand(Command: String; Args: TStringArray; StartPath: String): UIntPtr;
|
||||
var
|
||||
ProcessId : TPid;
|
||||
|
|
@ -106,6 +140,92 @@ begin
|
|||
Result := ProcessId;
|
||||
end;
|
||||
|
||||
function ExecuteSudo(Args: TStringArray; const StartPath: String): UIntPtr;
|
||||
begin
|
||||
with TSuperUser.Create(Args, StartPath) do
|
||||
begin
|
||||
Start;
|
||||
FEvent.WaitFor(INFINITE);
|
||||
Result:= FCtl.Process.ProcessHandle;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TSuperUser }
|
||||
|
||||
procedure TSuperUser.Ready;
|
||||
begin
|
||||
FEvent.SetEvent;
|
||||
Yield;
|
||||
FreeOnTerminate:= True;
|
||||
FCtl.OnOperationProgress:= nil;
|
||||
end;
|
||||
|
||||
procedure TSuperUser.RequestPassword;
|
||||
var
|
||||
S: String = '';
|
||||
begin
|
||||
if Length(FMessage) = 0 then begin
|
||||
FMessage:= rsMsgPasswordEnter
|
||||
end;
|
||||
if not InputQuery('Double Commander', FMessage, True, S) then
|
||||
FCtl.Stop
|
||||
else begin
|
||||
S:= S + LineEnding;
|
||||
FCtl.Process.Input.Write(S[1], Length(S));
|
||||
end;
|
||||
FMessage:= EmptyStr;
|
||||
end;
|
||||
|
||||
procedure TSuperUser.OnReadLn(Str: String);
|
||||
begin
|
||||
FMessage:= Str;
|
||||
end;
|
||||
|
||||
procedure TSuperUser.OnQueryString(Str: String);
|
||||
begin
|
||||
Synchronize(@RequestPassword)
|
||||
end;
|
||||
|
||||
procedure TSuperUser.Execute;
|
||||
var
|
||||
GUID : TGUID;
|
||||
Index: Integer;
|
||||
begin
|
||||
CreateGUID(GUID);
|
||||
FPrompt:= GUIDToString(GUID);
|
||||
FCtl.Process.Options:= FCtl.Process.Options + [poStderrToOutPut];
|
||||
FCtl.Process.Executable:= PATH_SUDO;
|
||||
FCtl.Process.Parameters.Add('-S');
|
||||
FCtl.Process.Parameters.Add('-k');
|
||||
FCtl.Process.Parameters.Add('-p');
|
||||
FCtl.Process.Parameters.Add(FPrompt);
|
||||
for Index:= 0 to High(FArgs) do begin
|
||||
FCtl.Process.Parameters.Add(FArgs[Index]);
|
||||
end;
|
||||
FCtl.QueryString:= FPrompt;
|
||||
FCtl.OnQueryString:= @OnQueryString;
|
||||
FCtl.OnOperationProgress:= @Ready;
|
||||
fCtl.OnProcessExit:= @Ready;
|
||||
FCtl.OnReadLn:= @OnReadLn;
|
||||
FCtl.Execute;
|
||||
end;
|
||||
|
||||
constructor TSuperUser.Create(Args: TStringArray; const StartPath: String);
|
||||
begin
|
||||
inherited Create(True);
|
||||
FCtl:= TExProcess.Create(EmptyStr);
|
||||
FCtl.Process.CurrentDirectory:= StartPath;
|
||||
FEvent:= TSimpleEvent.Create;
|
||||
FArgs:= Args;
|
||||
end;
|
||||
|
||||
destructor TSuperUser.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
FEvent.Free;
|
||||
FCtl.Free;
|
||||
end;
|
||||
|
||||
{$ELSEIF DEFINED(MSWINDOWS)}
|
||||
|
||||
function MaybeQuoteIfNotQuoted(const S: String): String;
|
||||
|
|
@ -176,13 +296,28 @@ begin
|
|||
AParams[Index + 1]:= Args[Index];
|
||||
AParams[0] := Exe;
|
||||
|
||||
Result:= ExecuteCommand('/usr/bin/pkexec', AParams, sStartPath);
|
||||
case SuperProgram of
|
||||
spSudo: Result:= ExecuteSudo(AParams, sStartPath);
|
||||
spPkexec: Result:= ExecuteCommand(PATH_PKEXEC, AParams, sStartPath);
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
initialization
|
||||
{$IF DEFINED(UNIX)}
|
||||
FAdministratorPrivileges:= {$IFDEF DARWIN}True{$ELSE}(fpGetUID = 0){$ENDIF};
|
||||
{$IF DEFINED(DARWIN)}
|
||||
FAdministratorPrivileges:= True;
|
||||
{$ELSEIF DEFINED(UNIX)}
|
||||
{$IFDEF LINUX}
|
||||
if fpAccess(PATH_PKEXEC, X_OK) = 0 then
|
||||
SuperProgram:= spPkexec
|
||||
else
|
||||
{$ENDIF}
|
||||
if fpAccess(PATH_SUDO, X_OK) = 0 then
|
||||
SuperProgram:= spSudo
|
||||
else begin
|
||||
SuperProgram:= spNone;
|
||||
end;
|
||||
FAdministratorPrivileges:= (fpGetUID = 0) or (SuperProgram = spNone);
|
||||
{$ELSE}
|
||||
FAdministratorPrivileges:= (IsUserAdmin <> dupError);
|
||||
{$ENDIF}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ begin
|
|||
else
|
||||
begin
|
||||
Sleep(1);
|
||||
if Assigned(FOnQueryString) and (FProcess.Stderr.NumBytesAvailable > 0) then
|
||||
if Assigned(FOnQueryString) and Assigned(FProcess.Stderr) and (FProcess.Stderr.NumBytesAvailable > 0) then
|
||||
begin
|
||||
SetLength(OutputBuffer, BufferSize);
|
||||
// Waits for the process output
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue