【问题标题】:Getting execute permission to xp_cmdshell获取 xp_cmdshell 的执行权限
【发布时间】:2010-01-06 22:13:51
【问题描述】:

我在尝试从存储过程中执行 xp_cmdshell 时看到一条错误消息。

xp_cmdshell 已在实例上启用。并且已向我的用户授予了执行权限,但我仍然看到异常。

对象“xp_cmdshell”、数据库“mssqlsystemresource”、模式“sys”的执行权限被拒绝

部分问题在于这是一个共享集群,并且我们在实例上只有一个数据库,因此我们没有完整的管理员权限。所以我无法进入并授予权限,等等。

【问题讨论】:

  • 你为什么要使用有史以来最危险的存储过程? (xp_cmdshell)
  • 这是旧代码,目前没有时间重写。我们使用它来调用 BCP 将文件导入临时表进行处理。临时表是动态sql,我们根据动态sql使用的相同逻辑生成.fmt文件。重新实现这一点需要一天多的时间。
  • 您能否发布确切的 SQL Server 版本号,包括内部版本号?
  • SQLServer 2005,9.00.3042.00,企业版,64 位
  • 是否可以在您的系统上运行此查询并发布返回的日期? select expiry_date from master.sys.certificates where name = '##MS_SQLResourceSigningCertificate##'

标签: sql-server database xp-cmdshell


【解决方案1】:

对于不是 SQL Server 实例上 sysadmin 角色成员的用户,您需要执行以下操作来授予对 xp_cmdshell 扩展存储过程的访问权限。此外,如果您忘记了其中一个步骤,我列出了将引发的错误。

  1. 启用 xp_cmdshell 过程

    消息 15281,级别 16,状态 1,过程 xp_cmdshell,第 1 行 SQL Server 阻止了对组件“xp_cmdshell”的过程“sys.xp_cmdshell”的访问,因为该组件作为该服务器安全配置的一部分被关闭。系统管理员可以使用 sp_configure 启用“xp_cmdshell”的使用。有关启用“xp_cmdshell”的详细信息,请参阅 SQL Server 联机丛书中的“表面区域配置”。*

  2. 为对 master 数据库具有公共访问权限的非系统管理员用户创建登录名

    消息 229,级别 14,状态 5,过程 xp_cmdshell,第 1 行 对象“xp_cmdshell”、数据库“mssqlsystemresource”、架构“sys”的执行权限被拒绝。*

  3. 授予 xp_cmdshell 存储过程的 EXEC 权限

    消息 229,级别 14,状态 5,过程 xp_cmdshell,第 1 行 对象“xp_cmdshell”、数据库“mssqlsystemresource”、架构“sys”的执行权限被拒绝。*

  4. 使用 sp_xp_cmdshell_proxy_account 创建 xp_cmdshell 将在其下运行的代理帐户

    消息 15153,级别 16,状态 1,过程 xp_cmdshell,第 1 行 xp_cmdshell 代理帐户信息无法检索或无效。验证“##xp_cmdshell_proxy_account##”凭据是否存在并包含有效信息。*

从您的错误看来,第 2 步或第 3 步被遗漏了。我不熟悉集群,不知道该设置是否有什么特别之处。

【讨论】:

  • 对于 SQL Server 2008 R2 实例,我不需要第 4 步。
  • 如下面提到的几次,但在高分答案下在这里重复... 让用户作为批处理作业登录:打开本地安全策略 -> 本地策略 -> 用户权限分配。将用户添加到“作为批处理作业登录”
【解决方案2】:

我想完成tchester的回答。

(1) 启用 xp_cmdshell 程序:

-- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO

-- Enable the xp_cmdshell procedure
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE
GO

(2) 为对 master 数据库具有公共访问权限的非 sysadmin 用户创建登录 'Domain\TestUser'(windows 用户)

(3) 授予 xp_cmdshell 存储过程的 EXEC 权限:

GRANT EXECUTE ON xp_cmdshell TO [Domain\TestUser]

(4) 使用 sp_xp_cmdshell_proxy_account 创建 xp_cmdshell 将在其下运行的代理帐户

EXEC sp_xp_cmdshell_proxy_account 'Domain\TestUser', 'pwd'
-- Note: pwd means windows password for [Domain\TestUser] account id on the box.
--       Don't include square brackets around Domain\TestUser.

(5) 授予用户控制服务器权限

USE master;
GRANT CONTROL SERVER TO [Domain\TestUser]
GO

【讨论】:

  • Doesn GRANT CONTROL SERVER TO [Domain\TestUser] 有效地赋予该用户系统管理员权限?我认为整个想法是最小化该用户的权限?
  • 当我读到这篇文章时,我认为非系统管理员用户必须是 Windows 帐户并且也是代理帐户。不对。代理帐户需要是 windows。然后任何非系统管理员用户都需要对 master 的公共访问权限和 xp_cmdshell 上的执行权限
  • 在我的情况下,步骤 4 完全没有必要!
  • 如果运行第 4 步时出现此错误:Msg 15137, Level 16, State 1, Procedure sp_xp_cmdshell_proxy_account, Line 1 执行 sp_xp_cmdshell_proxy_account 期间发生错误。可能的原因:提供的帐户无效或无法创建“##xp_cmdshell_proxy_account##”凭据。错误代码:“5”以管理员权限打开 SQL Server Management Studio。归功于:dbamohsin.wordpress.com/2017/02/22/…
  • 正如@Colin 上面正确指出的那样,我也不会给用户CONTROL SERVER 权限。相反,您可以授予她在 Windows 中批量登录的权限,如 here 所述。在 Windows 中打开 本地安全设置,转到 本地策略 -> 用户分配 -> 作为批处理作业登录并在此处添加 Windows 帐户 [Domain\TestUser]。为我工作,没有给服务器上的域用户太多权限。
【解决方案3】:

切斯特说:

(2) 为对 master 数据库具有公共访问权限的非 sysadmin 用户创建登录

我去了我的用户的数据库列表(服务器/安全/连接/我的用户名/属性/用户映射,并想选中主数据库的框。我收到一条错误消息,告诉我用户已经存在于主数据库中数据库。转到 master 数据库,删除用户,返回“用户映射”并选中 master 框。选中下面的“public”框。

之后,您需要将 xp_cmdshell 上的授权执行重新发出到“我的用户名”

【讨论】:

    【解决方案4】:

    扩展已提供的内容,用于通过 SQL Server 代理将数据自动导出为 csv 到网络共享。

    (1) 启用 xp_cmdshell 程序:

    -- To allow advanced options to be changed.
    EXEC sp_configure 'show advanced options', 1
    RECONFIGURE
    GO
    
    -- Enable the xp_cmdshell procedure
    EXEC sp_configure 'xp_cmdshell', 1
    RECONFIGURE
    GO
    

    (2) 为对 master 数据库具有公共访问权限的非 sysadmin 用户创建登录“Domain\TestUser”(Windows 用户)。通过用户映射完成

    (3) 将登录作为批处理作业:导航到本地安全策略 -> 本地策略 -> 用户权限分配。将用户添加到“作为批处理作业登录”

    (4) 授予域\用户对网络文件夹的读/写权限

    (5) 授予 xp_cmdshell 存储过程的 EXEC 权限:

    GRANT EXECUTE ON xp_cmdshell TO [Domain\TestUser]
    

    (6) 使用 sp_xp_cmdshell_proxy_account 创建 xp_cmdshell 将在其下运行的代理帐户

    EXEC sp_xp_cmdshell_proxy_account 'Domain\TestUser', 'password_for_domain_user'
    

    (7) 如果 sp_xp_cmdshell_proxy_account 命令不起作用,请手动创建它

    create credential ##xp_cmdshell_proxy_account## with identity = 'Domain\DomainUser', secret = 'password'
    

    (8) 启用 SQL Server 代理。打开 SQL Server 配置管理器,导航到 SQL Server 服务,启用 SQL Server 代理。

    (9) 创建自动化作业。打开 SSMS,选择 SQL Server Agent,然后右键单击作业并单击“新建作业”。

    (10) 选择“所有者”作为您创建的用户。选择“步骤”,使“类型”= T-SQL。填写类似于下面的命令字段。将分隔符设置为','

    EXEC master..xp_cmdshell 'SQLCMD -q "select * from master" -o file.csv -s "," 
    

    (11) 相应地填写时间表。

    【讨论】:

      【解决方案5】:

      现在是时候贡献了。我是系统管理员角色,致力于让两个公共访问用户执行 xp_cmdshell。我可以执行 xp_cmdshell 但不能执行这两个用户。

      我做了以下步骤:

      1. 创建新角色:

        使用大师
        创建角色 [CmdShell_Executor] 授权 [dbo]
        GRANT EXEC ON xp_cmdshell TO [CmdShell_Executor]

      2. 在 master 数据库中添加用户:安全性 --> 用户。成员资格仅检查刚刚创建的 [CmdShell_Executor]

      3. 设置代理帐户:

        EXEC sp_xp_cmdshell_proxy_account 'domain\user1','users1 Windows 密码'
        EXEC sp_xp_cmdshell_proxy_account 'domain\user2','users2 Windows 密码'

      然后两个用户都可以执行包含 xp_cmdshell 调用 R 脚本运行的存储过程。我让用户来我的电脑输入密码,执行一行代码,然后删除密码。

      【讨论】:

        【解决方案6】:

        不要将控制权授予用户,这是完全没有必要的。 选择数据库的权限就足够了。 在 master 上创建登录名和用户后(请参阅上面的答案):

        use YourDatabase
        go
        create user [YourDomain\YourUser] for login [YourDomain\YourUser] with default_schema=[dbo]
        go
        alter role [db_datareader] add member [YourDomain\YourUser]
        go
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-17
          • 1970-01-01
          相关资源
          最近更新 更多