2011-02-28 30 views
3

我正在用Java寫一個服務器程序,允許用戶使用DRMAA提交作業。雖然主服務器進程的運行時間爲root,但它所做的只是對用戶進行身份驗證,然後啓動另一個以該用戶身份運行的Java程序並實際完成該工作以符合最小化特權的原則。最初,我是在Runtime.exec()sudo(下面的例子)這樣做的情況下正常工作,直到該進程被分類爲止,此時sudo因爲沒有終端而變得不安。用Java的叉和下降權限

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

當作爲守護程序運行時,在Java中執行這種fork和drop權限模式的最佳方式是什麼?有沒有辦法?我將不得不突破C並學習如何使用JNI創建JVM?

回答

1

您可以使用su(1)而不是sudo(8)su(1)涉及得少得多,並且可能不希望終端本身。 (當然,如果你的PAM配置需要終端輸入su(1),那麼這可能也不工作。)

0

如果你只啓動非root過程root,然後su就足夠了。當從root到另一個用戶,它不會要求密碼,所以它不應該需要一個終端。

6

使用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從使用javahUID.class機器生成的。

+0

這段代碼在某些時候會產生錯誤,因爲'uid_t'在一些系統上是無符號的,'jint'是有符號的。鑄造通常非常糟糕 - 如果所有的JNI庫都使用了鑄造,則會有設計缺陷。 – specializt 2015-03-25 22:12:56