Newsgroup: it.comp.lang.delphi
Titolo: Eseguire un programma come amministratore

Ho la necessità di eseguire l'installazione di un'applicativo su alcuni
client alcuni dei quali però non hanno i privilegi per eseguire tale
operazione in quanto gli utenti sono loggati come semplici power-user.
E' possibile creare uno script che, magari impostando al suo interno
user e password di amministratore, lanci l'installazione del programma
bypassando i privilegi di Windows?
Grazie in anticipo
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

bypassando i privilegi di Windows?
Non credo, comunque ti suggerisco a priori di abbandonare questa strada
perche' contraria alla logica dei privilegi del sistema operativo.
Stai creando un trojan ? ;-)
-- 
Morde. 
(
mo...@despammed.com
)
M-List di icld: 
http://it.groups.yahoo.com/group/icld/

 operativo.  Stai creando un trojan ? ;-)
In informatica tutto si puo' fare, e' solo una questione di tempi e
costi ;)
unit uExecAndWait;
interface
{ $DEFINE MY_DEBUG}
uses Messages, Wintypes, WinProcs, Classes, Forms, SysUtils, uUtily;
{$IFDEF MY_DEBUG}
const
  DebugFile: string = 'C:\debug.txt';
{$ENDIF}
function ExecAndWait(const Filename, Params: string; WindowState:
word): boolean; overload;
function ExecAndWait(const Filename, Params, Username, Domain,
Password: string; WindowState: word): boolean; overload;
function RunDosInMemo(DosApp: string): string;
implementation
uses Windows;
function RunDosInMemo(DosApp: string): string;
const
  ReadBuffer = 2400;
var
  Security: TSecurityAttributes;
  ReadPipe, WritePipe: THandle;
  start: TStartUpInfo;
  ProcessInfo: TProcessInformation;
  Buffer: Pchar;
  BytesRead: DWord;
  Apprunning: DWord;
begin
  Result := '';
  with Security do begin
    nlength := SizeOf(TSecurityAttributes);
    binherithandle := true;
    lpsecuritydescriptor := nil;
  end;
  if Createpipe(ReadPipe, WritePipe,
    @Security, 0) then begin
    Buffer := AllocMem(ReadBuffer + 1);
    FillChar(Start, Sizeof(Start), #0);
    start.cb := SizeOf(start);
    start.hStdOutput := WritePipe;
    start.hStdInput := ReadPipe;
    start.dwFlags := STARTF_USESTDHANDLES +
      STARTF_USESHOWWINDOW;
    start.wShowWindow := SW_HIDE;
    if CreateProcess(nil,
      PChar(DosApp),
      @Security,
      @Security,
      true,
      NORMAL_PRIORITY_CLASS,
      nil,
      nil,
      start,
      ProcessInfo)
      then
    begin
      repeat
        Apprunning := WaitForSingleObject
          (ProcessInfo.hProcess, 100);
        Application.ProcessMessages;
      until (Apprunning <> WAIT_TIMEOUT);
      repeat
        BytesRead := 0;
        ReadFile(ReadPipe, Buffer[0],
          ReadBuffer, BytesRead, nil);
        Buffer[BytesRead] := #0;
        OemToAnsi(Buffer, Buffer);
        Result := Result + string(Buffer);
      until (BytesRead < ReadBuffer);
    end;
    FreeMem(Buffer);
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ReadPipe);
    CloseHandle(WritePipe);
  end;
end;
function ExecAndWait(const Filename, Params: string; WindowState:
word): boolean;
var
  proc_info: TProcessInformation;
  startinfo: TStartupInfo;
  Command: string;
begin
  Command := '"' + Filename + '" ' + Params;
  FillChar(proc_info, sizeof(TProcessInformation), 0);
  FillChar(startinfo, sizeof(TStartupInfo), 0);
  startinfo.cb := sizeof(TStartupInfo);
  Result := CreateProcess(nil, PChar(Command), nil,
    nil, false, CREATE_DEFAULT_ERROR_MODE
    + NORMAL_PRIORITY_CLASS, nil, nil, startinfo,
    proc_info);
  if Result then
  begin
    WaitForSingleObject(proc_info.hProcess, INFINITE);
    CloseHandle(proc_info.hProcess);
    CloseHandle(proc_info.hThread);
  end;
end;
function GetUserObjectName(hUserObject: THandle; var Name: string):
boolean;
var dw: DWord;
begin
  Name := EmptyStr;
  GetUserObjectInformation(hUserObject, UOI_NAME, PChar(Name), 0, dw);
  SetLength(Name, dw + 1);
  Result := GetUserObjectInformation(hUserObject, UOI_NAME,
PChar(Name), dw, dw);
  if Result then SetLength(Name, dw - 1)
  else Name := EmptyStr;
end;
function SetUserObjectAllAccess(hUserObject: THANDLE): boolean;
var
  pSD: PSecurity_Descriptor;
  si: Security_Information; { dword }
begin
  (* Initialize a security descriptor. *)
  pSD := PSecurity_Descriptor(
    LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH));
  if pSD = nil then
  begin
    Result := FALSE; exit;
  end;
  if not InitializeSecurityDescriptor(pSD,
SECURITY_DESCRIPTOR_REVISION) then
  begin
    LocalFree(HLOCAL(pSD));
    Result := FALSE; exit;
  end;
  (* Add a NULL disc. ACL to the security descriptor. *)
  if not SetSecurityDescriptorDacl(pSD,
    TRUE, // specifying a disc. ACL
    PACL(nil),
    FALSE) then // not a default disc. ACL
  begin
    LocalFree(HLOCAL(pSD));
    Result := FALSE; exit;
  end;
  (* Add the security descriptor to the userobject (like a window or a
DDE
     conversation), NOT to a kernelobject (like a process, thread or
event). *)
  si := DACL_SECURITY_INFORMATION;
  Result := SetUserObjectSecurity(hUserObject, si, pSD);
  LocalFree(HLOCAL(pSD));
end;
function GetPrivilegeDisplayName(const PrivilegeName: string): string;
{ PrivilegeName is of string type 'SE_'* }
var dw, li: DWord;
begin
  Result := EmptyStr; dw := 0; li := 0; { li:=
dword(MAKELANGID(LANG_DEFAULT, LANG_USER)); }
  if not LookupPrivilegeDisplayName(nil, PChar(PrivilegeName),
PChar(Result), dw, li)
    then dw := 256;
  SetLength(Result, dw + 1);
  if LookupPrivilegeDisplayName(nil, PChar(PrivilegeName),
PChar(Result), dw, li)
    then SetLength(Result, StrLen(PChar(Result)))
  else Result := EmptyStr;
end;
function ExecAndWait(const Filename, Params, Username, Domain,
Password: string; WindowState: word): boolean; overload;
var
  startUpInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CurrentDir: string;
  ApplicationName: string;
  CmdLine: string;
  hUserToken: THANDLE;
  hWindowStation: HWINSTA;
  hDesktop: HDESK;
  WinStaName, DeskTopName: string;
const
  SE_TCB_NAME = 'SeTcbPrivilege';
  DEFWINSTATION: string = 'WinSta0';
  DEFDESKTOP: string = 'Default';
  WHITESPACE: string = ' ' {SPACE} + chr(9) {TAB} + chr(10) {LF};
  DOMUSERSEP: string = '\';
begin
  { Enclose filename in quotes to take care of long filenames with
spaces. }
  CmdLine := '"' + Filename + '" ' + Params;
  CurrentDir := ExtractFilePath(Filename);
  ApplicationName := Filename;
  Result := LogonUser(PChar(Username), PChar(Domain), PChar(Password),
    LOGON32_LOGON_INTERACTIVE,
    LOGON32_PROVIDER_DEFAULT, hUserToken);
  if not Result then
  begin
{$IFDEF MY_DEBUG}
    SaveToFile(DebugFile, 'Error: ' + SysErrorMessage(GetLastError) +
#13#10);
{$ENDIF}
    case GetLastError of
      ERROR_PRIVILEGE_NOT_HELD:
        begin
{$IFDEF MY_DEBUG}
          AppendToFile(DebugFile, 'Error: ERROR_PRIVILEGE_NOT_HELD' +
#13#10);
{$ENDIF}
        end;
      ERROR_LOGON_FAILURE:
        begin
{$IFDEF MY_DEBUG}
          AppendToFile(DebugFile, 'Error: ERROR_LOGON_FAILURE' +
#13#10);
{$ENDIF}
        end;
      ERROR_ACCESS_DENIED:
        begin
{$IFDEF MY_DEBUG}
          AppendToFile(DebugFile, 'Error: ERROR_ACCESS_DENIED' +
#13#10);
{$ENDIF}
        end;
    end;
  end;
{$IFDEF MY_DEBUG}
  AppendToFile(DebugFile, 'LogonUser: ' + BoolToStr(Result, True) +
#13#10);
{$ENDIF}
  hWindowStation := GetProcessWindowStation;
  if not GetUserObjectName(hWindowStation, WinStaName) then
    WinStaName := DEFWINSTATION;
{$IFDEF MY_DEBUG}
  Result := SetUserObjectAllAccess(hWindowStation);
  AppendToFile(DebugFile, 'SetUserObjectAllAccess: ' +
BoolToStr(Result, True) + #13#10);
{$ELSE}
  SetUserObjectAllAccess(hWindowStation);
{$ENDIF}
  hDesktop := GetThreadDesktop(GetCurrentThreadId);
  if not GetUserObjectName(hDesktop, DeskTopName) then
    DeskTopName := DEFDESKTOP;
{$IFDEF MY_DEBUG}
  Result := SetUserObjectAllAccess(hDesktop);
  AppendToFile(DebugFile, 'SetUserObjectAllAccess: ' +
BoolToStr(Result, True) + #13#10);
{$ELSE}
  SetUserObjectAllAccess(hDesktop);
{$ENDIF}
  FillChar(startUpInfo, sizeof(startUpInfo), 0);
  with startUpInfo do
  begin
    cb := sizeof(startUpInfo);
    lpTitle := PChar('SignCode');
    lpDesktop := PChar(WinStaName + '\' + DeskTopName);
    wShowWindow := WindowState;
  end;
  Result := CreateProcessAsUser(hUserToken,
    nil, PChar(CmdLine), nil, nil, FALSE {no inherit handles},
    CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP,
    nil, nil, startUpInfo, procInfo);
{$IFDEF MY_DEBUG}
  AppendToFile(DebugFile, 'CreateProcessAsUser: ' + BoolToStr(Result,
True) + #13#10);
  AppendToFile(DebugFile, 'CmdLine: ' + CmdLine + #13#10);
{$ENDIF}
  { Wait for it to finish. }
  if Result then
  begin
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
     { Clean up the handles. }
    CloseHandle(ProcInfo.hProcess);
    CloseHandle(ProcInfo.hThread);
  end;
end;
end.
-- 
I am what I am, I do what I can
Non trovi qualche cosa? 
http://url.repository.biz/go/1J

> In informatica tutto si puo' fare [...]
Questa è la tipica frase che fa fallire tutti i progetti ... :)

costi ;)
hi hi hi hi.... ~>>>>:-)))


"Setec Astronomy" <setec@_NO_NOSPAM_freemail.it> wrote in message
news:Ew9Ub.13390$
Mt6.4...@twister2.libero.it
[cut]
Uffa ho un problema. Sto cercando di utilizzare la funzione che mi hai 
postato solo che mi da il seguente errore in fase di compilazione:
"there is no overloaded version of ExecAndWait that can be called with
these argument". Che significa? Dove sbaglio? 
Ho utilizzato la funzione come segue:
procedure TForm1.Button2Click(Sender: TObject);
begin
  if ExecAndWait('d:\setup.exe', 
                 nil, 
                 'Administrator', 
                 'SIS-07', 
                 'password', 
                 SW_SHOWNORMAL) then
    showmessage('ok funziona')
  else
    showmessage('no errore');
end;
Grazie mille


these argument". Che significa? Dove sbaglio? 
La stai ivocando usando parametri che hanno il tipo diverso dalla
dichiarazione.
Se le dichiarazioni vogliono questi parametri:
function SetecAndWait(string,string,word)
function SetecAndWait(string,string, string,string,string,word)
e' evidente che se gli passi NIL non gli stai passando una stringa, ti pare ?


 e' evidente che se gli passi NIL non gli stai passando una stringa, ti pare ?
ehm...  ok, adesso compila!
Mi togli una curiosità? Ma l'ultimo parametro (WindowState) esattamente
a cosa serve? Cioè, cosa indica? Scusa se faccio delle domande magari
stupide,
però sono nuovo a queste cose!


 wrote in message
news:hav320l6r5sc9pe21...@4ax.com
Va in errore! :(
Ti riporto il file di debug che ha creato.
Error: Il privilegio richiesto non appartiene al client
LogonUser: False
SetUserObjectAllAccess: True
SetUserObjectAllAccess: True
CreateProcessAsUser: False
CmdLine: "d:\setup.exe" 
GIURO di avergli passato i valori corretti! (intendo username, dominio 
e password). Da cosa può dipendere quindi?


 dominio e password). Da cosa può dipendere quindi?
Sembrerebbe di no invece (LogonUser: False). Cosa hai passato come
dominio?


"Setec Astronomy" <setec@_NO_NOSPAM_freemail.it> wrote in message
news:AgpUb.14873$
Mt6.5...@twister2.libero.it
Ho scritto il nome del dominio della rete aziendale, lo stesso che 
appare nella maschera di login di Windows tanto per capirci. Ho perň 
inserito anzichč i miei soliti user e password personali quelli di 
amministratore del dominio (ma anche se passo i miei non cambia nulla)
Ho letto sul sito MSDN che in alcuni casi bisogna passare lo user con 
la sintassi "dominio\utente" (quindi nel mio caso "ACS\Dario") ma 
neppure cosě funziona. 


Gohan wrote:

Inserisci come user e password i dati di un utente locale e come
password il nome della macchina.


 password il nome della macchina.
[ERRATA CORRIGE]
Inserisci come user e password i dati di un utente locale e come
DOMINIO il nome della macchina.
[/ERRATA CORRIGE]


"Setec Astronomy" <setec@_NO_NOSPAM_freemail.it> wrote in message
news:xzpUb.14914$
Mt6.5...@twister2.libero.it
Ho già provato anche così... ma continua ad andarmi in errore nella 
funzione LogonUser (Ah! Io ho un win2000 professional come SO, non 
so se può servire come informazione).


 so se può servire come informazione).
La funzione postata viene tuttora utilizzata su un server di produzione
per effetturare la certificazione on the fly di eseguibili, il codice
e' corretto.
