diff --git selinux-python-2.7/semanage/semanage selinux-python-2.7/semanage/semanage index 313537c..8d8a086 100644 --- selinux-python-2.7/semanage/semanage +++ selinux-python-2.7/semanage/semanage @@ -89,16 +89,6 @@ class CheckRole(argparse.Action): newval.append(v) setattr(namespace, self.dest, newval) -store = '' - - -class SetStore(argparse.Action): - - def __call__(self, parser, namespace, values, option_string=None): - global store - store = values - setattr(namespace, self.dest, values) - class seParser(argparse.ArgumentParser): @@ -134,67 +124,21 @@ class SetImportFile(argparse.Action): sys.exit(1) setattr(namespace, self.dest, values) -# functions for OBJECT initialization - - -def login_ini(): - OBJECT = seobject.loginRecords(store) - return OBJECT - - -def user_ini(): - OBJECT = seobject.seluserRecords(store) - return OBJECT - - -def port_ini(): - OBJECT = seobject.portRecords(store) - return OBJECT - -def ibpkey_ini(): - OBJECT = seobject.ibpkeyRecords(store) - return OBJECT - -def ibendport_ini(): - OBJECT = seobject.ibendportRecords(store) - return OBJECT - -def module_ini(): - OBJECT = seobject.moduleRecords(store) - return OBJECT - - -def interface_ini(): - OBJECT = seobject.interfaceRecords(store) - return OBJECT - - -def node_ini(): - OBJECT = seobject.nodeRecords(store) - return OBJECT - - -def fcontext_ini(): - OBJECT = seobject.fcontextRecords(store) - return OBJECT - - -def boolean_ini(): - OBJECT = seobject.booleanRecords(store) - return OBJECT - - -def permissive_ini(): - OBJECT = seobject.permissiveRecords(store) - return OBJECT - - -def dontaudit_ini(): - OBJECT = seobject.dontauditClass(store) - return OBJECT - # define dictonary for seobject OBEJCTS -object_dict = {'login': login_ini, 'user': user_ini, 'port': port_ini, 'module': module_ini, 'interface': interface_ini, 'node': node_ini, 'fcontext': fcontext_ini, 'boolean': boolean_ini, 'permissive': permissive_ini, 'dontaudit': dontaudit_ini, 'ibpkey': ibpkey_ini, 'ibendport': ibendport_ini} +object_dict = { + 'login': seobject.loginRecords, + 'user': seobject.seluserRecords, + 'port': seobject.portRecords, + 'module': seobject.moduleRecords, + 'interface': seobject.interfaceRecords, + 'node': seobject.nodeRecords, + 'fcontext': seobject.fcontextRecords, + 'boolean': seobject.booleanRecords, + 'permissive': seobject.permissiveRecords, + 'dontaudit': seobject.dontauditClass, + 'ibpkey': seobject.ibpkeyRecords, + 'ibendport': seobject.ibendportRecords +} def generate_custom_usage(usage_text, usage_dict): # generate custom usage from given text and dictonary @@ -238,8 +182,7 @@ def handleLogin(args): handle_opts(args, login_args, args.action) - OBJECT = object_dict['login']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['login'](args) if args.action is "add": OBJECT.add(args.login, args.seuser, args.range) @@ -257,7 +200,7 @@ def handleLogin(args): def parser_add_store(parser, name): - parser.add_argument('-S', '--store', action=SetStore, help=_("Select an alternate SELinux Policy Store to manage")) + parser.add_argument('-S', '--store', default='', help=_("Select an alternate SELinux Policy Store to manage")) def parser_add_priority(parser, name): @@ -269,7 +212,7 @@ def parser_add_noheading(parser, name): def parser_add_noreload(parser, name): - parser.add_argument('-N', '--noreload', action='store_false', default=True, help=_('Do not reload policy after commit')) + parser.add_argument('-N', '--noreload', action='store_true', default=False, help=_('Do not reload policy after commit')) def parser_add_locallist(parser, name): @@ -372,8 +315,7 @@ def handleFcontext(args): else: handle_opts(args, fcontext_args, args.action) - OBJECT = object_dict['fcontext']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['fcontext'](args) if args.action is "add": if args.equal: @@ -441,8 +383,7 @@ def handleUser(args): handle_opts(args, user_args, args.action) - OBJECT = object_dict['user']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['user'](args) if args.action is "add": OBJECT.add(args.selinux_name, args.roles, args.level, args.range, args.prefix) @@ -492,8 +433,7 @@ def handlePort(args): handle_opts(args, port_args, args.action) - OBJECT = object_dict['port']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['port'](args) if args.action is "add": OBJECT.add(args.port, args.proto, args.range, args.type) @@ -538,8 +478,7 @@ def handlePkey(args): handle_opts(args, ibpkey_args, args.action) - OBJECT = object_dict['ibpkey']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['ibpkey'](args) if args.action is "add": OBJECT.add(args.ibpkey, args.subnet_prefix, args.range, args.type) @@ -582,8 +521,7 @@ def handleIbendport(args): handle_opts(args, ibendport_args, args.action) - OBJECT = object_dict['ibendport']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['ibendport'](args) if args.action is "add": OBJECT.add(args.ibendport, args.ibdev_name, args.range, args.type) @@ -626,8 +564,7 @@ def handleInterface(args): handle_opts(args, interface_args, args.action) - OBJECT = object_dict['interface']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['interface'](args) if args.action is "add": OBJECT.add(args.interface, args.range, args.type) @@ -666,8 +603,7 @@ def setupInterfaceParser(subparsers): def handleModule(args): - OBJECT = seobject.moduleRecords(store) - OBJECT.set_reload(args.noreload) + OBJECT = seobject.moduleRecords(args) if args.action == "add": OBJECT.add(args.module_name, args.priority) if args.action == "enable": @@ -709,8 +645,7 @@ def handleNode(args): node_args = {'list': [('node', 'type', 'proto', 'netmask'), ('')], 'add': [('locallist'), ('type', 'node', 'proto', 'netmask')], 'modify': [('locallist'), ('node', 'netmask', 'proto')], 'delete': [('locallist'), ('node', 'netmask', 'prototype')], 'extract': [('locallist', 'node', 'type', 'proto', 'netmask'), ('')], 'deleteall': [('locallist'), ('')]} handle_opts(args, node_args, args.action) - OBJECT = object_dict['node']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['node'](args) if args.action is "add": OBJECT.add(args.node, args.netmask, args.proto, args.range, args.type) @@ -756,8 +691,7 @@ def handleBoolean(args): handle_opts(args, boolean_args, args.action) - OBJECT = object_dict['boolean']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['boolean'](args) if args.action is "modify": if args.boolean: @@ -795,8 +729,7 @@ def setupBooleanParser(subparsers): def handlePermissive(args): - OBJECT = object_dict['permissive']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['permissive'](args) if args.action is "list": OBJECT.list(args.noheading) @@ -830,8 +763,7 @@ def setupPermissiveParser(subparsers): def handleDontaudit(args): - OBJECT = object_dict['dontaudit']() - OBJECT.set_reload(args.noreload) + OBJECT = object_dict['dontaudit'](args) OBJECT.toggle(args.action) @@ -848,7 +780,7 @@ def handleExport(args): for i in manageditems: print("%s -D" % i) for i in manageditems: - OBJECT = object_dict[i]() + OBJECT = object_dict[i](args) for c in OBJECT.customized(): print("%s %s" % (i, str(c))) @@ -912,7 +844,7 @@ def mkargv(line): def handleImport(args): - trans = seobject.semanageRecords(store) + trans = seobject.semanageRecords(args) trans.start() for l in sys.stdin.readlines(): @@ -932,7 +864,6 @@ def handleImport(args): except KeyboardInterrupt: sys.exit(0) - trans.set_reload(args.noreload) trans.finish() diff --git selinux-python-2.7/semanage/semanage.8 selinux-python-2.7/semanage/semanage.8 index 0bdb90f..0cdcfcc 100644 --- selinux-python-2.7/semanage/semanage.8 +++ selinux-python-2.7/semanage/semanage.8 @@ -57,9 +57,8 @@ to SELinux user identities (which controls the initial security context assigned to Linux users when they login and bounds their authorized role set) as well as security context mappings for various kinds of objects, such as network ports, interfaces, infiniband pkeys and endports, and nodes (hosts) -as well as the file context mapping. See the EXAMPLES section below for some -examples of common usage. Note that the semanage login command deals with the -mapping from Linux usernames (logins) to SELinux user identities, +as well as the file context mapping. Note that the semanage login command deals +with the mapping from Linux usernames (logins) to SELinux user identities, while the semanage user command deals with the mapping from SELinux user identities to authorized role sets. In most cases, only the former mapping needs to be adjusted by the administrator; the latter diff --git selinux-python-2.7/semanage/seobject.py selinux-python-2.7/semanage/seobject.py index 70fd192..dca9506 100644 --- selinux-python-2.7/semanage/seobject.py +++ selinux-python-2.7/semanage/seobject.py @@ -238,20 +238,31 @@ class semanageRecords: transaction = False handle = None store = None + args = None + noreload = False - def __init__(self, store): + def __init__(self, args = None): global handle - self.load = True - self.sh = self.get_handle(store) + if args: + # legacy code - args was store originally + if type(args) == str: + self.store = args + else: + self.args = args + self.noreload = getattr(args, "noreload", False) + if not self.store: + self.store = getattr(args, "store", "") + + self.sh = self.get_handle(self.store) rc, localstore = selinux.selinux_getpolicytype() - if store == "" or store == localstore: + if self.store == "" or self.store == localstore: self.mylog = logger() else: self.mylog = nulllogger() def set_reload(self, load): - self.load = load + self.noreload = not load def get_handle(self, store): global is_mls_enabled @@ -312,7 +323,8 @@ class semanageRecords: if semanageRecords.transaction: return - semanage_set_reload(self.sh, self.load) + if self.noreload: + semanage_set_reload(self.sh, 0) rc = semanage_commit(self.sh) if rc < 0: self.mylog.commit(0) @@ -328,8 +340,8 @@ class semanageRecords: class moduleRecords(semanageRecords): - def __init__(self, store): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) def get_all(self): l = [] @@ -386,6 +398,8 @@ class moduleRecords(semanageRecords): print("%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled)) def add(self, file, priority): + if not file: + raise ValueError(_("You did not define module.")) if not os.path.exists(file): raise ValueError(_("Module does not exist: %s ") % file) @@ -398,6 +412,8 @@ class moduleRecords(semanageRecords): self.commit() def set_enabled(self, module, enable): + if not module: + raise ValueError(_("You did not define module name.")) for m in module.split(): rc, key = semanage_module_key_create(self.sh) if rc < 0: @@ -416,11 +432,15 @@ class moduleRecords(semanageRecords): self.commit() def modify(self, file): + if not file: + raise ValueError(_("You did not define module.")) rc = semanage_module_update_file(self.sh, file) if rc >= 0: self.commit() def delete(self, module, priority): + if not module: + raise ValueError(_("You did not define module name.")) rc = semanage_set_default_priority(self.sh, priority) if rc < 0: raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority) @@ -440,8 +460,8 @@ class moduleRecords(semanageRecords): class dontauditClass(semanageRecords): - def __init__(self, store): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) def toggle(self, dontaudit): if dontaudit not in ["on", "off"]: @@ -453,8 +473,8 @@ class dontauditClass(semanageRecords): class permissiveRecords(semanageRecords): - def __init__(self, store): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) def get_all(self): l = [] @@ -522,8 +542,8 @@ class permissiveRecords(semanageRecords): class loginRecords(semanageRecords): - def __init__(self, store=""): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) self.oldsename = None self.oldserange = None self.sename = None @@ -534,7 +554,7 @@ class loginRecords(semanageRecords): if sename == "": sename = "user_u" - userrec = seluserRecords() + userrec = seluserRecords(self.args) range, (rc, oldserole) = userrec.get(self.oldsename) range, (rc, serole) = userrec.get(sename) @@ -603,7 +623,7 @@ class loginRecords(semanageRecords): if sename == "" and serange == "": raise ValueError(_("Requires seuser or serange")) - userrec = seluserRecords() + userrec = seluserRecords(self.args) range, (rc, oldserole) = userrec.get(self.oldsename) if sename != "": @@ -660,7 +680,7 @@ class loginRecords(semanageRecords): def __delete(self, name): rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) - userrec = seluserRecords() + userrec = seluserRecords(self.args) range, (rc, oldserole) = userrec.get(self.oldsename) (rc, k) = semanage_seuser_key_create(self.sh, name) @@ -779,8 +799,8 @@ class loginRecords(semanageRecords): class seluserRecords(semanageRecords): - def __init__(self, store=""): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) def get(self, name): (rc, k) = semanage_user_key_create(self.sh, name) @@ -1042,8 +1062,8 @@ class portRecords(semanageRecords): except RuntimeError: valid_types = [] - def __init__(self, store=""): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) def __genkey(self, port, proto): if proto == "tcp": @@ -1317,8 +1337,8 @@ class ibpkeyRecords(semanageRecords): except: valid_types = [] - def __init__(self, store=""): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) def __genkey(self, pkey, subnet_prefix): if subnet_prefix == "": @@ -1540,9 +1560,8 @@ class ibpkeyRecords(semanageRecords): def customized(self): l = [] ddict = self.get_all(True) - keys = ddict.keys() - keys.sort() - for k in keys: + + for k in sorted(ddict.keys()): if k[0] == k[1]: l.append("-a -t %s -x %s %s" % (ddict[k][0], k[2], k[0])) else: @@ -1554,11 +1573,10 @@ class ibpkeyRecords(semanageRecords): keys = ddict.keys() if len(keys) == 0: return - keys.sort() if heading: print("%-30s %-18s %s\n" % (_("SELinux IB Pkey Type"), _("Subnet_Prefix"), _("Pkey Number"))) - for i in keys: + for i in sorted(keys): rec = "%-30s %-18s " % i rec += "%s" % ddict[i][0] for p in ddict[i][1:]: @@ -1572,8 +1590,8 @@ class ibendportRecords(semanageRecords): except: valid_types = [] - def __init__(self, store=""): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) def __genkey(self, ibendport, ibdev_name): if ibdev_name == "": @@ -1782,10 +1800,9 @@ class ibendportRecords(semanageRecords): def customized(self): l = [] ddict = self.get_all(True) - keys = ddict.keys() - keys.sort() - for k in keys: - l.append("-a -t %s -x %s %s" % (ddict[k][0], k[2], k[0])) + + for k in sorted(ddict.keys()): + l.append("-a -t %s -r %s -z %s %s" % (ddict[k][0], ddict[k][1], k[1], k[0])) return l def list(self, heading=1, locallist=0): @@ -1793,11 +1810,10 @@ class ibendportRecords(semanageRecords): keys = ddict.keys() if len(keys) == 0: return - keys.sort() if heading: print("%-30s %-18s %s\n" % (_("SELinux IB End Port Type"), _("IB Device Name"), _("Port Number"))) - for i in keys: + for i in sorted(keys): rec = "%-30s %-18s " % i rec += "%s" % ddict[i][0] for p in ddict[i][1:]: @@ -1810,8 +1826,8 @@ class nodeRecords(semanageRecords): except RuntimeError: valid_types = [] - def __init__(self, store=""): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) self.protocol = ["ipv4", "ipv6"] def validate(self, addr, mask, protocol): @@ -2046,8 +2062,8 @@ class nodeRecords(semanageRecords): class interfaceRecords(semanageRecords): - def __init__(self, store=""): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) def __add(self, interface, serange, ctype): if is_mls_enabled == 1: @@ -2243,8 +2259,8 @@ class fcontextRecords(semanageRecords): except RuntimeError: valid_types = [] - def __init__(self, store=""): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) self.equiv = {} self.equiv_dist = {} self.equal_ind = False @@ -2566,10 +2582,15 @@ class fcontextRecords(semanageRecords): if rc < 0: raise ValueError(_("Could not list file contexts")) + (rc, fchomedirs) = semanage_fcontext_list_homedirs(self.sh) + if rc < 0: + raise ValueError(_("Could not list file contexts for home directories")) + (rc, fclocal) = semanage_fcontext_list_local(self.sh) if rc < 0: raise ValueError(_("Could not list local file contexts")) + self.flist += fchomedirs self.flist += fclocal ddict = {} @@ -2627,8 +2648,8 @@ class fcontextRecords(semanageRecords): class booleanRecords(semanageRecords): - def __init__(self, store=""): - semanageRecords.__init__(self, store) + def __init__(self, args = None): + semanageRecords.__init__(self, args) self.dict = {} self.dict["TRUE"] = 1 self.dict["FALSE"] = 0 diff --git selinux-python-2.7/sepolicy/sepolicy.8 selinux-python-2.7/sepolicy/sepolicy.8 index 7900586..09d2b24 100644 --- selinux-python-2.7/sepolicy/sepolicy.8 +++ selinux-python-2.7/sepolicy/sepolicy.8 @@ -22,14 +22,15 @@ Query SELinux policy to see if domains can communicate with each other .br .B generate -.br .br Generate SELinux Policy module template -.B gui +.B sepolicy-generate(8) .br + +.B gui .br Launch Graphical User Interface for SELinux Policy, requires policycoreutils-gui package. -.B sepolicy-generate(8) +.B sepolicy-gui(8) .br .B interface diff --git selinux-python-2.7/sepolicy/sepolicy/__init__.py selinux-python-2.7/sepolicy/sepolicy/__init__.py index 5cfc071..24e3526 100644 --- selinux-python-2.7/sepolicy/sepolicy/__init__.py +++ selinux-python-2.7/sepolicy/sepolicy/__init__.py @@ -4,6 +4,7 @@ # Author: Ryan Hallisey # Author: Jason Zaman +import errno import selinux import setools import glob @@ -207,10 +208,17 @@ def info(setype, name=None): elif len(ports) == 1: q.ports = (ports[0], ports[0]) + if _pol.mls: + return ({ + 'high': x.ports.high, + 'protocol': str(x.protocol), + 'range': str(x.context.range_), + 'type': str(x.context.type_), + 'low': x.ports.low, + } for x in q.results()) return ({ 'high': x.ports.high, 'protocol': str(x.protocol), - 'range': str(x.context.range_), 'type': str(x.context.type_), 'low': x.ports.low, } for x in q.results()) @@ -220,11 +228,16 @@ def info(setype, name=None): if name: q.name = name + if _pol.mls: + return ({ + 'range': str(x.mls_range), + 'name': str(x), + 'roles': list(map(str, x.roles)), + 'level': str(x.mls_level), + } for x in q.results()) return ({ - 'range': str(x.mls_range), 'name': str(x), 'roles': list(map(str, x.roles)), - 'level': str(x.mls_level), } for x in q.results()) elif setype == BOOLEAN: @@ -511,12 +524,15 @@ def find_entrypoint_path(exe, exclude_list=[]): def read_file_equiv(edict, fc_path, modify): - fd = open(fc_path, "r") - fc = fd.readlines() - fd.close() - for e in fc: - f = e.split() - edict[f[0]] = {"equiv": f[1], "modify": modify} + try: + with open(fc_path, "r") as fd: + for e in fd: + f = e.split() + if f and not f[0].startswith('#'): + edict[f[0]] = {"equiv": f[1], "modify": modify} + except OSError as e: + if e.errno != errno.ENOENT: + raise return edict @@ -543,9 +559,13 @@ def get_local_file_paths(fc_path=selinux.selinux_file_context_path()): if local_files: return local_files local_files = [] - fd = open(fc_path + ".local", "r") - fc = fd.readlines() - fd.close() + try: + with open(fc_path + ".local", "r") as fd: + fc = fd.readlines() + except OSError as e: + if e.errno != errno.ENOENT: + raise + return [] for i in fc: rec = i.split() if len(rec) == 0: @@ -573,9 +593,12 @@ def get_fcdict(fc_path=selinux.selinux_file_context_path()): fc += fd.readlines() fd.close() fcdict = {} - fd = open(fc_path + ".local", "r") - fc += fd.readlines() - fd.close() + try: + with open(fc_path + ".local", "r") as fd: + fc += fd.readlines() + except OSError as e: + if e.errno != errno.ENOENT: + raise for i in fc: rec = i.split() @@ -856,8 +879,9 @@ def get_selinux_users(): global selinux_user_list if not selinux_user_list: selinux_user_list = list(info(USER)) - for x in selinux_user_list: - x['range'] = "".join(x['range'].split(" ")) + if _pol.mls: + for x in selinux_user_list: + x['range'] = "".join(x['range'].split(" ")) return selinux_user_list @@ -955,7 +979,7 @@ def get_description(f, markup=markup): if f.endswith("_db_t"): return txt + "treat the files as %s database content." % prettyprint(f, "_db_t") if f.endswith("_ra_content_t"): - return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_conten_t") + return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_content_t") if f.endswith("_cert_t"): return txt + "treat the files as %s certificate data." % prettyprint(f, "_cert_t") if f.endswith("_key_t"): @@ -1136,27 +1160,14 @@ def boolean_desc(boolean): def get_os_version(): - os_version = "" - pkg_name = "selinux-policy" + system_release = "" try: - try: - from commands import getstatusoutput - except ImportError: - from subprocess import getstatusoutput - rc, output = getstatusoutput("rpm -q '%s'" % pkg_name) - if rc == 0: - os_version = output.split(".")[-2] - except: - os_version = "" - - if os_version[0:2] == "fc": - os_version = "Fedora" + os_version[2:] - elif os_version[0:2] == "el": - os_version = "RHEL" + os_version[2:] - else: - os_version = "" + with open('/etc/system-release') as f: + system_release = f.readline().rstrip() + except IOError: + system_release = "Misc" - return os_version + return system_release def reinit(): diff --git selinux-python-2.7/sepolicy/sepolicy/gui.py selinux-python-2.7/sepolicy/sepolicy/gui.py index 007c94a..6562aa8 100644 --- selinux-python-2.7/sepolicy/sepolicy/gui.py +++ selinux-python-2.7/sepolicy/sepolicy/gui.py @@ -907,8 +907,8 @@ class SELinuxGui(): if "object_r" in roles: roles.remove("object_r") self.user_liststore.set_value(iter, 1, ", ".join(roles)) - self.user_liststore.set_value(iter, 2, u["level"]) - self.user_liststore.set_value(iter, 3, u["range"]) + self.user_liststore.set_value(iter, 2, u.get("level", "")) + self.user_liststore.set_value(iter, 3, u.get("range", "")) self.user_liststore.set_value(iter, 4, True) self.ready_mouse() @@ -1755,14 +1755,14 @@ class SELinuxGui(): if self.login_mls_entry.get_text() == "": for u in sepolicy.get_selinux_users(): if seuser == u['name']: - self.login_mls_entry.set_text(u['range']) + self.login_mls_entry.set_text(u.get('range', '')) def user_roles_combobox_change(self, combo, *args): serole = self.combo_get_active_text(combo) if self.user_mls_entry.get_text() == "": for u in sepolicy.get_all_roles(): if serole == u['name']: - self.user_mls_entry.set_text(u['range']) + self.user_mls_entry.set_text(u.get('range', '')) def get_selected_iter(self): iter = None @@ -1973,7 +1973,10 @@ class SELinuxGui(): self.cur_dict["user"][name] = {"action": "-m", "range": mls_range, "level": level, "role": roles, "oldrange": oldrange, "oldlevel": oldlevel, "oldroles": oldroles, "oldname": oldname} else: iter = self.liststore.append(None) - self.cur_dict["user"][name] = {"action": "-a", "range": mls_range, "level": level, "role": roles} + if mls_range or level: + self.cur_dict["user"][name] = {"action": "-a", "range": mls_range, "level": level, "role": roles} + else: + self.cur_dict["user"][name] = {"action": "-a", "role": roles} self.liststore.set_value(iter, 0, name) self.liststore.set_value(iter, 1, roles) @@ -2089,8 +2092,8 @@ class SELinuxGui(): user_dict = self.cust_dict["user"] for user in user_dict: roles = user_dict[user]["role"] - mls = user_dict[user]["range"] - level = user_dict[user]["level"] + mls = user_dict[user].get("range", "") + level = user_dict[user].get("level", "") iter = self.user_delete_liststore.append() self.user_delete_liststore.set_value(iter, 1, user) self.user_delete_liststore.set_value(iter, 2, roles) @@ -2104,7 +2107,7 @@ class SELinuxGui(): login_dict = self.cust_dict["login"] for login in login_dict: seuser = login_dict[login]["seuser"] - mls = login_dict[login]["range"] + mls = login_dict[login].get("range", "") iter = self.login_delete_liststore.append() self.login_delete_liststore.set_value(iter, 1, seuser) self.login_delete_liststore.set_value(iter, 2, login) @@ -2268,7 +2271,7 @@ class SELinuxGui(): self.update_treestore.set_value(niter, 3, False) roles = self.cur_dict["user"][user]["role"] self.update_treestore.set_value(niter, 1, (_("Roles: %s")) % roles) - mls = self.cur_dict["user"][user]["range"] + mls = self.cur_dict["user"][user].get("range", "") niter = self.update_treestore.append(iter) self.update_treestore.set_value(niter, 3, False) self.update_treestore.set_value(niter, 1, _("MLS/MCS Range: %s") % mls) @@ -2293,7 +2296,7 @@ class SELinuxGui(): self.update_treestore.set_value(niter, 3, False) seuser = self.cur_dict["login"][login]["seuser"] self.update_treestore.set_value(niter, 1, (_("SELinux User: %s")) % seuser) - mls = self.cur_dict["login"][login]["range"] + mls = self.cur_dict["login"][login].get("range", "") niter = self.update_treestore.append(iter) self.update_treestore.set_value(niter, 3, False) self.update_treestore.set_value(niter, 1, _("MLS/MCS Range: %s") % mls) @@ -2487,14 +2490,18 @@ class SELinuxGui(): for l in self.cur_dict[k]: if self.cur_dict[k][l]["action"] == "-d": update_buffer += "login -d %s\n" % l - else: + elif "range" in self.cur_dict[k][l]: update_buffer += "login %s -s %s -r %s %s\n" % (self.cur_dict[k][l]["action"], self.cur_dict[k][l]["seuser"], self.cur_dict[k][l]["range"], l) + else: + update_buffer += "login %s -s %s %s\n" % (self.cur_dict[k][l]["action"], self.cur_dict[k][l]["seuser"], l) if k in "user": for u in self.cur_dict[k]: if self.cur_dict[k][u]["action"] == "-d": update_buffer += "user -d %s\n" % u - else: + elif "level" in self.cur_dict[k][u] and "range" in self.cur_dict[k][u]: update_buffer += "user %s -L %s -r %s -R %s %s\n" % (self.cur_dict[k][u]["action"], self.cur_dict[k][u]["level"], self.cur_dict[k][u]["range"], self.cur_dict[k][u]["role"], u) + else: + update_buffer += "user %s -R %s %s\n" % (self.cur_dict[k][u]["action"], self.cur_dict[k][u]["role"], u) if k in "fcontext-equiv": for f in self.cur_dict[k]: diff --git selinux-python-2.7/sepolicy/sepolicy/manpage.py selinux-python-2.7/sepolicy/sepolicy/manpage.py index 4d84636..b463165 100755 --- selinux-python-2.7/sepolicy/sepolicy/manpage.py +++ selinux-python-2.7/sepolicy/sepolicy/manpage.py @@ -84,7 +84,8 @@ def get_all_users_info(): for d in allusers_info: allusers.append(d['name']) - users_range[d['name'].split("_")[0]] = d['range'] + if 'range' in d: + users_range[d['name'].split("_")[0]] = d['range'] for u in allusers: if u not in ["system_u", "root", "unconfined_u"]: @@ -125,8 +126,36 @@ def gen_domains(): domains.sort() return domains -types = None +exec_types = None + +def _gen_exec_types(): + global exec_types + if exec_types is None: + exec_types = next(sepolicy.info(sepolicy.ATTRIBUTE, "exec_type"))["types"] + return exec_types + +entry_types = None + +def _gen_entry_types(): + global entry_types + if entry_types is None: + entry_types = next(sepolicy.info(sepolicy.ATTRIBUTE, "entry_type"))["types"] + return entry_types + +mcs_constrained_types = None + +def _gen_mcs_constrained_types(): + global mcs_constrained_types + if mcs_constrained_types is None: + try: + mcs_constrained_types = next(sepolicy.info(sepolicy.ATTRIBUTE, "mcs_constrained_type")) + except StopIteration: + mcs_constrained_types = [] + return mcs_constrained_types + + +types = None def _gen_types(): global types @@ -149,10 +178,6 @@ def prettyprint(f, trim): manpage_domains = [] manpage_roles = [] -fedora_releases = ["Fedora17", "Fedora18"] -rhel_releases = ["RHEL6", "RHEL7"] - - def get_alphabet_manpages(manpage_list): alphabet_manpages = dict.fromkeys(string.ascii_letters, []) for i in string.ascii_letters: @@ -182,7 +207,7 @@ def convert_manpage_to_html(html_manpage, manpage): class HTMLManPages: """ - Generate a HHTML Manpages on an given SELinux domains + Generate a HTML Manpages on an given SELinux domains """ def __init__(self, manpage_roles, manpage_domains, path, os_version): @@ -190,9 +215,9 @@ class HTMLManPages: self.manpage_domains = get_alphabet_manpages(manpage_domains) self.os_version = os_version self.old_path = path + "/" - self.new_path = self.old_path + self.os_version + "/" + self.new_path = self.old_path - if self.os_version in fedora_releases or rhel_releases: + if self.os_version: self.__gen_html_manpages() else: print("SELinux HTML man pages can not be generated for this %s" % os_version) @@ -201,7 +226,6 @@ class HTMLManPages: def __gen_html_manpages(self): self._write_html_manpage() self._gen_index() - self._gen_body() self._gen_css() def _write_html_manpage(self): @@ -219,67 +243,21 @@ class HTMLManPages: convert_manpage_to_html((self.new_path + r.rsplit("_selinux", 1)[0] + ".html"), self.old_path + r) def _gen_index(self): - index = self.old_path + "index.html" - fd = open(index, 'w') - fd.write(""" - - - - SELinux man pages online - - -

SELinux man pages

-

-Fedora or Red Hat Enterprise Linux Man Pages. -

-
-

Fedora

- - -
-
-
-""")
-        for f in fedora_releases:
-            fd.write("""
-%s - SELinux man pages for %s """ % (f, f, f, f))
-
-        fd.write("""
-
-
-

RHEL

- - -
-
-
-""")
-        for r in rhel_releases:
-            fd.write("""
-%s - SELinux man pages for %s """ % (r, r, r, r))
-
-        fd.write("""
-
- """) - fd.close() - print("%s has been created") % index - - def _gen_body(self): html = self.new_path + self.os_version + ".html" fd = open(html, 'w') fd.write(""" - - Linux man-pages online for Fedora18 + + SELinux man pages -

SELinux man pages for Fedora18

+

SELinux man pages for %s


SELinux roles

-""") +""" % self.os_version) for letter in self.manpage_roles: if len(self.manpage_roles[letter]): fd.write(""" @@ -423,6 +401,9 @@ class ManPage: self.all_file_types = sepolicy.get_all_file_types() self.role_allows = sepolicy.get_all_role_allows() self.types = _gen_types() + self.exec_types = _gen_exec_types() + self.entry_types = _gen_entry_types() + self.mcs_constrained_types = _gen_mcs_constrained_types() if self.source_files: self.fcpath = self.root + "file_contexts" @@ -735,10 +716,13 @@ Default Defined Ports:""") def _file_context(self): flist = [] + flist_non_exec = [] mpaths = [] for f in self.all_file_types: if f.startswith(self.domainname): flist.append(f) + if not f in self.exec_types or not f in self.entry_types: + flist_non_exec.append(f) if f in self.fcdict: mpaths = mpaths + self.fcdict[f]["regex"] if len(mpaths) == 0: @@ -790,19 +774,20 @@ SELinux %(domainname)s policy is very flexible allowing users to setup their %(d .PP """ % {'domainname': self.domainname, 'equiv': e, 'alt': e.split('/')[-1]}) - self.fd.write(r""" + if flist_non_exec: + self.fd.write(r""" .PP .B STANDARD FILE CONTEXT SELinux defines the file context types for the %(domainname)s, if you wanted to store files with these types in a diffent paths, you need to execute the semanage command to sepecify alternate labeling and then use restorecon to put the labels on disk. -.B semanage fcontext -a -t %(type)s '/srv/%(domainname)s/content(/.*)?' +.B semanage fcontext -a -t %(type)s '/srv/my%(domainname)s_content(/.*)?' .br .B restorecon -R -v /srv/my%(domainname)s_content Note: SELinux often uses regular expressions to specify labels that match multiple files. -""" % {'domainname': self.domainname, "type": flist[0]}) +""" % {'domainname': self.domainname, "type": flist_non_exec[-1]}) self.fd.write(r""" .I The following file types are defined for %(domainname)s: @@ -921,8 +906,7 @@ This manual page was auto-generated using .B "sepolicy manpage". .SH "SEE ALSO" -selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8) -""" % (self.domainname)) +selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8)""" % (self.domainname)) if self.booltext != "": self.fd.write(", setsebool(8)") @@ -974,8 +958,7 @@ All executeables with the default executable label, usually stored in /usr/bin a %s""" % ", ".join(paths)) def _mcs_types(self): - mcs_constrained_type = next(sepolicy.info(sepolicy.ATTRIBUTE, "mcs_constrained_type")) - if self.type not in mcs_constrained_type['types']: + if self.type not in self.mcs_constrained_types['types']: return self.fd.write (""" .SH "MCS Constrained"