int do_setresgid(struct lwp *l, gid_t r, gid_t e, gid_t sv, u_int flags) { struct proc *p = l->l_proc; kauth_cred_t cred, ncred; ncred = kauth_cred_alloc(); /* Get a write lock on the process credential. */ proc_crmod_enter(); cred = p->p_cred; /* * check new value is one of the allowed existing values. * otherwise, check if we have root privilege. */ if ((r != -1 && !((flags & ID_R_EQ_R) && r == kauth_cred_getgid(cred)) && !((flags & ID_R_EQ_E) && r == kauth_cred_getegid(cred)) && !((flags & ID_R_EQ_S) && r == kauth_cred_getsvgid(cred))) || (e != -1 && !((flags & ID_E_EQ_R) && e == kauth_cred_getgid(cred)) && !((flags & ID_E_EQ_E) && e == kauth_cred_getegid(cred)) && !((flags & ID_E_EQ_S) && e == kauth_cred_getsvgid(cred))) || (sv != -1 && !((flags & ID_S_EQ_R) && sv == kauth_cred_getgid(cred)) && !((flags & ID_S_EQ_E) && sv == kauth_cred_getegid(cred)) && !((flags & ID_S_EQ_S) && sv == kauth_cred_getsvgid(cred)))) { int error; error = kauth_authorize_process(cred, KAUTH_PROCESS_SETID, p, NULL, NULL, NULL); if (error != 0) { proc_crmod_leave(cred, ncred, false); return error; } } /* If nothing has changed, short circuit the request */ if ((r == -1 || r == kauth_cred_getgid(cred)) && (e == -1 || e == kauth_cred_getegid(cred)) && (sv == -1 || sv == kauth_cred_getsvgid(cred))) { proc_crmod_leave(cred, ncred, false); return 0; } kauth_cred_clone(cred, ncred); if (r != -1) kauth_cred_setgid(ncred, r); if (sv != -1) kauth_cred_setsvgid(ncred, sv); if (e != -1) kauth_cred_setegid(ncred, e); /* Broadcast our credentials to the process and other LWPs. */ proc_crmod_leave(ncred, cred, true); return 0; }
kauth_cred_t rump_cred_create(uid_t uid, gid_t gid, size_t ngroups, gid_t *groups) { kauth_cred_t cred; int rv; cred = kauth_cred_alloc(); kauth_cred_setuid(cred, uid); kauth_cred_seteuid(cred, uid); kauth_cred_setsvuid(cred, uid); kauth_cred_setgid(cred, gid); kauth_cred_setgid(cred, gid); kauth_cred_setegid(cred, gid); kauth_cred_setsvgid(cred, gid); rv = kauth_cred_setgroups(cred, groups, ngroups, 0, UIO_SYSSPACE); /* oh this is silly. and by "this" I mean kauth_cred_setgroups() */ assert(rv == 0); return cred; }