1# Copyright (C) 2005-2013 Red Hat 2# see file 'COPYING' for use and warranty information 3# 4# semanage is a tool for managing SELinux configuration files 5# 6# This program is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License as 8# published by the Free Software Foundation; either version 2 of 9# the License, or (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19# 02111-1307 USA 20# 21# 22 23import pwd 24import grp 25import selinux 26import os 27import re 28import sys 29import stat 30import socket 31from semanage import * 32PROGNAME = "selinux-python" 33import sepolicy 34from setools.policyrep import SELinuxPolicy 35from setools.typequery import TypeQuery 36import ipaddress 37 38try: 39 import gettext 40 kwargs = {} 41 if sys.version_info < (3,): 42 kwargs['unicode'] = True 43 t = gettext.translation(PROGNAME, 44 localedir="/usr/share/locale", 45 **kwargs, 46 fallback=True) 47 _ = t.gettext 48except: 49 try: 50 import builtins 51 builtins.__dict__['_'] = str 52 except ImportError: 53 import __builtin__ 54 __builtin__.__dict__['_'] = unicode 55 56import syslog 57 58file_types = {} 59file_types[""] = SEMANAGE_FCONTEXT_ALL 60file_types["all files"] = SEMANAGE_FCONTEXT_ALL 61file_types["a"] = SEMANAGE_FCONTEXT_ALL 62file_types["regular file"] = SEMANAGE_FCONTEXT_REG 63file_types["--"] = SEMANAGE_FCONTEXT_REG 64file_types["f"] = SEMANAGE_FCONTEXT_REG 65file_types["-d"] = SEMANAGE_FCONTEXT_DIR 66file_types["directory"] = SEMANAGE_FCONTEXT_DIR 67file_types["d"] = SEMANAGE_FCONTEXT_DIR 68file_types["-c"] = SEMANAGE_FCONTEXT_CHAR 69file_types["character device"] = SEMANAGE_FCONTEXT_CHAR 70file_types["c"] = SEMANAGE_FCONTEXT_CHAR 71file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK 72file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK 73file_types["b"] = SEMANAGE_FCONTEXT_BLOCK 74file_types["-s"] = SEMANAGE_FCONTEXT_SOCK 75file_types["socket"] = SEMANAGE_FCONTEXT_SOCK 76file_types["s"] = SEMANAGE_FCONTEXT_SOCK 77file_types["-l"] = SEMANAGE_FCONTEXT_LINK 78file_types["l"] = SEMANAGE_FCONTEXT_LINK 79file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK 80file_types["p"] = SEMANAGE_FCONTEXT_PIPE 81file_types["-p"] = SEMANAGE_FCONTEXT_PIPE 82file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE 83 84file_type_str_to_option = {"all files": "a", 85 "regular file": "f", 86 "directory": "d", 87 "character device": "c", 88 "block device": "b", 89 "socket": "s", 90 "symbolic link": "l", 91 "named pipe": "p"} 92 93ftype_to_audit = {"": "any", 94 "a" : "any", 95 "b": "block", 96 "c": "char", 97 "d": "dir", 98 "f": "file", 99 "l": "symlink", 100 "p": "pipe", 101 "s": "socket"} 102 103try: 104 import audit 105 #test if audit module is enabled 106 audit.audit_close(audit.audit_open()) 107 108 class logger: 109 110 def __init__(self): 111 self.audit_fd = audit.audit_open() 112 self.log_list = [] 113 self.log_change_list = [] 114 115 def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""): 116 117 sep = "-" 118 if sename != oldsename: 119 msg += sep + "sename" 120 sep = "," 121 if serole != oldserole: 122 msg += sep + "role" 123 sep = "," 124 if serange != oldserange: 125 msg += sep + "range" 126 sep = "," 127 128 self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_ASSIGN, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""]) 129 130 def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""): 131 self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""]) 132 133 def log_change(self, msg): 134 self.log_change_list.append([self.audit_fd, audit.AUDIT_USER_MAC_CONFIG_CHANGE, str(msg), "semanage", "", "", ""]) 135 136 def commit(self, success): 137 for l in self.log_list: 138 audit.audit_log_semanage_message(*(l + [success])) 139 for l in self.log_change_list: 140 audit.audit_log_user_comm_message(*(l + [success])) 141 142 self.log_list = [] 143 self.log_change_list = [] 144except (OSError, ImportError): 145 class logger: 146 147 def __init__(self): 148 self.log_list = [] 149 150 def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""): 151 message = " %s name=%s" % (msg, name) 152 if sename != "": 153 message += " sename=" + sename 154 if oldsename != "": 155 message += " oldsename=" + oldsename 156 if serole != "": 157 message += " role=" + serole 158 if oldserole != "": 159 message += " old_role=" + oldserole 160 if serange != "" and serange is not None: 161 message += " MLSRange=" + serange 162 if oldserange != "" and oldserange is not None: 163 message += " old_MLSRange=" + oldserange 164 self.log_list.append(message) 165 166 def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""): 167 self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange) 168 169 def log_change(self, msg): 170 self.log_list.append(" %s" % msg) 171 172 def commit(self, success): 173 if success == 1: 174 message = "Successful: " 175 else: 176 message = "Failed: " 177 for l in self.log_list: 178 syslog.syslog(syslog.LOG_INFO, message + l) 179 180 181class nulllogger: 182 183 def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""): 184 pass 185 186 def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""): 187 pass 188 189 def log_change(self, msg): 190 pass 191 192 def commit(self, success): 193 pass 194 195 196def validate_level(raw): 197 sensitivity = "s[0-9]*" 198 category = "c[0-9]*" 199 cat_range = category + r"(\." + category + ")?" 200 categories = cat_range + r"(\," + cat_range + ")*" 201 reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?" 202 return re.search("^" + reg + "$", raw) 203 204 205def translate(raw, prepend=1): 206 filler = "a:b:c:" 207 if prepend == 1: 208 context = "%s%s" % (filler, raw) 209 else: 210 context = raw 211 (rc, trans) = selinux.selinux_raw_to_trans_context(context) 212 if rc != 0: 213 return raw 214 if prepend: 215 trans = trans[len(filler):] 216 if trans == "": 217 return raw 218 else: 219 return trans 220 221 222def untranslate(trans, prepend=1): 223 filler = "a:b:c:" 224 if prepend == 1: 225 context = "%s%s" % (filler, trans) 226 else: 227 context = trans 228 229 (rc, raw) = selinux.selinux_trans_to_raw_context(context) 230 if rc != 0: 231 return trans 232 if prepend: 233 raw = raw[len(filler):] 234 if raw == "": 235 return trans 236 else: 237 return raw 238 239 240class semanageRecords: 241 transaction = False 242 handle = None 243 store = None 244 args = None 245 246 def __init__(self, args = None): 247 global handle 248 if args: 249 # legacy code - args was store originally 250 if isinstance(args, str): 251 self.store = args 252 else: 253 self.args = args 254 self.noreload = getattr(args, "noreload", False) 255 if not self.store: 256 self.store = getattr(args, "store", "") 257 258 self.sh = self.get_handle(self.store) 259 260 rc, localstore = selinux.selinux_getpolicytype() 261 if self.store == "" or self.store == localstore: 262 self.mylog = logger() 263 else: 264 sepolicy.load_store_policy(self.store) 265 selinux.selinux_set_policy_root("%s%s" % (selinux.selinux_path(), self.store)) 266 self.mylog = nulllogger() 267 268 def set_reload(self, load): 269 self.noreload = not load 270 271 def get_handle(self, store): 272 global is_mls_enabled 273 274 if semanageRecords.handle: 275 return semanageRecords.handle 276 277 handle = semanage_handle_create() 278 if not handle: 279 raise ValueError(_("Could not create semanage handle")) 280 281 if not semanageRecords.transaction and store != "": 282 semanage_select_store(handle, store, SEMANAGE_CON_DIRECT) 283 semanageRecords.store = store 284 285 if not semanage_is_managed(handle): 286 semanage_handle_destroy(handle) 287 raise ValueError(_("SELinux policy is not managed or store cannot be accessed.")) 288 289 rc = semanage_access_check(handle) 290 if rc < SEMANAGE_CAN_READ: 291 semanage_handle_destroy(handle) 292 raise ValueError(_("Cannot read policy store.")) 293 294 rc = semanage_connect(handle) 295 if rc < 0: 296 semanage_handle_destroy(handle) 297 raise ValueError(_("Could not establish semanage connection")) 298 299 is_mls_enabled = semanage_mls_enabled(handle) 300 if is_mls_enabled < 0: 301 semanage_handle_destroy(handle) 302 raise ValueError(_("Could not test MLS enabled status")) 303 304 semanageRecords.handle = handle 305 return semanageRecords.handle 306 307 def deleteall(self): 308 raise ValueError(_("Not yet implemented")) 309 310 def start(self): 311 if semanageRecords.transaction: 312 raise ValueError(_("Semanage transaction already in progress")) 313 self.begin() 314 semanageRecords.transaction = True 315 316 def begin(self): 317 if semanageRecords.transaction: 318 return 319 rc = semanage_begin_transaction(self.sh) 320 if rc < 0: 321 raise ValueError(_("Could not start semanage transaction")) 322 323 def customized(self): 324 raise ValueError(_("Not yet implemented")) 325 326 def commit(self): 327 if semanageRecords.transaction: 328 return 329 330 if self.noreload: 331 semanage_set_reload(self.sh, 0) 332 rc = semanage_commit(self.sh) 333 if rc < 0: 334 self.mylog.commit(0) 335 raise ValueError(_("Could not commit semanage transaction")) 336 self.mylog.commit(1) 337 338 def finish(self): 339 if not semanageRecords.transaction: 340 raise ValueError(_("Semanage transaction not in progress")) 341 semanageRecords.transaction = False 342 self.commit() 343 344 345class moduleRecords(semanageRecords): 346 347 def __init__(self, args = None): 348 semanageRecords.__init__(self, args) 349 350 def get_all(self): 351 l = [] 352 (rc, mlist, number) = semanage_module_list_all(self.sh) 353 if rc < 0: 354 raise ValueError(_("Could not list SELinux modules")) 355 356 for i in range(number): 357 mod = semanage_module_list_nth(mlist, i) 358 359 rc, name = semanage_module_info_get_name(self.sh, mod) 360 if rc < 0: 361 raise ValueError(_("Could not get module name")) 362 363 rc, enabled = semanage_module_info_get_enabled(self.sh, mod) 364 if rc < 0: 365 raise ValueError(_("Could not get module enabled")) 366 367 rc, priority = semanage_module_info_get_priority(self.sh, mod) 368 if rc < 0: 369 raise ValueError(_("Could not get module priority")) 370 371 rc, lang_ext = semanage_module_info_get_lang_ext(self.sh, mod) 372 if rc < 0: 373 raise ValueError(_("Could not get module lang_ext")) 374 375 l.append((name, enabled, priority, lang_ext)) 376 377 # sort the list so they are in name order, but with higher priorities coming first 378 l.sort(key=lambda t: t[3], reverse=True) 379 l.sort(key=lambda t: t[0]) 380 return l 381 382 def customized(self): 383 all = self.get_all() 384 if len(all) == 0: 385 return [] 386 return ["-d %s" % x[0] for x in [t for t in all if t[1] == 0]] 387 388 def list(self, heading=1, locallist=0): 389 all = self.get_all() 390 if len(all) == 0: 391 return 392 393 if heading: 394 print("\n%-25s %-9s %s\n" % (_("Module Name"), _("Priority"), _("Language"))) 395 for t in all: 396 if t[1] == 0: 397 disabled = _("Disabled") 398 else: 399 if locallist: 400 continue 401 disabled = "" 402 print("%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled)) 403 404 def add(self, file, priority): 405 if not os.path.exists(file): 406 raise ValueError(_("Module does not exist: %s ") % file) 407 408 rc = semanage_set_default_priority(self.sh, priority) 409 if rc < 0: 410 raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority) 411 412 rc = semanage_module_install_file(self.sh, file) 413 if rc >= 0: 414 self.commit() 415 416 def set_enabled(self, module, enable): 417 for m in module.split(): 418 rc, key = semanage_module_key_create(self.sh) 419 if rc < 0: 420 raise ValueError(_("Could not create module key")) 421 422 rc = semanage_module_key_set_name(self.sh, key, m) 423 if rc < 0: 424 raise ValueError(_("Could not set module key name")) 425 426 rc = semanage_module_set_enabled(self.sh, key, enable) 427 if rc < 0: 428 if enable: 429 raise ValueError(_("Could not enable module %s") % m) 430 else: 431 raise ValueError(_("Could not disable module %s") % m) 432 self.commit() 433 434 def delete(self, module, priority): 435 rc = semanage_set_default_priority(self.sh, priority) 436 if rc < 0: 437 raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority) 438 439 for m in module.split(): 440 rc = semanage_module_remove(self.sh, m) 441 if rc < 0 and rc != -2: 442 raise ValueError(_("Could not remove module %s (remove failed)") % m) 443 444 self.commit() 445 446 def deleteall(self): 447 l = [x[0] for x in [t for t in self.get_all() if t[1] == 0]] 448 for m in l: 449 self.set_enabled(m, True) 450 451 452class dontauditClass(semanageRecords): 453 454 def __init__(self, args = None): 455 semanageRecords.__init__(self, args) 456 457 def toggle(self, dontaudit): 458 if dontaudit not in ["on", "off"]: 459 raise ValueError(_("dontaudit requires either 'on' or 'off'")) 460 self.begin() 461 semanage_set_disable_dontaudit(self.sh, dontaudit == "off") 462 self.commit() 463 464 465class permissiveRecords(semanageRecords): 466 467 def __init__(self, args = None): 468 semanageRecords.__init__(self, args) 469 470 def get_all(self): 471 l = [] 472 (rc, mlist, number) = semanage_module_list(self.sh) 473 if rc < 0: 474 raise ValueError(_("Could not list SELinux modules")) 475 476 for i in range(number): 477 mod = semanage_module_list_nth(mlist, i) 478 name = semanage_module_get_name(mod) 479 if name and name.startswith("permissive_"): 480 l.append(name.split("permissive_")[1]) 481 return l 482 483 def customized(self): 484 return ["-a %s" % x for x in sorted(self.get_all())] 485 486 def list(self, heading=1, locallist=0): 487 all = [y["name"] for y in [x for x in sepolicy.info(sepolicy.TYPE) if x["permissive"]]] 488 if len(all) == 0: 489 return 490 491 if heading: 492 print("\n%-25s\n" % (_("Builtin Permissive Types"))) 493 customized = self.get_all() 494 for t in all: 495 if t not in customized: 496 print(t) 497 498 if len(customized) == 0: 499 return 500 501 if heading: 502 print("\n%-25s\n" % (_("Customized Permissive Types"))) 503 for t in customized: 504 print(t) 505 506 def add(self, type): 507 name = "permissive_%s" % type 508 modtxt = "(typepermissive %s)" % type 509 510 rc = semanage_module_install(self.sh, modtxt, len(modtxt), name, "cil") 511 if rc >= 0: 512 self.commit() 513 514 if rc < 0: 515 raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name) 516 517 def delete(self, name): 518 for n in name.split(): 519 rc = semanage_module_remove(self.sh, "permissive_%s" % n) 520 if rc < 0: 521 raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name) 522 523 self.commit() 524 525 def deleteall(self): 526 l = self.get_all() 527 if len(l) > 0: 528 all = " ".join(l) 529 self.delete(all) 530 531 532class loginRecords(semanageRecords): 533 534 def __init__(self, args = None): 535 semanageRecords.__init__(self, args) 536 self.oldsename = None 537 self.oldserange = None 538 self.sename = None 539 self.serange = None 540 541 def __add(self, name, sename, serange): 542 rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) 543 if sename == "": 544 sename = "user_u" 545 546 userrec = seluserRecords(self.args) 547 range, (rc, oldserole) = userrec.get(self.oldsename) 548 range, (rc, serole) = userrec.get(sename) 549 550 if is_mls_enabled == 1: 551 if serange != "": 552 serange = untranslate(serange) 553 else: 554 serange = range 555 556 (rc, k) = semanage_seuser_key_create(self.sh, name) 557 if rc < 0: 558 raise ValueError(_("Could not create a key for %s") % name) 559 560 if name[0] == '%': 561 try: 562 grp.getgrnam(name[1:]) 563 except: 564 raise ValueError(_("Linux Group %s does not exist") % name[1:]) 565 else: 566 try: 567 pwd.getpwnam(name) 568 except: 569 raise ValueError(_("Linux User %s does not exist") % name) 570 571 (rc, u) = semanage_seuser_create(self.sh) 572 if rc < 0: 573 raise ValueError(_("Could not create login mapping for %s") % name) 574 575 rc = semanage_seuser_set_name(self.sh, u, name) 576 if rc < 0: 577 raise ValueError(_("Could not set name for %s") % name) 578 579 if (is_mls_enabled == 1) and (serange != ""): 580 rc = semanage_seuser_set_mlsrange(self.sh, u, serange) 581 if rc < 0: 582 raise ValueError(_("Could not set MLS range for %s") % name) 583 584 rc = semanage_seuser_set_sename(self.sh, u, sename) 585 if rc < 0: 586 raise ValueError(_("Could not set SELinux user for %s") % name) 587 588 rc = semanage_seuser_modify_local(self.sh, k, u) 589 if rc < 0: 590 raise ValueError(_("Could not add login mapping for %s") % name) 591 592 semanage_seuser_key_free(k) 593 semanage_seuser_free(u) 594 595 def add(self, name, sename, serange): 596 try: 597 self.begin() 598 # Add a new mapping, or modify an existing one 599 if self.__exists(name): 600 print(_("Login mapping for %s is already defined, modifying instead") % name) 601 self.__modify(name, sename, serange) 602 else: 603 self.__add(name, sename, serange) 604 self.commit() 605 except ValueError as error: 606 raise error 607 608 # check if login mapping for given user exists 609 def __exists(self, name): 610 (rc, k) = semanage_seuser_key_create(self.sh, name) 611 if rc < 0: 612 raise ValueError(_("Could not create a key for %s") % name) 613 614 (rc, exists) = semanage_seuser_exists(self.sh, k) 615 if rc < 0: 616 raise ValueError(_("Could not check if login mapping for %s is defined") % name) 617 semanage_seuser_key_free(k) 618 619 return exists 620 621 def __modify(self, name, sename="", serange=""): 622 rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) 623 if sename == "" and serange == "": 624 raise ValueError(_("Requires seuser or serange")) 625 626 userrec = seluserRecords(self.args) 627 range, (rc, oldserole) = userrec.get(self.oldsename) 628 629 if sename != "": 630 range, (rc, serole) = userrec.get(sename) 631 else: 632 serole = oldserole 633 634 if serange != "": 635 self.serange = serange 636 else: 637 self.serange = range 638 639 (rc, k) = semanage_seuser_key_create(self.sh, name) 640 if rc < 0: 641 raise ValueError(_("Could not create a key for %s") % name) 642 643 (rc, exists) = semanage_seuser_exists(self.sh, k) 644 if rc < 0: 645 raise ValueError(_("Could not check if login mapping for %s is defined") % name) 646 if not exists: 647 raise ValueError(_("Login mapping for %s is not defined") % name) 648 649 (rc, u) = semanage_seuser_query(self.sh, k) 650 if rc < 0: 651 raise ValueError(_("Could not query seuser for %s") % name) 652 653 self.oldserange = semanage_seuser_get_mlsrange(u) 654 self.oldsename = semanage_seuser_get_sename(u) 655 if (is_mls_enabled == 1) and (serange != ""): 656 semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange)) 657 658 if sename != "": 659 semanage_seuser_set_sename(self.sh, u, sename) 660 self.sename = sename 661 else: 662 self.sename = self.oldsename 663 664 rc = semanage_seuser_modify_local(self.sh, k, u) 665 if rc < 0: 666 raise ValueError(_("Could not modify login mapping for %s") % name) 667 668 semanage_seuser_key_free(k) 669 semanage_seuser_free(u) 670 671 def modify(self, name, sename="", serange=""): 672 try: 673 self.begin() 674 self.__modify(name, sename, serange) 675 self.commit() 676 except ValueError as error: 677 raise error 678 679 def __delete(self, name): 680 rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) 681 userrec = seluserRecords(self.args) 682 range, (rc, oldserole) = userrec.get(self.oldsename) 683 684 (rc, k) = semanage_seuser_key_create(self.sh, name) 685 if rc < 0: 686 raise ValueError(_("Could not create a key for %s") % name) 687 688 (rc, exists) = semanage_seuser_exists(self.sh, k) 689 if rc < 0: 690 raise ValueError(_("Could not check if login mapping for %s is defined") % name) 691 if not exists: 692 raise ValueError(_("Login mapping for %s is not defined") % name) 693 694 (rc, exists) = semanage_seuser_exists_local(self.sh, k) 695 if rc < 0: 696 raise ValueError(_("Could not check if login mapping for %s is defined") % name) 697 if not exists: 698 raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name) 699 700 rc = semanage_seuser_del_local(self.sh, k) 701 if rc < 0: 702 raise ValueError(_("Could not delete login mapping for %s") % name) 703 704 semanage_seuser_key_free(k) 705 706 rec, self.sename, self.serange = selinux.getseuserbyname("__default__") 707 range, (rc, serole) = userrec.get(self.sename) 708 709 def delete(self, name): 710 try: 711 self.begin() 712 self.__delete(name) 713 self.commit() 714 715 except ValueError as error: 716 raise error 717 718 def deleteall(self): 719 (rc, ulist) = semanage_seuser_list_local(self.sh) 720 if rc < 0: 721 raise ValueError(_("Could not list login mappings")) 722 723 try: 724 self.begin() 725 for u in ulist: 726 self.__delete(semanage_seuser_get_name(u)) 727 self.commit() 728 except ValueError as error: 729 raise error 730 731 def get_all_logins(self): 732 ddict = {} 733 self.logins_path = selinux.selinux_policy_root() + "/logins" 734 for path, dirs, files in os.walk(self.logins_path): 735 if path == self.logins_path: 736 for name in files: 737 try: 738 fd = open(path + "/" + name) 739 rec = fd.read().rstrip().split(":") 740 fd.close() 741 ddict[name] = (rec[1], rec[2], rec[0]) 742 except IndexError: 743 pass 744 return ddict 745 746 def get_all(self, locallist=0): 747 ddict = {} 748 if locallist: 749 (rc, self.ulist) = semanage_seuser_list_local(self.sh) 750 else: 751 (rc, self.ulist) = semanage_seuser_list(self.sh) 752 if rc < 0: 753 raise ValueError(_("Could not list login mappings")) 754 755 for u in self.ulist: 756 name = semanage_seuser_get_name(u) 757 ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u), "*") 758 return ddict 759 760 def customized(self): 761 l = [] 762 ddict = self.get_all(True) 763 for k in sorted(ddict.keys()): 764 if ddict[k][1]: 765 l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k)) 766 else: 767 l.append("-a -s %s %s" % (ddict[k][0], k)) 768 return l 769 770 def list(self, heading=1, locallist=0): 771 ddict = self.get_all(locallist) 772 ldict = self.get_all_logins() 773 lkeys = sorted(ldict.keys()) 774 keys = sorted(ddict.keys()) 775 if len(keys) == 0 and len(lkeys) == 0: 776 return 777 778 if is_mls_enabled == 1: 779 if heading: 780 print("\n%-20s %-20s %-20s %s\n" % (_("Login Name"), _("SELinux User"), _("MLS/MCS Range"), _("Service"))) 781 for k in keys: 782 u = ddict[k] 783 print("%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])) 784 if len(lkeys): 785 print("\nLocal customization in %s" % self.logins_path) 786 787 for k in lkeys: 788 u = ldict[k] 789 print("%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])) 790 else: 791 if heading: 792 print("\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User"))) 793 for k in keys: 794 print("%-25s %-25s" % (k, ddict[k][0])) 795 796 797class seluserRecords(semanageRecords): 798 799 def __init__(self, args = None): 800 semanageRecords.__init__(self, args) 801 802 def get(self, name): 803 (rc, k) = semanage_user_key_create(self.sh, name) 804 if rc < 0: 805 raise ValueError(_("Could not create a key for %s") % name) 806 (rc, exists) = semanage_user_exists(self.sh, k) 807 if rc < 0: 808 raise ValueError(_("Could not check if SELinux user %s is defined") % name) 809 (rc, u) = semanage_user_query(self.sh, k) 810 if rc < 0: 811 raise ValueError(_("Could not query user for %s") % name) 812 serange = semanage_user_get_mlsrange(u) 813 serole = semanage_user_get_roles(self.sh, u) 814 semanage_user_key_free(k) 815 semanage_user_free(u) 816 return serange, serole 817 818 def __add(self, name, roles, selevel, serange, prefix): 819 if is_mls_enabled == 1: 820 if serange == "": 821 serange = "s0" 822 else: 823 serange = untranslate(serange) 824 825 if selevel == "": 826 selevel = "s0" 827 else: 828 selevel = untranslate(selevel) 829 830 if len(roles) < 1: 831 raise ValueError(_("You must add at least one role for %s") % name) 832 833 (rc, k) = semanage_user_key_create(self.sh, name) 834 if rc < 0: 835 raise ValueError(_("Could not create a key for %s") % name) 836 837 (rc, u) = semanage_user_create(self.sh) 838 if rc < 0: 839 raise ValueError(_("Could not create SELinux user for %s") % name) 840 841 rc = semanage_user_set_name(self.sh, u, name) 842 if rc < 0: 843 raise ValueError(_("Could not set name for %s") % name) 844 845 for r in roles: 846 rc = semanage_user_add_role(self.sh, u, r) 847 if rc < 0: 848 raise ValueError(_("Could not add role {role} for {name}").format(role=r, name=name)) 849 850 if is_mls_enabled == 1: 851 rc = semanage_user_set_mlsrange(self.sh, u, serange) 852 if rc < 0: 853 raise ValueError(_("Could not set MLS range for %s") % name) 854 855 rc = semanage_user_set_mlslevel(self.sh, u, selevel) 856 if rc < 0: 857 raise ValueError(_("Could not set MLS level for %s") % name) 858 rc = semanage_user_set_prefix(self.sh, u, prefix) 859 if rc < 0: 860 raise ValueError(_("Could not add prefix {prefix} for {role}").format(role=r, prefix=prefix)) 861 (rc, key) = semanage_user_key_extract(self.sh, u) 862 if rc < 0: 863 raise ValueError(_("Could not extract key for %s") % name) 864 865 rc = semanage_user_modify_local(self.sh, k, u) 866 if rc < 0: 867 raise ValueError(_("Could not add SELinux user %s") % name) 868 869 semanage_user_key_free(k) 870 semanage_user_free(u) 871 self.mylog.log("seuser", sename=name, serole=",".join(roles), serange=serange) 872 873 def add(self, name, roles, selevel, serange, prefix): 874 try: 875 self.begin() 876 if self.__exists(name): 877 print(_("SELinux user %s is already defined, modifying instead") % name) 878 self.__modify(name, roles, selevel, serange, prefix) 879 else: 880 self.__add(name, roles, selevel, serange, prefix) 881 self.commit() 882 except ValueError as error: 883 self.mylog.commit(0) 884 raise error 885 886 def __exists(self, name): 887 (rc, k) = semanage_user_key_create(self.sh, name) 888 if rc < 0: 889 raise ValueError(_("Could not create a key for %s") % name) 890 891 (rc, exists) = semanage_user_exists(self.sh, k) 892 if rc < 0: 893 raise ValueError(_("Could not check if SELinux user %s is defined") % name) 894 semanage_user_key_free(k) 895 896 return exists 897 898 def __modify(self, name, roles=[], selevel="", serange="", prefix=""): 899 oldserole = "" 900 oldserange = "" 901 newroles = " ".join(roles) 902 if prefix == "" and len(roles) == 0 and serange == "" and selevel == "": 903 if is_mls_enabled == 1: 904 raise ValueError(_("Requires prefix, roles, level or range")) 905 else: 906 raise ValueError(_("Requires prefix or roles")) 907 908 (rc, k) = semanage_user_key_create(self.sh, name) 909 if rc < 0: 910 raise ValueError(_("Could not create a key for %s") % name) 911 912 (rc, exists) = semanage_user_exists(self.sh, k) 913 if rc < 0: 914 raise ValueError(_("Could not check if SELinux user %s is defined") % name) 915 if not exists: 916 raise ValueError(_("SELinux user %s is not defined") % name) 917 918 (rc, u) = semanage_user_query(self.sh, k) 919 if rc < 0: 920 raise ValueError(_("Could not query user for %s") % name) 921 922 oldserange = semanage_user_get_mlsrange(u) 923 (rc, rlist) = semanage_user_get_roles(self.sh, u) 924 if rc >= 0: 925 oldserole = " ".join(rlist) 926 927 if (is_mls_enabled == 1) and (serange != ""): 928 semanage_user_set_mlsrange(self.sh, u, untranslate(serange)) 929 if (is_mls_enabled == 1) and (selevel != ""): 930 semanage_user_set_mlslevel(self.sh, u, untranslate(selevel)) 931 932 if prefix != "": 933 semanage_user_set_prefix(self.sh, u, prefix) 934 935 if len(roles) != 0: 936 for r in rlist: 937 if r not in roles: 938 semanage_user_del_role(u, r) 939 for r in roles: 940 if r not in rlist: 941 semanage_user_add_role(self.sh, u, r) 942 943 rc = semanage_user_modify_local(self.sh, k, u) 944 if rc < 0: 945 raise ValueError(_("Could not modify SELinux user %s") % name) 946 947 semanage_user_key_free(k) 948 semanage_user_free(u) 949 950 role = ",".join(newroles.split()) 951 oldserole = ",".join(oldserole.split()) 952 self.mylog.log("seuser", sename=name, oldsename=name, serole=role, serange=serange, oldserole=oldserole, oldserange=oldserange) 953 954 def modify(self, name, roles=[], selevel="", serange="", prefix=""): 955 try: 956 self.begin() 957 self.__modify(name, roles, selevel, serange, prefix) 958 self.commit() 959 except ValueError as error: 960 self.mylog.commit(0) 961 raise error 962 963 def __delete(self, name): 964 (rc, k) = semanage_user_key_create(self.sh, name) 965 if rc < 0: 966 raise ValueError(_("Could not create a key for %s") % name) 967 968 (rc, exists) = semanage_user_exists(self.sh, k) 969 if rc < 0: 970 raise ValueError(_("Could not check if SELinux user %s is defined") % name) 971 if not exists: 972 raise ValueError(_("SELinux user %s is not defined") % name) 973 974 (rc, exists) = semanage_user_exists_local(self.sh, k) 975 if rc < 0: 976 raise ValueError(_("Could not check if SELinux user %s is defined") % name) 977 if not exists: 978 raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name) 979 980 (rc, u) = semanage_user_query(self.sh, k) 981 if rc < 0: 982 raise ValueError(_("Could not query user for %s") % name) 983 oldserange = semanage_user_get_mlsrange(u) 984 (rc, rlist) = semanage_user_get_roles(self.sh, u) 985 oldserole = ",".join(rlist) 986 987 rc = semanage_user_del_local(self.sh, k) 988 if rc < 0: 989 raise ValueError(_("Could not delete SELinux user %s") % name) 990 991 semanage_user_key_free(k) 992 semanage_user_free(u) 993 994 self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole) 995 996 def delete(self, name): 997 try: 998 self.begin() 999 self.__delete(name) 1000 self.commit() 1001 1002 except ValueError as error: 1003 self.mylog.commit(0) 1004 raise error 1005 1006 def deleteall(self): 1007 (rc, ulist) = semanage_user_list_local(self.sh) 1008 if rc < 0: 1009 raise ValueError(_("Could not list login mappings")) 1010 1011 try: 1012 self.begin() 1013 for u in ulist: 1014 self.__delete(semanage_user_get_name(u)) 1015 self.commit() 1016 except ValueError as error: 1017 self.mylog.commit(0) 1018 raise error 1019 1020 def get_all(self, locallist=0): 1021 ddict = {} 1022 if locallist: 1023 (rc, self.ulist) = semanage_user_list_local(self.sh) 1024 else: 1025 (rc, self.ulist) = semanage_user_list(self.sh) 1026 if rc < 0: 1027 raise ValueError(_("Could not list SELinux users")) 1028 1029 for u in self.ulist: 1030 name = semanage_user_get_name(u) 1031 (rc, rlist) = semanage_user_get_roles(self.sh, u) 1032 if rc < 0: 1033 raise ValueError(_("Could not list roles for user %s") % name) 1034 1035 roles = " ".join(rlist) 1036 ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles) 1037 1038 return ddict 1039 1040 def customized(self): 1041 l = [] 1042 ddict = self.get_all(True) 1043 for k in sorted(ddict.keys()): 1044 if ddict[k][1] or ddict[k][2]: 1045 l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k)) 1046 else: 1047 l.append("-a -R '%s' %s" % (ddict[k][3], k)) 1048 return l 1049 1050 def list(self, heading=1, locallist=0): 1051 ddict = self.get_all(locallist) 1052 if len(ddict) == 0: 1053 return 1054 keys = sorted(ddict.keys()) 1055 1056 if is_mls_enabled == 1: 1057 if heading: 1058 print("\n%-15s %-10s %-10s %-30s" % ("", _("Labeling"), _("MLS/"), _("MLS/"))) 1059 print("%-15s %-10s %-10s %-30s %s\n" % (_("SELinux User"), _("Prefix"), _("MCS Level"), _("MCS Range"), _("SELinux Roles"))) 1060 for k in keys: 1061 print("%-15s %-10s %-10s %-30s %s" % (k, ddict[k][0], translate(ddict[k][1]), translate(ddict[k][2]), ddict[k][3])) 1062 else: 1063 if heading: 1064 print("%-15s %s\n" % (_("SELinux User"), _("SELinux Roles"))) 1065 for k in keys: 1066 print("%-15s %s" % (k, ddict[k][3])) 1067 1068 1069class portRecords(semanageRecords): 1070 1071 valid_types = [] 1072 1073 def __init__(self, args = None): 1074 semanageRecords.__init__(self, args) 1075 try: 1076 self.valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "port_type"))[0]["types"]) 1077 except RuntimeError: 1078 pass 1079 1080 def __genkey(self, port, proto): 1081 protocols = {"tcp": SEMANAGE_PROTO_TCP, 1082 "udp": SEMANAGE_PROTO_UDP, 1083 "sctp": SEMANAGE_PROTO_SCTP, 1084 "dccp": SEMANAGE_PROTO_DCCP} 1085 1086 if proto in protocols.keys(): 1087 proto_d = protocols[proto] 1088 else: 1089 raise ValueError(_("Protocol has to be one of udp, tcp, dccp or sctp")) 1090 if port == "": 1091 raise ValueError(_("Port is required")) 1092 1093 if isinstance(port, str): 1094 ports = port.split('-', 1) 1095 else: 1096 ports = (port,) 1097 1098 if len(ports) == 1: 1099 high = low = int(ports[0]) 1100 else: 1101 low = int(ports[0]) 1102 high = int(ports[1]) 1103 1104 if high > 65535: 1105 raise ValueError(_("Invalid Port")) 1106 1107 (rc, k) = semanage_port_key_create(self.sh, low, high, proto_d) 1108 if rc < 0: 1109 raise ValueError(_("Could not create a key for {proto}/{port}").format(proto=proto, port=port)) 1110 return (k, proto_d, low, high) 1111 1112 def __add(self, port, proto, serange, type): 1113 if is_mls_enabled == 1: 1114 if serange == "": 1115 serange = "s0" 1116 else: 1117 serange = untranslate(serange) 1118 1119 if type == "": 1120 raise ValueError(_("Type is required")) 1121 1122 type = sepolicy.get_real_type_name(type) 1123 1124 if type not in self.valid_types: 1125 raise ValueError(_("Type %s is invalid, must be a port type") % type) 1126 1127 (k, proto_d, low, high) = self.__genkey(port, proto) 1128 1129 (rc, p) = semanage_port_create(self.sh) 1130 if rc < 0: 1131 raise ValueError(_("Could not create port for {proto}/{port}").format(proto=proto, port=port)) 1132 1133 semanage_port_set_proto(p, proto_d) 1134 semanage_port_set_range(p, low, high) 1135 (rc, con) = semanage_context_create(self.sh) 1136 if rc < 0: 1137 raise ValueError(_("Could not create context for {proto}/{port}").format(proto=proto, port=port)) 1138 1139 rc = semanage_context_set_user(self.sh, con, "system_u") 1140 if rc < 0: 1141 raise ValueError(_("Could not set user in port context for {proto}/{port}").format(proto=proto, port=port)) 1142 1143 rc = semanage_context_set_role(self.sh, con, "object_r") 1144 if rc < 0: 1145 raise ValueError(_("Could not set role in port context for {proto}/{port}").format(proto=proto, port=port)) 1146 1147 rc = semanage_context_set_type(self.sh, con, type) 1148 if rc < 0: 1149 raise ValueError(_("Could not set type in port context for {proto}/{port}").format(proto=proto, port=port)) 1150 1151 if (is_mls_enabled == 1) and (serange != ""): 1152 rc = semanage_context_set_mls(self.sh, con, serange) 1153 if rc < 0: 1154 raise ValueError(_("Could not set mls fields in port context for {proto}/{port}").format(proto=proto, port=port)) 1155 1156 rc = semanage_port_set_con(self.sh, p, con) 1157 if rc < 0: 1158 raise ValueError(_("Could not set port context for {proto}/{port}").format(proto=proto, port=port)) 1159 1160 rc = semanage_port_modify_local(self.sh, k, p) 1161 if rc < 0: 1162 raise ValueError(_("Could not add port {proto}/{port}").format(proto=proto, port=port)) 1163 1164 semanage_context_free(con) 1165 semanage_port_key_free(k) 1166 semanage_port_free(p) 1167 1168 self.mylog.log_change("resrc=port op=add lport=%s proto=%s tcontext=%s:%s:%s:%s" % (port, socket.getprotobyname(proto), "system_u", "object_r", type, serange)) 1169 1170 def add(self, port, proto, serange, type): 1171 self.begin() 1172 if self.__exists(port, proto): 1173 print(_("Port {proto}/{port} already defined, modifying instead").format(proto=proto, port=port)) 1174 self.__modify(port, proto, serange, type) 1175 else: 1176 self.__add(port, proto, serange, type) 1177 self.commit() 1178 1179 def __exists(self, port, proto): 1180 (k, proto_d, low, high) = self.__genkey(port, proto) 1181 1182 (rc, exists) = semanage_port_exists(self.sh, k) 1183 if rc < 0: 1184 raise ValueError(_("Could not check if port {proto}/{port} is defined").format(proto=proto, port=port)) 1185 semanage_port_key_free(k) 1186 1187 return exists 1188 1189 def __modify(self, port, proto, serange, setype): 1190 if serange == "" and setype == "": 1191 if is_mls_enabled == 1: 1192 raise ValueError(_("Requires setype or serange")) 1193 else: 1194 raise ValueError(_("Requires setype")) 1195 1196 setype = sepolicy.get_real_type_name(setype) 1197 if setype and setype not in self.valid_types: 1198 raise ValueError(_("Type %s is invalid, must be a port type") % setype) 1199 1200 (k, proto_d, low, high) = self.__genkey(port, proto) 1201 1202 (rc, exists) = semanage_port_exists(self.sh, k) 1203 if rc < 0: 1204 raise ValueError(_("Could not check if port {proto}/{port} is defined").format(proto=proto, port=port)) 1205 if not exists: 1206 raise ValueError(_("Port {proto}/{port} is not defined").format(proto=proto, port=port)) 1207 1208 (rc, p) = semanage_port_query(self.sh, k) 1209 if rc < 0: 1210 raise ValueError(_("Could not query port {proto}/{port}").format(proto=proto, port=port)) 1211 1212 con = semanage_port_get_con(p) 1213 1214 if is_mls_enabled == 1: 1215 if serange == "": 1216 serange = "s0" 1217 else: 1218 semanage_context_set_mls(self.sh, con, untranslate(serange)) 1219 if setype != "": 1220 semanage_context_set_type(self.sh, con, setype) 1221 1222 rc = semanage_port_modify_local(self.sh, k, p) 1223 if rc < 0: 1224 raise ValueError(_("Could not modify port {proto}/{port}").format(proto=proto, port=port)) 1225 1226 semanage_port_key_free(k) 1227 semanage_port_free(p) 1228 1229 self.mylog.log_change("resrc=port op=modify lport=%s proto=%s tcontext=%s:%s:%s:%s" % (port, socket.getprotobyname(proto), "system_u", "object_r", setype, serange)) 1230 1231 def modify(self, port, proto, serange, setype): 1232 self.begin() 1233 self.__modify(port, proto, serange, setype) 1234 self.commit() 1235 1236 def deleteall(self): 1237 (rc, plist) = semanage_port_list_local(self.sh) 1238 if rc < 0: 1239 raise ValueError(_("Could not list the ports")) 1240 1241 self.begin() 1242 1243 for port in plist: 1244 proto = semanage_port_get_proto(port) 1245 proto_str = semanage_port_get_proto_str(proto) 1246 low = semanage_port_get_low(port) 1247 high = semanage_port_get_high(port) 1248 port_str = "%s-%s" % (low, high) 1249 1250 (k, proto_d, low, high) = self.__genkey(port_str, proto_str) 1251 if rc < 0: 1252 raise ValueError(_("Could not create a key for %s") % port_str) 1253 1254 rc = semanage_port_del_local(self.sh, k) 1255 if rc < 0: 1256 raise ValueError(_("Could not delete the port %s") % port_str) 1257 semanage_port_key_free(k) 1258 1259 if low == high: 1260 port_str = low 1261 1262 self.mylog.log_change("resrc=port op=delete lport=%s proto=%s" % (port_str, socket.getprotobyname(proto_str))) 1263 1264 self.commit() 1265 1266 def __delete(self, port, proto): 1267 (k, proto_d, low, high) = self.__genkey(port, proto) 1268 (rc, exists) = semanage_port_exists(self.sh, k) 1269 if rc < 0: 1270 raise ValueError(_("Could not check if port {proto}/{port} is defined").format(proto=proto, port=port)) 1271 if not exists: 1272 raise ValueError(_("Port {proto}/{port} is not defined").format(proto=proto, port=port)) 1273 1274 (rc, exists) = semanage_port_exists_local(self.sh, k) 1275 if rc < 0: 1276 raise ValueError(_("Could not check if port {proto}/{port} is defined").format(proto=proto, port=port)) 1277 if not exists: 1278 raise ValueError(_("Port {proto}/{port} is defined in policy, cannot be deleted").format(proto=proto, port=port)) 1279 1280 rc = semanage_port_del_local(self.sh, k) 1281 if rc < 0: 1282 raise ValueError(_("Could not delete port {proto}/{port}").format(proto=proto, port=port)) 1283 1284 semanage_port_key_free(k) 1285 1286 self.mylog.log_change("resrc=port op=delete lport=%s proto=%s" % (port, socket.getprotobyname(proto))) 1287 1288 def delete(self, port, proto): 1289 self.begin() 1290 self.__delete(port, proto) 1291 self.commit() 1292 1293 def get_all(self, locallist=0): 1294 ddict = {} 1295 if locallist: 1296 (rc, self.plist) = semanage_port_list_local(self.sh) 1297 else: 1298 (rc, self.plist) = semanage_port_list(self.sh) 1299 if rc < 0: 1300 raise ValueError(_("Could not list ports")) 1301 1302 for port in self.plist: 1303 con = semanage_port_get_con(port) 1304 ctype = semanage_context_get_type(con) 1305 level = semanage_context_get_mls(con) 1306 proto = semanage_port_get_proto(port) 1307 proto_str = semanage_port_get_proto_str(proto) 1308 low = semanage_port_get_low(port) 1309 high = semanage_port_get_high(port) 1310 ddict[(low, high, proto_str)] = (ctype, level) 1311 return ddict 1312 1313 def get_all_by_type(self, locallist=0): 1314 ddict = {} 1315 if locallist: 1316 (rc, self.plist) = semanage_port_list_local(self.sh) 1317 else: 1318 (rc, self.plist) = semanage_port_list(self.sh) 1319 if rc < 0: 1320 raise ValueError(_("Could not list ports")) 1321 1322 for port in self.plist: 1323 con = semanage_port_get_con(port) 1324 ctype = semanage_context_get_type(con) 1325 proto = semanage_port_get_proto(port) 1326 proto_str = semanage_port_get_proto_str(proto) 1327 low = semanage_port_get_low(port) 1328 high = semanage_port_get_high(port) 1329 if (ctype, proto_str) not in ddict.keys(): 1330 ddict[(ctype, proto_str)] = [] 1331 if low == high: 1332 ddict[(ctype, proto_str)].append("%d" % low) 1333 else: 1334 ddict[(ctype, proto_str)].append("%d-%d" % (low, high)) 1335 return ddict 1336 1337 def customized(self): 1338 l = [] 1339 ddict = self.get_all(True) 1340 for k in sorted(ddict.keys()): 1341 port = k[0] if k[0] == k[1] else "%s-%s" % (k[0], k[1]) 1342 if ddict[k][1]: 1343 l.append("-a -t %s -r '%s' -p %s %s" % (ddict[k][0], ddict[k][1], k[2], port)) 1344 else: 1345 l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], port)) 1346 return l 1347 1348 def list(self, heading=1, locallist=0): 1349 ddict = self.get_all_by_type(locallist) 1350 if len(ddict) == 0: 1351 return 1352 keys = sorted(ddict.keys()) 1353 1354 if heading: 1355 print("%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number"))) 1356 for i in keys: 1357 rec = "%-30s %-8s " % i 1358 rec += "%s" % ddict[i][0] 1359 for p in ddict[i][1:]: 1360 rec += ", %s" % p 1361 print(rec) 1362 1363class ibpkeyRecords(semanageRecords): 1364 1365 valid_types = [] 1366 1367 def __init__(self, args = None): 1368 semanageRecords.__init__(self, args) 1369 try: 1370 q = TypeQuery(SELinuxPolicy(sepolicy.get_store_policy(self.store)), attrs=["ibpkey_type"]) 1371 self.valid_types = sorted(str(t) for t in q.results()) 1372 except: 1373 pass 1374 1375 def __genkey(self, pkey, subnet_prefix): 1376 if subnet_prefix == "": 1377 raise ValueError(_("Subnet Prefix is required")) 1378 1379 pkeys = pkey.split("-") 1380 if len(pkeys) == 1: 1381 high = low = int(pkeys[0], 0) 1382 else: 1383 low = int(pkeys[0], 0) 1384 high = int(pkeys[1], 0) 1385 1386 if high > 65535: 1387 raise ValueError(_("Invalid Pkey")) 1388 1389 (rc, k) = semanage_ibpkey_key_create(self.sh, subnet_prefix, low, high) 1390 if rc < 0: 1391 raise ValueError(_("Could not create a key for {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1392 return (k, subnet_prefix, low, high) 1393 1394 def __add(self, pkey, subnet_prefix, serange, type): 1395 if is_mls_enabled == 1: 1396 if serange == "": 1397 serange = "s0" 1398 else: 1399 serange = untranslate(serange) 1400 1401 if type == "": 1402 raise ValueError(_("Type is required")) 1403 1404 type = sepolicy.get_real_type_name(type) 1405 1406 if type not in self.valid_types: 1407 raise ValueError(_("Type %s is invalid, must be a ibpkey type") % type) 1408 1409 (k, subnet_prefix, low, high) = self.__genkey(pkey, subnet_prefix) 1410 1411 (rc, p) = semanage_ibpkey_create(self.sh) 1412 if rc < 0: 1413 raise ValueError(_("Could not create ibpkey for {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1414 1415 semanage_ibpkey_set_subnet_prefix(self.sh, p, subnet_prefix) 1416 semanage_ibpkey_set_range(p, low, high) 1417 (rc, con) = semanage_context_create(self.sh) 1418 if rc < 0: 1419 raise ValueError(_("Could not create context for {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1420 1421 rc = semanage_context_set_user(self.sh, con, "system_u") 1422 if rc < 0: 1423 raise ValueError(_("Could not set user in ibpkey context for {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1424 1425 rc = semanage_context_set_role(self.sh, con, "object_r") 1426 if rc < 0: 1427 raise ValueError(_("Could not set role in ibpkey context for {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1428 1429 rc = semanage_context_set_type(self.sh, con, type) 1430 if rc < 0: 1431 raise ValueError(_("Could not set type in ibpkey context for {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1432 1433 if (is_mls_enabled == 1) and (serange != ""): 1434 rc = semanage_context_set_mls(self.sh, con, serange) 1435 if rc < 0: 1436 raise ValueError(_("Could not set mls fields in ibpkey context for {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1437 1438 rc = semanage_ibpkey_set_con(self.sh, p, con) 1439 if rc < 0: 1440 raise ValueError(_("Could not set ibpkey context for {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1441 1442 rc = semanage_ibpkey_modify_local(self.sh, k, p) 1443 if rc < 0: 1444 raise ValueError(_("Could not add ibpkey {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1445 1446 semanage_context_free(con) 1447 semanage_ibpkey_key_free(k) 1448 semanage_ibpkey_free(p) 1449 1450 def add(self, pkey, subnet_prefix, serange, type): 1451 self.begin() 1452 if self.__exists(pkey, subnet_prefix): 1453 print(_("ibpkey {subnet_prefix}/{pkey} already defined, modifying instead").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1454 self.__modify(pkey, subnet_prefix, serange, type) 1455 else: 1456 self.__add(pkey, subnet_prefix, serange, type) 1457 self.commit() 1458 1459 def __exists(self, pkey, subnet_prefix): 1460 (k, subnet_prefix, low, high) = self.__genkey(pkey, subnet_prefix) 1461 1462 (rc, exists) = semanage_ibpkey_exists(self.sh, k) 1463 if rc < 0: 1464 raise ValueError(_("Could not check if ibpkey {subnet_prefix}/{pkey} is defined").formnat(subnet_prefix=subnet_prefix, pkey=pkey)) 1465 semanage_ibpkey_key_free(k) 1466 1467 return exists 1468 1469 def __modify(self, pkey, subnet_prefix, serange, setype): 1470 if serange == "" and setype == "": 1471 if is_mls_enabled == 1: 1472 raise ValueError(_("Requires setype or serange")) 1473 else: 1474 raise ValueError(_("Requires setype")) 1475 1476 setype = sepolicy.get_real_type_name(setype) 1477 1478 if setype and setype not in self.valid_types: 1479 raise ValueError(_("Type %s is invalid, must be a ibpkey type") % setype) 1480 1481 (k, subnet_prefix, low, high) = self.__genkey(pkey, subnet_prefix) 1482 1483 (rc, exists) = semanage_ibpkey_exists(self.sh, k) 1484 if rc < 0: 1485 raise ValueError(_("Could not check if ibpkey {subnet_prefix}/{pkey} is defined").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1486 if not exists: 1487 raise ValueError(_("ibpkey {subnet_prefix}/{pkey} is not defined").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1488 1489 (rc, p) = semanage_ibpkey_query(self.sh, k) 1490 if rc < 0: 1491 raise ValueError(_("Could not query ibpkey {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1492 1493 con = semanage_ibpkey_get_con(p) 1494 1495 if (is_mls_enabled == 1) and (serange != ""): 1496 semanage_context_set_mls(self.sh, con, untranslate(serange)) 1497 if setype != "": 1498 semanage_context_set_type(self.sh, con, setype) 1499 1500 rc = semanage_ibpkey_modify_local(self.sh, k, p) 1501 if rc < 0: 1502 raise ValueError(_("Could not modify ibpkey {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1503 1504 semanage_ibpkey_key_free(k) 1505 semanage_ibpkey_free(p) 1506 1507 def modify(self, pkey, subnet_prefix, serange, setype): 1508 self.begin() 1509 self.__modify(pkey, subnet_prefix, serange, setype) 1510 self.commit() 1511 1512 def deleteall(self): 1513 (rc, plist) = semanage_ibpkey_list_local(self.sh) 1514 if rc < 0: 1515 raise ValueError(_("Could not list the ibpkeys")) 1516 1517 self.begin() 1518 1519 for ibpkey in plist: 1520 (rc, subnet_prefix) = semanage_ibpkey_get_subnet_prefix(self.sh, ibpkey) 1521 low = semanage_ibpkey_get_low(ibpkey) 1522 high = semanage_ibpkey_get_high(ibpkey) 1523 pkey_str = "%s-%s" % (low, high) 1524 (k, subnet_prefix, low, high) = self.__genkey(pkey_str, subnet_prefix) 1525 if rc < 0: 1526 raise ValueError(_("Could not create a key for %s") % pkey_str) 1527 1528 rc = semanage_ibpkey_del_local(self.sh, k) 1529 if rc < 0: 1530 raise ValueError(_("Could not delete the ibpkey %s") % pkey_str) 1531 semanage_ibpkey_key_free(k) 1532 1533 self.commit() 1534 1535 def __delete(self, pkey, subnet_prefix): 1536 (k, subnet_prefix, low, high) = self.__genkey(pkey, subnet_prefix) 1537 (rc, exists) = semanage_ibpkey_exists(self.sh, k) 1538 if rc < 0: 1539 raise ValueError(_("Could not check if ibpkey {subnet_prefix}/{pkey} is defined").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1540 if not exists: 1541 raise ValueError(_("ibpkey {subnet_prefix}/{pkey} is not defined").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1542 1543 (rc, exists) = semanage_ibpkey_exists_local(self.sh, k) 1544 if rc < 0: 1545 raise ValueError(_("Could not check if ibpkey {subnet_prefix}/{pkey} is defined").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1546 if not exists: 1547 raise ValueError(_("ibpkey {subnet_prefix}/{pkey} is defined in policy, cannot be deleted").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1548 1549 rc = semanage_ibpkey_del_local(self.sh, k) 1550 if rc < 0: 1551 raise ValueError(_("Could not delete ibpkey {subnet_prefix}/{pkey}").format(subnet_prefix=subnet_prefix, pkey=pkey)) 1552 1553 semanage_ibpkey_key_free(k) 1554 1555 def delete(self, pkey, subnet_prefix): 1556 self.begin() 1557 self.__delete(pkey, subnet_prefix) 1558 self.commit() 1559 1560 def get_all(self, locallist=0): 1561 ddict = {} 1562 if locallist: 1563 (rc, self.plist) = semanage_ibpkey_list_local(self.sh) 1564 else: 1565 (rc, self.plist) = semanage_ibpkey_list(self.sh) 1566 if rc < 0: 1567 raise ValueError(_("Could not list ibpkeys")) 1568 1569 for ibpkey in self.plist: 1570 con = semanage_ibpkey_get_con(ibpkey) 1571 ctype = semanage_context_get_type(con) 1572 if ctype == "reserved_ibpkey_t": 1573 continue 1574 level = semanage_context_get_mls(con) 1575 (rc, subnet_prefix) = semanage_ibpkey_get_subnet_prefix(self.sh, ibpkey) 1576 low = semanage_ibpkey_get_low(ibpkey) 1577 high = semanage_ibpkey_get_high(ibpkey) 1578 ddict[(low, high, subnet_prefix)] = (ctype, level) 1579 return ddict 1580 1581 def get_all_by_type(self, locallist=0): 1582 ddict = {} 1583 if locallist: 1584 (rc, self.plist) = semanage_ibpkey_list_local(self.sh) 1585 else: 1586 (rc, self.plist) = semanage_ibpkey_list(self.sh) 1587 if rc < 0: 1588 raise ValueError(_("Could not list ibpkeys")) 1589 1590 for ibpkey in self.plist: 1591 con = semanage_ibpkey_get_con(ibpkey) 1592 ctype = semanage_context_get_type(con) 1593 (rc, subnet_prefix) = semanage_ibpkey_get_subnet_prefix(self.sh, ibpkey) 1594 low = semanage_ibpkey_get_low(ibpkey) 1595 high = semanage_ibpkey_get_high(ibpkey) 1596 if (ctype, subnet_prefix) not in ddict.keys(): 1597 ddict[(ctype, subnet_prefix)] = [] 1598 if low == high: 1599 ddict[(ctype, subnet_prefix)].append("0x%x" % low) 1600 else: 1601 ddict[(ctype, subnet_prefix)].append("0x%x-0x%x" % (low, high)) 1602 return ddict 1603 1604 def customized(self): 1605 l = [] 1606 ddict = self.get_all(True) 1607 1608 for k in sorted(ddict.keys()): 1609 port = k[0] if k[0] == k[1] else "%s-%s" % (k[0], k[1]) 1610 if ddict[k][1]: 1611 l.append("-a -t %s -r '%s' -x %s %s" % (ddict[k][0], ddict[k][1], k[2], port)) 1612 else: 1613 l.append("-a -t %s -x %s %s" % (ddict[k][0], k[2], port)) 1614 return l 1615 1616 def list(self, heading=1, locallist=0): 1617 ddict = self.get_all_by_type(locallist) 1618 keys = ddict.keys() 1619 if len(keys) == 0: 1620 return 1621 1622 if heading: 1623 print("%-30s %-18s %s\n" % (_("SELinux IB Pkey Type"), _("Subnet_Prefix"), _("Pkey Number"))) 1624 for i in sorted(keys): 1625 rec = "%-30s %-18s " % i 1626 rec += "%s" % ddict[i][0] 1627 for p in ddict[i][1:]: 1628 rec += ", %s" % p 1629 print(rec) 1630 1631class ibendportRecords(semanageRecords): 1632 1633 valid_types = [] 1634 1635 def __init__(self, args = None): 1636 semanageRecords.__init__(self, args) 1637 try: 1638 q = TypeQuery(SELinuxPolicy(sepolicy.get_store_policy(self.store)), attrs=["ibendport_type"]) 1639 self.valid_types = set(str(t) for t in q.results()) 1640 except: 1641 pass 1642 1643 def __genkey(self, ibendport, ibdev_name): 1644 if ibdev_name == "": 1645 raise ValueError(_("IB device name is required")) 1646 1647 port = int(ibendport) 1648 1649 if port > 255 or port < 1: 1650 raise ValueError(_("Invalid Port Number")) 1651 1652 (rc, k) = semanage_ibendport_key_create(self.sh, ibdev_name, port) 1653 if rc < 0: 1654 raise ValueError(_("Could not create a key for ibendport {ibdev_name}/{ibendport}").format(ibdev_name=ibdev_name, ibendport=ibendport)) 1655 return (k, ibdev_name, port) 1656 1657 def __add(self, ibendport, ibdev_name, serange, type): 1658 if is_mls_enabled == 1: 1659 if serange == "": 1660 serange = "s0" 1661 else: 1662 serange = untranslate(serange) 1663 1664 if type == "": 1665 raise ValueError(_("Type is required")) 1666 1667 type = sepolicy.get_real_type_name(type) 1668 1669 if type not in self.valid_types: 1670 raise ValueError(_("Type %s is invalid, must be an ibendport type") % type) 1671 (k, ibendport, port) = self.__genkey(ibendport, ibdev_name) 1672 1673 (rc, p) = semanage_ibendport_create(self.sh) 1674 if rc < 0: 1675 raise ValueError(_("Could not create ibendport for {ibdev_name}/{port}").format(ibdev_name=ibdev_name, port=port)) 1676 1677 semanage_ibendport_set_ibdev_name(self.sh, p, ibdev_name) 1678 semanage_ibendport_set_port(p, port) 1679 (rc, con) = semanage_context_create(self.sh) 1680 if rc < 0: 1681 raise ValueError(_("Could not create context for {ibendport}/{port}").format(ibdev_name=ibdev_name, port=port)) 1682 1683 rc = semanage_context_set_user(self.sh, con, "system_u") 1684 if rc < 0: 1685 raise ValueError(_("Could not set user in ibendport context for {ibdev_name}/{port}").format(ibdev_name=ibdev_name, port=port)) 1686 1687 rc = semanage_context_set_role(self.sh, con, "object_r") 1688 if rc < 0: 1689 raise ValueError(_("Could not set role in ibendport context for {ibdev_name}/{port}").format(ibdev_name=ibdev_name, port=port)) 1690 1691 rc = semanage_context_set_type(self.sh, con, type) 1692 if rc < 0: 1693 raise ValueError(_("Could not set type in ibendport context for {ibdev_name}/{port}").format(ibdev_name=ibdev_name, port=port)) 1694 1695 if (is_mls_enabled == 1) and (serange != ""): 1696 rc = semanage_context_set_mls(self.sh, con, serange) 1697 if rc < 0: 1698 raise ValueError(_("Could not set mls fields in ibendport context for {ibdev_name}/{port}").format(ibdev_name=ibdev_name, port=port)) 1699 1700 rc = semanage_ibendport_set_con(self.sh, p, con) 1701 if rc < 0: 1702 raise ValueError(_("Could not set ibendport context for {ibdev_name}/{port}").format(ibdev_name=ibdev_name, port=port)) 1703 1704 rc = semanage_ibendport_modify_local(self.sh, k, p) 1705 if rc < 0: 1706 raise ValueError(_("Could not add ibendport {ibdev_name}/{port}").format(ibdev_name=ibdev_name, port=port)) 1707 1708 semanage_context_free(con) 1709 semanage_ibendport_key_free(k) 1710 semanage_ibendport_free(p) 1711 1712 def add(self, ibendport, ibdev_name, serange, type): 1713 self.begin() 1714 if self.__exists(ibendport, ibdev_name): 1715 print(_("ibendport {ibdev_name}/{port} already defined, modifying instead").format(ibdev_name=ibdev_name, port=port)) 1716 self.__modify(ibendport, ibdev_name, serange, type) 1717 else: 1718 self.__add(ibendport, ibdev_name, serange, type) 1719 self.commit() 1720 1721 def __exists(self, ibendport, ibdev_name): 1722 (k, ibendport, port) = self.__genkey(ibendport, ibdev_name) 1723 1724 (rc, exists) = semanage_ibendport_exists(self.sh, k) 1725 if rc < 0: 1726 raise ValueError(_("Could not check if ibendport {ibdev_name}/{port} is defined").format(ibdev_name=ibdev_name, port=port)) 1727 semanage_ibendport_key_free(k) 1728 1729 return exists 1730 1731 def __modify(self, ibendport, ibdev_name, serange, setype): 1732 if serange == "" and setype == "": 1733 if is_mls_enabled == 1: 1734 raise ValueError(_("Requires setype or serange")) 1735 else: 1736 raise ValueError(_("Requires setype")) 1737 1738 setype = sepolicy.get_real_type_name(setype) 1739 1740 if setype and setype not in self.valid_types: 1741 raise ValueError(_("Type %s is invalid, must be an ibendport type") % setype) 1742 1743 (k, ibdev_name, port) = self.__genkey(ibendport, ibdev_name) 1744 1745 (rc, exists) = semanage_ibendport_exists(self.sh, k) 1746 if rc < 0: 1747 raise ValueError(_("Could not check if ibendport {ibdev_name}/{ibendport} is defined").format(ibdev_name=ibdev_name, ibendport=ibendport)) 1748 if not exists: 1749 raise ValueError(_("ibendport {ibdev_name}/{ibendport} is not defined").format(ibdev_name=ibdev_name, ibendport=ibendport)) 1750 1751 (rc, p) = semanage_ibendport_query(self.sh, k) 1752 if rc < 0: 1753 raise ValueError(_("Could not query ibendport {ibdev_name}/{ibendport}").format(ibdev_name=ibdev_name, ibendport=ibendport)) 1754 1755 con = semanage_ibendport_get_con(p) 1756 1757 if (is_mls_enabled == 1) and (serange != ""): 1758 semanage_context_set_mls(self.sh, con, untranslate(serange)) 1759 if setype != "": 1760 semanage_context_set_type(self.sh, con, setype) 1761 1762 rc = semanage_ibendport_modify_local(self.sh, k, p) 1763 if rc < 0: 1764 raise ValueError(_("Could not modify ibendport {ibdev_name}/{ibendport}").format(ibdev_name=ibdev_name, ibendport=ibendport)) 1765 1766 semanage_ibendport_key_free(k) 1767 semanage_ibendport_free(p) 1768 1769 def modify(self, ibendport, ibdev_name, serange, setype): 1770 self.begin() 1771 self.__modify(ibendport, ibdev_name, serange, setype) 1772 self.commit() 1773 1774 def deleteall(self): 1775 (rc, plist) = semanage_ibendport_list_local(self.sh) 1776 if rc < 0: 1777 raise ValueError(_("Could not list the ibendports")) 1778 1779 self.begin() 1780 1781 for ibendport in plist: 1782 (rc, ibdev_name) = semanage_ibendport_get_ibdev_name(self.sh, ibendport) 1783 port = semanage_ibendport_get_port(ibendport) 1784 (k, ibdev_name, port) = self.__genkey(str(port), ibdev_name) 1785 if rc < 0: 1786 raise ValueError(_("Could not create a key for {ibdev_name}/{port}").format(ibdev_name=ibdev_name, port=port)) 1787 1788 rc = semanage_ibendport_del_local(self.sh, k) 1789 if rc < 0: 1790 raise ValueError(_("Could not delete the ibendport {ibdev_name}/{port}").format(ibdev_name=ibdev_name, port=port)) 1791 semanage_ibendport_key_free(k) 1792 1793 self.commit() 1794 1795 def __delete(self, ibendport, ibdev_name): 1796 (k, ibdev_name, port) = self.__genkey(ibendport, ibdev_name) 1797 (rc, exists) = semanage_ibendport_exists(self.sh, k) 1798 if rc < 0: 1799 raise ValueError(_("Could not check if ibendport {ibdev_name}/{ibendport} is defined").format(ibdev_name=ibdev_name, ibendport=ibendport)) 1800 if not exists: 1801 raise ValueError(_("ibendport {ibdev_name}/{ibendport} is not defined").format(ibdev_name=ibdev_name, ibendport=ibendport)) 1802 1803 (rc, exists) = semanage_ibendport_exists_local(self.sh, k) 1804 if rc < 0: 1805 raise ValueError(_("Could not check if ibendport {ibdev_name}/{ibendport} is defined").format(ibdev_name=ibdev_name, ibendport=ibendport)) 1806 if not exists: 1807 raise ValueError(_("ibendport {ibdev_name}/{ibendport} is defined in policy, cannot be deleted").format(ibdev_name=ibdev_name, ibendport=ibendport)) 1808 1809 rc = semanage_ibendport_del_local(self.sh, k) 1810 if rc < 0: 1811 raise ValueError(_("Could not delete ibendport {ibdev_name}/{ibendport}").format(ibdev_name=ibdev_name, ibendport=ibendport)) 1812 1813 semanage_ibendport_key_free(k) 1814 1815 def delete(self, ibendport, ibdev_name): 1816 self.begin() 1817 self.__delete(ibendport, ibdev_name) 1818 self.commit() 1819 1820 def get_all(self, locallist=0): 1821 ddict = {} 1822 if locallist: 1823 (rc, self.plist) = semanage_ibendport_list_local(self.sh) 1824 else: 1825 (rc, self.plist) = semanage_ibendport_list(self.sh) 1826 if rc < 0: 1827 raise ValueError(_("Could not list ibendports")) 1828 1829 for ibendport in self.plist: 1830 con = semanage_ibendport_get_con(ibendport) 1831 ctype = semanage_context_get_type(con) 1832 if ctype == "reserved_ibendport_t": 1833 continue 1834 level = semanage_context_get_mls(con) 1835 (rc, ibdev_name) = semanage_ibendport_get_ibdev_name(self.sh, ibendport) 1836 port = semanage_ibendport_get_port(ibendport) 1837 ddict[(port, ibdev_name)] = (ctype, level) 1838 return ddict 1839 1840 def get_all_by_type(self, locallist=0): 1841 ddict = {} 1842 if locallist: 1843 (rc, self.plist) = semanage_ibendport_list_local(self.sh) 1844 else: 1845 (rc, self.plist) = semanage_ibendport_list(self.sh) 1846 if rc < 0: 1847 raise ValueError(_("Could not list ibendports")) 1848 1849 for ibendport in self.plist: 1850 con = semanage_ibendport_get_con(ibendport) 1851 ctype = semanage_context_get_type(con) 1852 (rc, ibdev_name) = semanage_ibendport_get_ibdev_name(self.sh, ibendport) 1853 port = semanage_ibendport_get_port(ibendport) 1854 if (ctype, ibdev_name) not in ddict.keys(): 1855 ddict[(ctype, ibdev_name)] = [] 1856 ddict[(ctype, ibdev_name)].append("0x%x" % port) 1857 return ddict 1858 1859 def customized(self): 1860 l = [] 1861 ddict = self.get_all(True) 1862 1863 for k in sorted(ddict.keys()): 1864 if ddict[k][1]: 1865 l.append("-a -t %s -r '%s' -z %s %s" % (ddict[k][0], ddict[k][1], k[1], k[0])) 1866 else: 1867 l.append("-a -t %s -z %s %s" % (ddict[k][0], k[1], k[0])) 1868 return l 1869 1870 def list(self, heading=1, locallist=0): 1871 ddict = self.get_all_by_type(locallist) 1872 keys = ddict.keys() 1873 if len(keys) == 0: 1874 return 1875 1876 if heading: 1877 print("%-30s %-18s %s\n" % (_("SELinux IB End Port Type"), _("IB Device Name"), _("Port Number"))) 1878 for i in sorted(keys): 1879 rec = "%-30s %-18s " % i 1880 rec += "%s" % ddict[i][0] 1881 for p in ddict[i][1:]: 1882 rec += ", %s" % p 1883 print(rec) 1884 1885class nodeRecords(semanageRecords): 1886 1887 valid_types = [] 1888 1889 def __init__(self, args = None): 1890 semanageRecords.__init__(self, args) 1891 self.protocol = ["ipv4", "ipv6"] 1892 try: 1893 self.valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "node_type"))[0]["types"]) 1894 except RuntimeError: 1895 pass 1896 1897 def validate(self, addr, mask, protocol): 1898 newaddr = addr 1899 newmask = mask 1900 newprotocol = "" 1901 1902 if addr == "": 1903 raise ValueError(_("Node Address is required")) 1904 1905 # verify that (addr, mask) is either a IP address (without a mask) or a valid network mask 1906 if len(mask) == 0 or mask[0] == "/": 1907 i = ipaddress.ip_network(addr + mask) 1908 newaddr = str(i.network_address) 1909 newmask = str(i.netmask) 1910 protocol = "ipv%d" % i.version 1911 1912 try: 1913 newprotocol = self.protocol.index(protocol) 1914 except: 1915 raise ValueError(_("Unknown or missing protocol")) 1916 1917 try: 1918 audit_protocol = socket.getprotobyname(protocol) 1919 except: 1920 # Entry for "ipv4" not found in /etc/protocols on (at 1921 # least) Debian? To ensure audit log compatibility, let's 1922 # use the same numeric value as Fedora: 4, which is 1923 # actually understood by kernel as IP over IP. 1924 if (protocol == "ipv4"): 1925 audit_protocol = socket.IPPROTO_IPIP 1926 else: 1927 raise ValueError(_("Unknown or missing protocol")) 1928 1929 return newaddr, newmask, newprotocol, audit_protocol 1930 1931 def __add(self, addr, mask, proto, serange, ctype): 1932 addr, mask, proto, audit_proto = self.validate(addr, mask, proto) 1933 1934 if is_mls_enabled == 1: 1935 if serange == "": 1936 serange = "s0" 1937 else: 1938 serange = untranslate(serange) 1939 1940 if ctype == "": 1941 raise ValueError(_("SELinux node type is required")) 1942 1943 ctype = sepolicy.get_real_type_name(ctype) 1944 1945 if ctype not in self.valid_types: 1946 raise ValueError(_("Type %s is invalid, must be a node type") % ctype) 1947 1948 (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) 1949 if rc < 0: 1950 raise ValueError(_("Could not create key for %s") % addr) 1951 1952 (rc, node) = semanage_node_create(self.sh) 1953 if rc < 0: 1954 raise ValueError(_("Could not create addr for %s") % addr) 1955 semanage_node_set_proto(node, proto) 1956 1957 rc = semanage_node_set_addr(self.sh, node, proto, addr) 1958 (rc, con) = semanage_context_create(self.sh) 1959 if rc < 0: 1960 raise ValueError(_("Could not create context for %s") % addr) 1961 1962 rc = semanage_node_set_mask(self.sh, node, proto, mask) 1963 if rc < 0: 1964 raise ValueError(_("Could not set mask for %s") % addr) 1965 1966 rc = semanage_context_set_user(self.sh, con, "system_u") 1967 if rc < 0: 1968 raise ValueError(_("Could not set user in addr context for %s") % addr) 1969 1970 rc = semanage_context_set_role(self.sh, con, "object_r") 1971 if rc < 0: 1972 raise ValueError(_("Could not set role in addr context for %s") % addr) 1973 1974 rc = semanage_context_set_type(self.sh, con, ctype) 1975 if rc < 0: 1976 raise ValueError(_("Could not set type in addr context for %s") % addr) 1977 1978 if (is_mls_enabled == 1) and (serange != ""): 1979 rc = semanage_context_set_mls(self.sh, con, serange) 1980 if rc < 0: 1981 raise ValueError(_("Could not set mls fields in addr context for %s") % addr) 1982 1983 rc = semanage_node_set_con(self.sh, node, con) 1984 if rc < 0: 1985 raise ValueError(_("Could not set addr context for %s") % addr) 1986 1987 rc = semanage_node_modify_local(self.sh, k, node) 1988 if rc < 0: 1989 raise ValueError(_("Could not add addr %s") % addr) 1990 1991 semanage_context_free(con) 1992 semanage_node_key_free(k) 1993 semanage_node_free(node) 1994 1995 self.mylog.log_change("resrc=node op=add laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, audit_proto, "system_u", "object_r", ctype, serange)) 1996 1997 def add(self, addr, mask, proto, serange, ctype): 1998 self.begin() 1999 if self.__exists(addr, mask, proto): 2000 print(_("Addr %s already defined, modifying instead") % addr) 2001 self.__modify(addr, mask, proto, serange, ctype) 2002 else: 2003 self.__add(addr, mask, proto, serange, ctype) 2004 self.commit() 2005 2006 def __exists(self, addr, mask, proto): 2007 addr, mask, proto, audit_proto = self.validate(addr, mask, proto) 2008 2009 (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) 2010 if rc < 0: 2011 raise ValueError(_("Could not create key for %s") % addr) 2012 2013 (rc, exists) = semanage_node_exists(self.sh, k) 2014 if rc < 0: 2015 raise ValueError(_("Could not check if addr %s is defined") % addr) 2016 semanage_node_key_free(k) 2017 2018 return exists 2019 2020 def __modify(self, addr, mask, proto, serange, setype): 2021 addr, mask, proto, audit_proto = self.validate(addr, mask, proto) 2022 2023 if serange == "" and setype == "": 2024 raise ValueError(_("Requires setype or serange")) 2025 2026 setype = sepolicy.get_real_type_name(setype) 2027 2028 if setype and setype not in self.valid_types: 2029 raise ValueError(_("Type %s is invalid, must be a node type") % setype) 2030 2031 (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) 2032 if rc < 0: 2033 raise ValueError(_("Could not create key for %s") % addr) 2034 2035 (rc, exists) = semanage_node_exists(self.sh, k) 2036 if rc < 0: 2037 raise ValueError(_("Could not check if addr %s is defined") % addr) 2038 if not exists: 2039 raise ValueError(_("Addr %s is not defined") % addr) 2040 2041 (rc, node) = semanage_node_query(self.sh, k) 2042 if rc < 0: 2043 raise ValueError(_("Could not query addr %s") % addr) 2044 2045 con = semanage_node_get_con(node) 2046 if (is_mls_enabled == 1) and (serange != ""): 2047 semanage_context_set_mls(self.sh, con, untranslate(serange)) 2048 if setype != "": 2049 semanage_context_set_type(self.sh, con, setype) 2050 2051 rc = semanage_node_modify_local(self.sh, k, node) 2052 if rc < 0: 2053 raise ValueError(_("Could not modify addr %s") % addr) 2054 2055 semanage_node_key_free(k) 2056 semanage_node_free(node) 2057 2058 self.mylog.log_change("resrc=node op=modify laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, audit_proto, "system_u", "object_r", setype, serange)) 2059 2060 def modify(self, addr, mask, proto, serange, setype): 2061 self.begin() 2062 self.__modify(addr, mask, proto, serange, setype) 2063 self.commit() 2064 2065 def __delete(self, addr, mask, proto): 2066 addr, mask, proto, audit_proto = self.validate(addr, mask, proto) 2067 2068 (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) 2069 if rc < 0: 2070 raise ValueError(_("Could not create key for %s") % addr) 2071 2072 (rc, exists) = semanage_node_exists(self.sh, k) 2073 if rc < 0: 2074 raise ValueError(_("Could not check if addr %s is defined") % addr) 2075 if not exists: 2076 raise ValueError(_("Addr %s is not defined") % addr) 2077 2078 (rc, exists) = semanage_node_exists_local(self.sh, k) 2079 if rc < 0: 2080 raise ValueError(_("Could not check if addr %s is defined") % addr) 2081 if not exists: 2082 raise ValueError(_("Addr %s is defined in policy, cannot be deleted") % addr) 2083 2084 rc = semanage_node_del_local(self.sh, k) 2085 if rc < 0: 2086 raise ValueError(_("Could not delete addr %s") % addr) 2087 2088 semanage_node_key_free(k) 2089 2090 self.mylog.log_change("resrc=node op=delete laddr=%s netmask=%s proto=%s" % (addr, mask, audit_proto)) 2091 2092 def delete(self, addr, mask, proto): 2093 self.begin() 2094 self.__delete(addr, mask, proto) 2095 self.commit() 2096 2097 def deleteall(self): 2098 (rc, nlist) = semanage_node_list_local(self.sh) 2099 if rc < 0: 2100 raise ValueError(_("Could not deleteall node mappings")) 2101 2102 self.begin() 2103 for node in nlist: 2104 self.__delete(semanage_node_get_addr(self.sh, node)[1], semanage_node_get_mask(self.sh, node)[1], self.protocol[semanage_node_get_proto(node)]) 2105 self.commit() 2106 2107 def get_all(self, locallist=0): 2108 ddict = {} 2109 if locallist: 2110 (rc, self.ilist) = semanage_node_list_local(self.sh) 2111 else: 2112 (rc, self.ilist) = semanage_node_list(self.sh) 2113 if rc < 0: 2114 raise ValueError(_("Could not list addrs")) 2115 2116 for node in self.ilist: 2117 con = semanage_node_get_con(node) 2118 addr = semanage_node_get_addr(self.sh, node) 2119 mask = semanage_node_get_mask(self.sh, node) 2120 proto = self.protocol[semanage_node_get_proto(node)] 2121 ddict[(addr[1], mask[1], proto)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) 2122 2123 return ddict 2124 2125 def customized(self): 2126 l = [] 2127 ddict = self.get_all(True) 2128 for k in sorted(ddict.keys()): 2129 if ddict[k][3]: 2130 l.append("-a -M %s -p %s -t %s -r '%s' %s" % (k[1], k[2], ddict[k][2], ddict[k][3], k[0])) 2131 else: 2132 l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2], ddict[k][2], k[0])) 2133 return l 2134 2135 def list(self, heading=1, locallist=0): 2136 ddict = self.get_all(locallist) 2137 if len(ddict) == 0: 2138 return 2139 keys = sorted(ddict.keys()) 2140 2141 if heading: 2142 print("%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context")) 2143 if is_mls_enabled: 2144 for k in keys: 2145 val = '' 2146 for fields in k: 2147 val = val + '\t' + str(fields) 2148 print("%-18s %-18s %-5s %s:%s:%s:%s " % (k[0], k[1], k[2], ddict[k][0], ddict[k][1], ddict[k][2], translate(ddict[k][3], False))) 2149 else: 2150 for k in keys: 2151 print("%-18s %-18s %-5s %s:%s:%s " % (k[0], k[1], k[2], ddict[k][0], ddict[k][1], ddict[k][2])) 2152 2153 2154class interfaceRecords(semanageRecords): 2155 2156 def __init__(self, args = None): 2157 semanageRecords.__init__(self, args) 2158 2159 def __add(self, interface, serange, ctype): 2160 if is_mls_enabled == 1: 2161 if serange == "": 2162 serange = "s0" 2163 else: 2164 serange = untranslate(serange) 2165 2166 if ctype == "": 2167 raise ValueError(_("SELinux Type is required")) 2168 2169 (rc, k) = semanage_iface_key_create(self.sh, interface) 2170 if rc < 0: 2171 raise ValueError(_("Could not create key for %s") % interface) 2172 2173 (rc, iface) = semanage_iface_create(self.sh) 2174 if rc < 0: 2175 raise ValueError(_("Could not create interface for %s") % interface) 2176 2177 rc = semanage_iface_set_name(self.sh, iface, interface) 2178 (rc, con) = semanage_context_create(self.sh) 2179 if rc < 0: 2180 raise ValueError(_("Could not create context for %s") % interface) 2181 2182 rc = semanage_context_set_user(self.sh, con, "system_u") 2183 if rc < 0: 2184 raise ValueError(_("Could not set user in interface context for %s") % interface) 2185 2186 rc = semanage_context_set_role(self.sh, con, "object_r") 2187 if rc < 0: 2188 raise ValueError(_("Could not set role in interface context for %s") % interface) 2189 2190 rc = semanage_context_set_type(self.sh, con, ctype) 2191 if rc < 0: 2192 raise ValueError(_("Could not set type in interface context for %s") % interface) 2193 2194 if (is_mls_enabled == 1) and (serange != ""): 2195 rc = semanage_context_set_mls(self.sh, con, serange) 2196 if rc < 0: 2197 raise ValueError(_("Could not set mls fields in interface context for %s") % interface) 2198 2199 rc = semanage_iface_set_ifcon(self.sh, iface, con) 2200 if rc < 0: 2201 raise ValueError(_("Could not set interface context for %s") % interface) 2202 2203 rc = semanage_iface_set_msgcon(self.sh, iface, con) 2204 if rc < 0: 2205 raise ValueError(_("Could not set message context for %s") % interface) 2206 2207 rc = semanage_iface_modify_local(self.sh, k, iface) 2208 if rc < 0: 2209 raise ValueError(_("Could not add interface %s") % interface) 2210 2211 semanage_context_free(con) 2212 semanage_iface_key_free(k) 2213 semanage_iface_free(iface) 2214 2215 self.mylog.log_change("resrc=interface op=add netif=%s tcontext=%s:%s:%s:%s" % (interface, "system_u", "object_r", ctype, serange)) 2216 2217 def add(self, interface, serange, ctype): 2218 self.begin() 2219 if self.__exists(interface): 2220 print(_("Interface %s already defined, modifying instead") % interface) 2221 self.__modify(interface, serange, ctype) 2222 else: 2223 self.__add(interface, serange, ctype) 2224 self.commit() 2225 2226 def __exists(self, interface): 2227 (rc, k) = semanage_iface_key_create(self.sh, interface) 2228 if rc < 0: 2229 raise ValueError(_("Could not create key for %s") % interface) 2230 2231 (rc, exists) = semanage_iface_exists(self.sh, k) 2232 if rc < 0: 2233 raise ValueError(_("Could not check if interface %s is defined") % interface) 2234 semanage_iface_key_free(k) 2235 2236 return exists 2237 2238 def __modify(self, interface, serange, setype): 2239 if serange == "" and setype == "": 2240 raise ValueError(_("Requires setype or serange")) 2241 2242 (rc, k) = semanage_iface_key_create(self.sh, interface) 2243 if rc < 0: 2244 raise ValueError(_("Could not create key for %s") % interface) 2245 2246 (rc, exists) = semanage_iface_exists(self.sh, k) 2247 if rc < 0: 2248 raise ValueError(_("Could not check if interface %s is defined") % interface) 2249 if not exists: 2250 raise ValueError(_("Interface %s is not defined") % interface) 2251 2252 (rc, iface) = semanage_iface_query(self.sh, k) 2253 if rc < 0: 2254 raise ValueError(_("Could not query interface %s") % interface) 2255 2256 con = semanage_iface_get_ifcon(iface) 2257 2258 if (is_mls_enabled == 1) and (serange != ""): 2259 semanage_context_set_mls(self.sh, con, untranslate(serange)) 2260 if setype != "": 2261 semanage_context_set_type(self.sh, con, setype) 2262 2263 rc = semanage_iface_modify_local(self.sh, k, iface) 2264 if rc < 0: 2265 raise ValueError(_("Could not modify interface %s") % interface) 2266 2267 semanage_iface_key_free(k) 2268 semanage_iface_free(iface) 2269 2270 self.mylog.log_change("resrc=interface op=modify netif=%s tcontext=%s:%s:%s:%s" % (interface, "system_u", "object_r", setype, serange)) 2271 2272 def modify(self, interface, serange, setype): 2273 self.begin() 2274 self.__modify(interface, serange, setype) 2275 self.commit() 2276 2277 def __delete(self, interface): 2278 (rc, k) = semanage_iface_key_create(self.sh, interface) 2279 if rc < 0: 2280 raise ValueError(_("Could not create key for %s") % interface) 2281 2282 (rc, exists) = semanage_iface_exists(self.sh, k) 2283 if rc < 0: 2284 raise ValueError(_("Could not check if interface %s is defined") % interface) 2285 if not exists: 2286 raise ValueError(_("Interface %s is not defined") % interface) 2287 2288 (rc, exists) = semanage_iface_exists_local(self.sh, k) 2289 if rc < 0: 2290 raise ValueError(_("Could not check if interface %s is defined") % interface) 2291 if not exists: 2292 raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface) 2293 2294 rc = semanage_iface_del_local(self.sh, k) 2295 if rc < 0: 2296 raise ValueError(_("Could not delete interface %s") % interface) 2297 2298 semanage_iface_key_free(k) 2299 2300 self.mylog.log_change("resrc=interface op=delete netif=%s" % interface) 2301 2302 def delete(self, interface): 2303 self.begin() 2304 self.__delete(interface) 2305 self.commit() 2306 2307 def deleteall(self): 2308 (rc, ulist) = semanage_iface_list_local(self.sh) 2309 if rc < 0: 2310 raise ValueError(_("Could not delete all interface mappings")) 2311 2312 self.begin() 2313 for i in ulist: 2314 self.__delete(semanage_iface_get_name(i)) 2315 self.commit() 2316 2317 def get_all(self, locallist=0): 2318 ddict = {} 2319 if locallist: 2320 (rc, self.ilist) = semanage_iface_list_local(self.sh) 2321 else: 2322 (rc, self.ilist) = semanage_iface_list(self.sh) 2323 if rc < 0: 2324 raise ValueError(_("Could not list interfaces")) 2325 2326 for interface in self.ilist: 2327 con = semanage_iface_get_ifcon(interface) 2328 ddict[semanage_iface_get_name(interface)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) 2329 2330 return ddict 2331 2332 def customized(self): 2333 l = [] 2334 ddict = self.get_all(True) 2335 for k in sorted(ddict.keys()): 2336 if ddict[k][3]: 2337 l.append("-a -t %s -r '%s' %s" % (ddict[k][2], ddict[k][3], k)) 2338 else: 2339 l.append("-a -t %s %s" % (ddict[k][2], k)) 2340 return l 2341 2342 def list(self, heading=1, locallist=0): 2343 ddict = self.get_all(locallist) 2344 if len(ddict) == 0: 2345 return 2346 keys = sorted(ddict.keys()) 2347 2348 if heading: 2349 print("%-30s %s\n" % (_("SELinux Interface"), _("Context"))) 2350 if is_mls_enabled: 2351 for k in keys: 2352 print("%-30s %s:%s:%s:%s " % (k, ddict[k][0], ddict[k][1], ddict[k][2], translate(ddict[k][3], False))) 2353 else: 2354 for k in keys: 2355 print("%-30s %s:%s:%s " % (k, ddict[k][0], ddict[k][1], ddict[k][2])) 2356 2357 2358class fcontextRecords(semanageRecords): 2359 2360 valid_types = [] 2361 2362 def __init__(self, args = None): 2363 semanageRecords.__init__(self, args) 2364 try: 2365 self.valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "file_type"))[0]["types"]) 2366 self.valid_types += list(list(sepolicy.info(sepolicy.ATTRIBUTE, "device_node"))[0]["types"]) 2367 except RuntimeError: 2368 pass 2369 2370 self.equiv = {} 2371 self.equiv_dist = {} 2372 self.equal_ind = False 2373 try: 2374 fd = open(selinux.selinux_file_context_subs_path(), "r") 2375 for i in fd.readlines(): 2376 i = i.strip() 2377 if len(i) == 0: 2378 continue 2379 if i.startswith("#"): 2380 continue 2381 target, substitute = i.split() 2382 self.equiv[target] = substitute 2383 fd.close() 2384 except IOError: 2385 pass 2386 try: 2387 fd = open(selinux.selinux_file_context_subs_dist_path(), "r") 2388 for i in fd.readlines(): 2389 i = i.strip() 2390 if len(i) == 0: 2391 continue 2392 if i.startswith("#"): 2393 continue 2394 target, substitute = i.split() 2395 self.equiv_dist[target] = substitute 2396 fd.close() 2397 except IOError: 2398 pass 2399 2400 def commit(self): 2401 if self.equal_ind: 2402 subs_file = selinux.selinux_file_context_subs_path() 2403 tmpfile = "%s.tmp" % subs_file 2404 fd = open(tmpfile, "w") 2405 for target in self.equiv.keys(): 2406 fd.write("%s %s\n" % (target, self.equiv[target])) 2407 fd.close() 2408 try: 2409 os.chmod(tmpfile, os.stat(subs_file)[stat.ST_MODE]) 2410 except: 2411 pass 2412 os.rename(tmpfile, subs_file) 2413 self.equal_ind = False 2414 semanageRecords.commit(self) 2415 2416 def add_equal(self, target, substitute): 2417 self.begin() 2418 if target != "/" and target[-1] == "/": 2419 raise ValueError(_("Target %s is not valid. Target is not allowed to end with '/'") % target) 2420 2421 if substitute != "/" and substitute[-1] == "/": 2422 raise ValueError(_("Substitute %s is not valid. Substitute is not allowed to end with '/'") % substitute) 2423 2424 if target in self.equiv.keys(): 2425 print(_("Equivalence class for %s already exists, modifying instead") % target) 2426 self.equiv[target] = substitute 2427 self.equal_ind = True 2428 self.mylog.log_change("resrc=fcontext op=modify-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0))) 2429 self.commit() 2430 return 2431 2432 self.validate(target) 2433 2434 for fdict in (self.equiv, self.equiv_dist): 2435 for i in fdict: 2436 if i.startswith(target + "/"): 2437 raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i])) 2438 2439 self.mylog.log_change("resrc=fcontext op=add-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0))) 2440 2441 self.equiv[target] = substitute 2442 self.equal_ind = True 2443 self.commit() 2444 2445 def modify_equal(self, target, substitute): 2446 self.begin() 2447 if target not in self.equiv.keys(): 2448 raise ValueError(_("Equivalence class for %s does not exist") % target) 2449 self.equiv[target] = substitute 2450 self.equal_ind = True 2451 2452 self.mylog.log_change("resrc=fcontext op=modify-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0))) 2453 2454 self.commit() 2455 2456 def createcon(self, target, seuser="system_u"): 2457 (rc, con) = semanage_context_create(self.sh) 2458 if rc < 0: 2459 raise ValueError(_("Could not create context for %s") % target) 2460 if seuser == "": 2461 seuser = "system_u" 2462 2463 rc = semanage_context_set_user(self.sh, con, seuser) 2464 if rc < 0: 2465 raise ValueError(_("Could not set user in file context for %s") % target) 2466 2467 rc = semanage_context_set_role(self.sh, con, "object_r") 2468 if rc < 0: 2469 raise ValueError(_("Could not set role in file context for %s") % target) 2470 2471 if is_mls_enabled == 1: 2472 rc = semanage_context_set_mls(self.sh, con, "s0") 2473 if rc < 0: 2474 raise ValueError(_("Could not set mls fields in file context for %s") % target) 2475 2476 return con 2477 2478 def validate(self, target): 2479 if target == "" or target.find("\n") >= 0: 2480 raise ValueError(_("Invalid file specification")) 2481 if target.find(" ") != -1: 2482 raise ValueError(_("File specification can not include spaces")) 2483 for fdict in (self.equiv, self.equiv_dist): 2484 for i in fdict: 2485 if target.startswith(i + "/"): 2486 t = re.sub(i, fdict[i], target) 2487 raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'; Try adding '%s' instead") % (target, i, fdict[i], t)) 2488 2489 def __add(self, target, type, ftype="", serange="", seuser="system_u"): 2490 self.validate(target) 2491 2492 if is_mls_enabled == 1: 2493 serange = untranslate(serange) 2494 2495 if type == "": 2496 raise ValueError(_("SELinux Type is required")) 2497 2498 if type != "<<none>>": 2499 type = sepolicy.get_real_type_name(type) 2500 if type not in self.valid_types: 2501 raise ValueError(_("Type %s is invalid, must be a file or device type") % type) 2502 2503 (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) 2504 if rc < 0: 2505 raise ValueError(_("Could not create key for %s") % target) 2506 2507 (rc, fcontext) = semanage_fcontext_create(self.sh) 2508 if rc < 0: 2509 raise ValueError(_("Could not create file context for %s") % target) 2510 2511 rc = semanage_fcontext_set_expr(self.sh, fcontext, target) 2512 if type != "<<none>>": 2513 con = self.createcon(target, seuser) 2514 2515 rc = semanage_context_set_type(self.sh, con, type) 2516 if rc < 0: 2517 raise ValueError(_("Could not set type in file context for %s") % target) 2518 2519 if (is_mls_enabled == 1) and (serange != ""): 2520 rc = semanage_context_set_mls(self.sh, con, serange) 2521 if rc < 0: 2522 raise ValueError(_("Could not set mls fields in file context for %s") % target) 2523 rc = semanage_fcontext_set_con(self.sh, fcontext, con) 2524 if rc < 0: 2525 raise ValueError(_("Could not set file context for %s") % target) 2526 2527 semanage_fcontext_set_type(fcontext, file_types[ftype]) 2528 2529 rc = semanage_fcontext_modify_local(self.sh, k, fcontext) 2530 if rc < 0: 2531 raise ValueError(_("Could not add file context for %s") % target) 2532 2533 if type != "<<none>>": 2534 semanage_context_free(con) 2535 semanage_fcontext_key_free(k) 2536 semanage_fcontext_free(fcontext) 2537 2538 if not seuser: 2539 seuser = "system_u" 2540 2541 self.mylog.log_change("resrc=fcontext op=add %s ftype=%s tcontext=%s:%s:%s:%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype], seuser, "object_r", type, serange)) 2542 2543 def add(self, target, type, ftype="", serange="", seuser="system_u"): 2544 self.begin() 2545 if self.__exists(target, ftype): 2546 print(_("File context for %s already defined, modifying instead") % target) 2547 self.__modify(target, type, ftype, serange, seuser) 2548 else: 2549 self.__add(target, type, ftype, serange, seuser) 2550 self.commit() 2551 2552 def __exists(self, target, ftype): 2553 (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) 2554 if rc < 0: 2555 raise ValueError(_("Could not create key for %s") % target) 2556 2557 (rc, exists) = semanage_fcontext_exists(self.sh, k) 2558 if rc < 0: 2559 raise ValueError(_("Could not check if file context for %s is defined") % target) 2560 2561 if not exists: 2562 (rc, exists) = semanage_fcontext_exists_local(self.sh, k) 2563 if rc < 0: 2564 raise ValueError(_("Could not check if file context for %s is defined") % target) 2565 semanage_fcontext_key_free(k) 2566 2567 return exists 2568 2569 def __modify(self, target, setype, ftype, serange, seuser): 2570 if serange == "" and setype == "" and seuser == "": 2571 raise ValueError(_("Requires setype, serange or seuser")) 2572 if setype not in ["", "<<none>>"]: 2573 setype = sepolicy.get_real_type_name(setype) 2574 if setype not in self.valid_types: 2575 raise ValueError(_("Type %s is invalid, must be a file or device type") % setype) 2576 2577 self.validate(target) 2578 2579 (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) 2580 if rc < 0: 2581 raise ValueError(_("Could not create a key for %s") % target) 2582 2583 (rc, exists) = semanage_fcontext_exists(self.sh, k) 2584 if rc < 0: 2585 raise ValueError(_("Could not check if file context for %s is defined") % target) 2586 if exists: 2587 try: 2588 (rc, fcontext) = semanage_fcontext_query(self.sh, k) 2589 except OSError: 2590 raise ValueError(_("Could not query file context for %s") % target) 2591 else: 2592 (rc, exists) = semanage_fcontext_exists_local(self.sh, k) 2593 if rc < 0: 2594 raise ValueError(_("Could not check if file context for %s is defined") % target) 2595 if not exists: 2596 raise ValueError(_("File context for %s is not defined") % target) 2597 try: 2598 (rc, fcontext) = semanage_fcontext_query_local(self.sh, k) 2599 except OSError: 2600 raise ValueError(_("Could not query file context for %s") % target) 2601 2602 if setype != "<<none>>": 2603 con = semanage_fcontext_get_con(fcontext) 2604 2605 if con is None: 2606 con = self.createcon(target) 2607 2608 if (is_mls_enabled == 1) and (serange != ""): 2609 semanage_context_set_mls(self.sh, con, untranslate(serange)) 2610 if seuser != "": 2611 semanage_context_set_user(self.sh, con, seuser) 2612 2613 if setype != "": 2614 semanage_context_set_type(self.sh, con, setype) 2615 2616 rc = semanage_fcontext_set_con(self.sh, fcontext, con) 2617 if rc < 0: 2618 raise ValueError(_("Could not set file context for %s") % target) 2619 else: 2620 rc = semanage_fcontext_set_con(self.sh, fcontext, None) 2621 if rc < 0: 2622 raise ValueError(_("Could not set file context for %s") % target) 2623 2624 rc = semanage_fcontext_modify_local(self.sh, k, fcontext) 2625 if rc < 0: 2626 raise ValueError(_("Could not modify file context for %s") % target) 2627 2628 semanage_fcontext_key_free(k) 2629 semanage_fcontext_free(fcontext) 2630 2631 if not seuser: 2632 seuser = "system_u" 2633 2634 self.mylog.log_change("resrc=fcontext op=modify %s ftype=%s tcontext=%s:%s:%s:%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype], seuser, "object_r", setype, serange)) 2635 2636 def modify(self, target, setype, ftype, serange, seuser): 2637 self.begin() 2638 self.__modify(target, setype, ftype, serange, seuser) 2639 self.commit() 2640 2641 def deleteall(self): 2642 (rc, flist) = semanage_fcontext_list_local(self.sh) 2643 if rc < 0: 2644 raise ValueError(_("Could not list the file contexts")) 2645 2646 self.begin() 2647 2648 for fcontext in flist: 2649 target = semanage_fcontext_get_expr(fcontext) 2650 ftype = semanage_fcontext_get_type(fcontext) 2651 ftype_str = semanage_fcontext_get_type_str(ftype) 2652 (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype_str]) 2653 if rc < 0: 2654 raise ValueError(_("Could not create a key for %s") % target) 2655 2656 rc = semanage_fcontext_del_local(self.sh, k) 2657 if rc < 0: 2658 raise ValueError(_("Could not delete the file context %s") % target) 2659 semanage_fcontext_key_free(k) 2660 2661 self.mylog.log_change("resrc=fcontext op=delete %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[file_type_str_to_option[ftype_str]])) 2662 2663 self.equiv = {} 2664 self.equal_ind = True 2665 self.commit() 2666 2667 def __delete(self, target, ftype): 2668 if target in self.equiv.keys(): 2669 self.equiv.pop(target) 2670 self.equal_ind = True 2671 2672 self.mylog.log_change("resrc=fcontext op=delete-equal %s" % (audit.audit_encode_nv_string("tglob", target, 0))) 2673 2674 return 2675 2676 (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) 2677 if rc < 0: 2678 raise ValueError(_("Could not create a key for %s") % target) 2679 2680 (rc, exists) = semanage_fcontext_exists_local(self.sh, k) 2681 if rc < 0: 2682 raise ValueError(_("Could not check if file context for %s is defined") % target) 2683 if not exists: 2684 (rc, exists) = semanage_fcontext_exists(self.sh, k) 2685 if rc < 0: 2686 raise ValueError(_("Could not check if file context for %s is defined") % target) 2687 if exists: 2688 raise ValueError(_("File context for %s is defined in policy, cannot be deleted") % target) 2689 else: 2690 raise ValueError(_("File context for %s is not defined") % target) 2691 2692 rc = semanage_fcontext_del_local(self.sh, k) 2693 if rc < 0: 2694 raise ValueError(_("Could not delete file context for %s") % target) 2695 2696 semanage_fcontext_key_free(k) 2697 2698 self.mylog.log_change("resrc=fcontext op=delete %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype])) 2699 2700 def delete(self, target, ftype): 2701 self.begin() 2702 self.__delete(target, ftype) 2703 self.commit() 2704 2705 def get_all(self, locallist=0): 2706 if locallist: 2707 (rc, self.flist) = semanage_fcontext_list_local(self.sh) 2708 else: 2709 (rc, self.flist) = semanage_fcontext_list(self.sh) 2710 if rc < 0: 2711 raise ValueError(_("Could not list file contexts")) 2712 2713 (rc, fchomedirs) = semanage_fcontext_list_homedirs(self.sh) 2714 if rc < 0: 2715 raise ValueError(_("Could not list file contexts for home directories")) 2716 2717 (rc, fclocal) = semanage_fcontext_list_local(self.sh) 2718 if rc < 0: 2719 raise ValueError(_("Could not list local file contexts")) 2720 2721 self.flist += fchomedirs 2722 self.flist += fclocal 2723 2724 ddict = {} 2725 for fcontext in self.flist: 2726 expr = semanage_fcontext_get_expr(fcontext) 2727 ftype = semanage_fcontext_get_type(fcontext) 2728 ftype_str = semanage_fcontext_get_type_str(ftype) 2729 con = semanage_fcontext_get_con(fcontext) 2730 if con: 2731 ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con)) 2732 else: 2733 ddict[(expr, ftype_str)] = con 2734 2735 return ddict 2736 2737 def customized(self): 2738 l = [] 2739 fcon_dict = self.get_all(True) 2740 for k in fcon_dict.keys(): 2741 if fcon_dict[k]: 2742 if fcon_dict[k][3]: 2743 l.append("-a -f %s -t %s -r '%s' '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], fcon_dict[k][3], k[0])) 2744 else: 2745 l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0])) 2746 2747 if len(self.equiv): 2748 for target in self.equiv.keys(): 2749 l.append("-a -e %s %s" % (self.equiv[target], target)) 2750 return l 2751 2752 def list(self, heading=1, locallist=0): 2753 fcon_dict = self.get_all(locallist) 2754 if len(fcon_dict) != 0: 2755 if heading: 2756 print("%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context"))) 2757 # do not sort local customizations since they are evaluated based on the order they where added in 2758 if locallist: 2759 fkeys = fcon_dict.keys() 2760 else: 2761 fkeys = sorted(fcon_dict.keys()) 2762 for k in fkeys: 2763 if fcon_dict[k]: 2764 if is_mls_enabled: 2765 print("%-50s %-18s %s:%s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2], translate(fcon_dict[k][3], False))) 2766 else: 2767 print("%-50s %-18s %s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2])) 2768 else: 2769 print("%-50s %-18s <<None>>" % (k[0], k[1])) 2770 2771 if len(self.equiv_dist): 2772 if not locallist: 2773 if heading: 2774 print(_("\nSELinux Distribution fcontext Equivalence \n")) 2775 for target in self.equiv_dist.keys(): 2776 print("%s = %s" % (target, self.equiv_dist[target])) 2777 if len(self.equiv): 2778 if heading: 2779 print(_("\nSELinux Local fcontext Equivalence \n")) 2780 2781 for target in self.equiv.keys(): 2782 print("%s = %s" % (target, self.equiv[target])) 2783 2784 2785class booleanRecords(semanageRecords): 2786 2787 def __init__(self, args = None): 2788 semanageRecords.__init__(self, args) 2789 self.dict = {} 2790 self.dict["TRUE"] = 1 2791 self.dict["FALSE"] = 0 2792 self.dict["ON"] = 1 2793 self.dict["OFF"] = 0 2794 self.dict["1"] = 1 2795 self.dict["0"] = 0 2796 2797 try: 2798 rc, self.current_booleans = selinux.security_get_boolean_names() 2799 rc, ptype = selinux.selinux_getpolicytype() 2800 except: 2801 self.current_booleans = [] 2802 ptype = None 2803 2804 if self.store == "" or self.store == ptype: 2805 self.modify_local = True 2806 else: 2807 self.modify_local = False 2808 2809 def __mod(self, name, value): 2810 name = selinux.selinux_boolean_sub(name) 2811 2812 (rc, k) = semanage_bool_key_create(self.sh, name) 2813 if rc < 0: 2814 raise ValueError(_("Could not create a key for %s") % name) 2815 (rc, exists) = semanage_bool_exists(self.sh, k) 2816 if rc < 0: 2817 raise ValueError(_("Could not check if boolean %s is defined") % name) 2818 if not exists: 2819 raise ValueError(_("Boolean %s is not defined") % name) 2820 2821 (rc, b) = semanage_bool_query(self.sh, k) 2822 if rc < 0: 2823 raise ValueError(_("Could not query file context %s") % name) 2824 2825 if value.upper() in self.dict: 2826 semanage_bool_set_value(b, self.dict[value.upper()]) 2827 else: 2828 raise ValueError(_("You must specify one of the following values: %s") % ", ".join(self.dict.keys())) 2829 2830 if self.modify_local and name in self.current_booleans: 2831 rc = semanage_bool_set_active(self.sh, k, b) 2832 if rc < 0: 2833 raise ValueError(_("Could not set active value of boolean %s") % name) 2834 rc = semanage_bool_modify_local(self.sh, k, b) 2835 if rc < 0: 2836 raise ValueError(_("Could not modify boolean %s") % name) 2837 semanage_bool_key_free(k) 2838 semanage_bool_free(b) 2839 2840 def modify(self, name, value=None, use_file=False): 2841 self.begin() 2842 if use_file: 2843 fd = open(name) 2844 for b in fd.read().split("\n"): 2845 b = b.strip() 2846 if len(b) == 0: 2847 continue 2848 2849 try: 2850 boolname, val = b.split("=") 2851 except ValueError: 2852 raise ValueError(_("Bad format {filename}: Record {record}").format(filename=name, record=b)) 2853 self.__mod(boolname.strip(), val.strip()) 2854 fd.close() 2855 else: 2856 self.__mod(name, value) 2857 2858 self.commit() 2859 2860 def __delete(self, name): 2861 name = selinux.selinux_boolean_sub(name) 2862 2863 (rc, k) = semanage_bool_key_create(self.sh, name) 2864 if rc < 0: 2865 raise ValueError(_("Could not create a key for %s") % name) 2866 (rc, exists) = semanage_bool_exists(self.sh, k) 2867 if rc < 0: 2868 raise ValueError(_("Could not check if boolean %s is defined") % name) 2869 if not exists: 2870 raise ValueError(_("Boolean %s is not defined") % name) 2871 2872 (rc, exists) = semanage_bool_exists_local(self.sh, k) 2873 if rc < 0: 2874 raise ValueError(_("Could not check if boolean %s is defined") % name) 2875 if not exists: 2876 raise ValueError(_("Boolean %s is defined in policy, cannot be deleted") % name) 2877 2878 rc = semanage_bool_del_local(self.sh, k) 2879 if rc < 0: 2880 raise ValueError(_("Could not delete boolean %s") % name) 2881 2882 semanage_bool_key_free(k) 2883 2884 def delete(self, name): 2885 self.begin() 2886 self.__delete(name) 2887 self.commit() 2888 2889 def deleteall(self): 2890 (rc, self.blist) = semanage_bool_list_local(self.sh) 2891 if rc < 0: 2892 raise ValueError(_("Could not list booleans")) 2893 2894 self.begin() 2895 2896 for boolean in self.blist: 2897 name = semanage_bool_get_name(boolean) 2898 self.__delete(name) 2899 2900 self.commit() 2901 2902 def get_all(self, locallist=0): 2903 ddict = {} 2904 if locallist: 2905 (rc, self.blist) = semanage_bool_list_local(self.sh) 2906 else: 2907 (rc, self.blist) = semanage_bool_list(self.sh) 2908 if rc < 0: 2909 raise ValueError(_("Could not list booleans")) 2910 2911 for boolean in self.blist: 2912 value = [] 2913 name = semanage_bool_get_name(boolean) 2914 value.append(semanage_bool_get_value(boolean)) 2915 if self.modify_local and name in self.current_booleans: 2916 value.append(selinux.security_get_boolean_pending(name)) 2917 value.append(selinux.security_get_boolean_active(name)) 2918 else: 2919 value.append(value[0]) 2920 value.append(value[0]) 2921 ddict[name] = value 2922 2923 return ddict 2924 2925 def get_desc(self, name): 2926 name = selinux.selinux_boolean_sub(name) 2927 return sepolicy.boolean_desc(name) 2928 2929 def get_category(self, name): 2930 name = selinux.selinux_boolean_sub(name) 2931 return sepolicy.boolean_category(name) 2932 2933 def customized(self): 2934 l = [] 2935 ddict = self.get_all(True) 2936 for k in sorted(ddict.keys()): 2937 if ddict[k]: 2938 l.append("-m -%s %s" % (ddict[k][2], k)) 2939 return l 2940 2941 def list(self, heading=True, locallist=False, use_file=False): 2942 on_off = (_("off"), _("on")) 2943 if use_file: 2944 ddict = self.get_all(locallist) 2945 for k in sorted(ddict.keys()): 2946 if ddict[k]: 2947 print("%s=%s" % (k, ddict[k][2])) 2948 return 2949 ddict = self.get_all(locallist) 2950 if len(ddict) == 0: 2951 return 2952 2953 if heading: 2954 print("%-30s %s %s %s\n" % (_("SELinux boolean"), _("State"), _("Default"), _("Description"))) 2955 for k in sorted(ddict.keys()): 2956 if ddict[k]: 2957 print("%-30s (%-5s,%5s) %s" % (k, on_off[ddict[k][2]], on_off[ddict[k][0]], self.get_desc(k))) 2958