Module: Process::UID
Relationships & Source Files | |
Defined in: | process.c |
Overview
The 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.
Class Attribute Summary
-
.eid ⇒ Integer
readonly
mod_func
Alias for euid.
-
.re_exchangeable? ⇒ Boolean
readonly
mod_func
Returns
true
if the real and effective user IDs of a process may be exchanged on the current platform. -
.rid ⇒ Integer
readonly
mod_func
Alias for uid.
-
.sid_available? ⇒ Boolean
readonly
mod_func
Returns
true
if the current platform has saved user ID functionality.
Class Method Summary
-
.change_privilege(user) ⇒ Integer
mod_func
Change the current process’s real and effective user ID to that specified by user.
-
.from_name(name) ⇒ UID
mod_func
Get the user ID by the name.
-
.grant_privilege(user) ⇒ Integer
mod_func
Set the effective user ID, and if possible, the saved user ID of the process to the given user.
-
.re_exchange ⇒ Integer
mod_func
Exchange real and effective user IDs and return the new effective user ID.
-
.switch ⇒ Integer
mod_func
Switch the effective and real user IDs of the current process.
Class Attribute Details
.eid ⇒ Integer (readonly, mod_func)
Alias for Process.euid.
.re_exchangeable? ⇒ Boolean
(readonly, mod_func)
Returns true
if the real and effective user IDs of a process may be exchanged on the current platform.
# File 'process.c', line 7490
static VALUE p_uid_exchangeable(VALUE _) { #if defined(HAVE_SETRESUID) return Qtrue; #elif defined(HAVE_SETREUID) && !defined(OBSOLETE_SETREUID) return Qtrue; #else return Qfalse; #endif }
.rid ⇒ Integer (readonly, mod_func)
Alias for Process.uid.
.sid_available? ⇒ Boolean
(readonly, mod_func)
Returns true
if the current platform has saved user ID functionality.
# File 'process.c', line 7615
static VALUE p_uid_have_saved_id(VALUE _) { #if defined(HAVE_SETRESUID) || defined(HAVE_SETEUID) || defined(_POSIX_SAVED_IDS) return Qtrue; #else return Qfalse; #endif }
Class Method Details
.change_privilege(user) ⇒ Integer (mod_func)
# File 'process.c', line 6354
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; }
.from_name(name) ⇒ UID
(mod_func)
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)
# File 'process.c', line 6039
static VALUE p_uid_from_name(VALUE self, VALUE id) { return UIDT2NUM(OBJ2UID(id)); }
# File 'process.c', line 7341
static VALUE p_uid_grant_privilege(VALUE obj, VALUE id) { rb_seteuid_core(OBJ2UID(id)); return id; }
.re_exchange ⇒ Integer (mod_func)
# File 'process.c', line 7515
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); }
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.
# File 'process.c', line 7650
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_RETURN(Qnil); }