Process::UID
module Process::UID
该Process::UID
模块包含一组模块功能,可用于便携地获取,设置和切换当前进程的真实,有效和保存的用户标识。
公共类方法
Process::UID.change_privilege(user) → integer Show source
当前进程的真实和有效用户
ID改为由指定的用户
。返回新的用户
标识。不适用于所有平台。
[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 → integer Show source
Process::UID.eid → integer
Process::Sys.geteuid → integer
返回此进程的有效用户标识。
Process.euid #=> 501
static VALUE
proc_geteuid(VALUE obj)
{
rb_uid_t euid = geteuid(
return UIDT2NUM(euid
}
Process::UID.from_name(name) → uid Show source
按名称
获取用户标识。如果用户没有找到,ArgumentError
将会被提出。
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) → integer Show source
Process::UID.eid= user → integer
将有效用户
标识(如果可能)设置为给定用户
的已保存进程的用户
标识。返回新的有效用户
标识。不适用于所有平台。
[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 → integer Show source
交换真实有效的用户ID并返回新的有效用户ID。不适用于所有平台。
[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 Show source
true
如果可以在当前平台上交换进程的真实和有效用户标识,则返回。
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 → integer Show source
Process::UID.rid → integer
Process::Sys.getuid → integer
返回此进程的(实际)用户标识。
Process.uid #=> 501
static VALUE
proc_getuid(VALUE obj)
{
rb_uid_t uid = getuid(
return UIDT2NUM(uid
}
Process::UID.sid_available? → true or false Show source
返回true
如果当前平台已保存的用户ID的功能。
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 → integer Show source
Process::UID.switch {|| block} → object
切换当前进程的有效用户ID和真实用户ID。如果给出了一个块
,则在该块
执行后,用户ID将被切回。如果在没有块
的情况下调用,则返回新的有效用户ID,如果给出块
,则返回块
的返回值。
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;
}