From 4254724cef739aa75e92c9ea5c1f6e68012a8fee Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Sun, 26 May 2013 07:00:33 -0400 Subject: [PATCH] Fix the name of the spec file generated in the build script - Add mgrepl patch to support argparse for semanage command parsing --- policycoreutils-rhat.patch | 9 +- policycoreutils-semanage.patch | 1256 ++++++++++++++++++++++++++++++++ policycoreutils.spec | 8 +- 3 files changed, 1268 insertions(+), 5 deletions(-) create mode 100644 policycoreutils-semanage.patch diff --git a/policycoreutils-rhat.patch b/policycoreutils-rhat.patch index 3f5008d..c174078 100644 --- a/policycoreutils-rhat.patch +++ b/policycoreutils-rhat.patch @@ -250741,7 +250741,7 @@ index a179d95..9b9a09a 100755 tlist = [] for l in map(lambda y: y[sepolicy.TARGET], filter(lambda x: set(perm).issubset(x[sepolicy.PERMS]), allows)): diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py -index 26f8390..837d3e3 100644 +index 26f8390..ce328e6 100644 --- a/policycoreutils/sepolicy/sepolicy/generate.py +++ b/policycoreutils/sepolicy/sepolicy/generate.py @@ -63,20 +63,6 @@ except IOError: @@ -250908,7 +250908,7 @@ index 26f8390..837d3e3 100644 newsh += re.sub("TEMPLATETYPE", self.name, t1) newsh += self.generate_user_sh() -+ newsh += re.sub("TEMPLATETYPE", self.name, script.rpm) ++ newsh += re.sub("TEMPLATEFILE", self.file_name, script.rpm) return newsh @@ -251462,7 +251462,7 @@ index 66efe26..a446d68 100755 tlist = get_types(src, "%s_socket" % protocol, [perm]) if len(tlist) > 0: diff --git a/policycoreutils/sepolicy/sepolicy/templates/script.py b/policycoreutils/sepolicy/sepolicy/templates/script.py -index c139070..54fd40a 100644 +index c139070..c79738b 100644 --- a/policycoreutils/sepolicy/sepolicy/templates/script.py +++ b/policycoreutils/sepolicy/sepolicy/templates/script.py @@ -66,14 +66,17 @@ set -x @@ -251477,7 +251477,8 @@ index c139070..54fd40a 100644 # Generate a rpm package for the newly generated policy pwd=$(pwd) - rpmbuild --define "_sourcedir ${pwd}" --define "_specdir ${pwd}" --define "_builddir ${pwd}" --define "_srcrpmdir ${pwd}" --define "_rpmdir ${pwd}" --define "_buildrootdir ${pwd}/.build" -ba TEMPLATETYPE_selinux.spec +-rpmbuild --define "_sourcedir ${pwd}" --define "_specdir ${pwd}" --define "_builddir ${pwd}" --define "_srcrpmdir ${pwd}" --define "_rpmdir ${pwd}" --define "_buildrootdir ${pwd}/.build" -ba TEMPLATETYPE_selinux.spec ++rpmbuild --define "_sourcedir ${pwd}" --define "_specdir ${pwd}" --define "_builddir ${pwd}" --define "_srcrpmdir ${pwd}" --define "_rpmdir ${pwd}" --define "_buildrootdir ${pwd}/.build" -ba TEMPLATEFILE_selinux.spec +""" +manpage="""\ diff --git a/policycoreutils-semanage.patch b/policycoreutils-semanage.patch new file mode 100644 index 0000000..f110952 --- /dev/null +++ b/policycoreutils-semanage.patch @@ -0,0 +1,1256 @@ +--- policycoreutils-2.1.14/semanage/semanage.old 2013-05-24 15:11:36.014601386 +0200 ++++ policycoreutils-2.1.14/semanage/semanage 2013-05-24 15:16:56.845299693 +0200 +@@ -1,5 +1,7 @@ + #! /usr/bin/python -Es +-# Copyright (C) 2005-2012 Red Hat ++# Copyright (C) 2012-2013 Red Hat ++# AUTHOR: Miroslav Grepl ++# AUTHOR: David Quigley + # see file 'COPYING' for use and warranty information + # + # semanage is a tool for managing SELinux configuration files +@@ -19,567 +21,689 @@ + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + # 02111-1307 USA + # +-# ++# ++ + import policycoreutils.default_encoding_utf8 +-import sys, getopt, re ++import argparse + import seobject + import selinux +-PROGNAME="policycoreutils" ++import sys + + import gettext +-gettext.bindtextdomain(PROGNAME, "/usr/share/locale") +-gettext.textdomain(PROGNAME) +- ++PROGNAME="policycoreutils" + try: +- gettext.install(PROGNAME, +- localedir="/usr/share/locale", +- unicode=True, +- codeset = 'utf-8') ++ gettext.install(PROGNAME, ++ localedir="/usr/share/locale", ++ unicode=False, ++ codeset = 'utf-8') ++ + except IOError: +- import __builtin__ +- __builtin__.__dict__['_'] = unicode ++ import __builtin__ ++ __builtin__.__dict__['_'] = unicode ++ ++# define custom usages for selected main actions ++usage_login = "semanage login [-h] [-n] [-N] [-s STORE] [" ++usage_login_dict = {' --add':('-s SEUSER','-r RANGE','LOGIN',),' --modify':('-s SEUSER','-r RANGE','LOGIN',),' --delete':('LOGIN',), ' --list':('-C',),' --extract':('',), ' --deleteall':('',)} ++ ++usage_fcontext = "semanage fcontext [-h] [-n] [-N] [-s STORE] [" ++usage_fcontext_dict = {' --add':('(','-t TYPE','-f FTYPE','-r RANGE','-s SEUSER', '|','-e EQUAL', ')','FILE_SPEC',')' ,),' --delete':('(','-t TYPE','-f FTYPE','|','-e EQUAL',')','FILE_SPEC', ')',),' --modify':('(','-t TYPE','-f FTYPE','-r RANGE','-s SEUSER','|','-e EQUAL',')','FILE_SPEC )',),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} ++ ++usage_user = "semanage fcontext [-h] [-n] [-N] [-s STORE] [" ++usage_user_dict = {' --add':('(','-L LEVEL','-P PREFIX','-R ROLES','-r RANGE','-s SEUSER','selinux_name'')'),' --delete':('selinux_name',),' --modify':('(','-L LEVEL','-P PREFIX','-R ROLES','-r RANGE','-s SEUSER','selinux_name',')'),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} ++ ++usage_port = "semanage port [-h] [-n] [-N] [-s STORE] [" ++usage_port_dict = {' --add':('-t TYPE','-p PROTOCOL','-r RANGE','port_name','|','port_range'),' --modify':('-t TYPE','-p PROTOCOL','-r RANGE','port_name','|','port_range'), ' --delete':('-p PROTOCOL', 'port_name','|','port_range'),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} ++ ++usage_node = "semanage node [-h] [-n] [-N] [-s STORE] [" ++usage_node_dict = {' --add':('-M NETMASK','-p PROTOCOL','-t TYPE','-r RANGE','node'),' --modify':('-M NETMASK','-p PROTOCOL','-t TYPE','-r RANGE','node'), ' --delete':('-M NETMASK','-p PROTOCOL','node'),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} ++ ++usage_interface = "semanage interface [-h] [-n] [-N] [-s STORE] [" ++usage_interface_dict = {' --add':('-t TYPE','-r RANGE','interface'),' --modify':('-t TYPE','-r RANGE','interface'), ' --delete':('interface',),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} ++ ++usage_boolean = "semanage boolean [-h] [-n] [-N] [-s STORE] [" ++usage_boolean_dict = {' --modify':('(','(','(','--on','|','--off',')','(','boolean',')',')','|','-F boolean_file',')',')'), ' --list':('-C',), ' --extract':('',), ' --deleteall':('',)} ++ ++store = '' ++class SetStore(argparse.Action): ++ def __call__(self, parser, namespace, values, option_string=None): ++ global store ++ store=values[0] ++ setattr(namespace, self.dest, values) ++ ++class seParser(argparse.ArgumentParser): ++ def error(self, message): ++ if len(sys.argv) == 2: ++ self.print_help() ++ sys.exit(2) ++ self.print_usage() ++ self.exit(2, ('%s: error: %s\n') % (self.prog, message)) ++ ++class SetExportFile(argparse.Action): ++ def __call__(self, parser, namespace, values, option_string=None): ++ if values is not None: ++ if values is not "-": ++ try: ++ sys.stdout = open(values, 'w') ++ except: ++ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) ++ sys.exit(1) ++ ++fd = None ++class SetImportFile(argparse.Action): ++ def __call__(self, parser, namespace, values, option_string=None): ++ global fd ++ if values != None: ++ if values == "-": ++ fd = sys.stdin ++ else: ++ try: ++ fd = open(values, 'r') ++ except IOError,e: ++ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) ++ sys.exit(1) ++ ++# 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 module_ini(): ++ OBJECT = seobject.moduleRecords(store) ++ return OBJECT ++ ++def interface_ini(): ++ OBJECT = seobject.nodeRecords(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} ++ ++def generate_custom_usage(usage_text,usage_dict): ++ # generate custom usage from given text and dictonary ++ sorted_keys = [] ++ for i in usage_dict.keys(): ++ sorted_keys.append(i) ++ sorted_keys.sort() ++ for k in sorted_keys: ++ usage_text += "%s %s |" % (k,(" ".join(usage_dict[k]))) ++ usage_text = usage_text[:-1] + "]" ++ usage_text = _(usage_text) ++ ++ return usage_text ++ ++def handle_opts(args,dict,target_key): ++ # handle conflict and required options for given dictonary ++ # {action:[conflict_opts,require_opts]} ++ ++ # first we need to catch conflicts ++ for k in args.__dict__.keys(): ++ try: ++ if k in dict[target_key][0] and args.__dict__[k]: ++ print("%s option can not be used with --%s" % (target_key,k)) ++ sys.exit(2) ++ except KeyError: ++ continue ++ ++ for k in args.__dict__.keys(): ++ try: ++ if k in dict[target_key][1] and not args.__dict__[k]: ++ print("%s option is needed for %s" % (k,target_key)) ++ sys.exit(2) ++ except KeyError: ++ continue ++ ++def handleLogin(args): ++ # {action:[conflict_opts,require_opts]} ++ login_args = {'list':[('login','range','seuser'),('')],'add':[('locallist'),('seuser','login')],'modify':[('locallist'),('seuser','login')], 'delete':[('locallist'),('seuser','login')],'extract':[('locallist','login','range','seuser'),('')],'deleteall':[('locallist','login','range','seuser'),('')]} ++ ++ handle_opts(args,login_args,args.action) ++ ++ OBJECT = object_dict['login']() ++ OBJECT.set_reload(args.noreload) ++ ++ if args.action is "add": ++ OBJECT.add(args.login, args.seuser[0], args.range) ++ if args.action is "modify": ++ OBJECT.modify(args.login, args.seuser[0], args.range) ++ if args.action is "delete": ++ OBJECT.delete(args.login) ++ if args.action is "list": ++ OBJECT.list(args.noheading, args.locallist) ++ if args.action is "deleteall": ++ OBJECT.deleteall() ++ if args.action is "extract": ++ for i in OBJECT.customized(): ++ print "%s %s" % (object, str(i)) ++ ++def setupLoginParser(subparsers): ++ generated_usage = generate_custom_usage(usage_login, usage_login_dict) ++ loginParser = subparsers.add_parser('login', usage=generated_usage, help=_("Manage login mappings between linux users and SELinux confined users")) ++ loginParser.add_argument('-n', '--noheading', action='store_false', default=True, help=_("Do not print heading when listing the specified object type")) ++ loginParser.add_argument('-N', '--noreload', action='store_false', default=False, help=_("Do not reload policy after commit")) ++ loginParser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List OBJECTS local customizations")) ++ loginParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_("Select an alternate SELinux Policy Store to manage")) ++ ++ login_action = loginParser.add_mutually_exclusive_group(required=True) ++ login_action.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_("Add a record of the specified object type")) ++ login_action.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_("Delete a record of the specified object type")) ++ login_action.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_("Modify a record of the specified object type")) ++ login_action.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_("List records of the specified object type")) ++ login_action.add_argument('-E', '--extract', dest='action', action='store_const', const='extract', help=_("Extract customizable commands, for use within a transaction")) ++ login_action.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_("Remove all OBJECTS local customizations")) ++ ++ loginParser.add_argument('-s', '--seuser', nargs=1, help=_("SELinux user name")) ++ loginParser.add_argument('-r', '--range', nargs=1, default="", help=_('''MLS/MCS Security Range (MLS/MCS Systems only) ++ SELinux Range for SELinux login mapping ++ defaults to the SELinux user record range. ++ SELinux Range for SELinux user defaults to s0.''')) ++ loginParser.add_argument('login', nargs='?', default=None, help=_("login_name | %%groupname")) ++ loginParser.set_defaults(func=handleLogin) ++ ++def handleFcontext(args): ++ fcontext_args = {'list':[('equal','ftype','range','seuser','type'),('')],'add':[('locallist'),('type','file_spec')],'modify':[('locallist'),('type','file_spec')], 'delete':[('locallist'),('type','file_spec')],'extract':[('locallist','equal','ftype','range','seuser','type'),('')],'deleteall':[('locallist','equal','ftype','range','seuser','type'),('')]} ++ # we can not use mutually for equal because we can define some actions together with equal ++ fcontext_equal_args = {'equal':[('list','locallist','type','ftype','range','seuser','deleteall','extract'),('add','modify','delete','file_spec')]} ++ ++ if args.action is None: ++ print("usage: "+"%s" % generate_custom_usage(usage_fcontext, usage_fcontext_dict)) ++ sys.exit(2) ++ elif args.action and args.equal: ++ handle_opts(args, fcontext_equal_args, "equal") ++ else: ++ handle_opts(args, fcontext_args, args.action) ++ ++ OBJECT = object_dict['fcontext']() ++ OBJECT.set_reload(args.noreload) ++ ++ if args.action is "add": ++ if args.equal: ++ OBJECT.add_equal(args.file_spec, args.equal[0]) ++ else: ++ OBJECT.add(args.file_spec, args.type[0], args.ftype, args.seuser, args.range) ++ if args.action is "modify": ++ if args.equal: ++ OBJECT.add_equal(args.file_spec, args.equal[0]) ++ else: ++ OBJECT.modify(args.file_spec, args.type[0], args.ftype, args.seuser, args.range) ++ if args.action is "delete": ++ if args.equal: ++ OBJECT.delete(args.file_spec, args.equal[0]) ++ else: ++ OBJECT.delete(args.file_spec,args.ftype) ++ if args.action is "list": ++ OBJECT.list(args.noheading, args.locallist) ++ if args.action is "deleteall": ++ OBJECT.deleteall() ++ if args.action is "extract": ++ for i in OBJECT.customized(): ++ print "%s %s" % (object, str(i)) ++ ++def setupFcontextParser(subparsers): ++ ftype_help = ''' ++File Type. This is used with fcontext. Requires a file type ++as shown in the mode field by ls, e.g. use -d to match only ++directories or -- to match only regular files. The following ++file type options can be passed: ++"" (all files),-- (regular file),-d (directory),-c (character device), ++-b (block device),-s (socket),-l (symbolic link),-p (named pipe) ++''' ++ generate_usage = generate_custom_usage(usage_fcontext, usage_fcontext_dict) ++ fcontextParser = subparsers.add_parser('fcontext',usage=generate_usage, help=_("Manage file context mapping definitions")) ++ fcontextParser.add_argument('-n', '--noheading', action='store_false', default=True, help=_("Do not print heading when listing the specified object type")) ++ fcontextParser.add_argument('-N', '--noreload', action='store_false', default=False, help=_("Do not reload policy after commit")) ++ fcontextParser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List OBJECTS local customizations")) ++ fcontextParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ ++ fcontext_action = fcontextParser.add_mutually_exclusive_group(required=False) ++ fcontext_action.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_('Add a record of the specified object type')) ++ fcontext_action.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_('Delete a record of the specified object type')) ++ fcontext_action.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_('Modify a record of the specified object type')) ++ fcontext_action.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_('List records of the specified object type')) ++ fcontext_action.add_argument('-E', '--extract', dest='action', action='store_const', const='extract', help=_('Extract customizable commands, for use within a transaction')) ++ fcontext_action.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all OBJECTS local customizations')) ++ ++ fcontextParser.add_argument('-e', '--equal', nargs=1, help=_('''Substitute target path with sourcepath when generating default ++ label. This is used with fcontext. Requires source and target ++ path arguments. The context labeling for the target subtree is ++ made equivalent to that defined for the source.''')) ++ fcontextParser.add_argument('-f', '--ftype', nargs='?', default="", choices=['""',"--","-d","-c","-b","-s","-l","-p"], help=_(ftype_help)) ++ fcontextParser.add_argument('-s', '--seuser', nargs=1, default="", help=_('SELinux user name')) ++ fcontextParser.add_argument('-t', '--type', nargs=1, help=_('SELinux Type for the object')) ++ fcontextParser.add_argument('-r', '--range', nargs=1, default="", help=_('''MLS/MCS Security Range (MLS/MCS Systems only) SELinux Range for ++ SELinux login mapping defaults to the SELinux user record range. ++ SELinux Range for SELinux user defaults to s0.''')) ++ fcontextParser.add_argument('file_spec', nargs='?', default=None, help=_('file_spec')) ++ fcontextParser.set_defaults(func=handleFcontext) ++ ++def handleUser(args): ++ user_args = {'list':[('selinux_name','range','seuser','level','roles'),('')],'add':[('locallist'),('roles','selinux_name')],'modify':[('locallist'),('roles','selinux_name')], 'delete':[('locallist'),('selinux_name')],'extract':[('locallist','selinux_name','range','seuser','level','role'),('')],'deleteall':[('locallist','selinux_name','range','seuser','level','roles'),('')]} ++ ++ handle_opts(args,user_args,args.action) ++ ++ OBJECT = object_dict['user']() ++ OBJECT.set_reload(args.noreload) ++ ++ if args.action is "add": ++ OBJECT.add(args.selinux_name, args.roles.split(), args.level, args.range, args.prefix) ++ if args.action is "modify": ++ OBJECT.modify(args.selinux_name, args.roles.split(), args.level, args.range, args.prefix) ++ if args.action is "delete": ++ OBJECT.delete(args.selinux_name) ++ if args.action is "list": ++ OBJECT.list(args.noheading, args.locallist) ++ if args.action is "deleteall": ++ OBJECT.deleteall() ++ if args.action is "extract": ++ for i in OBJECT.customized(): ++ print "%s %s" % (object, str(i)) ++ ++def setupUserParser(subparsers): ++ generated_usage = generate_custom_usage(usage_user, usage_user_dict) ++ userParser = subparsers.add_parser('user', usage=generated_usage,help=_('Manage SELinux confined users (Roles and levels for an SELinux user)')) ++ userParser.add_argument('-n', '--noheading', action='store_false', default=True, help=_('Do not print heading when listing the specified object type')) ++ userParser.add_argument('-N', '--noreload', action='store_false', default=False, help=_('Do not reload policy after commit')) ++ userParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ userParser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List OBJECTS local customizations")) ++ ++ user_action = userParser.add_mutually_exclusive_group(required=True) ++ user_action.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_('Add a record of the specified object type')) ++ user_action.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_('Delete a record of the specified object type')) ++ user_action.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_('Modify a record of the specified object type')) ++ user_action.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_('List records of the specified object type')) ++ user_action.add_argument('-E', '--extract', dest='action', action='store_const', const='extract', help=_('Extract customizable commands, for use within a transaction')) ++ user_action.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all OBJECTS local customizations')) ++ ++ userParser.add_argument('-L', '--level', nargs=1, default="", help=_('Default SELinux Level for SELinux user, s0 Default. (MLS/MCS Systems only)')) ++ userParser.add_argument('-r', '--range', nargs=1, default="", help=_('''MLS/MCS Security Range (MLS/MCS Systems only) SELinux ++ Range for SELinux login mapping defaults to the SELinux ++ user record range. SELinux Range for SELinux user defaults ++ to s0.''')) ++ userParser.add_argument('-R', '--roles', nargs='?', default="", help=_('''SELinux Roles. You must enclose multiple roles within quotes, ++ separate by spaces. Or specify -R multiple times.''')) ++ userParser.add_argument('-P', '--prefix', nargs=1, default="user", help=_('''SELinux Prefix. Prefix added to home_dir_t and home_t for ++ labeling users home directories.''')) ++ userParser.add_argument('selinux_name',nargs='?', default=None, help=_('selinux_name')) ++ userParser.set_defaults(func=handleUser) ++ ++def handlePort(args): ++ port_args = {'list':[('port','range','type','proto'),('')],'add':[('locallist'),('type','port','proto')],'modify':[('localist'),('type','port','proto')], 'delete':[('locallist'),('port','proto')],'extract':[('locallist','port','range','type','proto'),('')],'deleteall':[('locallist','port','range','type','proto'),('')]} ++ ++ handle_opts(args,port_args,args.action) ++ ++ OBJECT = object_dict['port']() ++ OBJECT.set_reload(args.noreload) ++ ++ if args.action is "add": ++ OBJECT.add(args.port, args.proto[0], args.range, args.type[0]) ++ if args.action is "modify": ++ OBJECT.modify(args.port, args.proto[0], args.range, args.type[0]) ++ if args.action is "delete": ++ OBJECT.delete(args.port, args.proto[0]) ++ if args.action is "list": ++ OBJECT.list(args.noheading, args.locallist) ++ if args.action is "deleteall": ++ OBJECT.deleteall() ++ if args.action is "extract": ++ for i in OBJECT.customized(): ++ print "%s %s" % (object, str(i)) ++ ++def setupPortParser(subparsers): ++ generated_usage = generate_custom_usage(usage_port, usage_port_dict) ++ portParser = subparsers.add_parser('port', usage=generated_usage, help=_('Manage network port type definitions')) ++ portParser.add_argument('-n', '--noheading', action='store_false', default=True, help=_('Do not print heading when listing the specified object type')) ++ portParser.add_argument('-N', '--noreload', action='store_false', default=False, help=_('Do not reload policy after commit')) ++ portParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ portParser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List OBJECTS local customizations")) ++ ++ port_action = portParser.add_mutually_exclusive_group(required=True) ++ port_action.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_('Add a record of the specified object type')) ++ port_action.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_('Delete a record of the specified object type')) ++ port_action.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_('Modify a record of the specified object type')) ++ port_action.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_('List records of the specified object type')) ++ port_action.add_argument('-E', '--extract', dest='action', action='store_const', const='extract', help=_('Extract customizable commands, for use within a transaction')) ++ port_action.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all OBJECTS local customizations')) ++ portParser.add_argument('-t', '--type', nargs=1, help=_('SELinux type for the object')) ++ portParser.add_argument('-r', '--range', nargs=1, default="", help=_('''MLS/MCS Security Range (MLS/MCS Systems only) SELinux ++ Range for SELinux login mapping defaults to the SELinux ++ user record range. SELinux Range for SELinux user defaults ++ to s0.''')) ++ portParser.add_argument('-p', '--proto', nargs=1, help=_('''Protocol for the specified port (tcp|udp) or internet protocol ++ version for the specified node (ipv4|ipv6).''')) ++ portParser.add_argument('port', nargs='?', default=None, help=_('port | port_range')) ++ portParser.set_defaults(func=handlePort) ++ ++def handleInterface(args): ++ interface_args = {'list':[('interface','range'),('')],'add':[('locallist'),('type','interface')],'modify':[('locallist'),('type','interface')], 'delete':[('locallist'),('type','interface')],'extract':[('locallist','interface','range','type'),('')],'deleteall':[('locallist','interface','range','type'),('')]} ++ ++ handle_opts(args,interface_args,args.action) ++ ++ OBJECT = object_dict['interface']() ++ OBJECT.set_reload(args.noreload) ++ ++ if args.action is "add": ++ OBJECT.add(args.interface, args.range, args.type[0]) ++ if args.action is "modify": ++ OBJECT.add(args.interface, args.range, args.type[0]) ++ if args.action is "delete": ++ OBJECT.delete(args.interface) ++ if args.action is "list": ++ OBJECT.list(args.noheading, args.locallist) ++ if args.action is "deleteall": ++ OBJECT.deleteall() ++ if args.action is "extract": ++ for i in OBJECT.customized(): ++ print "%s %s" % (object, str(i)) ++ ++def setupInterfaceParser(subparsers): ++ generated_usage = generate_custom_usage(usage_interface, usage_interface_dict) ++ interfaceParser = subparsers.add_parser('interface', usage=generated_usage, help=_('Manage network interface type definitions')) ++ interfaceParser.add_argument('-n', '--noheading', action='store_false', default=True, help=_('Do not print heading when listing the specified object type')) ++ interfaceParser.add_argument('-N', '--noreload', action='store_false', default=False, help=_('Do not reload policy after commit')) ++ interfaceParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ interfaceParser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List OBJECTS local customizations")) ++ ++ interface_action = interfaceParser.add_mutually_exclusive_group(required=True) ++ interface_action.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_('Add a record of the specified object type')) ++ interface_action.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_('Delete a record of the specified object type')) ++ interface_action.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_('Modify a record of the specified object type')) ++ interface_action.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_('List records of the specified object type')) ++ interface_action.add_argument('-E', '--extract', dest='action', action='store_const', const='extract', help=_('Extract customizable commands, for use within a transaction')) ++ interface_action.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all OBJECTS local customizations')) ++ ++ interfaceParser.add_argument('-t', '--type', nargs=1, help=_('SELinux type for the object')) ++ interfaceParser.add_argument('-r', '--range', nargs=1, help=_('''MLS/MCS Security Range (MLS/MCS Systems only) SELinux ++ Range for SELinux login mapping defaults to the SELinux ++ user record range. SELinux Range for SELinux user defaults ++ to s0.''')) ++ interfaceParser.add_argument('interface', nargs='?', default=None, help=_('interface_spec')) ++ interfaceParser.set_defaults(func=handleInterface) ++ ++def handleModule(args): ++ OBJECT = seobject.moduleRecords(args.store) ++ OBJECT.set_reload(args.noreload) ++ ++ if args.action is "add": ++ OBJECT.add(args.module) ++ if args.action is "enable": ++ OBJECT.enable(args.module) ++ if args.action is "disable": ++ OBJECT.disable(args.module) ++ if args.action is "delete": ++ OBJECT.delete(args.module) ++ if args.action is "list": ++ OBJECT.list(args.noheading) ++ ++def setupModuleParser(subparsers): ++ moduleParser = subparsers.add_parser('module', help=_('Manage SELinux policy modules')) ++ moduleParser.add_argument('-n', '--noheading', action='store_false', default=True, help=_('Do not print heading when listing the specified object type')) ++ moduleParser.add_argument('-N', '--noreload', action='store_false', default=False, help=_('Do not reload policy after commit')) ++ moduleParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ ++ mgroup = moduleParser.add_mutually_exclusive_group(required=True) ++ mgroup.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_('Add a record of the specified object type')) ++ mgroup.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_('Delete a record of the specified object type')) ++ mgroup.add_argument('-m', '--modify', dest='action', choices=['enable', 'disable'], help=_('Enable or Disable specified module')) ++ mgroup.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_('List records of the specified object type')) ++ ++ moduleParser.add_argument('module_name', nargs='?', default=None, help=_('Name of the module to act on')) ++ moduleParser.set_defaults(func=handleModule) ++ ++def handleNode(args): ++ node_args = {'list':[('node','range','type','proto','mask'),('')],'add':[('locallist'),('type','node','proto','mask')],'modify':[('locallist'),('type','node','mask','proto')], 'delete':[('locallist'),('type','node','mask')],'extract':[('locallist','node','range','type','proto','mask'),('')],'deleteall':[('locallist','node','range','type','proto','mask'),('')]} ++ handle_opts(args,node_args,args.action) ++ ++ OBJECT = object_dict['node']() ++ OBJECT.set_reload(args.noreload) ++ ++ if args.action is "add": ++ OBJECT.add(args.node, args.mask[0], args.proto[0], args.range, args.type[0]) ++ if args.action is "modify": ++ OBJECT.add(args.node, args.mask[0], args.proto[0], args.range, args.type[0]) ++ if args.action is "delete": ++ OBJECT.delete(args.node, args.mask[0], args.proto[0]) ++ if args.action is "list": ++ OBJECT.list(args.noheading, args.locallist) ++ if args.action is "deleteall": ++ OBJECT.deleteall() ++ if args.action is "extract": ++ for i in OBJECT.customized(): ++ print "%s %s" % (object, str(i)) ++ ++def setupNodeParser(subparsers): ++ generated_usage = generate_custom_usage(usage_node, usage_node_dict) ++ nodeParser = subparsers.add_parser('node', usage=generated_usage, help=_('Manage network node type definitions')) ++ nodeParser.add_argument('-n', '--noheading', action='store_false', default=True, help=_('Do not print heading when listing the specified object type')) ++ nodeParser.add_argument('-N', '--noreload', action='store_false', default=False, help=_('Do not reload policy after commit')) ++ nodeParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ nodeParser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List OBJECTS local customizations")) ++ ++ node_action = nodeParser.add_mutually_exclusive_group(required=True) ++ node_action.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_('Add a record of the specified object type')) ++ node_action.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_('Delete a record of the specified object type')) ++ node_action.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_('Modify a record of the specified object type')) ++ node_action.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_('List records of the specified object type')) ++ node_action.add_argument('-E', '--extract', dest='action', action='store_const', const='extract', help=_('Extract customizable commands, for use within a transaction')) ++ node_action.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all OBJECTS local customizations')) ++ ++ nodeParser.add_argument('-M', '--netmask', nargs=1, help=_('Network Mask')) ++ nodeParser.add_argument('-t', '--type', nargs=1, help=_('SELinux type for the object')) ++ nodeParser.add_argument('-r', '--range', nargs=1, default="", help=_('''MLS/MCS Security Range (MLS/MCS Systems only) SELinux ++ Range for SELinux login mapping defaults to the SELinux ++ user record range. SELinux Range for SELinux user defaults ++ to s0.''')) ++ nodeParser.add_argument('-p', '--proto', nargs=1, help=_('''Protocol for the specified port (tcp|udp) or internet protocol ++ version for the specified node (ipv4|ipv6).''')) ++ nodeParser.add_argument('node',nargs='?', default=None, help=_('node')) ++ nodeParser.set_defaults(func=handleNode) ++ ++def handleBoolean(args): ++ boolean_args = {'list':[('state','filename','boolean'),('')],'modify':[('localist'),('')], 'extract':[('locallist','state','filename','boolean'),('')],'deleteall':[('locallist','state','filename','boolean'),('')],'state':[('locallist','list','extract','deleteall'),('modify')]} ++ if args.action is None: ++ print("Usage: "+"%s" % generate_custom_usage(usage_boolean, usage_boolean_dict)) ++ sys.exit(2) ++ # TODO: should be added to handle_opts logic ++ elif args.action is "modify" and not (args.boolean or args.filename) : ++ print "Either boolean or boolean_file is needed" ++ sys.exit(1) ++ elif args.action is "modify" and args.boolean and not args.state: ++ print "state option is needed" ++ sys.exit(1) ++ else: ++ handle_opts(args,boolean_args,args.action) ++ ++ OBJECT = object_dict['boolean']() ++ OBJECT.set_reload(args.noreload) ++ ++ if args.action is "modify": ++ if args.boolean: ++ OBJECT.modify(args.boolean, args.state, False) ++ if args.filename: ++ OBJECT.modify(args.filename[0], args.state, True) ++ if args.action is "list": ++ OBJECT.list(args.noheading, args.locallist) ++ if args.action is "deleteall": ++ OBJECT.deleteall() ++ if args.action is "extract": ++ for i in OBJECT.customized(): ++ print "%s %s" % (object, str(i)) ++ ++def setupBooleanParser(subparsers): ++ generated_usage = generate_custom_usage(usage_boolean, usage_boolean_dict) ++ booleanParser = subparsers.add_parser('boolean',usage=generated_usage, help=_('Manage booleans to selectively enable functionality')) ++ booleanParser.add_argument('-n', '--noheading', action='store_false', default=True, help=_('Do not print heading when listing the specified object type')) ++ booleanParser.add_argument('-N', '--noreload', action='store_false', default=False, help=_('Do not reload policy after commit')) ++ booleanParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ booleanParser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List OBJECTS local customizations")) ++ ++ boolean_action = booleanParser.add_mutually_exclusive_group(required=False) ++ #boolean_action.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_('Add a record of the specified object type') ++ boolean_action.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_('Delete a record of the specified object type')) ++ boolean_action.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_('Modify a record of the specified object type')) ++ boolean_action.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_('List records of the specified object type')) ++ boolean_action.add_argument('-E', '--extract', dest='action', action='store_const', const='extract', help=_('Extract customizable commands, for use within a transaction')) ++ boolean_action.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all OBJECTS local customizations')) ++ ++ booleanGroup = booleanParser.add_mutually_exclusive_group(required=False) ++ booleanGroup.add_argument('-1', '--on', dest='state', action='store_const', const='on', help=_('Enable the boolean')) ++ booleanGroup.add_argument('-0', '--off', dest='state', action='store_const', const='off', help=_('Disable the boolean')) ++ ++ booleanTarget = booleanParser.add_mutually_exclusive_group(required=False) ++ booleanTarget.add_argument('-F', '--file', nargs=1, dest='filename', help=_('''Set multiple records from the input file. When used with the -l ++ --list, it will output the current settings to stdout in the ++ proper format. (Currently booleans only)''')) ++ booleanTarget.add_argument('boolean', nargs='?', default=None, help=_('boolean | boolean_file')) ++ booleanParser.set_defaults(func=handleBoolean) ++ ++def handlePermissive(args): ++ OBJECT = object_dict['permissive']() ++ OBJECT.set_reload(args.noreload) ++ ++ if args.action is "add": ++ OBJECT.add(args.type) ++ if args.action is "list": ++ OBJECT.list(args.noheading) ++ if args.action is "delete": ++ OBJECT.delete(args.type) ++ ++def setupPermissiveParser(subparsers): ++ permissiveParser = subparsers.add_parser('permissive', help=_('Manage process type enforcement mode')) ++ ++ pgroup = permissiveParser.add_mutually_exclusive_group(required=True) ++ pgroup.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_('Add a record of the specified object type')) ++ pgroup.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_('Delete a record of the specified object type')) ++ pgroup.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_('List records of the specified object type')) ++ #TODO: probably should be also added => need to implement own option handling ++ #pgroup.add_argument('-D', '--deleteall', action='store_true', help=_('Remove all local customizations for the specified object type') ++ ++ permissiveParser.add_argument('-n', '--noheading', action='store_true', help=_('Do not print heading when listing the specified object type')) ++ permissiveParser.add_argument('-N', '--noreload', action='store_true', help=_('Do not reload the policy after commit')) ++ permissiveParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ permissiveParser.add_argument('type', nargs='?', default=None, help=_('type')) ++ permissiveParser.set_defaults(func=handlePermissive) ++ ++def handleDontaudit(args): ++ OBJECT = object_dict['dontaudit']() ++ OBJECT.set_reload(args.noreload) ++ OBJECT.toggle(args.action) ++ ++def setupDontauditParser(subparsers): ++ dontauditParser = subparsers.add_parser('dontaudit', help=_('Disable/Enable dontaudit rules in policy')) ++ dontauditParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ dontauditParser.add_argument('action', choices=["on", "off"]) ++ dontauditParser.set_defaults(func=handleDontaudit) ++ ++def handleExport(args): ++ manageditems=[ "boolean", "login", "interface", "user", "port", "node", "fcontext"] ++ for i in manageditems: ++ OBJECT = object_dict[i]() ++ print "semanage %s -E" % i ++ for i in OBJECT.customized(): ++ print "%s %s" % (object, str(i)) ++ ++ sys.exit(0) ++ ++def setupExportParser(subparsers): ++ exportParser = subparsers.add_parser('export', help=_('Output local customizations')) ++ exportParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ exportParser.add_argument('-f', '--output_file', dest='output_file', action=SetExportFile, help=_('Output file')) ++ exportParser.set_defaults(func=handleExport) ++ ++def handleImport(args): ++ trans = seobject.semanageRecords(store) ++ trans.start() ++ ++ for l in fd.readlines(): ++ try: ++ commandParser = createCommandParser() ++ args = commandParser.parse_args(l.split()) ++ args.func(args) ++ except ValueError,e: ++ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) ++ sys.exit(1) ++ except IOError,e: ++ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) ++ sys.exit(1) ++ except KeyboardInterrupt: ++ sys.exit(0) ++ ++ trans.set_reload(args.noreload) ++ trans.finish() ++ fd.close() ++ ++def setupImportParser(subparsers): ++ importParser = subparsers.add_parser('import', help=_('Output local customizations')) ++ importParser.add_argument('-N', '--noreload', action='store_false', default=False, help=_('Do not reload policy after commit')) ++ importParser.add_argument('-S', '--store', nargs=1, action=SetStore, help=_('Select an alternate SELinux Policy Store to manage')) ++ importParser.add_argument('-f', '--input_file', dest='input_file', action=SetImportFile, help=_('Input file')) ++ importParser.set_defaults(func=handleImport) ++ ++def createCommandParser(): ++ commandParser = seParser(prog='semanage', ++ formatter_class=argparse.ArgumentDefaultsHelpFormatter, ++ description='''semanage is used to configure certain elements ++ of SELinux policy with-out requiring modification ++ to or recompilation from policy source.''') ++ ++ #To add a new subcommand define the parser for it in a function above and call it here. ++ subparsers = commandParser.add_subparsers(dest='subcommand') ++ setupImportParser(subparsers) ++ setupExportParser(subparsers) ++ setupLoginParser(subparsers) ++ setupUserParser(subparsers) ++ setupPortParser(subparsers) ++ setupInterfaceParser(subparsers) ++ setupModuleParser(subparsers) ++ setupNodeParser(subparsers) ++ setupFcontextParser(subparsers) ++ setupBooleanParser(subparsers) ++ setupPermissiveParser(subparsers) ++ setupDontauditParser(subparsers) ++ ++ return commandParser ++ ++def do_parser(): ++ try: ++ commandParser = createCommandParser() ++ args = commandParser.parse_args() ++ args.func(args) ++ sys.exit(0) ++ except ValueError,e: ++ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) ++ sys.exit(1) ++ except IOError,e: ++ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) ++ sys.exit(1) ++ except KeyboardInterrupt: ++ sys.exit(0) + + if __name__ == '__main__': +- manageditems=[ "boolean", "login", "user", "port", "interface", "node", "fcontext"] +- action = False +- load = True +- def set_action(option): +- global action +- if action: +- raise ValueError(_("%s bad option") % option) +- action = True +- +- def usage(message = ""): +- text = _(""" +-semanage [ -S store ] -i [ input_file | - ] +-semanage [ -S store ] -o [ output_file | - ] +- +-semanage login -{a|d|m|l|D|E} [-Nnsr] login_name | %groupname +-semanage user -{a|d|m|l|D|E} [-LNnrRP] selinux_name +-semanage port -{a|d|m|l|D|E} [-Nntr] [ -p proto ] port | port_range +-semanage interface -{a|d|m|l|D|E} [-Nntr] interface_spec +-semanage module -{a|d|m} [--enable|--disable] [-N] module +-semanage node -{a|d|m|l|D|E} [-Nntr] [ -p protocol ] [-M netmask] addr +-semanage fcontext -{a|d|m|l|D|E} [-Nefnrst] file_spec +-semanage boolean -{d|m} {--on|--off|-1|-0} [-N] -F boolean | boolean_file +-semanage permissive -{d|a|l} [-Nn] type +-semanage dontaudit [ on | off ] [-N] +- +-Primary Options: +- +- -a, --add Add a OBJECT record NAME +- -d, --delete Delete a OBJECT record NAME +- -m, --modify Modify a OBJECT record NAME +- -i, --input Input multiple semange commands in a transaction +- -o, --output Output current customizations as semange commands +- -l, --list List the OBJECTS +- -E, --extract Extract customizable commands, for use within a transaction +- -C, --locallist List OBJECTS local customizations +- -D, --deleteall Remove all OBJECTS local customizations +- +- -h, --help Display this message +- -n, --noheading Do not print heading when listing OBJECTS +- -S, --store Select and alternate SELinux store to manage +- +-Object-specific Options (see above): +- +- -f, --ftype File Type of OBJECT +- "" (all files) +- -- (regular file) +- -d (directory) +- -c (character device) +- -b (block device) +- -s (socket) +- -l (symbolic link) +- -p (named pipe) +- +- -F, --file Treat target as an input file for command, change multiple settings +- -p, --proto Port protocol (tcp or udp) or internet protocol version of node (ipv4 or ipv6) +- -M, --mask Netmask +- -N, --noreload Do not reload policy after commit +- -e, --equal Substitue source path for dest path when labeling +- -P, --prefix Prefix for home directory labeling +- -L, --level Default SELinux Level (MLS/MCS Systems only) +- -R, --roles SELinux Roles (ex: "sysadm_r staff_r") +- -s, --seuser SELinux User Name +- -t, --type SELinux Type for the object +- -r, --range MLS/MCS Security Range (MLS/MCS Systems only) +- --enable Enable a module +- --disable Disable a module +-""") +- raise ValueError("%s\n%s" % (text, message)) +- +- def errorExit(error): +- sys.stderr.write("%s: " % sys.argv[0]) +- sys.stderr.write("%s\n" % error) +- sys.stderr.flush() +- sys.exit(1) +- +- def get_options(): +- valid_option={} +- valid_everyone=[ '-a', '--add', '-d', '--delete', '-m', '--modify', '-l', '--list', '-h', '--help', '-n', '--noheading', '-S', '--store' ] +- valid_local=[ '-E', '--extract', '-C', '--locallist', '-D', '--deleteall', '-N', '--noreload'] +- valid_option["login"] = [] +- valid_option["login"] += valid_everyone + valid_local + [ '-s', '--seuser', '-r', '--range'] +- valid_option["user"] = [] +- valid_option["user"] += valid_everyone + valid_local + [ '-L', '--level', '-r', '--range', '-R', '--roles', '-P', '--prefix', '-N', '--noreload' ] +- valid_option["port"] = [] +- valid_option["port"] += valid_everyone + valid_local + [ '-t', '--type', '-r', '--range', '-p', '--proto' , '-N', '--noreload' ] +- valid_option["interface"] = [] +- valid_option["interface"] += valid_everyone + valid_local + [ '-t', '--type', '-r', '--range', '-N', '--noreload' ] +- valid_option["node"] = [] +- valid_option["node"] += valid_everyone + valid_local + [ '-M', '--mask', '-t', '--type', '-r', '--range', '-p', '--protocol', '-N', '--noreload' ] +- valid_option["module"] = [] +- valid_option["module"] += valid_everyone + [ '--enable', '--disable', '-N', '--noreload' ] +- valid_option["fcontext"] = [] +- valid_option["fcontext"] += valid_everyone + valid_local + [ '-e', '--equal', '-f', '--ftype', '-s', '--seuser', '-t', '--type', '-r', '--range', '-N', '--noreload' ] +- valid_option["dontaudit"] = [ '-S', '--store' ] +- valid_option["boolean"] = [] +- valid_option["boolean"] += valid_everyone + valid_local + [ '--on', "--off", "-1", "-0", "-F", "--file", '-N', '--noreload' ] +- valid_option["permissive"] = [] +- valid_option["permissive"] += [ '-a', '--add', '-d', '--delete', '-l', '--list', '-h', '--help', '-n', '--noheading', '-D', '--deleteall' , '-N', '--noreload' ] +- return valid_option +- +- def mkargv(line): +- dquote = "\"" +- squote = "\'" +- l = line.split() +- ret = [] +- i = 0 +- while i < len(l): +- cnt = len(re.findall(dquote, l[i])) +- if cnt > 1: +- ret.append(l[i].strip(dquote)) +- i = i + 1 +- continue +- if cnt == 1: +- quote = [ l[i].strip(dquote) ] +- i = i + 1 +- +- while i < len(l) and dquote not in l[i]: +- quote.append(l[i]) +- i = i + 1 +- quote.append(l[i].strip(dquote)) +- ret.append(" ".join(quote)) +- i = i + 1 +- continue +- +- cnt = len(re.findall(squote, l[i])) +- if cnt > 1: +- ret.append(l[i].strip(squote)) +- i = i + 1 +- continue +- if cnt == 1: +- quote = [ l[i].strip(squote) ] +- i = i + 1 +- while i < len(l) and squote not in l[i]: +- quote.append(l[i]) +- i = i + 1 +- +- quote.append(l[i].strip(squote)) +- ret.append(" ".join(quote)) +- i = i + 1 +- continue +- +- ret.append(l[i]) +- i = i + 1 +- +- return ret +- +- def process_args(argv): +- global action +- global load +- action = False +- serange = "" +- port = "" +- proto = "" +- mask = "" +- selevel = "" +- setype = "" +- ftype = "" +- roles = "" +- seuser = "" +- prefix = "user" +- heading = True +- value = None +- add = False +- modify = False +- delete = False +- deleteall = False +- enable = False +- extract = False +- disable = False +- list = False +- locallist = False +- use_file = False +- store = "" +- equal = "" +- +- if len(argv) == 0: +- return +- object = argv[0] +- option_dict=get_options() +- if object not in option_dict.keys(): +- usage(_("Invalid parameter %s not defined") % object) +- +- args = argv[1:] +- +- try: +- gopts, cmds = getopt.getopt(args, +- '01adEe:f:i:lhmNnp:s:FCDR:L:r:t:P:S:M:', +- ['add', +- 'delete', +- 'deleteall', +- 'enable', +- 'equal=', +- 'extract', +- 'disable', +- 'ftype=', +- 'file', +- 'help', +- 'input=', +- 'list', +- 'modify', +- 'noheading', +- 'noreload', +- 'off', +- 'on', +- 'proto=', +- 'seuser=', +- 'store=', +- 'range=', +- 'locallist', +- 'level=', +- 'roles=', +- 'type=', +- 'prefix=', +- 'mask=' +- ]) +- except getopt.error, error: +- usage(_("Options Error %s ") % error.msg) +- +- for o, a in gopts: +- if o not in option_dict[object]: +- sys.stderr.write(_("%s not valid for %s objects\n") % ( o, object) ); +- return +- +- for o,a in gopts: +- if o == "-a" or o == "--add": +- set_action(o) +- add = True +- +- if o == "-d" or o == "--delete": +- set_action(o) +- delete = True +- +- if o == "-D" or o == "--deleteall": +- set_action(o) +- deleteall = True +- +- if o == "-E" or o == "--extract": +- set_action(o) +- extract = True +- +- if o == "-f" or o == "--ftype": +- ftype=a +- +- if o == "-e" or o == "--equal": +- equal = a +- +- if o == "--enable": +- enable = True +- +- if o == "--disable": +- disable = True +- +- if o == "-F" or o == "--file": +- use_file = True +- +- if o == "-h" or o == "--help": +- raise usage() +- +- if o == "-n" or o == "--noheading": +- heading = False +- +- if o == "-N" or o == "--noreload": +- load = False +- +- if o == "-C" or o == "--locallist": +- locallist = True +- +- if o == "-m"or o == "--modify": +- set_action(o) +- modify = True +- +- if o == "-S" or o == '--store': +- store = a +- +- if o == "-r" or o == '--range': +- serange = a +- +- if o == "-l" or o == "--list": +- list = True +- +- if o == "-L" or o == '--level': +- selevel = a +- +- if o == "-p" or o == '--proto': +- proto = a +- +- if o == "-P" or o == '--prefix': +- prefix = a +- +- if o == "-R" or o == '--roles': +- roles = roles + " " + a +- +- if o == "-s" or o == "--seuser": +- seuser = a +- +- if o == "-M" or o == '--mask': +- mask = a +- +- if o == "-t" or o == "--type": +- setype = a +- +- if o == "--on" or o == "-1": +- value = "on" +- modify = True +- +- if o == "--off" or o == "-0": +- value = "off" +- modify = True +- +- if object == "login": +- OBJECT = seobject.loginRecords(store) +- +- if object == "user": +- OBJECT = seobject.seluserRecords(store) +- +- if object == "port": +- OBJECT = seobject.portRecords(store) +- +- if object == "interface": +- OBJECT = seobject.interfaceRecords(store) +- +- if object == "node": +- OBJECT = seobject.nodeRecords(store) +- +- if object == "fcontext": +- OBJECT = seobject.fcontextRecords(store) +- +- if object == "boolean": +- OBJECT = seobject.booleanRecords(store) +- if use_file: +- modify = True +- +- if object == "module": +- OBJECT = seobject.moduleRecords(store) +- +- if object == "permissive": +- OBJECT = seobject.permissiveRecords(store) +- +- if object == "dontaudit": +- OBJECT = seobject.dontauditClass(store) +- +- if list: +- if object == "boolean": +- OBJECT.list(heading, locallist, use_file) +- else: +- OBJECT.list(heading, locallist) +- return +- +- OBJECT.set_reload(load) +- if deleteall: +- OBJECT.deleteall() +- return +- +- if extract: +- for i in OBJECT.customized(): +- print "%s %s" % (object, str(i)) +- return +- +- if len(cmds) != 1: +- raise ValueError(_("bad option")) +- +- target = cmds[0] +- +- if object == "dontaudit": +- OBJECT.toggle(target) +- return +- +- if add: +- if object == "login": +- OBJECT.add(target, seuser, serange) +- return +- +- if object == "user": +- OBJECT.add(target, roles.split(), selevel, serange, prefix) +- return +- +- if object == "port": +- OBJECT.add(target, proto, serange, setype) +- return +- +- if object == "interface": +- OBJECT.add(target, serange, setype) +- return +- +- if object == "module": +- OBJECT.add(target) +- return +- +- if object == "node": +- OBJECT.add(target, mask, proto, serange, setype) +- return +- +- if object == "fcontext": +- if equal == "": +- OBJECT.add(target, setype, ftype, serange, seuser) +- else: +- OBJECT.add_equal(target, equal) +- return +- +- if object == "permissive": +- OBJECT.add(target) +- return +- +- if modify: +- if object == "boolean": +- if not value: +- raise ValueError(_("Value Required [ --on | --off ]")) +- OBJECT.modify(target, value, use_file) +- return +- +- if object == "login": +- OBJECT.modify(target, seuser, serange) +- return +- +- if object == "user": +- rlist = roles.split() +- OBJECT.modify(target, rlist, selevel, serange, prefix) +- return +- +- if object == "module": +- if enable: +- OBJECT.enable(target) +- elif disable: +- OBJECT.disable(target) +- else: +- OBJECT.modify(target) +- return +- +- if object == "port": +- OBJECT.modify(target, proto, serange, setype) +- return +- +- if object == "interface": +- OBJECT.modify(target, serange, setype) +- return +- +- if object == "node": +- OBJECT.modify(target, mask, proto, serange, setype) +- return +- +- if object == "fcontext": +- if equal == "": +- OBJECT.modify(target, setype, ftype, serange, seuser) +- else: +- OBJECT.modify_equal(target, equal) +- return +- +- if delete: +- if object == "port": +- OBJECT.delete(target, proto) +- +- elif object == "fcontext": +- OBJECT.delete(target, ftype) +- +- elif object == "node": +- OBJECT.delete(target, mask, proto) +- +- else: +- OBJECT.delete(target) +- return +- +- raise ValueError(_("Invalid command: semanage %s") % " ".join(argv)) +- +- # +- # +- # +- try: +- output = None +- input = None +- store = "" +- +- if len(sys.argv) < 3: +- usage(_("Requires 2 or more arguments")) +- +- gopts, cmds = getopt.getopt(sys.argv[1:], +- '01adf:i:lhmno:p:s:NFCDR:L:r:t:P:S:', +- ['add', +- 'delete', +- 'deleteall', +- 'ftype=', +- 'file', +- 'help', +- 'input=', +- 'list', +- 'modify', +- 'noheading', +- 'noreload', +- 'off', +- 'on', +- 'output=', +- 'proto=', +- 'seuser=', +- 'store=', +- 'range=', +- 'level=', +- 'roles=', +- 'type=', +- 'prefix=' +- ]) +- for o, a in gopts: +- if o == "-S" or o == '--store': +- store = a +- if o == "-i" or o == '--input': +- input = a +- if o == "-o" or o == '--output': +- output = a +- if o == "-N" or o == "--noreload": +- load = False +- +- if output != None: +- if output != "-": +- sys.stdout = open(output, 'w') +- for i in manageditems: +- print "%s -D" % i +- process_args([i, "-E"]) +- sys.exit(0) +- +- if input != None: +- if input == "-": +- fd = sys.stdin +- else: +- fd = open(input, 'r') +- trans = seobject.semanageRecords(store) +- trans.start() +- for l in fd.readlines(): +- process_args(mkargv(l)) +- trans.set_reload(load) +- trans.finish() +- else: +- process_args(sys.argv[1:]) +- +- except getopt.error, error: +- usage(_("Options Error %s ") % error.msg) +- except ValueError, error: +- errorExit(error.args[0]) +- except KeyError, error: +- errorExit(_("Invalid value %s") % error.args[0]) +- except IOError, error: +- errorExit(error.args[1]) +- except OSError, error: +- errorExit(error.args[1]) +- except RuntimeError, error: +- errorExit(error.args[0]) ++ do_parser() ++ diff --git a/policycoreutils.spec b/policycoreutils.spec index e83f675..9f83147 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -7,7 +7,7 @@ Summary: SELinux policy core utilities Name: policycoreutils Version: 2.1.14 -Release: 45%{?dist} +Release: 46%{?dist} License: GPLv2 Group: System Environment/Base # Based on git repository with tag 20101221 @@ -18,6 +18,7 @@ Source2: policycoreutils_man_ru2.tar.bz2 Source3: system-config-selinux.png Patch: policycoreutils-rhat.patch Patch1: policycoreutils-sepolgen.patch +Patch2: policycoreutils-semanage.patch Obsoletes: policycoreutils < 2.0.61-2 Conflicts: filesystem < 3 Provides: /sbin/fixfiles @@ -53,6 +54,7 @@ to switch roles. %setup -q -a 1 %patch -p2 -b .rhat %patch1 -p2 -b .sepolgen -d sepolgen-%{sepolgenver} +%patch2 -p1 -b .semanage %build cp %{SOURCE3} gui/ @@ -309,6 +311,10 @@ The policycoreutils-restorecond package contains the restorecond service. %systemd_postun_with_restart restorecond.service %changelog +* Sum May 26 2013 Dan Walsh - 2.1.14-46 +- Fix the name of the spec file generated in the build script +- Add mgrepl patch to support argparse for semanage command parsing + * Tue May 21 2013 Dan Walsh - 2.1.14-45 - Fix sandbox to always use sandbox_file_t, so generated policy will work. - Update Translations