]> WPIA git - gigi.git/blob - natives/club_wpia_gigi_natives_SetUID.c
fix: move switch to organisation context to separate page
[gigi.git] / natives / club_wpia_gigi_natives_SetUID.c
1 #include <jni.h>
2 #include <sys/types.h>
3
4 #include <unistd.h>
5
6 #ifndef _Included_club_wpia_natives_SetUID
7 #define _Included_club_wpia_natives_SetUID
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11
12 static jobject getStatus(JNIEnv *env, int successCode, const char * message) {
13     jstring message_str = (*env)->NewStringUTF(env, message);
14     jboolean success = successCode;
15     jclass cls = (*env)->FindClass(env, "Lclub/wpia/gigi/natives/SetUID$Status;");
16     jmethodID constructor = (*env)->GetMethodID(env, cls, "<init>", "(ZLjava/lang/String;)V");
17     return (*env)->NewObject(env, cls, constructor, success, message_str);
18 }
19
20 JNIEXPORT jobject JNICALL Java_club_wpia_gigi_natives_SetUID_setUid
21         (JNIEnv *env, jobject obj, jint uid_, jint gid_) {
22
23     /* We don't need the reference for the object/class we are working on */
24     (void)obj;
25     /* Fix uid and gid types */
26     uid_t uid = (uid_t)uid_;
27     if ((jint)uid != uid_) {
28       return getStatus(env, 0, "UID does not fit in uid_t type.");
29     }
30     gid_t gid = (gid_t)gid_;
31     if ((jint)gid != gid_) {
32       return getStatus(env, 0, "GID does not fit in gid_t type.");
33     }
34
35     unsigned char work = 0;
36
37     if(getgid() != gid || getegid() != gid) {
38         if(setgid(gid)) {
39             return getStatus(env, 0, "Error while setting GID.");
40         }
41         work |= 1;
42     }
43
44     if(getuid() != uid || geteuid() != uid) {
45         if(setuid(uid)) {
46             return getStatus(env, 0, "Error while setting UID.");
47         }
48         work |= 2;
49     }
50
51     char *status;
52     switch (work) {
53     case 0: status = "UID and GID already set."; break;
54     case 1: status = "Successfully set GID (UID already set)."; break;
55     case 2: status = "Successfully set UID (GID already set)."; break;
56     case 3: status = "Successfully set UID and GID."; break;
57     default: return getStatus(env, 0, "Unexpected internal state.");
58     }
59     return getStatus(env, 1, status);
60 }
61
62 #ifdef __cplusplus
63 }
64 #endif
65 #endif