1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
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;
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;
44:
45:
46:
47:
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:
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:
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:
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)
154: return err;
155:
156:
157:
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:
198:
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:
210:
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,
218: NULL, MACH_MSG_TYPE_COPY_SEND, 0,
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: }