Announcement

Collapse
No announcement yet.

CreateProcessAsUser Hilfe

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • CreateProcessAsUser Hilfe

    Hallo zusammen,

    ich bin in der Windows API mit Delphi 5 (unter Win 2000) hängengeblieben.

    Mit folgendem Quellcode versuche ich einen Consolenprozess zu starten, der aber die Rechte eines localen Admins haben muss
    (der aufruf von cmd.exe ist nur ein Beispiel):
    '
    '
    function TForm1.GetConsoleOutput(const Command: String; var Output, Errors: TStringList): Boolean;
    var
    StartupInfo: TStartupInfo;
    ProcessInfo: TProcessInformation;
    SecurityAttr: TSecurityAttributes;

    gsaSecAttr : TSecurityAttributes;
    gsaSecDescr: TSecurityDescriptor;

    PipeOutputRead: THandle;
    PipeOutputWrite: THandle;
    PipeErrorsRead: THandle;
    PipeErrorsWrite: THandle;
    hAccessToken : Cardinal;
    NewPrimToken : Cardinal;
    Succeed: Boolean;
    Buffer: array [0..255] of Char;
    NumberOfBytesRead: DWORD;
    Stream: TMemoryStream;
    SecurityImpersonation : TSecurityImpersonationLevel;

    begin
    if LogonUser(PAnsiChar('Administrator'), // UserName
    PAnsiChar(''), // Domäne oder lokaler Rechner
    PAnsiChar('MyPasswort'), // Password
    LOGON32_LOGON_NETWORK or LOGON32_LOGON_BATCH ,
    LOGON32_PROVIDER_DEFAULT,
    hAccessToken)
    then
    begin
    if ImpersonateLoggedOnUser(hAccessToken) then
    begin

    SecurityImpersonation := SecurityIdentification;

    if not DuplicateTokenEx(hAccessToken, TOKEN_DUPLICATE or TOKEN_QUERY , nil , SecurityImpersonation, TokenPrimary, NewPrimToken)
    then showmessage('DuplicateTokenEx: ' + SysErrorMessage(GetLastError));

    FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
    FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
    SecurityAttr.nLength := SizeOf(SecurityAttr);
    SecurityAttr.bInheritHandle := true;
    SecurityAttr.lpSecurityDescriptor := nil;

    //Pipes erzeugen
    CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);
    CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);

    //Initialisierung StartupInfo
    FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
    StartupInfo.cb:=SizeOf(StartupInfo);
    StartupInfo.hStdInput := 0;
    StartupInfo.hStdOutput := PipeOutputWrite;
    StartupInfo.hStdError := PipeErrorsWrite;
    StartupInfo.wShowWindow := sw_Show;
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

    if CreateProcessAsUser(NewPrimToken,nil, PChar('c:\winnt\system32\cmd.exe'), nil, nil, true, CREATE_NEW_PROCESS_GROUP or
    CREATE_DEFAULT_ERROR_MODE or NORMAL_PRIORITY_CLASS, nil, nil,
    StartupInfo, ProcessInfo) then
    begin
    result:=true;
    //Write-Pipes schließen
    CloseHandle(PipeOutputWrite);
    CloseHandle(PipeErrorsWrite);

    //Ausgabe Read-Pipe auslesen
    Stream := TMemoryStream.Create;
    try
    while true do begin
    succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil);
    if not succeed then break;
    Stream.Write(Buffer, NumberOfBytesRead);
    end;
    Stream.Position := 0;
    Output.LoadFromStream(Stream);
    finally
    Stream.Free;
    end;
    CloseHandle(PipeOutputRead);

    //Fehler Read-Pipe auslesen
    Stream := TMemoryStream.Create;
    try
    while true do begin
    succeed := ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil);
    if not succeed then break;
    Stream.Write(Buffer, NumberOfBytesRead);
    end;
    Stream.Position := 0;
    Errors.LoadFromStream(Stream);
    finally
    Stream.Free;
    end;
    CloseHandle(PipeErrorsRead);

    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    CloseHandle(ProcessInfo.hProcess);
    end
    else //CreateProcess failed
    begin
    showmessage('Ende: ' + syserrormessage(getlasterror));
    result:=false;
    CloseHandle(PipeOutputRead);
    CloseHandle(PipeOutputWrite);
    CloseHandle(PipeErrorsRead);
    CloseHandle(PipeErrorsWrite);
    CloseHandle(hAccessToken);
    CloseHandle(NewPrimToken);
    end;

    RevertToSelf; // zurückschalten zum angemeldeten Benutzer
    end;

    end;

    end;
    '
    '

    Wenn ich die Sache aufrufe tut sich eigentlich gar nichts. Erst der Aufruf des GetLastError zum Schluss sagt dann "Zugriff verweigert" - die Meldung müsste aus dem Aufruf von "CreateProcessAsUser" resultieren.

    Ich tippe mal darauf, daß ich im Umgang mit "DuplicateTokenEx" oder "CreateProcessAsUser" mindestens einen Fehler gemacht habe - nur wo?

    Kann mir bitte jemand helfen?

    Danke im voraus.

    Knut

    '
    PS: Kann mir mal jemand zeigen, wie man hier Leerzeilen in den Text einfügt, mehrfach ENTER wird offensichtlich ignoriert.
Working...
X