如何复制ntfs权限

时间:2010-06-25 13:38:24

标签: c# .net winforms security

我找到了一种将ntfs权限信息从一个现有文件夹复制到新创建的文件夹的方法 - 我不确定它是否正在做它应该做的工作。也许可以看看这个方法并给出一些评论:

private static void CopySecurityInformation(String source, String dest)
{
    FileSecurity fileSecurity = File.GetAccessControl(
        source,
        AccessControlSections.All);
    FileAttributes fileAttributes = File.GetAttributes(source);
    File.SetAccessControl(dest, fileSecurity);
    File.SetAttributes(dest, fileAttributes);
}

感谢您的帮助, 丹尼尔

2 个答案:

答案 0 :(得分:2)

我尝试遵循OP建议的模式来复制文件的ACL和属性,并在我们的应用程序中发现了一些问题。希望这些信息有助于其他人。

根据MSDN,使用上面显示的File.SetAccessControl()方法不起作用。

  

SetAccessControl方法仅保留FileSecurity对象   在创建对象后进行了修改。如果是FileSecurity对象   尚未修改,它不会被持久保存到文件中。因此,   无法从一个文件中检索FileSecurity对象   将同一个对象重新应用到另一个文件

必须为目标文件创建一个新的FileSecurity对象,并为其分配源FileSecurity对象的副本。

这是一个可以在我们的应用程序中运行的模式示例。

    public static void CopyFile(string source, string destination)
    {
        // Copy the file
        File.Copy(source, destination, true);

        // Get the source file's ACLs
        FileSecurity fileSecuritySource = File.GetAccessControl(source, AccessControlSections.All);
        string sddlSource = fileSecuritySource.GetSecurityDescriptorSddlForm(AccessControlSections.All);

        // Create the destination file's ACLs
        FileSecurity fileSecurityDestination = new FileSecurity();
        fileSecurityDestination.SetSecurityDescriptorSddlForm(sddlSource);

        // Set the destination file's ACLs
        File.SetAccessControl(destination, fileSecurityDestination);

        // copy the file attributes now
        FileAttributes fileAttributes = File.GetAttributes(source);
        File.SetAttributes(destination, fileAttributes);
    }

修复第一个问题后,我们发现未复制所有者属性。相反,在我们的例子中,目标文件由管理员拥有。要解决此问题,该流程需要启用SE_RESTORE_NAME权限。查看pinvoke.net上的AdjustTokenPrivileges以获取一个完整的Privileges类,它可以轻松设置权限。

我们必须处理的最后一件事是UAC。如果用户在UAC下运行,我们需要使用管理权限重新启动我们的应用程序。以下是我们的应用程序中的另一个示例,该示例涉及使用提升的权限重新启动应用程序。

    private static void RelaunchWithAdministratorRights(string[] args)
    {
        // Launch as administrator
        ProcessStartInfo processStartInfo = new ProcessStartInfo();
        processStartInfo.UseShellExecute = true;
        processStartInfo.WorkingDirectory = Environment.CurrentDirectory;
        string executablePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
        processStartInfo.FileName = executablePath;
        processStartInfo.Verb = "runas";

        if (args != null && args.Count() > 0)
        {
            string arguments = args[0];
            for (int i = 1; i < args.Count(); i++)
                arguments += " " + args[i];
            processStartInfo.Arguments = arguments;
        }

        try
        {
            using (Process exeProcess = Process.Start(processStartInfo))
            {
                exeProcess.WaitForExit();
            }
        }
        catch
        {
            // The user refused to allow privileges elevation. Do nothing and return directly ...
        }

        Environment.Exit(0);
    }

我们是一个控制台应用,因此我们需要将args方法中的Main参数传递给RelaunchWithAdministratorRights(args)。非控制台应用程序可以传递null。我们从RelaunchWithAdministratorRights块中调用catch,如下所示:

        try
        {
            ...
        }
        catch (SecurityException)
        {
            RelaunchWithAdministratorRights(args);
            return;
        }

在我们的应用中,我们只需在调用RelaunchWithAdministratorRights后返回,即可退出缺少权限的应用实例。根据您的应用,您可能更愿意throw出路。无论如何,从RelaunchWithAdministratorRights返回后,您不希望此实例继续处理。

享受!

答案 1 :(得分:1)

它不仅仅是复制NTFS权限。它还复制文件的属性。我不确定它是否复制了继承权限,但是运行一次,你应该能够找到它。

请注意,复制权限本身需要特殊权限(管理员当然也有这些权限),请确保运行此方法的进程具有查询,查看和设置这些对象的权限所需的权限。

相关问题