Laden...

Eigentümer einer Datei ändern C#

Erstellt von Piep000r vor 11 Jahren Letzter Beitrag vor 11 Jahren 6.958 Views
P
Piep000r Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren
Eigentümer einer Datei ändern C#

Hallo, ich möchte gerne ein kleines Tool schreiben mit dem ich unter anderem den Besitzer einer Datei neu setzen kann (SetOwner).

Ich habe bisher den folgenden Ansatz. Allerdings übernimmt er die Einstellungen über den Besitzer leider nicht.

Geht das so überhaupt? Ich habe das Programm auch schon als lokaler Administrator ausgeführt. Jedoch brachte dies auch nicht den gewünschten Erfolg (fehlende Berechtigung).

Lässt Windows meine Idee in der Form überhaupt zu?


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;


namespace set_acls
{
    class Program
    {
        static void Main(string[] args)
        {
            string FILE = @"c:\temp\test.txt";

            try
            {


                // aktuellen Besitzer einer Datei auslesen
                var fs = File.GetAccessControl(FILE);

                var sid = fs.GetOwner(typeof(SecurityIdentifier));
                Console.WriteLine(sid);

                var ntAccount = sid.Translate(typeof(NTAccount));
                Console.WriteLine(ntAccount);



                // neuen Besitzer einer Datei festlegen
                var NTAccount = new NTAccount("Developer-PC","test");

                fs.SetOwner(NTAccount);
                File.SetAccessControl(FILE, fs);

                Console.WriteLine("Besitzer erfolgreich geändert");


                Console.ReadLine();
    

            }
            catch (Exception e) {

                Win32Exception w32exp = new Win32Exception();
                Console.WriteLine(w32exp);

                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();

                Console.WriteLine(e);
                Console.ReadLine();
                
            }



        }
    }
}

W
872 Beiträge seit 2005
vor 11 Jahren
P
Piep000r Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren

Genau!

Von Dort habe ich den Großteil meines Programms.

Jedoch Funktioniert es nicht.

Ich bekomme folgende Ausgabe (siehe Bild)!

Mir ist an der Stelle unklar, wieso ich einen nicht autorisierten Vorgang ausführe, denn mein Benutzerkonto ist ein Administrator!

Hat da vielleicht einer eine Idee warum dieser Fehler entsteht?

6.911 Beiträge seit 2009
vor 11 Jahren

Hallo Piep000r,

denn mein Benutzerkonto ist ein Administrator!

unter UAC hat ein Admin-Konto 2 Benutzer-Token, eines für den normalen Benutzer, das standardmäßig verwendet wird, und eines für den Admin, das bei "Run as Admin..." verwendet wird. D.h. dazu musst du dein Programm auch als Admin ausführen lassen.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

P
Piep000r Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren

Vielen Dank für Deine Hilfe gfoidl!

Ich habe es nun wie hier gemacht:

How to force my .NET App to run as administrator on Windows 7

Also eine Manifestdatei erstellt und meine Anwendung laufen lassen.

Jedoch macht das Programm noch nicht ganz das was ich mir vorgestellt habe.

Ich kann nur als aktuell angemeldeter Benutzer den Besitz der Datei übernehmen. Aber nicht einfach einen beliebigen Benutzer als Besitzer zuweisen.

Gibts da ein Workaround um mich während ich dieses Programm als User x ausführe für den Teil der Besitzübernahme als User y auszugeben?

Oder habt Ihr vielleicht noch ein bessere Idee?

16.832 Beiträge seit 2008
vor 11 Jahren

Du musst auch andere Benutzer als Owner setzen können. Das einzige, was Du brauchst, ist die TakeOvershipPermission, die Du als Admin hast. Ich mach das zwar über die WinAPI SetNamedSecurityInfo, aber .NET AccessControl greift im Hintergrund auf diese Schnittstelle zu.

Und nein, selbstverständlich kannst Du nicht einfach so irgendwelche Anwendungen unter einem anderen Benutzerkonto ausführen, wenn Du dessen Passwort nicht hast...

Gibt auch noch folgende Möglichkeit, die man verwendet, wenn eine Datei eine / mehrere fehlerhafte Zuweisungen oder gar kein Owner mehr hat (NTFS):

var fs = new FileSecurity(); 
fs.SetOwner(<neuer admin>); 
fs.AddAccessRule(new FileSystemAccessRule(<neuer admin> FileSystemRights.FullControl, AccessControlType.Allow)); 

File.SetAccessControl(<path>, fs); 

P
Piep000r Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren

Ich bekomme bei dem Versuch die Datei einem anderen Besitzer zuzuweisen folgende Exception:

Fehlermeldung:
System.InvalidOperationException: Die Sicherheits-ID darf nicht der Besitzer dieses Objekts sein.

@Abt: Kann ich diese TakeOwnershipPermission denn irgendwo vielleicht noch setzen?

Mein Programm sieht nun folgendermaßen aus:


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Security.AccessControl;


namespace set_acls
{
    class Program
    {
        static void Main(string[] args)
        {
           const string FILE = @"c:\temp\test.txt";

            try
            {

                //string username = System.Security.Principal.Window


                // aktuellen Besitzer einer Datei auslesen
                var fs = File.GetAccessControl(FILE);

                var sid = fs.GetOwner(typeof(SecurityIdentifier));
                Console.WriteLine(sid);

                var ntAccount = sid.Translate(typeof(NTAccount));
                Console.WriteLine(ntAccount);



                // neuen Besitzer einer Datei festlegen
                var NTAccount = new NTAccount("Developer-PC","test");

                var FileSecurity = new FileSecurity();
                FileSecurity.SetOwner(NTAccount);
                FileSecurity.AddAccessRule(new FileSystemAccessRule(NTAccount, FileSystemRights.FullControl, AccessControlType.Allow));

                // fs.SetOwner(NTAccount);
                File.SetAccessControl(FILE, FileSecurity);

                Console.WriteLine("Besitzer erfolgreich geändert");


                Console.ReadLine();
    

            }
            catch (Exception e) {

                //Win32Exception w32exp = new Win32Exception();
                //Console.WriteLine(w32exp);

                /*
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                */

                Console.WriteLine(e);
                Console.ReadLine();
                
            }



        }
    }
}


Und die Manifestdatei so:



<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC-Manifestoptionen
          Wenn Sie die Zugangsebene für das Windows-Benutzerkonto ändern möchten, ersetzen Sie den 
          requestedExecutionLevel-Knoten durch eines der folgenden Elemente.

        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

            Durch Angeben des requestedExecutionLevel-Knotens wird die Datei- und Registrierungsvirtualisierung deaktiviert.
            Wenn Sie Datei- und Registrierungsvirtualisierung für Abwärts- 
            kompatibilität verwenden möchten, löschen Sie den requestedExecutionLevel-Knoten.
        -->
        <!--requestedExecutionLevel level="asInvoker" uiAccess="false" /-->
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>

  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!-- Eine Liste aller Windows-Versionen, mit denen die Anwendung kompatibel ist. 
      Windows wählt automatisch die am stärksten kompatible Umgebung aus.-->

      <!-- Wenn die Anwendung mit Windows Vista kompatibel ist, heben Sie die Auskommentierung des folgenden supportedOS-Knotens auf-->
      <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>-->

      <!-- Wenn die Anwendung mit Windows 7 kompatibel ist, heben Sie die Kommentierung des folgenden supportedOS-Knotens auf.-->
      <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->

      <!-- Wenn die Anwendung mit Windows 8 kompatibel ist, heben Sie die Auskommentierung des folgenden supportedOS-Knotens auf-->
      <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>-->

    </application>
  </compatibility>

  <!-- Designs für allgemeine Windows-Steuerelemente und -Dialogfelder (Windows XP und höher) aktivieren -->
  <!-- <dependency>
    <dependentAssembly>
      <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="*"
          publicKeyToken="6595b64144ccf1df"
          language="*"
        />
    </dependentAssembly>
  </dependency>-->

</asmv1:assembly>

Jedoch hat sich leider an dem Problem nichts geändert

16.832 Beiträge seit 2008
vor 11 Jahren

Versuchst Du den Owner einem User zuzuweisen, der gar kein Admin ist? DDas dürfte nicht funktionieren.

Hast Du nach der Fehlermeldung mal gegoogelt? Dann hättest Du das sicherlich auch herausgefunden.
Die englische Fehlermeldung, mit der man bestimmt mehr findet, müsste > Fehlermeldung:

The security identifier is not allowed to be the owner of this object lauten.

Ansonsten sagt die Fehlermeldung eben auch aus, dass Dir oder dem User die Privileges fehlen. Zum Thema TakeOwnership spuckt die MSDN folgendes aus: Taking Object Ownership
Daran kannst Du Dich ja orientieren und schauen, obs was identisches in C# gibt.

49.485 Beiträge seit 2005
vor 11 Jahren

Hallo zusammen,

ich bin bisher davon ausgegangen, dass man als Administrator zwar den Besitz einer Datei übernehmen kann (als Administrator selbst oder als Admingruppe), aber den Besitz nicht verschenken kann.

Das hat aus meiner Sicht den Zweck, dass ein Admin nicht einfach den Besitz einer Datei, auf die er keine Zugriffsrechte hat, übernehmen kann, sich als (nunmehriger) Besitzer der Datei die nötigen Zugriffsrechte gibt, die Datei einsieht oder kopiert oder was auch immer man machen will, dann die Zugriffsrechte wieder entfernt und die Datei wieder dem ursprünglichen Besitzer schenkt, ohne dass der eine Chance hat, von den Vorgängen etwas zu merken. Wenn er den Besitz nicht zurückgeben kann, bleibt immer ein Spur seines Tuns.

Es sollte aber möglich sein, einem bestimmten Benutzer das Recht zu geben, den Besitz zu übernehmen, so dass der Benutzer diese Aktion selbst ausführen kann.

herbivore

P
Piep000r Themenstarter:in
11 Beiträge seit 2012
vor 11 Jahren

Naja, mit icacls beispielsweise könnte man das machen. Lässt man dies als Admin laufen, kann man jedem beliebigen Benutzer die Datei zuweisen wie man lustig ist.

Ich wollte nur sehr ungerne den Weg gehen icacls über eine c# Anwendung anzustoßen. Das fand ich persönlich ein bisschen unschön.

16.832 Beiträge seit 2008
vor 11 Jahren

Es ist eine Sicherheitsvorkehrung, dass man Besitzrechte nicht an Nicht-Admins versetzen kann. Steht auch so in der Privileges-Beschreibung.
Zumindest über WMI kann man auch das TokenPrivlege verteilen, das sodas der Benutzer (wohl) den Besitzstatus annehmen kann. Heißt irgendwas mit SE_TAKE_OWNERSHIP_PRIVLEGE oder sowas.