Announcement

Collapse
No announcement yet.

Mailslot von Service > Zugriff verweigert bei Zugriff aus Programm

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

  • #16
    Es gibt (wie bei Grimm's Märchen) eine lange Liste von Geschichten, wie man zu einer Sicherheitsbeschreibung kommt.

    Das oben erwähnte Beispiel setzt ihn fein säuberlich aus den Einzelteilen zusammen.<br>
    Dabei ist die Sache noch dadurch vereinfacht, das nur Standard-SIDs verwendet werden, die auf jedem NT-system gleich sind (JEDER und Gruppe der lokalen Administratoren, letztere sind eigentlich überflüssig, da eh' JEDER Vollzugriff hat, doch es ging in dem Beispiel von M$, das ich nach Delphi portiert habe u.a. darum, wie man mehrere Bedingungen einpackt...).

    Es grob Eingeteilt 3 Abstraktions-Stufen für die API im Zusammenhang mit Sicherheit von Objekten (im allgemeinen Sinne).<br>
    # LowLevel-API, in jeder NT-version vorhanden, kann (fast) alles, aufwendig, aber teilweise der direktere Weg zum Ziel.<br>
    # Standard-API (ab ~NT4 implementiert) nimmmt viele Standard-Aufgaben ab (DACL in SACL einfügen etc).<br>
    # High-Level-API, zum größten Teil erst mit Windows 2000 eingeführt, kannn selbst komplexe, oder vorher kaum lösbare Probleme bewältigen ( manche Funktionen stehen eben erst mit 2K zur Verfügung =/ )

    Also keine Angst, das es völlig anders aussieht, es war die "einfachere" Variante.

    Wie jede API hat auch die Sicherheits-API ihre Eigenheiten, es gibt schöne Fehler in den Versionen der Standard-API vor SP3 von NT4 (was ich so alte Sachen auch kennen muss =).<br>
    Aber einiges verstehe ich an Windows 2000 auch nicht -- warum zum '*)$)("$?"(?!= kann ich ein Desktop-Objekt nicht öffnen, wenn ich zwar DESKTOP_READOBJECTS aber nicht DESKTOP_WRITEOBJECTS habe -- Antwort, weil in Win2k.sys einfach mal beim Öffnen _beide_ Flags über die Parameter gelegt werden... (ok ich hör' jetzt auf).

    Was ich eigentlich sagen wollte, falls das alles irgendwie nicht will, stehe ich zum "ma so gucken" zur Verfügung.

    Gruß Nic

    Comment


    • #17
      Letzendlich glaube ich, daß wenn man einmal die Gültigkeitsbereiche von Accounts/Gruppen/Domänen begriffen hat.<br>
      Und dazu noch die Abfrage-Logik kennt (beim ersten gefundenen Verbot wird abgebrochen, egal wieviele "Erlaubnisse" danach kommen),<br>
      dann ist das gar nicht mehr so schwer...

      Gruß Nico

      PS: Warum machst Du es Dir auch so schwer und nimmst MailsSlots zur Kommunikation, oder vererbst einfach ein gültiges Handle per DuplicateHandle an den Aufrufer ;-

      Comment


      • #18
        1. Soll das ganze später auch Netzwerk und Multiuserfähig sein.<p>
        2. Soll es nicht so ein Dateizugriffsfest wie der gesamte Fritz-Kram veranstalten, wenn man sich das mal ansieht, fragt man sich glatt, warum der Rechner noch benutzbar ist!<p>
        3. Ist ja das ganze Problem an der Sache das es sauber sein soll, sprich der Service kann nur was unbedingt nötig ist, die gesamte Benutzerkommunikation läuft wie es sein soll über ein normales Programm, beide sollen dann aber eben verschiedene Nachrichten austauschen können (wie gesagt auch übers netz)...
        <p>
        Ausserdem dachte ich (wie so oft, schluchz ) nicht, das dieses "Ideechen" so anstrengend werden würde, jetzt habe ich innerhalb weniger tage Adress, Logbuch und Nachrichten(wav-dateien) import für Fritz!Vox und Fritz!Dings(das Telefonteil eben), import aller Telefonnummern mit Bezeichnung aus dem WAB (wegen der Outlook Express nutzer), import von Kontakten und WAB-Adressen aus (groß) Outlook geschrieben, allesamt mit automatischer Erkennung, wenn ein neuer Import fällig ist, zusätzlich Export von anrufen nach Outlook (incl. wav-datei als anlage), rufnummernprofile / Zeitprofile (deutlich besser als bei fritz) mit beliebigen ansagen usw. und so fort geschrieben. Woran bleibe ich jetzt seit Tagen hängen? Am Umschalten der blöden Birnen auf der verflixten Tastatur und daran, das der Service vom Programm nix mitbekommt, seufz! Naja den neuen Security Teil werde ich heute abend testen.

        Comment


        • #19
          Also der Mailslot wird jetzt wieder vom Service fehlerfrei erzeugt, bei Zugriff aus dem Programm bekomme ich dafür jetzt aber auch wieder 'Zugriff verweigert'..., hier ein paar Codehäppchen im Service in einem extramodul:<pre>
          function CreateSDiscriptor:Boolean;
          begin
          Result := False;
          EveryoneSID := nil;
          AdminSID := nil;
          ACL := nil;
          SecurityDescriptor := nil;
          { Bekannte SID für die "Jeder"-Gruppe erzeugen. }
          if AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHOR ITY, 1,
          SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, EveryoneSID) then
          try
          { Der ACE wird "Jeder" Vollzugriff erlauben. }
          FillChar(ExplicitAccesses, 2 * SizeOf(TExplicitAccess), 0);
          ExplicitAccesses[0].grfAccessPermissions := KEY_ALL_ACCESS;
          ExplicitAccesses[0].grfAccessMode := SET_ACCESS;
          ExplicitAccesses[0].grfInheritance := NO_INHERITANCE;
          ExplicitAccesses[0].Trustee.TrusteeForm := TRUSTEE_IS_SID;
          ExplicitAccesses[0].Trustee.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;
          ExplicitAccesses[0].Trustee.pSid := EveryoneSID;
          { Bekannte SID für die "Administratoren"-Gruppe erzeugen. }
          if AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
          SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
          AdminSID) then
          begin
          { Der ACE wird "Administratoren" Vollzugriff erlauben. }
          ExplicitAccesses[1].grfAccessPermissions := KEY_ALL_ACCESS;
          ExplicitAccesses[1].grfAccessMode := SET_ACCESS;
          ExplicitAccesses[1].grfInheritance := NO_INHERITANCE;
          ExplicitAccesses[1].Trustee.TrusteeForm := TRUSTEE_IS_SID;
          ExplicitAccesses[1].Trustee.TrusteeType := TRUSTEE_IS_GROUP;
          ExplicitAccesses[1].Trustee.pSid := AdminSID;
          { Neue ACL erzeugen, die den neuen ACE enthält. }
          if SetEntriesInAcl(2, @ExplicitAccesses, nil, PACL(@Acl)^) = ERROR_SUCCESS then
          begin
          { Security Descriptor initialisieren. }
          SecurityDescriptor := PSecurityDescriptor(LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH));
          if Assigned(SecurityDescriptor) then
          if InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) then
          { Die ACL zum Security Descriptor hinzufügen. }
          if SetSecurityDescriptorDacl(SecurityDescriptor, True, ACL, False) then
          begin
          { Eine Sicherheits-Attribute-Struktur initialisieren. }
          SecurityAttributes.nLength := SizeOf(TSecurityAttributes);
          SecurityAttributes.lpSecurityDescriptor := SecurityDescriptor;
          SecurityAttributes.bInheritHandle := False;
          Result := True;
          end;
          end;
          end;
          finally
          end;
          end;

          initialization
          everyoneSid := nil;
          adminSid := nil;
          acl := nil;
          SecurityDescriptor := nil;

          finalization
          if Assigned(EveryoneSID) then
          FreeSid(EveryoneSID);
          if Assigned(AdminSID) then
          FreeSid(AdminSID);
          if Assigned(Acl) then
          LocalFree(HLOCAL(Acl));
          if Assigned(SecurityDescriptor) then
          LocalFree(HLOCAL(SecurityDescriptor));
          </pre>und im Create Teil:<pre
          if CreateSDiscriptor then begin
          mailSlot2 := CreateMailSlot(PChar(msMailSlot2Name), 0, 0, @SecurityAttributes);
          if mailSlot2 = INVALID_HANDLE_VALUE then begin
          debugP('Mailslot2 konnte nicht erstellt werden');
          debugP(GetLastWin32Error);
          end else begin
          settingsTimer.Enabled := true;
          if SecurityAttributes.lpSecurityDescriptor = nil then
          debugP('EY!')
          else debugP('SecurityAttributes.

          Comment


          • #20
            <pre> if CreateSDiscriptor then begin
            mailSlot2 := CreateMailSlot(PChar(msMailSlot2Name), 0, 0, @SecurityAttributes);
            if mailSlot2 = INVALID_HANDLE_VALUE then begin
            debugP('Mailslot2 konnte nicht erstellt werden');
            debugP(GetLastWin32Error);
            end else begin
            settingsTimer.Enabled := true;
            if SecurityAttributes.lpSecurityDescriptor = nil then
            debugP('EY!')
            else debugP('SecurityAttributes.lpSecurityDescriptor OKAY!');
            debugP('Mailslot2 erstellt!')
            end;
            end else debugP('Fehler beim Erstellen des Security Descriptors: '+GetLastWin32Error);
            </pre>schlieslich dann im Programm:<pre>
            procedure Tmain.kickMessage(msg:String);
            var bytes : Dword;
            mailSlot2 : THandle;
            t : String;
            begin
            t := msMailSlot2Name;
            try
            mailSlot2 := CreateFile(PChar(t),Generic_Write, FILE_SHARE_READ,@SecurityAttributes,Open_Existing, File_Attribute_Normal,0);
            if mailSlot2 <> INVALID_HANDLE_VALUE then begin
            win32Check(WriteFile(mailSlot2,msg[1],length(msg),bytes,nil));
            closeHandle(mailSlot2);
            end else RaiseLastWin32Error;
            except
            hist.lines.add('Fehler bei Nachricht an den Server');
            end;
            end;
            </pre>Hier habe ich es erst ohne (da ja eigentlich vollzugriff für alle), dann mit den SecurityAttributes versucht, in beiden Fällen schlägt CreateFile fehl und RaiseLastWin32Error gibt fehlercode 5, Zugriff verweigert zurück, seufz, was ist falsch

            Comment


            • #21
              OK: vergiß mal kurz den ganzen Sicherheitskram...<br>
              (ich hätte eher im MSDN nachsehen sollen, naja, der SecurityDiscriptor wird eh' ignoriert (bis auf das inherited-flag))

              Wie lautet der Name für den Mailslot ?

              Gruß Nic

              Comment


              • #22
                resourcestring
                msMailSlotName = '\\.\mailslot\ModsoTapiSlot';
                msMailSlot2Name = '\\.\mailslot\ModsoTapiSlot2';
                Wie mal erwähnt, der eine für Anwendung an Service, der andere für Service an Anwendung
                <p>
                Aber wieso ignoriert?
                <p>
                lpSecurityAttributes

                Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpSecurityAttributes is NULL, the handle cannot be inherited.

                Windows NT: The lpSecurityDescriptor member of the structure specifies a security descriptor for the new mailslot. If lpSecurityAttributes is NULL, the mailslot gets a default security descriptor.
                <p> Da der Service ja für NT/2K ist wird er doch benutzt?! Einen Satz weiter steht lediglich, das er unter 95 ignoriert wird..

                Comment


                • #23
                  MSDN August 2001 = "lpSecurityAttributes
                  [in] Pointer to a SECURITY_ATTRIBUTES structure. The bInheritHandle member of the structure determines whether the returned handle can be inherited by child processes. If lpSecurityAttributes is NULL, the handle cannot be inherited. <b>The lpSecurityDescriptor member of the structure is ignored.</b>"

                  Gruß Nico

                  PS: M$ ändert ab-und-zu seine Meinung *g

                  Comment


                  • #24
                    Nun, denn hier einmal ein Minimalbeispiel, im Service:
                    <pre>
                    <font size = 2>
                    var mailslot : THandle;

                    procedure TService1.ServiceCreate(Sender: TObject);
                    begin
                    mailSlot := CreateMailSlot('\\.\mailslot\testslot', 0, 0, nil);
                    if mailSlot = INVALID_HANDLE_VALUE then
                    raiselastwin32error;
                    end;

                    procedure TService1.ServiceDestroy(Sender: TObject);
                    begin
                    if mailSlot <> INVALID_HANDLE_VALUE then
                    closeHandle(mailSlot);
                    end;

                    </pre> und um Programm:<pre>
                    mailSlot := CreateFile('\\.\mailslot\testslot', Generic_Write, FILE_SHARE_READ,nil,Open_Existing,FILE_ATTRIBUTE_N ORMAL,0);
                    if mailSlot <> INVALID_HANDLE_VALUE then begin
                    win32Check(WriteFile(mailSlot,'bla',3,bytes,nil));
                    closeHandle(mailSlot);
                    end else RaiseLastWin32Error;
                    </pre>
                    Resultat: "Fehlercode 5, Zugriff verweigert" Das muss doch zu machen sein?

                    Comment


                    • #25
                      Keiner eine Idee? Schluchz ;

                      Comment


                      • #26
                        Ich habe es bis heute nicht hinbekommen, hat nicht doch noch irgendeiner eine Idee

                        Comment


                        • #27
                          Ich habes leider bis heute nicht geschafft, hat nicht soch jemand eine Idee, wie man in einem Service einen Mailslot erstellen kann, auf den "normale" Programme zugreifen können

                          Comment


                          • #28
                            Hallo,

                            &gt;Windows 95/98/Me: The lpSecurityDescriptor member of this structure is ignored.

                            der Hinweis von NicoDE gilt <b>nicht</b> für Windows NT/2000/XP. Microsoft hat im der Hilfe aus dem Platform SDK (Hilfeseite zu SECURITY_ATTRIBUTES) folgendes dazu geschrieben:

                            <i>lpSecurityDescriptor = Pointer to a security descriptor for the object that controls the sharing of it. If NULL is specified for this member, the object is assigned the default security descriptor of the calling process. This is not the same as granting access to everyone by assigning a null DACL. The default security descriptor is based on the default DACL of the access token belonging to the calling process. <b>By default, the default DACL in the access token of a process allows access only to the user represented by the access token. If other users must access the object, you can either create a security descriptor with a null DACL, or add ACEs to the DACL that grants access to a group of users.</b></i>

                            Nur dann, wenn der Dienst unter dem gleichen Benutzerkonto ausgeführt wird wie der interaktiv angemeldete Benutzer, benötigt man lpSecurityDescriptor nicht.

                            P.S: Wenn die Anwendung unter Windows 2000 laufen soll, warum wird dann nicht auf COM+ zurückgegriffen? Dort muss man sich mit diesem ganzen Low-Level-Kram nicht mehr beschäftigten, da die COM+ Roles auf Wunsch die Zugangsprüfung über Benutzernamen bzw. Gruppennamen erledigen

                            Comment

                            Working...
                            X