/* This file handles the 4 system calls that get and set uids and gids. * It also handles getpid(), setsid(), and getpgrp(). The code for each * one is so tiny that it hardly seemed worthwhile to make each a separate * function. */ #include "pm.h" #include #include #include "mproc.h" #include "param.h" /*===========================================================================* * do_getset * *===========================================================================*/ PUBLIC int do_getset() { /* Handle GETUID, GETGID, GETPID, GETPGRP, SETUID, SETGID, SETSID. The four * GETs and SETSID return their primary results in 'r'. GETUID, GETGID, and * GETPID also return secondary results (the effective IDs, or the parent * process ID) in 'reply_res2', which is returned to the user. */ register struct mproc *rmp = mp; register int r; switch(call_nr) { case GETUID: r = rmp->mp_realuid; rmp->mp_reply.reply_res2 = rmp->mp_effuid; break; case GETGID: r = rmp->mp_realgid; rmp->mp_reply.reply_res2 = rmp->mp_effgid; break; case GETPID: r = mproc[who].mp_pid; rmp->mp_reply.reply_res2 = mproc[rmp->mp_parent].mp_pid; break; case SETUID: if (rmp->mp_realuid != (uid_t) m_in.usr_id && rmp->mp_effuid != SUPER_USER) return(EPERM); rmp->mp_realuid = (uid_t) m_in.usr_id; rmp->mp_effuid = (uid_t) m_in.usr_id; tell_fs(SETUID, who, rmp->mp_realuid, rmp->mp_effuid); r = OK; break; case SETGID: if (rmp->mp_realgid != (gid_t) m_in.grp_id && rmp->mp_effuid != SUPER_USER) return(EPERM); rmp->mp_realgid = (gid_t) m_in.grp_id; rmp->mp_effgid = (gid_t) m_in.grp_id; tell_fs(SETGID, who, rmp->mp_realgid, rmp->mp_effgid); r = OK; break; case SETSID: if (rmp->mp_procgrp == rmp->mp_pid) return(EPERM); rmp->mp_procgrp = rmp->mp_pid; tell_fs(SETSID, who, 0, 0); /* fall through */ case GETPGRP: r = rmp->mp_procgrp; break; default: r = EINVAL; break; } return(r); }