X-Git-Url: https://code.wpia.club/?a=blobdiff_plain;f=natives%2Forg_cacert_gigi_natives_SetUID.c;h=1b2350b4ab856102906013b6fcf80dfe8b0e6da5;hb=d7ca3ea303443dbe54163c06c2b097c8d14b6e6f;hp=7b2068ce22c6729600389cb77965158ea9a9bdac;hpb=ce2e587000376fffa4c88db087da4d15708eb9b2;p=gigi.git diff --git a/natives/org_cacert_gigi_natives_SetUID.c b/natives/org_cacert_gigi_natives_SetUID.c index 7b2068ce..1b2350b4 100644 --- a/natives/org_cacert_gigi_natives_SetUID.c +++ b/natives/org_cacert_gigi_natives_SetUID.c @@ -1,40 +1,65 @@ -#include +#include #include -#include - -#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, "", "(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)) { - char str[15]; - sprintf(str, "%d", gid); - return (jobject)getStatus(env, 0, str); - } - - if(setuid((int)uid)) { - char str[15]; - sprintf(str, "%d", uid); - return (jobject)getStatus(env, 0, str); - } - - return (jobject)getStatus(env, 1, "Successfully set uid/gid."); -} - -#ifdef __cplusplus -} -#endif -#endif + +#include + +#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, "", "(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