Einzelnen Beitrag anzeigen

Angel4585

Registriert seit: 4. Okt 2005
Ort: i.d.N.v. Freiburg im Breisgau
2.199 Beiträge
 
Delphi 2010 Professional
 
#1

Problem mit Sicherheitskennung bei CreateProcessAsUser

  Alt 5. Nov 2009, 10:08
Hallo!

Wie in meinem andern Thread angekündigt, ein neuer Thread für ein Problem in der gleichen Methode.

Es geht um den Aufruf CreateProcessAsUser.

Der Fehler tritt nur sporadisch auf und zeigt sich wie folgt:

Die Methode CreateProcessAsUser wird laut Rückgabewert korrekt ausgeführt.
Tatsächlich wurde der Prozess jedoch garnicht gestartet!
Ein GetLastError nach dem CreateProcessAsUser liefert folgendes Ergebnis:
"Diese Sicherheitskennung kann nicht als Besitzer des Objekts zugeordnet werden"

Das ist natürlich ein großes Problem.

Hintergrundinfo: Das ganze wird in einem Service aufgerufen und der es werden die Anmeldedaten des Administratorkontos verwendet, welches auch jetz im Moment angemeldet ist.

Das Problem tritt nich immer auf, gestern lief das ganze stundenlang problemlos, bis dann abends auf einmal der Fehler auftauchte. Ab da ging dann garnichtsmehr.

Edit: Sehr seltsam ist auch, dass die Meldung nach einem Neustart des Rechners erstmal nichtmehr kommt... ma schaun wie lang..
Edit2: Noch seltsamer: Nachdem ich die exe-Datei von dem Dienst austausche kommt der Fehler wieder...

Delphi-Quellcode:
procedure TMyDienst.CreateNewUserProcess(AUser, APassword, ADomain, AProgram : string);
var
  ltoken,ltoken2 : Cardinal;
  LEnv : Pointer;
  pi : TProfileInfo;
  si : STARTUPINFO;
  pri : _PROCESS_INFORMATION;
  sil : TSecurityImpersonationLevel;
  LUser, LDomain, LPassword, LProgram : string;
// reg : TRegistry;
  err : Integer;
  created : LongBool;
begin

try
  LUser:=AUser;
  LPassword:=APassword;
  LDomain:=ADomain;
  LProgram:=AProgram;
  try
  FillChar(sil,SizeOf(TSecurityImpersonationLevel),#0);
  sil := SecurityIdentification;
  if LogonUser(PAnsiChar(LUser),PAnsiChar(LDomain),PAnsiChar(LPassword),LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,ltoken)then
    begin
    if DuplicateTokenEx(ltoken,TOKEN_ALL_ACCESS,nil,sil,TokenPrimary,ltoken2)then
    begin
    fillchar(pi,sizeof(TProfileInfo),#0);
    pi.dwSize:=sizeof(TProfileInfo);
    pi.lpUserName:=PAnsiChar(LUser);
    if(LoadUserProfile(ltoken2,pi))then
      begin

      if (CreateEnvironmentBlock(
        lenv,
        ltoken2,
        true //false
      ))then
        begin
        FillChar(pri,sizeof(_PROCESS_INFORMATION),#0);
        ZeroMemory(@si,sizeof(si));
        err:=GetlastError;
        if err<>0 then SNLogger.Log(SysErrorMessage(err),ltBoth);
        created:= CreateProcessAsUser(
            ltoken2,
            nil,
            PAnsiChar(LProgram),
            nil,
            nil,
            false,
            CREATE_UNICODE_ENVIRONMENT or CREATE_NEW_PROCESS_GROUP or NORMAL_PRIORITY_CLASS or CREATE_NO_WINDOW, //TODO: Priorität einstellen?
            lenv,
            nil,
            si,
            pri
            );
        if(created = LongBool(0))then SNLogger.Log('Prozess konnte nicht gestartet werden.',ltBoth)
        else SNLogger.Log('Prozess erfolgreich gestartet.'+BoolToStr(created),ltBoth);//<------ Das hier wird ausgeführt
        err:=GetlastError;
        if err<>0 then SNLogger.Log('Prozess konnte nicht gestartet werden. '+SysErrorMessage(err),ltBoth);//<------ Das hier wird ebenfalls ausgeführt mit Fehler:"Diese Sicherheitskennung kann nicht als Besitzer des Objekts zugeorndet werden"
        if not DestroyEnvironmentBlock(lenv)then snlogger.Log('EnvironmentBlock konnte nicht geschlossen werden');
        if not UnloadUserProfile(ltoken,pi.hProfile)then snlogger.Log('UserProfile konnte nicht geschlossen werden');
        if not CloseHandle(pri.hProcess)then snlogger.Log('hProcess konnte nicht geschlossen werden');
        if not CloseHandle(pri.hThread)then snlogger.Log('hThread konnte nicht geschlossen werden');
        if not CloseHandle(ltoken2)then snlogger.Log('ltoken2 konnte nicht geschlossen werden');
        if not CloseHandle(ltoken) then snlogger.Log('ltoken konnte nicht geschlossen werden');

        
        //snlogger.log(inttostr(GetLastError));
        end else SNLogger.Log('Arbeitsumgebung konnte nicht erstellt werden. '+SysErrorMessage(GetLastError));
      end else SNLogger.Log('Benutzerprofil konnte nicht geladen werden. '+SysErrorMessage(GetLastError));
    end else SNLogger.Log('Duplicate nicht möglich. '+SysErrorMessage(GetLastError));
  end else SNLogger.Log('Login nicht möglich. '+SysErrorMessage(GetLastError),ltBoth);
except
  on e : exception do
    SNLogger.Log('Fehler beim Starten eines Prozesses:'+e.Message+slinebreak+SysErrorMessage(GetLastError),ltBoth);
  end;
finally
snlogger.log('CreateProcess:'+syserrormessage(getlasterror));
end;
end;
Ich hoffe jemand kann mir einen Tipp geben, ich hab zwar bissl was gefunden über google, aber das sind dann alles sachen wo es drum geht den Prozess in irgendwelche Sessions zu schubsen, oder wo es ein Problem beim Einrichten von Gruppenrichtlinien gibt.

Martin Weber
Ich bin ein Rüsselmops
  Mit Zitat antworten Zitat