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 / 问题 / 201776
Accepted
VansFannel
VansFannel
Asked: 2018-03-21 02:53:04 +0800 CST2018-03-21 02:53:04 +0800 CST 2018-03-21 02:53:04 +0800 CST

从我的数据库中授予用户执行 xp_cmdshell

  • 772

我正在使用 SQL Server 2016,我需要让用户从中MyDatabase执行xp_cmdshell。我执行以下操作:

USE [MyDatabase]
GO

GRANT EXECUTE ON xp_cmdshell TO myUser
GO

myUser是来自的用户MyDatabase,当我运行上述代码时,登录为sa,我收到以下错误:

仅当当前数据库为主数据库时,才能授予对服务器范围目录视图或系统存储过程或扩展存储过程的权限。

我需要将用户添加到master数据库吗?我不认为这是安全的。

我需要这个,因为我想从存储过程中编写一个文本文件。我找到了以下文章http://www.nigelrivett.net/WriteTextFile.html,说我可以使用以下方式编写文本文件:

You will need to create the data to be output as in dynamic sql statements
The first command here creates or overwrites the file - the rest append to the file.
exec master..xp_cmdshell 'echo hello > c:\file.txt'
exec master..xp_cmdshell 'echo appended data >> c:\file.txt'
exec master..xp_cmdshell 'echo more data >> c:\file.txt'

我问这个是因为我的存储过程会生成一个大字符串 (nvarchar(max)) json,当我尝试用 C# 写下它时,我什么也没得到:既不是文件也不是异常。我曾想过在存储过程中编写 json 字符串(如果可以的话)。

存储过程正确结束,我在调试器中检查了我在输出参数 json 中得到了一些东西(我知道是因为 Visual Studio 设置没有足够的内存来显示它的内容),File.WriteAllText因为我有一个断点而运行它,而且,路径是绝对的。但也许,有些事情我忽略了,我必须再次仔细检查所有内容。

sql-server permissions
  • 2 2 个回答
  • 3169 Views

2 个回答

  • Voted
  1. Best Answer
    Dan Guzman
    2018-03-21T04:36:12+08:002018-03-21T04:36:12+08:00

    我建议您将执行 xp_cmdshell 的代码包装在用户数据库中的存储过程中,并使用具有所需权限的证书对其进行签名。这样,用户被限制在用户存储过程中,不能执行临时 xp_cmdshell 命令。操作系统权限也仅限于非系统管理员角色成员的代理帐户。此证书技术在Erland Sommarskog 的存储过程中的打包权限一文中有详细说明。

    下面是一个示例脚本。

    -- Enable xp_cmdshell and create proxy account
    USE master;
    EXEC sp_configure 'show',1;
    RECONFIGURE;
    EXEC sp_configure 'xp_cmdshell',1;
    RECONFIGURE; 
    EXEC dbo.sp_xp_cmdshell_proxy_account 'YourDomain\YourProxyAccount', 'YourPr0xy@accountPassw0rd';
    GO
    
    -- Create certificate in master.
    CREATE CERTIFICATE xp_cmdshell_cert
       ENCRYPTION BY PASSWORD = 'All you need is love'
       WITH SUBJECT = 'For xp_cmdshell privileges',
       START_DATE = '20020101', EXPIRY_DATE = '20300101';
    GO
    
    -- Create a login for the certificate.
    CREATE LOGIN xp_cmdshell_cert_login FROM CERTIFICATE xp_cmdshell_cert;
    CREATE USER xp_cmdshell_cert_login;
    GRANT EXECUTE ON dbo.xp_cmdshell TO xp_cmdshell_cert_login;
    GO
    
    -- Copy cert to user database
    DECLARE @cert_id int = cert_id('xp_cmdshell_cert')
    DECLARE @public_key  varbinary(MAX) = certencoded(@cert_id),
            @private_key varbinary(MAX) =
               certprivatekey(@cert_id,
                  'All you need is love',
                  'All you need is love')
    
    SELECT @cert_id, @public_key, @private_key
    
    DECLARE @sql nvarchar(MAX) =
          'CREATE CERTIFICATE xp_cmdshell_cert
           FROM  BINARY = ' + convert(varchar(MAX), @public_key, 1) + '
           WITH PRIVATE KEY (BINARY = ' +
              convert(varchar(MAX), @private_key, 1) + ',
              DECRYPTION BY PASSWORD = ''All you need is love'',
              ENCRYPTION BY PASSWORD = ''All you need is love'')'
    
    EXEC YourUserDatabase.sys.sp_executesql @sql;
    
    ALTER CERTIFICATE xp_cmdshell_cert REMOVE PRIVATE KEY;
    GO
    
    USE YourUserDatabase;
    GO
    
    CREATE PROC dbo.CreateFile
    AS
    EXEC master..xp_cmdshell 'echo hello > c:\file.txt';
    EXEC master..xp_cmdshell 'echo appended data >> c:\file.txt';
    EXEC master..xp_cmdshell 'echo more data >> c:\file.txt';
    GO
    ADD SIGNATURE TO dbo.CreateFile BY CERTIFICATE xp_cmdshell_cert
       WITH PASSWORD = 'All you need is love';
    GRANT EXEC ON dbo.CreateFile TO YourUserOrRole;
    GO
    ALTER CERTIFICATE xp_cmdshell_cert REMOVE PRIVATE KEY;
    GO
    
    • 5
  2. Solomon Rutzky
    2018-03-21T07:52:38+08:002018-03-21T07:52:38+08:00

    关于处理与执行相关的权限的问题xp_cmdshell,我同意(并赞成)丹的回答。但是,鉴于有关此请求原因的新信息(即写出大型 JSON 文档),安全性xp_cmdshell成为一个有争议的问题,因为xp_cmdshell最多只能处理 8000 个VARCHAR字符(如果使用双字节字符集和其中的某些字符,则更少) ,但这里可能不是这种情况,只是需要注意)。另外,我似乎记得某些字符在命令行上效果不佳,并且不能轻易逃脱(但目前找不到)。

    所以也许最好接受 Dan 对这个问题的回答(因为它对于所述问题是正确的),然后打开一个关于如何最好地导出大型 JSON 文档的新问题,我可以将这个答案转移到那个问题.


    File通过使用该类的 SQLCLR,可以相当容易地处理此操作。

    请在 DBA.SE 上查看我的以下答案,其中包括一些用于执行此类操作的代码示例:

    将结果导出到 XML

    此外,对于不想弄乱编码、部署等的任何人:SQL#库(我编写的)中有一个File_Write函数可以处理这个问题,甚至允许传入所需的编码,以便文件可以例如,保存为带有字节顺序标记 (BOM) 的 UTF-8。请注意,此功能仅在完整版中可用,在免费版中不可用。这是一个相当简单的创建函数,但最好有选项。

    • 2

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

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

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

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

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

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