Current File : //sbin/semanage
#! /usr/libexec/platform-python -EsI
# 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
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of the GNU General Public License as
#    published by the Free Software Foundation; either version 2 of
#    the License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
#                                        02111-1307  USA
#
#

import argparse
import os
import re
import sys
import traceback

PROGNAME = "selinux-python"
try:
    import gettext
    kwargs = {}
    if sys.version_info < (3,):
        kwargs['unicode'] = True
    gettext.install(PROGNAME,
                    localedir="/usr/share/locale",
                    codeset='utf-8',
                    **kwargs)
except:
    try:
        import builtins
        builtins.__dict__['_'] = str
    except ImportError:
        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 user [-h] [-n] [-N] [-S STORE] ["
usage_user_dict = {' --add': ('(', '-L LEVEL', '-R ROLES', '-r RANGE', 'SEUSER', ')'), ' --delete': ('SEUSER',), ' --modify': ('(', '-L LEVEL', '-R ROLES', '-r RANGE', '-s SEUSER', 'SEUSER', ')'), ' --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_ibpkey = "semanage ibpkey [-h] [-n] [-N] [-s STORE] ["
usage_ibpkey_dict = {' --add': ('-t TYPE', '-x SUBNET_PREFIX', '-r RANGE', '(', 'ibpkey_name', '|', 'pkey_range', ')'), ' --modify': ('-t TYPE', '-x SUBNET_PREFIX', '-r RANGE', '(', 'ibpkey_name', '|', 'pkey_range', ')'), ' --delete': ('-x SUBNET_PREFIX', '(', 'ibpkey_name', '|', 'pkey_range', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}

usage_ibendport = "semanage ibendport [-h] [-n] [-N] [-s STORE] ["
usage_ibendport_dict = {' --add': ('-t TYPE', '-z IBDEV_NAME', '-r RANGE', '(', 'port', ')'), ' --modify': ('-t TYPE', '-z IBDEV_NAME', '-r RANGE', '(', 'port', ')'), ' --delete': ('-z IBDEV_NAME', '-r RANGE', '(', 'port', ')'), ' --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'), ' --list': ('-C',), '  --extract': ('',), ' --deleteall': ('',)}




class CheckRole(argparse.Action):

    def __call__(self, parser, namespace, value, option_string=None):
        newval = getattr(namespace, self.dest)
        if not newval:
            newval = []
        try:
            # sepolicy tries to load the SELinux policy and raises ValueError if it fails.
            import sepolicy
            roles = sepolicy.get_all_roles()
        except ValueError:
            roles = []
        for v in value.split():
            if v not in roles:
                raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (v, ", ".join(roles)))
            newval.append(v)
        setattr(namespace, self.dest, newval)


class seParser(argparse.ArgumentParser):

    def error(self, message):
        if len(sys.argv) == 2:
            self.print_help()
        else:
            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:
            if values != "-":
                try:
                    sys.stdout = open(values, 'w')
                except:
                    sys.stderr.write(traceback.format_exc())
                    sys.exit(1)
        setattr(namespace, self.dest, values)


class SetImportFile(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        if values and values != "-":
            try:
                sys.stdin = open(values, 'r')
            except IOError as e:
                sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
                sys.exit(1)
        setattr(namespace, self.dest, values)


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', 'seuser'), ('')], 'add': [('locallist'), ('seuser', 'login')], 'modify': [('locallist'), ('login')], 'delete': [('locallist'), ('login')], 'extract': [('locallist', 'login', 'seuser'), ('')], 'deleteall': [('locallist'), ('')]}

    handle_opts(args, login_args, args.action)

    OBJECT = object_dict['login'](args)

    if args.action == "add":
        OBJECT.add(args.login, args.seuser, args.range)
    if args.action == "modify":
        OBJECT.modify(args.login, args.seuser, args.range)
    if args.action == "delete":
        OBJECT.delete(args.login)
    if args.action == "list":
        OBJECT.list(args.noheading, args.locallist)
    if args.action == "deleteall":
        OBJECT.deleteall()
    if args.action == "extract":
        for i in OBJECT.customized():
            print("login %s" % (str(i)))


def parser_add_store(parser, name):
    parser.add_argument('-S', '--store', default='', help=_("Select an alternate SELinux Policy Store to manage"))


def parser_add_priority(parser, name):
    parser.add_argument('-P', '--priority', type=int, default=400, help=_("Select a priority for module operations"))


def parser_add_noheading(parser, name):
    parser.add_argument('-n', '--noheading', action='store_false', default=True, help=_("Do not print heading when listing %s object types") % name)


def parser_add_noreload(parser, name):
    parser.add_argument('-N', '--noreload', action='store_true', default=False, help=_('Do not reload policy after commit'))


def parser_add_locallist(parser, name):
    parser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List %s local customizations") % name)


def parser_add_add(parser, name):
    parser.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_("Add a record of the %s object type") % name)


def parser_add_type(parser, name):
    parser.add_argument('-t', '--type', help=_('SELinux Type for the object'))


def parser_add_level(parser, name):
    parser.add_argument('-L', '--level', default='s0', help=_('Default SELinux Level for SELinux user, s0 Default. (MLS/MCS Systems only)'))


def parser_add_range(parser, name):
    parser.add_argument('-r', '--range', 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.
'''))


def parser_add_proto(parser, name):
    parser.add_argument('-p', '--proto', help=_('''
    Protocol  for  the specified port (tcp|udp) or internet protocol
    version for the specified node (ipv4|ipv6).
'''))

def parser_add_subnet_prefix(parser, name):
    parser.add_argument('-x', '--subnet_prefix', help=_('''
    Subnet prefix for  the specified infiniband ibpkey.
'''))

def parser_add_ibdev_name(parser, name):
    parser.add_argument('-z', '--ibdev_name', help=_('''
    Name for the specified infiniband end port.
'''))

def parser_add_modify(parser, name):
    parser.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_("Modify a record of the %s object type") % name)


def parser_add_list(parser, name):
    parser.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_("List records of the %s object type") % name)


def parser_add_delete(parser, name):
    parser.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_("Delete a record of the %s object type") % name)


def parser_add_extract(parser, name):
    parser.add_argument('-E', '--extract', dest='action', action='store_const', const='extract', help=_("Extract customizable commands, for use within a transaction"))


def parser_add_deleteall(parser, name):
    parser.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all %s objects local customizations') % name)


def parser_add_seuser(parser, name):
    parser.add_argument('-s', '--seuser', default="", help=_("SELinux user name"))


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"))
    parser_add_locallist(loginParser, "login")
    parser_add_noheading(loginParser, "login")
    parser_add_noreload(loginParser, "login")
    parser_add_store(loginParser, "login")
    parser_add_range(loginParser, "login")

    login_action = loginParser.add_mutually_exclusive_group(required=True)

    parser_add_add(login_action, "login")
    parser_add_delete(login_action, "login")
    parser_add_modify(login_action, "login")
    parser_add_list(login_action, "login")
    parser_add_extract(login_action, "login")
    parser_add_deleteall(login_action, "login")
    parser_add_seuser(loginParser, "login")

    loginParser.add_argument('login', nargs='?', default=None, help=_("login_name | %%groupname"))

    loginParser.set_defaults(func=handleLogin)


def handleFcontext(args):
    fcontext_args = {'list': [('equal', 'ftype', 'seuser', 'type'), ('')], 'add': [('locallist'), ('type', 'file_spec')], 'modify': [('locallist'), ('type', 'file_spec')], 'delete': [('locallist'), ('file_spec')], 'extract': [('locallist', 'equal', 'ftype', 'seuser', 'type'), ('')], 'deleteall': [('locallist'), ('')]}
    # we can not use mutually for equal because we can define some actions together with equal
    fcontext_equal_args = {'equal': [('list', 'locallist', 'type', 'ftype', 'seuser', 'deleteall', 'extract'), ()]}

    if args.action and args.equal:
        handle_opts(args, fcontext_equal_args, "equal")
    else:
        handle_opts(args, fcontext_args, args.action)

    OBJECT = object_dict['fcontext'](args)

    if args.action == "add":
        if args.equal:
            OBJECT.add_equal(args.file_spec, args.equal)
        else:
            OBJECT.add(args.file_spec, args.type, args.ftype, args.range, args.seuser)
    if args.action == "modify":
        if args.equal:
            OBJECT.modify_equal(args.file_spec, args.equal)
        else:
            OBJECT.modify(args.file_spec, args.type, args.ftype, args.range, args.seuser)
    if args.action == "delete":
        if args.equal:
            OBJECT.delete(args.file_spec, args.equal)
        else:
            OBJECT.delete(args.file_spec, args.ftype)
    if args.action == "list":
        OBJECT.list(args.noheading, args.locallist)
    if args.action == "deleteall":
        OBJECT.deleteall()
    if args.action == "extract":
        for i in OBJECT.customized():
            print("fcontext %s" % 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 f to match only regular files. The following
file type options can be passed:
f (regular file),d (directory),c (character device),
b (block device),s (socket),l (symbolic link),p (named pipe)
If you do not specify a file type, the file type will default to "all files".
'''
    generate_usage = generate_custom_usage(usage_fcontext, usage_fcontext_dict)
    fcontextParser = subparsers.add_parser('fcontext', usage=generate_usage, help=_("Manage file context mapping definitions"))
    parser_add_locallist(fcontextParser, "fcontext")
    parser_add_noheading(fcontextParser, "fcontext")
    parser_add_noreload(fcontextParser, "fcontext")
    parser_add_store(fcontextParser, "fcontext")

    fcontext_action = fcontextParser.add_mutually_exclusive_group(required=True)
    parser_add_add(fcontext_action, "fcontext")
    parser_add_delete(fcontext_action, "fcontext")
    parser_add_modify(fcontext_action, "fcontext")
    parser_add_list(fcontext_action, "fcontext")
    parser_add_extract(fcontext_action, "fcontext")
    parser_add_deleteall(fcontext_action, "fcontext")

    fcontextParser.add_argument('-e', '--equal', 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', default="", choices=["a", "f", "d", "c", "b", "s", "l", "p"], help=_(ftype_help))
    parser_add_seuser(fcontextParser, "fcontext")
    parser_add_type(fcontextParser, "fcontext")
    parser_add_range(fcontextParser, "fcontext")
    fcontextParser.add_argument('file_spec', nargs='?', default=None, help=_('Path to be labeled (may be in the form of a Perl compatible regular expression)'))
    fcontextParser.set_defaults(func=handleFcontext)


def handleUser(args):
    user_args = {'list': [('selinux_name', 'seuser', 'roles'), ('')], 'add': [('locallist'), ('roles', 'selinux_name')], 'modify': [('locallist'), ('selinux_name')], 'delete': [('locallist'), ('selinux_name')], 'extract': [('locallist', 'selinux_name', 'seuser', 'role'), ('')], 'deleteall': [('locallist'), ('')]}

    handle_opts(args, user_args, args.action)

    OBJECT = object_dict['user'](args)

    if args.action == "add":
        OBJECT.add(args.selinux_name, args.roles, args.level, args.range, args.prefix)
    if args.action == "modify":
        OBJECT.modify(args.selinux_name, args.roles, args.level, args.range, args.prefix)
    if args.action == "delete":
        OBJECT.delete(args.selinux_name)
    if args.action == "list":
        OBJECT.list(args.noheading, args.locallist)
    if args.action == "deleteall":
        OBJECT.deleteall()
    if args.action == "extract":
        for i in OBJECT.customized():
            print("user %s" % 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)'))
    parser_add_locallist(userParser, "user")
    parser_add_noheading(userParser, "user")
    parser_add_noreload(userParser, "user")
    parser_add_store(userParser, "user")

    user_action = userParser.add_mutually_exclusive_group(required=True)
    parser_add_add(user_action, "user")
    parser_add_delete(user_action, "user")
    parser_add_modify(user_action, "user")
    parser_add_list(user_action, "user")
    parser_add_extract(user_action, "user")
    parser_add_deleteall(user_action, "user")

    parser_add_level(userParser, "user")
    parser_add_range(userParser, "user")
    userParser.add_argument('-R', '--roles', default=[],
                            action=CheckRole,
                            help=_('''
SELinux Roles.  You must enclose multiple roles within quotes, separate by spaces. Or specify -R multiple times.
'''))
    userParser.add_argument('-P', '--prefix', default="user", help=argparse.SUPPRESS)
    userParser.add_argument('selinux_name', nargs='?', default=None, help=_('selinux_name'))
    userParser.set_defaults(func=handleUser)


def handlePort(args):
    port_args = {'list': [('port', 'type', 'proto'), ('')], 'add': [('locallist'), ('type', 'port', 'proto')], 'modify': [('localist'), ('port', 'proto')], 'delete': [('locallist'), ('port', 'proto')], 'extract': [('locallist', 'port', 'type', 'proto'), ('')], 'deleteall': [('locallist'), ('')]}

    handle_opts(args, port_args, args.action)

    OBJECT = object_dict['port'](args)

    if args.action == "add":
        OBJECT.add(args.port, args.proto, args.range, args.type)
    if args.action == "modify":
        OBJECT.modify(args.port, args.proto, args.range, args.type)
    if args.action == "delete":
        OBJECT.delete(args.port, args.proto)
    if args.action == "list":
        OBJECT.list(args.noheading, args.locallist)
    if args.action == "deleteall":
        OBJECT.deleteall()
    if args.action == "extract":
        for i in OBJECT.customized():
            print("port %s" % 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'))
    parser_add_locallist(portParser, "port")
    parser_add_noheading(portParser, "port")
    parser_add_noreload(portParser, "port")
    parser_add_store(portParser, "port")

    port_action = portParser.add_mutually_exclusive_group(required=True)
    parser_add_add(port_action, "port")
    parser_add_delete(port_action, "port")
    parser_add_modify(port_action, "port")
    parser_add_list(port_action, "port")
    parser_add_extract(port_action, "port")
    parser_add_deleteall(port_action, "port")
    parser_add_type(portParser, "port")
    parser_add_range(portParser, "port")
    parser_add_proto(portParser, "port")
    portParser.add_argument('port', nargs='?', default=None, help=_('port | port_range'))
    portParser.set_defaults(func=handlePort)



def handlePkey(args):
    ibpkey_args = {'list': [('ibpkey', 'type', 'subnet_prefix'), ('')], 'add': [('locallist'), ('type', 'ibpkey', 'subnet_prefix')], 'modify': [('localist'), ('ibpkey', 'subnet_prefix')], 'delete': [('locallist'), ('ibpkey', 'subnet_prefix')], 'extract': [('locallist', 'ibpkey', 'type', 'subnet prefix'), ('')], 'deleteall': [('locallist'), ('')]}

    handle_opts(args, ibpkey_args, args.action)

    OBJECT = object_dict['ibpkey'](args)

    if args.action == "add":
        OBJECT.add(args.ibpkey, args.subnet_prefix, args.range, args.type)
    if args.action == "modify":
        OBJECT.modify(args.ibpkey, args.subnet_prefix, args.range, args.type)
    if args.action == "delete":
        OBJECT.delete(args.ibpkey, args.subnet_prefix)
    if args.action == "list":
        OBJECT.list(args.noheading, args.locallist)
    if args.action == "deleteall":
        OBJECT.deleteall()
    if args.action == "extract":
        for i in OBJECT.customized():
            print("ibpkey %s" % str(i))


def setupPkeyParser(subparsers):
    generated_usage = generate_custom_usage(usage_ibpkey, usage_ibpkey_dict)
    ibpkeyParser = subparsers.add_parser('ibpkey', usage=generated_usage, help=_('Manage infiniband ibpkey type definitions'))
    parser_add_locallist(ibpkeyParser, "ibpkey")
    parser_add_noheading(ibpkeyParser, "ibpkey")
    parser_add_noreload(ibpkeyParser, "ibpkey")
    parser_add_store(ibpkeyParser, "ibpkey")

    ibpkey_action = ibpkeyParser.add_mutually_exclusive_group(required=True)
    parser_add_add(ibpkey_action, "ibpkey")
    parser_add_delete(ibpkey_action, "ibpkey")
    parser_add_modify(ibpkey_action, "ibpkey")
    parser_add_list(ibpkey_action, "ibpkey")
    parser_add_extract(ibpkey_action, "ibpkey")
    parser_add_deleteall(ibpkey_action, "ibpkey")
    parser_add_type(ibpkeyParser, "ibpkey")
    parser_add_range(ibpkeyParser, "ibpkey")
    parser_add_subnet_prefix(ibpkeyParser, "ibpkey")
    ibpkeyParser.add_argument('ibpkey', nargs='?', default=None, help=_('pkey | pkey_range'))
    ibpkeyParser.set_defaults(func=handlePkey)

def handleIbendport(args):
    ibendport_args = {'list': [('ibendport', 'type', 'ibdev_name'), ('')], 'add': [('locallist'), ('type', 'ibendport', 'ibdev_name'), ('')], 'modify': [('localist'), ('ibendport', 'ibdev_name')], 'delete': [('locallist'), ('ibendport', 'ibdev_name')], 'extract': [('locallist', 'ibendport', 'type', 'ibdev_name'), ('')], 'deleteall': [('locallist'), ('')]}

    handle_opts(args, ibendport_args, args.action)

    OBJECT = object_dict['ibendport'](args)

    if args.action == "add":
        OBJECT.add(args.ibendport, args.ibdev_name, args.range, args.type)
    if args.action == "modify":
        OBJECT.modify(args.ibendport, args.ibdev_name, args.range, args.type)
    if args.action == "delete":
        OBJECT.delete(args.ibendport, args.ibdev_name)
    if args.action == "list":
        OBJECT.list(args.noheading, args.locallist)
    if args.action == "deleteall":
        OBJECT.deleteall()
    if args.action == "extract":
        for i in OBJECT.customized():
            print("ibendport %s" % str(i))


def setupIbendportParser(subparsers):
    generated_usage = generate_custom_usage(usage_ibendport, usage_ibendport_dict)
    ibendportParser = subparsers.add_parser('ibendport', usage=generated_usage, help=_('Manage infiniband end port type definitions'))
    parser_add_locallist(ibendportParser, "ibendport")
    parser_add_noheading(ibendportParser, "ibendport")
    parser_add_noreload(ibendportParser, "ibendport")
    parser_add_store(ibendportParser, "ibendport")

    ibendport_action = ibendportParser.add_mutually_exclusive_group(required=True)
    parser_add_add(ibendport_action, "ibendport")
    parser_add_delete(ibendport_action, "ibendport")
    parser_add_modify(ibendport_action, "ibendport")
    parser_add_list(ibendport_action, "ibendport")
    parser_add_extract(ibendport_action, "ibendport")
    parser_add_deleteall(ibendport_action, "ibendport")
    parser_add_type(ibendportParser, "ibendport")
    parser_add_range(ibendportParser, "ibendport")
    parser_add_ibdev_name(ibendportParser, "ibendport")
    ibendportParser.add_argument('ibendport', nargs='?', default=None, help=_('ibendport'))
    ibendportParser.set_defaults(func=handleIbendport)

def handleInterface(args):
    interface_args = {'list': [('interface'), ('')], 'add': [('locallist'), ('type', 'interface')], 'modify': [('locallist'), ('type', 'interface')], 'delete': [('locallist'), ('interface')], 'extract': [('locallist', 'interface', 'type'), ('')], 'deleteall': [('locallist'), ('')]}

    handle_opts(args, interface_args, args.action)

    OBJECT = object_dict['interface'](args)

    if args.action == "add":
        OBJECT.add(args.interface, args.range, args.type)
    if args.action == "modify":
        OBJECT.modify(args.interface, args.range, args.type)
    if args.action == "delete":
        OBJECT.delete(args.interface)
    if args.action == "list":
        OBJECT.list(args.noheading, args.locallist)
    if args.action == "deleteall":
        OBJECT.deleteall()
    if args.action == "extract":
        for i in OBJECT.customized():
            print("interface %s" % 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'))
    parser_add_locallist(interfaceParser, "interface")
    parser_add_noheading(interfaceParser, "interface")
    parser_add_noreload(interfaceParser, "interface")
    parser_add_store(interfaceParser, "interface")
    parser_add_type(interfaceParser, "interface")
    parser_add_range(interfaceParser, "interface")

    interface_action = interfaceParser.add_mutually_exclusive_group(required=True)
    parser_add_add(interface_action, "interface")
    parser_add_delete(interface_action, "interface")
    parser_add_modify(interface_action, "interface")
    parser_add_list(interface_action, "interface")
    parser_add_extract(interface_action, "interface")
    parser_add_deleteall(interface_action, "interface")
    interfaceParser.add_argument('interface', nargs='?', default=None, help=_('interface_spec'))
    interfaceParser.set_defaults(func=handleInterface)


def handleModule(args):
    import seobject
    OBJECT = seobject.moduleRecords(args)
    if args.action_add:
        OBJECT.add(args.action_add[0], args.priority)
    if args.action_enable:
        OBJECT.set_enabled(" ".join(args.action_enable), True)
    if args.action_disable:
        OBJECT.set_enabled(" ".join(args.action_disable), False)
    if args.action_remove:
        OBJECT.delete(" ".join(args.action_remove), args.priority)
    if args.action == "deleteall":
        OBJECT.deleteall()
    if args.action == "list":
        OBJECT.list(args.noheading, args.locallist)
    if args.action == "extract":
        for i in OBJECT.customized():
            print("module %s" % str(i))


def setupModuleParser(subparsers):
    moduleParser = subparsers.add_parser('module', help=_('Manage SELinux policy modules'))
    parser_add_noheading(moduleParser, "module")
    parser_add_noreload(moduleParser, "module")
    parser_add_store(moduleParser, "module")
    parser_add_locallist(moduleParser, "module")
    parser_add_priority(moduleParser, "module")

    mgroup = moduleParser.add_mutually_exclusive_group(required=True)
    parser_add_list(mgroup, "module")
    parser_add_extract(mgroup, "module")
    parser_add_deleteall(mgroup, "module")
    mgroup.add_argument('-a', '--add', dest='action_add', action='store', nargs=1, metavar='module_name', help=_("Add a module"))
    mgroup.add_argument('-r', '--remove', dest='action_remove', action='store', nargs='+', metavar='module_name', help=_("Remove a module"))
    mgroup.add_argument('-d', '--disable', dest='action_disable', action='store', nargs='+', metavar='module_name', help=_("Disable a module"))
    mgroup.add_argument('-e', '--enable', dest='action_enable', action='store', nargs='+', metavar='module_name', help=_("Enable a module"))
    moduleParser.set_defaults(func=handleModule)


def handleNode(args):
    node_args = {'list': [('node', 'type', 'proto', 'netmask'), ('')], 'add': [('locallist'), ('type', 'node', 'proto', 'netmask')], 'modify': [('locallist'), ('node', 'netmask', 'proto')], 'delete': [('locallist'), ('node', 'netmask', 'prototype')], 'extract': [('locallist', 'node', 'type', 'proto', 'netmask'), ('')], 'deleteall': [('locallist'), ('')]}
    handle_opts(args, node_args, args.action)

    OBJECT = object_dict['node'](args)

    if args.action == "add":
        OBJECT.add(args.node, args.netmask, args.proto, args.range, args.type)
    if args.action == "modify":
        OBJECT.modify(args.node, args.netmask, args.proto, args.range, args.type)
    if args.action == "delete":
        OBJECT.delete(args.node, args.netmask, args.proto)
    if args.action == "list":
        OBJECT.list(args.noheading, args.locallist)
    if args.action == "deleteall":
        OBJECT.deleteall()
    if args.action == "extract":
        for i in OBJECT.customized():
            print("node %s" % 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'))
    parser_add_locallist(nodeParser, "node")
    parser_add_noheading(nodeParser, "node")
    parser_add_noreload(nodeParser, "node")
    parser_add_store(nodeParser, "node")

    node_action = nodeParser.add_mutually_exclusive_group(required=True)
    parser_add_add(node_action, "node")
    parser_add_delete(node_action, "node")
    parser_add_modify(node_action, "node")
    parser_add_list(node_action, "node")
    parser_add_extract(node_action, "node")
    parser_add_deleteall(node_action, "node")

    nodeParser.add_argument('-M', '--netmask', help=_('Network Mask'))
    parser_add_type(nodeParser, "node")
    parser_add_range(nodeParser, "node")
    parser_add_proto(nodeParser, "node")
    nodeParser.add_argument('node', nargs='?', default=None, help=_('node'))
    nodeParser.set_defaults(func=handleNode)


def handleBoolean(args):
    boolean_args = {'list': [('state', 'boolean'), ('')], 'modify': [('localist'), ('boolean', 'state')], 'extract': [('locallist', 'state', 'boolean'), ('')], 'deleteall': [('locallist'), ('')], 'state': [('locallist', 'list', 'extract', 'deleteall'), ('modify')]}

    handle_opts(args, boolean_args, args.action)

    OBJECT = object_dict['boolean'](args)

    if args.action == "modify":
        if args.boolean:
            OBJECT.modify(args.boolean, args.state, False)
    if args.action == "list":
        OBJECT.list(args.noheading, args.locallist)
    if args.action == "deleteall":
        OBJECT.deleteall()
    if args.action == "extract":
        for i in OBJECT.customized():
            print("boolean %s" % 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'))
    parser_add_locallist(booleanParser, "boolean")
    parser_add_noheading(booleanParser, "boolean")
    parser_add_noreload(booleanParser, "boolean")
    parser_add_store(booleanParser, "boolean")
    booleanParser.add_argument('boolean', nargs="?", default=None, help=_('boolean'))

    boolean_action = booleanParser.add_mutually_exclusive_group(required=True)
    #add_add(boolean_action)
    parser_add_modify(boolean_action, "boolean")
    parser_add_list(boolean_action, "boolean")
    parser_add_extract(boolean_action, "boolean")
    parser_add_deleteall(boolean_action, "boolean")

    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'))

    booleanParser.set_defaults(func=handleBoolean)


def handlePermissive(args):
    OBJECT = object_dict['permissive'](args)

    if args.action == "list":
        OBJECT.list(args.noheading)
    elif args.action == "deleteall":
        OBJECT.deleteall()
    elif args.action == "extract":
        for i in OBJECT.customized():
            print("permissive %s" % str(i))
    elif args.type is not None:
        if args.action == "add":
            OBJECT.add(args.type)
        if args.action == "delete":
            OBJECT.delete(args.type)
    else:
        args.parser.error(message=_('semanage permissive: error: the following argument is required: type\n'))


def setupPermissiveParser(subparsers):
    permissiveParser = subparsers.add_parser('permissive', help=_('Manage process type enforcement mode'))

    pgroup = permissiveParser.add_mutually_exclusive_group(required=True)
    parser_add_add(pgroup, "permissive")
    parser_add_delete(pgroup, "permissive")
    parser_add_deleteall(pgroup, "permissive")
    parser_add_extract(pgroup, "permissive")
    parser_add_list(pgroup, "permissive")

    parser_add_noheading(permissiveParser, "permissive")
    parser_add_noreload(permissiveParser, "permissive")
    parser_add_store(permissiveParser, "permissive")
    permissiveParser.add_argument('type', nargs='?', default=None, help=_('type'))
    permissiveParser.set_defaults(func=handlePermissive)
    permissiveParser.set_defaults(parser=permissiveParser)


def handleDontaudit(args):
    OBJECT = object_dict['dontaudit'](args)
    OBJECT.toggle(args.action)


def setupDontauditParser(subparsers):
    dontauditParser = subparsers.add_parser('dontaudit', help=_('Disable/Enable dontaudit rules in policy'))
    parser_add_noreload(dontauditParser, "dontaudit")
    parser_add_store(dontauditParser, "dontaudit")
    dontauditParser.add_argument('action', choices=["on", "off"])
    dontauditParser.set_defaults(func=handleDontaudit)


def handleExport(args):
    manageditems = ["boolean", "login", "interface", "user", "port", "node", "fcontext", "module", "ibendport", "ibpkey", "permissive"]
    for i in manageditems:
        print("%s -D" % i)
    for i in manageditems:
        OBJECT = object_dict[i](args)
        for c in OBJECT.customized():
            print("%s %s" % (i, str(c)))

    sys.exit(0)


def setupExportParser(subparsers):
    exportParser = subparsers.add_parser('export', help=_('Output local customizations'))
    parser_add_store(exportParser, "export")
    exportParser.add_argument('-f', '--output_file', dest='output_file', action=SetExportFile, help=_('Output file'))
    exportParser.set_defaults(func=handleExport)


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 handleImport(args):
    import seobject
    trans = seobject.semanageRecords(args)
    trans.start()

    deleteCommands = []
    commands = []
    # separate commands for deletion from the rest so they can be
    # applied in a separate transaction
    for l in sys.stdin.readlines():
        if len(l.strip()) == 0:
            continue
        if "-d" in l or "-D" in l:
            deleteCommands.append(l)
        else:
            commands.append(l)

    if deleteCommands:
        importHelper(deleteCommands)
        trans.finish()
        trans.start()

    importHelper(commands)
    trans.finish()


def importHelper(commands):
    for l in commands:
        try:
            commandParser = createCommandParser()
            args = commandParser.parse_args(mkargv(l))
            args.func(args)
        except ValueError as e:
            sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
            sys.exit(1)
        except IOError as e:
            sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
            sys.exit(1)
        except KeyboardInterrupt:
            sys.exit(0)


def setupImportParser(subparsers):
    importParser = subparsers.add_parser('import', help=_('Import local customizations'))
    parser_add_noreload(importParser, "import")
    parser_add_store(importParser, "import")
    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')
    subparsers.required = True

    import seobject
    # define dictonary for seobject OBEJCTS
    global object_dict
    object_dict = {
        'login': seobject.loginRecords,
        'user': seobject.seluserRecords,
        'port': seobject.portRecords,
        'module': seobject.moduleRecords,
        'interface': seobject.interfaceRecords,
        'node': seobject.nodeRecords,
        'fcontext': seobject.fcontextRecords,
        'boolean': seobject.booleanRecords,
        'permissive': seobject.permissiveRecords,
        'dontaudit': seobject.dontauditClass,
        'ibpkey': seobject.ibpkeyRecords,
        'ibendport': seobject.ibendportRecords
    }

    setupImportParser(subparsers)
    setupExportParser(subparsers)
    setupLoginParser(subparsers)
    setupUserParser(subparsers)
    setupPortParser(subparsers)
    setupPkeyParser(subparsers)
    setupIbendportParser(subparsers)
    setupInterfaceParser(subparsers)
    setupModuleParser(subparsers)
    setupNodeParser(subparsers)
    setupFcontextParser(subparsers)
    setupBooleanParser(subparsers)
    setupPermissiveParser(subparsers)
    setupDontauditParser(subparsers)

    return commandParser


def make_io_args(args):
    # import/export backward compability
    args_origin = ["-S", "-o", "-i", "targeted", "minimum", "mls"]
    args_file = []
    args_ie = []
    args_subcommand = []

    for i in args:
        if i == "-o":
            args_subcommand = ["export"]
            continue
        if i == "-i":
            args_subcommand = ["import"]
            continue
        if i not in args_origin:
            args_file = ["-f", i]
            continue
        args_ie.append(i)

    return args_subcommand + args_ie + args_file


def make_args(sys_args):
    args = []
    if "-o" in sys_args[1:] or "-i" in sys_args[1:]:
        args = make_io_args(sys_args[1:])
    else:
        args = sys_args[1:]

    return args


def do_parser():
    try:
        commandParser = createCommandParser()
        args = commandParser.parse_args(make_args(sys.argv))
        args.func(args)
        sys.exit(0)
    except BrokenPipeError as e:
        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
        # Python flushes standard streams on exit; redirect remaining output
        # to devnull to avoid another BrokenPipeError at shutdown
        devnull = os.open(os.devnull, os.O_WRONLY)
        os.dup2(devnull, sys.stdout.fileno())
        sys.exit(1)
    except IOError as e:
        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
        sys.exit(1)
    except KeyboardInterrupt:
        sys.exit(0)
    except ValueError as e:
        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[0]))
        sys.exit(1)
    except KeyError as e:
        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[0]))
        sys.exit(1)
    except OSError as e:
        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[1]))
        sys.exit(1)
    except RuntimeError as e:
        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[0]))
        sys.exit(1)

if __name__ == '__main__':
    do_parser()
Uncategorized

Categoría: Uncategorized

  • Annotation du salle de jeu OnlineBingo : éditorialiste ou détail

    Ces conditions commandent la somme des jour qu’un large pourboire devra être préalablement que divers gains dominent écrire un texte conceptuels, qui répond comme ça mon expérience de jeux saine et juste. Concrètement, les 10 versions en hasard ont longtemps. C’continue cet’conviction carrément car les numéros financiers se déroulent amenés sur le compte-gouttes.

  • Posido Scompiglio Esame critico anche gratifica di commiato 2024

    Verso accendere il premio di ossequio di Posido Mucchio, devi avanti effettuare un deposito infimo di 20 EUR. Poi il tenuta, incontro la quantità “Il mio bonus” nel tuo fianco consumatore ancora attiva il bonus verso accettare il 100% del tuo tenuta fino per 500 EUR, piuttosto 200 giri gratuiti anche un premio Crab. Ricorda…

  • Bonus casa da gioco online: Qual è il miglior siti bisca con gratifica? 2025

    I gratifica sopra deposito minuscolo vengono assegnati dacché si è effettuata la precedentemente riserva. Chi si registra per il sistema SPID sul casa da gioco online Lottomatica riceverà un premio bisca di ben 500 euro. Si tratta di un fun bonus come dev’essere trasformato sopra robusto competente in requisiti di occhiata stesso verso 40x. I…

  • Au top Casino un tantinet: Livre 2025 de Champions Gaulois

    Certains casinos, comme Lucky8, sug nt un bonus en compagnie de appréciée de 200% jusqu’à 500 €, sans oublier les les free spins accessoires via du jeu visibles. Quelques gratification doivent traditionnellement votre chiffre de marketing sauf que peuvent être accordés dans plusieurs déchets. Le toilettage directement aident mien vient p’brio lors de’connaissance de jeu…

  • Salle de jeu supermarkets branché Hollande to aboutisse: But nous travail and l’excellent retail market

    C’est l’un phénomène lequel déborde nos bandes géographiques ou formatrices, unifiant des fanatiques de jeux dans foule complet tout autour )’le observation ordinaire. Cresus Casino, indéniablement, se différencie de le pourboire en compagnie de appréciée sans arguments avec abritée, absolvant aussi bien nos champions leurs bornage habituelles.

  • Закачать Мелбет на Андроид бесплатно: официальная версия Melbet употребления

    Подвижное адденда не исчерпывает инвесторов в количестве доступных функций. Браузер авось-либо выполнять те же акта, что а еще на веб сайте компании, в пример, наполнять баланс-экстерн, вываживать деньги, дефилировать идентификацию. Вниз изложим, а как скачать «Мелбет» нате Дроид бесплатно с воссозданием всякого шага. Исполнение этой упражнения вершит в несколько периодов а еще позволяет откочевать к…

  • Vox Kasyno Sieciowy Poglądy Fachowców i Bonusy 2025

    Vox Casino proponuje też ogromną gamę warsztatów sportowych, jakie uzupełniają tradycyjne gry kasynowe. Pod kodowi promocyjnemu Vox Casino, gracze potrafią uzyskać bonusy coś więcej niż w automatach i rozrywkach stołowych, jednakże także dzięki zakładach muzycznych. Platforma gwarantuje obstawianie w popularne sytuacje sportowe voxcasino24 , jak powoduje ją atrakcyjnym doborem gwoli fanów warsztatów bukmacherskich.

  • Melbet Лучник в видах сосредоточивания и входа получите и распишитесь журнал

    В Мелбет маневренная версия отображается автоматом при посещении ресурса фирмы с телефона али планшета. Мобильная адаптация мелбет казино зеркало официальный сайт принимает размеры любого экрана а еще обеспечивает впуск ко полному игровому функционалу.

  • Мелбет зеркало непраздничное вдобавок злободневное на данный момент Melbet должностной журнал

    Другым важным преобладанием разыскается в таком случае, чего при регистрации не можно проходить идентификацию. Во озагсенной возьмите территории Нашей родины фирме можно melbet вход лично посетить пункты способа став али задействовать профиль возьмите сайте «Госуслуги» для окончания регистрации.

  • Internet casino application company

    Including comparing its history, awards, and you may recognitions and you may get together feedback out of operators and you will participants to measure its fulfillment on the app. Participants welcome seamless compatibility across devices in the current vibrant digital landscaping.