Laden...

Löschen von Benutzerordnern

Erstellt von Panawr vor 8 Jahren Letzter Beitrag vor 8 Jahren 3.695 Views
P
Panawr Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren
Löschen von Benutzerordnern

Hallo werte Community!

Ich stehe derzeit vor einem Problem und finde leider keine passende Lösung, vielleicht weiß ja jemand von euch weiter.

Kurz worum es geht:
Ich benutze einen Windows-Service, der beim Start alle (bis auf einige Ausnahmen) Benutzerordner unter C:\Users löschen soll.

Leider bekomme ich die Fehlermeldung, dass der Zugriff auf den Pfad xy verweigert wurde.
Das löschen bezieht sich nur auf Benutzer, die nicht angemeldet sind.

Hier kurz den Code, den ich dafür benutze:

public static void DeleteDirectory(string path, bool recursive)
{
    if (recursive)
    {
        var subfolders = Directory.GetDirectories(path);
        foreach (var s in subfolders)
        {
            DeleteDirectory(s, recursive);
        }
    }
 
    var files = Directory.GetFiles(path);
    foreach (var f in files)
    {
        var attr = File.GetAttributes(f);
 
        if ((attr & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
        {
            File.SetAttributes(f, attr ^ FileAttributes.ReadOnly);
        }
 
        File.Delete(f);
    }
 
    Directory.Delete(path);
}

Diese Methode habe ich mir schon ausm Netz gesucht, da dass einfache Directory.Delete(path, true) nicht funktioniert, da ich hier die Fehlermeldung "Verzeichnis ist nicht leer" bekommen würde.

Hat jemand eine Idee, warum dem Service den Zugriff verweigert wird?
Die Anwendung wird unter Administrator Bedingungen installiert.

MfG
Pana

127 Beiträge seit 2015
vor 8 Jahren

Die Frage ist nicht unter welchem Account du die Anwendung installierst sondern unter welchem Account der Windows-Service läuft.
Dieser Account braucht die notwendigen Berechtigungen zum löschen der gewünschten Verzeichnisse.

P
Panawr Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren

Hallo, danke für die Antwort.
Müsste ich dem Dienst also quasi einen Adminnuter + Passwort mitgeben?

LG
Pana

127 Beiträge seit 2015
vor 8 Jahren

Dienste laufen unter einem, bei der Installation des Dienstes angegeben, Account.
Neben einem expliziten Benutzer Account gibt es noch spezielle Windows-Dienst Konten (Service User Accounts (Windows))
Wenn dir also nicht bekannt ist unter welchem Benutzer der Dienst läuft weil du keinen angegeben hast, dann läuft dein Dienst vermutlich erstmal unter einem dieser drei. Meine Vermutung LocalSystem.
Das ist grundsätzlich erstmal ein recht eingeschränkter Account der nicht viel darf.

Man kann den Dienst auch noch nach der Installation einen anderen Account zuweisen:
Configure How a Service Is Started

Du mußt also den Dienst einfach nur in der Dienstverwaltung umkonfigurieren und einen Account zuweisen der Löschberechtigungen auf diese Verzeichnisse hat.

P
Panawr Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren

Ich danke dir vielmals.

P
Panawr Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren

Guten Morgen!

Habe soeben mal deinen Ansatz getestet und dem Dienst einen Admin-Account zugewiesen.
Klassisch unter Dienste -> Dienst ausgewählt -> Eigenschaften -> Anmelden.
Das habe ich unter 3 verschiedenen Admin-Accounts getestet.

Leider nach wie vor System.UnauthorizedAccessException: Der Zugriff auf den Pfad "C:\Users****" wurde verweigert.

Habe langsam die Befürchtung, dass ein Dienst nicht dafür ausgelegt ist, irgendwelche Directorys zu löschen 😦

Vielleicht jemand noch eine Idee?

LG
Pana

1.040 Beiträge seit 2007
vor 8 Jahren

Meiner Meinung nach wird das Angeben von Logininformationen nichts bringen, wenn der Service nicht als "User" läuft.

Schaue dir das mal an:
ServiceAccount-Enumeration

1.696 Beiträge seit 2006
vor 8 Jahren

Selbst ein Admin kann nicht auf alles zugreifen, vor allem wenn der Besitzer es explizit ausgrenzt. Jedoch mit Adminrechte kann man "den Besitzt übernehmen" und danach sind Tur und Tor offen. Abzuklären bleibt nur noch, ob man/du das darfst (juristisch).

Ein Service mit Admin-Account laufen zu lassen ist auch nicht "normal". Bessere Lösung ist Impersonation.

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

P
Panawr Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren

Meiner Meinung nach wird das Angeben von Logininformationen nichts bringen, wenn der Service nicht als "User" läuft.

Schaue dir das mal an:

>

Hey,

dieses Verfahren bringt quasi das gleiche Ergebnis wie wenn ich unter der Dienstverwaltung einen expliziten Benutzer eingebe. Hilft also leider auch nicht.

Selbst ein Admin kann nicht auf alles zugreifen, vor allem wenn der Besitzer es explizit ausgrenzt. Jedoch mit Adminrechte kann man "den Besitzt übernehmen" und danach sind Tur und Tor offen. Abzuklären bleibt nur noch, ob man/du das darfst (juristisch).

Ein Service mit Admin-Account laufen zu lassen ist auch nicht "normal". Bessere Lösung ist Impersonation.

Danke für die Antwort.
Ja, im Endeffekt wäre es die unschönste Methode einen Adminuser angeben zu müssen.
Habe es auch lediglich aus dem Grund versucht, um zu sehen ob es überhaupt funktioniert.

Ich erläutere noch mal kurz, worum es in meiner Anwendung geht:

Meine Anwendung wird auf unseren Terminalservern in der Firma installiert, um regelmäßige Neustarts unter bestimmten Voraussetzungen zu gewährleisten.
Die Parameter übergibt der Administrator also in der GUI und werden per XML gespeichert.
Bei der Installation wird auch ein Dienst installiert, der in Intervallen bestimmte Methoden aufruft.
Zum einen eine Methode um den Neustart auszuführen, und eine Methode die auf Wunsch die Benutzerordner + Registrykeys nach dem nächsten Neustart löschen soll.

Zum Thema Impersonation:

Ich habe bereits versucht, mithilfe einer Impersonation-Klasse, beim Aufruf der Methode zum löschen der Ordner einen Admin-User anzugeben. Leider auch ohne Erfolg.

1.040 Beiträge seit 2007
vor 8 Jahren

Hast du es mal mit 'LocalSystem' ausprobiert?

1.696 Beiträge seit 2006
vor 8 Jahren

Ich habe bereits versucht, mithilfe einer Impersonation-Klasse, beim Aufruf der Methode zum löschen der Ordner einen Admin-User anzugeben. Leider auch ohne Erfolg.

Wie gesagt, auch mit Impersonation muss du zuerst den Besitz übenehmen wenn du keine Rechte hast, erst dann kannst du löschen.

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

P
Panawr Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren

Probiere es derzeit so:

public static void DeleteDirectory(string path, bool recursive)
        {
            //Besitzer ändern
            var fs = File.GetAccessControl(path);
            var NTAccount = new NTAccount("WIN-GIM3JHBT5MH", "Admin");
            fs.SetOwner(NTAccount);
            File.SetAccessControl(path, fs);

            if (recursive)
            {
                var subfolders = Directory.GetDirectories(path);
                foreach (var s in subfolders)
                {
                    DeleteDirectory(s, recursive);
                }
            }

            var files = Directory.GetFiles(path);
            foreach (var f in files)
            {
                var attr = File.GetAttributes(f);
                
                if ((attr & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    File.SetAttributes(f, FileAttributes.Normal);
                }

                File.Delete(f);
            }

            Directory.Delete(path);
        }

Vor Aufruf der Methode nutze ich noch die Impersonation-Klasse.
Leider auch das alles ohne Erfolg, bekomme einfach kein Zugriff auf die Dateien 😦

P
Panawr Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren

Also langsam wird es wirklich kurios.
Ich habe jetzt C:\Users extra für absoluten Jeden Schreib- und Leserechte gegeben.
Jeden Ordner von irgendwelchen Berechtigungen befreit und dem Service wird noch immer den Zugriff verweigert, blicke allmählich nicht mehr durch.

Werde es wohl anscheinend nicht per Service lösen können, da muss vielleicht doch ein Batch her, der manuell aufgerufen werden muss 😦

1.696 Beiträge seit 2006
vor 8 Jahren

Wenn du dein Programm laufen läßt, hast du z.B. im Windows Explorer überprüft, ob die Besitzübernahme per Programm funktioniert oder nicht?

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

1.040 Beiträge seit 2007
vor 8 Jahren

Was hast du denn jetzt unter 'Account' im ServiceProcessInstaller eingestellt?

P
Panawr Themenstarter:in
8 Beiträge seit 2015
vor 8 Jahren

Wenn du dein Programm laufen läßt, hast du z.B. im Windows Explorer überprüft, ob die Besitzübernahme per Programm funktioniert oder nicht?

Ja, selbst hier kommt eine eine exception: Die Sicherheits-ID darf nicht der Besitzer dieses Objekts sein.
Habe es mir anderen Accounts auch versucht.

Was hast du denn jetzt unter 'Account' im ServiceProcessInstaller eingestellt?

Habe es als User und als LocalSystem versucht, beides erfolglos.

Kurz zu meinem Testverfahren:
Ich teste natürlich nicht vom debugger aus oder auf meinem lokalen System, sondern erstelle eine .exe und installiere diese jedes mal auf einer VM.

Danke für die Antworten.

LG Pana

1.696 Beiträge seit 2006
vor 8 Jahren

Wenn du dein Programm laufen läßt, hast du z.B. im Windows Explorer überprüft, ob die Besitzübernahme per Programm funktioniert oder nicht?

Ja, selbst hier kommt eine eine exception: Die Sicherheits-ID darf nicht der Besitzer dieses Objekts sein.
Habe es mir anderen Accounts auch versucht.

Tja, wenn 'ne Exception kommt, dann stimmt was nicht mit deiner Impersonation! Finde heraus, woran es liegt, dann sollte es gehen.

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

U
135 Beiträge seit 2009
vor 8 Jahren

Meine Vermutung LocalSystem.
Das ist grundsätzlich erstmal ein recht eingeschränkter Account der nicht viel darf.

Auch wenn's eigentlich nicht zum eigentlichen Thema beiträgt, wollte ich das so nicht stehen lassen.
**:::

Genau das Gegenteil ist der Fall... ich würde sogar soweit gehen und sagen: der darf mehr, als ein "normaler" Administrator-Account.
Meintest Du vielleicht LocalService? Auf den würde die Beschreibung eher zutreffen 😃

Steht ja auch in dem von Dir verlinkten Microsoft-Arttikel zu LocalSystem:

"It has extensive privileges on the local computer, and acts as the computer on the network. Its token includes the NT AUTHORITY\SYSTEM and BUILTIN\Administrators SIDs; these accounts have access to most system objects."

Aus diesem Grund ist in den größeren Unternehmen i.d.R. bei den IT-Security-Kollegen äußerst ungern gesehen, wenn eine Drittanbieter-Software einen Dienst installiert, die als LocalSystem laufen will. Zumal es in vielen Fällen gar nicht benötigt wird 😃
Bei uns ist es etwa so, dass bei jeglicher neuen Software zu prüfen ist, ob der Dienst mit einem Managed Service Account laufen kann - und falls zwingend LocalSystem sein muss, so muss das explizit dokumentiert werden. Sonst würde es bei jedem Security-Scan in Form eines Security Incidents beim zuständigen Admin landen, der erneut prüfen müsste, ob der Dienst wirklich als LocalSystem laufen muss.

127 Beiträge seit 2015
vor 8 Jahren

Ja, da hast du recht. Da habe ich LocalSystem und LocalService tatsächlich verwechselt.
Danke für das Aufmerksam machen!
Denn LocalService:

It has minimum privileges on the local computer and presents anonymous credentials on the network. LocalService Account (Windows)
Und denn hatte ich im Sinn als ich meine Vermutung geschrieben hatte.
Mea culpa.