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