11643b3535
- Fix semange module command
1257 lines
60 KiB
Diff
1257 lines
60 KiB
Diff
diff -up policycoreutils-2.1.14/semanage/semanage.semanage policycoreutils-2.1.14/semanage/semanage
|
|
--- policycoreutils-2.1.14/semanage/semanage.semanage 2013-06-18 14:55:40.909048376 -0400
|
|
+++ policycoreutils-2.1.14/semanage/semanage 2013-06-18 15:00:14.100276927 -0400
|
|
@@ -1,5 +1,7 @@
|
|
#! /usr/bin/python -Es
|
|
-# Copyright (C) 2005-2012 Red Hat
|
|
+# Copyright (C) 2012-2013 Red Hat
|
|
+# AUTHOR: Miroslav Grepl <mgrepl@redhat.com>
|
|
+# AUTHOR: David Quigley <selinux@davequigley.com>
|
|
# see file 'COPYING' for use and warranty information
|
|
#
|
|
# semanage is a tool for managing SELinux configuration files
|
|
@@ -19,16 +21,14 @@
|
|
# 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)
|
|
|
|
try:
|
|
gettext.install(PROGNAME,
|
|
@@ -39,545 +39,681 @@ except IOError:
|
|
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('-N', '--noreload', action='store_true', help=_('Do not reload the policy after commit'))
|
|
+ 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 make_args(sys_args):
|
|
+ args = []
|
|
+ for i in sys_args[1:]:
|
|
+ if i == '-o':
|
|
+ args += [ "export", "-f" ]
|
|
+ continue
|
|
+ if i == '-i':
|
|
+ args += [ "import", "-f" ]
|
|
+ continue
|
|
+ args.append(i)
|
|
+ return args
|
|
+
|
|
+def do_parser():
|
|
+ try:
|
|
+ commandParser = createCommandParser()
|
|
+ args = commandParser.parse_args(make_args(sys.argv))
|
|
+ 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
|
|
- -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":
|
|
- 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()
|