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 string
     27 import selinux
     28 import tempfile
     29 import os
     30 import re
     31 import sys
     32 import stat
     33 import shutil
     34 from semanage import *
     35 PROGNAME = "policycoreutils"
     36 import sepolicy
     37 from sepolicy import boolean_desc, boolean_category, gen_bool_dict
     38 gen_bool_dict()
     39 from IPy import IP
     40 
     41 import gettext
     42 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
     43 gettext.textdomain(PROGNAME)
     44 
     45 import gettext
     46 translation = gettext.translation(PROGNAME, localedir="/usr/share/locale", fallback=True)
     47 _ = translation.ugettext
     48 
     49 import syslog
     50 
     51 file_types = {}
     52 file_types[""] = SEMANAGE_FCONTEXT_ALL
     53 file_types["all files"] = SEMANAGE_FCONTEXT_ALL
     54 file_types["a"] = SEMANAGE_FCONTEXT_ALL
     55 file_types["regular file"] = SEMANAGE_FCONTEXT_REG
     56 file_types["--"] = SEMANAGE_FCONTEXT_REG
     57 file_types["f"] = SEMANAGE_FCONTEXT_REG
     58 file_types["-d"] = SEMANAGE_FCONTEXT_DIR
     59 file_types["directory"] = SEMANAGE_FCONTEXT_DIR
     60 file_types["d"] = SEMANAGE_FCONTEXT_DIR
     61 file_types["-c"] = SEMANAGE_FCONTEXT_CHAR
     62 file_types["character device"] = SEMANAGE_FCONTEXT_CHAR
     63 file_types["c"] = SEMANAGE_FCONTEXT_CHAR
     64 file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK
     65 file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK
     66 file_types["b"] = SEMANAGE_FCONTEXT_BLOCK
     67 file_types["-s"] = SEMANAGE_FCONTEXT_SOCK
     68 file_types["socket"] = SEMANAGE_FCONTEXT_SOCK
     69 file_types["s"] = SEMANAGE_FCONTEXT_SOCK
     70 file_types["-l"] = SEMANAGE_FCONTEXT_LINK
     71 file_types["l"] = SEMANAGE_FCONTEXT_LINK
     72 file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK
     73 file_types["p"] = SEMANAGE_FCONTEXT_PIPE
     74 file_types["-p"] = SEMANAGE_FCONTEXT_PIPE
     75 file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE
     76 
     77 file_type_str_to_option = {"all files": "a",
     78                            "regular file": "f",
     79                            "directory": "d",
     80                            "character device": "c",
     81                            "block device": "b",
     82                            "socket file": "s",
     83                            "symbolic link": "l",
     84                            "named pipe": "p"}
     85 try:
     86     import audit
     87 
     88     class logger:
     89 
     90         def __init__(self):
     91             self.audit_fd = audit.audit_open()
     92             self.log_list = []
     93 
     94         def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
     95 
     96             sep = "-"
     97             if sename != oldsename:
     98                 msg += sep + "sename"
     99                 sep = ","
    100             if serole != oldserole:
    101                 msg += sep + "role"
    102                 sep = ","
    103             if serange != oldserange:
    104                 msg += sep + "range"
    105                 sep = ","
    106 
    107             self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_ASSIGN, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
    108 
    109         def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
    110             self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
    111 
    112         def commit(self, success):
    113             for l in self.log_list:
    114                 audit.audit_log_semanage_message(*(l + [success]))
    115             self.log_list = []
    116 except:
    117     class logger:
    118 
    119         def __init__(self):
    120             self.log_list = []
    121 
    122         def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
    123             message = " %s name=%s" % (msg, name)
    124             if sename != "":
    125                 message += " sename=" + sename
    126             if oldsename != "":
    127                 message += " oldsename=" + oldsename
    128             if serole != "":
    129                 message += " role=" + serole
    130             if oldserole != "":
    131                 message += " old_role=" + oldserole
    132             if serange != "" and serange != None:
    133                 message += " MLSRange=" + serange
    134             if oldserange != "" and oldserange != None:
    135                 message += " old_MLSRange=" + oldserange
    136             self.log_list.append(message)
    137 
    138         def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
    139             self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange)
    140 
    141         def commit(self, success):
    142             if success == 1:
    143                 message = "Successful: "
    144             else:
    145                 message = "Failed: "
    146             for l in self.log_list:
    147                 syslog.syslog(syslog.LOG_INFO, message + l)
    148 
    149 
    150 class nulllogger:
    151 
    152     def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
    153         pass
    154 
    155     def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
    156         pass
    157 
    158     def commit(self, success):
    159         pass
    160 
    161 
    162 def validate_level(raw):
    163     sensitivity = "s[0-9]*"
    164     category = "c[0-9]*"
    165     cat_range = category + "(\." + category + ")?"
    166     categories = cat_range + "(\," + cat_range + ")*"
    167     reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?"
    168     return re.search("^" + reg + "$", raw)
    169 
    170 
    171 def translate(raw, prepend=1):
    172     filler = "a:b:c:"
    173     if prepend == 1:
    174         context = "%s%s" % (filler, raw)
    175     else:
    176         context = raw
    177     (rc, trans) = selinux.selinux_raw_to_trans_context(context)
    178     if rc != 0:
    179         return raw
    180     if prepend:
    181         trans = trans[len(filler):]
    182     if trans == "":
    183         return raw
    184     else:
    185         return trans
    186 
    187 
    188 def untranslate(trans, prepend=1):
    189     filler = "a:b:c:"
    190     if prepend == 1:
    191         context = "%s%s" % (filler, trans)
    192     else:
    193         context = trans
    194 
    195     (rc, raw) = selinux.selinux_trans_to_raw_context(context)
    196     if rc != 0:
    197         return trans
    198     if prepend:
    199         raw = raw[len(filler):]
    200     if raw == "":
    201         return trans
    202     else:
    203         return raw
    204 
    205 
    206 class semanageRecords:
    207     transaction = False
    208     handle = None
    209     store = None
    210 
    211     def __init__(self, store):
    212         global handle
    213         self.load = True
    214         self.sh = self.get_handle(store)
    215 
    216         rc, localstore = selinux.selinux_getpolicytype()
    217         if store == "" or store == localstore:
    218             self.mylog = logger()
    219         else:
    220             self.mylog = nulllogger()
    221 
    222     def set_reload(self, load):
    223         self.load = load
    224 
    225     def get_handle(self, store):
    226         global is_mls_enabled
    227 
    228         if semanageRecords.handle:
    229             return semanageRecords.handle
    230 
    231         handle = semanage_handle_create()
    232         if not handle:
    233             raise ValueError(_("Could not create semanage handle"))
    234 
    235         if not semanageRecords.transaction and store != "":
    236             semanage_select_store(handle, store, SEMANAGE_CON_DIRECT)
    237             semanageRecords.store = store
    238 
    239         if not semanage_is_managed(handle):
    240             semanage_handle_destroy(handle)
    241             raise ValueError(_("SELinux policy is not managed or store cannot be accessed."))
    242 
    243         rc = semanage_access_check(handle)
    244         if rc < SEMANAGE_CAN_READ:
    245             semanage_handle_destroy(handle)
    246             raise ValueError(_("Cannot read policy store."))
    247 
    248         rc = semanage_connect(handle)
    249         if rc < 0:
    250             semanage_handle_destroy(handle)
    251             raise ValueError(_("Could not establish semanage connection"))
    252 
    253         is_mls_enabled = semanage_mls_enabled(handle)
    254         if is_mls_enabled < 0:
    255             semanage_handle_destroy(handle)
    256             raise ValueError(_("Could not test MLS enabled status"))
    257 
    258         semanageRecords.handle = handle
    259         return semanageRecords.handle
    260 
    261     def deleteall(self):
    262         raise ValueError(_("Not yet implemented"))
    263 
    264     def start(self):
    265         if semanageRecords.transaction:
    266             raise ValueError(_("Semanage transaction already in progress"))
    267         self.begin()
    268         semanageRecords.transaction = True
    269 
    270     def begin(self):
    271         if semanageRecords.transaction:
    272             return
    273         rc = semanage_begin_transaction(self.sh)
    274         if rc < 0:
    275             raise ValueError(_("Could not start semanage transaction"))
    276 
    277     def customized(self):
    278         raise ValueError(_("Not yet implemented"))
    279 
    280     def commit(self):
    281         if semanageRecords.transaction:
    282             return
    283 
    284         semanage_set_reload(self.sh, self.load)
    285         rc = semanage_commit(self.sh)
    286         if rc < 0:
    287             self.mylog.commit(0)
    288             raise ValueError(_("Could not commit semanage transaction"))
    289         self.mylog.commit(1)
    290 
    291     def finish(self):
    292         if not semanageRecords.transaction:
    293             raise ValueError(_("Semanage transaction not in progress"))
    294         semanageRecords.transaction = False
    295         self.commit()
    296 
    297 
    298 class moduleRecords(semanageRecords):
    299 
    300     def __init__(self, store):
    301         semanageRecords.__init__(self, store)
    302 
    303     def get_all(self):
    304         l = []
    305         (rc, mlist, number) = semanage_module_list_all(self.sh)
    306         if rc < 0:
    307             raise ValueError(_("Could not list SELinux modules"))
    308 
    309         for i in range(number):
    310             mod = semanage_module_list_nth(mlist, i)
    311 
    312             rc, name = semanage_module_info_get_name(self.sh, mod)
    313             if rc < 0:
    314                 raise ValueError(_("Could not get module name"))
    315 
    316             rc, enabled = semanage_module_info_get_enabled(self.sh, mod)
    317             if rc < 0:
    318                 raise ValueError(_("Could not get module enabled"))
    319 
    320             rc, priority = semanage_module_info_get_priority(self.sh, mod)
    321             if rc < 0:
    322                 raise ValueError(_("Could not get module priority"))
    323 
    324             rc, lang_ext = semanage_module_info_get_lang_ext(self.sh, mod)
    325             if rc < 0:
    326                 raise ValueError(_("Could not get module lang_ext"))
    327 
    328             l.append((name, enabled, priority, lang_ext))
    329 
    330         # sort the list so they are in name order, but with higher priorities coming first
    331         l.sort(key=lambda t: t[3], reverse=True)
    332         l.sort(key=lambda t: t[0])
    333         return l
    334 
    335     def customized(self):
    336         all = self.get_all()
    337         if len(all) == 0:
    338             return
    339         return map(lambda x: "-d %s" % x[0], filter(lambda t: t[1] == 0, all))
    340 
    341     def list(self, heading=1, locallist=0):
    342         all = self.get_all()
    343         if len(all) == 0:
    344             return
    345 
    346         if heading:
    347             print "\n%-25s %-9s %s\n" % (_("Module Name"), _("Priority"), _("Language"))
    348         for t in all:
    349             if t[1] == 0:
    350                 disabled = _("Disabled")
    351             else:
    352                 if locallist:
    353                     continue
    354                 disabled = ""
    355             print "%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled)
    356 
    357     def add(self, file, priority):
    358         if not os.path.exists(file):
    359             raise ValueError(_("Module does not exists %s ") % file)
    360 
    361         rc = semanage_set_default_priority(self.sh, priority)
    362         if rc < 0:
    363             raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
    364 
    365         rc = semanage_module_install_file(self.sh, file)
    366         if rc >= 0:
    367             self.commit()
    368 
    369     def set_enabled(self, module, enable):
    370         for m in module.split():
    371             rc, key = semanage_module_key_create(self.sh)
    372             if rc < 0:
    373                 raise ValueError(_("Could not create module key"))
    374 
    375             rc = semanage_module_key_set_name(self.sh, key, m)
    376             if rc < 0:
    377                 raise ValueError(_("Could not set module key name"))
    378 
    379             rc = semanage_module_set_enabled(self.sh, key, enable)
    380             if rc < 0:
    381                 if enable:
    382                     raise ValueError(_("Could not enable module %s") % m)
    383                 else:
    384                     raise ValueError(_("Could not disable module %s") % m)
    385         self.commit()
    386 
    387     def modify(self, file):
    388         rc = semanage_module_update_file(self.sh, file)
    389         if rc >= 0:
    390             self.commit()
    391 
    392     def delete(self, module, priority):
    393         rc = semanage_set_default_priority(self.sh, priority)
    394         if rc < 0:
    395             raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
    396 
    397         for m in module.split():
    398             rc = semanage_module_remove(self.sh, m)
    399             if rc < 0 and rc != -2:
    400                 raise ValueError(_("Could not remove module %s (remove failed)") % m)
    401 
    402         self.commit()
    403 
    404     def deleteall(self):
    405         l = map(lambda x: x[0], filter(lambda t: t[1] == 0, self.get_all()))
    406         for m in l:
    407             self.set_enabled(m, True)
    408 
    409 
    410 class dontauditClass(semanageRecords):
    411 
    412     def __init__(self, store):
    413         semanageRecords.__init__(self, store)
    414 
    415     def toggle(self, dontaudit):
    416         if dontaudit not in ["on", "off"]:
    417             raise ValueError(_("dontaudit requires either 'on' or 'off'"))
    418         self.begin()
    419         rc = semanage_set_disable_dontaudit(self.sh, dontaudit == "off")
    420         self.commit()
    421 
    422 
    423 class permissiveRecords(semanageRecords):
    424 
    425     def __init__(self, store):
    426         semanageRecords.__init__(self, store)
    427 
    428     def get_all(self):
    429         l = []
    430         (rc, mlist, number) = semanage_module_list(self.sh)
    431         if rc < 0:
    432             raise ValueError(_("Could not list SELinux modules"))
    433 
    434         for i in range(number):
    435             mod = semanage_module_list_nth(mlist, i)
    436             name = semanage_module_get_name(mod)
    437             if name and name.startswith("permissive_"):
    438                 l.append(name.split("permissive_")[1])
    439         return l
    440 
    441     def list(self, heading=1, locallist=0):
    442         all = map(lambda y: y["name"], filter(lambda x: x["permissive"], sepolicy.info(sepolicy.TYPE)))
    443         if len(all) == 0:
    444             return
    445 
    446         if heading:
    447             print "\n%-25s\n" % (_("Builtin Permissive Types"))
    448         customized = self.get_all()
    449         for t in all:
    450             if t not in customized:
    451                 print t
    452 
    453         if len(customized) == 0:
    454             return
    455 
    456         if heading:
    457             print "\n%-25s\n" % (_("Customized Permissive Types"))
    458         for t in customized:
    459             print t
    460 
    461     def add(self, type):
    462         import glob
    463         try:
    464             import sepolgen.module as module
    465         except ImportError:
    466             raise ValueError(_("The sepolgen python module is required to setup permissive domains.\nIn some distributions it is included in the policycoreutils-devel patckage.\n# yum install policycoreutils-devel\nOr similar for your distro."))
    467 
    468         name = "permissive_%s" % type
    469         modtxt = "(typepermissive %s)" % type
    470 
    471         rc = semanage_module_install(self.sh, modtxt, len(modtxt), name, "cil")
    472         if rc >= 0:
    473             self.commit()
    474 
    475         if rc < 0:
    476             raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name)
    477 
    478     def delete(self, name):
    479         for n in name.split():
    480             rc = semanage_module_remove(self.sh, "permissive_%s" % n)
    481             if rc < 0:
    482                 raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name)
    483 
    484         self.commit()
    485 
    486     def deleteall(self):
    487         l = self.get_all()
    488         if len(l) > 0:
    489             all = " ".join(l)
    490             self.delete(all)
    491 
    492 
    493 class loginRecords(semanageRecords):
    494 
    495     def __init__(self, store=""):
    496         semanageRecords.__init__(self, store)
    497         self.oldsename = None
    498         self.oldserange = None
    499         self.sename = None
    500         self.serange = None
    501 
    502     def __add(self, name, sename, serange):
    503         rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
    504         if sename == "":
    505             sename = "user_u"
    506 
    507         userrec = seluserRecords()
    508         range, (rc, oldserole) = userrec.get(self.oldsename)
    509         range, (rc, serole) = userrec.get(sename)
    510 
    511         if is_mls_enabled == 1:
    512             if serange != "":
    513                 serange = untranslate(serange)
    514             else:
    515                 serange = range
    516 
    517         (rc, k) = semanage_seuser_key_create(self.sh, name)
    518         if rc < 0:
    519             raise ValueError(_("Could not create a key for %s") % name)
    520 
    521         (rc, exists) = semanage_seuser_exists(self.sh, k)
    522         if rc < 0:
    523             raise ValueError(_("Could not check if login mapping for %s is defined") % name)
    524         if exists:
    525             raise ValueError(_("Login mapping for %s is already defined") % name)
    526         if name[0] == '%':
    527             try:
    528                 grp.getgrnam(name[1:])
    529             except:
    530                 raise ValueError(_("Linux Group %s does not exist") % name[1:])
    531         else:
    532             try:
    533                 pwd.getpwnam(name)
    534             except:
    535                 raise ValueError(_("Linux User %s does not exist") % name)
    536 
    537         (rc, u) = semanage_seuser_create(self.sh)
    538         if rc < 0:
    539             raise ValueError(_("Could not create login mapping for %s") % name)
    540 
    541         rc = semanage_seuser_set_name(self.sh, u, name)
    542         if rc < 0:
    543             raise ValueError(_("Could not set name for %s") % name)
    544 
    545         if (is_mls_enabled == 1) and (serange != ""):
    546             rc = semanage_seuser_set_mlsrange(self.sh, u, serange)
    547             if rc < 0:
    548                 raise ValueError(_("Could not set MLS range for %s") % name)
    549 
    550         rc = semanage_seuser_set_sename(self.sh, u, sename)
    551         if rc < 0:
    552             raise ValueError(_("Could not set SELinux user for %s") % name)
    553 
    554         rc = semanage_seuser_modify_local(self.sh, k, u)
    555         if rc < 0:
    556             raise ValueError(_("Could not add login mapping for %s") % name)
    557 
    558         semanage_seuser_key_free(k)
    559         semanage_seuser_free(u)
    560         self.mylog.log("login", name, sename=sename, serange=serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange)
    561 
    562     def add(self, name, sename, serange):
    563         try:
    564             self.begin()
    565             self.__add(name, sename, serange)
    566             self.commit()
    567         except ValueError, error:
    568             self.mylog.commit(0)
    569             raise error
    570 
    571     def __modify(self, name, sename="", serange=""):
    572         rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
    573         if sename == "" and serange == "":
    574             raise ValueError(_("Requires seuser or serange"))
    575 
    576         userrec = seluserRecords()
    577         range, (rc, oldserole) = userrec.get(self.oldsename)
    578 
    579         if sename != "":
    580             range, (rc, serole) = userrec.get(sename)
    581         else:
    582             serole = oldserole
    583 
    584         if serange != "":
    585             self.serange = serange
    586         else:
    587             self.serange = range
    588 
    589         (rc, k) = semanage_seuser_key_create(self.sh, name)
    590         if rc < 0:
    591             raise ValueError(_("Could not create a key for %s") % name)
    592 
    593         (rc, exists) = semanage_seuser_exists(self.sh, k)
    594         if rc < 0:
    595             raise ValueError(_("Could not check if login mapping for %s is defined") % name)
    596         if not exists:
    597             raise ValueError(_("Login mapping for %s is not defined") % name)
    598 
    599         (rc, u) = semanage_seuser_query(self.sh, k)
    600         if rc < 0:
    601             raise ValueError(_("Could not query seuser for %s") % name)
    602 
    603         self.oldserange = semanage_seuser_get_mlsrange(u)
    604         self.oldsename = semanage_seuser_get_sename(u)
    605         if (is_mls_enabled == 1) and (serange != ""):
    606             semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange))
    607 
    608         if sename != "":
    609             semanage_seuser_set_sename(self.sh, u, sename)
    610             self.sename = sename
    611         else:
    612             self.sename = self.oldsename
    613 
    614         rc = semanage_seuser_modify_local(self.sh, k, u)
    615         if rc < 0:
    616             raise ValueError(_("Could not modify login mapping for %s") % name)
    617 
    618         semanage_seuser_key_free(k)
    619         semanage_seuser_free(u)
    620         self.mylog.log("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange)
    621 
    622     def modify(self, name, sename="", serange=""):
    623         try:
    624             self.begin()
    625             self.__modify(name, sename, serange)
    626             self.commit()
    627         except ValueError, error:
    628             self.mylog.commit(0)
    629             raise error
    630 
    631     def __delete(self, name):
    632         rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
    633         userrec = seluserRecords()
    634         range, (rc, oldserole) = userrec.get(self.oldsename)
    635 
    636         (rc, k) = semanage_seuser_key_create(self.sh, name)
    637         if rc < 0:
    638             raise ValueError(_("Could not create a key for %s") % name)
    639 
    640         (rc, exists) = semanage_seuser_exists(self.sh, k)
    641         if rc < 0:
    642             raise ValueError(_("Could not check if login mapping for %s is defined") % name)
    643         if not exists:
    644             raise ValueError(_("Login mapping for %s is not defined") % name)
    645 
    646         (rc, exists) = semanage_seuser_exists_local(self.sh, k)
    647         if rc < 0:
    648             raise ValueError(_("Could not check if login mapping for %s is defined") % name)
    649         if not exists:
    650             raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name)
    651 
    652         rc = semanage_seuser_del_local(self.sh, k)
    653         if rc < 0:
    654             raise ValueError(_("Could not delete login mapping for %s") % name)
    655 
    656         semanage_seuser_key_free(k)
    657 
    658         rec, self.sename, self.serange = selinux.getseuserbyname("__default__")
    659         range, (rc, serole) = userrec.get(self.sename)
    660 
    661         self.mylog.log_remove("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange)
    662 
    663     def delete(self, name):
    664         try:
    665             self.begin()
    666             self.__delete(name)
    667             self.commit()
    668 
    669         except ValueError, error:
    670             self.mylog.commit(0)
    671             raise error
    672 
    673     def deleteall(self):
    674         (rc, ulist) = semanage_seuser_list_local(self.sh)
    675         if rc < 0:
    676             raise ValueError(_("Could not list login mappings"))
    677 
    678         try:
    679             self.begin()
    680             for u in ulist:
    681                 self.__delete(semanage_seuser_get_name(u))
    682             self.commit()
    683         except ValueError, error:
    684             self.mylog.commit(0)
    685             raise error
    686 
    687     def get_all_logins(self):
    688         ddict = {}
    689         self.logins_path = selinux.selinux_policy_root() + "/logins"
    690         for path, dirs, files in os.walk(self.logins_path):
    691             if path == self.logins_path:
    692                 for name in files:
    693                     try:
    694                         fd = open(path + "/" + name)
    695                         rec = fd.read().rstrip().split(":")
    696                         fd.close()
    697                         ddict[name] = (rec[1], rec[2], rec[0])
    698                     except IndexError:
    699                         pass
    700         return ddict
    701 
    702     def get_all(self, locallist=0):
    703         ddict = {}
    704         if locallist:
    705             (rc, self.ulist) = semanage_seuser_list_local(self.sh)
    706         else:
    707             (rc, self.ulist) = semanage_seuser_list(self.sh)
    708         if rc < 0:
    709             raise ValueError(_("Could not list login mappings"))
    710 
    711         for u in self.ulist:
    712             name = semanage_seuser_get_name(u)
    713             ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u), "*")
    714         return ddict
    715 
    716     def customized(self):
    717         l = []
    718         ddict = self.get_all(True)
    719         keys = ddict.keys()
    720         keys.sort()
    721         for k in keys:
    722             l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k))
    723         return l
    724 
    725     def list(self, heading=1, locallist=0):
    726         ddict = self.get_all(locallist)
    727         ldict = self.get_all_logins()
    728         lkeys = ldict.keys()
    729         keys = ddict.keys()
    730         if len(keys) == 0 and len(lkeys) == 0:
    731             return
    732         keys.sort()
    733         lkeys.sort()
    734 
    735         if is_mls_enabled == 1:
    736             if heading:
    737                 print "\n%-20s %-20s %-20s %s\n" % (_("Login Name"), _("SELinux User"), _("MLS/MCS Range"), _("Service"))
    738             for k in keys:
    739                 u = ddict[k]
    740                 print "%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])
    741             if len(lkeys):
    742                 print "\nLocal customization in %s" % self.logins_path
    743 
    744             for k in lkeys:
    745                 u = ldict[k]
    746                 print "%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])
    747         else:
    748             if heading:
    749                 print "\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User"))
    750             for k in keys:
    751                 print "%-25s %-25s" % (k, ddict[k][0])
    752 
    753 
    754 class seluserRecords(semanageRecords):
    755 
    756     def __init__(self, store=""):
    757         semanageRecords.__init__(self, store)
    758 
    759     def get(self, name):
    760         (rc, k) = semanage_user_key_create(self.sh, name)
    761         if rc < 0:
    762             raise ValueError(_("Could not create a key for %s") % name)
    763         (rc, exists) = semanage_user_exists(self.sh, k)
    764         if rc < 0:
    765             raise ValueError(_("Could not check if SELinux user %s is defined") % name)
    766         (rc, u) = semanage_user_query(self.sh, k)
    767         if rc < 0:
    768             raise ValueError(_("Could not query user for %s") % name)
    769         serange = semanage_user_get_mlsrange(u)
    770         serole = semanage_user_get_roles(self.sh, u)
    771         semanage_user_key_free(k)
    772         semanage_user_free(u)
    773         return serange, serole
    774 
    775     def __add(self, name, roles, selevel, serange, prefix):
    776         if is_mls_enabled == 1:
    777             if serange == "":
    778                 serange = "s0"
    779             else:
    780                 serange = untranslate(serange)
    781 
    782             if selevel == "":
    783                 selevel = "s0"
    784             else:
    785                 selevel = untranslate(selevel)
    786 
    787         if len(roles) < 1:
    788             raise ValueError(_("You must add at least one role for %s") % name)
    789 
    790         (rc, k) = semanage_user_key_create(self.sh, name)
    791         if rc < 0:
    792             raise ValueError(_("Could not create a key for %s") % name)
    793 
    794         (rc, exists) = semanage_user_exists(self.sh, k)
    795         if rc < 0:
    796             raise ValueError(_("Could not check if SELinux user %s is defined") % name)
    797         if exists:
    798             raise ValueError(_("SELinux user %s is already defined") % name)
    799 
    800         (rc, u) = semanage_user_create(self.sh)
    801         if rc < 0:
    802             raise ValueError(_("Could not create SELinux user for %s") % name)
    803 
    804         rc = semanage_user_set_name(self.sh, u, name)
    805         if rc < 0:
    806             raise ValueError(_("Could not set name for %s") % name)
    807 
    808         for r in roles:
    809             rc = semanage_user_add_role(self.sh, u, r)
    810             if rc < 0:
    811                 raise ValueError(_("Could not add role %s for %s") % (r, name))
    812 
    813         if is_mls_enabled == 1:
    814             rc = semanage_user_set_mlsrange(self.sh, u, serange)
    815             if rc < 0:
    816                 raise ValueError(_("Could not set MLS range for %s") % name)
    817 
    818             rc = semanage_user_set_mlslevel(self.sh, u, selevel)
    819             if rc < 0:
    820                 raise ValueError(_("Could not set MLS level for %s") % name)
    821         rc = semanage_user_set_prefix(self.sh, u, prefix)
    822         if rc < 0:
    823             raise ValueError(_("Could not add prefix %s for %s") % (r, prefix))
    824         (rc, key) = semanage_user_key_extract(self.sh, u)
    825         if rc < 0:
    826             raise ValueError(_("Could not extract key for %s") % name)
    827 
    828         rc = semanage_user_modify_local(self.sh, k, u)
    829         if rc < 0:
    830             raise ValueError(_("Could not add SELinux user %s") % name)
    831 
    832         semanage_user_key_free(k)
    833         semanage_user_free(u)
    834         self.mylog.log("seuser", sename=name, serole=",".join(roles), serange=serange)
    835 
    836     def add(self, name, roles, selevel, serange, prefix):
    837         serole = " ".join(roles)
    838         try:
    839             self.begin()
    840             self.__add(name, roles, selevel, serange, prefix)
    841             self.commit()
    842         except ValueError, error:
    843             self.mylog.commit(0)
    844             raise error
    845 
    846     def __modify(self, name, roles=[], selevel="", serange="", prefix=""):
    847         oldserole = ""
    848         oldserange = ""
    849         newroles = " ".join(roles)
    850         if prefix == "" and len(roles) == 0 and serange == "" and selevel == "":
    851             if is_mls_enabled == 1:
    852                 raise ValueError(_("Requires prefix, roles, level or range"))
    853             else:
    854                 raise ValueError(_("Requires prefix or roles"))
    855 
    856         (rc, k) = semanage_user_key_create(self.sh, name)
    857         if rc < 0:
    858             raise ValueError(_("Could not create a key for %s") % name)
    859 
    860         (rc, exists) = semanage_user_exists(self.sh, k)
    861         if rc < 0:
    862             raise ValueError(_("Could not check if SELinux user %s is defined") % name)
    863         if not exists:
    864             raise ValueError(_("SELinux user %s is not defined") % name)
    865 
    866         (rc, u) = semanage_user_query(self.sh, k)
    867         if rc < 0:
    868             raise ValueError(_("Could not query user for %s") % name)
    869 
    870         oldserange = semanage_user_get_mlsrange(u)
    871         (rc, rlist) = semanage_user_get_roles(self.sh, u)
    872         if rc >= 0:
    873             oldserole = " ".join(rlist)
    874 
    875         if (is_mls_enabled == 1) and (serange != ""):
    876             semanage_user_set_mlsrange(self.sh, u, untranslate(serange))
    877         if (is_mls_enabled == 1) and (selevel != ""):
    878             semanage_user_set_mlslevel(self.sh, u, untranslate(selevel))
    879 
    880         if prefix != "":
    881             semanage_user_set_prefix(self.sh, u, prefix)
    882 
    883         if len(roles) != 0:
    884             for r in rlist:
    885                 if r not in roles:
    886                     semanage_user_del_role(u, r)
    887             for r in roles:
    888                 if r not in rlist:
    889                     semanage_user_add_role(self.sh, u, r)
    890 
    891         rc = semanage_user_modify_local(self.sh, k, u)
    892         if rc < 0:
    893             raise ValueError(_("Could not modify SELinux user %s") % name)
    894 
    895         semanage_user_key_free(k)
    896         semanage_user_free(u)
    897 
    898         role = ",".join(newroles.split())
    899         oldserole = ",".join(oldserole.split())
    900         self.mylog.log("seuser", sename=name, oldsename=name, serole=role, serange=serange, oldserole=oldserole, oldserange=oldserange)
    901 
    902     def modify(self, name, roles=[], selevel="", serange="", prefix=""):
    903         try:
    904             self.begin()
    905             self.__modify(name, roles, selevel, serange, prefix)
    906             self.commit()
    907         except ValueError, error:
    908             self.mylog.commit(0)
    909             raise error
    910 
    911     def __delete(self, name):
    912         (rc, k) = semanage_user_key_create(self.sh, name)
    913         if rc < 0:
    914             raise ValueError(_("Could not create a key for %s") % name)
    915 
    916         (rc, exists) = semanage_user_exists(self.sh, k)
    917         if rc < 0:
    918             raise ValueError(_("Could not check if SELinux user %s is defined") % name)
    919         if not exists:
    920             raise ValueError(_("SELinux user %s is not defined") % name)
    921 
    922         (rc, exists) = semanage_user_exists_local(self.sh, k)
    923         if rc < 0:
    924             raise ValueError(_("Could not check if SELinux user %s is defined") % name)
    925         if not exists:
    926             raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name)
    927 
    928         (rc, u) = semanage_user_query(self.sh, k)
    929         if rc < 0:
    930             raise ValueError(_("Could not query user for %s") % name)
    931         oldserange = semanage_user_get_mlsrange(u)
    932         (rc, rlist) = semanage_user_get_roles(self.sh, u)
    933         oldserole = ",".join(rlist)
    934 
    935         rc = semanage_user_del_local(self.sh, k)
    936         if rc < 0:
    937             raise ValueError(_("Could not delete SELinux user %s") % name)
    938 
    939         semanage_user_key_free(k)
    940         semanage_user_free(u)
    941 
    942         self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole)
    943 
    944     def delete(self, name):
    945         try:
    946             self.begin()
    947             self.__delete(name)
    948             self.commit()
    949 
    950         except ValueError, error:
    951             self.mylog.commit(0)
    952             raise error
    953 
    954     def deleteall(self):
    955         (rc, ulist) = semanage_user_list_local(self.sh)
    956         if rc < 0:
    957             raise ValueError(_("Could not list login mappings"))
    958 
    959         try:
    960             self.begin()
    961             for u in ulist:
    962                 self.__delete(semanage_user_get_name(u))
    963             self.commit()
    964         except ValueError, error:
    965             self.mylog.commit(0)
    966             raise error
    967 
    968     def get_all(self, locallist=0):
    969         ddict = {}
    970         if locallist:
    971             (rc, self.ulist) = semanage_user_list_local(self.sh)
    972         else:
    973             (rc, self.ulist) = semanage_user_list(self.sh)
    974         if rc < 0:
    975             raise ValueError(_("Could not list SELinux users"))
    976 
    977         for u in self.ulist:
    978             name = semanage_user_get_name(u)
    979             (rc, rlist) = semanage_user_get_roles(self.sh, u)
    980             if rc < 0:
    981                 raise ValueError(_("Could not list roles for user %s") % name)
    982 
    983             roles = " ".join(rlist)
    984             ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles)
    985 
    986         return ddict
    987 
    988     def customized(self):
    989         l = []
    990         ddict = self.get_all(True)
    991         keys = ddict.keys()
    992         keys.sort()
    993         for k in keys:
    994             l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k))
    995         return l
    996 
    997     def list(self, heading=1, locallist=0):
    998         ddict = self.get_all(locallist)
    999         keys = ddict.keys()
   1000         if len(keys) == 0:
   1001             return
   1002         keys.sort()
   1003 
   1004         if is_mls_enabled == 1:
   1005             if heading:
   1006                 print "\n%-15s %-10s %-10s %-30s" % ("", _("Labeling"), _("MLS/"), _("MLS/"))
   1007                 print "%-15s %-10s %-10s %-30s %s\n" % (_("SELinux User"), _("Prefix"), _("MCS Level"), _("MCS Range"), _("SELinux Roles"))
   1008             for k in keys:
   1009                 print "%-15s %-10s %-10s %-30s %s" % (k, ddict[k][0], translate(ddict[k][1]), translate(ddict[k][2]), ddict[k][3])
   1010         else:
   1011             if heading:
   1012                 print "%-15s %s\n" % (_("SELinux User"), _("SELinux Roles"))
   1013             for k in keys:
   1014                 print "%-15s %s" % (k, ddict[k][3])
   1015 
   1016 
   1017 class portRecords(semanageRecords):
   1018     try:
   1019         valid_types = sepolicy.info(sepolicy.ATTRIBUTE, "port_type")[0]["types"]
   1020     except RuntimeError:
   1021         valid_types = []
   1022 
   1023     def __init__(self, store=""):
   1024         semanageRecords.__init__(self, store)
   1025 
   1026     def __genkey(self, port, proto):
   1027         if proto == "tcp":
   1028             proto_d = SEMANAGE_PROTO_TCP
   1029         else:
   1030             if proto == "udp":
   1031                 proto_d = SEMANAGE_PROTO_UDP
   1032             else:
   1033                 raise ValueError(_("Protocol udp or tcp is required"))
   1034         if port == "":
   1035             raise ValueError(_("Port is required"))
   1036 
   1037         ports = port.split("-")
   1038         if len(ports) == 1:
   1039             high = low = int(ports[0])
   1040         else:
   1041             low = int(ports[0])
   1042             high = int(ports[1])
   1043 
   1044         if high > 65535:
   1045             raise ValueError(_("Invalid Port"))
   1046 
   1047         (rc, k) = semanage_port_key_create(self.sh, low, high, proto_d)
   1048         if rc < 0:
   1049             raise ValueError(_("Could not create a key for %s/%s") % (proto, port))
   1050         return (k, proto_d, low, high)
   1051 
   1052     def __add(self, port, proto, serange, type):
   1053         if is_mls_enabled == 1:
   1054             if serange == "":
   1055                 serange = "s0"
   1056             else:
   1057                 serange = untranslate(serange)
   1058 
   1059         if type == "":
   1060             raise ValueError(_("Type is required"))
   1061 
   1062         if type not in self.valid_types:
   1063             raise ValueError(_("Type %s is invalid, must be a port type") % type)
   1064 
   1065         (k, proto_d, low, high) = self.__genkey(port, proto)
   1066 
   1067         (rc, exists) = semanage_port_exists(self.sh, k)
   1068         if rc < 0:
   1069             raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
   1070         if exists:
   1071             raise ValueError(_("Port %s/%s already defined") % (proto, port))
   1072 
   1073         (rc, p) = semanage_port_create(self.sh)
   1074         if rc < 0:
   1075             raise ValueError(_("Could not create port for %s/%s") % (proto, port))
   1076 
   1077         semanage_port_set_proto(p, proto_d)
   1078         semanage_port_set_range(p, low, high)
   1079         (rc, con) = semanage_context_create(self.sh)
   1080         if rc < 0:
   1081             raise ValueError(_("Could not create context for %s/%s") % (proto, port))
   1082 
   1083         rc = semanage_context_set_user(self.sh, con, "system_u")
   1084         if rc < 0:
   1085             raise ValueError(_("Could not set user in port context for %s/%s") % (proto, port))
   1086 
   1087         rc = semanage_context_set_role(self.sh, con, "object_r")
   1088         if rc < 0:
   1089             raise ValueError(_("Could not set role in port context for %s/%s") % (proto, port))
   1090 
   1091         rc = semanage_context_set_type(self.sh, con, type)
   1092         if rc < 0:
   1093             raise ValueError(_("Could not set type in port context for %s/%s") % (proto, port))
   1094 
   1095         if (is_mls_enabled == 1) and (serange != ""):
   1096             rc = semanage_context_set_mls(self.sh, con, serange)
   1097             if rc < 0:
   1098                 raise ValueError(_("Could not set mls fields in port context for %s/%s") % (proto, port))
   1099 
   1100         rc = semanage_port_set_con(self.sh, p, con)
   1101         if rc < 0:
   1102             raise ValueError(_("Could not set port context for %s/%s") % (proto, port))
   1103 
   1104         rc = semanage_port_modify_local(self.sh, k, p)
   1105         if rc < 0:
   1106             raise ValueError(_("Could not add port %s/%s") % (proto, port))
   1107 
   1108         semanage_context_free(con)
   1109         semanage_port_key_free(k)
   1110         semanage_port_free(p)
   1111 
   1112     def add(self, port, proto, serange, type):
   1113         self.begin()
   1114         self.__add(port, proto, serange, type)
   1115         self.commit()
   1116 
   1117     def __modify(self, port, proto, serange, setype):
   1118         if serange == "" and setype == "":
   1119             if is_mls_enabled == 1:
   1120                 raise ValueError(_("Requires setype or serange"))
   1121             else:
   1122                 raise ValueError(_("Requires setype"))
   1123 
   1124         if setype and setype not in self.valid_types:
   1125             raise ValueError(_("Type %s is invalid, must be a port type") % setype)
   1126 
   1127         (k, proto_d, low, high) = self.__genkey(port, proto)
   1128 
   1129         (rc, exists) = semanage_port_exists(self.sh, k)
   1130         if rc < 0:
   1131             raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
   1132         if not exists:
   1133             raise ValueError(_("Port %s/%s is not defined") % (proto, port))
   1134 
   1135         (rc, p) = semanage_port_query(self.sh, k)
   1136         if rc < 0:
   1137             raise ValueError(_("Could not query port %s/%s") % (proto, port))
   1138 
   1139         con = semanage_port_get_con(p)
   1140 
   1141         if (is_mls_enabled == 1) and (serange != ""):
   1142             semanage_context_set_mls(self.sh, con, untranslate(serange))
   1143         if setype != "":
   1144             semanage_context_set_type(self.sh, con, setype)
   1145 
   1146         rc = semanage_port_modify_local(self.sh, k, p)
   1147         if rc < 0:
   1148             raise ValueError(_("Could not modify port %s/%s") % (proto, port))
   1149 
   1150         semanage_port_key_free(k)
   1151         semanage_port_free(p)
   1152 
   1153     def modify(self, port, proto, serange, setype):
   1154         self.begin()
   1155         self.__modify(port, proto, serange, setype)
   1156         self.commit()
   1157 
   1158     def deleteall(self):
   1159         (rc, plist) = semanage_port_list_local(self.sh)
   1160         if rc < 0:
   1161             raise ValueError(_("Could not list the ports"))
   1162 
   1163         self.begin()
   1164 
   1165         for port in plist:
   1166             proto = semanage_port_get_proto(port)
   1167             proto_str = semanage_port_get_proto_str(proto)
   1168             low = semanage_port_get_low(port)
   1169             high = semanage_port_get_high(port)
   1170             port_str = "%s-%s" % (low, high)
   1171             (k, proto_d, low, high) = self.__genkey(port_str, proto_str)
   1172             if rc < 0:
   1173                 raise ValueError(_("Could not create a key for %s") % port_str)
   1174 
   1175             rc = semanage_port_del_local(self.sh, k)
   1176             if rc < 0:
   1177                 raise ValueError(_("Could not delete the port %s") % port_str)
   1178             semanage_port_key_free(k)
   1179 
   1180         self.commit()
   1181 
   1182     def __delete(self, port, proto):
   1183         (k, proto_d, low, high) = self.__genkey(port, proto)
   1184         (rc, exists) = semanage_port_exists(self.sh, k)
   1185         if rc < 0:
   1186             raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
   1187         if not exists:
   1188             raise ValueError(_("Port %s/%s is not defined") % (proto, port))
   1189 
   1190         (rc, exists) = semanage_port_exists_local(self.sh, k)
   1191         if rc < 0:
   1192             raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
   1193         if not exists:
   1194             raise ValueError(_("Port %s/%s is defined in policy, cannot be deleted") % (proto, port))
   1195 
   1196         rc = semanage_port_del_local(self.sh, k)
   1197         if rc < 0:
   1198             raise ValueError(_("Could not delete port %s/%s") % (proto, port))
   1199 
   1200         semanage_port_key_free(k)
   1201 
   1202     def delete(self, port, proto):
   1203         self.begin()
   1204         self.__delete(port, proto)
   1205         self.commit()
   1206 
   1207     def get_all(self, locallist=0):
   1208         ddict = {}
   1209         if locallist:
   1210             (rc, self.plist) = semanage_port_list_local(self.sh)
   1211         else:
   1212             (rc, self.plist) = semanage_port_list(self.sh)
   1213         if rc < 0:
   1214             raise ValueError(_("Could not list ports"))
   1215 
   1216         for port in self.plist:
   1217             con = semanage_port_get_con(port)
   1218             ctype = semanage_context_get_type(con)
   1219             level = semanage_context_get_mls(con)
   1220             proto = semanage_port_get_proto(port)
   1221             proto_str = semanage_port_get_proto_str(proto)
   1222             low = semanage_port_get_low(port)
   1223             high = semanage_port_get_high(port)
   1224             ddict[(low, high, proto_str)] = (ctype, level)
   1225         return ddict
   1226 
   1227     def get_all_by_type(self, locallist=0):
   1228         ddict = {}
   1229         if locallist:
   1230             (rc, self.plist) = semanage_port_list_local(self.sh)
   1231         else:
   1232             (rc, self.plist) = semanage_port_list(self.sh)
   1233         if rc < 0:
   1234             raise ValueError(_("Could not list ports"))
   1235 
   1236         for port in self.plist:
   1237             con = semanage_port_get_con(port)
   1238             ctype = semanage_context_get_type(con)
   1239             proto = semanage_port_get_proto(port)
   1240             proto_str = semanage_port_get_proto_str(proto)
   1241             low = semanage_port_get_low(port)
   1242             high = semanage_port_get_high(port)
   1243             if (ctype, proto_str) not in ddict.keys():
   1244                 ddict[(ctype, proto_str)] = []
   1245             if low == high:
   1246                 ddict[(ctype, proto_str)].append("%d" % low)
   1247             else:
   1248                 ddict[(ctype, proto_str)].append("%d-%d" % (low, high))
   1249         return ddict
   1250 
   1251     def customized(self):
   1252         l = []
   1253         ddict = self.get_all(True)
   1254         keys = ddict.keys()
   1255         keys.sort()
   1256         for k in keys:
   1257             if k[0] == k[1]:
   1258                 l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], k[0]))
   1259             else:
   1260                 l.append("-a -t %s -p %s %s-%s" % (ddict[k][0], k[2], k[0], k[1]))
   1261         return l
   1262 
   1263     def list(self, heading=1, locallist=0):
   1264         ddict = self.get_all_by_type(locallist)
   1265         keys = ddict.keys()
   1266         if len(keys) == 0:
   1267             return
   1268         keys.sort()
   1269 
   1270         if heading:
   1271             print "%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number"))
   1272         for i in keys:
   1273             rec = "%-30s %-8s " % i
   1274             rec += "%s" % ddict[i][0]
   1275             for p in ddict[i][1:]:
   1276                 rec += ", %s" % p
   1277             print rec
   1278 
   1279 
   1280 class nodeRecords(semanageRecords):
   1281     try:
   1282         valid_types = sepolicy.info(sepolicy.ATTRIBUTE, "node_type")[0]["types"]
   1283     except RuntimeError:
   1284         valid_types = []
   1285 
   1286     def __init__(self, store=""):
   1287         semanageRecords.__init__(self, store)
   1288         self.protocol = ["ipv4", "ipv6"]
   1289 
   1290     def validate(self, addr, mask, protocol):
   1291         newaddr = addr
   1292         newmask = mask
   1293         newprotocol = ""
   1294 
   1295         if addr == "":
   1296             raise ValueError(_("Node Address is required"))
   1297 
   1298         # verify valid comination
   1299         if len(mask) == 0 or mask[0] == "/":
   1300             i = IP(addr + mask)
   1301             newaddr = i.strNormal(0)
   1302             newmask = str(i.netmask())
   1303             if newmask == "0.0.0.0" and i.version() == 6:
   1304                 newmask = "::"
   1305 
   1306             protocol = "ipv%d" % i.version()
   1307 
   1308         try:
   1309             newprotocol = self.protocol.index(protocol)
   1310         except:
   1311             raise ValueError(_("Unknown or missing protocol"))
   1312 
   1313         return newaddr, newmask, newprotocol
   1314 
   1315     def __add(self, addr, mask, proto, serange, ctype):
   1316         addr, mask, proto = self.validate(addr, mask, proto)
   1317 
   1318         if is_mls_enabled == 1:
   1319             if serange == "":
   1320                 serange = "s0"
   1321             else:
   1322                 serange = untranslate(serange)
   1323 
   1324         if ctype == "":
   1325             raise ValueError(_("SELinux node type is required"))
   1326 
   1327         if ctype not in self.valid_types:
   1328             raise ValueError(_("Type %s is invalid, must be a node type") % ctype)
   1329 
   1330         (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
   1331         if rc < 0:
   1332             raise ValueError(_("Could not create key for %s") % addr)
   1333         if rc < 0:
   1334             raise ValueError(_("Could not check if addr %s is defined") % addr)
   1335 
   1336         (rc, exists) = semanage_node_exists(self.sh, k)
   1337         if exists:
   1338             raise ValueError(_("Addr %s already defined") % addr)
   1339 
   1340         (rc, node) = semanage_node_create(self.sh)
   1341         if rc < 0:
   1342             raise ValueError(_("Could not create addr for %s") % addr)
   1343         semanage_node_set_proto(node, proto)
   1344 
   1345         rc = semanage_node_set_addr(self.sh, node, proto, addr)
   1346         (rc, con) = semanage_context_create(self.sh)
   1347         if rc < 0:
   1348             raise ValueError(_("Could not create context for %s") % addr)
   1349 
   1350         rc = semanage_node_set_mask(self.sh, node, proto, mask)
   1351         if rc < 0:
   1352             raise ValueError(_("Could not set mask for %s") % addr)
   1353 
   1354         rc = semanage_context_set_user(self.sh, con, "system_u")
   1355         if rc < 0:
   1356             raise ValueError(_("Could not set user in addr context for %s") % addr)
   1357 
   1358         rc = semanage_context_set_role(self.sh, con, "object_r")
   1359         if rc < 0:
   1360             raise ValueError(_("Could not set role in addr context for %s") % addr)
   1361 
   1362         rc = semanage_context_set_type(self.sh, con, ctype)
   1363         if rc < 0:
   1364             raise ValueError(_("Could not set type in addr context for %s") % addr)
   1365 
   1366         if (is_mls_enabled == 1) and (serange != ""):
   1367             rc = semanage_context_set_mls(self.sh, con, serange)
   1368             if rc < 0:
   1369                 raise ValueError(_("Could not set mls fields in addr context for %s") % addr)
   1370 
   1371         rc = semanage_node_set_con(self.sh, node, con)
   1372         if rc < 0:
   1373             raise ValueError(_("Could not set addr context for %s") % addr)
   1374 
   1375         rc = semanage_node_modify_local(self.sh, k, node)
   1376         if rc < 0:
   1377             raise ValueError(_("Could not add addr %s") % addr)
   1378 
   1379         semanage_context_free(con)
   1380         semanage_node_key_free(k)
   1381         semanage_node_free(node)
   1382 
   1383     def add(self, addr, mask, proto, serange, ctype):
   1384         self.begin()
   1385         self.__add(addr, mask, proto, serange, ctype)
   1386         self.commit()
   1387 
   1388     def __modify(self, addr, mask, proto, serange, setype):
   1389         addr, mask, proto = self.validate(addr, mask, proto)
   1390 
   1391         if serange == "" and setype == "":
   1392             raise ValueError(_("Requires setype or serange"))
   1393 
   1394         if setype and setype not in self.valid_types:
   1395             raise ValueError(_("Type %s is invalid, must be a node type") % setype)
   1396 
   1397         (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
   1398         if rc < 0:
   1399             raise ValueError(_("Could not create key for %s") % addr)
   1400 
   1401         (rc, exists) = semanage_node_exists(self.sh, k)
   1402         if rc < 0:
   1403             raise ValueError(_("Could not check if addr %s is defined") % addr)
   1404         if not exists:
   1405             raise ValueError(_("Addr %s is not defined") % addr)
   1406 
   1407         (rc, node) = semanage_node_query(self.sh, k)
   1408         if rc < 0:
   1409             raise ValueError(_("Could not query addr %s") % addr)
   1410 
   1411         con = semanage_node_get_con(node)
   1412         if (is_mls_enabled == 1) and (serange != ""):
   1413             semanage_context_set_mls(self.sh, con, untranslate(serange))
   1414         if setype != "":
   1415             semanage_context_set_type(self.sh, con, setype)
   1416 
   1417         rc = semanage_node_modify_local(self.sh, k, node)
   1418         if rc < 0:
   1419             raise ValueError(_("Could not modify addr %s") % addr)
   1420 
   1421         semanage_node_key_free(k)
   1422         semanage_node_free(node)
   1423 
   1424     def modify(self, addr, mask, proto, serange, setype):
   1425         self.begin()
   1426         self.__modify(addr, mask, proto, serange, setype)
   1427         self.commit()
   1428 
   1429     def __delete(self, addr, mask, proto):
   1430 
   1431         addr, mask, proto = self.validate(addr, mask, proto)
   1432 
   1433         (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
   1434         if rc < 0:
   1435             raise ValueError(_("Could not create key for %s") % addr)
   1436 
   1437         (rc, exists) = semanage_node_exists(self.sh, k)
   1438         if rc < 0:
   1439             raise ValueError(_("Could not check if addr %s is defined") % addr)
   1440         if not exists:
   1441             raise ValueError(_("Addr %s is not defined") % addr)
   1442 
   1443         (rc, exists) = semanage_node_exists_local(self.sh, k)
   1444         if rc < 0:
   1445             raise ValueError(_("Could not check if addr %s is defined") % addr)
   1446         if not exists:
   1447             raise ValueError(_("Addr %s is defined in policy, cannot be deleted") % addr)
   1448 
   1449         rc = semanage_node_del_local(self.sh, k)
   1450         if rc < 0:
   1451             raise ValueError(_("Could not delete addr %s") % addr)
   1452 
   1453         semanage_node_key_free(k)
   1454 
   1455     def delete(self, addr, mask, proto):
   1456         self.begin()
   1457         self.__delete(addr, mask, proto)
   1458         self.commit()
   1459 
   1460     def deleteall(self):
   1461         (rc, nlist) = semanage_node_list_local(self.sh)
   1462         if rc < 0:
   1463             raise ValueError(_("Could not deleteall node mappings"))
   1464 
   1465         self.begin()
   1466         for node in nlist:
   1467             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)])
   1468         self.commit()
   1469 
   1470     def get_all(self, locallist=0):
   1471         ddict = {}
   1472         if locallist:
   1473             (rc, self.ilist) = semanage_node_list_local(self.sh)
   1474         else:
   1475             (rc, self.ilist) = semanage_node_list(self.sh)
   1476         if rc < 0:
   1477             raise ValueError(_("Could not list addrs"))
   1478 
   1479         for node in self.ilist:
   1480             con = semanage_node_get_con(node)
   1481             addr = semanage_node_get_addr(self.sh, node)
   1482             mask = semanage_node_get_mask(self.sh, node)
   1483             proto = self.protocol[semanage_node_get_proto(node)]
   1484             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))
   1485 
   1486         return ddict
   1487 
   1488     def customized(self):
   1489         l = []
   1490         ddict = self.get_all(True)
   1491         keys = ddict.keys()
   1492         keys.sort()
   1493         for k in keys:
   1494             l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2], ddict[k][2], k[0]))
   1495         return l
   1496 
   1497     def list(self, heading=1, locallist=0):
   1498         ddict = self.get_all(locallist)
   1499         keys = ddict.keys()
   1500         if len(keys) == 0:
   1501             return
   1502         keys.sort()
   1503 
   1504         if heading:
   1505             print "%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context")
   1506         if is_mls_enabled:
   1507             for k in keys:
   1508                 val = ''
   1509                 for fields in k:
   1510                     val = val + '\t' + str(fields)
   1511                 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))
   1512         else:
   1513             for k in keys:
   1514                 print "%-18s %-18s %-5s %s:%s:%s " % (k[0], k[1], k[2], ddict[k][0], ddict[k][1], ddict[k][2])
   1515 
   1516 
   1517 class interfaceRecords(semanageRecords):
   1518 
   1519     def __init__(self, store=""):
   1520         semanageRecords.__init__(self, store)
   1521 
   1522     def __add(self, interface, serange, ctype):
   1523         if is_mls_enabled == 1:
   1524             if serange == "":
   1525                 serange = "s0"
   1526             else:
   1527                 serange = untranslate(serange)
   1528 
   1529         if ctype == "":
   1530             raise ValueError(_("SELinux Type is required"))
   1531 
   1532         (rc, k) = semanage_iface_key_create(self.sh, interface)
   1533         if rc < 0:
   1534             raise ValueError(_("Could not create key for %s") % interface)
   1535 
   1536         (rc, exists) = semanage_iface_exists(self.sh, k)
   1537         if rc < 0:
   1538             raise ValueError(_("Could not check if interface %s is defined") % interface)
   1539         if exists:
   1540             raise ValueError(_("Interface %s already defined") % interface)
   1541 
   1542         (rc, iface) = semanage_iface_create(self.sh)
   1543         if rc < 0:
   1544             raise ValueError(_("Could not create interface for %s") % interface)
   1545 
   1546         rc = semanage_iface_set_name(self.sh, iface, interface)
   1547         (rc, con) = semanage_context_create(self.sh)
   1548         if rc < 0:
   1549             raise ValueError(_("Could not create context for %s") % interface)
   1550 
   1551         rc = semanage_context_set_user(self.sh, con, "system_u")
   1552         if rc < 0:
   1553             raise ValueError(_("Could not set user in interface context for %s") % interface)
   1554 
   1555         rc = semanage_context_set_role(self.sh, con, "object_r")
   1556         if rc < 0:
   1557             raise ValueError(_("Could not set role in interface context for %s") % interface)
   1558 
   1559         rc = semanage_context_set_type(self.sh, con, ctype)
   1560         if rc < 0:
   1561             raise ValueError(_("Could not set type in interface context for %s") % interface)
   1562 
   1563         if (is_mls_enabled == 1) and (serange != ""):
   1564             rc = semanage_context_set_mls(self.sh, con, serange)
   1565             if rc < 0:
   1566                 raise ValueError(_("Could not set mls fields in interface context for %s") % interface)
   1567 
   1568         rc = semanage_iface_set_ifcon(self.sh, iface, con)
   1569         if rc < 0:
   1570             raise ValueError(_("Could not set interface context for %s") % interface)
   1571 
   1572         rc = semanage_iface_set_msgcon(self.sh, iface, con)
   1573         if rc < 0:
   1574             raise ValueError(_("Could not set message context for %s") % interface)
   1575 
   1576         rc = semanage_iface_modify_local(self.sh, k, iface)
   1577         if rc < 0:
   1578             raise ValueError(_("Could not add interface %s") % interface)
   1579 
   1580         semanage_context_free(con)
   1581         semanage_iface_key_free(k)
   1582         semanage_iface_free(iface)
   1583 
   1584     def add(self, interface, serange, ctype):
   1585         self.begin()
   1586         self.__add(interface, serange, ctype)
   1587         self.commit()
   1588 
   1589     def __modify(self, interface, serange, setype):
   1590         if serange == "" and setype == "":
   1591             raise ValueError(_("Requires setype or serange"))
   1592 
   1593         (rc, k) = semanage_iface_key_create(self.sh, interface)
   1594         if rc < 0:
   1595             raise ValueError(_("Could not create key for %s") % interface)
   1596 
   1597         (rc, exists) = semanage_iface_exists(self.sh, k)
   1598         if rc < 0:
   1599             raise ValueError(_("Could not check if interface %s is defined") % interface)
   1600         if not exists:
   1601             raise ValueError(_("Interface %s is not defined") % interface)
   1602 
   1603         (rc, iface) = semanage_iface_query(self.sh, k)
   1604         if rc < 0:
   1605             raise ValueError(_("Could not query interface %s") % interface)
   1606 
   1607         con = semanage_iface_get_ifcon(iface)
   1608 
   1609         if (is_mls_enabled == 1) and (serange != ""):
   1610             semanage_context_set_mls(self.sh, con, untranslate(serange))
   1611         if setype != "":
   1612             semanage_context_set_type(self.sh, con, setype)
   1613 
   1614         rc = semanage_iface_modify_local(self.sh, k, iface)
   1615         if rc < 0:
   1616             raise ValueError(_("Could not modify interface %s") % interface)
   1617 
   1618         semanage_iface_key_free(k)
   1619         semanage_iface_free(iface)
   1620 
   1621     def modify(self, interface, serange, setype):
   1622         self.begin()
   1623         self.__modify(interface, serange, setype)
   1624         self.commit()
   1625 
   1626     def __delete(self, interface):
   1627         (rc, k) = semanage_iface_key_create(self.sh, interface)
   1628         if rc < 0:
   1629             raise ValueError(_("Could not create key for %s") % interface)
   1630 
   1631         (rc, exists) = semanage_iface_exists(self.sh, k)
   1632         if rc < 0:
   1633             raise ValueError(_("Could not check if interface %s is defined") % interface)
   1634         if not exists:
   1635             raise ValueError(_("Interface %s is not defined") % interface)
   1636 
   1637         (rc, exists) = semanage_iface_exists_local(self.sh, k)
   1638         if rc < 0:
   1639             raise ValueError(_("Could not check if interface %s is defined") % interface)
   1640         if not exists:
   1641             raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface)
   1642 
   1643         rc = semanage_iface_del_local(self.sh, k)
   1644         if rc < 0:
   1645             raise ValueError(_("Could not delete interface %s") % interface)
   1646 
   1647         semanage_iface_key_free(k)
   1648 
   1649     def delete(self, interface):
   1650         self.begin()
   1651         self.__delete(interface)
   1652         self.commit()
   1653 
   1654     def deleteall(self):
   1655         (rc, ulist) = semanage_iface_list_local(self.sh)
   1656         if rc < 0:
   1657             raise ValueError(_("Could not delete all interface  mappings"))
   1658 
   1659         self.begin()
   1660         for i in ulist:
   1661             self.__delete(semanage_iface_get_name(i))
   1662         self.commit()
   1663 
   1664     def get_all(self, locallist=0):
   1665         ddict = {}
   1666         if locallist:
   1667             (rc, self.ilist) = semanage_iface_list_local(self.sh)
   1668         else:
   1669             (rc, self.ilist) = semanage_iface_list(self.sh)
   1670         if rc < 0:
   1671             raise ValueError(_("Could not list interfaces"))
   1672 
   1673         for interface in self.ilist:
   1674             con = semanage_iface_get_ifcon(interface)
   1675             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))
   1676 
   1677         return ddict
   1678 
   1679     def customized(self):
   1680         l = []
   1681         ddict = self.get_all(True)
   1682         keys = ddict.keys()
   1683         keys.sort()
   1684         for k in keys:
   1685             l.append("-a -t %s %s" % (ddict[k][2], k))
   1686         return l
   1687 
   1688     def list(self, heading=1, locallist=0):
   1689         ddict = self.get_all(locallist)
   1690         keys = ddict.keys()
   1691         if len(keys) == 0:
   1692             return
   1693         keys.sort()
   1694 
   1695         if heading:
   1696             print "%-30s %s\n" % (_("SELinux Interface"), _("Context"))
   1697         if is_mls_enabled:
   1698             for k in keys:
   1699                 print "%-30s %s:%s:%s:%s " % (k, ddict[k][0], ddict[k][1], ddict[k][2], translate(ddict[k][3], False))
   1700         else:
   1701             for k in keys:
   1702                 print "%-30s %s:%s:%s " % (k, ddict[k][0], ddict[k][1], ddict[k][2])
   1703 
   1704 
   1705 class fcontextRecords(semanageRecords):
   1706     try:
   1707         valid_types = sepolicy.info(sepolicy.ATTRIBUTE, "file_type")[0]["types"]
   1708         valid_types += sepolicy.info(sepolicy.ATTRIBUTE, "device_node")[0]["types"]
   1709         valid_types.append("<<none>>")
   1710     except RuntimeError:
   1711         valid_types = []
   1712 
   1713     def __init__(self, store=""):
   1714         semanageRecords.__init__(self, store)
   1715         self.equiv = {}
   1716         self.equiv_dist = {}
   1717         self.equal_ind = False
   1718         try:
   1719             fd = open(selinux.selinux_file_context_subs_path(), "r")
   1720             for i in fd.readlines():
   1721                 i = i.strip()
   1722                 if len(i) == 0:
   1723                     continue
   1724                 if i.startswith("#"):
   1725                     continue
   1726                 target, substitute = i.split()
   1727                 self.equiv[target] = substitute
   1728             fd.close()
   1729         except IOError:
   1730             pass
   1731         try:
   1732             fd = open(selinux.selinux_file_context_subs_dist_path(), "r")
   1733             for i in fd.readlines():
   1734                 i = i.strip()
   1735                 if len(i) == 0:
   1736                     continue
   1737                 if i.startswith("#"):
   1738                     continue
   1739                 target, substitute = i.split()
   1740                 self.equiv_dist[target] = substitute
   1741             fd.close()
   1742         except IOError:
   1743             pass
   1744 
   1745     def commit(self):
   1746         if self.equal_ind:
   1747             subs_file = selinux.selinux_file_context_subs_path()
   1748             tmpfile = "%s.tmp" % subs_file
   1749             fd = open(tmpfile, "w")
   1750             for target in self.equiv.keys():
   1751                 fd.write("%s %s\n" % (target, self.equiv[target]))
   1752             fd.close()
   1753             try:
   1754                 os.chmod(tmpfile, os.stat(subs_file)[stat.ST_MODE])
   1755             except:
   1756                 pass
   1757             os.rename(tmpfile, subs_file)
   1758             self.equal_ind = False
   1759         semanageRecords.commit(self)
   1760 
   1761     def add_equal(self, target, substitute):
   1762         self.begin()
   1763         if target != "/" and target[-1] == "/":
   1764             raise ValueError(_("Target %s is not valid. Target is not allowed to end with '/'") % target)
   1765 
   1766         if substitute != "/" and substitute[-1] == "/":
   1767             raise ValueError(_("Substiture %s is not valid. Substitute is not allowed to end with '/'") % substitute)
   1768 
   1769         if target in self.equiv.keys():
   1770             raise ValueError(_("Equivalence class for %s already exists") % target)
   1771         self.validate(target)
   1772 
   1773         for fdict in (self.equiv, self.equiv_dist):
   1774             for i in fdict:
   1775                 if i.startswith(target + "/"):
   1776                     raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i]))
   1777 
   1778         self.equiv[target] = substitute
   1779         self.equal_ind = True
   1780         self.commit()
   1781 
   1782     def modify_equal(self, target, substitute):
   1783         self.begin()
   1784         if target not in self.equiv.keys():
   1785             raise ValueError(_("Equivalence class for %s does not exists") % target)
   1786         self.equiv[target] = substitute
   1787         self.equal_ind = True
   1788         self.commit()
   1789 
   1790     def createcon(self, target, seuser="system_u"):
   1791         (rc, con) = semanage_context_create(self.sh)
   1792         if rc < 0:
   1793             raise ValueError(_("Could not create context for %s") % target)
   1794         if seuser == "":
   1795             seuser = "system_u"
   1796 
   1797         rc = semanage_context_set_user(self.sh, con, seuser)
   1798         if rc < 0:
   1799             raise ValueError(_("Could not set user in file context for %s") % target)
   1800 
   1801         rc = semanage_context_set_role(self.sh, con, "object_r")
   1802         if rc < 0:
   1803             raise ValueError(_("Could not set role in file context for %s") % target)
   1804 
   1805         if is_mls_enabled == 1:
   1806             rc = semanage_context_set_mls(self.sh, con, "s0")
   1807             if rc < 0:
   1808                 raise ValueError(_("Could not set mls fields in file context for %s") % target)
   1809 
   1810         return con
   1811 
   1812     def validate(self, target):
   1813         if target == "" or target.find("\n") >= 0:
   1814             raise ValueError(_("Invalid file specification"))
   1815         if target.find(" ") != -1:
   1816             raise ValueError(_("File specification can not include spaces"))
   1817         for fdict in (self.equiv, self.equiv_dist):
   1818             for i in fdict:
   1819                 if target.startswith(i + "/"):
   1820                     t = re.sub(i, fdict[i], target)
   1821                     raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'; Try adding '%s' instead") % (target, i, fdict[i], t))
   1822 
   1823     def __add(self, target, type, ftype="", serange="", seuser="system_u"):
   1824         self.validate(target)
   1825 
   1826         if is_mls_enabled == 1:
   1827             serange = untranslate(serange)
   1828 
   1829         if type == "":
   1830             raise ValueError(_("SELinux Type is required"))
   1831 
   1832         if type not in self.valid_types:
   1833             raise ValueError(_("Type %s is invalid, must be a file or device type") % type)
   1834 
   1835         (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
   1836         if rc < 0:
   1837             raise ValueError(_("Could not create key for %s") % target)
   1838 
   1839         (rc, exists) = semanage_fcontext_exists(self.sh, k)
   1840         if rc < 0:
   1841             raise ValueError(_("Could not check if file context for %s is defined") % target)
   1842 
   1843         if not exists:
   1844             (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
   1845             if rc < 0:
   1846                 raise ValueError(_("Could not check if file context for %s is defined") % target)
   1847 
   1848         if exists:
   1849             raise ValueError(_("File context for %s already defined") % target)
   1850 
   1851         (rc, fcontext) = semanage_fcontext_create(self.sh)
   1852         if rc < 0:
   1853             raise ValueError(_("Could not create file context for %s") % target)
   1854 
   1855         rc = semanage_fcontext_set_expr(self.sh, fcontext, target)
   1856         if type != "<<none>>":
   1857             con = self.createcon(target, seuser)
   1858 
   1859             rc = semanage_context_set_type(self.sh, con, type)
   1860             if rc < 0:
   1861                 raise ValueError(_("Could not set type in file context for %s") % target)
   1862 
   1863             if (is_mls_enabled == 1) and (serange != ""):
   1864                 rc = semanage_context_set_mls(self.sh, con, serange)
   1865                 if rc < 0:
   1866                     raise ValueError(_("Could not set mls fields in file context for %s") % target)
   1867             rc = semanage_fcontext_set_con(self.sh, fcontext, con)
   1868             if rc < 0:
   1869                 raise ValueError(_("Could not set file context for %s") % target)
   1870 
   1871         semanage_fcontext_set_type(fcontext, file_types[ftype])
   1872 
   1873         rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
   1874         if rc < 0:
   1875             raise ValueError(_("Could not add file context for %s") % target)
   1876 
   1877         if type != "<<none>>":
   1878             semanage_context_free(con)
   1879         semanage_fcontext_key_free(k)
   1880         semanage_fcontext_free(fcontext)
   1881 
   1882     def add(self, target, type, ftype="", serange="", seuser="system_u"):
   1883         self.begin()
   1884         self.__add(target, type, ftype, serange, seuser)
   1885         self.commit()
   1886 
   1887     def __modify(self, target, setype, ftype, serange, seuser):
   1888         if serange == "" and setype == "" and seuser == "":
   1889             raise ValueError(_("Requires setype, serange or seuser"))
   1890         if setype and setype not in self.valid_types:
   1891             raise ValueError(_("Type %s is invalid, must be a port type") % setype)
   1892 
   1893         self.validate(target)
   1894 
   1895         (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
   1896         if rc < 0:
   1897             raise ValueError(_("Could not create a key for %s") % target)
   1898 
   1899         (rc, exists) = semanage_fcontext_exists(self.sh, k)
   1900         if rc < 0:
   1901             raise ValueError(_("Could not check if file context for %s is defined") % target)
   1902         if not exists:
   1903             (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
   1904             if not exists:
   1905                 raise ValueError(_("File context for %s is not defined") % target)
   1906 
   1907         (rc, fcontext) = semanage_fcontext_query_local(self.sh, k)
   1908         if rc < 0:
   1909             (rc, fcontext) = semanage_fcontext_query(self.sh, k)
   1910             if rc < 0:
   1911                 raise ValueError(_("Could not query file context for %s") % target)
   1912 
   1913         if setype != "<<none>>":
   1914             con = semanage_fcontext_get_con(fcontext)
   1915 
   1916             if con == None:
   1917                 con = self.createcon(target)
   1918 
   1919             if (is_mls_enabled == 1) and (serange != ""):
   1920                 semanage_context_set_mls(self.sh, con, untranslate(serange))
   1921             if seuser != "":
   1922                 semanage_context_set_user(self.sh, con, seuser)
   1923 
   1924             if setype != "":
   1925                 semanage_context_set_type(self.sh, con, setype)
   1926 
   1927             rc = semanage_fcontext_set_con(self.sh, fcontext, con)
   1928             if rc < 0:
   1929                 raise ValueError(_("Could not set file context for %s") % target)
   1930         else:
   1931             rc = semanage_fcontext_set_con(self.sh, fcontext, None)
   1932             if rc < 0:
   1933                 raise ValueError(_("Could not set file context for %s") % target)
   1934 
   1935         rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
   1936         if rc < 0:
   1937             raise ValueError(_("Could not modify file context for %s") % target)
   1938 
   1939         semanage_fcontext_key_free(k)
   1940         semanage_fcontext_free(fcontext)
   1941 
   1942     def modify(self, target, setype, ftype, serange, seuser):
   1943         self.begin()
   1944         self.__modify(target, setype, ftype, serange, seuser)
   1945         self.commit()
   1946 
   1947     def deleteall(self):
   1948         (rc, flist) = semanage_fcontext_list_local(self.sh)
   1949         if rc < 0:
   1950             raise ValueError(_("Could not list the file contexts"))
   1951 
   1952         self.begin()
   1953 
   1954         for fcontext in flist:
   1955             target = semanage_fcontext_get_expr(fcontext)
   1956             ftype = semanage_fcontext_get_type(fcontext)
   1957             ftype_str = semanage_fcontext_get_type_str(ftype)
   1958             (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype_str])
   1959             if rc < 0:
   1960                 raise ValueError(_("Could not create a key for %s") % target)
   1961 
   1962             rc = semanage_fcontext_del_local(self.sh, k)
   1963             if rc < 0:
   1964                 raise ValueError(_("Could not delete the file context %s") % target)
   1965             semanage_fcontext_key_free(k)
   1966 
   1967         self.equiv = {}
   1968         self.equal_ind = True
   1969         self.commit()
   1970 
   1971     def __delete(self, target, ftype):
   1972         if target in self.equiv.keys():
   1973             self.equiv.pop(target)
   1974             self.equal_ind = True
   1975             return
   1976 
   1977         (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
   1978         if rc < 0:
   1979             raise ValueError(_("Could not create a key for %s") % target)
   1980 
   1981         (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
   1982         if rc < 0:
   1983             raise ValueError(_("Could not check if file context for %s is defined") % target)
   1984         if not exists:
   1985             (rc, exists) = semanage_fcontext_exists(self.sh, k)
   1986             if rc < 0:
   1987                 raise ValueError(_("Could not check if file context for %s is defined") % target)
   1988             if exists:
   1989                 raise ValueError(_("File context for %s is defined in policy, cannot be deleted") % target)
   1990             else:
   1991                 raise ValueError(_("File context for %s is not defined") % target)
   1992 
   1993         rc = semanage_fcontext_del_local(self.sh, k)
   1994         if rc < 0:
   1995             raise ValueError(_("Could not delete file context for %s") % target)
   1996 
   1997         semanage_fcontext_key_free(k)
   1998 
   1999     def delete(self, target, ftype):
   2000         self.begin()
   2001         self.__delete(target, ftype)
   2002         self.commit()
   2003 
   2004     def get_all(self, locallist=0):
   2005         if locallist:
   2006             (rc, self.flist) = semanage_fcontext_list_local(self.sh)
   2007         else:
   2008             (rc, self.flist) = semanage_fcontext_list(self.sh)
   2009             if rc < 0:
   2010                 raise ValueError(_("Could not list file contexts"))
   2011 
   2012             (rc, fclocal) = semanage_fcontext_list_local(self.sh)
   2013             if rc < 0:
   2014                 raise ValueError(_("Could not list local file contexts"))
   2015 
   2016             self.flist += fclocal
   2017 
   2018         ddict = {}
   2019         for fcontext in self.flist:
   2020             expr = semanage_fcontext_get_expr(fcontext)
   2021             ftype = semanage_fcontext_get_type(fcontext)
   2022             ftype_str = semanage_fcontext_get_type_str(ftype)
   2023             con = semanage_fcontext_get_con(fcontext)
   2024             if con:
   2025                 ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
   2026             else:
   2027                 ddict[(expr, ftype_str)] = con
   2028 
   2029         return ddict
   2030 
   2031     def customized(self):
   2032         l = []
   2033         fcon_dict = self.get_all(True)
   2034         keys = fcon_dict.keys()
   2035         keys.sort()
   2036         for k in keys:
   2037             if fcon_dict[k]:
   2038                 l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0]))
   2039 
   2040         if len(self.equiv):
   2041             for target in self.equiv.keys():
   2042                 l.append("-a -e %s %s" % (self.equiv[target], target))
   2043         return l
   2044 
   2045     def list(self, heading=1, locallist=0):
   2046         fcon_dict = self.get_all(locallist)
   2047         keys = fcon_dict.keys()
   2048         if len(keys) != 0:
   2049             keys.sort()
   2050             if heading:
   2051                 print "%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context"))
   2052             for k in keys:
   2053                 if fcon_dict[k]:
   2054                     if is_mls_enabled:
   2055                         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))
   2056                     else:
   2057                         print "%-50s %-18s %s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2])
   2058                 else:
   2059                     print "%-50s %-18s <<None>>" % (k[0], k[1])
   2060 
   2061         if len(self.equiv_dist):
   2062             if not locallist:
   2063                 if heading:
   2064                     print _("\nSELinux Distribution fcontext Equivalence \n")
   2065                 for target in self.equiv_dist.keys():
   2066                     print "%s = %s" % (target, self.equiv_dist[target])
   2067         if len(self.equiv):
   2068             if heading:
   2069                 print _("\nSELinux Local fcontext Equivalence \n")
   2070 
   2071             for target in self.equiv.keys():
   2072                 print "%s = %s" % (target, self.equiv[target])
   2073 
   2074 
   2075 class booleanRecords(semanageRecords):
   2076 
   2077     def __init__(self, store=""):
   2078         semanageRecords.__init__(self, store)
   2079         self.dict = {}
   2080         self.dict["TRUE"] = 1
   2081         self.dict["FALSE"] = 0
   2082         self.dict["ON"] = 1
   2083         self.dict["OFF"] = 0
   2084         self.dict["1"] = 1
   2085         self.dict["0"] = 0
   2086 
   2087         try:
   2088             rc, self.current_booleans = selinux.security_get_boolean_names()
   2089             rc, ptype = selinux.selinux_getpolicytype()
   2090         except:
   2091             self.current_booleans = []
   2092             ptype = None
   2093 
   2094         if self.store == None or self.store == ptype:
   2095             self.modify_local = True
   2096         else:
   2097             self.modify_local = False
   2098 
   2099     def __mod(self, name, value):
   2100         name = selinux.selinux_boolean_sub(name)
   2101 
   2102         (rc, k) = semanage_bool_key_create(self.sh, name)
   2103         if rc < 0:
   2104             raise ValueError(_("Could not create a key for %s") % name)
   2105         (rc, exists) = semanage_bool_exists(self.sh, k)
   2106         if rc < 0:
   2107             raise ValueError(_("Could not check if boolean %s is defined") % name)
   2108         if not exists:
   2109             raise ValueError(_("Boolean %s is not defined") % name)
   2110 
   2111         (rc, b) = semanage_bool_query(self.sh, k)
   2112         if rc < 0:
   2113             raise ValueError(_("Could not query file context %s") % name)
   2114 
   2115         if value.upper() in self.dict:
   2116             semanage_bool_set_value(b, self.dict[value.upper()])
   2117         else:
   2118             raise ValueError(_("You must specify one of the following values: %s") % ", ".join(self.dict.keys()))
   2119 
   2120         if self.modify_local and name in self.current_booleans:
   2121             rc = semanage_bool_set_active(self.sh, k, b)
   2122             if rc < 0:
   2123                 raise ValueError(_("Could not set active value of boolean %s") % name)
   2124         rc = semanage_bool_modify_local(self.sh, k, b)
   2125         if rc < 0:
   2126             raise ValueError(_("Could not modify boolean %s") % name)
   2127         semanage_bool_key_free(k)
   2128         semanage_bool_free(b)
   2129 
   2130     def modify(self, name, value=None, use_file=False):
   2131         self.begin()
   2132         if use_file:
   2133             fd = open(name)
   2134             for b in fd.read().split("\n"):
   2135                 b = b.strip()
   2136                 if len(b) == 0:
   2137                     continue
   2138 
   2139                 try:
   2140                     boolname, val = b.split("=")
   2141                 except ValueError:
   2142                     raise ValueError(_("Bad format %s: Record %s" % (name, b)))
   2143                 self.__mod(boolname.strip(), val.strip())
   2144             fd.close()
   2145         else:
   2146             self.__mod(name, value)
   2147 
   2148         self.commit()
   2149 
   2150     def __delete(self, name):
   2151         name = selinux.selinux_boolean_sub(name)
   2152 
   2153         (rc, k) = semanage_bool_key_create(self.sh, name)
   2154         if rc < 0:
   2155             raise ValueError(_("Could not create a key for %s") % name)
   2156         (rc, exists) = semanage_bool_exists(self.sh, k)
   2157         if rc < 0:
   2158             raise ValueError(_("Could not check if boolean %s is defined") % name)
   2159         if not exists:
   2160             raise ValueError(_("Boolean %s is not defined") % name)
   2161 
   2162         (rc, exists) = semanage_bool_exists_local(self.sh, k)
   2163         if rc < 0:
   2164             raise ValueError(_("Could not check if boolean %s is defined") % name)
   2165         if not exists:
   2166             raise ValueError(_("Boolean %s is defined in policy, cannot be deleted") % name)
   2167 
   2168         rc = semanage_bool_del_local(self.sh, k)
   2169         if rc < 0:
   2170             raise ValueError(_("Could not delete boolean %s") % name)
   2171 
   2172         semanage_bool_key_free(k)
   2173 
   2174     def delete(self, name):
   2175         self.begin()
   2176         self.__delete(name)
   2177         self.commit()
   2178 
   2179     def deleteall(self):
   2180         (rc, self.blist) = semanage_bool_list_local(self.sh)
   2181         if rc < 0:
   2182             raise ValueError(_("Could not list booleans"))
   2183 
   2184         self.begin()
   2185 
   2186         for boolean in self.blist:
   2187             name = semanage_bool_get_name(boolean)
   2188             self.__delete(name)
   2189 
   2190         self.commit()
   2191 
   2192     def get_all(self, locallist=0):
   2193         ddict = {}
   2194         if locallist:
   2195             (rc, self.blist) = semanage_bool_list_local(self.sh)
   2196         else:
   2197             (rc, self.blist) = semanage_bool_list(self.sh)
   2198         if rc < 0:
   2199             raise ValueError(_("Could not list booleans"))
   2200 
   2201         for boolean in self.blist:
   2202             value = []
   2203             name = semanage_bool_get_name(boolean)
   2204             value.append(semanage_bool_get_value(boolean))
   2205             if self.modify_local and boolean in self.current_booleans:
   2206                 value.append(selinux.security_get_boolean_pending(name))
   2207                 value.append(selinux.security_get_boolean_active(name))
   2208             else:
   2209                 value.append(value[0])
   2210                 value.append(value[0])
   2211             ddict[name] = value
   2212 
   2213         return ddict
   2214 
   2215     def get_desc(self, name):
   2216         name = selinux.selinux_boolean_sub(name)
   2217         return boolean_desc(name)
   2218 
   2219     def get_category(self, name):
   2220         name = selinux.selinux_boolean_sub(name)
   2221         return boolean_category(name)
   2222 
   2223     def customized(self):
   2224         l = []
   2225         ddict = self.get_all(True)
   2226         keys = ddict.keys()
   2227         keys.sort()
   2228         for k in keys:
   2229             if ddict[k]:
   2230                 l.append("-m -%s %s" % (ddict[k][2], k))
   2231         return l
   2232 
   2233     def list(self, heading=True, locallist=False, use_file=False):
   2234         on_off = (_("off"), _("on"))
   2235         if use_file:
   2236             ddict = self.get_all(locallist)
   2237             keys = ddict.keys()
   2238             for k in keys:
   2239                 if ddict[k]:
   2240                     print "%s=%s" % (k, ddict[k][2])
   2241             return
   2242         ddict = self.get_all(locallist)
   2243         keys = ddict.keys()
   2244         if len(keys) == 0:
   2245             return
   2246 
   2247         if heading:
   2248             print "%-30s %s  %s %s\n" % (_("SELinux boolean"), _("State"), _("Default"), _("Description"))
   2249         for k in keys:
   2250             if ddict[k]:
   2251                 print "%-30s (%-5s,%5s)  %s" % (k, on_off[selinux.security_get_boolean_active(k)], on_off[ddict[k][2]], self.get_desc(k))
   2252