【问题标题】:Which account is used when executing xp_cmdshell 'wmic ... "java -jar ..."'执行 xp_cmdshell 'wmic ... "java -jar ..."' 时使用哪个帐户
【发布时间】:2016-11-15 10:36:31
【问题描述】:

我有一个 jar 文件,我想在 SQL 作业 中将其作为一个步骤运行。 但是,jar 文件必须在 ma​​chineA 上运行,而 SQL 作业计划在 serverA 上。

为了实现这一点,在 serverA 的 SQL 作业中,我使用xp_cmdshell 向终端发出wmic 命令。

xp_cmdshell 允许我从 T-SQL 脚本发出终端命令

wmic 允许我向机器发出终端命令(在本例中为 java -jar 命令)

下面是我使用的命令

EXEC master..xp_cmdshell 'wmic /user:mydomain\myuser /password:mypassword /node:machineA process call create "cmd /c java -jar D:\jars\saveToSharedFolder.jar"'

saveToSharedFolder.jar 是一个 java 应用程序,它从数据库中提取数据并将其写入 excel 文件,然后将此 excel 文件保存到位于服务器中的共享文件夹中,例如 \ serverA\files\savedData.xlsx.

文件 savedData.xlsx 没有保存在 \serverA\files 中。

当我尝试将 java 错误消息输出到文件时,我得到了这个。

java.io.FileNotFoundException: \\serverA\files\savedData.xlsx (Access is denied)
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException: Fail to save: an error occurs while saving the package : null
    at org.apache.poi.openxml4j.opc.ZipPackage.saveImpl(ZipPackage.java:602)
    at org.apache.poi.openxml4j.opc.OPCPackage.save(OPCPackage.java:1557)
    at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:248)
    at saveToSharedFolder.saveData(saveToSharedFolder.java:115)
    at saveToSharedFolder.main(saveToSharedFolder.java:46)
    ... 5 more
Caused by: java.lang.NullPointerException
    at java.util.zip.DeflaterOutputStream.<init>(Unknown Source)
    at java.util.zip.DeflaterOutputStream.<init>(Unknown Source)
    at java.util.zip.ZipOutputStream.<init>(Unknown Source)
    at java.util.zip.ZipOutputStream.<init>(Unknown Source)
    at org.apache.poi.openxml4j.opc.ZipPackage.saveImpl(ZipPackage.java:531)
    ... 9 more

我知道这是文件夹权限问题。但是,我不知道应该授予哪个帐户对该文件夹的写入权限。

当我尝试使用我在 wmic 命令中使用的mydomain\myuser 和mypassword 登录 machineA 并在 machineA 中运行 jar 文件时,它成功保存了 \serverA\files\savedData.xlsx

我还尝试授予运行EXEC master..xp_cmdshell 'whoami' 时获得的nt service 帐户。因为那是运行 wmic 帐户的帐户,对吗?但它仍然没有创建 \serverA\files\savedData.xlsx

这很奇怪,因为我使用 mydomain\myusermypassword 启动 wmic 不应该使用 myuser 的凭据运行 jar 文件,从而能够创建 \serverA\files\savedData .xlsx?

【问题讨论】:

    标签: java sql-server excel wmic xp-cmdshell


    【解决方案1】:

    如果调用登录名是 sysadmin 角色成员,则 xp_cmdshell 在 SQL Server 服务帐户的安全上下文下运行。对于非系统管理员角色成员,xp_cmdshell 在xp_cmdshell proxy account 的安全上下文下运行。

    不确定您为什么要使用 T-SQL 来调用该过程。相反,请考虑使用 CmdExec 作业步骤类型直接执行命令。您可以在作业步骤配置(SQL Server 代理服务帐户或代理)中指定所需的流程安全上下文。见https://msdn.microsoft.com/en-us/library/ms190264.aspx

    【讨论】:

    • 嗨@Dan Guzman 非常感谢。我尝试为 serverA 的本地管理员帐户创建代理。我还创建了一个运行 wmic 命令的 cmdexec 作业。我已经使用仅包含 1 个步骤的测试 sql 作业进行了测试,即 cmdexec 作业。但是,当我尝试编辑 sql 作业以将步骤 1 作为 t-sql 脚本并将步骤 2 作为 cmdexec 时,我得到一个 Transact-SQL 子系统不允许代理帐户。 (Microsoft SQL Server,错误:14517) 错误
    • @Krish,您不需要为 T-SQL 步骤指定代理帐户。如果您使用的是 SSMS UI,这甚至不应该是 T-SQL 作业步骤类型的选项。对于 sysadmin 角色成员拥有的作业,T-SQL 作业步骤在 SQL 代理服务帐户下执行。对于非系统管理员拥有的作业,T-SQL 步骤在作业所有者的安全上下文下运行。 CmdExec 和 T-SQL 步骤安全上下文是独立的。
    • 你是对的。当我使用 step1 作为 t-sql 脚本和 step2 作为 cmdexec 作业创建新作业时,没有出现该错误。我认为这是因为我之前所做的作业只有 1 步,使用 cmdexec 作业类型。然后,我将该步骤更改为 t-sql 脚本并添加了 step2(cmdexec)。我认为这就是矛盾的开始。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 2010-11-08
    • 2014-10-15
    • 2020-06-08
    相关资源
    最近更新 更多