AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 199237
Accepted
McNets
McNets
Asked: 2018-03-03 07:59:51 +0800 CST2018-03-03 07:59:51 +0800 CST 2018-03-03 07:59:51 +0800 CST

网络共享上的 SQL Server 服务权限取决于 IntegratedSecurity=true/false

  • 772

我们公司从我们的一位客户那里收到一份每日文件。它是一个翻译成 XML 并从 SFTP 服务器下载的 EDIFACT 文件。

我们开发了一个(c# 控制台)应用程序:

  1. 下载文件。
  2. 使用存储过程将其上传到一台 SQL Server (2005)。
  3. 从网络共享中删除此文件。
  4. 运行另一个存储过程以将其与我们的销售订单表集成。

SQL-Server 和 SQL-Server 代理服务作为LocalSystem帐户启动。(它很快就会被替换,我宁愿让它保持原样,我知道它没有正确配置。)

将文件存储在我们的 SQL-Server 中的过程与此类似:

CREATE PROCEDURE [dbo].[sp_ProviderName_Download]
(
    -- FQN of XML file
    @file_name nvarchar(260)
)
AS
BEGIN

    DECLARE @xml_data XML,
            @cmd nvarchar(max);

    BEGIN TRY

        SET @cmd = 'SELECT @xmlText = BulkColumn FROM OPENROWSET(BULK '
                    + '''' + @file_name + ''''
                    + ', SINGLE_BLOB) x;';

        EXEC sp_executesql @cmd, N'@xmlText XML OUTPUT', @xmlText = @xml_data OUTPUT;

        INSERT INTO [dbo].[ProviderXML_Register] (..., xml_data)
        VALUES (..., @xml_data);

        RETURN 0;

    END TRY
    BEGIN CATCH

        EXEC [dbo].[vsp_error_handler];
        RETURN -1;

    END CATCH

END

问题:

存储过程的工作方式取决于我们在 C# 应用程序中设置 ConnectionString 的方式。

如果它使用 IntegratedSecurity=false:

this.scsb = new SqlConnectionStringBuilder();
this.scsb.ApplicationName = "ProviderXML_Download";
this.scsb.WorkstationID = Environment.MachineName;
this.scsb.DataSource = "xxx.xxx.xxx.xxx";
this.scsb.InitialCatalog = "my_db";
this.scsb.IntegratedSecurity = false;
this.scsb.Password = "*******";
this.scsb.UserID = "SqlServerLogin";

它可以正常工作而没有错误。

但如果它使用 IntegratedSecurity=true 连接(AD 用户)

this.scsb = new SqlConnectionStringBuilder();
this.scsb.ApplicationName = "ProviderXML_Download";
this.scsb.WorkstationID = Environment.MachineName;
this.scsb.DataSource = "SQL_INSTANCE_NAME";
this.scsb.InitialCatalog = "my_db";
this.scsb.IntegratedSecurity = true;

它失败并出现错误:

操作系统错误 5 访问被拒绝。

AD 用户对网络共享拥有 MODIFY 权限。据我所知,“LocalSystem”帐户不应该能够访问网络共享。

  • 为什么当 IntegratedSecurity=true 时出现此错误?
sql-server sql-server-2005
  • 1 1 个回答
  • 6569 Views

1 个回答

  • Voted
  1. Best Answer
    Solomon Rutzky
    2018-03-03T09:01:48+08:002018-03-03T09:01:48+08:00

    问题在于如何处理批量操作的安全性以及模拟的默认限制。

    使用 SQL Server 登录连接时,没有外部 Windows SID/安全上下文,因此当需要访问 SQL Server 外部(即与操作系统、网络等交互)时,SQL Server 使用服务帐户的安全上下文。因此,如果 SQL Server 服务帐户是本地系统帐户,那么它就是用于外部访问的帐户。由于您的文件在网络上,因此“本地系统”必须有权访问该网络共享。这可以通过授予服务器本身访问权限(通过为 NTFS 权限指定<domain_name>\<computer_name>$ )来实现。在这种情况下,SQL Server 进程没有使用模拟:外部访问是在进程本身的安全上下文中进行的。

    使用 Windows 登录(无论是 AD 帐户还是服务器上的本地帐户)连接到 SQL Server 时,有一个 SID 可供使用,SQL Server 将使用该 SID(指向 Windows / AD 帐户的安全 ID)进行外部访问. 这就是使用 "Integrated Security" / "Trusted_Connection" = 连接时发生的情况true。现在,使用登录到 SQL Server 的帐户的 SID 意味着 SQL Server 正在使用模拟使其网络请求看起来来自另一个 SID 而不是来自“本地系统”(请记住,服务帐户拥有sqlservr.exe进程,发出网络请求的是那个进程,而不是登录到 SQL Server 的 SID)。默认情况下,模拟被隔离到启动进程的机器上(类似于EXECUTE AS user默认情况下使用模拟通过被隔离到数据库的方式)。因此,BULK INSERT/OPENROWSET(BULK...命令应该能够在运行 SQL Server 的服务器上本地查看文件,但网络共享不是本地的,并且默认情况下模拟的安全上下文不会扩展那么远。您在这里看到的应该与臭名昭著的“双跳”问题相同。

    因此,您可以执行以下操作之一:

    1. 授予对该网络共享的权限EVERYONE

    2. 继续通过 SQL Server Login 登录,不用担心使用集成安全/可信连接。

    3. 启用“委托”,虽然我不确定这是否适用于本地系统帐户(您提到 SQL Server 代理作为“本地系统”运行,所以这就是连接到 SQL Server 的内容)。它可能需要设置一个 AD 帐户并为“委托”启用该帐户,以便它可以超越本地服务器。无论哪种方式,“委托”都是如何配置 AD 以允许帐户(甚至可能是帐户/服务组合)权限超出默认隔离区。

      PS @StrayCatDBA 提到使用网络服务帐户(即NT AUTHORITY\NETWORK SERVICE允许委派。此外,请参阅底部的“配置 Windows 服务帐户和权限”链接,因为该文档涵盖了您拥有的各种选项。

    这里的一些信息:

    • 使用 BULK INSERT 或 OPENROWSET(BULK...) 导入批量数据(安全注意事项部分;链接应直接转到那里)
    • Kerberos 约束委派概述
    • 如何将服务器配置为受信任以进行委派
    • 如何使用 SQL Server 2008 实现 Kerberos 约束委派
    • 配置 Windows 服务帐户和权限
    • 4

相关问题

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

  • 从 SQL Server 2008 降级到 2005

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve