Module: Process::UID (Ruby 2.3.4)

    In Files

    • process.c

    Class/Module Index [+]

    Quicksearch

    Process::UID

    The Process::UID module contains a collection of module functions which can be used to portably get, set, and switch the current process's real, effective, and saved user IDs.

    Public Class Methods

    Process::UID.change_privilege(user) → fixnum click to toggle source

    Change the current process’s real and effective user ID to that specified by user. Returns the new user ID. Not available on all platforms.

    [Process.uid, Process.euid]          #=> [0, 0]
    Process::UID.change_privilege(31)    #=> 31
    [Process.uid, Process.euid]          #=> [31, 31]
    
     
                   static VALUE
    p_uid_change_privilege(VALUE obj, VALUE id)
    {
        rb_uid_t uid;
    
        check_uid_switch();
    
        uid = OBJ2UID(id);
    
        if (geteuid() == 0) { /* root-user */
    #if defined(HAVE_SETRESUID)
            if (setresuid(uid, uid, uid) < 0) rb_sys_fail(0);
            SAVED_USER_ID = uid;
    #elif defined(HAVE_SETUID)
            if (setuid(uid) < 0) rb_sys_fail(0);
            SAVED_USER_ID = uid;
    #elif defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID)
            if (getuid() == uid) {
                if (SAVED_USER_ID == uid) {
                    if (setreuid(-1, uid) < 0) rb_sys_fail(0);
                }
                else {
                    if (uid == 0) { /* (r,e,s) == (root, root, x) */
                        if (setreuid(-1, SAVED_USER_ID) < 0) rb_sys_fail(0);
                        if (setreuid(SAVED_USER_ID, 0) < 0) rb_sys_fail(0);
                        SAVED_USER_ID = 0; /* (r,e,s) == (x, root, root) */
                        if (setreuid(uid, uid) < 0) rb_sys_fail(0);
                        SAVED_USER_ID = uid;
                    }
                    else {
                        if (setreuid(0, -1) < 0) rb_sys_fail(0);
                        SAVED_USER_ID = 0;
                        if (setreuid(uid, uid) < 0) rb_sys_fail(0);
                        SAVED_USER_ID = uid;
                    }
                }
            }
            else {
                if (setreuid(uid, uid) < 0) rb_sys_fail(0);
                SAVED_USER_ID = uid;
            }
    #elif defined(HAVE_SETRUID) && defined(HAVE_SETEUID)
            if (getuid() == uid) {
                if (SAVED_USER_ID == uid) {
                    if (seteuid(uid) < 0) rb_sys_fail(0);
                }
                else {
                    if (uid == 0) {
                        if (setruid(SAVED_USER_ID) < 0) rb_sys_fail(0);
                        SAVED_USER_ID = 0;
                        if (setruid(0) < 0) rb_sys_fail(0);
                    }
                    else {
                        if (setruid(0) < 0) rb_sys_fail(0);
                        SAVED_USER_ID = 0;
                        if (seteuid(uid) < 0) rb_sys_fail(0);
                        if (setruid(uid) < 0) rb_sys_fail(0);
                        SAVED_USER_ID = uid;
                    }
                }
            }
            else {
                if (seteuid(uid) < 0) rb_sys_fail(0);
                if (setruid(uid) < 0) rb_sys_fail(0);
                SAVED_USER_ID = uid;
            }
    #else
            (void)uid;
            rb_notimplement();
    #endif
        }
        else { /* unprivileged user */
    #if defined(HAVE_SETRESUID)
            if (setresuid((getuid() == uid)? (rb_uid_t)-1: uid,
                          (geteuid() == uid)? (rb_uid_t)-1: uid,
                          (SAVED_USER_ID == uid)? (rb_uid_t)-1: uid) < 0) rb_sys_fail(0);
            SAVED_USER_ID = uid;
    #elif defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID)
            if (SAVED_USER_ID == uid) {
                if (setreuid((getuid() == uid)? (rb_uid_t)-1: uid,
                             (geteuid() == uid)? (rb_uid_t)-1: uid) < 0)
                    rb_sys_fail(0);
            }
            else if (getuid() != uid) {
                if (setreuid(uid, (geteuid() == uid)? (rb_uid_t)-1: uid) < 0)
                    rb_sys_fail(0);
                SAVED_USER_ID = uid;
            }
            else if (/* getuid() == uid && */ geteuid() != uid) {
                if (setreuid(geteuid(), uid) < 0) rb_sys_fail(0);
                SAVED_USER_ID = uid;
                if (setreuid(uid, -1) < 0) rb_sys_fail(0);
            }
            else { /* getuid() == uid && geteuid() == uid */
                if (setreuid(-1, SAVED_USER_ID) < 0) rb_sys_fail(0);
                if (setreuid(SAVED_USER_ID, uid) < 0) rb_sys_fail(0);
                SAVED_USER_ID = uid;
                if (setreuid(uid, -1) < 0) rb_sys_fail(0);
            }
    #elif defined(HAVE_SETRUID) && defined(HAVE_SETEUID)
            if (SAVED_USER_ID == uid) {
                if (geteuid() != uid && seteuid(uid) < 0) rb_sys_fail(0);
                if (getuid() != uid && setruid(uid) < 0) rb_sys_fail(0);
            }
            else if (/* SAVED_USER_ID != uid && */ geteuid() == uid) {
                if (getuid() != uid) {
                    if (setruid(uid) < 0) rb_sys_fail(0);
                    SAVED_USER_ID = uid;
                }
                else {
                    if (setruid(SAVED_USER_ID) < 0) rb_sys_fail(0);
                    SAVED_USER_ID = uid;
                    if (setruid(uid) < 0) rb_sys_fail(0);
                }
            }
            else if (/* geteuid() != uid && */ getuid() == uid) {
                if (seteuid(uid) < 0) rb_sys_fail(0);
                if (setruid(SAVED_USER_ID) < 0) rb_sys_fail(0);
                SAVED_USER_ID = uid;
                if (setruid(uid) < 0) rb_sys_fail(0);
            }
            else {
                rb_syserr_fail(EPERM, 0);
            }
    #elif defined HAVE_44BSD_SETUID
            if (getuid() == uid) {
                /* (r,e,s)==(uid,?,?) ==> (uid,uid,uid) */
                if (setuid(uid) < 0) rb_sys_fail(0);
                SAVED_USER_ID = uid;
            }
            else {
                rb_syserr_fail(EPERM, 0);
            }
    #elif defined HAVE_SETEUID
            if (getuid() == uid && SAVED_USER_ID == uid) {
                if (seteuid(uid) < 0) rb_sys_fail(0);
            }
            else {
                rb_syserr_fail(EPERM, 0);
            }
    #elif defined HAVE_SETUID
            if (getuid() == uid && SAVED_USER_ID == uid) {
                if (setuid(uid) < 0) rb_sys_fail(0);
            }
            else {
                rb_syserr_fail(EPERM, 0);
            }
    #else
            rb_notimplement();
    #endif
        }
        return id;
    }
                
    euid → fixnum click to toggle source
    Process::UID.eid → fixnum
    Process::Sys.geteuid → fixnum

    Returns the effective user ID for this process.

    Process.euid   #=> 501
    
     
                   static VALUE
    proc_geteuid(VALUE obj)
    {
        rb_uid_t euid = geteuid();
        return UIDT2NUM(euid);
    }
                
    Process::UID.from_name(name) → uid click to toggle source

    Get the user ID by the name. If the user is not found, ArgumentError will be raised.

    Process::UID.from_name("root") #=> 0
    Process::UID.from_name("nosuchuser") #=> can't find user for nosuchuser (ArgumentError)
    
     
                   static VALUE
    p_uid_from_name(VALUE self, VALUE id)
    {
        return UIDT2NUM(OBJ2UID(id));
    }
                
    Process::UID.grant_privilege(user) → fixnum click to toggle source
    Process::UID.eid= user → fixnum

    Set the effective user ID, and if possible, the saved user ID of the process to the given user. Returns the new effective user ID. Not available on all platforms.

    [Process.uid, Process.euid]          #=> [0, 0]
    Process::UID.grant_privilege(31)     #=> 31
    [Process.uid, Process.euid]          #=> [0, 31]
    
     
                   static VALUE
    p_uid_grant_privilege(VALUE obj, VALUE id)
    {
        rb_seteuid_core(OBJ2UID(id));
        return id;
    }
                
    Process::UID.re_exchange → fixnum click to toggle source

    Exchange real and effective user IDs and return the new effective user ID. Not available on all platforms.

    [Process.uid, Process.euid]   #=> [0, 31]
    Process::UID.re_exchange      #=> 0
    [Process.uid, Process.euid]   #=> [31, 0]
    
     
                   static VALUE
    p_uid_exchange(VALUE obj)
    {
        rb_uid_t uid;
    #if defined(HAVE_SETRESUID) || (defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID))
        rb_uid_t euid;
    #endif
    
        check_uid_switch();
    
        uid = getuid();
    #if defined(HAVE_SETRESUID) || (defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID))
        euid = geteuid();
    #endif
    
    #if defined(HAVE_SETRESUID)
        if (setresuid(euid, uid, uid) < 0) rb_sys_fail(0);
        SAVED_USER_ID = uid;
    #elif defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID)
        if (setreuid(euid,uid) < 0) rb_sys_fail(0);
        SAVED_USER_ID = uid;
    #else
        rb_notimplement();
    #endif
        return UIDT2NUM(uid);
    }
                
    Process::UID.re_exchangeable? → true or false click to toggle source

    Returns true if the real and effective user IDs of a process may be exchanged on the current platform.

     
                   static VALUE
    p_uid_exchangeable(void)
    {
    #if defined(HAVE_SETRESUID)
        return Qtrue;
    #elif defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID)
        return Qtrue;
    #else
        return Qfalse;
    #endif
    }
                
    uid → fixnum click to toggle source
    Process::UID.rid → fixnum
    Process::Sys.getuid → fixnum

    Returns the (real) user ID of this process.

    Process.uid   #=> 501
    
     
                   static VALUE
    proc_getuid(VALUE obj)
    {
        rb_uid_t uid = getuid();
        return UIDT2NUM(uid);
    }
                
    Process::UID.sid_available? → true or false click to toggle source

    Returns true if the current platform has saved user ID functionality.

     
                   static VALUE
    p_uid_have_saved_id(void)
    {
    #if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || defined(_POSIX_SAVED_IDS)
        return Qtrue;
    #else
        return Qfalse;
    #endif
    }
                
    Process::UID.switch → fixnum click to toggle source
    Process::UID.switch {|| block} → object

    Switch the effective and real user IDs of the current process. If a block is given, the user IDs will be switched back after the block is executed. Returns the new effective user ID if called without a block, and the return value of the block if one is given.

     
                   static VALUE
    p_uid_switch(VALUE obj)
    {
        rb_uid_t uid, euid;
    
        check_uid_switch();
    
        uid = getuid();
        euid = geteuid();
    
        if (uid != euid) {
            proc_seteuid(uid);
            if (rb_block_given_p()) {
                under_uid_switch = 1;
                return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, SAVED_USER_ID);
            }
            else {
                return UIDT2NUM(euid);
            }
        }
        else if (euid != SAVED_USER_ID) {
            proc_seteuid(SAVED_USER_ID);
            if (rb_block_given_p()) {
                under_uid_switch = 1;
                return rb_ensure(rb_yield, Qnil, p_uid_sw_ensure, euid);
            }
            else {
                return UIDT2NUM(uid);
            }
        }
        else {
            rb_syserr_fail(EPERM, 0);
        }
    
        UNREACHABLE;
    }