123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- /* Copyright (C) 1991-2019 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
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
- #include <hurd.h>
- #include <hurd/msg_server.h>
- #include <hurd/id.h>
- #include <string.h>
- int
- _hurd_refport_secure_p (mach_port_t ref)
- {
- if (ref == __mach_task_self ())
- return 1;
- if (__USEPORT (AUTH, ref == port))
- return 1;
- return 0;
- }
- kern_return_t
- _S_msg_add_auth (mach_port_t me,
- auth_t addauth)
- {
- error_t err;
- auth_t newauth;
- uid_t *genuids, *gengids, *auxuids, *auxgids;
- mach_msg_type_number_t ngenuids, ngengids, nauxuids, nauxgids;
- uid_t *newgenuids, *newgengids, *newauxuids, *newauxgids;
- mach_msg_type_number_t nnewgenuids, nnewgengids, nnewauxuids, nnewauxgids;
- /* Create a list of ids and store it in NEWLISTP, length NEWLISTLEN.
- Keep all the ids in EXIST (len NEXIST), adding in those from NEW
- (len NNEW) which are not already there. */
- error_t make_list (uid_t **newlistp, mach_msg_type_number_t *newlistlen,
- uid_t *exist, mach_msg_type_number_t nexist,
- uid_t *new, mach_msg_type_number_t nnew)
- {
- error_t urp;
- int i, j, k;
- vm_size_t offset;
- urp = __vm_allocate (mach_task_self (), (vm_address_t *) newlistp,
- nexist + nnew * sizeof (uid_t), 1);
- if (urp)
- return urp;
- j = 0;
- for (i = 0; i < nexist; i++)
- (*newlistp)[j++] = exist[i];
- for (i = 0; i < nnew; i++)
- {
- for (k = 0; k < nexist; k++)
- if (exist[k] == new[i])
- break;
- if (k < nexist)
- continue;
- (*newlistp)[j++] = new[i];
- }
- offset = (round_page (nexist + nnew * sizeof (uid_t))
- - round_page (j * sizeof (uid_t)));
- if (offset)
- __vm_deallocate (mach_task_self (),
- (vm_address_t) (*newlistp
- + (nexist + nnew * sizeof (uid_t))),
- offset);
- *newlistlen = j;
- return 0;
- }
- /* Find out what ids ADDAUTH refers to */
- genuids = gengids = auxuids = auxgids = 0;
- ngenuids = ngengids = nauxuids = nauxgids = 0;
- err = __auth_getids (addauth,
- &genuids, &ngenuids,
- &auxuids, &nauxuids,
- &gengids, &ngengids,
- &auxgids, &nauxgids);
- if (err)
- return err;
- /* OR in these ids to what we already have, creating a new list. */
- HURD_CRITICAL_BEGIN;
- __mutex_lock (&_hurd_id.lock);
- _hurd_check_ids ();
- #define MAKE(genaux,uidgid) \
- make_list (&new ## genaux ## uidgid ## s, \
- &nnew ## genaux ## uidgid ## s, \
- _hurd_id.genaux.uidgid ## s, \
- _hurd_id.genaux.n ## uidgid ## s, \
- genaux ## uidgid ## s, \
- n ## genaux ## uidgid ## s)
- err = MAKE (gen, uid);
- if (!err)
- MAKE (aux, uid);
- if (!err)
- MAKE (gen, gid);
- if (!err)
- MAKE (aux, gid);
- #undef MAKE
- __mutex_unlock (&_hurd_id.lock);
- HURD_CRITICAL_END;
- /* Create the new auth port */
- if (!err)
- err = __USEPORT (AUTH,
- __auth_makeauth (port,
- &addauth, MACH_MSG_TYPE_MOVE_SEND, 1,
- newgenuids, nnewgenuids,
- newauxuids, nnewauxuids,
- newgengids, nnewgengids,
- newauxgids, nnewauxgids,
- &newauth));
- #define freeup(array, len) \
- if (array) \
- __vm_deallocate (mach_task_self (), (vm_address_t) array, \
- len * sizeof (uid_t));
- freeup (genuids, ngenuids);
- freeup (auxuids, nauxuids);
- freeup (gengids, ngengids);
- freeup (auxgids, nauxgids);
- freeup (newgenuids, nnewgenuids);
- freeup (newauxuids, nnewauxuids);
- freeup (newgengids, nnewgengids);
- freeup (newauxgids, nnewauxgids);
- #undef freeup
- if (err)
- return err;
- /* And install it. */
- err = __setauth (newauth);
- __mach_port_deallocate (__mach_task_self (), newauth);
- if (err)
- return errno;
- return 0;
- }
- kern_return_t
- _S_msg_del_auth (mach_port_t me,
- task_t task,
- intarray_t uids, mach_msg_type_number_t nuids,
- intarray_t gids, mach_msg_type_number_t ngids)
- {
- error_t err;
- auth_t newauth;
- if (!_hurd_refport_secure_p (task))
- return EPERM;
- HURD_CRITICAL_BEGIN;
- __mutex_lock (&_hurd_id.lock);
- err = _hurd_check_ids ();
- if (!err)
- {
- size_t i, j;
- size_t nu = _hurd_id.gen.nuids, ng = _hurd_id.gen.ngids;
- uid_t newu[nu];
- gid_t newg[ng];
- memcpy (newu, _hurd_id.gen.uids, nu * sizeof (uid_t));
- memcpy (newg, _hurd_id.gen.gids, ng * sizeof (gid_t));
- for (j = 0; j < nuids; ++j)
- {
- const uid_t uid = uids[j];
- for (i = 0; i < nu; ++i)
- if (newu[i] == uid)
- /* Move the last uid into this slot, and decrease the
- number of uids so the last slot is no longer used. */
- newu[i] = newu[--nu];
- }
- __vm_deallocate (__mach_task_self (),
- (vm_address_t) uids, nuids * sizeof (uid_t));
- for (j = 0; j < ngids; ++j)
- {
- const gid_t gid = gids[j];
- for (i = 0; i < nu; ++i)
- if (newu[i] == gid)
- /* Move the last gid into this slot, and decrease the
- number of gids so the last slot is no longer used. */
- newu[i] = newu[--nu];
- }
- __vm_deallocate (__mach_task_self (),
- (vm_address_t) gids, ngids * sizeof (gid_t));
- err = __USEPORT (AUTH, __auth_makeauth
- (port,
- NULL, MACH_MSG_TYPE_COPY_SEND, 0,
- newu, nu,
- _hurd_id.aux.uids, _hurd_id.aux.nuids,
- newg, ng,
- _hurd_id.aux.uids, _hurd_id.aux.ngids,
- &newauth));
- }
- __mutex_unlock (&_hurd_id.lock);
- HURD_CRITICAL_END;
- if (err)
- return err;
- err = __setauth (newauth);
- __mach_port_deallocate (__mach_task_self (), newauth);
- if (err)
- return errno;
- return 0;
- }
|