]> git.ipfire.org Git - thirdparty/glibc.git/blame - hurd/hurdauth.c
2005-12-28 Roland McGrath <roland@redhat.com>
[thirdparty/glibc.git] / hurd / hurdauth.c
CommitLineData
c84142e8
UD
1/* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
28f540f4 3
c84142e8 4 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
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.
28f540f4 8
c84142e8
UD
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
41bdb6e2 12 Lesser General Public License for more details.
28f540f4 13
41bdb6e2
AJ
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. */
28f540f4
RM
18
19#include <hurd.h>
20#include <hurd/msg_server.h>
21#include <hurd/id.h>
22#include <string.h>
23
24int
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
34kern_return_t
35_S_msg_add_auth (mach_port_t me,
36 auth_t addauth)
37{
38 error_t err;
39 auth_t newauth;
1f205a47
UD
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;
28f540f4 44
1f205a47
UD
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)
28f540f4
RM
154 return err;
155
1f205a47
UD
156 /* And install it. */
157
28f540f4
RM
158 err = __setauth (newauth);
159 __mach_port_deallocate (__mach_task_self (), newauth);
160 if (err)
161 return errno;
162
163 return 0;
164}
165
166kern_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,
4cca6b86 218 NULL, MACH_MSG_TYPE_COPY_SEND, 0,
28f540f4
RM
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}