1/************************************************************ 2 3Author: Eamon Walsh <ewalsh@tycho.nsa.gov> 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7this permission notice appear in supporting documentation. This permission 8notice shall be included in all copies or substantial portions of the 9Software. 10 11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 15AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16CONNECTION 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 "modinit.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 39typedef 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/* 49 * Extension Dispatch 50 */ 51 52static security_context_t 53SELinuxCopyContext(char *ptr, unsigned len) 54{ 55 security_context_t copy = malloc(len + 1); 56 if (!copy) 57 return NULL; 58 strncpy(copy, ptr, len); 59 copy[len] = '\0'; 60 return copy; 61} 62 63static int 64ProcSELinuxQueryVersion(ClientPtr client) 65{ 66 SELinuxQueryVersionReply rep; 67 68 rep.type = X_Reply; 69 rep.length = 0; 70 rep.sequenceNumber = client->sequence; 71 rep.server_major = SELINUX_MAJOR_VERSION; 72 rep.server_minor = SELINUX_MINOR_VERSION; 73 if (client->swapped) { 74 int n; 75 swaps(&rep.sequenceNumber, n); 76 swapl(&rep.length, n); 77 swaps(&rep.server_major, n); 78 swaps(&rep.server_minor, n); 79 } 80 WriteToClient(client, sizeof(rep), (char *)&rep); 81 return Success; 82} 83 84static int 85SELinuxSendContextReply(ClientPtr client, security_id_t sid) 86{ 87 SELinuxGetContextReply rep; 88 security_context_t ctx = NULL; 89 int len = 0; 90 91 if (sid) { 92 if (avc_sid_to_context_raw(sid, &ctx) < 0) 93 return BadValue; 94 len = strlen(ctx) + 1; 95 } 96 97 rep.type = X_Reply; 98 rep.length = bytes_to_int32(len); 99 rep.sequenceNumber = client->sequence; 100 rep.context_len = len; 101 102 if (client->swapped) { 103 int n; 104 swapl(&rep.length, n); 105 swaps(&rep.sequenceNumber, n); 106 swapl(&rep.context_len, n); 107 } 108 109 WriteToClient(client, sizeof(SELinuxGetContextReply), (char *)&rep); 110 WriteToClient(client, len, ctx); 111 freecon(ctx); 112 return Success; 113} 114 115static int 116ProcSELinuxSetCreateContext(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 148static int 149ProcSELinuxGetCreateContext(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 165static int 166ProcSELinuxSetDeviceContext(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; 200out: 201 free(ctx); 202 return rc; 203} 204 205static int 206ProcSELinuxGetDeviceContext(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 223static int 224ProcSELinuxGetDrawableContext(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 247static int 248ProcSELinuxGetPropertyContext(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 271static int 272ProcSELinuxGetSelectionContext(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 289static int 290ProcSELinuxGetClientContext(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 307static int 308SELinuxPopulateItem(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 327static void 328SELinuxFreeItems(SELinuxListItemRec *items, int count) 329{ 330 int k; 331 for (k = 0; k < count; k++) { 332 freecon(items[k].octx); 333 freecon(items[k].dctx); 334 } 335 free(items); 336} 337 338static int 339SELinuxSendItemsToClient(ClientPtr client, SELinuxListItemRec *items, 340 int size, int count) 341{ 342 int rc, k, n, pos = 0; 343 SELinuxListItemsReply rep; 344 CARD32 *buf; 345 346 buf = calloc(size, sizeof(CARD32)); 347 if (size && !buf) { 348 rc = BadAlloc; 349 goto out; 350 } 351 352 /* Fill in the buffer */ 353 for (k = 0; k < count; k++) { 354 buf[pos] = items[k].id; 355 if (client->swapped) 356 swapl(buf + pos, n); 357 pos++; 358 359 buf[pos] = items[k].octx_len * 4; 360 if (client->swapped) 361 swapl(buf + pos, n); 362 pos++; 363 364 buf[pos] = items[k].dctx_len * 4; 365 if (client->swapped) 366 swapl(buf + pos, n); 367 pos++; 368 369 memcpy((char *)(buf + pos), items[k].octx, strlen(items[k].octx) + 1); 370 pos += items[k].octx_len; 371 memcpy((char *)(buf + pos), items[k].dctx, strlen(items[k].dctx) + 1); 372 pos += items[k].dctx_len; 373 } 374 375 /* Send reply to client */ 376 rep.type = X_Reply; 377 rep.length = size; 378 rep.sequenceNumber = client->sequence; 379 rep.count = count; 380 381 if (client->swapped) { 382 swapl(&rep.length, n); 383 swaps(&rep.sequenceNumber, n); 384 swapl(&rep.count, n); 385 } 386 387 WriteToClient(client, sizeof(SELinuxListItemsReply), (char *)&rep); 388 WriteToClient(client, size * 4, (char *)buf); 389 390 /* Free stuff and return */ 391 rc = Success; 392 free(buf); 393out: 394 SELinuxFreeItems(items, count); 395 return rc; 396} 397 398static int 399ProcSELinuxListProperties(ClientPtr client) 400{ 401 WindowPtr pWin; 402 PropertyPtr pProp; 403 SELinuxListItemRec *items; 404 int rc, count, size, i; 405 CARD32 id; 406 407 REQUEST(SELinuxGetContextReq); 408 REQUEST_SIZE_MATCH(SELinuxGetContextReq); 409 410 rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess); 411 if (rc != Success) 412 return rc; 413 414 /* Count the number of properties and allocate items */ 415 count = 0; 416 for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) 417 count++; 418 items = calloc(count, sizeof(SELinuxListItemRec)); 419 if (count && !items) 420 return BadAlloc; 421 422 /* Fill in the items and calculate size */ 423 i = 0; 424 size = 0; 425 for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { 426 id = pProp->propertyName; 427 rc = SELinuxPopulateItem(items + i, &pProp->devPrivates, id, &size); 428 if (rc != Success) { 429 SELinuxFreeItems(items, count); 430 return rc; 431 } 432 i++; 433 } 434 435 return SELinuxSendItemsToClient(client, items, size, count); 436} 437 438static int 439ProcSELinuxListSelections(ClientPtr client) 440{ 441 Selection *pSel; 442 SELinuxListItemRec *items; 443 int rc, count, size, i; 444 CARD32 id; 445 446 REQUEST_SIZE_MATCH(SELinuxGetCreateContextReq); 447 448 /* Count the number of selections and allocate items */ 449 count = 0; 450 for (pSel = CurrentSelections; pSel; pSel = pSel->next) 451 count++; 452 items = calloc(count, sizeof(SELinuxListItemRec)); 453 if (count && !items) 454 return BadAlloc; 455 456 /* Fill in the items and calculate size */ 457 i = 0; 458 size = 0; 459 for (pSel = CurrentSelections; pSel; pSel = pSel->next) { 460 id = pSel->selection; 461 rc = SELinuxPopulateItem(items + i, &pSel->devPrivates, id, &size); 462 if (rc != Success) { 463 SELinuxFreeItems(items, count); 464 return rc; 465 } 466 i++; 467 } 468 469 return SELinuxSendItemsToClient(client, items, size, count); 470} 471 472static int 473ProcSELinuxDispatch(ClientPtr client) 474{ 475 REQUEST(xReq); 476 switch (stuff->data) { 477 case X_SELinuxQueryVersion: 478 return ProcSELinuxQueryVersion(client); 479 case X_SELinuxSetDeviceCreateContext: 480 return ProcSELinuxSetCreateContext(client, CTX_DEV); 481 case X_SELinuxGetDeviceCreateContext: 482 return ProcSELinuxGetCreateContext(client, CTX_DEV); 483 case X_SELinuxSetDeviceContext: 484 return ProcSELinuxSetDeviceContext(client); 485 case X_SELinuxGetDeviceContext: 486 return ProcSELinuxGetDeviceContext(client); 487 case X_SELinuxSetDrawableCreateContext: 488 return ProcSELinuxSetCreateContext(client, CTX_WIN); 489 case X_SELinuxGetDrawableCreateContext: 490 return ProcSELinuxGetCreateContext(client, CTX_WIN); 491 case X_SELinuxGetDrawableContext: 492 return ProcSELinuxGetDrawableContext(client); 493 case X_SELinuxSetPropertyCreateContext: 494 return ProcSELinuxSetCreateContext(client, CTX_PRP); 495 case X_SELinuxGetPropertyCreateContext: 496 return ProcSELinuxGetCreateContext(client, CTX_PRP); 497 case X_SELinuxSetPropertyUseContext: 498 return ProcSELinuxSetCreateContext(client, USE_PRP); 499 case X_SELinuxGetPropertyUseContext: 500 return ProcSELinuxGetCreateContext(client, USE_PRP); 501 case X_SELinuxGetPropertyContext: 502 return ProcSELinuxGetPropertyContext(client, objectKey); 503 case X_SELinuxGetPropertyDataContext: 504 return ProcSELinuxGetPropertyContext(client, dataKey); 505 case X_SELinuxListProperties: 506 return ProcSELinuxListProperties(client); 507 case X_SELinuxSetSelectionCreateContext: 508 return ProcSELinuxSetCreateContext(client, CTX_SEL); 509 case X_SELinuxGetSelectionCreateContext: 510 return ProcSELinuxGetCreateContext(client, CTX_SEL); 511 case X_SELinuxSetSelectionUseContext: 512 return ProcSELinuxSetCreateContext(client, USE_SEL); 513 case X_SELinuxGetSelectionUseContext: 514 return ProcSELinuxGetCreateContext(client, USE_SEL); 515 case X_SELinuxGetSelectionContext: 516 return ProcSELinuxGetSelectionContext(client, objectKey); 517 case X_SELinuxGetSelectionDataContext: 518 return ProcSELinuxGetSelectionContext(client, dataKey); 519 case X_SELinuxListSelections: 520 return ProcSELinuxListSelections(client); 521 case X_SELinuxGetClientContext: 522 return ProcSELinuxGetClientContext(client); 523 default: 524 return BadRequest; 525 } 526} 527 528static int 529SProcSELinuxQueryVersion(ClientPtr client) 530{ 531 return ProcSELinuxQueryVersion(client); 532} 533 534static int 535SProcSELinuxSetCreateContext(ClientPtr client, unsigned offset) 536{ 537 REQUEST(SELinuxSetCreateContextReq); 538 int n; 539 540 REQUEST_AT_LEAST_SIZE(SELinuxSetCreateContextReq); 541 swapl(&stuff->context_len, n); 542 return ProcSELinuxSetCreateContext(client, offset); 543} 544 545static int 546SProcSELinuxSetDeviceContext(ClientPtr client) 547{ 548 REQUEST(SELinuxSetContextReq); 549 int n; 550 551 REQUEST_AT_LEAST_SIZE(SELinuxSetContextReq); 552 swapl(&stuff->id, n); 553 swapl(&stuff->context_len, n); 554 return ProcSELinuxSetDeviceContext(client); 555} 556 557static int 558SProcSELinuxGetDeviceContext(ClientPtr client) 559{ 560 REQUEST(SELinuxGetContextReq); 561 int n; 562 563 REQUEST_SIZE_MATCH(SELinuxGetContextReq); 564 swapl(&stuff->id, n); 565 return ProcSELinuxGetDeviceContext(client); 566} 567 568static int 569SProcSELinuxGetDrawableContext(ClientPtr client) 570{ 571 REQUEST(SELinuxGetContextReq); 572 int n; 573 574 REQUEST_SIZE_MATCH(SELinuxGetContextReq); 575 swapl(&stuff->id, n); 576 return ProcSELinuxGetDrawableContext(client); 577} 578 579static int 580SProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey) 581{ 582 REQUEST(SELinuxGetPropertyContextReq); 583 int n; 584 585 REQUEST_SIZE_MATCH(SELinuxGetPropertyContextReq); 586 swapl(&stuff->window, n); 587 swapl(&stuff->property, n); 588 return ProcSELinuxGetPropertyContext(client, privKey); 589} 590 591static int 592SProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey) 593{ 594 REQUEST(SELinuxGetContextReq); 595 int n; 596 597 REQUEST_SIZE_MATCH(SELinuxGetContextReq); 598 swapl(&stuff->id, n); 599 return ProcSELinuxGetSelectionContext(client, privKey); 600} 601 602static int 603SProcSELinuxListProperties(ClientPtr client) 604{ 605 REQUEST(SELinuxGetContextReq); 606 int n; 607 608 REQUEST_SIZE_MATCH(SELinuxGetContextReq); 609 swapl(&stuff->id, n); 610 return ProcSELinuxListProperties(client); 611} 612 613static int 614SProcSELinuxGetClientContext(ClientPtr client) 615{ 616 REQUEST(SELinuxGetContextReq); 617 int n; 618 619 REQUEST_SIZE_MATCH(SELinuxGetContextReq); 620 swapl(&stuff->id, n); 621 return ProcSELinuxGetClientContext(client); 622} 623 624static int 625SProcSELinuxDispatch(ClientPtr client) 626{ 627 REQUEST(xReq); 628 int n; 629 630 swaps(&stuff->length, n); 631 632 switch (stuff->data) { 633 case X_SELinuxQueryVersion: 634 return SProcSELinuxQueryVersion(client); 635 case X_SELinuxSetDeviceCreateContext: 636 return SProcSELinuxSetCreateContext(client, CTX_DEV); 637 case X_SELinuxGetDeviceCreateContext: 638 return ProcSELinuxGetCreateContext(client, CTX_DEV); 639 case X_SELinuxSetDeviceContext: 640 return SProcSELinuxSetDeviceContext(client); 641 case X_SELinuxGetDeviceContext: 642 return SProcSELinuxGetDeviceContext(client); 643 case X_SELinuxSetDrawableCreateContext: 644 return SProcSELinuxSetCreateContext(client, CTX_WIN); 645 case X_SELinuxGetDrawableCreateContext: 646 return ProcSELinuxGetCreateContext(client, CTX_WIN); 647 case X_SELinuxGetDrawableContext: 648 return SProcSELinuxGetDrawableContext(client); 649 case X_SELinuxSetPropertyCreateContext: 650 return SProcSELinuxSetCreateContext(client, CTX_PRP); 651 case X_SELinuxGetPropertyCreateContext: 652 return ProcSELinuxGetCreateContext(client, CTX_PRP); 653 case X_SELinuxSetPropertyUseContext: 654 return SProcSELinuxSetCreateContext(client, USE_PRP); 655 case X_SELinuxGetPropertyUseContext: 656 return ProcSELinuxGetCreateContext(client, USE_PRP); 657 case X_SELinuxGetPropertyContext: 658 return SProcSELinuxGetPropertyContext(client, objectKey); 659 case X_SELinuxGetPropertyDataContext: 660 return SProcSELinuxGetPropertyContext(client, dataKey); 661 case X_SELinuxListProperties: 662 return SProcSELinuxListProperties(client); 663 case X_SELinuxSetSelectionCreateContext: 664 return SProcSELinuxSetCreateContext(client, CTX_SEL); 665 case X_SELinuxGetSelectionCreateContext: 666 return ProcSELinuxGetCreateContext(client, CTX_SEL); 667 case X_SELinuxSetSelectionUseContext: 668 return SProcSELinuxSetCreateContext(client, USE_SEL); 669 case X_SELinuxGetSelectionUseContext: 670 return ProcSELinuxGetCreateContext(client, USE_SEL); 671 case X_SELinuxGetSelectionContext: 672 return SProcSELinuxGetSelectionContext(client, objectKey); 673 case X_SELinuxGetSelectionDataContext: 674 return SProcSELinuxGetSelectionContext(client, dataKey); 675 case X_SELinuxListSelections: 676 return ProcSELinuxListSelections(client); 677 case X_SELinuxGetClientContext: 678 return SProcSELinuxGetClientContext(client); 679 default: 680 return BadRequest; 681 } 682} 683 684 685/* 686 * Extension Setup / Teardown 687 */ 688 689static void 690SELinuxResetProc(ExtensionEntry *extEntry) 691{ 692 SELinuxFlaskReset(); 693 SELinuxLabelReset(); 694} 695 696void 697SELinuxExtensionInit(INITARGS) 698{ 699 ExtensionEntry *extEntry; 700 701 /* Check SELinux mode on system, configuration file, and boolean */ 702 if (!is_selinux_enabled()) { 703 LogMessage(X_INFO, "SELinux: Disabled on system\n"); 704 return; 705 } 706 if (selinuxEnforcingState == SELINUX_MODE_DISABLED) { 707 LogMessage(X_INFO, "SELinux: Disabled in configuration file\n"); 708 return; 709 } 710 if (!security_get_boolean_active("xserver_object_manager")) { 711 LogMessage(X_INFO, "SELinux: Disabled by boolean\n"); 712 return; 713 } 714 715 /* Set up XACE hooks */ 716 SELinuxLabelInit(); 717 SELinuxFlaskInit(); 718 719 /* Add extension to server */ 720 extEntry = AddExtension(SELINUX_EXTENSION_NAME, 721 SELinuxNumberEvents, SELinuxNumberErrors, 722 ProcSELinuxDispatch, SProcSELinuxDispatch, 723 SELinuxResetProc, StandardMinorOpcode); 724 725 AddExtensionAlias("Flask", extEntry); 726} 727