Back to index

glibc  2.9
hurdauth.c
Go to the documentation of this file.
00001 /* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <hurd.h>
00020 #include <hurd/msg_server.h>
00021 #include <hurd/id.h>
00022 #include <string.h>
00023 
00024 int
00025 _hurd_refport_secure_p (mach_port_t ref)
00026 {
00027   if (ref == __mach_task_self ())
00028     return 1;
00029   if (__USEPORT (AUTH, ref == port))
00030     return 1;
00031   return 0;
00032 }
00033 
00034 kern_return_t
00035 _S_msg_add_auth (mach_port_t me,
00036                auth_t addauth)
00037 {
00038   error_t err;
00039   auth_t newauth;
00040   uid_t *genuids, *gengids, *auxuids, *auxgids;
00041   mach_msg_type_number_t ngenuids, ngengids, nauxuids, nauxgids;
00042   uid_t *newgenuids, *newgengids, *newauxuids, *newauxgids;
00043   mach_msg_type_number_t nnewgenuids, nnewgengids, nnewauxuids, nnewauxgids;
00044 
00045   /* Create a list of ids and store it in NEWLISTP, length NEWLISTLEN.
00046      Keep all the ids in EXIST (len NEXIST), adding in those from NEW
00047      (len NNEW) which are not already there.  */
00048   error_t make_list (uid_t **newlistp, mach_msg_type_number_t *newlistlen,
00049                    uid_t *exist, mach_msg_type_number_t nexist,
00050                    uid_t *new, mach_msg_type_number_t nnew)
00051     {
00052       error_t urp;
00053       int i, j, k;
00054       vm_size_t offset;
00055 
00056       urp = vm_allocate (mach_task_self (), (vm_address_t *) newlistp,
00057                       nexist + nnew * sizeof (uid_t), 1);
00058       if (urp)
00059        return urp;
00060 
00061       j = 0;
00062       for (i = 0; i < nexist; i++)
00063        (*newlistp)[j++] = exist[i];
00064 
00065       for (i = 0; i < nnew; i++)
00066        {
00067          for (k = 0; k < nexist; k++)
00068            if (exist[k] == new[i])
00069              break;
00070          if (k < nexist)
00071            continue;
00072 
00073          (*newlistp)[j++] = new[i];
00074        }
00075 
00076       offset = (round_page (nexist + nnew * sizeof (uid_t))
00077               - round_page (j * sizeof (uid_t)));
00078       if (offset)
00079        vm_deallocate (mach_task_self (),
00080                      (vm_address_t) (*newlistp
00081                                    + (nexist + nnew * sizeof (uid_t))),
00082                      offset);
00083       *newlistlen = j;
00084       return 0;
00085     }
00086 
00087   /* Find out what ids ADDAUTH refers to */
00088 
00089   genuids = gengids = auxuids = auxgids = 0;
00090   ngenuids = ngengids = nauxuids = nauxgids = 0;
00091   err = __auth_getids (addauth,
00092                      &genuids, &ngenuids,
00093                      &auxuids, &nauxuids,
00094                      &gengids, &ngengids,
00095                      &auxgids, &nauxgids);
00096   if (err)
00097     return err;
00098 
00099   /* OR in these ids to what we already have, creating a new list. */
00100 
00101   HURD_CRITICAL_BEGIN;
00102   __mutex_lock (&_hurd_id.lock);
00103   _hurd_check_ids ();
00104 
00105 #define MAKE(genaux,uidgid)                                               \
00106   make_list (&new ## genaux ## uidgid ## s,                               \
00107             &nnew ## genaux ## uidgid ## s,                               \
00108             _hurd_id.genaux.uidgid ## s,                           \
00109             _hurd_id.genaux.n ## uidgid ## s,                             \
00110             genaux ## uidgid ## s,                                 \
00111             n ## genaux ## uidgid ## s)
00112 
00113   err = MAKE (gen, uid);
00114   if (!err)
00115     MAKE (aux, uid);
00116   if (!err)
00117     MAKE (gen, gid);
00118   if (!err)
00119     MAKE (aux, gid);
00120 #undef MAKE
00121 
00122   __mutex_unlock (&_hurd_id.lock);
00123   HURD_CRITICAL_END;
00124 
00125 
00126   /* Create the new auth port */
00127 
00128   if (!err)
00129     err = __USEPORT (AUTH,
00130                    __auth_makeauth (port,
00131                                   &addauth, MACH_MSG_TYPE_MOVE_SEND, 1,
00132                                   newgenuids, nnewgenuids,
00133                                   newauxuids, nnewauxuids,
00134                                   newgengids, nnewgengids,
00135                                   newauxgids, nnewauxgids,
00136                                   &newauth));
00137 
00138 #define freeup(array, len) \
00139   if (array) \
00140     vm_deallocate (mach_task_self (), (vm_address_t) array, \
00141                  len * sizeof (uid_t));
00142 
00143   freeup (genuids, ngenuids);
00144   freeup (auxuids, nauxuids);
00145   freeup (gengids, ngengids);
00146   freeup (auxgids, nauxgids);
00147   freeup (newgenuids, nnewgenuids);
00148   freeup (newauxuids, nnewauxuids);
00149   freeup (newgengids, nnewgengids);
00150   freeup (newauxgids, nnewauxgids);
00151 #undef freeup
00152 
00153   if (err)
00154     return err;
00155 
00156   /* And install it. */
00157 
00158   err = __setauth (newauth);
00159   __mach_port_deallocate (__mach_task_self (), newauth);
00160   if (err)
00161     return errno;
00162 
00163   return 0;
00164 }
00165 
00166 kern_return_t
00167 _S_msg_del_auth (mach_port_t me,
00168                task_t task,
00169                intarray_t uids, mach_msg_type_number_t nuids,
00170                intarray_t gids, mach_msg_type_number_t ngids)
00171 {
00172   error_t err;
00173   auth_t newauth;
00174 
00175   if (!_hurd_refport_secure_p (task))
00176     return EPERM;
00177 
00178   HURD_CRITICAL_BEGIN;
00179   __mutex_lock (&_hurd_id.lock);
00180   err = _hurd_check_ids ();
00181 
00182   if (!err)
00183     {
00184       size_t i, j;
00185       size_t nu = _hurd_id.gen.nuids, ng = _hurd_id.gen.ngids;
00186       uid_t newu[nu];
00187       gid_t newg[ng];
00188 
00189       memcpy (newu, _hurd_id.gen.uids, nu * sizeof (uid_t));
00190       memcpy (newg, _hurd_id.gen.gids, ng * sizeof (gid_t));
00191 
00192       for (j = 0; j < nuids; ++j)
00193        {
00194          const uid_t uid = uids[j];
00195          for (i = 0; i < nu; ++i)
00196            if (newu[i] == uid)
00197              /* Move the last uid into this slot, and decrease the
00198                number of uids so the last slot is no longer used.  */
00199              newu[i] = newu[--nu];
00200        }
00201       __vm_deallocate (__mach_task_self (),
00202                      (vm_address_t) uids, nuids * sizeof (uid_t));
00203 
00204       for (j = 0; j < ngids; ++j)
00205        {
00206          const gid_t gid = gids[j];
00207          for (i = 0; i < nu; ++i)
00208            if (newu[i] == gid)
00209              /* Move the last gid into this slot, and decrease the
00210                number of gids so the last slot is no longer used.  */
00211              newu[i] = newu[--nu];
00212        }
00213       __vm_deallocate (__mach_task_self (),
00214                      (vm_address_t) gids, ngids * sizeof (gid_t));
00215 
00216       err = __USEPORT (AUTH, __auth_makeauth
00217                      (port,
00218                      NULL, MACH_MSG_TYPE_COPY_SEND, 0,
00219                      newu, nu,
00220                      _hurd_id.aux.uids, _hurd_id.aux.nuids,
00221                      newg, ng,
00222                      _hurd_id.aux.uids, _hurd_id.aux.ngids,
00223                      &newauth));
00224     }
00225   __mutex_unlock (&_hurd_id.lock);
00226   HURD_CRITICAL_END;
00227 
00228   if (err)
00229     return err;
00230 
00231   err = __setauth (newauth);
00232   __mach_port_deallocate (__mach_task_self (), newauth);
00233   if (err)
00234     return errno;
00235 
00236   return 0;
00237 }