Einzelnen Beitrag anzeigen

Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#16

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 15:19
Nunja, das war Code aus einem kleinen Beispiel von mir, wie man eine Pipe erstellt auf die nur Mitglieder einer bestimmten Gruppe Zugriff haben. Für Deine Zwecke wäre es wahrscheinlich besser den Zugriff an einen Well Known SID zu koppeln. Der Code würde dann so aussehen:

Delphi-Quellcode:
program pipeserver;

{$APPTYPE CONSOLE}

uses
  jwawinbase, jwawintype, jwawinnt, jwaaccctrl, jwaaclapi, jwawinerror, sysutils;

function InstanceThread(PipeHandle : dword) : dword; stdcall;
var
  Value : dword;
  tmp : dword;
begin
  result := 0;

  ReadFile(PipeHandle, @Value, 4, @tmp, nil);
  WriteFile(PipeHandle, @Value, 4, @tmp, nil);

  FlushFileBuffers(PipeHandle);
  DisconnectNamedPipe(PipeHandle);
  CloseHandle(PipeHandle);
end;

function ServerThread(unused : dword) : dword; stdcall;
const
  BUFSIZE = 4;
var
  PipeHandle : dword;
  Connected : boolean;
  SA : LPSECURITY_ATTRIBUTES;
  ACL : PACL;
  Group : TRUSTEE;
  EA : PEXPLICIT_ACCESS;
  SD : PSECURITY_DESCRIPTOR;
  ACL_SIZE : ACL_SIZE_INFORMATION;
  WellKnownSID : PSID;
  tmp : dword;
begin
  tmp := SECURITY_MAX_SID_SIZE;
  GetMem(WellKnownSID, tmp);
  CreateWellKnownSid(WinWorldSid, nil, WellKnownSID, tmp);

  Group.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
  Group.pMultipleTrustee := nil;
  Group.ptstrName := Pointer(WellKnownSID);
  Group.TrusteeForm := TRUSTEE_IS_SID;
  Group.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;

  new(EA);
  EA^.grfAccessMode := GRANT_ACCESS;
  EA^.grfAccessPermissions := GENERIC_READ or GENERIC_WRITE;
  EA^.grfInheritance := NO_INHERITANCE;
  EA^.Trustee := group;

  SetEntriesInAcl(1, EA, nil, ACL);
  GetAclInformation(ACL, @ACL_SIZE, sizeof(ACL_SIZE), AclSizeInformation);
  getmem(SD, SECURITY_DESCRIPTOR_MIN_LENGTH + ACL_SIZE.AclBytesFree + ACL_SIZE.AclBytesInUse);
  InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(sd, TRUE, ACL, FALSE);

  new(SA);
  sa^.bInheritHandle := FALSE;
  sa^.lpSecurityDescriptor := sd;
  sa^.nLength := sizeof(sa);

  while true do
    begin
      PipeHandle := CreateNamedPipeW('\\.\pipe\demopipe', PIPE_ACCESS_DUPLEX,
                                     PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or
                                     PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE,
                                     BUFSIZE, INFINITE, SA);

      if PipeHandle = INVALID_HANDLE_VALUE then
        begin
          sleep(100);
          continue;
        end;

      Connected := ConnectNamedPipe(PipeHandle, nil)
                   or (GetLastError = ERROR_PIPE_CONNECTED);

      if Connected then
        begin
          tmp := CreateThread(nil, 0, @InstanceThread,
                                       Pointer(PipeHandle), 0, nil);
          if tmp = 0 then
            begin
              DisconnectNamedPipe(PipeHandle);
              CloseHandle(PipeHandle);
              continue;
            end else
              CloseHandle(tmp);
        end else
          CloseHandle(PipeHandle);
  end;

  LocalFree(cardinal(ACL));
  freemem(SD);
  freemem(WellKnownSID);
  dispose(EA);
end;

var
  tmp : dword;
begin
  write('Starting ServerThread: ');
  tmp := CreateThread(nil, 0, @ServerThread, nil, 0, nil);
  writeln(tmp <> 0);
  CloseHandle(tmp);
  readln;
end.
Eine Liste der Well Known SIDs gibts hier: http://msdn.microsoft.com/en-us/library/aa379650(VS.85).aspx
In Deinem Falle wäre wohl WinLocalSid nützlich.

Man kann den Code übrigens noch stark vereinfachen indem man die JWSCL benutzt. Allerdings ist mir die JWSCL für meinen Geschmack zu viel Overhead.
Fridolin Walther
  Mit Zitat antworten Zitat