【问题标题】:How to run superuser commands on Linux through Java code?如何通过 Java 代码在 Linux 上运行超级用户命令?
【发布时间】:2014-03-12 01:45:04
【问题描述】:

我的应用程序有多个用户和 1 个超级用户。我正在尝试通过 Java 代码在 Linux 中编写和存储文件,但出现权限被拒绝错误。我使用了以下代码:

Process process = Runtime.getRuntime().exec("/usr/bin/tiff2pdf -o /tmp/tiff_dir/temp.pdf /tmp/tiff_dir/image.tiff");
int returnCode = process.waitFor();

我收到以下错误:

java.io.FileNotFoundException: image.tiff (Permission denied)

从我的分析来看,似乎是因为用户没有root权限,所以我收到了这个错误。有什么办法解决这个问题?

【问题讨论】:

  • 在命令行中使用 sudo。但您需要输入密码。小心root...
  • 找出您没有所需权限而不是运行超级用户命令的原因。这似乎不是一个需要 root 访问权限的命令。
  • 您是否尝试过使用文件的完整路径?可能问题在于 cwd 不是您认为的那样。特权提升永远不是答案。
  • @PhilippSander 但我不希望用户输入 root 密码。
  • 如果允许随机程序在没有任何密码提示等的情况下获得超级用户权限,您不认为这将是一个巨大的安全漏洞吗?

标签: java linux exec elevated-privileges


【解决方案1】:

你不应该以超级用户的身份运行这样的命令,因为它会带来安全风险(即,如果有人控制了你的 java 程序,那么他们就拥有了通往王国的钥匙)。相反,您应该以较低的权限运行。

看起来问题在于访问image.tiff 而不是tiff2pdf。检查image.tiff的所有者和权限。

【讨论】:

  • 是的,我知道问题出在“image.tiff”文件的权限上。问题是如何从非超级用户更改此文件的权限?
  • 如何提升进程的权限?看看这个:stackoverflow.com/questions/4662574/…
  • 不过,我要补充的是,如果管理权限在应用程序的范围内,这应该只是计划。如果它只是一种“完成它的方法”,你需要找到另一种方法。
  • 另一种可能的解决方案是创建一个服务,其唯一目的是运行tiff2pdf 命令。您可以将它作为具有更高权限的守护程序运行,并从您的较低权限程序调用它。如果您绝对需要以超级用户身份运行它,这样您就可以控制安全风险。
  • @orourkedd,这显然是一个 Linux 问题,提升 UAC 在这里并不是特别重要。无论如何,这个问题有问题,因为它不可能在那里抛出这个异常。
【解决方案2】:

首先,这两行不会产生java.io.FileNotFoundException: image.tiff (Permission denied)

Process process = Runtime.getRuntime().exec("/usr/bin/tiff2pdf -o temp.pdf image.tiff");
int returnCode = process.waitFor();

如果由于某种原因,命令失败,它将返回一个非零返回码,将在进程的标准错误中产生一些输出(这是约定)。您可以从process.getErrorStream() 获得该标准错误(以防万一,也可能值得查看标准输出)。如果在那里找不到文件存在问题,它不会像这样抛出 FileNotFoundException,因为 Java 无法理解您的命令的预期输出。

编辑,按照您的评论:

仅从此时抛出,returnCode 的值为 1。一旦我从 root 用户手动更改文件权限,一切正常。

这是不可能的。如果您的应用程序在这两行中的任何一行抛出异常,它将退出正常的控制流:您将根本无法读取returnCode

其次,您应该在 String[] 中使用每个参数运行 exec 命令,而不是将它们全部放在一行中,这应该可以防止在文件名包含空格时出现引用问题。

我还建议在您的命令中使用绝对路径,以确保您在预期的目录中工作。 (*编辑:* 现在您使用的是绝对路径,请确保您的用户对 /tmp/tiff_dir 具有 rwx 权限。)

要更直接地回答您的问题,您当然可以运行 sudoRuntime.exec(new String[] {"/usr/bin/sudo", ... the rest of your command ... },但出于安全原因,这是个坏主意。您还需要更改sudoers 文件以允许它没有密码,或者找到一种方法来传递密码,或者on the command line(绝对是一个安全风险!)或者通过手动将其传递给输入流,不知何故.)

【讨论】:

  • Java 中的 setid() 方法和 C 一样吗?
【解决方案3】:

试试这个:

File file = new File("/opt/image.tiff");
Runtime runtime = Runtime.getRuntime();
runtime.exec(new String[] { "/bin/chmod", "777",file.getPath()});

这将对文件执行完全权限。

【讨论】:

  • 老兄...他确实不想想要更改文件的权限。
  • @noloader 可以,但是更改文件的权限比以超级用户身份执行要好
  • 没有。永远不要更改用户设置的内容,至少在询问用户之前不要更改。文件具有某种权限模式可能是有某种原因的。
  • @Sandeep 非超级用户可以更改文件权限吗?我无法更改非超级用户的权限。
  • @akshay,普通用户更改他们拥有的文件的更改文件权限。但是,再一次,您得到的错误不是由您向我们展示的两行代码产生的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-16
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 2018-05-10
  • 2012-02-07
  • 1970-01-01
相关资源
最近更新 更多