我有一个作为用户运行的web应用程序。但是,在某一时刻,它需要代表用户Alice和Bob从Linux文件系统读取文件。
这样做的一种方法是启动一个shell (Runtime.exec())并调用一个C setuid可执行文件来更改userid并读取文件。
有没有办法通过JNI ( web应用程序需要以www而不是root的形式运行)来实现这一点?我试图编写一个在Linux上调用本机方法的Java程序(我使这些本机方法为root所拥有,并设置了setuid位)。但是,除非我以root身份运行Java程序,否则它不允许我切换用户I。我遗漏了什么吗?有办法做到这一点吗?
谢谢!
发布于 2011-05-16 18:21:02
不是的。根本就没有。setuid和setgid只能在两种情况下使用(在普通Linux上):
setuid或setgid位的文件中启动的。在前一种情况下,这一过程可能会称这些职能任意采用任何身份。在后一种情况下,我唯一的进程在父进程的uid/gid和它启动的文件的uid/gid之间来回切换。
也就是说,如果setuid,它可以采用文件的uid,如果是setgid,则是gid。
由于您是在java中,所以exec-ed程序本身就是java,您不希望它是setuid或setgid,除非您想要创建一个巨大的安全暴露。
您可以编写一个通过JNI调用接口启动JVM的C或C++程序,并将该程序设置为setuid或setgid,然后在其中调用的JNI代码可以进行适当的切换调用。
发布于 2017-06-27 21:03:12
是的,有可能。您可以在这里看到一个例子:
https://github.com/kebernet/pretty/blob/master/src/main/java/com/reachcall/util/SetUID.java
下面是代码的示例:
CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class);
public static int setuid(int uid) {
if (Platform.isWindows()) {
return OK;
}
return CLibrary.INSTANCE.setuid(uid);
}bmargulies的答案不正确(或不完全正确)。UNIX中的非根进程可以设置uid或gid,如果它有各自的功能:
http://man7.org/linux/man-pages/man7/capabilities.7.html
CAP_SETUID
进行任意操作。
由于从OS的角度来看,您的程序是作为" java“进程运行的,因此必须为java可执行文件本身启用此setguid功能:
$ sudo setcap cap_setuid,cap_setgid+ep /usr/java/latest/bin/java还请注意,java可执行文件系统没有使用"nosuid“选项挂载。
回到你原来的问题
这个web应用程序需要以www而不是root
的形式运行。
通常,让web服务具有setuid功能并不是一个好主意。最好在启动web应用程序的shell包装脚本中删除uid。
https://stackoverflow.com/questions/5985597
复制相似问题