2009-05-22 1 views
5

Ich habe eine Reihe von Win32-Anwendungen, die Informationen mit einem gemeinsamen Speichersegment teilen, das mit CreateFileMapping() und MapViewOfFile() erstellt wurde. Eine der Anwendungen ist ein Systemdienst; Der Rest wird vom angemeldeten Benutzer gestartet. Unter Windows XP gab es kein Problem. Wir haben unsere Segmente "Global \ Something" genannt und alles war gut.Wie kann der Speicher zwischen Diensten und Benutzerprozessen gemeinsam genutzt werden?

Die zusätzliche Sicherheit in Vista (und vermutlich Windows 7) scheint zu verhindern, dass diese Architektur funktioniert. Normale Benutzer dürfen keine Objekte im globalen Namespace erstellen (Win32-Fehler 5). Der MSDN gibt an, dass, wenn das Konto über die Berechtigung "global erstellen" verfügt, alles gut sein sollte, aber dies scheint in der Praxis nicht der Fall zu sein. Außerdem scheinen die "Integritäts" -Funktionen von Vista zu verhindern, dass die Benutzerprozesse mit "geringer Integrität" auf das vom Dienst erstellte Shared Memory-Objekt mit "hoher Integrität" zugreifen. Es sieht so aus, als ob ich in der Lage wäre, das über eine magische SetSecurityDescriptorSacl() Beschwörungsformel zu beheben, aber ich habe Schwierigkeiten beim Sprechenlernen.

Die Frage ist also: Was der Verwendung eines Shared-Memory-Segment zwischen Diensten und normalen Benutzerprozessen der richtige Weg ist?

Um die einfache Antwort "nur UAC abschalten" zu vermeiden, sind wir in einer ziemlich gesperrten Umgebung und das ist keine Möglichkeit.

Edit: Sowohl der Dienst als auch der Benutzerprozess benötigen Lese-/Schreibzugriff auf das Segment.

Antwort

9

Der einfachste Weg, Ihren Dienst zu haben sein würde, schafft den gemeinsam genutzten Speicher und eine DACL in Create angeben, die regelmäßigen Nutzer gewährt Zugriff auf den gemeinsamen Speicher zu lesen.

Normale Benutzer haben nicht die globale Berechtigung erstellen, aber Dienste können Sie dieses Recht haben. Wenn Ihre Benutzer den gemeinsam genutzten Speicher erstellen und dann den Dienst testen lassen müssen, könnten Sie ein IPC-Schema haben, bei dem Ihr Benutzercode eine Nachricht an den Dienst mit dem Dateizuordnungshandle sendet und der Dienst dann DuplicateHandle aufruft, um einen zu erhalten Hinweis darauf. Dies würde erfordern, dass Ihr Dienst mit der Debug-Berechtigung ausgeführt wird.

Die einfachste Methode zum Erstellen einer DACL ist ConvertStringSecurityDescriptorToSecurityDescriptor, die eine Zeichenfolge in einem Format namens SDDL verwendet, das die ACL angibt.

Writing Secure Code enthält ein hervorragendes Kapitel über DACL der mit SDDL zu schaffen.

// Error handling removed for brevity 
SECURITY_ATTRIBUTES security; 
ZeroMemory(&security, sizeof(security)); 
security.nLength = sizeof(security); 
ConvertStringSecurityDescriptorToSecurityDescriptor(
     L"D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GR;;;IU)", 
     SDDL_REVISION_1, 
     &security.lpSecurityDescriptor, 
     NULL); 

CreateFileMapping(INVALID_HANDLE_VALUE, &security, 
       PAGE_READWRITE, sizeHigh, sizeLow, L"Global\\MyObject"); 

LocalFree(securityDescriptor.lpSecurityDescriptor); 

"D: P (A; OICI; GA ;;; SY) (A; OICI; GA ;;; BA) (A; OICI; ;;; GR IE)" gibt die DACL. D: P bedeutet, dass dies eine DACL ist (statt einer SACL... Würden Sie selten SACLs verwenden), gefolgt von mehreren ACE-Strings, die kontrollieren, wer Zugriff bekommt. Jeder ist A (erlaubt) und erlaubt Objekt und enthält Vererbung (OICI). Der erste, der alle Zugriffe (GA - Grant all) auf System (SY) und Administratoren (BA, eingebaute Administratos) gewährt. Das letzte gewährt interaktiven Benutzern (IE) Lesezugriff (GR), bei denen es sich um Benutzer handelt, die tatsächlich bei einer Sitzung angemeldet sind.

Sobald dies geschehen ist, normale Benutzer sollten in der Lage sein OpenFileMapping ruft einen Griff auf das gemeinsam genutzte Mapping zu bekommen, und die Lage sein, sie in ihren Prozess abzubilden. Da normale Benutzer eingeschränkte Rechte an dem Objekt haben, müssen sie sicher sein, es zu öffnen und es nur für Lesezugriff zuzuordnen.

Wenn Benutzer Schreibzugriff benötigen, würden Sie GR durch GWGR ersetzen. Beachten Sie, dass dies nicht sicher ist. Ein eingeschränkter Benutzer wäre dann in der Lage, den gemeinsamen Speicher zu ändern, während Ihr Dienst versucht, Informationen zu analysieren und zu analysieren, was zu einem Absturz Ihres Dienstes führt.

+1

Leider müssen die normalen Benutzer auch Schreibzugriff haben – Clay

+1

Aktualisierte Antwort. Sie müssen nur die Sicherheitsbeschreibung optimieren. – Michael

+0

Gute Antwort - wir sind in einer seltsamen Sicherheitslage. Den Endbenutzern wird vertraut, dass sie mit dem System interagieren (daher können sie den Speicher ändern, der dem Dienst gehört), aber wir müssen ihren Zugriff beschränken (UAC muss eingeschaltet sein usw.). Willkommen zum Wahnsinn der Regierungsnetzwelt. – Clay