从 Java 以不同用户身份运行 UNIX 命令

Posted

技术标签:

【中文标题】从 Java 以不同用户身份运行 UNIX 命令【英文标题】:Running UNIX commands as different user, from Java 【发布时间】:2010-11-04 00:14:07 【问题描述】:

试图编写一个能够以其他 UNIX 用户身份运行 UNIX 命令的 Java 程序。我有用户的密码,并且知道要运行的命令,但是该命令必须以该用户身份运行 - 所以我必须先以该用户身份登录。

例如:假设我们有一个用户 jim,他想查看 bob 的主目录中的内容,并且(无论出于何种原因)jim 有权执行 ls 而 bob 没有。 我们目前以 bob 身份登录。这是我们(可以)做的:

bob@host$ su jim && ls ~bob

问题是,系统提示我们输入 jim 的密码。由于这是从 Java 程序运行的,即

Process p = Runtime.getRuntime().exec("su jim && ls ~bob");

系统提示我们输入 jim 的密码并挂断了电话。 我们知道吉姆的密码。但是,我进不去。

此外,我们不能使用 Expect 脚本(没有安装它),我们也不能成为超级用户。我还研究过使用 SSH 来尝试这个,因为我们在技术上可以做到

bob@host$ ssh jim@host "ls ~bob"

但这也不起作用,因为我没有设置无密码 SSH 的权限。

我最后的努力是尝试使用 Java 的 SSH 库,因为 Java 程序可以使用密码,并且我可以使用该密码登录(并执行正确的命令)。但是由于我要在同一台主机上运行,​​这似乎有点矫枉过正。

有什么建议吗?

P.S:Java版本1.4.2,无法升级; AIX UNIX 5.3。

【问题讨论】:

您是否能够在不使用第三方库的情况下找到解决方法,如果可以,请分享一下? 【参考方案1】:

已安装 sudo,让运行 Java 程序的用户在 /etc/sudoers 中输入相关命令,并使用 sudo -u jim ls ~bob

【讨论】:

这不是解决方案。不幸的是,无论如何我都无法修改系统——包括安装 sudo。 你需要切换主机。 同意安德鲁。如果您的主机不允许您使用 pubkey SSH 之类的东西,并且您甚至无法安装“sudo”,那么您可能会想出关于您的“su”方案的任何东西,虽然可能是可能的,但您的主机不允许要么,你一定会遇到麻烦。找一个允许 sudo 的主机,这是唯一明智的解决方案。 刚刚意识到我从未解决过这些 cmets。这是一个与工作相关的问题,我当时工作的公司有足够的繁文缛节,以至于在他们的服务器周围,以任何方式获得 sudo 访问都是不可能的。 @GlenHunt:我知道类型。由对所涉及的技术一无所知的人编写的繁文缛节,并取缔他们不了解的一切,迫使那些知道知道他们的东西的人使用二级解决方法而不是做事情正确(和安全)的方式......慰问。【参考方案2】:

问题解决了。使用 JSch (http://www.jcraft.com/jsch/) SSH 到已知用户名和密码的服务器,并执行命令。谢谢大家的建议!

【讨论】:

请在此处添加示例。【参考方案3】:

可能是Expect 的java 实现?谷歌搜索时出现ExpectJ,但我找不到任何关于在 1.4.2 下运行的文档。

【讨论】:

这可能是一个解决方案。感谢您的提示。 好吧,ExpectJ 看起来应该可以工作 - 设法复制并构建依赖项。但问题是,ExpectJ 使用 StringBuilder,它直到 1.5 才实现。有什么建议吗? 您可以询问 ExpectJ 人员是否有旧版本(sourceforge 上没有)。如果唯一的问题是StringBuilder,你应该可以自己修改代码。【参考方案4】:

您是否尝试过重定向 sudo 命令输入并写入。我有一段时间没有使用 Java,但我相信有一种方法可以获取输入流并写入它。你可以用它来写密码,然后换行,sudo 或 su 应该接受密码。

使用 getInputStream() 并将您的密码写入其中。

su jim -c ls ~Bob

【讨论】:

【参考方案5】:

也许这会起作用:

Process process = Runtime.getRuntime().exec("su jim && ls ~bob");

OutputStream standardInput = process.getOutputStream();
Writer standardInputWriter = new OutputStreamWriter(standardInput);
standardInputWriter.write("password\n");
standardInputWriter.close();

【讨论】:

谢谢,但没用。我之前尝试过类似的方法,但结果大致相同。【参考方案6】:

我不确定这段代码:

Process p = Runtime.getRuntime().exec("su jim && ls ~bob");

将在 shell 中执行,需要评估 &&,即 shell 命令 (/bin/sh)。您应该通过 su 的命令行开关传递命令“ls ~bob”。比如:

su jim -c 'ls ~bob'

【讨论】:

那么 SSH imho 是唯一可行的选择

以上是关于从 Java 以不同用户身份运行 UNIX 命令的主要内容,如果未能解决你的问题,请参考以下文章

Sudo漏洞允许非特权Linux和macOS用户以root身份运行命令

在 Java 中使用 Selenium Webdriver 以不同用户身份运行 IE

无法以不同用户身份运行 C# 进程

批处理文件:删除提升的权限(以原始用户身份运行命令)

在 VS2008 中以不同用户身份调试应用程序

如何以管理员身份运行cmd