如何使用 P/Invoke 复制文件/目录权限?

发布于 2024-11-19 15:28:43 字数 179 浏览 4 评论 0原文

我花了几个小时寻找解决方案,但文档很少,我无法找到我需要的内容。

如果我有一个文件或目录,我如何在 C# 中使用 P/Invoke 将权限(即所有者和 SID 及其权限)从一个文件复制到另一个文件或从一个目录复制到另一个目录,假设这些文件和目录是在同一台计算机上还是在同一 Active Directory 服务器控制的网络上?

I'm searching for the solution for hours, but the documentation being sparse, I'm unable to find what I need.

If I have a file or a directory, how can I, in C# with P/Invoke, duplicate the permissions (ie. the owner and SIDs with their permissions) from one file to another or from one directory to another, assuming that those files and directories are either on the same machine or the network controlled by the same Active Directory server?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枕梦 2024-11-26 15:28:43

以下是使用 GetNamedSecurityInfo和
SetNamedSecurityInfo

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.AccessControl;

namespace PermissionsExample
{
    class Program
    {
        static void Main(string[] args)
        {
            string source = "C:\\source.txt";
            string dest = "C:\\dest.txt";

            string result = CopyPermissions(source, dest);
            if (!string.IsNullOrEmpty(result)) { Console.WriteLine(result); }
            else { Console.WriteLine("SUCCESS"); }
        }

        public static string CopyPermissions(string source_file, string dest_file)
        {
            string errmsg = string.Empty;
            IntPtr sidOwner = IntPtr.Zero;
            IntPtr sidOwnerDescriptor = IntPtr.Zero;
            IntPtr sidGroup = IntPtr.Zero;
            IntPtr sidGroupDescriptor = IntPtr.Zero;
            IntPtr dacl = IntPtr.Zero;
            IntPtr daclDescriptor = IntPtr.Zero;
            IntPtr sacl = IntPtr.Zero;
            try
            {
                int result = GetNamedSecurityInfo(source_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfos.DiscretionaryAcl, out sidOwner, out sidGroup, out dacl, out sacl, out daclDescriptor);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }
                result = GetNamedSecurityInfo(source_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfos.Owner, out sidOwner, out sidGroup, out dacl, out sacl, out sidGroupDescriptor);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }

                result = GetNamedSecurityInfo(source_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfos.Group, out sidOwner, out sidGroup, out dacl, out sacl, out sidGroupDescriptor);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }

                SecurityInfos info = SecurityInfos.DiscretionaryAcl | SecurityInfos.Group | SecurityInfos.Owner;
                result = SetNamedSecurityInfo(dest_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, info, sidOwner, sidGroup, dacl, sacl);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }
            }
            finally
            {
                if (sidOwnerDescriptor != IntPtr.Zero && LocalFree(sidOwnerDescriptor) != IntPtr.Zero)
                {
                    int err = Marshal.GetLastWin32Error();
                    Win32Exception e = new Win32Exception(err);
                    errmsg += "ERROR: " + e.Message;
                }
                if (sidGroupDescriptor != IntPtr.Zero && LocalFree(sidGroupDescriptor) != IntPtr.Zero)
                {
                    int err = Marshal.GetLastWin32Error();
                    Win32Exception e = new Win32Exception(err);
                    errmsg += "ERROR: " + e.Message;
                }
                if (daclDescriptor != IntPtr.Zero && LocalFree(daclDescriptor) != IntPtr.Zero)
                {
                    int err = Marshal.GetLastWin32Error();
                    Win32Exception e = new Win32Exception(err);
                    errmsg += "ERROR: " + e.Message;
                }
            }

            return errmsg;
        }

        public enum SE_OBJECT_TYPE
        {
            SE_UNKNOWN_OBJECT_TYPE = 0,
            SE_FILE_OBJECT,
            SE_SERVICE,
            SE_PRINTER,
            SE_REGISTRY_KEY,
            SE_LMSHARE,
            SE_KERNEL_OBJECT,
            SE_WINDOW_OBJECT,
            SE_DS_OBJECT,
            SE_DS_OBJECT_ALL,
            SE_PROVIDER_DEFINED_OBJECT,
            SE_WMIGUID_OBJECT,
            SE_REGISTRY_WOW64_32KEY
        }

        [DllImport("advapi32.dll", EntryPoint = "GetNamedSecurityInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)]
        private static extern int GetNamedSecurityInfo(string objectName, SE_OBJECT_TYPE objectType,
            System.Security.AccessControl.SecurityInfos securityInfo, out IntPtr sidOwner,
            out IntPtr sidGroup, out IntPtr dacl, out IntPtr sacl, out IntPtr securityDescriptor);

        [DllImport("advapi32.dll", EntryPoint = "SetNamedSecurityInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)]
        private static extern int SetNamedSecurityInfo(string objectName, SE_OBJECT_TYPE objectType,
            System.Security.AccessControl.SecurityInfos securityInfo, IntPtr sidOwner,
            IntPtr sidGroup, IntPtr dacl, IntPtr sacl);

        [DllImport("kernel32.dll", EntryPoint = "LocalFree", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern IntPtr LocalFree(IntPtr hMem);
    }
}

Here's an example using GetNamedSecurityInfo and
SetNamedSecurityInfo.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.AccessControl;

namespace PermissionsExample
{
    class Program
    {
        static void Main(string[] args)
        {
            string source = "C:\\source.txt";
            string dest = "C:\\dest.txt";

            string result = CopyPermissions(source, dest);
            if (!string.IsNullOrEmpty(result)) { Console.WriteLine(result); }
            else { Console.WriteLine("SUCCESS"); }
        }

        public static string CopyPermissions(string source_file, string dest_file)
        {
            string errmsg = string.Empty;
            IntPtr sidOwner = IntPtr.Zero;
            IntPtr sidOwnerDescriptor = IntPtr.Zero;
            IntPtr sidGroup = IntPtr.Zero;
            IntPtr sidGroupDescriptor = IntPtr.Zero;
            IntPtr dacl = IntPtr.Zero;
            IntPtr daclDescriptor = IntPtr.Zero;
            IntPtr sacl = IntPtr.Zero;
            try
            {
                int result = GetNamedSecurityInfo(source_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfos.DiscretionaryAcl, out sidOwner, out sidGroup, out dacl, out sacl, out daclDescriptor);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }
                result = GetNamedSecurityInfo(source_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfos.Owner, out sidOwner, out sidGroup, out dacl, out sacl, out sidGroupDescriptor);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }

                result = GetNamedSecurityInfo(source_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfos.Group, out sidOwner, out sidGroup, out dacl, out sacl, out sidGroupDescriptor);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }

                SecurityInfos info = SecurityInfos.DiscretionaryAcl | SecurityInfos.Group | SecurityInfos.Owner;
                result = SetNamedSecurityInfo(dest_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, info, sidOwner, sidGroup, dacl, sacl);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }
            }
            finally
            {
                if (sidOwnerDescriptor != IntPtr.Zero && LocalFree(sidOwnerDescriptor) != IntPtr.Zero)
                {
                    int err = Marshal.GetLastWin32Error();
                    Win32Exception e = new Win32Exception(err);
                    errmsg += "ERROR: " + e.Message;
                }
                if (sidGroupDescriptor != IntPtr.Zero && LocalFree(sidGroupDescriptor) != IntPtr.Zero)
                {
                    int err = Marshal.GetLastWin32Error();
                    Win32Exception e = new Win32Exception(err);
                    errmsg += "ERROR: " + e.Message;
                }
                if (daclDescriptor != IntPtr.Zero && LocalFree(daclDescriptor) != IntPtr.Zero)
                {
                    int err = Marshal.GetLastWin32Error();
                    Win32Exception e = new Win32Exception(err);
                    errmsg += "ERROR: " + e.Message;
                }
            }

            return errmsg;
        }

        public enum SE_OBJECT_TYPE
        {
            SE_UNKNOWN_OBJECT_TYPE = 0,
            SE_FILE_OBJECT,
            SE_SERVICE,
            SE_PRINTER,
            SE_REGISTRY_KEY,
            SE_LMSHARE,
            SE_KERNEL_OBJECT,
            SE_WINDOW_OBJECT,
            SE_DS_OBJECT,
            SE_DS_OBJECT_ALL,
            SE_PROVIDER_DEFINED_OBJECT,
            SE_WMIGUID_OBJECT,
            SE_REGISTRY_WOW64_32KEY
        }

        [DllImport("advapi32.dll", EntryPoint = "GetNamedSecurityInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)]
        private static extern int GetNamedSecurityInfo(string objectName, SE_OBJECT_TYPE objectType,
            System.Security.AccessControl.SecurityInfos securityInfo, out IntPtr sidOwner,
            out IntPtr sidGroup, out IntPtr dacl, out IntPtr sacl, out IntPtr securityDescriptor);

        [DllImport("advapi32.dll", EntryPoint = "SetNamedSecurityInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)]
        private static extern int SetNamedSecurityInfo(string objectName, SE_OBJECT_TYPE objectType,
            System.Security.AccessControl.SecurityInfos securityInfo, IntPtr sidOwner,
            IntPtr sidGroup, IntPtr dacl, IntPtr sacl);

        [DllImport("kernel32.dll", EntryPoint = "LocalFree", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern IntPtr LocalFree(IntPtr hMem);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文