]> git.ipfire.org Git - thirdparty/glibc.git/blame - hurd/hurdauth.c
y2038: Introduce struct __timespec64 - new internal glibc type
[thirdparty/glibc.git] / hurd / hurdauth.c
CommitLineData
04277e02 1/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
c84142e8 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 14 You should have received a copy of the GNU Lesser General Public
59ba27a6 15 License along with the GNU C Library; if not, see
5a82c748 16 <https://www.gnu.org/licenses/>. */
28f540f4
RM
17
18#include <hurd.h>
19#include <hurd/msg_server.h>
20#include <hurd/id.h>
21#include <string.h>
22
23int
24_hurd_refport_secure_p (mach_port_t ref)
25{
26 if (ref == __mach_task_self ())
27 return 1;
28 if (__USEPORT (AUTH, ref == port))
29 return 1;
30 return 0;
31}
32
33kern_return_t
34_S_msg_add_auth (mach_port_t me,
35 auth_t addauth)
36{
37 error_t err;
38 auth_t newauth;
1f205a47
UD
39 uid_t *genuids, *gengids, *auxuids, *auxgids;
40 mach_msg_type_number_t ngenuids, ngengids, nauxuids, nauxgids;
41 uid_t *newgenuids, *newgengids, *newauxuids, *newauxgids;
42 mach_msg_type_number_t nnewgenuids, nnewgengids, nnewauxuids, nnewauxgids;
28f540f4 43
1f205a47
UD
44 /* Create a list of ids and store it in NEWLISTP, length NEWLISTLEN.
45 Keep all the ids in EXIST (len NEXIST), adding in those from NEW
46 (len NNEW) which are not already there. */
47 error_t make_list (uid_t **newlistp, mach_msg_type_number_t *newlistlen,
48 uid_t *exist, mach_msg_type_number_t nexist,
49 uid_t *new, mach_msg_type_number_t nnew)
50 {
51 error_t urp;
52 int i, j, k;
53 vm_size_t offset;
54
dba2bdbe
ST
55 urp = __vm_allocate (mach_task_self (), (vm_address_t *) newlistp,
56 nexist + nnew * sizeof (uid_t), 1);
1f205a47
UD
57 if (urp)
58 return urp;
59
60 j = 0;
61 for (i = 0; i < nexist; i++)
62 (*newlistp)[j++] = exist[i];
63
64 for (i = 0; i < nnew; i++)
65 {
66 for (k = 0; k < nexist; k++)
67 if (exist[k] == new[i])
68 break;
69 if (k < nexist)
70 continue;
71
72 (*newlistp)[j++] = new[i];
73 }
74
75 offset = (round_page (nexist + nnew * sizeof (uid_t))
76 - round_page (j * sizeof (uid_t)));
77 if (offset)
dba2bdbe
ST
78 __vm_deallocate (mach_task_self (),
79 (vm_address_t) (*newlistp
80 + (nexist + nnew * sizeof (uid_t))),
81 offset);
1f205a47
UD
82 *newlistlen = j;
83 return 0;
84 }
85
86 /* Find out what ids ADDAUTH refers to */
87
88 genuids = gengids = auxuids = auxgids = 0;
89 ngenuids = ngengids = nauxuids = nauxgids = 0;
90 err = __auth_getids (addauth,
91 &genuids, &ngenuids,
92 &auxuids, &nauxuids,
93 &gengids, &ngengids,
94 &auxgids, &nauxgids);
95 if (err)
96 return err;
97
98 /* OR in these ids to what we already have, creating a new list. */
99
100 HURD_CRITICAL_BEGIN;
101 __mutex_lock (&_hurd_id.lock);
102 _hurd_check_ids ();
103
104#define MAKE(genaux,uidgid) \
105 make_list (&new ## genaux ## uidgid ## s, \
106 &nnew ## genaux ## uidgid ## s, \
107 _hurd_id.genaux.uidgid ## s, \
108 _hurd_id.genaux.n ## uidgid ## s, \
109 genaux ## uidgid ## s, \
110 n ## genaux ## uidgid ## s)
111
112 err = MAKE (gen, uid);
113 if (!err)
114 MAKE (aux, uid);
115 if (!err)
116 MAKE (gen, gid);
117 if (!err)
118 MAKE (aux, gid);
119#undef MAKE
120
121 __mutex_unlock (&_hurd_id.lock);
122 HURD_CRITICAL_END;
123
124
125 /* Create the new auth port */
126
127 if (!err)
128 err = __USEPORT (AUTH,
129 __auth_makeauth (port,
130 &addauth, MACH_MSG_TYPE_MOVE_SEND, 1,
131 newgenuids, nnewgenuids,
132 newauxuids, nnewauxuids,
133 newgengids, nnewgengids,
134 newauxgids, nnewauxgids,
135 &newauth));
136
137#define freeup(array, len) \
138 if (array) \
dba2bdbe
ST
139 __vm_deallocate (mach_task_self (), (vm_address_t) array, \
140 len * sizeof (uid_t));
1f205a47
UD
141
142 freeup (genuids, ngenuids);
143 freeup (auxuids, nauxuids);
144 freeup (gengids, ngengids);
145 freeup (auxgids, nauxgids);
146 freeup (newgenuids, nnewgenuids);
147 freeup (newauxuids, nnewauxuids);
148 freeup (newgengids, nnewgengids);
149 freeup (newauxgids, nnewauxgids);
150#undef freeup
151
152 if (err)
28f540f4
RM
153 return err;
154
1f205a47
UD
155 /* And install it. */
156
28f540f4
RM
157 err = __setauth (newauth);
158 __mach_port_deallocate (__mach_task_self (), newauth);
159 if (err)
160 return errno;
161
162 return 0;
163}
164
165kern_return_t
166_S_msg_del_auth (mach_port_t me,
167 task_t task,
168 intarray_t uids, mach_msg_type_number_t nuids,
169 intarray_t gids, mach_msg_type_number_t ngids)
170{
171 error_t err;
172 auth_t newauth;
173
174 if (!_hurd_refport_secure_p (task))
175 return EPERM;
176
177 HURD_CRITICAL_BEGIN;
178 __mutex_lock (&_hurd_id.lock);
179 err = _hurd_check_ids ();
180
181 if (!err)
182 {
183 size_t i, j;
184 size_t nu = _hurd_id.gen.nuids, ng = _hurd_id.gen.ngids;
185 uid_t newu[nu];
186 gid_t newg[ng];
187
188 memcpy (newu, _hurd_id.gen.uids, nu * sizeof (uid_t));
189 memcpy (newg, _hurd_id.gen.gids, ng * sizeof (gid_t));
190
191 for (j = 0; j < nuids; ++j)
192 {
193 const uid_t uid = uids[j];
194 for (i = 0; i < nu; ++i)
195 if (newu[i] == uid)
196 /* Move the last uid into this slot, and decrease the
197 number of uids so the last slot is no longer used. */
198 newu[i] = newu[--nu];
199 }
200 __vm_deallocate (__mach_task_self (),
201 (vm_address_t) uids, nuids * sizeof (uid_t));
202
203 for (j = 0; j < ngids; ++j)
204 {
205 const gid_t gid = gids[j];
206 for (i = 0; i < nu; ++i)
207 if (newu[i] == gid)
208 /* Move the last gid into this slot, and decrease the
209 number of gids so the last slot is no longer used. */
210 newu[i] = newu[--nu];
211 }
212 __vm_deallocate (__mach_task_self (),
213 (vm_address_t) gids, ngids * sizeof (gid_t));
214
215 err = __USEPORT (AUTH, __auth_makeauth
216 (port,
4cca6b86 217 NULL, MACH_MSG_TYPE_COPY_SEND, 0,
28f540f4
RM
218 newu, nu,
219 _hurd_id.aux.uids, _hurd_id.aux.nuids,
220 newg, ng,
221 _hurd_id.aux.uids, _hurd_id.aux.ngids,
222 &newauth));
223 }
224 __mutex_unlock (&_hurd_id.lock);
225 HURD_CRITICAL_END;
226
227 if (err)
228 return err;
229
230 err = __setauth (newauth);
231 __mach_port_deallocate (__mach_task_self (), newauth);
232 if (err)
233 return errno;
234
235 return 0;
236}