(linenum→info "unix/slp.c:2238")

glibc/2.7/hurd/hurdauth.c

    1: /* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
    2:    This file is part of the GNU C Library.
    3: 
    4:    The GNU C Library is free software; you can redistribute it and/or
    5:    modify it under the terms of the GNU Lesser General Public
    6:    License as published by the Free Software Foundation; either
    7:    version 2.1 of the License, or (at your option) any later version.
    8: 
    9:    The GNU C Library is distributed in the hope that it will be useful,
   10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12:    Lesser General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU Lesser General Public
   15:    License along with the GNU C Library; if not, write to the Free
   16:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   17:    02111-1307 USA.  */
   18: 
   19: #include <hurd.h>
   20: #include <hurd/msg_server.h>
   21: #include <hurd/id.h>
   22: #include <string.h>
   23: 
   24: int
   25: _hurd_refport_secure_p (mach_port_t ref)
   26: {
   27:   if (ref == __mach_task_self ())
   28:     return 1;
   29:   if (__USEPORT (AUTH, ref == port))
   30:     return 1;
   31:   return 0;
   32: }
   33: 
   34: kern_return_t
   35: _S_msg_add_auth (mach_port_t me,
   36:                  auth_t addauth)
   37: {
   38:   error_t err;
   39:   auth_t newauth;
   40:   uid_t *genuids, *gengids, *auxuids, *auxgids;
   41:   mach_msg_type_number_t ngenuids, ngengids, nauxuids, nauxgids;
   42:   uid_t *newgenuids, *newgengids, *newauxuids, *newauxgids;
   43:   mach_msg_type_number_t nnewgenuids, nnewgengids, nnewauxuids, nnewauxgids;
   44: 
   45:   /* Create a list of ids and store it in NEWLISTP, length NEWLISTLEN.
   46:      Keep all the ids in EXIST (len NEXIST), adding in those from NEW
   47:      (len NNEW) which are not already there.  */
   48:   error_t make_list (uid_t **newlistp, mach_msg_type_number_t *newlistlen,
   49:                      uid_t *exist, mach_msg_type_number_t nexist,
   50:                      uid_t *new, mach_msg_type_number_t nnew)
   51:     {
   52:       error_t urp;
   53:       int i, j, k;
   54:       vm_size_t offset;
   55: 
   56:       urp = vm_allocate (mach_task_self (), (vm_address_t *) newlistp,
   57:                          nexist + nnew * sizeof (uid_t), 1);
   58:       if (urp)
   59:         return urp;
   60: 
   61:       j = 0;
   62:       for (i = 0; i < nexist; i++)
   63:         (*newlistp)[j++] = exist[i];
   64: 
   65:       for (i = 0; i < nnew; i++)
   66:         {
   67:           for (k = 0; k < nexist; k++)
   68:             if (exist[k] == new[i])
   69:               break;
   70:           if (k < nexist)
   71:             continue;
   72: 
   73:           (*newlistp)[j++] = new[i];
   74:         }
   75: 
   76:       offset = (round_page (nexist + nnew * sizeof (uid_t))
   77:                 - round_page (j * sizeof (uid_t)));
   78:       if (offset)
   79:         vm_deallocate (mach_task_self (),
   80:                        (vm_address_t) (*newlistp
   81:                                        + (nexist + nnew * sizeof (uid_t))),
   82:                        offset);
   83:       *newlistlen = j;
   84:       return 0;
   85:     }
   86: 
   87:   /* Find out what ids ADDAUTH refers to */
   88: 
   89:   genuids = gengids = auxuids = auxgids = 0;
   90:   ngenuids = ngengids = nauxuids = nauxgids = 0;
   91:   err = __auth_getids (addauth,
   92:                        &genuids, &ngenuids,
   93:                        &auxuids, &nauxuids,
   94:                        &gengids, &ngengids,
   95:                        &auxgids, &nauxgids);
   96:   if (err)
   97:     return err;
   98: 
   99:   /* OR in these ids to what we already have, creating a new list. */
  100: 
  101:   HURD_CRITICAL_BEGIN;
  102:   __mutex_lock (&_hurd_id.lock);
  103:   _hurd_check_ids ();
  104: 
  105: #define MAKE(genaux,uidgid)                                                 \
  106:   make_list (&new ## genaux ## uidgid ## s,                                 \
  107:              &nnew ## genaux ## uidgid ## s,                               \
  108:              _hurd_id.genaux.uidgid ## s,                                  \
  109:              _hurd_id.genaux.n ## uidgid ## s,                             \
  110:              genaux ## uidgid ## s,                                        \
  111:              n ## genaux ## uidgid ## s)
  112: 
  113:   err = MAKE (gen, uid);
  114:   if (!err)
  115:     MAKE (aux, uid);
  116:   if (!err)
  117:     MAKE (gen, gid);
  118:   if (!err)
  119:     MAKE (aux, gid);
  120: #undef MAKE
  121: 
  122:   __mutex_unlock (&_hurd_id.lock);
  123:   HURD_CRITICAL_END;
  124: 
  125: 
  126:   /* Create the new auth port */
  127: 
  128:   if (!err)
  129:     err = __USEPORT (AUTH,
  130:                      __auth_makeauth (port,
  131:                                       &addauth, MACH_MSG_TYPE_MOVE_SEND, 1,
  132:                                       newgenuids, nnewgenuids,
  133:                                       newauxuids, nnewauxuids,
  134:                                       newgengids, nnewgengids,
  135:                                       newauxgids, nnewauxgids,
  136:                                       &newauth));
  137: 
  138: #define freeup(array, len) \
  139:   if (array) \
  140:     vm_deallocate (mach_task_self (), (vm_address_t) array, \
  141:                    len * sizeof (uid_t));
  142: 
  143:   freeup (genuids, ngenuids);
  144:   freeup (auxuids, nauxuids);
  145:   freeup (gengids, ngengids);
  146:   freeup (auxgids, nauxgids);
  147:   freeup (newgenuids, nnewgenuids);
  148:   freeup (newauxuids, nnewauxuids);
  149:   freeup (newgengids, nnewgengids);
  150:   freeup (newauxgids, nnewauxgids);
  151: #undef freeup
  152: 
  153:   if (err)
  154:     return err;
  155: 
  156:   /* And install it. */
  157: 
  158:   err = __setauth (newauth);
  159:   __mach_port_deallocate (__mach_task_self (), newauth);
  160:   if (err)
  161:     return errno;
  162: 
  163:   return 0;
  164: }
  165: 
  166: kern_return_t
  167: _S_msg_del_auth (mach_port_t me,
  168:                  task_t task,
  169:                  intarray_t uids, mach_msg_type_number_t nuids,
  170:                  intarray_t gids, mach_msg_type_number_t ngids)
  171: {
  172:   error_t err;
  173:   auth_t newauth;
  174: 
  175:   if (!_hurd_refport_secure_p (task))
  176:     return EPERM;
  177: 
  178:   HURD_CRITICAL_BEGIN;
  179:   __mutex_lock (&_hurd_id.lock);
  180:   err = _hurd_check_ids ();
  181: 
  182:   if (!err)
  183:     {
  184:       size_t i, j;
  185:       size_t nu = _hurd_id.gen.nuids, ng = _hurd_id.gen.ngids;
  186:       uid_t newu[nu];
  187:       gid_t newg[ng];
  188: 
  189:       memcpy (newu, _hurd_id.gen.uids, nu * sizeof (uid_t));
  190:       memcpy (newg, _hurd_id.gen.gids, ng * sizeof (gid_t));
  191: 
  192:       for (j = 0; j < nuids; ++j)
  193:         {
  194:           const uid_t uid = uids[j];
  195:           for (i = 0; i < nu; ++i)
  196:             if (newu[i] == uid)
  197:               /* Move the last uid into this slot, and decrease the
  198:                  number of uids so the last slot is no longer used.  */
  199:               newu[i] = newu[--nu];
  200:         }
  201:       __vm_deallocate (__mach_task_self (),
  202:                        (vm_address_t) uids, nuids * sizeof (uid_t));
  203: 
  204:       for (j = 0; j < ngids; ++j)
  205:         {
  206:           const gid_t gid = gids[j];
  207:           for (i = 0; i < nu; ++i)
  208:             if (newu[i] == gid)
  209:               /* Move the last gid into this slot, and decrease the
  210:                  number of gids so the last slot is no longer used.  */
  211:               newu[i] = newu[--nu];
  212:         }
  213:       __vm_deallocate (__mach_task_self (),
  214:                        (vm_address_t) gids, ngids * sizeof (gid_t));
  215: 
  216:       err = __USEPORT (AUTH, __auth_makeauth
  217:                        (port,
  218:                         NULL, MACH_MSG_TYPE_COPY_SEND, 0,
  219:                         newu, nu,
  220:                         _hurd_id.aux.uids, _hurd_id.aux.nuids,
  221:                         newg, ng,
  222:                         _hurd_id.aux.uids, _hurd_id.aux.ngids,
  223:                         &newauth));
  224:     }
  225:   __mutex_unlock (&_hurd_id.lock);
  226:   HURD_CRITICAL_END;
  227: 
  228:   if (err)
  229:     return err;
  230: 
  231:   err = __setauth (newauth);
  232:   __mach_port_deallocate (__mach_task_self (), newauth);
  233:   if (err)
  234:     return errno;
  235: 
  236:   return 0;
  237: }
Syntax (Markdown)