Datei-Eigentümer/ Gruppe ändern

  • VB.NET
  • .NET (FX) 3.0–3.5

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von TRiViUM.

    Datei-Eigentümer/ Gruppe ändern

    Nabend liebe Community,

    zur Lösung

    mein Vorhaben liegt darin, den Eigentümer von einer Datei zu ändern.

    Es handelt sich um eine Systemdatei, weshalb ich das Programm bereits mit level="highestAvailable" ausführe.
    Ursprünglicher Eigentümer ist TrustedInstaller, ich möchte den Eigentümer aber auf das Gruppenkonto Administratoren ändern.
    Anschließend möchte ich diesem neuen Gruppenkonto einen Vollzugriff für diese Datei erteilen.

    Ich habe folgenden Code:

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Try
    4. Dim Datei As String = System.Environment.SystemDirectory & "\drivers\battc.sys" 'C:\Windows\System32\drivers\battc.sys
    5. ' Benutzer festlegen
    6. Dim benutzer As Security.Principal.IdentityReference = New Security.Principal.NTAccount("Administratoren")
    7. ' Instanziierung der FileSecurity ohne Parameter
    8. Dim berechtigung As New AccessControl.FileSecurity()
    9. ' ...und auf die Datei anwenden.
    10. Dim file As New IO.FileInfo(Datei)
    11. file.SetAccessControl(berechtigung)
    12. ' Erst danach Zugriffsrechte setzen
    13. Dim regel As New AccessControl.FileSystemAccessRule(benutzer, AccessControl.FileSystemRights.FullControl, AccessControl.AccessControlType.Allow)
    14. berechtigung.SetAccessRule(regel)
    15. file.SetAccessControl(berechtigung)
    16. Catch ex As Exception
    17. MessageBox.Show(ex.Message & Environment.NewLine & Environment.NewLine & ex.StackTrace, "Errorcode " & Err.Number, MessageBoxButtons.OK, MessageBoxIcon.Error)
    18. End Try


    Ich bekomme jedoch folgende Fehlermeldung:

    Quellcode

    1. Es wurde versucht, einen nicht autorisierten Vorgang auszuführen.
    2. bei System.Security.AccessControl.Win32.SetSecurityInfo(ResourceType type, String name, SafeHandle handle, SecurityInfos securityInformation, SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl, GenericAcl dacl)
    3. bei System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
    4. bei System.Security.AccessControl.NativeObjectSecurity.Persist(String name, AccessControlSections includeSections, Object exceptionContext)
    5. bei System.Security.AccessControl.FileSystemSecurity.Persist(String fullPath)
    6. bei System.IO.FileInfo.SetAccessControl(FileSecurity fileSecurity)
    7. bei GroupChange.Form1.ChOwn()


    Ich kann das manuell ohne Probleme durchführen, jedoch habe ich einige PCs damit auszustatten, und das ist ne blöde und aufwändige Arbeit.
    Darum mein Vorhaben, es mit einem Programm zu automatisieren.

    Was mache ich da falsch?

    Danke für Eure Hilfe ^^

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „TRiViUM“ ()

    TRiViUM schrieb:

    ändern
    Unter der Voraussetzung, dass das legal ist:
    Kopiere die Datei auf einen FAT32-formatierten USB-Stick, lösche die Originaldatei, sofern die Admin-Rechte dazu genügen, kopiere die FAT-32-Datei zurück und gib ihr die erforderlichen Rechte.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Du setzt ja nirgends den Owner:

    VB.NET-Quellcode

    1. Dim fs as FileSecurity = fi.GetAccessControl;
    2. fs.SetOwner(benutzer);


    msdn.microsoft.com/en-us/libra…y.setowner(v=vs.110).aspx
    Das ist meine Signatur und sie wird wunderbar sein!
    @RodFromGermany
    wird mit Sicherheit legal sein, sonst wäre das ja eine beachtliche Sicherheitslücke, die schon seit langer Zeit besteht...
    Könnte man (falls es klappt) zwar so machen, jedoch habe ich nicht die Nerven dazu, an jedem PC immer nen Stick etc. anzuschließen, nur um von einer Datei den Besitzer zu ändern :)

    Mono schrieb:

    Du setzt ja nirgends den Owner

    auch wenn ich es so mache, wie Du mir vorgeschlagen hast, bleibt die selbe Fehlermeldung bestehen.

    Unautorisierter Vorgang klingt so, als hätte ich nicht die nötigen Rechte.
    Wenn ich es aber manuell mache, klappt es ohne Probleme.

    Kann ich noch nicht ganz nachvollziehen :S
    Starte dein Programm mit SYSTEM Rechten.
    Aber immer schön legal bleiben.
    für XP kannst du den at Befehlt beutzen. Also z.B:
    at 13:37 /interactive deinProgramm.exe

    für Vista und höher kannst du das mit psexec machen.
    Du brauchst dafür den Paramenter -s für die SYSTEM-Rechte und -i damit du das Programm sehen kannst.
    (Normalerweise sind Programme die von SYSTEM ausgeführt werden nicht sichtbar für den Anwender.




    Gruß

    Pantsuu schrieb:

    mit SYSTEM Rechten

    Danke für deine Hilfe.

    Zum Verständnis:
    wenn ich den Besitzer manuell ändere, funktioniert das.
    Heißt das jetzt, dass ich mit einem "normalen" Benutzerkonto (Standard-Benutzerkonto) Systemrechte besitze?
    Falls ja, wieso kann ich mein Programm dann nicht gleich mit Systemrechten starten ?!

    Habe es mit PsExec.exe probiert, bekomme jedoch folgende Fehlermeldung:

    Quellcode

    1. Error establishing communication with PsExec service on Virtual-PC
    2. Die Netzwerkadresse ist nicht erreichbar.
    Ich muss dazu sagen, dass ich das alles erstmal auf einem virtuellen PC teste (bevor ich mir noch mein System zerschieße), wo ich keine Netzwerkadapter aktiviert habe.
    Falls, wieso ist PsExec von Netzwerkadaptern abhängig?

    Und, ich habe es mit at 15:22 /interactive programm.exe versucht.
    Hat zwar (wie von dir beschrieben) nicht geklappt, jedoch wurde mir vorgeschlagen, schtaskstattdessen zu benutzen.
    Probier mal:

    VB.NET-Quellcode

    1. dim p as Privilege= new Privilege(Privilege.TakeOwnership)
    2. p.Enable()


    Brauchst dazu System.Security.AccessControl als imported Namespace.
    Dann versuch die Recht zu setzen und mach wieder

    p.Revert
    Das ist meine Signatur und sie wird wunderbar sein!
    Ja kann sein das es das noch nicht gibt.
    Vermutlich geht es dann nur mit WinAPI oder Reflection, die Klasse Privilege ist vorhanden aber Sealed.

    Vll nimmst das:
    processprivileges.codeplex.com/
    Das ist meine Signatur und sie wird wunderbar sein!

    TRiViUM schrieb:

    Pantsuu schrieb:

    mit SYSTEM Rechten

    Habe es mit PsExec.exe probiert, bekomme jedoch folgende Fehlermeldung:

    Quellcode

    1. Error establishing communication with PsExec service on Virtual-PC
    2. Die Netzwerkadresse ist nicht erreichbar.
    Ich muss dazu sagen, dass ich das alles erstmal auf einem virtuellen PC teste (bevor ich mir noch mein System zerschieße), wo ich keine Netzwerkadapter aktiviert habe.
    Falls, wieso ist PsExec von Netzwerkadaptern abhängig?


    Weil es ursprünglich für Remotezugriff erstellt wurde.
    Wenn man aber keine Remote-Daten angibt führt es das Programm lokal aus.
    Ich denke der Fehler kommt einfach weil es beim Programmstart prüft ob es eine Netzwerkkarte verfügbar ist. Kann ich aber nicht mit Sicherheit sagen, hatte diesen Fall noch nie.
    Kannst doch mal den Adapter in der VM anschalten zum testen.
    Das Programm benutze ich schon länger für Administrative Aufgaben die eben höhere Rechte brauchen.

    Gruß :)

    Mono schrieb:

    Vll nimmst das:
    processprivileges.codeplex.com/
    Jetzt sieht die Sache schon besser aus :)

    Ich habe jetzt folgendes:

    VB.NET-Quellcode

    1. Private Sub test()
    2. Dim p As Process = Process.GetCurrentProcess()
    3. Using New PrivilegeEnabler(p, Privilege.TakeOwnership)
    4. ' Privilege is enabled within the using block.
    5. Console.WriteLine("{0} => {1}", Privilege.TakeOwnership, p.GetPrivilegeState(Privilege.TakeOwnership))
    6. End Using
    7. ' Privilege is disabled outside the using block.
    8. Console.WriteLine("{0} => {1}", Privilege.TakeOwnership, p.GetPrivilegeState(Privilege.TakeOwnership))
    9. End Sub

    Die Ausgabe ist diese:
    TakeOwnership => Enabled
    TakeOwnership => Disabled

    Das sagt mir jetzt genau was?
    Also wenn ich den PrivilegeEnabler benutze, kann ich wohl mehr machen.
    Wie wende ich das auf mein Projekt an?

    Pantsuu schrieb:

    ursprünglich für Remotezugriff

    mit Netzwerkadapter klappt es (fast).
    Es kommt eine Fehlermeldung zu einem Pfad, welcher nicht existiert (irgendwas mit C:\Windows\System32\config\systemprofile\...)
    Aber anschließend bekomme ich in meinem Programm immer noch die selbe Fehlermeldung wie am Anfang:
    Es wurde versucht, einen nicht autorisierten Vorgang auszuführen.


    :huh:

    Mono schrieb:

    Funkioniert es mit WindowsIdentity.GetCurrent().User?

    wenn du mir sagen kannst, wie man Security.Principal.IdentityReference nach Security.Principal.WindowsIdentity umwandeln kann :D

    Umwandeln deshalb, da ​AccessControl.FileSystemAccessRule als erste Überladung eine ​IdentityReference verlangt.

    Ich steige da langsam nicht mehr durch :whistling:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „TRiViUM“ ()

    Einfach so.

    C#-Quellcode

    1. FileInfo file = new FileInfo(filepat);
    2. FileSecurity fsec = file.GetAccessControl();
    3. IdentityReference newUser = WindowsIdentity.GetCurrent().User;
    4. fsec.SetOwner(newUser);
    5. FileSystemAccessRule permissions = new FileSystemAccessRule(newUser,FileSystemRights.FullControl, AccessControlType.Allow);
    6. fsec.AddAccessRule(permissions);
    7. file.SetAccessControl(fsec);
    Das ist meine Signatur und sie wird wunderbar sein!

    Mono schrieb:

    Einfach so

    Ok, aber hat leider auch nichts geholfen.
    Die Fehlermeldung kommt dennoch...

    Meine Grundlage für Eigentümer-Änderungen bzw. Dateiberechtigungen war folgende:
    - vbarchiv.net -

    // Edit:
    Ich hab endlich die Lösung!

    Benötigter DLL-Verweis: processprivileges.codeplex.com/

    Und anschließender Import:
    Imports ProcessPrivileges

    VB.NET-Quellcode

    1. Try
    2. Dim p As Process = Process.GetCurrentProcess
    3. Using New PrivilegeEnabler(p, Privilege.TakeOwnership)
    4. ' Benutzer festlegen
    5. Dim benutzer As Security.Principal.IdentityReference = _
    6. New Security.Principal.NTAccount("Administratoren")
    7. ' Instanziierung der FileSecurity ohne Parameter
    8. Dim berechtigung As New AccessControl.FileSecurity
    9. ' Besitzer festlegen...
    10. berechtigung.SetOwner(benutzer)
    11. ' ...und auf die Datei anwenden.
    12. Dim file As New IO.FileInfo("Dateipfad")
    13. file.SetAccessControl(berechtigung)
    14. ' Erst danach Zugriffsrechte setzen
    15. Dim regel As New AccessControl.FileSystemAccessRule(benutzer, _
    16. AccessControl.FileSystemRights.FullControl, _
    17. AccessControl.AccessControlType.Allow)
    18. berechtigung.SetAccessRule(regel)
    19. file.SetAccessControl(berechtigung)
    20. End Using
    21. Catch ex As Exception
    22. MessageBox.Show(ex.Message & Environment.NewLine & Environment.NewLine & ex.StackTrace, "Errorcode " & Err.Number, MessageBoxButtons.OK, MessageBoxIcon.Error)
    23. End Try


    nach unzähligem Testen war dann am Ende des Tunnels doch noch Licht :thumbsup:

    Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „TRiViUM“ ()