Formerly ../hurd/hurdauth.c.~12~
[kopensolaris-gnu/glibc.git] / hurd / hurdauth.c
1 /* Copyright (C) 1991, 1992, 1993 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, __auth_combine (port, addauth, &newauth)))
40     return err;
41
42   /* XXX clobbers errno. Need per-thread errno. */
43   err = __setauth (newauth);
44   __mach_port_deallocate (__mach_task_self (), newauth);
45   if (err)
46     return errno;
47
48   __mach_port_deallocate (__mach_task_self (), addauth);
49   return 0;
50 }
51
52 error_t
53 _S_del_auth (mach_port_t me,
54              task_t task,
55              intarray_t uids, mach_msg_type_number_t nuids,
56              intarray_t gids, mach_msg_type_number_t ngids)
57 {
58   error_t err;
59   auth_t newauth;
60
61   if (!_hurd_refport_secure_p (task))
62     return EPERM;
63
64   __mutex_lock (&_hurd_id.lock);
65   err = _hurd_check_ids ();
66
67   if (!err)
68     {
69       size_t i, j;
70       size_t nu = _hurd_id.gen.nuids, ng = _hurd_id.gen.ngids;
71       uid_t newu[nu];
72       gid_t newg[ng];
73
74       memcpy (newu, _hurd_id.gen.uids, nu * sizeof (uid_t));
75       memcpy (newg, _hurd_id.gen.gids, ng * sizeof (gid_t));
76
77       for (j = 0; j < nuids; ++j)
78         {
79           const uid_t uid = uids[j];
80           for (i = 0; i < nu; ++i)
81             if (newu[i] == uid)
82               /* Move the last uid into this slot, and decrease the
83                  number of uids so the last slot is no longer used.  */
84               newu[i] = newu[--nu];
85         }
86       __vm_deallocate (__mach_task_self (),
87                        (vm_address_t) uids, nuids * sizeof (uid_t));
88
89       for (j = 0; j < ngids; ++j)
90         {
91           const gid_t gid = gids[j];
92           for (i = 0; i < nu; ++i)
93             if (newu[i] == gid)
94               /* Move the last gid into this slot, and decrease the
95                  number of gids so the last slot is no longer used.  */
96               newu[i] = newu[--nu];
97         }
98       __vm_deallocate (__mach_task_self (),
99                        (vm_address_t) gids, ngids * sizeof (gid_t));
100
101       err = __USEPORT (AUTH, __auth_makeauth
102                        (port,
103                         newu, nu,
104                         _hurd_id.aux.uids, _hurd_id.aux.nuids,
105                         newg, ng,
106                         _hurd_id.aux.uids, _hurd_id.aux.ngids,
107                         &newauth));
108     }
109   __mutex_unlock (&_hurd_id.lock);
110
111   if (err)
112     return err;
113
114   err = __setauth (newauth);    /* XXX clobbers errno */
115   __mach_port_deallocate (__mach_task_self (), newauth);
116   if (err)
117     return errno;
118
119   return 0;
120 }