【问题标题】:.NET Folder Permission Issue.NET 文件夹权限问题
【发布时间】:2011-01-11 00:41:29
【问题描述】:

我正在制作一个尝试将数据库恢复到 sql server 的软件,但为此,我需要完全控制将托管 .mdf 和 .ldf 文件的文件夹,我正在使用 System.Security.AccessControl课程让每个人都可以完全控制,但它不起作用! 我只是不知道它为什么会发生...该应用程序应用规则正常,但是当它到达还原数据库部分时,它会抛出一个异常,告诉我“操作系统返回错误(错误 5,访问被拒绝)”。我的代码如下:

public static void GiveDirFullPermissionEveryoneDotNet(String dir)
{
    GiveDirFullPermissionDotNet(dir, new String[] { @"TODOS", @"EVERYONE", @"BUILTIN/Users", @"Users", @"NT AUTHORITY\NETWORK SERVICE", @"NETWORK", @"Administrators", @"Administrator", @"Administradores", @"Administrador", @"SYSTEM" });
}

public static void GiveDirFullPermissionDotNet(String dir, String[] users)
{
    DirectorySecurity dirSec = Directory.GetAccessControl(dir);
    FileSystemAccessRule fsar;

    foreach (String userAtual in users)
    {
        try
        {
            fsar = new FileSystemAccessRule(userAtual
                                          , FileSystemRights.FullControl
                                          , InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit
                                          , PropagationFlags.InheritOnly
                                          , AccessControlType.Allow);
            dirSec.AddAccessRule(fsar);
        }
        catch (Exception)
        {
            continue;
        }
    }

    Directory.SetAccessControl(dir, dirSec);
}

我尝试了 shell 方式,使用“CACLS.EXE”,但某些 Windows 版本使用“ICACLS.EXE”(感谢 Microsoft 为我们开发人员提供可移植性的优秀人才!)。所以我真的很想用 .NET 的方式来做,请帮忙。

编辑:

我将在此处发布我的 RestoreDatabase 方法,在“sqlRestore.SqlRestore(sqlServer);”处引发异常线

public void RestoreDatabase(string databaseName,
                            string filePath,
                            string serverName,
                            string userName,
                            string password,
                            string dataFilePath,
                            string logFilePath)
{
    //! Classe de restauração do SQL server
    Restore sqlRestore = new Restore();

    //! adicionando o arquivo indicado ao Restore
    BackupDeviceItem deviceItem = new BackupDeviceItem(filePath, DeviceType.File);
    sqlRestore.Devices.Add(deviceItem);
    sqlRestore.Database = databaseName;

    ServerConnection connection;

    //! Se passou string vazia no usuário, tenta Windows Authentication
    if (userName == "")
    {
        SqlConnection sqlCon = new SqlConnection(@"Data Source=" + serverName + @"; Integrated Security=True;");
        connection = new ServerConnection(sqlCon);
    }
    //! Se passou login de usuário, tenta Server Autentication
    else
        connection = new ServerConnection(serverName, userName, password);


    Server sqlServer = new Server(connection);

    Database db = sqlServer.Databases[databaseName];
    sqlRestore.Action = RestoreActionType.Database;
    string dataFileLocation = dataFilePath + databaseName + ".mdf";
    string logFileLocation = logFilePath + databaseName + "_Log.ldf";
    db = sqlServer.Databases[databaseName];
    RelocateFile rf = new RelocateFile(databaseName, dataFileLocation);

    sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFileLocation));
    sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFileLocation));
    sqlRestore.ReplaceDatabase = true;
    sqlRestore.Complete += new ServerMessageEventHandler(sqlRestoreComplete);
    sqlRestore.PercentCompleteNotification = 10;
    sqlRestore.PercentComplete += new PercentCompleteEventHandler(sqlRestorePercentComplete);

    sqlRestore.SqlRestore(sqlServer);

    db = sqlServer.Databases[databaseName];

    db.SetOnline();

    sqlServer.Refresh();
}

【问题讨论】:

  • 为什么每个人都需要访问此目录才能执行还原?如果是您在进行恢复,难道您不是唯一需要完全访问权限的人吗?您不应该已经拥有完全访问权限吗?
  • 是的!那是个大问题!为什么我作为管理员无法访问该目录?我可以在资源管理器中做任何事情,但是当我的应用程序尝试做某事时,操作系统会打我
  • 最有趣的是,我试图访问的目录是我几秒钟前在同一个应用程序中创建的!
  • 这是一个蹩脚的问题,但是您在尝试还原之前是否停止了 SQL Server 服务?
  • 如果你想解决这个问题,你必须删除你的 try/catch 块。

标签: c# sql-server security permissions


【解决方案1】:

我的钱不是 .Net 问题,而是 SQL Server 的问题...

这是我的猜测(来自here

http://www.fmsinc.com/freE/NewTips/SQL/SQLtip9.asp

虽然只显示本地设备 Enterprise Manager 的备份/恢复 对话框,有一种方法可以创建或 恢复 SQL Server 数据库备份 在网络文件共享上。创建或 恢复数据库备份 网络文件共享需要 以下先决条件:

1) SQL Server 服务,在 包含 SQL 实例的服务器 服务器,必须运行在 域级帐户(例如域 管理员帐户)。这是 通过更改“登录”来完成 命名服务的属性 “MSSQLSERVER”和“SQLSERVERAGENT” 运行 SQL Server 的服务器(不是 您的本地实例)。当你有 完成更改登录 这 2 项服务的信息,您 将需要重新启动“MSSQLSERVER” 该服务器上的服务。请注意,这 将询问您是否要重新启动 “SQLSERVERAGENT”以及 - 答案: 是的。

2) SQL Server 服务帐户必须 对文件拥有完全控制权 系统文件夹和共享。那 意味着你需要一个共享的 登录帐户所在的位置 您在 1(上面)中指定的已满 控制权。

3) 文件共享应该只 通过 UNC 名称访问。映射驱动器 可能不会始终可见 SQL 服务。

4) 你不能指定路径 使用浏览省略号 (...)。你 必须输入完全限定的路径

【讨论】:

  • sqlservr.exe 在 NETWORK SERVICE 用户下运行,sqlwriter.exe 在 SYSTEM 用户下运行,正如您在我的代码中看到的,两者都获得完全控制权限
  • 1) 在上面回答 2) 在上面回答 3) 它不是映射驱动器,它只是 c:\program files\myApp 文件夹 4) 我给出了文件夹的完整/绝对路径," C:\program files\myapp",而不是 %programfiles% neiter 任何关系路径...
【解决方案2】:

我刚刚自己找到了答案……

在我的方法“RestoreDatabase”中,当我在“Restore”类中设置“RelocateFile”实例时,我是说 sql server 将 .mdf 和 .ldf 文件移动到我指向的新文件夹中,直到现在听起来不错,因为我向将接收文件的文件夹中的每个人授予完全权限。

但这就是问题开始的地方:SQL Server 在其默认数据文件夹中创建 .mdf 和 .ldf 文件,使用它自己的用户(这个用户可以完全控制 SQL 的默认数据文件夹)但是(再次)当他移动恢复完成后的文件,他使用另一个用户,并且该用户必须对 SQL 的默认数据文件夹具有权限。如果此用户没有所需的权限会怎样?答案是:“正是发生在我身上的事情:'操作系统返回错误(错误 5,访问被拒绝)'”。

为了解决这个问题,我登录到 SQL 服务器,查询 SQL 默认数据文件夹位置并对其设置完全控制。之后,一切顺利=]

希望这能帮助遇到同样问题的人! 感谢所有试图提供帮助的人!

【讨论】:

    【解决方案3】:

    我已经测试了您的代码“RestoreDatabase”,没有对我的计算机上的权限进行任何修改,它适用于我。 视觉工作室 2008 SP1, SQL 2008 速成版 SP1, Windows 7 x64。

    希望对你有帮助。

    【讨论】:

    • 我的是 VS2008 SP1、SQL 2005 Express、Win7 x64...但是当我在其他虚拟机上测试时也会出现同样的问题...
    • 可能取决于数据库结构?尝试创建、备份和恢复一些测试数据库。
    猜你喜欢
    • 2011-09-17
    • 2011-11-14
    • 2012-08-27
    • 2018-04-08
    • 2016-09-21
    • 1970-01-01
    • 2017-07-04
    • 2019-03-19
    • 2011-12-14
    相关资源
    最近更新 更多