Module: Process::GID
- Defined in:
- process.c
Overview
The Process::GID
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 group IDs.
Class Method Summary collapse
-
.Process::GID.change_privilege(integer) ⇒ Fixnum
Change the current process's real and effective group ID to that specified by integer.
-
.eid ⇒ Object
Returns the effective group ID for this process.
-
.grant_privilege ⇒ Object
Set the effective group ID, and if possible, the saved group ID of the process to the given integer.
-
.Process::GID.re_exchange ⇒ Fixnum
Exchange real and effective group IDs and return the new effective group ID.
-
.Process::GID.re_exchangeable? ⇒ Boolean
Returns
true
if the real and effective group IDs of a process may be exchanged on the current platform. -
.rid ⇒ Object
Returns the (real) group ID for this process.
-
.Process::GID.sid_available? ⇒ Boolean
Returns
true
if the current platform has saved group ID functionality. -
.switch ⇒ Object
Switch the effective and real group IDs of the current process.
Class Method Details
.Process::GID.change_privilege(integer) ⇒ Fixnum
Change the current process's real and effective group ID to that specified by integer. Returns the new group ID. Not available on all platforms.
[Process.gid, Process.egid] #=> [0, 0]
Process::GID.change_privilege(33) #=> 33
[Process.gid, Process.egid] #=> [33, 33]
|
# File 'process.c'
/*
* call-seq:
* Process::GID.change_privilege(integer) => fixnum
*
* Change the current process's real and effective group ID to that
* specified by _integer_. Returns the new group ID. Not
* available on all platforms.
*
* [Process.gid, Process.egid] #=> [0, 0]
* Process::GID.change_privilege(33) #=> 33
* [Process.gid, Process.egid] #=> [33, 33]
*/
static VALUE
p_gid_change_privilege(obj, id)
VALUE obj, id;
{
int gid;
check_gid_switch();
gid = NUM2INT(id);
if (geteuid() == 0) { /* root-user */
#if defined(HAVE_SETRESGID)
if (setresgid(gid, gid, gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
#elif defined HAVE_SETGID
if (setgid(gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
#elif defined(HAVE_SETREGID) && !defined(OBSOLETE_SETREGID)
if (getgid() == gid) {
if (SAVED_GROUP_ID == gid) {
if (setregid(-1, gid) < 0) rb_sys_fail(0);
} else {
if (gid == 0) { /* (r,e,s) == (root, y, x) */
if (setregid(-1, SAVED_GROUP_ID) < 0) rb_sys_fail(0);
if (setregid(SAVED_GROUP_ID, 0) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = 0; /* (r,e,s) == (x, root, root) */
if (setregid(gid, gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
} else { /* (r,e,s) == (z, y, x) */
if (setregid(0, 0) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = 0;
if (setregid(gid, gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
}
}
} else {
if (setregid(gid, gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
}
#elif defined(HAVE_SETRGID) && defined (HAVE_SETEGID)
if (getgid() == gid) {
if (SAVED_GROUP_ID == gid) {
if (setegid(gid) < 0) rb_sys_fail(0);
} else {
if (gid == 0) {
if (setegid(gid) < 0) rb_sys_fail(0);
if (setrgid(SAVED_GROUP_ID) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = 0;
if (setrgid(0) < 0) rb_sys_fail(0);
} else {
if (setrgid(0) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = 0;
if (setegid(gid) < 0) rb_sys_fail(0);
if (setrgid(gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
}
}
} else {
if (setegid(gid) < 0) rb_sys_fail(0);
if (setrgid(gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
}
#else
rb_notimplement();
#endif
} else { /* unprivileged user */
#if defined(HAVE_SETRESGID)
if (setresgid((getgid() == gid)? -1: gid,
(getegid() == gid)? -1: gid,
(SAVED_GROUP_ID == gid)? -1: gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
#elif defined(HAVE_SETREGID) && !defined(OBSOLETE_SETREGID)
if (SAVED_GROUP_ID == gid) {
if (setregid((getgid() == gid)? -1: gid,
(getegid() == gid)? -1: gid) < 0) rb_sys_fail(0);
} else if (getgid() != gid) {
if (setregid(gid, (getegid() == gid)? -1: gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
} else if (/* getgid() == gid && */ getegid() != gid) {
if (setregid(getegid(), gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
if (setregid(gid, -1) < 0) rb_sys_fail(0);
} else { /* getgid() == gid && getegid() == gid */
if (setregid(-1, SAVED_GROUP_ID) < 0) rb_sys_fail(0);
if (setregid(SAVED_GROUP_ID, gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
if (setregid(gid, -1) < 0) rb_sys_fail(0);
}
#elif defined(HAVE_SETRGID) && defined(HAVE_SETEGID)
if (SAVED_GROUP_ID == gid) {
if (getegid() != gid && setegid(gid) < 0) rb_sys_fail(0);
if (getgid() != gid && setrgid(gid) < 0) rb_sys_fail(0);
} else if (/* SAVED_GROUP_ID != gid && */ getegid() == gid) {
if (getgid() != gid) {
if (setrgid(gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
} else {
if (setrgid(SAVED_GROUP_ID) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
if (setrgid(gid) < 0) rb_sys_fail(0);
}
} else if (/* getegid() != gid && */ getgid() == gid) {
if (setegid(gid) < 0) rb_sys_fail(0);
if (setrgid(SAVED_GROUP_ID) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
if (setrgid(gid) < 0) rb_sys_fail(0);
} else {
errno = EPERM;
rb_sys_fail(0);
}
#elif defined HAVE_44BSD_SETGID
if (getgid() == gid) {
/* (r,e,s)==(gid,?,?) ==> (gid,gid,gid) */
if (setgid(gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
} else {
errno = EPERM;
rb_sys_fail(0);
}
#elif defined HAVE_SETEGID
if (getgid() == gid && SAVED_GROUP_ID == gid) {
if (setegid(gid) < 0) rb_sys_fail(0);
} else {
errno = EPERM;
rb_sys_fail(0);
}
#elif defined HAVE_SETGID
if (getgid() == gid && SAVED_GROUP_ID == gid) {
if (setgid(gid) < 0) rb_sys_fail(0);
} else {
errno = EPERM;
rb_sys_fail(0);
}
#else
rb_notimplement();
#endif
}
return INT2FIX(gid);
}
|
.egid ⇒ Fixnum .Process::GID.eid ⇒ Fixnum .Process::Sys.geteid ⇒ Fixnum
Returns the effective group ID for this process. Not available on all platforms.
Process.egid #=> 500
|
# File 'process.c'
/*
* call-seq:
* Process.egid => fixnum
* Process::GID.eid => fixnum
* Process::Sys.geteid => fixnum
*
* Returns the effective group ID for this process. Not available on
* all platforms.
*
* Process.egid #=> 500
*/
static VALUE
proc_getegid(obj)
VALUE obj;
{
int egid = getegid();
return INT2FIX(egid);
}
|
.Process::GID.grant_privilege(integer) ⇒ Fixnum .Process::GID.eid( = integer) ⇒ Fixnum
Set the effective group ID, and if possible, the saved group ID of the process to the given integer. Returns the new effective group ID. Not available on all platforms.
[Process.gid, Process.egid] #=> [0, 0]
Process::GID.grant_privilege(31) #=> 33
[Process.gid, Process.egid] #=> [0, 33]
|
# File 'process.c'
/*
* call-seq:
* Process::GID.grant_privilege(integer) => fixnum
* Process::GID.eid = integer => fixnum
*
* Set the effective group ID, and if possible, the saved group ID of
* the process to the given _integer_. Returns the new
* effective group ID. Not available on all platforms.
*
* [Process.gid, Process.egid] #=> [0, 0]
* Process::GID.grant_privilege(31) #=> 33
* [Process.gid, Process.egid] #=> [0, 33]
*/
static VALUE
p_gid_grant_privilege(obj, id)
VALUE obj, id;
{
return rb_setegid_core(NUM2INT(id));
}
|
.Process::GID.re_exchange ⇒ Fixnum
Exchange real and effective group IDs and return the new effective group ID. Not available on all platforms.
[Process.gid, Process.egid] #=> [0, 33]
Process::GID.re_exchange #=> 0
[Process.gid, Process.egid] #=> [33, 0]
|
# File 'process.c'
/*
* call-seq:
* Process::GID.re_exchange => fixnum
*
* Exchange real and effective group IDs and return the new effective
* group ID. Not available on all platforms.
*
* [Process.gid, Process.egid] #=> [0, 33]
* Process::GID.re_exchange #=> 0
* [Process.gid, Process.egid] #=> [33, 0]
*/
static VALUE
p_gid_exchange(obj)
VALUE obj;
{
int gid, egid;
check_gid_switch();
gid = getgid();
egid = getegid();
#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)
if (setresgid(egid, gid, gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
#elif defined(HAVE_SETREGID) && !defined(OBSOLETE_SETREGID)
if (setregid(egid,gid) < 0) rb_sys_fail(0);
SAVED_GROUP_ID = gid;
#else
rb_notimplement();
#endif
return INT2FIX(gid);
}
|
.Process::GID.re_exchangeable? ⇒ Boolean
Returns true
if the real and effective group IDs of a process may be exchanged on the current platform.
|
# File 'process.c'
/*
* call-seq:
* Process::GID.re_exchangeable? => true or false
*
* Returns +true+ if the real and effective group IDs of a
* process may be exchanged on the current platform.
*
*/
static VALUE
p_gid_exchangeable()
{
#if defined(HAVE_SETRESGID) && !defined(__CHECKER__)
return Qtrue;
#elif defined(HAVE_SETREGID) && !defined(OBSOLETE_SETREGID)
return Qtrue;
#else
return Qfalse;
#endif
}
|
.gid ⇒ Fixnum .Process::GID.rid ⇒ Fixnum .Process::Sys.getgid ⇒ Fixnum
Returns the (real) group ID for this process.
Process.gid #=> 500
|
# File 'process.c'
/*
* call-seq:
* Process.gid => fixnum
* Process::GID.rid => fixnum
* Process::Sys.getgid => fixnum
*
* Returns the (real) group ID for this process.
*
* Process.gid #=> 500
*/
static VALUE
proc_getgid(obj)
VALUE obj;
{
int gid = getgid();
return INT2FIX(gid);
}
|
.Process::GID.sid_available? ⇒ Boolean
Returns true
if the current platform has saved group ID functionality.
|
# File 'process.c'
/*
* call-seq:
* Process::GID.sid_available? => true or false
*
* Returns +true+ if the current platform has saved group
* ID functionality.
*
*/
static VALUE
p_gid_have_saved_id()
{
#if defined(HAVE_SETRESGID) || defined(HAVE_SETEGID) || defined(_POSIX_SAVED_IDS)
return Qtrue;
#else
return Qfalse;
#endif
}
|
.Process::GID.switch ⇒ Fixnum .Process::GID.switch { ... } ⇒ Object
Switch the effective and real group IDs of the current process. If a block is given, the group IDs will be switched back after the block is executed. Returns the new effective group ID if called without a block, and the return value of the block if one is given.
|
# File 'process.c'
/*
* call-seq:
* Process::GID.switch => fixnum
* Process::GID.switch {|| block} => object
*
* Switch the effective and real group IDs of the current process. If
* a <em>block</em> is given, the group IDs will be switched back
* after the block is executed. Returns the new effective group ID if
* called without a block, and the return value of the block if one
* is given.
*
*/
static VALUE
p_gid_switch(obj)
VALUE obj;
{
int gid, egid;
check_gid_switch();
gid = getgid();
egid = getegid();
if (gid != egid) {
proc_setegid(obj, INT2FIX(gid));
if (rb_block_given_p()) {
under_gid_switch = 1;
return rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, SAVED_GROUP_ID);
} else {
return INT2FIX(egid);
}
} else if (egid != SAVED_GROUP_ID) {
proc_setegid(obj, INT2FIX(SAVED_GROUP_ID));
if (rb_block_given_p()) {
under_gid_switch = 1;
return rb_ensure(rb_yield, Qnil, p_gid_sw_ensure, egid);
} else {
return INT2FIX(gid);
}
} else {
errno = EPERM;
rb_sys_fail(0);
}
#else
static VALUE
p_gid_sw_ensure(obj)
VALUE obj;
{
under_gid_switch = 0;
return p_gid_exchange(obj);
}
|