Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /************************************************************ |
2 | ||
3 | Author: Eamon Walsh <ewalsh@tycho.nsa.gov> | |
4 | ||
5 | Permission to use, copy, modify, distribute, and sell this software and its | |
6 | documentation for any purpose is hereby granted without fee, provided that | |
7 | this permission notice appear in supporting documentation. This permission | |
8 | notice shall be included in all copies or substantial portions of the | |
9 | Software. | |
10 | ||
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
13 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
14 | AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |
15 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
16 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
17 | ||
18 | ********************************************************/ | |
19 | ||
20 | #ifdef HAVE_DIX_CONFIG_H | |
21 | #include <dix-config.h> | |
22 | #endif | |
23 | ||
24 | #include "selection.h" | |
25 | #include "inputstr.h" | |
26 | #include "windowstr.h" | |
27 | #include "propertyst.h" | |
28 | #include "extnsionst.h" | |
29 | #include "extinit.h" | |
30 | #include "xselinuxint.h" | |
31 | ||
32 | #define CTX_DEV offsetof(SELinuxSubjectRec, dev_create_sid) | |
33 | #define CTX_WIN offsetof(SELinuxSubjectRec, win_create_sid) | |
34 | #define CTX_PRP offsetof(SELinuxSubjectRec, prp_create_sid) | |
35 | #define CTX_SEL offsetof(SELinuxSubjectRec, sel_create_sid) | |
36 | #define USE_PRP offsetof(SELinuxSubjectRec, prp_use_sid) | |
37 | #define USE_SEL offsetof(SELinuxSubjectRec, sel_use_sid) | |
38 | ||
39 | typedef struct { | |
40 | security_context_t octx; | |
41 | security_context_t dctx; | |
42 | CARD32 octx_len; | |
43 | CARD32 dctx_len; | |
44 | CARD32 id; | |
45 | } SELinuxListItemRec; | |
46 | ||
47 | /* | |
48 | * Extension Dispatch | |
49 | */ | |
50 | ||
51 | static security_context_t | |
52 | SELinuxCopyContext(char *ptr, unsigned len) | |
53 | { | |
54 | security_context_t copy = malloc(len + 1); | |
55 | ||
56 | if (!copy) | |
57 | return NULL; | |
58 | strncpy(copy, ptr, len); | |
59 | copy[len] = '\0'; | |
60 | return copy; | |
61 | } | |
62 | ||
63 | static int | |
64 | ProcSELinuxQueryVersion(ClientPtr client) | |
65 | { | |
66 | SELinuxQueryVersionReply rep = { | |
67 | .type = X_Reply, | |
68 | .sequenceNumber = client->sequence, | |
69 | .length = 0, | |
70 | .server_major = SELINUX_MAJOR_VERSION, | |
71 | .server_minor = SELINUX_MINOR_VERSION | |
72 | }; | |
73 | if (client->swapped) { | |
74 | swaps(&rep.sequenceNumber); | |
75 | swapl(&rep.length); | |
76 | swaps(&rep.server_major); | |
77 | swaps(&rep.server_minor); | |
78 | } | |
79 | WriteToClient(client, sizeof(rep), &rep); | |
80 | return Success; | |
81 | } | |
82 | ||
83 | static int | |
84 | SELinuxSendContextReply(ClientPtr client, security_id_t sid) | |
85 | { | |
86 | SELinuxGetContextReply rep; | |
87 | security_context_t ctx = NULL; | |
88 | int len = 0; | |
89 | ||
90 | if (sid) { | |
91 | if (avc_sid_to_context_raw(sid, &ctx) < 0) | |
92 | return BadValue; | |
93 | len = strlen(ctx) + 1; | |
94 | } | |
95 | ||
96 | rep = (SELinuxGetContextReply) { | |
97 | .type = X_Reply, | |
98 | .sequenceNumber = client->sequence, | |
99 | .length = bytes_to_int32(len), | |
100 | .context_len = len | |
101 | }; | |
102 | ||
103 | if (client->swapped) { | |
104 | swapl(&rep.length); | |
105 | swaps(&rep.sequenceNumber); | |
106 | swapl(&rep.context_len); | |
107 | } | |
108 | ||
109 | WriteToClient(client, sizeof(SELinuxGetContextReply), &rep); | |
110 | WriteToClient(client, len, ctx); | |
111 | freecon(ctx); | |
112 | return Success; | |
113 | } | |
114 | ||
115 | static int | |
116 | ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset) | |
117 | { | |
118 | PrivateRec **privPtr = &client->devPrivates; | |
119 | security_id_t *pSid; | |
120 | security_context_t ctx = NULL; | |
121 | char *ptr; | |
122 | int rc; | |
123 | ||
124 | REQUEST(SELinuxSetCreateContextReq); | |
125 | REQUEST_FIXED_SIZE(SELinuxSetCreateContextReq, stuff->context_len); | |
126 | ||
127 | if (stuff->context_len > 0) { | |
128 | ctx = SELinuxCopyContext((char *) (stuff + 1), stuff->context_len); | |
129 | if (!ctx) | |
130 | return BadAlloc; | |
131 | } | |
132 | ||
133 | ptr = dixLookupPrivate(privPtr, subjectKey); | |
134 | pSid = (security_id_t *) (ptr + offset); | |
135 | *pSid = NULL; | |
136 | ||
137 | rc = Success; | |
138 | if (stuff->context_len > 0) { | |
139 | if (security_check_context_raw(ctx) < 0 || | |
140 | avc_context_to_sid_raw(ctx, pSid) < 0) | |
141 | rc = BadValue; | |
142 | } | |
143 | ||
144 | free(ctx); | |
145 | return rc; | |
146 | } | |
147 | ||
148 | static int | |
149 | ProcSELinuxGetCreateContext(ClientPtr client, unsigned offset) | |
150 | { | |
151 | security_id_t *pSid; | |
152 | char *ptr; | |
153 | ||
154 | REQUEST_SIZE_MATCH(SELinuxGetCreateContextReq); | |
155 | ||
156 | if (offset == CTX_DEV) | |
157 | ptr = dixLookupPrivate(&serverClient->devPrivates, subjectKey); | |
158 | else | |
159 | ptr = dixLookupPrivate(&client->devPrivates, subjectKey); | |
160 | ||
161 | pSid = (security_id_t *) (ptr + offset); | |
162 | return SELinuxSendContextReply(client, *pSid); | |
163 | } | |
164 | ||
165 | static int | |
166 | ProcSELinuxSetDeviceContext(ClientPtr client) | |
167 | { | |
168 | security_context_t ctx; | |
169 | security_id_t sid; | |
170 | DeviceIntPtr dev; | |
171 | SELinuxSubjectRec *subj; | |
172 | SELinuxObjectRec *obj; | |
173 | int rc; | |
174 | ||
175 | REQUEST(SELinuxSetContextReq); | |
176 | REQUEST_FIXED_SIZE(SELinuxSetContextReq, stuff->context_len); | |
177 | ||
178 | if (stuff->context_len < 1) | |
179 | return BadLength; | |
180 | ctx = SELinuxCopyContext((char *) (stuff + 1), stuff->context_len); | |
181 | if (!ctx) | |
182 | return BadAlloc; | |
183 | ||
184 | rc = dixLookupDevice(&dev, stuff->id, client, DixManageAccess); | |
185 | if (rc != Success) | |
186 | goto out; | |
187 | ||
188 | if (security_check_context_raw(ctx) < 0 || | |
189 | avc_context_to_sid_raw(ctx, &sid) < 0) { | |
190 | rc = BadValue; | |
191 | goto out; | |
192 | } | |
193 | ||
194 | subj = dixLookupPrivate(&dev->devPrivates, subjectKey); | |
195 | subj->sid = sid; | |
196 | obj = dixLookupPrivate(&dev->devPrivates, objectKey); | |
197 | obj->sid = sid; | |
198 | ||
199 | rc = Success; | |
200 | out: | |
201 | free(ctx); | |
202 | return rc; | |
203 | } | |
204 | ||
205 | static int | |
206 | ProcSELinuxGetDeviceContext(ClientPtr client) | |
207 | { | |
208 | DeviceIntPtr dev; | |
209 | SELinuxSubjectRec *subj; | |
210 | int rc; | |
211 | ||
212 | REQUEST(SELinuxGetContextReq); | |
213 | REQUEST_SIZE_MATCH(SELinuxGetContextReq); | |
214 | ||
215 | rc = dixLookupDevice(&dev, stuff->id, client, DixGetAttrAccess); | |
216 | if (rc != Success) | |
217 | return rc; | |
218 | ||
219 | subj = dixLookupPrivate(&dev->devPrivates, subjectKey); | |
220 | return SELinuxSendContextReply(client, subj->sid); | |
221 | } | |
222 | ||
223 | static int | |
224 | ProcSELinuxGetDrawableContext(ClientPtr client) | |
225 | { | |
226 | DrawablePtr pDraw; | |
227 | PrivateRec **privatePtr; | |
228 | SELinuxObjectRec *obj; | |
229 | int rc; | |
230 | ||
231 | REQUEST(SELinuxGetContextReq); | |
232 | REQUEST_SIZE_MATCH(SELinuxGetContextReq); | |
233 | ||
234 | rc = dixLookupDrawable(&pDraw, stuff->id, client, 0, DixGetAttrAccess); | |
235 | if (rc != Success) | |
236 | return rc; | |
237 | ||
238 | if (pDraw->type == DRAWABLE_PIXMAP) | |
239 | privatePtr = &((PixmapPtr) pDraw)->devPrivates; | |
240 | else | |
241 | privatePtr = &((WindowPtr) pDraw)->devPrivates; | |
242 | ||
243 | obj = dixLookupPrivate(privatePtr, objectKey); | |
244 | return SELinuxSendContextReply(client, obj->sid); | |
245 | } | |
246 | ||
247 | static int | |
248 | ProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey) | |
249 | { | |
250 | WindowPtr pWin; | |
251 | PropertyPtr pProp; | |
252 | SELinuxObjectRec *obj; | |
253 | int rc; | |
254 | ||
255 | REQUEST(SELinuxGetPropertyContextReq); | |
256 | REQUEST_SIZE_MATCH(SELinuxGetPropertyContextReq); | |
257 | ||
258 | rc = dixLookupWindow(&pWin, stuff->window, client, DixGetPropAccess); | |
259 | if (rc != Success) | |
260 | return rc; | |
261 | ||
262 | rc = dixLookupProperty(&pProp, pWin, stuff->property, client, | |
263 | DixGetAttrAccess); | |
264 | if (rc != Success) | |
265 | return rc; | |
266 | ||
267 | obj = dixLookupPrivate(&pProp->devPrivates, privKey); | |
268 | return SELinuxSendContextReply(client, obj->sid); | |
269 | } | |
270 | ||
271 | static int | |
272 | ProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey) | |
273 | { | |
274 | Selection *pSel; | |
275 | SELinuxObjectRec *obj; | |
276 | int rc; | |
277 | ||
278 | REQUEST(SELinuxGetContextReq); | |
279 | REQUEST_SIZE_MATCH(SELinuxGetContextReq); | |
280 | ||
281 | rc = dixLookupSelection(&pSel, stuff->id, client, DixGetAttrAccess); | |
282 | if (rc != Success) | |
283 | return rc; | |
284 | ||
285 | obj = dixLookupPrivate(&pSel->devPrivates, privKey); | |
286 | return SELinuxSendContextReply(client, obj->sid); | |
287 | } | |
288 | ||
289 | static int | |
290 | ProcSELinuxGetClientContext(ClientPtr client) | |
291 | { | |
292 | ClientPtr target; | |
293 | SELinuxSubjectRec *subj; | |
294 | int rc; | |
295 | ||
296 | REQUEST(SELinuxGetContextReq); | |
297 | REQUEST_SIZE_MATCH(SELinuxGetContextReq); | |
298 | ||
299 | rc = dixLookupClient(&target, stuff->id, client, DixGetAttrAccess); | |
300 | if (rc != Success) | |
301 | return rc; | |
302 | ||
303 | subj = dixLookupPrivate(&target->devPrivates, subjectKey); | |
304 | return SELinuxSendContextReply(client, subj->sid); | |
305 | } | |
306 | ||
307 | static int | |
308 | SELinuxPopulateItem(SELinuxListItemRec * i, PrivateRec ** privPtr, CARD32 id, | |
309 | int *size) | |
310 | { | |
311 | SELinuxObjectRec *obj = dixLookupPrivate(privPtr, objectKey); | |
312 | SELinuxObjectRec *data = dixLookupPrivate(privPtr, dataKey); | |
313 | ||
314 | if (avc_sid_to_context_raw(obj->sid, &i->octx) < 0) | |
315 | return BadValue; | |
316 | if (avc_sid_to_context_raw(data->sid, &i->dctx) < 0) | |
317 | return BadValue; | |
318 | ||
319 | i->id = id; | |
320 | i->octx_len = bytes_to_int32(strlen(i->octx) + 1); | |
321 | i->dctx_len = bytes_to_int32(strlen(i->dctx) + 1); | |
322 | ||
323 | *size += i->octx_len + i->dctx_len + 3; | |
324 | return Success; | |
325 | } | |
326 | ||
327 | static void | |
328 | SELinuxFreeItems(SELinuxListItemRec * items, int count) | |
329 | { | |
330 | int k; | |
331 | ||
332 | for (k = 0; k < count; k++) { | |
333 | freecon(items[k].octx); | |
334 | freecon(items[k].dctx); | |
335 | } | |
336 | free(items); | |
337 | } | |
338 | ||
339 | static int | |
340 | SELinuxSendItemsToClient(ClientPtr client, SELinuxListItemRec * items, | |
341 | int size, int count) | |
342 | { | |
343 | int rc, k, pos = 0; | |
344 | SELinuxListItemsReply rep; | |
345 | CARD32 *buf; | |
346 | ||
347 | buf = calloc(size, sizeof(CARD32)); | |
348 | if (size && !buf) { | |
349 | rc = BadAlloc; | |
350 | goto out; | |
351 | } | |
352 | ||
353 | /* Fill in the buffer */ | |
354 | for (k = 0; k < count; k++) { | |
355 | buf[pos] = items[k].id; | |
356 | if (client->swapped) | |
357 | swapl(buf + pos); | |
358 | pos++; | |
359 | ||
360 | buf[pos] = items[k].octx_len * 4; | |
361 | if (client->swapped) | |
362 | swapl(buf + pos); | |
363 | pos++; | |
364 | ||
365 | buf[pos] = items[k].dctx_len * 4; | |
366 | if (client->swapped) | |
367 | swapl(buf + pos); | |
368 | pos++; | |
369 | ||
370 | memcpy((char *) (buf + pos), items[k].octx, strlen(items[k].octx) + 1); | |
371 | pos += items[k].octx_len; | |
372 | memcpy((char *) (buf + pos), items[k].dctx, strlen(items[k].dctx) + 1); | |
373 | pos += items[k].dctx_len; | |
374 | } | |
375 | ||
376 | /* Send reply to client */ | |
377 | rep = (SELinuxListItemsReply) { | |
378 | .type = X_Reply, | |
379 | .sequenceNumber = client->sequence, | |
380 | .length = size, | |
381 | .count = count | |
382 | }; | |
383 | ||
384 | if (client->swapped) { | |
385 | swapl(&rep.length); | |
386 | swaps(&rep.sequenceNumber); | |
387 | swapl(&rep.count); | |
388 | } | |
389 | ||
390 | WriteToClient(client, sizeof(SELinuxListItemsReply), &rep); | |
391 | WriteToClient(client, size * 4, buf); | |
392 | ||
393 | /* Free stuff and return */ | |
394 | rc = Success; | |
395 | free(buf); | |
396 | out: | |
397 | SELinuxFreeItems(items, count); | |
398 | return rc; | |
399 | } | |
400 | ||
401 | static int | |
402 | ProcSELinuxListProperties(ClientPtr client) | |
403 | { | |
404 | WindowPtr pWin; | |
405 | PropertyPtr pProp; | |
406 | SELinuxListItemRec *items; | |
407 | int rc, count, size, i; | |
408 | CARD32 id; | |
409 | ||
410 | REQUEST(SELinuxGetContextReq); | |
411 | REQUEST_SIZE_MATCH(SELinuxGetContextReq); | |
412 | ||
413 | rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess); | |
414 | if (rc != Success) | |
415 | return rc; | |
416 | ||
417 | /* Count the number of properties and allocate items */ | |
418 | count = 0; | |
419 | for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) | |
420 | count++; | |
421 | items = calloc(count, sizeof(SELinuxListItemRec)); | |
422 | if (count && !items) | |
423 | return BadAlloc; | |
424 | ||
425 | /* Fill in the items and calculate size */ | |
426 | i = 0; | |
427 | size = 0; | |
428 | for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { | |
429 | id = pProp->propertyName; | |
430 | rc = SELinuxPopulateItem(items + i, &pProp->devPrivates, id, &size); | |
431 | if (rc != Success) { | |
432 | SELinuxFreeItems(items, count); | |
433 | return rc; | |
434 | } | |
435 | i++; | |
436 | } | |
437 | ||
438 | return SELinuxSendItemsToClient(client, items, size, count); | |
439 | } | |
440 | ||
441 | static int | |
442 | ProcSELinuxListSelections(ClientPtr client) | |
443 | { | |
444 | Selection *pSel; | |
445 | SELinuxListItemRec *items; | |
446 | int rc, count, size, i; | |
447 | CARD32 id; | |
448 | ||
449 | REQUEST_SIZE_MATCH(SELinuxGetCreateContextReq); | |
450 | ||
451 | /* Count the number of selections and allocate items */ | |
452 | count = 0; | |
453 | for (pSel = CurrentSelections; pSel; pSel = pSel->next) | |
454 | count++; | |
455 | items = calloc(count, sizeof(SELinuxListItemRec)); | |
456 | if (count && !items) | |
457 | return BadAlloc; | |
458 | ||
459 | /* Fill in the items and calculate size */ | |
460 | i = 0; | |
461 | size = 0; | |
462 | for (pSel = CurrentSelections; pSel; pSel = pSel->next) { | |
463 | id = pSel->selection; | |
464 | rc = SELinuxPopulateItem(items + i, &pSel->devPrivates, id, &size); | |
465 | if (rc != Success) { | |
466 | SELinuxFreeItems(items, count); | |
467 | return rc; | |
468 | } | |
469 | i++; | |
470 | } | |
471 | ||
472 | return SELinuxSendItemsToClient(client, items, size, count); | |
473 | } | |
474 | ||
475 | static int | |
476 | ProcSELinuxDispatch(ClientPtr client) | |
477 | { | |
478 | REQUEST(xReq); | |
479 | switch (stuff->data) { | |
480 | case X_SELinuxQueryVersion: | |
481 | return ProcSELinuxQueryVersion(client); | |
482 | case X_SELinuxSetDeviceCreateContext: | |
483 | return ProcSELinuxSetCreateContext(client, CTX_DEV); | |
484 | case X_SELinuxGetDeviceCreateContext: | |
485 | return ProcSELinuxGetCreateContext(client, CTX_DEV); | |
486 | case X_SELinuxSetDeviceContext: | |
487 | return ProcSELinuxSetDeviceContext(client); | |
488 | case X_SELinuxGetDeviceContext: | |
489 | return ProcSELinuxGetDeviceContext(client); | |
490 | case X_SELinuxSetDrawableCreateContext: | |
491 | return ProcSELinuxSetCreateContext(client, CTX_WIN); | |
492 | case X_SELinuxGetDrawableCreateContext: | |
493 | return ProcSELinuxGetCreateContext(client, CTX_WIN); | |
494 | case X_SELinuxGetDrawableContext: | |
495 | return ProcSELinuxGetDrawableContext(client); | |
496 | case X_SELinuxSetPropertyCreateContext: | |
497 | return ProcSELinuxSetCreateContext(client, CTX_PRP); | |
498 | case X_SELinuxGetPropertyCreateContext: | |
499 | return ProcSELinuxGetCreateContext(client, CTX_PRP); | |
500 | case X_SELinuxSetPropertyUseContext: | |
501 | return ProcSELinuxSetCreateContext(client, USE_PRP); | |
502 | case X_SELinuxGetPropertyUseContext: | |
503 | return ProcSELinuxGetCreateContext(client, USE_PRP); | |
504 | case X_SELinuxGetPropertyContext: | |
505 | return ProcSELinuxGetPropertyContext(client, objectKey); | |
506 | case X_SELinuxGetPropertyDataContext: | |
507 | return ProcSELinuxGetPropertyContext(client, dataKey); | |
508 | case X_SELinuxListProperties: | |
509 | return ProcSELinuxListProperties(client); | |
510 | case X_SELinuxSetSelectionCreateContext: | |
511 | return ProcSELinuxSetCreateContext(client, CTX_SEL); | |
512 | case X_SELinuxGetSelectionCreateContext: | |
513 | return ProcSELinuxGetCreateContext(client, CTX_SEL); | |
514 | case X_SELinuxSetSelectionUseContext: | |
515 | return ProcSELinuxSetCreateContext(client, USE_SEL); | |
516 | case X_SELinuxGetSelectionUseContext: | |
517 | return ProcSELinuxGetCreateContext(client, USE_SEL); | |
518 | case X_SELinuxGetSelectionContext: | |
519 | return ProcSELinuxGetSelectionContext(client, objectKey); | |
520 | case X_SELinuxGetSelectionDataContext: | |
521 | return ProcSELinuxGetSelectionContext(client, dataKey); | |
522 | case X_SELinuxListSelections: | |
523 | return ProcSELinuxListSelections(client); | |
524 | case X_SELinuxGetClientContext: | |
525 | return ProcSELinuxGetClientContext(client); | |
526 | default: | |
527 | return BadRequest; | |
528 | } | |
529 | } | |
530 | ||
531 | static int | |
532 | SProcSELinuxQueryVersion(ClientPtr client) | |
533 | { | |
534 | return ProcSELinuxQueryVersion(client); | |
535 | } | |
536 | ||
537 | static int | |
538 | SProcSELinuxSetCreateContext(ClientPtr client, unsigned offset) | |
539 | { | |
540 | REQUEST(SELinuxSetCreateContextReq); | |
541 | ||
542 | REQUEST_AT_LEAST_SIZE(SELinuxSetCreateContextReq); | |
543 | swapl(&stuff->context_len); | |
544 | return ProcSELinuxSetCreateContext(client, offset); | |
545 | } | |
546 | ||
547 | static int | |
548 | SProcSELinuxSetDeviceContext(ClientPtr client) | |
549 | { | |
550 | REQUEST(SELinuxSetContextReq); | |
551 | ||
552 | REQUEST_AT_LEAST_SIZE(SELinuxSetContextReq); | |
553 | swapl(&stuff->id); | |
554 | swapl(&stuff->context_len); | |
555 | return ProcSELinuxSetDeviceContext(client); | |
556 | } | |
557 | ||
558 | static int | |
559 | SProcSELinuxGetDeviceContext(ClientPtr client) | |
560 | { | |
561 | REQUEST(SELinuxGetContextReq); | |
562 | ||
563 | REQUEST_SIZE_MATCH(SELinuxGetContextReq); | |
564 | swapl(&stuff->id); | |
565 | return ProcSELinuxGetDeviceContext(client); | |
566 | } | |
567 | ||
568 | static int | |
569 | SProcSELinuxGetDrawableContext(ClientPtr client) | |
570 | { | |
571 | REQUEST(SELinuxGetContextReq); | |
572 | ||
573 | REQUEST_SIZE_MATCH(SELinuxGetContextReq); | |
574 | swapl(&stuff->id); | |
575 | return ProcSELinuxGetDrawableContext(client); | |
576 | } | |
577 | ||
578 | static int | |
579 | SProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey) | |
580 | { | |
581 | REQUEST(SELinuxGetPropertyContextReq); | |
582 | ||
583 | REQUEST_SIZE_MATCH(SELinuxGetPropertyContextReq); | |
584 | swapl(&stuff->window); | |
585 | swapl(&stuff->property); | |
586 | return ProcSELinuxGetPropertyContext(client, privKey); | |
587 | } | |
588 | ||
589 | static int | |
590 | SProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey) | |
591 | { | |
592 | REQUEST(SELinuxGetContextReq); | |
593 | ||
594 | REQUEST_SIZE_MATCH(SELinuxGetContextReq); | |
595 | swapl(&stuff->id); | |
596 | return ProcSELinuxGetSelectionContext(client, privKey); | |
597 | } | |
598 | ||
599 | static int | |
600 | SProcSELinuxListProperties(ClientPtr client) | |
601 | { | |
602 | REQUEST(SELinuxGetContextReq); | |
603 | ||
604 | REQUEST_SIZE_MATCH(SELinuxGetContextReq); | |
605 | swapl(&stuff->id); | |
606 | return ProcSELinuxListProperties(client); | |
607 | } | |
608 | ||
609 | static int | |
610 | SProcSELinuxGetClientContext(ClientPtr client) | |
611 | { | |
612 | REQUEST(SELinuxGetContextReq); | |
613 | ||
614 | REQUEST_SIZE_MATCH(SELinuxGetContextReq); | |
615 | swapl(&stuff->id); | |
616 | return ProcSELinuxGetClientContext(client); | |
617 | } | |
618 | ||
619 | static int | |
620 | SProcSELinuxDispatch(ClientPtr client) | |
621 | { | |
622 | REQUEST(xReq); | |
623 | ||
624 | swaps(&stuff->length); | |
625 | ||
626 | switch (stuff->data) { | |
627 | case X_SELinuxQueryVersion: | |
628 | return SProcSELinuxQueryVersion(client); | |
629 | case X_SELinuxSetDeviceCreateContext: | |
630 | return SProcSELinuxSetCreateContext(client, CTX_DEV); | |
631 | case X_SELinuxGetDeviceCreateContext: | |
632 | return ProcSELinuxGetCreateContext(client, CTX_DEV); | |
633 | case X_SELinuxSetDeviceContext: | |
634 | return SProcSELinuxSetDeviceContext(client); | |
635 | case X_SELinuxGetDeviceContext: | |
636 | return SProcSELinuxGetDeviceContext(client); | |
637 | case X_SELinuxSetDrawableCreateContext: | |
638 | return SProcSELinuxSetCreateContext(client, CTX_WIN); | |
639 | case X_SELinuxGetDrawableCreateContext: | |
640 | return ProcSELinuxGetCreateContext(client, CTX_WIN); | |
641 | case X_SELinuxGetDrawableContext: | |
642 | return SProcSELinuxGetDrawableContext(client); | |
643 | case X_SELinuxSetPropertyCreateContext: | |
644 | return SProcSELinuxSetCreateContext(client, CTX_PRP); | |
645 | case X_SELinuxGetPropertyCreateContext: | |
646 | return ProcSELinuxGetCreateContext(client, CTX_PRP); | |
647 | case X_SELinuxSetPropertyUseContext: | |
648 | return SProcSELinuxSetCreateContext(client, USE_PRP); | |
649 | case X_SELinuxGetPropertyUseContext: | |
650 | return ProcSELinuxGetCreateContext(client, USE_PRP); | |
651 | case X_SELinuxGetPropertyContext: | |
652 | return SProcSELinuxGetPropertyContext(client, objectKey); | |
653 | case X_SELinuxGetPropertyDataContext: | |
654 | return SProcSELinuxGetPropertyContext(client, dataKey); | |
655 | case X_SELinuxListProperties: | |
656 | return SProcSELinuxListProperties(client); | |
657 | case X_SELinuxSetSelectionCreateContext: | |
658 | return SProcSELinuxSetCreateContext(client, CTX_SEL); | |
659 | case X_SELinuxGetSelectionCreateContext: | |
660 | return ProcSELinuxGetCreateContext(client, CTX_SEL); | |
661 | case X_SELinuxSetSelectionUseContext: | |
662 | return SProcSELinuxSetCreateContext(client, USE_SEL); | |
663 | case X_SELinuxGetSelectionUseContext: | |
664 | return ProcSELinuxGetCreateContext(client, USE_SEL); | |
665 | case X_SELinuxGetSelectionContext: | |
666 | return SProcSELinuxGetSelectionContext(client, objectKey); | |
667 | case X_SELinuxGetSelectionDataContext: | |
668 | return SProcSELinuxGetSelectionContext(client, dataKey); | |
669 | case X_SELinuxListSelections: | |
670 | return ProcSELinuxListSelections(client); | |
671 | case X_SELinuxGetClientContext: | |
672 | return SProcSELinuxGetClientContext(client); | |
673 | default: | |
674 | return BadRequest; | |
675 | } | |
676 | } | |
677 | ||
678 | /* | |
679 | * Extension Setup / Teardown | |
680 | */ | |
681 | ||
682 | static void | |
683 | SELinuxResetProc(ExtensionEntry * extEntry) | |
684 | { | |
685 | SELinuxFlaskReset(); | |
686 | SELinuxLabelReset(); | |
687 | } | |
688 | ||
689 | void | |
690 | SELinuxExtensionInit(void) | |
691 | { | |
692 | ExtensionEntry *extEntry; | |
693 | ||
694 | /* Check SELinux mode on system, configuration file, and boolean */ | |
695 | if (!is_selinux_enabled()) { | |
696 | LogMessage(X_INFO, "SELinux: Disabled on system\n"); | |
697 | return; | |
698 | } | |
699 | if (selinuxEnforcingState == SELINUX_MODE_DISABLED) { | |
700 | LogMessage(X_INFO, "SELinux: Disabled in configuration file\n"); | |
701 | return; | |
702 | } | |
703 | if (!security_get_boolean_active("xserver_object_manager")) { | |
704 | LogMessage(X_INFO, "SELinux: Disabled by boolean\n"); | |
705 | return; | |
706 | } | |
707 | ||
708 | /* Set up XACE hooks */ | |
709 | SELinuxLabelInit(); | |
710 | SELinuxFlaskInit(); | |
711 | ||
712 | /* Add extension to server */ | |
713 | extEntry = AddExtension(SELINUX_EXTENSION_NAME, | |
714 | SELinuxNumberEvents, SELinuxNumberErrors, | |
715 | ProcSELinuxDispatch, SProcSELinuxDispatch, | |
716 | SELinuxResetProc, StandardMinorOpcode); | |
717 | ||
718 | AddExtensionAlias("Flask", extEntry); | |
719 | } |