]> WPIA git - gigi.git/blobdiff - natives/org_cacert_gigi_natives_SetUID.c
Fix error message
[gigi.git] / natives / org_cacert_gigi_natives_SetUID.c
index f0ae7cb1d5548daeb8435f58880971599e6c8e58..1b2350b4ab856102906013b6fcf80dfe8b0e6da5 100644 (file)
@@ -1,36 +1,65 @@
-#include <jni.h>  
+#include <jni.h>
 #include <sys/types.h>
-#include <unistd.h> 
-  
-#ifndef _Included_org_cacert_natives_SetUID  
-#define _Included_org_cacert_natives_SetUID  
-#ifdef __cplusplus  
-extern "C" {  
-#endif  
-  
-jobject getStatus(JNIEnv *env, int successCode, const char * message) {  
-  
-   jstring message_str = (*env)->NewStringUTF(env, message);
-   jboolean success = successCode;  
-   jclass cls = (*env)->FindClass(env, "Lorg/cacert/gigi/natives/SetUID$Status;");  
-   jmethodID constructor = (*env)->GetMethodID(env, cls, "<init>", "(ZLjava/lang/String;)V");  
-   return (*env)->NewObject(env, cls, constructor, success, message_str);  
-}  
-  
-JNIEXPORT jobject JNICALL Java_org_cacert_gigi_natives_SetUID_setUid  
-  (JNIEnv *env, jobject obj, jint uid, jint gid) {  
-         if(setgid((int)gid)) {  
-         return (jobject)getStatus(env, 0, "Error while setting GID.");  
-      } 
-  
-      if(setuid((int)uid)) {
-         return (jobject)getStatus(env, 0, "Error while setting UID.");  
-      }  
-  
-      return (jobject)getStatus(env, 1, "Successfully set uid/gid.");  
-}  
-  
-#ifdef __cplusplus  
-}  
-#endif  
-#endif  
+
+#include <unistd.h>
+
+#ifndef _Included_org_cacert_natives_SetUID
+#define _Included_org_cacert_natives_SetUID
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static jobject getStatus(JNIEnv *env, int successCode, const char * message) {
+    jstring message_str = (*env)->NewStringUTF(env, message);
+    jboolean success = successCode;
+    jclass cls = (*env)->FindClass(env, "Lorg/cacert/gigi/natives/SetUID$Status;");
+    jmethodID constructor = (*env)->GetMethodID(env, cls, "<init>", "(ZLjava/lang/String;)V");
+    return (*env)->NewObject(env, cls, constructor, success, message_str);
+}
+
+JNIEXPORT jobject JNICALL Java_org_cacert_gigi_natives_SetUID_setUid
+        (JNIEnv *env, jobject obj, jint uid_, jint gid_) {
+
+    /* We don't need the reference for the object/class we are working on */
+    (void)obj;
+    /* Fix uid and gid types */
+    uid_t uid = (uid_t)uid_;
+    if ((jint)uid != uid_) {
+      return getStatus(env, 0, "UID does not fit in uid_t type.");
+    }
+    gid_t gid = (gid_t)gid_;
+    if ((jint)gid != gid_) {
+      return getStatus(env, 0, "GID does not fit in gid_t type.");
+    }
+
+    unsigned char work = 0;
+
+    if(getgid() != gid || getegid() != gid) {
+        if(setgid(gid)) {
+            return getStatus(env, 0, "Error while setting GID.");
+        }
+        work |= 1;
+    }
+
+    if(getuid() != uid || geteuid() != uid) {
+        if(setuid(uid)) {
+            return getStatus(env, 0, "Error while setting UID.");
+        }
+        work |= 2;
+    }
+
+    char *status;
+    switch (work) {
+    case 0: status = "UID and GID already set."; break;
+    case 1: status = "Successfully set GID (UID already set)."; break;
+    case 2: status = "Successfully set UID (GID already set)."; break;
+    case 3: status = "Successfully set UID and GID."; break;
+    default: return getStatus(env, 0, "Unexpected internal state.");
+    }
+    return getStatus(env, 1, status);
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif