Java的Fork和drop权限

Java的Fork和drop权限,java,unix,process,permissions,fork,Java,Unix,Process,Permissions,Fork,我正在用Java编写一个服务器程序,允许用户使用DRMAA提交作业。尽管主服务器进程以root身份运行,但它所做的只是对用户进行身份验证,然后启动另一个以该用户身份运行的Java程序,并实际执行该工作,以符合最小化特权的原则。最初,我是用Runtime.exec()和sudo(下面的示例)来实现这一点的,在进程被监视之前,这两种方法都可以正常工作,此时sudo会因为没有终端而感到不安 String[] command = {"sudo", "-i", "-u", username, java,

我正在用Java编写一个服务器程序,允许用户使用DRMAA提交作业。尽管主服务器进程以
root
身份运行,但它所做的只是对用户进行身份验证,然后启动另一个以该用户身份运行的Java程序,并实际执行该工作,以符合最小化特权的原则。最初,我是用
Runtime.exec()
sudo
(下面的示例)来实现这一点的,在进程被监视之前,这两种方法都可以正常工作,此时
sudo
会因为没有终端而感到不安

String[] command = {"sudo", "-i", "-u", username, java, theOtherJavaProgram};
Runtime.getRuntime().exec(command, null, getHomeDirectory(username));

当作为守护进程运行时,在Java中执行这种fork-and-drop特权模式的最佳方法是什么?有办法吗?我是否必须突破C,学习如何使用JNI创建JVM?

您可以使用
su(1)
而不是
sudo(8)
su(1)
涉及的内容要少得多,而且可能不需要终端本身。(当然,如果您的PAM配置需要为
su(1)
进行终端输入,那么这也可能无法正常工作。)

如果您只想以
root
的身份启动非
root
进程,那么
su
就足够了。当从
根用户转到另一个用户时,它不会要求密码,因此它不需要终端。

使用JNI删除权限可能更容易

String[] command = {"sudo", "-i", "-u", username, java, theOtherJavaProgram};
Runtime.getRuntime().exec(command, null, getHomeDirectory(username));
这是我早些时候弄到的一个:

UID.java

public class UID {

    public static native int setuid(int uid);

    static {
        System.loadLibrary("uid");
    }
}
unix\u 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”
JNIEXPORT jint JNICALL
Java_UID_setuid(JNIEnv*JNIEnv,jclass j,jint UID)
{
返回((jint)setuid((uid_t)uid));
}

UID.h
是机器使用
javah

UID.class
生成的。由于
UID\u t
在某些系统上未签名,并且
jint
已签名,因此此代码在某些点会产生错误。一般来说,强制转换非常糟糕——如果所有JNI库都使用强制转换,那么就会出现设计缺陷。