diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-05-10 15:34:53 -0700 |
---|---|---|
committer | Roland McGrath <roland@hack.frob.com> | 2012-05-10 15:57:27 -0700 |
commit | 3faebe6abc04ea8d632bee4537948ca85479c09a (patch) | |
tree | 3138bd56489f91b5b63072c9e45be1851827e297 /sysdeps/mach/hurd/setresgid.c | |
parent | c6474b07e7b5f0cdc9089c1c4fcfc4fcaa2bcd92 (diff) | |
download | glibc-3faebe6abc04ea8d632bee4537948ca85479c09a.tar.gz glibc-3faebe6abc04ea8d632bee4537948ca85479c09a.tar.xz glibc-3faebe6abc04ea8d632bee4537948ca85479c09a.zip |
Hurd: Fix setres[ug]id handling of -1
Diffstat (limited to 'sysdeps/mach/hurd/setresgid.c')
-rw-r--r-- | sysdeps/mach/hurd/setresgid.c | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/sysdeps/mach/hurd/setresgid.c b/sysdeps/mach/hurd/setresgid.c index 9d5885beda..eebd364fc6 100644 --- a/sysdeps/mach/hurd/setresgid.c +++ b/sysdeps/mach/hurd/setresgid.c @@ -1,5 +1,5 @@ /* setresgid -- set real group ID, effective group ID, and saved-set group ID - Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2002-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,6 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) { auth_t newauth; error_t err; - gid_t agids[2] = { rgid, sgid }; HURD_CRITICAL_BEGIN; __mutex_lock (&_hurd_id.lock); @@ -37,31 +36,78 @@ __setresgid (gid_t rgid, gid_t egid, gid_t sgid) if (!err) { /* Make a new auth handle which has EGID as the first element in the - list of effective gids. */ + list of effective gids. */ - if (_hurd_id.gen.ngids > 0) + uid_t *newgen, *newaux; + uid_t auxs[2] = { rgid, sgid }; + size_t ngen, naux; + + newgen = _hurd_id.gen.gids; + ngen = _hurd_id.gen.ngids; + if (egid != -1) + { + if (_hurd_id.gen.ngids == 0) + { + /* No effective gids now. The new set will be just UID. */ + newgen = &egid; + ngen = 1; + } + else + { + _hurd_id.gen.gids[0] = egid; + _hurd_id.valid = 0; + } + } + + newaux = _hurd_id.aux.gids; + naux = _hurd_id.aux.ngids; + if (rgid != -1) { - _hurd_id.gen.gids[0] = egid; - _hurd_id.valid = 0; + if (_hurd_id.aux.ngids == 0) + { + newaux = &rgid; + naux = 1; + } + else + { + _hurd_id.aux.gids[0] = rgid; + _hurd_id.valid = 0; + } } - if (_hurd_id.aux.ngids > 1) + + if (sgid != -1) { - _hurd_id.aux.gids[0] = rgid; - _hurd_id.aux.gids[1] = sgid; - _hurd_id.valid = 0; + if (rgid == -1) + { + if (_hurd_id.aux.ngids >= 1) + auxs[0] = _hurd_id.aux.gids[0]; + else if (_hurd_id.gen.ngids >= 1) + auxs[0] = _hurd_id.gen.gids[0]; + else + /* Not even an effective GID. + Fall back to the only GID we have. */ + auxs[0] = sgid; + } + if (_hurd_id.aux.ngids <= 1) + { + /* No saved gids now. The new set will be just UID. */ + newaux = auxs; + naux = 2; + } + else + { + _hurd_id.aux.gids[1] = sgid; + _hurd_id.valid = 0; + } } err = __USEPORT (AUTH, __auth_makeauth (port, NULL, MACH_MSG_TYPE_COPY_SEND, 0, _hurd_id.gen.uids, _hurd_id.gen.nuids, _hurd_id.aux.uids, _hurd_id.aux.nuids, - _hurd_id.gen.ngids ? _hurd_id.gen.gids : &egid, - _hurd_id.gen.ngids ?: 1, - _hurd_id.aux.ngids > 1 ? _hurd_id.aux.gids : agids, - _hurd_id.aux.ngids > 1 ? _hurd_id.aux.ngids : 2, + newgen, ngen, newaux, naux, &newauth)); } - __mutex_unlock (&_hurd_id.lock); HURD_CRITICAL_END; |