3

SQL Server 2012文件流一起使用。考虑这个SQL脚本:

CREATE DATABASE [Test]
GO

ALTER DATABASE [Test] ADD FILEGROUP [FileStream] CONTAINS FILESTREAM
GO

ALTER DATABASE [Test] ADD FILE (
    NAME = 'Test_FileStream',
    FILENAME = 'C:\Data')
    TO FILEGROUP [FileStream]
GO

显然,该C:\Data文件夹是由SQL Server. 因此,此文件夹的所有者是 SQL Server 帐户(通常是MSSQL$SQLEXPRESS)。我的软件需要通过文件系统直接读取NTFS文件流,因此我将FilestreamEffectiveLevel值设置为 3。因此,SQL Server需要写入文件流数据的权限(显然),客户端需要读取文件流数据的权限。

客户端将使用SqlFileStream读取数据:

using (var transaction = new TransactionScope())
{
    var fileStreamData = GetFileStreamData();
    using (var stream = new SqlFileStream(
        fileStreamData.FilePath,
        fileStreamData.TransactionContext,
        FileAccess.Read,
        FileOptions.SequentialScan,
        0))
    {
        var data = new byte[stream.Length];
        stream.Read(data, 0, data.Length);
    }
}

由于我的普通用户需要对文件流数据的读取权限,因此C:\Data普通用户必须可以读取该文件夹。我可以通过右键单击文件夹、提升并添加必要的读取权限来手动解决此问题。

问题是我不想要这个手动步骤!当我CreateDatabase()在我的C#代码中运行时,我希望一切都正确配置。我尝试了这段代码,但它抛出了一个UnauthorizedAccessException

var di = new DirectoryInfo(@"C:\Data");
var ds = di.GetAccessControl();
ds.AddAccessRule(new FileSystemAccessRule(
    @"Everyone",
    FileSystemRights.Read,
    AccessControlType.Allow));
di.SetAccessControl(ds);

是的,如果我运行我的软件提升它工作。问题是上面的代码需要在单元测试中运行。在这种情况下,提升 Visual Studio 将使单元测试的结果变得毫无用处!我确实使用impersonation以管理员身份运行我的测试,但没有提升。

概括

  • SQL Server为文件流数据创建一个目录。
  • 普通用户无法读取该目录。
  • 普通用户需要对该目录的读取权限。
  • 读取权限需要以编程方式从Unit Test.
  • 单元测试以管理员身份运行,但出于明显的原因未提升。

问题

我怎么知道SQL Server授予某些组/用户对新创建的文件流目录的读取权限?

我能想到几个想法:

  1. 使用某种T-SQL不需要提升的权限来更改权限。
  2. xp_cmdshell无需提升即可使用更改权限。
  3. 运行C#代码SQL Server更改权限。再次,没有海拔。

我确定SQL Server有能力设置权限,因为它实际上拥有该对象。

4

1 回答 1

1

据我所知,SQL Server 没有公开使用 T-SQL 更改存储文件流数据的目录权限的能力。由于 SQL Server 拥有该目录,因此此功能是可能的,但它似乎不存在。

您的 C# 代码无法在没有提升的情况下更新文件权限的原因是您的用户帐户既不拥有该目录,也没有被授予对它的“更改权限”权限。Administrators 组确实可以更改权限,但您必须提升权限才能使用该组成员资格。同样,除非您想禁用 UAC(不推荐)或弄乱本地安全策略(非常不推荐),否则您无法解决此问题。

因此,选项 2 听起来是您的最佳选择。xp_cmdshell会将您的命令作为拥有该目录的 SQL Server 服务帐户运行,因此它应该能够更改 ACL。您可以使用该cacls命令更改文件夹的权限。你可能想要一个类似这样的命令:

cacls "C:\Data" /e /g Users:r

    cacls      -- Change ACLs
    "C:\Data"  -- Directory to change
    /e         -- Edit the current ACL instad of replacing it
    /g Users:r -- Grant the "Users" group read-only access

另见:cacls文档xp_cmdshell文档

于 2013-03-21T20:05:27.150 回答