]>
Commit | Line | Data |
---|---|---|
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 | ||
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; | |
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 | ||
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, | |
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 | } |