Windows SetOwner mit C-Sharp

Aus MyWiki
Version vom 19. März 2013, 16:23 Uhr von Rueling (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „<u></u> Windows erlaubt es nicht, den Besitzer einer Datei oder eines Verzeichnisses auf einen anderen Benutzer zu setzen als den angemeldeten. Das betrifft zum…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

Windows erlaubt es nicht, den Besitzer einer Datei oder eines Verzeichnisses auf einen anderen Benutzer zu setzen als den angemeldeten. Das betrifft zumindest Powershell und C# Programme. Per Explorer-GUI funktioniert es.

Die Fehlermeldung die beim Versuch den Besitzer zu setzen kommt, lautet:
"Die Sicherheits-ID darf nicht der Besitzer dieses Objekts sein"
bzw. "The security identifier is not allowed to be the owner of this object"

Wenn ich es richtig gelesen habe, wird dafür die Berechtigung "Restore files and directories" benötigt

im Internet auf der folgenden Seite habe ich ein Code-Beispiel gefunden, mit dem die Berechtigung während der Laufzeit gesetzt wird.
Damit ist es möglich die SetOwner Funktion aufzurufen
Der Code stammt von: http://blog.salamandersoft.co.uk/index.php/2009/10/setting-the-owner-of-files-and-directories-in-c

Der Code wird ausgeführt mit: EnablePriviledge.GiveRestorePrivilege(); 
Die erstellte Anwendung muss trotzdem mit Admin-Rechten ausgeführt werden

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace CreateHomeDirs
{
    sealed class EnablePriviledge
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        // Use this signature if you do not want the previous state
        [DllImport("advapi32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool AdjustTokenPrivileges(IntPtr tokenHandle,
            [MarshalAs(UnmanagedType.Bool)]bool disableAllPrivileges,
            ref TOKEN_PRIVILEGES newState,
            UInt32 bufferLength,
            IntPtr previousState,
            IntPtr returnLength);

        [DllImport("kernel32.dll", ExactSpelling = true)]
        static extern IntPtr GetCurrentProcess();

        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        static extern bool OpenProcessToken
            (IntPtr processHandle, int desiredAccess, ref IntPtr phtok);

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool LookupPrivilegeValue
                (string host, string name, ref LUID lpLuid);

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        struct TOKEN_PRIVILEGES
        {
            public UInt32 PrivilegeCount;
            public LUID Luid;
            public UInt32 Attributes;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID
        {
            public uint LowPart;
            public int HighPart;
        }

        const int SE_PRIVILEGE_ENABLED = 0x00000002;
        const int TOKEN_QUERY = 0x00000008;
        const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
        //http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
        const string SE_RESTORE_PRIVILEGE = "SeRestorePrivilege";

        public static void GiveRestorePrivilege()
        {
            TOKEN_PRIVILEGES tokenPrivileges;
            tokenPrivileges.PrivilegeCount = 1;
            tokenPrivileges.Luid = new LUID();
            tokenPrivileges.Attributes = SE_PRIVILEGE_ENABLED;

            IntPtr tokenHandle = RetrieveProcessToken();

            try
            {
                bool success = LookupPrivilegeValue
                            (null, SE_RESTORE_PRIVILEGE, ref tokenPrivileges.Luid);
                if (success == false)
                {
                    int lastError = Marshal.GetLastWin32Error();
                    throw new Exception(
                        string.Format("Could not find privilege {0}. Error {1}",
                                            SE_RESTORE_PRIVILEGE, lastError));
                }

                success = AdjustTokenPrivileges(
                                                    tokenHandle, false,
                                                    ref tokenPrivileges, 0,
                                                    IntPtr.Zero, IntPtr.Zero);
                if (success == false)
                {
                    int lastError = Marshal.GetLastWin32Error();
                    throw new Exception(
                        string.Format("Could not assign privilege {0}. Error {1}",
                                        SE_RESTORE_PRIVILEGE, lastError));
                }
            }
            finally
            {
                CloseHandle(tokenHandle);
            }

        }

        static IntPtr RetrieveProcessToken()
        {
            IntPtr processHandle = GetCurrentProcess();
            IntPtr tokenHandle = IntPtr.Zero;
            bool success = OpenProcessToken(processHandle,
                                            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                                            ref tokenHandle);
            if (success == false)
            {
                int lastError = Marshal.GetLastWin32Error();
                throw new Exception(
                    string.Format("Could not retrieve process token. Error {0}",
                                        lastError));
            }
            return tokenHandle;
        }
    }
}