Formerly ../hurd/hurdauth.c.~13~
[kopensolaris-gnu/glibc.git] / hurd / hurdauth.c
1 /* Copyright (C) 1991, 1992, 1993, 1994 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 Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 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 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB.  If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA.  */
18
19 #include <hurd.h>
20 #include "hurd/msg_server.h"
21
22 int
23 _hurd_refport_secure_p (mach_port_t ref)
24 {
25   if (ref == __mach_task_self ())
26     return 1;
27   if (__USEPORT (AUTH, ref == port))
28     return 1;
29   return 0;
30 }
31
32 error_t
33 _S_add_auth (mach_port_t me,
34              auth_t addauth)
35 {
36   error_t err;
37   auth_t newauth;
38
39   if (err = __USEPORT (AUTH,
40                        __auth_makeauth (port,
41                                         &addauth, 1, MACH_MSG_TYPE_MOVE_SEND,
42                                         NULL, 0,
43                                         NULL, 0,
44                                         NULL, 0,
45                                         NULL, 0,
46                                         &newauth)))
47     return err;
48
49   /* XXX clobbers errno. Need per-thread errno. */
50   err = __setauth (newauth);
51   __mach_port_deallocate (__mach_task_self (), newauth);
52   if (err)
53     return errno;
54
55   return 0;
56 }
57
58 error_t
59 _S_del_auth (mach_port_t me,
60              task_t task,
61              intarray_t uids, mach_msg_type_number_t nuids,
62              intarray_t gids, mach_msg_type_number_t ngids)
63 {
64   error_t err;
65   auth_t newauth;
66
67   if (!_hurd_refport_secure_p (task))
68     return EPERM;
69
70   __mutex_lock (&_hurd_id.lock);
71   err = _hurd_check_ids ();
72
73   if (!err)
74     {
75       size_t i, j;
76       size_t nu = _hurd_id.gen.nuids, ng = _hurd_id.gen.ngids;
77       uid_t newu[nu];
78       gid_t newg[ng];
79
80       memcpy (newu, _hurd_id.gen.uids, nu * sizeof (uid_t));
81       memcpy (newg, _hurd_id.gen.gids, ng * sizeof (gid_t));
82
83       for (j = 0; j < nuids; ++j)
84         {
85           const uid_t uid = uids[j];
86           for (i = 0; i < nu; ++i)
87             if (newu[i] == uid)
88               /* Move the last uid into this slot, and decrease the
89                  number of uids so the last slot is no longer used.  */
90               newu[i] = newu[--nu];
91         }
92       __vm_deallocate (__mach_task_self (),
93                        (vm_address_t) uids, nuids * sizeof (uid_t));
94
95       for (j = 0; j < ngids; ++j)
96         {
97           const gid_t gid = gids[j];
98           for (i = 0; i < nu; ++i)
99             if (newu[i] == gid)
100               /* Move the last gid into this slot, and decrease the
101                  number of gids so the last slot is no longer used.  */
102               newu[i] = newu[--nu];
103         }
104       __vm_deallocate (__mach_task_self (),
105                        (vm_address_t) gids, ngids * sizeof (gid_t));
106
107       err = __USEPORT (AUTH, __auth_makeauth
108                        (port,
109                         NULL, 0, MACH_MSG_TYPE_COPY_SEND,
110                         newu, nu,
111                         _hurd_id.aux.uids, _hurd_id.aux.nuids,
112                         newg, ng,
113                         _hurd_id.aux.uids, _hurd_id.aux.ngids,
114                         &newauth));
115     }
116   __mutex_unlock (&_hurd_id.lock);
117
118   if (err)
119     return err;
120
121   err = __setauth (newauth);    /* XXX clobbers errno */
122   __mach_port_deallocate (__mach_task_self (), newauth);
123   if (err)
124     return errno;
125
126   return 0;
127 }