我正在用Java编写一个服务器程序,允许用户使用DRMAA提交作业。 尽pipe主服务器进程以root
身份运行,但它所做的只是对用户进行身份validation,然后启动另一个以该用户身份运行的Java程序,并实际执行工作以符合最小化特权的原则。 最初,我正在用Runtime.exec()
和sudo
(下面的例子)这样做,这工作正常,直到进程被分类为止,此时sudo
因为没有terminal而感到不安。
String[] command = {"sudo", "-i", "-u", username, java, theOtherJavaProgram}; Runtime.getRuntime().exec(command, null, getHomeDirectory(username));
作为守护程序运行时,在Java中执行这种fork和drop权限模式的最佳方式是什么? 有没有办法? 我将不得不突破C并学习如何使用JNI创buildJVM?
你可以使用su(1)
而不是sudo(8)
。 su(1)
涉及得少得多,而且可能不希望终端本身。 (当然,如果你的PAM配置需要su(1)
终端输入,那么这可能也不好用。)
使用JNI删除权限可能更容易。
这是我之前提到的一个:
UID.java
public class UID { public static native int setuid(int uid); static { System.loadLibrary("uid"); } }
unix_uid.c
#include <sys/types.h> #include <unistd.h> #include <jni.h> #include "UID.h" JNIEXPORT jint JNICALL Java_UID_setuid(JNIEnv * jnienv, jclass j, jint uid) { return((jint)setuid((uid_t)uid)); }
UID.h
是使用javah
从UID.class
生成的机器。
如果您只想以root
身份启动非root
进程,那么su
就足够了。 从 root
到另一个用户时,它不会要求输入密码,所以它不需要终端。