Beispiel #1
0
def updateGeoRepKeys(userName, geoRepPubKeys):
    try:
        userInfo = getpwnam(userName)
        homeDir = userInfo[5]
        uid = userInfo[2]
        gid = userInfo[3]
    except KeyError as e:
        raise ge.GlusterGeoRepUserNotFoundException(err=[str(e)])

    sshDir = homeDir + "/.ssh"
    authKeysFile = sshDir + "/authorized_keys"

    if not os.path.exists(sshDir):
        try:
            os.makedirs(sshDir, 0o700)
            os.chown(sshDir, uid, gid)
            if selinux.is_selinux_enabled():
                selinux.restorecon(sshDir)
        except OSError as e:
            raise ge.GlusterGeoRepPublicKeyWriteFailedException(err=[str(e)])

    newKeys = [" ".join(l.split()[:-1]) for l in geoRepPubKeys]
    newKeyDict = dict(zip(newKeys, geoRepPubKeys))

    try:
        with open(authKeysFile) as f:
            existingKeyLines = f.readlines()
    except IOError as e:
        if e.errno == errno.ENOENT:
            existingKeyLines = []
        else:
            raise ge.GlusterGeoRepPublicKeyWriteFailedException(err=[str(e)])

    try:
        existingKeys = [" ".join(l.split()[:-1]) for l in existingKeyLines]
        existingKeyDict = dict(zip(existingKeys, existingKeyLines))

        outLines = existingKeyLines
        outKeys = set(newKeyDict).difference(set(existingKeyDict))
        outLines.extend([newKeyDict[k] for k in outKeys if newKeyDict[k]])

        safeWrite(authKeysFile, ''.join(outLines))
        os.chmod(authKeysFile, 0o600)
        os.chown(authKeysFile, uid, gid)
        if selinux.is_selinux_enabled():
            selinux.restorecon(authKeysFile)
    except (IOError, OSError) as e:
        raise ge.GlusterGeoRepPublicKeyWriteFailedException(err=[str(e)])
    def __init__(self):
        self.tabs = []
        self.xml = xml
        xml.signal_connect("on_quit_activate", self.destroy)
        xml.signal_connect("on_delete_clicked", self.delete)
        xml.signal_connect("on_add_clicked", self.add)
        xml.signal_connect("on_properties_clicked", self.properties)
        xml.signal_connect("on_local_clicked", self.on_local_clicked)
        self.add_page(statusPage.statusPage(xml))
        if selinux.is_selinux_enabled() > 0:
            try:
                self.add_page(booleansPage.booleansPage(xml))
                self.add_page(fcontextPage.fcontextPage(xml))
                self.add_page(loginsPage.loginsPage(xml))
                self.add_page(usersPage.usersPage(xml))
                self.add_page(portsPage.portsPage(xml))
                self.add_page(modulesPage.modulesPage(xml))  # modules
                self.add_page(domainsPage.domainsPage(xml))  # domains
            except ValueError as e:
                self.error(e.message)

        xml.signal_connect("on_quit_activate", self.destroy)
        xml.signal_connect("on_policy_activate", self.policy)
        xml.signal_connect("on_logging_activate", self.logging)
        xml.signal_connect("on_about_activate", self.on_about_activate)

        self.add_menu = xml.get_widget("add_menu_item")
        self.properties_menu = xml.get_widget("properties_menu_item")
        self.delete_menu = xml.get_widget("delete_menu_item")
def run(options={}):
    """main loop for this plugin"""

    _success = 1
    _message = 'toggle unsuccessful, selinux setting unchanged'

    if 'dryrun' in options:
        if options['dryrun'] == True:
            _success = 0
            _message = 'I would have toggled selinux enforcing setting'
            return _success, _message

    # First, is SELinux available on this system?
    if selinux.is_selinux_enabled():
        try:
            is_enforce = selinux.security_getenforce()
        except OSError:
            _success, _message = 1, 'SELinux is not available on this host'
            return _success, _message
    else:
        print 'selinux disabled, will not be able to toggle setting'
        sys.exit(1)

    _success, _message = toggle_selinux(is_enforce)
    return _success, _message
 def selinux_enabled(self):
     if not HAVE_SELINUX:
         return False
     if selinux.is_selinux_enabled() == 1:
         return True
     else:
         return False
Beispiel #5
0
def symlink_atomically(srcpath, dstpath, force=False, preserve_context=True):
    """Create a symlink, optionally replacing dstpath atomically, optionally
    setting or preserving SELinux context."""

    dstdname = os.path.dirname(dstpath)
    dstbname = os.path.basename(dstpath)

    run_restorecon = False
    ctx = None

    if preserve_context and selinux.is_selinux_enabled() <= 0:
        preserve_context = False
    else:
        try:
            ret, ctx = selinux.lgetfilecon(dstpath)
            if ret < 0:
                raise RuntimeError("getfilecon(%r) failed" % dstpath)
        except OSError as e:
            if e.errno == errno.ENOENT:
                run_restorecon = True
            else:
                raise

    if not force:
        os.symlink(srcpath, dstpath)
        if preserve_context:
            selinux.restorecon(dstpath)
    else:
        dsttmp = None
        for attempt in range(tempfile.TMP_MAX):
            _dsttmp = tempfile.mktemp(
                prefix=dstbname + os.extsep, dir=dstdname)
            try:
                os.symlink(srcpath, _dsttmp)
            except OSError as e:
                if e.errno == errno.EEXIST:
                    # try again
                    continue
                raise
            else:
                dsttmp = _dsttmp
                break

        if dsttmp is None:
            raise IOError(
                errno.EEXIST,
                "No suitable temporary symlink could be created.")

        if preserve_context and not run_restorecon:
            selinux.lsetfilecon(dsttmp, ctx)

        try:
            os.rename(dsttmp, dstpath)
        except:
            # clean up
            os.remove(dsttmp)
            raise

        if run_restorecon:
            selinux.restorecon(dstpath)
Beispiel #6
0
    def read_cmdline(self):
        for f in ("selinux", "debug", "leavebootorder", "testing", "extlinux",
                  "nombr", "gpt", "noefi"):
            self.set_cmdline_bool(f)

        if not selinux.is_selinux_enabled():
            self.selinux = 0
Beispiel #7
0
    def diff(self, file_struct):
        self._validate_struct(file_struct)

        temp_file, temp_dirs = self.process(file_struct)
        path = file_struct['path']
        sectx_result = ''
        result = ''

        try:
            cur_sectx = lgetfilecon(path)[1]
        except OSError: # workarounding BZ 690238
            cur_sectx = None
        if not is_selinux_enabled():
            cur_sectx = None

        if cur_sectx == None:
            cur_sectx = ''

        if file_struct.has_key('selinux_ctx') and file_struct['selinux_ctx']:
            if cur_sectx != file_struct['selinux_ctx']:
                sectx_result = "SELinux contexts differ:  actual: [%s], expected: [%s]\n" % (cur_sectx, file_struct['selinux_ctx'])

        if file_struct['filetype'] == 'symlink':
            try:
                curlink = os.readlink(path)
                newlink = os.readlink(temp_file)
                if curlink == newlink:
                    result = ''
                else:
                    result = "Link targets differ for [%s]: actual: [%s], expected: [%s]\n" % (path, curlink, newlink)
            except OSError, e:
                if e.errno == 22:
                    result = "Deployed symlink is no longer a symlink!"
                else:
                    raise e
 def get_current_mode(self):
     if selinux.is_selinux_enabled():
         if selinux.security_getenforce() > 0:
             return ENFORCING
         else:
             return PERMISSIVE
     else:
         return DISABLED
Beispiel #9
0
def default_container_context():
    if selinux.is_selinux_enabled() != 0:
        fd = open(selinux.selinux_lxc_contexts_path())
        for i in fd.readlines():
            name, context = i.split("=")
            if name.strip() == "file":
                return context.strip("\n\" ")
    return ""
Beispiel #10
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(type='str', required=True),
            persistent=dict(type='bool', default=False),
            state=dict(type='bool', required=True),
        ),
        supports_check_mode=True,
    )

    if not HAVE_SELINUX:
        module.fail_json(msg="This module requires libselinux-python support")

    if not HAVE_SEMANAGE:
        module.fail_json(msg="This module requires libsemanage-python support")

    if not selinux.is_selinux_enabled():
        module.fail_json(msg="SELinux is disabled on this host.")

    name = module.params['name']
    persistent = module.params['persistent']
    state = module.params['state']

    result = dict(
        name=name,
    )

    if hasattr(selinux, 'selinux_boolean_sub'):
        # selinux_boolean_sub allows sites to rename a boolean and alias the old name
        # Feature only available in selinux library since 2012.
        name = selinux.selinux_boolean_sub(name)

    if not has_boolean_value(module, name):
        module.fail_json(msg="SELinux boolean %s does not exist." % name)

    cur_value = get_boolean_value(module, name)

    if cur_value == state:
        module.exit_json(changed=False, state=cur_value, **result)

    if module.check_mode:
        module.exit_json(changed=True)

    if persistent:
        r = semanage_boolean_value(module, name, state)
    else:
        r = set_boolean_value(module, name, state)

    result['changed'] = r
    if not r:
        module.fail_json(msg="Failed to set boolean %s to %s" % (name, state))
    try:
        selinux.security_commit_booleans()
    except:
        module.fail_json(msg="Failed to commit pending boolean %s value" % name)

    module.exit_json(**result)
Beispiel #11
0
    def __init__(self):
        #
        # mode of operation
        #
        self.testing = False
        self.debug = False

        #
        # minor modes
        #
        self.uevents = False

        #
        # enable/disable functionality
        #
        self.selinux = selinux.is_selinux_enabled()
        self.multipath = True
        self.dmraid = True
        self.ibft = True
        self.noiswmd = False

        self.gfs2 = True
        self.jfs = True
        self.reiserfs = True

        # for this flag to take effect,
        # blockdev.mpath.set_friendly_names(flags.multipath_friendly_names) must
        # be called prior to calling Blivet.reset() or DeviceTree.populate()
        self.multipath_friendly_names = True

        # set to False since automatic updates of a device's information
        # or state should not be necessary by default
        self.auto_dev_updates = False

        # set to False by default since a forced reset for file contexts
        # is ordinary not necessary
        self.selinux_reset_fcon = False

        # set to True since we want to keep these around by default
        self.keep_empty_ext_partitions = True

        # set to False to suppress the default LVM behavior of saving
        # backup metadata in /etc/lvm/{archive,backup}
        self.lvm_metadata_backup = True

        # whether to include nodev filesystems in the devicetree
        self.include_nodev = False

        # whether to enable discard for newly created devices
        # (so far only for LUKS)
        self.discard_new = False

        self.boot_cmdline = {}

        self.update_from_boot_cmdline()
        self.allow_imperfect_devices = True
        self.debug_threads = False
Beispiel #12
0
 def test_default_container_context(self):
     default = util.default_container_context()
     if selinux.is_selinux_enabled():
         # newer policies use container_file_t
         self.assertTrue(default in
                         ['system_u:object_r:container_file_t:s0',
                          'system_u:object_r:svirt_sandbox_file_t:s0'])
     else:
         self.assertEqual(default, '')
Beispiel #13
0
def overwrite_safely(path, content, preserve_mode=True, preserve_context=True):
    """Safely overwrite a file by creating a temporary file in the same
    directory, writing it, moving it over the original file, eventually
    preserving file mode and SELinux context."""

    path = os.path.realpath(path)
    dir_ = os.path.dirname(path)
    base = os.path.basename(path)

    fd = None
    f = None
    tmpname = None

    exists = os.path.exists(path)

    if preserve_context and selinux.is_selinux_enabled() <= 0:
        preserve_context = False

    try:
        fd, tmpname = tempfile.mkstemp(prefix=base + os.path.extsep,
                                       dir=dir_)

        if exists and preserve_mode:
            shutil.copymode(path, tmpname)

        if exists and preserve_context:
            ret, ctx = selinux.getfilecon(path)
            if ret < 0:
                raise RuntimeError("getfilecon(%r) failed" % path)

        f = os.fdopen(fd, "w")
        fd = None

        f.write(content)

        f.close()
        f = None

        os.rename(tmpname, path)

        if preserve_context:
            if exists:
                selinux.setfilecon(path, ctx)
            else:
                selinux.restorecon(path)

    finally:
        if f:
            f.close()
        elif fd:
            os.close(fd)
        if tmpname and os.path.isfile(tmpname):
            try:
                os.unlink(tmpname)
            except:
                pass
Beispiel #14
0
    def read_cmdline(self):
        for f in ("selinux", "debug", "leavebootorder", "testing", "extlinux",
                  "gpt", "dnf"):
            self.set_cmdline_bool(f)

        if "rpmarch" in self.cmdline:
            self.targetarch = self.cmdline.get("rpmarch")

        if not selinux.is_selinux_enabled():
            self.selinux = 0
 def _late_setup(self):
     self._selinux_enabled = selinux.is_selinux_enabled()
     if not os.path.exists(ohostedcons.FileLocations.VDSMCERT):
         self._generateVDSMcerts()
         self._copy_vdsm_pki()
     if not os.path.exists(
         ohostedcons.FileLocations.LIBVIRT_SPICE_SERVER_CERT
     ):
         self._generateSPICEcerts()
     self._getSPICEcerts()
Beispiel #16
0
def main():
    module = AnsibleModule(
        argument_spec={
                'ports': {
                    'required': True,
                },
                'proto': {
                    'required': True,
                    'choices': ['tcp', 'udp'],
                },
                'setype': {
                    'required': True,
                },
                'state': {
                    'required': True,
                    'choices': ['present', 'absent'],
                },
                'reload': {
                    'required': False,
                    'type': 'bool',
                    'default': 'yes',
                },
            },
        supports_check_mode=True
    )
    if not HAVE_SELINUX:
        module.fail_json(msg="This module requires libselinux-python")

    if not HAVE_SEOBJECT:
        module.fail_json(msg="This module requires policycoreutils-python")

    if not selinux.is_selinux_enabled():
        module.fail_json(msg="SELinux is disabled on this host.")

    ports = [x.strip() for x in str(module.params['ports']).split(',')]
    proto = module.params['proto']
    setype = module.params['setype']
    state = module.params['state']
    do_reload = module.params['reload']

    result = {
        'ports': ports,
        'proto': proto,
        'setype': setype,
        'state': state,
    }

    if state == 'present':
        result['changed'] = semanage_port_add(module, ports, proto, setype, do_reload)
    elif state == 'absent':
        result['changed'] = semanage_port_del(module, ports, proto, setype, do_reload)
    else:
        module.fail_json(msg='Invalid value of argument "state": {0}'.format(state))

    module.exit_json(**result)
Beispiel #17
0
    def selinux_role(self):
        """Setup proper selinux role.

        this must be called at beginning of process
        to adjust proper roles for selinux.
        it will re-execute the process with same arguments.

        This has similar effect of:
        # chcon -t rpm_exec_t executable.py

        We must do this dynamic as this class is to be
        used at bootstrap stage, so we cannot put any
        persistent selinux policy changes, and have no clue
        if filesystem where we put scripts supports extended
        attributes, or if we have proper role for chcon.

        """

        try:
            import selinux
        except ImportError:
            with self.transaction():
                self.install(['libselinux-python'])
                if self.buildTransaction():
                    self.processTransaction()
            #
            # on fedora-18 for example
            # the selinux core is updated
            # so we fail resolving symbols
            # solution is re-execute the process
            # after installation.
            #
            self._sink.reexec()
            os.execv(sys.executable, [sys.executable] + sys.argv)
            os._exit(1)

        if selinux.is_selinux_enabled():
            rc, ctx = selinux.getcon()
            if rc != 0:
                raise Exception(_('Cannot get selinux context'))
            ctx1 = selinux.context_new(ctx)
            if not ctx1:
                raise Exception(_('Cannot create selinux context'))
            if selinux.context_role_get(ctx1) != 'system_r':
                if selinux.context_role_set(ctx1, 'system_r') != 0:
                    raise Exception(
                        _('Cannot set role within selinux context')
                    )
                if selinux.setexeccon(selinux.context_str(ctx1)) != 0:
                    raise Exception(
                        _('Cannot set selinux exec context')
                    )
                self._sink.reexec()
                os.execv(sys.executable, [sys.executable] + sys.argv)
                os._exit(1)
Beispiel #18
0
    def __copy_from_user(self, user_path, profile_path):
        global has_selinux
        os.chown(user_path, os.geteuid(), os.getegid())
        shutil.move(user_path, profile_path)
        if has_selinux:
            if selinux.is_selinux_enabled() > 0:
                rc, con = selinux.matchpathcon(profile_path, 0)
                if rc == 0:
                    selinux.setfilecon(profile_path, con)

        dprint("Moved %s back from %s", user_path, profile_path)
def silent_restorecon(path):
    """Execute selinux restorecon cmd to determined file
    Args
    path -- full path to file
    """

    try:
        if selinux.is_selinux_enabled():
            selinux.restorecon(path)
    except:
        __PRINT_AND_LOG("restorecon {p} failed".format(p=path), "error")
Beispiel #20
0
def _silent_restorecon(path):
    """Execute selinux restorecon cmd to determined file

    Args
    path -- full path to file
    """

    try:
        if selinux.is_selinux_enabled():
            selinux.restorecon(path)
    except:
        _LOG.error("restorecon %s failed" % path)
    def _early_customization(self):
        self.dialog.note(
            _(
                'During customization use CTRL-D to abort.'
            )
        )
        self.cli = self.environment[ohostedcons.VDSMEnv.VDS_CLI]
        self._check_existing_pools()
        domain_type = self.environment[ohostedcons.StorageEnv.DOMAIN_TYPE]
        if domain_type is None:
            domain_type = self.dialog.queryString(
                name='OVEHOSTED_STORAGE_DOMAIN_TYPE',
                note=_(
                    'Please specify the storage '
                    'you would like to use (@VALUES@)[@DEFAULT@]: '
                ),
                prompt=True,
                caseSensitive=True,
                validValues=(
                    ohostedcons.DomainTypes.GLUSTERFS,
                    ohostedcons.DomainTypes.ISCSI,
                    ohostedcons.DomainTypes.FC,
                    ohostedcons.DomainTypes.NFS3,
                    ohostedcons.DomainTypes.NFS4,
                ),
                default=ohostedcons.DomainTypes.NFS3,
            )

        if domain_type == ohostedcons.DomainTypes.NFS3:
            self.storageType = ohostedcons.VDSMConstants.NFS_DOMAIN
            self.protocol_version = 3
        elif domain_type == ohostedcons.DomainTypes.NFS4:
            self.storageType = ohostedcons.VDSMConstants.NFS_DOMAIN
            self.protocol_version = 4
        elif domain_type == ohostedcons.DomainTypes.GLUSTERFS:
            self.storageType = ohostedcons.VDSMConstants.GLUSTERFS_DOMAIN
        elif domain_type == ohostedcons.DomainTypes.ISCSI:
            self.storageType = ohostedcons.VDSMConstants.ISCSI_DOMAIN
        elif domain_type == ohostedcons.DomainTypes.FC:
            self.storageType = ohostedcons.VDSMConstants.FC_DOMAIN

        else:
            raise RuntimeError(
                _(
                    'Invalid domain type: "{dtype}"'
                ).format(
                    dtype=self.environment[
                        ohostedcons.StorageEnv.DOMAIN_TYPE
                    ],
                )
            )
        self.environment[ohostedcons.StorageEnv.DOMAIN_TYPE] = domain_type
        self._selinux_enabled = selinux.is_selinux_enabled()
Beispiel #22
0
    def read_cmdline(self):
        for f in ("selinux", "debug"):
            self.set_cmdline_bool(f)

        if "rpmarch" in self.cmdline:
            self.targetarch = self.cmdline.get("rpmarch")

        if not selinux.is_selinux_enabled():
            self.selinux = 0

        if "gpt" in self.cmdline:
            self.gpt = True
Beispiel #23
0
 def selinux_enabled(self):
     if not HAVE_SELINUX:
         seenabled = self.get_bin_path('selinuxenabled')
         if seenabled is not None:
             (rc,out,err) = self.run_command(seenabled)
             if rc == 0:
                 self.fail_json(msg="Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!")
         return False
     if selinux.is_selinux_enabled() == 1:
         return True
     else:
         return False
Beispiel #24
0
def copyfile(srcpath, dstpath, copy_mode_from_dst=True, run_restorecon=True):
    """Copy srcpath to dstpath.

    Abort operation if e.g. not enough space is available.  Attempt to
    atomically replace dstpath if it exists."""

    if issamefile(srcpath, dstpath, catch_stat_exceptions=OSError):
        return

    dstpath = os.path.abspath(dstpath)
    dstdname = os.path.dirname(dstpath)
    dstbname = os.path.basename(dstpath)

    srcfile = open(srcpath, "rb")
    dsttmpfile = tempfile.NamedTemporaryFile(
        prefix=dstbname + os.path.extsep, dir=dstdname, delete=False)

    mode_copied = False

    if copy_mode_from_dst:

        # attempt to copy mode from destination file (if it exists,
        # otherwise fall back to copying it from the source file below)

        try:
            shutil.copymode(dstpath, dsttmpfile.name)
            mode_copied = True
        except (shutil.Error, OSError):
            pass

    if not mode_copied:
        shutil.copymode(srcpath, dsttmpfile.name)

    data = None

    while data != "":
        data = srcfile.read(BLOCKSIZE)
        try:
            dsttmpfile.write(data)
        except:
            srcfile.close()
            dsttmpfile.close()
            os.unlink(dsttmpfile.name)
            raise

    srcfile.close()
    dsttmpfile.close()

    os.rename(dsttmpfile.name, dstpath)

    if run_restorecon and selinux.is_selinux_enabled() > 0:
        selinux.restorecon(dstpath)
Beispiel #25
0
    def __init__(self):
        #
        # mode of operation
        #
        self.testing = False
        self.installer_mode = False
        self.debug = False

        #
        # minor modes
        #
        self.uevents = False

        #
        # minor modes (installer-specific)
        #
        self.automated_install = False
        self.live_install = False
        self.image_install = False

        #
        # enable/disable functionality
        #
        self.selinux = selinux.is_selinux_enabled()
        self.multipath = True
        self.dmraid = True
        self.ibft = True
        self.noiswmd = False

        self.gfs2 = True
        self.jfs = True
        self.reiserfs = True

        self.arm_platform = None

        self.gpt = False

        self.multipath_friendly_names = True

        # set to False to suppress the default LVM behavior of saving
        # backup metadata in /etc/lvm/{archive,backup}
        self.lvm_metadata_backup = True

        # whether to include nodev filesystems in the devicetree (only
        # meaningful when flags.installer_mode is False)
        self.include_nodev = False

        self.boot_cmdline = {}

        self.update_from_boot_cmdline()
        self.allow_imperfect_devices = True
        self.debug_threads = False
Beispiel #26
0
    def collect(self, module=None, collected_facts=None):
        facts_dict = {}
        selinux_facts = {}

        # If selinux library is missing, only set the status and selinux_python_present since
        # there is no way to tell if SELinux is enabled or disabled on the system
        # without the library.
        if not HAVE_SELINUX:
            selinux_facts['status'] = 'Missing selinux Python library'
            facts_dict['selinux'] = selinux_facts
            facts_dict['selinux_python_present'] = False
            return facts_dict

        # Set a boolean for testing whether the Python library is present
        facts_dict['selinux_python_present'] = True

        if not selinux.is_selinux_enabled():
            selinux_facts['status'] = 'disabled'
        else:
            selinux_facts['status'] = 'enabled'

            try:
                selinux_facts['policyvers'] = selinux.security_policyvers()
            except (AttributeError, OSError):
                selinux_facts['policyvers'] = 'unknown'

            try:
                (rc, configmode) = selinux.selinux_getenforcemode()
                if rc == 0:
                    selinux_facts['config_mode'] = SELINUX_MODE_DICT.get(configmode, 'unknown')
                else:
                    selinux_facts['config_mode'] = 'unknown'
            except (AttributeError, OSError):
                selinux_facts['config_mode'] = 'unknown'

            try:
                mode = selinux.security_getenforce()
                selinux_facts['mode'] = SELINUX_MODE_DICT.get(mode, 'unknown')
            except (AttributeError, OSError):
                selinux_facts['mode'] = 'unknown'

            try:
                (rc, policytype) = selinux.selinux_getpolicytype()
                if rc == 0:
                    selinux_facts['type'] = policytype
                else:
                    selinux_facts['type'] = 'unknown'
            except (AttributeError, OSError):
                selinux_facts['type'] = 'unknown'

        facts_dict['selinux'] = selinux_facts
        return facts_dict
Beispiel #27
0
    def _silent_restorecon(self, path):
        """
        Execute selinux restorecon cmd to determined file

        Args
        path -- full path to file
        """

        try:
            if selinux.is_selinux_enabled():
                selinux.restorecon(path)
        except:
            self.logger.error("restorecon %s failed" % path, exc_info=True)
Beispiel #28
0
def main():
    module = AnsibleModule(
        argument_spec = dict(
            name=dict(required=True),
            persistent=dict(default='no', type='bool'),
            state=dict(required=True, type='bool')
        ),
        supports_check_mode=True
    )

    if not HAVE_SELINUX:
        module.fail_json(msg="This module requires libselinux-python support")

    if not HAVE_SEMANAGE:
        module.fail_json(msg="This module requires libsemanage-python support")

    if not selinux.is_selinux_enabled():
        module.fail_json(msg="SELinux is disabled on this host.")

    name = module.params['name']
    persistent = module.params['persistent']
    state = module.params['state']
    result = {}
    result['name'] = name

    if not has_boolean_value(module, name):
        module.fail_json(msg="SELinux boolean %s does not exist." % name)

    cur_value = get_boolean_value(module, name)

    if cur_value == state:
        result['state'] = cur_value
        result['changed'] = False
        module.exit_json(**result)

    if module.check_mode:
        module.exit_json(changed=True)
    if persistent:
        r = semanage_boolean_value(module, name, state)
    else:
        r = set_boolean_value(module, name, state)

    result['changed'] = r
    if not r:
        module.fail_json(msg="Failed to set boolean %s to %s" % (name, value))
    try:
        selinux.security_commit_booleans()
    except:
        module.fail_json(msg="Failed to commit pending boolean %s value" % name)
    module.exit_json(**result)
Beispiel #29
0
    def __create_selinuxfs(self):
        arglist = ["/bin/mount", "--bind", "/dev/null", self._instroot + self.__selinux_mountpoint + "/load"]
        subprocess.call(arglist, close_fds = True)

        if kickstart.selinux_enabled(self.ks):
            # label the fs like it is a root before the bind mounting
            arglist = ["/sbin/setfiles", "-F", "-r", self._instroot, selinux.selinux_file_context_path(), self._instroot]
            subprocess.call(arglist, close_fds = True)
            # these dumb things don't get magically fixed, so make the user generic
        # if selinux exists on the host we need to lie to the chroot
        if selinux.is_selinux_enabled():
            for f in ("/proc", "/sys"):
                arglist = ["/usr/bin/chcon", "-u", "system_u", self._instroot + f]
                subprocess.call(arglist, close_fds = True)
Beispiel #30
0
def selinux_context(path):
    context = [None, None, None, None]
    if HAVE_SELINUX and selinux.is_selinux_enabled():
        try:
            # note: the selinux module uses byte strings on python2 and text
            # strings on python3
            ret = selinux.lgetfilecon_raw(to_native(path))
        except OSError:
            return context
        if ret[0] != -1:
            # Limit split to 4 because the selevel, the last in the list,
            # may contain ':' characters
            context = ret[1].split(':', 3)
    return context
def main():

    module = AnsibleModule(argument_spec=dict(
        policy=dict(required=False),
        state=dict(choices=['enforcing', 'permissive', 'disabled'],
                   required=True),
        configfile=dict(aliases=['conf', 'file'],
                        default='/etc/selinux/config')),
                           supports_check_mode=True)

    # global vars
    changed = False
    msgs = []
    configfile = module.params['configfile']
    policy = module.params['policy']
    state = module.params['state']
    runtime_enabled = selinux.is_selinux_enabled()
    runtime_policy = selinux.selinux_getpolicytype()[1]
    runtime_state = 'disabled'
    if (runtime_enabled):
        # enabled means 'enforcing' or 'permissive'
        if (selinux.security_getenforce()):
            runtime_state = 'enforcing'
        else:
            runtime_state = 'permissive'
    config_policy = get_config_policy(configfile)
    config_state = get_config_state(configfile)

    # check to see if policy is set if state is not 'disabled'
    if (state != 'disabled'):
        if not policy:
            module.fail_json(
                msg='policy is required if state is not \'disabled\'')
    else:
        if not policy:
            policy = config_policy

    # check changed values and run changes
    if (policy != runtime_policy):
        if module.check_mode:
            module.exit_json(changed=True)
        # cannot change runtime policy
        msgs.append('reboot to change the loaded policy')
        changed = True

    if (policy != config_policy):
        if module.check_mode:
            module.exit_json(changed=True)
        msgs.append('config policy changed from \'%s\' to \'%s\'' %
                    (config_policy, policy))
        set_config_policy(policy, configfile)
        changed = True

    if (state != runtime_state):
        if module.check_mode:
            module.exit_json(changed=True)
        if (state == 'disabled'):
            msgs.append('state change will take effect next reboot')
        else:
            if (runtime_enabled):
                set_state(state)
                msgs.append('runtime state changed from \'%s\' to \'%s\'' %
                            (runtime_state, state))
            else:
                msgs.append('state change will take effect next reboot')
        changed = True

    if (state != config_state):
        if module.check_mode:
            module.exit_json(changed=True)
        msgs.append('config state changed from \'%s\' to \'%s\'' %
                    (config_state, state))
        set_config_state(state, configfile)
        changed = True

    module.exit_json(changed=changed,
                     msg=', '.join(msgs),
                     configfile=configfile,
                     policy=policy,
                     state=state)
Beispiel #32
0
    def client(self, cache, job):
        """Run cache echo command operation.

        :param cache: Caching object used to template items within a command.
        :type cache: Object
        :param job: Information containing the original job specification.
        :type job: Dictionary
        :returns: tuple
        """

        if not selinux.is_selinux_enabled():
            return (None, "SELinux is not enabled.", True, None)

        if not AVAILABLE_SELINUX:
            return (
                None,
                "The required selinux library is not installed",
                False,
                None,
            )

        if not AVAILABLE_SEOBJECT:
            return (
                None,
                "The required seobject library is not installed",
                False,
                None,
            )

        target = job["target"]
        ftype = job.get("ftype")
        setype = job["setype"]
        seuser = job.get("seuser")
        selevel = job.get("selevel")

        secontext = seobject.fcontextRecords("")
        secontext.set_reload(job["reload"])

        (
            existing,
            orig_seuser,
            orig_selevel,
        ) = self.semanage_exists(secontext, target, ftype)

        if existing:
            if not seuser:
                seuser = orig_seuser

            if not selevel:
                selevel = orig_selevel

            secontext.modify(target, setype, ftype, selevel, seuser)
        else:
            if not seuser:
                seuser = "******"

            if not selevel:
                selevel = "s0"

            secontext.add(target, setype, ftype, selevel, seuser)

        return job["target"], None, True, None
Beispiel #33
0
# All rights reserved.
#

from __future__ import absolute_import
import selinux
import sys
import time

# PKI Deployment Imports
from .. import pkiconfig as config
from ..pkiconfig import pki_selinux_config_ports as ports
from .. import pkimessages as log
from .. import pkiscriptlet

seobject = None
if selinux.is_selinux_enabled():
    try:
        import seobject
    except ImportError:
        # TODO: Fedora 22 has an incomplete Python 3 package
        # sepolgen is missing.
        if sys.version_info.major == 2:
            raise


# PKI Deployment Selinux Setup Scriptlet
class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):

    suffix = "(/.*)?"

    def restore_context(self, mdict):
Beispiel #34
0
    def make_stat_info(self, path, file_stat):
        # Returns the stat information as required by the API
        ret = {}
        fields = {
            'mode': stat.ST_MODE,
            'user': stat.ST_UID,
            'group': stat.ST_GID,
            'size': stat.ST_SIZE,
            'mtime': stat.ST_MTIME,
            'ctime': stat.ST_CTIME,
        }
        for label, st in fields.items():
            ret[label] = file_stat[st]

        # server expects things like 644, 700, etc.
        ret['mode'] = deci_to_octal(ret['mode'] & 07777)

        #print ret['size']
        #if ret['size'] > self.get_maximum_file_size():
        #    die(4, "File %s exceeds the maximum file size (%s)" %
        #        (path, ret['size']))

        uid = ret['user']
        gid = ret['group']

        pw_name = self._uid_cache.get(uid)
        if not pw_name:
            try:
                pw_name = pwd.getpwuid(uid)[0]
            except KeyError:
                print "Error looking up user id %s" % (uid, )

        if pw_name:
            ret['user'] = pw_name
            self._uid_cache[uid] = pw_name

        gr_name = self._gid_cache.get(gid)
        if not gr_name:
            try:
                gr_name = grp.getgrgid(gid)[0]
            except KeyError:
                print "Error looking up group id %s" % (gid, )

        if gr_name:
            ret['group'] = gr_name
            self._gid_cache[gid] = gr_name

        # if selinux is disabled or on RHEL4 we do not send the selinux_ctx
        # flag at all - see bug 644985 - SELinux context cleared from
        # RHEL4 rhncfg-client
        try:
            selinux_ctx = lgetfilecon(path)[1]
        except OSError:
            selinux_ctx = None

        if is_selinux_enabled():
            ret['selinux_ctx'] = selinux_ctx
        else:
            ret['selinux_ctx'] = ''

        return ret
Beispiel #35
0
def selinux_label_port(port, remove_label=False):
    """
    Either set or remove an SELinux label(ldap_port_t) for a TCP port

    :param port: The TCP port to be labeled
    :type port: str
    :param remove_label: Set True if the port label should be removed
    :type remove_label: boolean
    :raises: ValueError: Error message
    """
    try:
        import selinux
    except ImportError:
        log.debug('selinux python module not found, skipping port labeling.')
        return

    if not selinux.is_selinux_enabled():
        log.debug('selinux is disabled, skipping port relabel')
        return

    # We only label ports that ARE NOT in the default policy that comes with
    # a RH based system.
    port = int(port)
    selinux_default_ports = [389, 636, 3268, 3269, 7389]
    if port in selinux_default_ports:
        log.debug('port {} already in {}, skipping port relabel'.format(
            port, selinux_default_ports))
        return
    label_set = False
    label_ex = None

    policies = _get_selinux_port_policies(port)

    for policy in policies:
        if "ldap_port_t" == policy['type']:
            label_set = True  # Port already has our label
            if port in policy['ports']:
                # The port is within the range, just return
                return
            break
        elif not remove_label:
            # Port belongs to someone else (bad)
            # This is only an issue during setting a label, not removing a label
            raise ValueError(
                "Port {} was already labeled with: ({})  Please choose a different port number"
                .format(port, policy['type']))

    if (remove_label and label_set) or (not remove_label and not label_set):
        for i in range(5):
            try:
                result = subprocess.run([
                    "semanage", "port", "-d" if remove_label else "-a", "-t",
                    "ldap_port_t", "-p", "tcp",
                    str(port)
                ],
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
                args = ' '.join(ensure_list_str(result.args))
                stdout = ensure_str(result.stdout)
                stderr = ensure_str(result.stderr)
                log.debug(f"CMD: {args} ; STDOUT: {stdout} ; STDERR: {stderr}")
                return
            except (OSError, subprocess.CalledProcessError) as e:
                label_ex = e
                time.sleep(3)
        raise ValueError("Failed to mangle port label: " + str(label_ex))
Beispiel #36
0
import os
import selinux
import tempfile
import unittest

import blivet
from tests import loopbackedtestcase
import blivet.formats.fs as fs
from blivet.size import Size


@unittest.skipUnless(selinux.is_selinux_enabled() == 1, "SELinux is disabled")
class SELinuxContextTestCase(loopbackedtestcase.LoopBackedTestCase):

    """Testing SELinux contexts.
    """

    def __init__(self, methodName='run_test'):
        super(SELinuxContextTestCase, self).__init__(methodName=methodName, device_spec=[Size("100 MiB")])

    def setUp(self):
        self.installer_mode = blivet.flags.installer_mode
        super(SELinuxContextTestCase, self).setUp()

    def test_mounting_ext2fs(self):
        """ Test that lost+found directory gets assigned correct SELinux
            context if installer_mode is True, and retains some random old
            context if installer_mode is False.
        """
        LOST_AND_FOUND_CONTEXT = 'system_u:object_r:lost_found_t:s0'
        an_fs = fs.Ext2FS(device=self.loop_devices[0], label="test")
Beispiel #37
0
def selinux_label_port(port, remove_label=False):
    """
    Either set or remove an SELinux label(ldap_port_t) for a TCP port

    :param port: The TCP port to be labelled
    :type port: str
    :param remove_label: Set True if the port label should be removed
    :type remove_label: boolean
    :raises: ValueError: Error message
    """
    try:
        import selinux
    except ImportError:
        log.debug('selinux python module not found, skipping port labeling.')
        return

    try:
        import sepolicy
    except ImportError:
        log.debug('sepolicy python module not found, skipping port labeling.')
        return

    if not selinux.is_selinux_enabled():
        log.debug('selinux is disabled, skipping port relabel')
        return

    # We only label ports that ARE NOT in the default policy that comes with
    # a RH based system.
    selinux_default_ports = [389, 636, 3268, 3269, 7389]
    if port in selinux_default_ports:
        log.debug('port %s already in %s, skipping port relabel' %
                  (port, selinux_default_ports))
        return

    label_set = False
    label_ex = None

    policies = [
        p for p in sepolicy.info(sepolicy.PORT) if p['protocol'] == 'tcp'
        if port in range(p['low'], p['high'] + 1) if p['type'] not in
        ['unreserved_port_t', 'reserved_port_t', 'ephemeral_port_t']
    ]

    for policy in policies:
        if "ldap_port_t" == policy['type']:
            label_set = True  # Port already has our label
            if policy['low'] != policy['high']:
                # We have a range
                if port in range(policy['low'], policy['high'] + 1):
                    # The port is within the range, just return
                    return
            break
        elif not remove_label:
            # Port belongs to someone else (bad)
            # This is only an issue during setting a label, not removing a label
            raise ValueError(
                "Port {} was already labelled with: ({})  Please choose a different port number"
                .format(port, policy['type']))

    if (remove_label and label_set) or (not remove_label and not label_set):
        for i in range(5):

            try:
                subprocess.check_call([
                    "semanage", "port", "-d" if remove_label else "-a", "-t",
                    "ldap_port_t", "-p", "tcp",
                    str(port)
                ])
                return
            except (OSError, subprocess.CalledProcessError) as e:
                label_ex = e
                time.sleep(3)
        raise ValueError("Failed to mangle port label: " + str(label_ex))
Beispiel #38
0
    def destroy(self, deployer):

        if not bool(selinux.is_selinux_enabled()):
            config.pki_log.info(log.SELINUX_DISABLED_DESTROY_1,
                                __name__,
                                extra=config.PKI_INDENTATION_LEVEL_1)
            return self.rv
        config.pki_log.info(log.SELINUX_DESTROY_1,
                            __name__,
                            extra=config.PKI_INDENTATION_LEVEL_1)

        # check first if any transactions are required
        if (len(ports) == 0 and deployer.mdict['pki_instance_name']
                == config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME):
            return self.rv
        # A maximum of 10 tries to delete the SELinux contexts
        counter = 1
        max_tries = 10
        while True:
            try:
                # remove SELinux contexts when removing the last subsystem
                if len(deployer.instance.tomcat_instance_subsystems()) == 0:
                    trans = seobject.semanageRecords("targeted")
                    trans.start()

                    if deployer.mdict['pki_instance_name'] != \
                            config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME:

                        fcon = seobject.fcontextRecords()

                        config.pki_log.info(
                            "deleting selinux fcontext \"%s\"",
                            deployer.mdict['pki_instance_path'] + self.suffix,
                            extra=config.PKI_INDENTATION_LEVEL_2)
                        fcon.delete(
                            deployer.mdict['pki_instance_path'] + self.suffix,
                            "")

                        config.pki_log.info(
                            "deleting selinux fcontext \"%s\"",
                            deployer.mdict['pki_instance_log_path'] +
                            self.suffix,
                            extra=config.PKI_INDENTATION_LEVEL_2)
                        fcon.delete(
                            deployer.mdict['pki_instance_log_path'] +
                            self.suffix, "")

                        config.pki_log.info(
                            "deleting selinux fcontext \"%s\"",
                            deployer.mdict['pki_instance_configuration_path'] +
                            self.suffix,
                            extra=config.PKI_INDENTATION_LEVEL_2)
                        fcon.delete(
                            deployer.mdict['pki_instance_configuration_path'] +
                            self.suffix, "")

                        config.pki_log.info(
                            "deleting selinux fcontext \"%s\"",
                            deployer.mdict['pki_database_path'] + self.suffix,
                            extra=config.PKI_INDENTATION_LEVEL_2)
                        fcon.delete(
                            deployer.mdict['pki_database_path'] + self.suffix,
                            "")

                        port_records = seobject.portRecords()
                        for port in ports:
                            config.pki_log.info(
                                "deleting selinux port %s",
                                port,
                                extra=config.PKI_INDENTATION_LEVEL_2)
                            port_records.delete(port, "tcp")

                    trans.finish()
                break
            except ValueError as e:
                error_message = str(e)
                config.pki_log.debug(error_message)
                if error_message.strip() == \
                        "Could not start semanage transaction":
                    counter += 1
                    if counter >= max_tries:
                        raise
                    time.sleep(5)
                    config.pki_log.debug(
                        "Retrying to remove selinux context ...")
                else:
                    raise

        return self.rv
Beispiel #39
0
#!/usr/bin/python
#
# Copyright (C) 2013
#
# 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, version 2 of the License.
#
# 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.

from selinux import is_selinux_enabled

if is_selinux_enabled():
    print "selinux is enabled"
else:
    print "selinux is disabled"
Beispiel #40
0
    def __init__(self, gate, uuid):
        cpuInfo = read_cpuinfo()
        memory = read_memory()
        self.UUID = uuid
        self.os = gate.process('distro', software.read_os(),
                               WITHHELD_MAGIC_STRING)
        self.defaultRunlevel = gate.process('run_level',
                                            software.read_runlevel(), -1)

        self.bogomips = gate.process('cpu', cpuInfo.get('bogomips', 0), 0)
        self.cpuVendor = gate.process('cpu', cpuInfo.get('type', ''),
                                      WITHHELD_MAGIC_STRING)
        self.cpuModel = gate.process('cpu', cpuInfo.get('model', ''),
                                     WITHHELD_MAGIC_STRING)
        self.cpu_stepping = gate.process('cpu', cpuInfo.get('cpu_stepping', 0),
                                         0)
        self.cpu_family = gate.process('cpu', cpuInfo.get('cpu_family', ''),
                                       '')
        self.cpu_model_num = gate.process('cpu',
                                          cpuInfo.get('cpu_model_num', 0), 0)
        self.numCpus = gate.process('cpu', cpuInfo.get('count', 0), 0)
        self.cpuSpeed = gate.process('cpu', cpuInfo.get('speed', 0), 0)

        self.systemMemory = gate.process('ram_size', memory['ram'], 0)
        self.systemSwap = gate.process('swap_size', memory['swap'], 0)
        self.kernelVersion = gate.process('kernel',
                                          os.uname()[2], WITHHELD_MAGIC_STRING)
        if gate.grants('language'):
            try:
                self.language = os.environ['LANG']
            except KeyError:
                try:
                    status, lang = commands.getstatusoutput(
                        "grep LANG /etc/sysconfig/i18n")
                    if status == 0:
                        self.language = lang.split('"')[1]
                    else:
                        self.language = 'Unknown'
                except:
                    self.language = 'Unknown'
        else:
            self.language = WITHHELD_MAGIC_STRING

        tempform = platform.machine()
        self.platform = gate.process('arch', tempform, WITHHELD_MAGIC_STRING)

        if gate.grants('vendor'):
            #self.systemVendor = hostInfo.get('system.vendor'
            try:
                self.systemVendor = cat(
                    '/sys/devices/virtual/dmi/id/sys_vendor')[0].strip()
            except:
                self.systemVendor = 'Unknown'
        else:
            self.systemVendor = WITHHELD_MAGIC_STRING

        if gate.grants('model'):
            try:
                self.systemModel = cat(
                    '/sys/devices/virtual/dmi/id/product_name'
                )[0].strip() + ' ' + cat(
                    '/sys/devices/virtual/dmi/id/product_version')[0].strip()
            except:
                self.systemModel = 'Unknown'
            #hostInfo was removed with the hal restructure
            #if not self.systemModel:
            #self.systemModel = hostInfo.get('system.hardware.product')
            #if hostInfo.get('system.hardware.version'):
            #self.systemModel += ' ' + hostInfo.get('system.hardware.version')
            #if not self.systemModel:
            #self.systemModel = 'Unknown'
        else:
            self.systemModel = WITHHELD_MAGIC_STRING

        if gate.grants('form_factor'):
            try:
                formfactor_id = int(
                    cat('/sys/devices/virtual/dmi/id/chassis_type')[0].strip())
                self.formfactor = FORMFACTOR_LIST[formfactor_id]
            except:
                self.formfactor = 'Unknown'
        else:
            self.formfactor = WITHHELD_MAGIC_STRING

        if tempform == 'ppc64':
            if hostInfo.get('openfirmware.model'):
                if hostInfo['openfirmware.model'][:3] == 'IBM':
                    self.systemVendor = 'IBM'
                model = hostInfo['openfirmware.model'][4:8]

                model_map = {
                    '8842': 'JS20',
                    '6779': 'JS21',
                    '6778': 'JS21',
                    '7988': 'JS21',
                    '8844': 'JS21',
                    '0200': 'QS20',
                    '0792': 'QS21',
                }
                try:
                    model_name = model_map[model]
                    self.systemModel = gate.process('model', model_name)
                    self.formfactor = gate.process('form_factor', 'Blade')
                except KeyError:
                    pass

        if gate.grants('selinux'):
            try:
                import selinux
                try:
                    if selinux.is_selinux_enabled() == 1:
                        self.selinux_enabled = SELINUX_ENABLED
                    else:
                        self.selinux_enabled = SELINUX_DISABLED
                except:
                    self.selinux_enabled = SELINUX_DISABLED
                try:
                    self.selinux_policy = selinux.selinux_getpolicytype()[1]
                except:
                    self.selinux_policy = "Unknown"
                try:
                    enforce = selinux.security_getenforce()
                    if enforce == 0:
                        self.selinux_enforce = "Permissive"
                    elif enforce == 1:
                        self.selinux_enforce = "Enforcing"
                    elif enforce == -1:
                        self.selinux_enforce = "Disabled"
                    else:
                        self.selinux_enforce = "FUBARD"
                except:
                    self.selinux_enforce = "Unknown"
            except ImportError:
                self.selinux_enabled = SELINUX_DISABLED
                self.selinux_policy = "Not Installed"
                self.selinux_enforce = "Not Installed"
        else:
            self.selinux_enabled = SELINUX_WITHHELD
            self.selinux_policy = WITHHELD_MAGIC_STRING
            self.selinux_enforce = WITHHELD_MAGIC_STRING
Beispiel #41
0
def default_ro_container_context():
    if selinux.is_selinux_enabled() != 0:
        return selinux.getfilecon("/usr")[1]
    return ""
Beispiel #42
0
    def convert_db(self):
        dbtype = self.get_dbtype()
        if dbtype is None:
            raise ValueError(
                "NSS database {} does not exist".format(self.directory)
            )
        elif dbtype == 'sql':
            raise ValueError(
                "NSS database {} already in SQL format".format(self.directory)
            )

        logger.info(
            "Convert NSSDB %s from DBM to SQL format", self.directory
        )

        basecmd = [
            'certutil',
            '-d', 'sql:{}'.format(self.directory),
            '-f', self.password_file,
        ]
        # See https://fedoraproject.org/wiki/Changes/NSSDefaultFileFormatSql
        cmd = basecmd + [
            '-N',
            '-@', self.password_file
        ]

        logger.debug('Command: %s', ' '.join(map(str, cmd)))
        subprocess.check_call(cmd)

        migration = (
            ('cert8.db', 'cert9.db'),
            ('key3.db', 'key4.db'),
            ('secmod.db', 'pkcs11.txt'),
        )

        for oldname, newname in migration:
            oldname = os.path.join(self.directory, oldname)
            newname = os.path.join(self.directory, newname)
            oldstat = os.stat(oldname)
            os.chmod(newname, stat.S_IMODE(oldstat.st_mode))
            os.chown(newname, oldstat.st_uid, oldstat.st_gid)

        if selinux is not None and selinux.is_selinux_enabled():
            selinux.restorecon(self.directory, recursive=True)

        # list certs to verify DB
        if self.get_dbtype() != 'sql':
            raise RuntimeError(
                "Migration of NSS database {} was not successfull.".format(
                    self.directory
                )
            )

        with open(os.devnull, 'wb') as f:
            subprocess.check_call(basecmd + ['-L'], stdout=f)

        for oldname, _ in migration:  # pylint: disable=unused-variable
            oldname = os.path.join(self.directory, oldname)
            os.rename(oldname, oldname + '.migrated')

        logger.info("Migration successful")
Beispiel #43
0
def get_runtime_status(ignore_selinux_state=False):
    return True if ignore_selinux_state is True else selinux.is_selinux_enabled(
    )
Beispiel #44
0
def is_selinux_enabled():
    return selinux.is_selinux_enabled()
Beispiel #45
0
""" Base class for tools that handle POSIX (Path) entries """

import os
import sys
import pwd
import grp
import stat
import copy
import shutil
import Bcfg2.Client.Tools
import Bcfg2.Client.XML
from Bcfg2.Compat import oct_mode

try:
    import selinux
    HAS_SELINUX = selinux.is_selinux_enabled()
except ImportError:
    HAS_SELINUX = False

try:
    import posix1e
    HAS_ACLS = True

    # map between permissions characters and numeric ACL constants
    ACL_MAP = dict(r=posix1e.ACL_READ,
                   w=posix1e.ACL_WRITE,
                   x=posix1e.ACL_EXECUTE)
except ImportError:
    HAS_ACLS = False
    ACL_MAP = dict(r=4, w=2, x=1)
Beispiel #46
0
    def _process_file(self, *args):
        owner_report = "%s:%s"
        group_report = "%s:%s"
        perm_report = "%s:%s"
        selinux_report = "%s|%s"

        src, dst, file, type, info = args[:5]
        owner_status = ""
        group_status = ""
        perm_status = ""
        selinux_status = ""

        status = []
        stat_err = 0
        #Stat the destination file
        try:
            dst_stat = os.lstat(dst)
        except:
            stat_err = 1
        if type != 'symlink':
            src_user = info['username']
            if not stat_err:
                #check for owner differences
                dst_uid = dst_stat[stat.ST_UID]
                try:
                    dst_user = pwd.getpwuid(dst_uid)[0]
                except KeyError:
                    # Orphan UID with no name,return unknown
                    dst_user = "******" % (dst_uid, )
            else:
                dst_user = "******"

            #owner_status gets displayed with the verbose option.
            if src_user == dst_user:
                owner_status = ""
            else:
                owner_status = owner_report % (src_user, dst_user)
                status.append('user')

            src_group = info['groupname']
            if not stat_err:
                #check for group differences
                dst_gid = dst_stat[stat.ST_GID]
                try:
                    dst_group = grp.getgrgid(dst_gid)[0]
                except KeyError:
                    # Orphan GID with no name,return unknown
                    dst_group = "unknown(GID %d)" % (dst_gid, )
            else:
                dst_group = "missing"

            #group_status gets displayed with the verbose option.
            if src_group == dst_group:
                group_status = ""
            else:
                group_status = group_report % (src_group, dst_group)
                status.append('group')

            #check for permissions differences
            src_perm = str(info['filemode'])
            if not stat_err:
                #The mode returned by stat is decimal, but won't match the value in file_info unless it's octal.
                #Unfortunately, the mode in file_info looks like the octal value of the mode, except it's in decimal.
                #The solution I came up with is to convert them both into strings, rip off the leading '0' from the
                #mode returned by stat, use the resulting strings. It sucks, but it seems to work (for now).
                dst_perm = str(oct(stat.S_IMODE(dst_stat[stat.ST_MODE])))
            else:
                dst_perm = "missing"

            #rip off the leading '0' from the mode returned by stat()
            if dst_perm[0] == '0':
                dst_perm = dst_perm[1:]

            #perm_status gets displayed with the verbose option.
            if src_perm == dst_perm:
                perm_status = ""
            else:
                perm_status = perm_report % (src_perm, dst_perm)
                status.append('mode')

        # compare selinux contexts
        if info.has_key('selinux_ctx'):
            src_selinux = info['selinux_ctx']
            if src_selinux:
                if not stat_err:
                    try:
                        dst_selinux = lgetfilecon(dst)[1]
                    except OSError:
                        dst_selinux = ""
                    if not is_selinux_enabled():
                        dst_selinux = ""
                    if dst_selinux == None:
                        dst_selinux = ""
                else:
                    dst_selinux = "missing"

                if src_selinux == dst_selinux:
                    selinux_status = ""
                else:
                    selinux_status = selinux_report % (src_selinux,
                                                       dst_selinux)
                    status.append('selinux')

        #figure out the ultimate value of status.
        if stat_err:
            status = ["missing"]
        elif type == 'symlink':
            if not os.path.islink(file):
                status = ["missing"]
            elif os.readlink(file) != info['symlink']:
                status.append('target-link-modified')
        elif type == 'directory':
            if not os.path.isdir(file):
                status = ["missing"]

        elif not os.access(dst, os.R_OK):
            status = ["missing"]

        else:
            src_sha1 = utils.sha1_file(src)
            dst_sha1 = utils.sha1_file(dst)
            if src_sha1 != dst_sha1:
                status.append('modified')

        return {
            "status": ','.join(status),
            "owner": owner_status,
            "group": group_status,
            "mode": perm_status,
            "selinux": selinux_status,
            "file": file,
        }
Beispiel #47
0
    on_travis_ci,
)


requires_root = pytest.mark.skipif(
    os.geteuid() != 0, reason="requires root")

requires_unprivileged_user = pytest.mark.skipif(
    os.geteuid() == 0, reason="This test can not run as root")

requires_sanlock = pytest.mark.skipif(
    isinstance(sanlock, compat.MissingModule),
    reason="sanlock is not available")

requires_selinux = pytest.mark.skipif(
    not selinux.is_selinux_enabled(), reason="Selinux is not enabled")

xfail_python3 = pytest.mark.xfail(
    six.PY3, reason="needs porting to python 3")

xfail_python37 = pytest.mark.xfail(
    sys.version_info[:2] == (3, 7), reason="needs porting to python 3.7")

# Note: This cannot be strict since in oVirt CI we run with older qemu-img
# version that does not reproduce this issue.
xfail_requires_target_is_zero = pytest.mark.xfail(
    not qemuimg.target_is_zero_supported(),
    reason="requires qemu-img convert --target-is-zero introdued in 5.1.0",
    strict=False)

broken_on_ci = pytest.mark.skipif(
Beispiel #48
0
def have_selinux():
    return bool(selinux) and bool(selinux.is_selinux_enabled())
Beispiel #49
0
 def _validation(self):
     self._selinux_enabled = selinux.is_selinux_enabled()
Beispiel #50
0
    def run(self,
            ybo,
            product,
            version,
            release,
            variant="",
            bugurl="",
            isfinal=False,
            workdir=None,
            outputdir=None,
            buildarch=None,
            volid=None,
            domacboot=True,
            remove_temp=False):

        assert self._configured

        if domacboot:
            try:
                runcmd(["rpm", "-q", "hfsplus-tools"])
            except CalledProcessError:
                logger.critical(
                    "you need to install hfsplus-tools to create mac images")
                sys.exit(1)

        # set up work directory
        self.workdir = workdir or tempfile.mkdtemp(prefix="pylorax.work.")
        if not os.path.isdir(self.workdir):
            os.makedirs(self.workdir)

        # set up log directory
        logdir = '/var/log/lorax'
        if not os.path.isdir(logdir):
            os.makedirs(logdir)

        self.init_stream_logging()
        self.init_file_logging(logdir)
        logger.debug("using work directory {0.workdir}".format(self))
        logger.debug("using log directory {0}".format(logdir))

        # set up output directory
        self.outputdir = outputdir or tempfile.mkdtemp(prefix="pylorax.out.")
        if not os.path.isdir(self.outputdir):
            os.makedirs(self.outputdir)
        logger.debug("using output directory {0.outputdir}".format(self))

        # do we have root privileges?
        logger.info("checking for root privileges")
        if not os.geteuid() == 0:
            logger.critical("no root privileges")
            sys.exit(1)

        # is selinux disabled?
        # With selinux in enforcing mode the rpcbind package required for
        # dracut nfs module, which is in turn required by anaconda module,
        # will not get installed, because it's preinstall scriptlet fails,
        # resulting in an incomplete initial ramdisk image.
        # The reason is that the scriptlet runs tools from the shadow-utils
        # package in chroot, particularly groupadd and useradd to add the
        # required rpc group and rpc user. This operation fails, because
        # the selinux context on files in the chroot, that the shadow-utils
        # tools need to access (/etc/group, /etc/passwd, /etc/shadow etc.),
        # is wrong and selinux therefore disallows access to these files.
        logger.info("checking the selinux mode")
        if selinux.is_selinux_enabled() and selinux.security_getenforce():
            logger.critical("selinux must be disabled or in Permissive mode")
            sys.exit(1)

        # do we have a proper yum base object?
        logger.info("checking yum base object")
        if not isinstance(ybo, yum.YumBase):
            logger.critical("no yum base object")
            sys.exit(1)
        self.inroot = ybo.conf.installroot
        logger.debug("using install root: {0}".format(self.inroot))

        if not buildarch:
            buildarch = get_buildarch(ybo)

        logger.info("setting up build architecture")
        self.arch = ArchData(buildarch)
        for attr in ('buildarch', 'basearch', 'libdir'):
            logger.debug("self.arch.%s = %s", attr, getattr(self.arch, attr))

        logger.info("setting up build parameters")
        product = DataHolder(name=product,
                             version=version,
                             release=release,
                             variant=variant,
                             bugurl=bugurl,
                             isfinal=isfinal)
        self.product = product
        logger.debug("product data: %s" % product)

        # NOTE: if you change isolabel, you need to change pungi to match, or
        # the pungi images won't boot.
        isolabel = volid or "{0.name} {0.version} {1.basearch}".format(
            self.product, self.arch)

        if len(isolabel) > 32:
            logger.fatal("the volume id cannot be longer than 32 characters")
            sys.exit(1)

        templatedir = self.conf.get("lorax", "sharedir")
        # NOTE: rb.root = ybo.conf.installroot (== self.inroot)
        rb = RuntimeBuilder(product=self.product,
                            arch=self.arch,
                            yum=ybo,
                            templatedir=templatedir)

        logger.info("installing runtime packages")
        rb.yum.conf.skip_broken = self.conf.getboolean("yum", "skipbroken")
        rb.install()

        # write .buildstamp
        buildstamp = BuildStamp(self.product.name, self.product.version,
                                self.product.bugurl, self.product.isfinal,
                                self.arch.buildarch)

        buildstamp.write(joinpaths(self.inroot, ".buildstamp"))

        if self.debug:
            rb.writepkglists(joinpaths(logdir, "pkglists"))
            rb.writepkgsizes(joinpaths(logdir, "original-pkgsizes.txt"))

        logger.info("doing post-install configuration")
        rb.postinstall()

        # write .discinfo
        discinfo = DiscInfo(self.product.release, self.arch.basearch)
        discinfo.write(joinpaths(self.outputdir, ".discinfo"))

        logger.info("backing up installroot")
        installroot = joinpaths(self.workdir, "installroot")
        linktree(self.inroot, installroot)

        logger.info("generating kernel module metadata")
        rb.generate_module_data()

        logger.info("cleaning unneeded files")
        rb.cleanup()

        if self.debug:
            rb.writepkgsizes(joinpaths(logdir, "final-pkgsizes.txt"))

        logger.info("creating the runtime image")
        runtime = "images/install.img"
        compression = self.conf.get("compression", "type")
        compressargs = self.conf.get("compression", "args").split()
        if self.conf.getboolean("compression", "bcj"):
            if self.arch.bcj:
                compressargs += ["-Xbcj", self.arch.bcj]
            else:
                logger.info("no BCJ filter for arch %s", self.arch.basearch)
        rb.create_runtime(joinpaths(installroot, runtime),
                          compression=compression,
                          compressargs=compressargs)

        logger.info("preparing to build output tree and boot images")
        treebuilder = TreeBuilder(product=self.product,
                                  arch=self.arch,
                                  inroot=installroot,
                                  outroot=self.outputdir,
                                  runtime=runtime,
                                  isolabel=isolabel,
                                  domacboot=domacboot,
                                  templatedir=templatedir)

        logger.info("rebuilding initramfs images")
        dracut_args = ["--xz", "--install", "/.buildstamp"]

        anaconda_args = dracut_args + ["--add", "anaconda pollcdrom"]
        treebuilder.rebuild_initrds(add_args=anaconda_args)

        # Build upgrade.img. It'd be nice if these could coexist in the same
        # image, but that would increase the size of the anaconda initramfs,
        # which worries some people (esp. PPC tftpboot). So they're separate.
        try:
            # If possible, use the 'fedup' plymouth theme
            themes = runcmd_output(['plymouth-set-default-theme', '--list'],
                                   root=installroot)
            if 'fedup' in themes.splitlines():
                os.environ['PLYMOUTH_THEME_NAME'] = 'fedup'
        except RuntimeError:
            pass
        upgrade_args = dracut_args + ["--add", "system-upgrade"]
        treebuilder.rebuild_initrds(add_args=upgrade_args, prefix="upgrade")

        logger.info("populating output tree and building boot images")
        treebuilder.build()

        # write .treeinfo file and we're done
        treeinfo = TreeInfo(self.product.name, self.product.version,
                            self.product.variant, self.arch.basearch)
        for section, data in treebuilder.treeinfo_data.items():
            treeinfo.add_section(section, data)
        treeinfo.write(joinpaths(self.outputdir, ".treeinfo"))

        # cleanup
        if remove_temp:
            remove(self.workdir)
Beispiel #51
0
    def spawn(self, deployer):

        if config.str2bool(deployer.mdict['pki_skip_installation']):
            logger.info('Skipping SELinux setup')
            return

        if not selinux.is_selinux_enabled() or seobject is None:
            logger.info('SELinux disabled')
            return

        logger.info('Creating SELinux contexts')

        # A maximum of 10 tries to create the SELinux contexts
        counter = 0
        max_tries = 10
        while True:
            try:
                # check first if any transactions are required
                if len(ports) == 0 and deployer.mdict['pki_instance_name'] == \
                        config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME:
                    self.restore_context(deployer.mdict)
                    return

                # add SELinux contexts when adding the first subsystem
                if len(deployer.instance.tomcat_instance_subsystems()) == 1:
                    trans = seobject.semanageRecords("targeted")
                    trans.start()
                    if deployer.mdict['pki_instance_name'] != \
                            config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME:

                        fcon = seobject.fcontextRecords(trans)

                        logger.info(
                            "adding selinux fcontext \"%s\"",
                            deployer.mdict['pki_instance_path'] + self.suffix)
                        fcon.add(
                            deployer.mdict['pki_instance_path'] + self.suffix,
                            config.PKI_INSTANCE_SELINUX_CONTEXT, "", "s0", "")

                        logger.info(
                            "adding selinux fcontext \"%s\"",
                            deployer.mdict['pki_instance_log_path'] +
                            self.suffix)
                        fcon.add(
                            deployer.mdict['pki_instance_log_path'] +
                            self.suffix,
                            config.PKI_LOG_SELINUX_CONTEXT, "", "s0", "")

                        logger.info(
                            "adding selinux fcontext \"%s\"",
                            deployer.mdict['pki_instance_configuration_path'] +
                            self.suffix)
                        fcon.add(
                            deployer.mdict['pki_instance_configuration_path'] +
                            self.suffix,
                            config.PKI_CFG_SELINUX_CONTEXT, "", "s0", "")

                        logger.info(
                            "adding selinux fcontext \"%s\"",
                            deployer.mdict['pki_server_database_path'] + self.suffix)
                        fcon.add(
                            deployer.mdict['pki_server_database_path'] + self.suffix,
                            config.PKI_CERTDB_SELINUX_CONTEXT, "", "s0", "")

                        port_records = seobject.portRecords(trans)
                        for port in ports:
                            logger.info("adding selinux port %s", port)
                            port_records.add(
                                port, "tcp", "s0",
                                config.PKI_PORT_SELINUX_CONTEXT)

                    trans.finish()

                    self.restore_context(deployer.mdict)
                break
            except ValueError as e:
                error_message = str(e)
                logger.error(error_message)
                if error_message.strip() == \
                        "Could not start semanage transaction":
                    counter += 1
                    if counter >= max_tries:
                        raise
                    time.sleep(5)
                    logger.debug("Retrying to setup the selinux context ...")
                else:
                    raise
Beispiel #52
0
    def destroy(self, deployer):

        if not bool(selinux.is_selinux_enabled()):
            logger.info('SELinux disabled')
            return

        # check first if any transactions are required
        if (len(ports) == 0 and deployer.mdict['pki_instance_name'] ==
                config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME):
            return

        logger.info('Removing SELinux contexts')

        # A maximum of 10 tries to delete the SELinux contexts
        max_tries = 10
        for counter in range(1, max_tries):
            try:
                # remove SELinux contexts when removing the last subsystem
                if len(deployer.instance.tomcat_instance_subsystems()) == 0:
                    trans = seobject.semanageRecords("targeted")
                    trans.start()

                    if deployer.mdict['pki_instance_name'] != \
                            config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME:

                        fcon = seobject.fcontextRecords(trans)
                        file_records = fcon.get_all()

                        if self.context_exists(file_records,
                                               deployer.mdict['pki_instance_path'] +
                                               self.suffix):
                            logger.info(
                                "deleting selinux fcontext \"%s\"",
                                deployer.mdict['pki_instance_path'] + self.suffix)
                            fcon.delete(
                                deployer.mdict['pki_instance_path'] +
                                self.suffix, "")

                        if self.context_exists(file_records,
                                               deployer.mdict['pki_instance_log_path'] +
                                               self.suffix):
                            logger.info(
                                "deleting selinux fcontext \"%s\"",
                                deployer.mdict['pki_instance_log_path'] +
                                self.suffix)
                            fcon.delete(
                                deployer.mdict['pki_instance_log_path'] +
                                self.suffix, "")

                        if self.context_exists(file_records,
                                               deployer.mdict['pki_instance_configuration_path'] +
                                               self.suffix):
                            logger.info(
                                "deleting selinux fcontext \"%s\"",
                                deployer.mdict['pki_instance_configuration_path'] +
                                self.suffix)
                            fcon.delete(
                                deployer.mdict['pki_instance_configuration_path'] +
                                self.suffix, "")

                        if self.context_exists(file_records,
                                               deployer.mdict['pki_server_database_path'] +
                                               self.suffix):
                            logger.info(
                                "deleting selinux fcontext \"%s\"",
                                deployer.mdict['pki_server_database_path'] + self.suffix)
                            fcon.delete(
                                deployer.mdict['pki_server_database_path'] +
                                self.suffix, "")

                        port_records = seobject.portRecords(trans)
                        port_record_values = port_records.get_all()
                        for port in ports:
                            if self.context_exists(port_record_values, port):
                                logger.info("deleting selinux port %s", port)
                                port_records.delete(port, "tcp")

                    trans.finish()
                break
            except ValueError as e:
                error_message = str(e)
                logger.error(error_message)
                if error_message.strip() == \
                        "Could not start semanage transaction":
                    if counter >= max_tries:
                        raise
                    time.sleep(5)
                    logger.debug("Retrying to remove selinux context ...")
                else:
                    raise
Beispiel #53
0
    def selinux_role(self):
        """Setup proper selinux role.

        this must be called at beginning of process
        to adjust proper roles for selinux.
        it will re-execute the process with same arguments.

        This has similar effect of:
        # chcon -t rpm_exec_t executable.py

        We must do this dynamic as this class is to be
        used at bootstrap stage, so we cannot put any
        persistent selinux policy changes, and have no clue
        if filesystem where we put scripts supports extended
        attributes, or if we have proper role for chcon.

        """

        try:
            import selinux
        except ImportError:
            package_name = None
            if sys.version_info.major == 2:
                package_name = 'libselinux-python'
            elif sys.version_info.major == 3:
                package_name = 'libselinux-python3'
            else:
                # Unknown python version, do nothing for now
                pass
            if package_name is not None:
                package_installed = False
                with self.transaction():
                    self.install([package_name])
                    if self.buildTransaction():
                        self.processTransaction()
                        package_installed = True
                #
                # on fedora-18 for example
                # the selinux core is updated
                # so we fail resolving symbols
                # solution is re-execute the process
                # after installation.
                #
                if package_installed:
                    self._sink.reexec()
                    os.execv(sys.executable, [sys.executable] + sys.argv)
                    os._exit(1)

        if selinux.is_selinux_enabled():
            rc, ctx = selinux.getcon()
            if rc != 0:
                raise Exception(_('Cannot get selinux context'))
            ctx1 = selinux.context_new(ctx)
            if not ctx1:
                raise Exception(_('Cannot create selinux context'))
            if selinux.context_role_get(ctx1) != 'system_r':
                if selinux.context_role_set(ctx1, 'system_r') != 0:
                    raise Exception(
                        _('Cannot set role within selinux context'))
                if selinux.setexeccon(selinux.context_str(ctx1)) != 0:
                    raise Exception(_('Cannot set selinux exec context'))
                self._sink.reexec()
                os.execv(sys.executable, [sys.executable] + sys.argv)
                os._exit(1)
Beispiel #54
0
           then verify we have returned to the proper hub.  Since most spokes
           are off the summary hub, that's the default.  If we are not back
           on the hub, the current test case will be failed.
        """
        button = self.find("_Done", "push button", node=node)
        self.assertIsNotNone(button, msg="Done button not found")
        button.click()
        doDelay(5)
        self.check_window_displayed(hubName)


@unittest.skipIf(os.geteuid() != 0, "GUI tests must be run as root")
@unittest.skipIf(
    os.environ.get("DISPLAY", "") == "", "DISPLAY must be defined")
@unittest.skipIf(
    selinux.is_selinux_enabled() and selinux.security_getenforce() == 1,
    "SELinux must be disabled or in Permissive mode, see rhbz#1276376")
@unittest.skipIf(not isA11yEnabled(), "Assistive Technologies are disabled")
class DogtailTestCase(unittest.TestCase):
    """A subclass that defines all the parameters for starting a local
       copy of anaconda, inspecting results, and managing temporary data!

       Most subclasses will only need to define the following four attributes:

       drives       -- A list of tuples describing disk images to create.  Each
                       tuple is the name of the drive and its size as a blivet.Size.
       environ      -- A dictionary of environment variables that should be added
                       to the environment the test suite will run under.
       name         -- A unique string that names the test.  This name will
                       be used in creating the results directory (and perhaps
                       other places in the future) so make sure it doesn't
    def __init__(self):
        self._log = logging.getLogger("%s.StorageServer" % __name__)
        self._log.addFilter(log_filter.get_intermittent_filter())
        self._config = config.Config(logger=self._log)
        self._cli = util.connect_vdsm_json_rpc(
            logger=self._log,
            timeout=constants.VDSCLI_SSL_TIMEOUT
        )

        self._type = self._config.get(config.ENGINE, const.DOMAIN_TYPE)
        self._spUUID = self._config.get(config.ENGINE, const.SP_UUID)
        self._sdUUID = self._config.get(config.ENGINE, const.SD_UUID)
        self._storage = self._config.get(config.ENGINE, const.STORAGE)
        self._HEVMID = self._config.get(config.ENGINE, const.HEVMID)
        self._host_id = int(self._config.get(config.ENGINE, const.HOST_ID))
        self._fake_sd_size = '2G'
        self._vfstype = 'ext3'

        self._vm_img_uuid = self._config.get(
            config.ENGINE,
            const.VM_DISK_IMG_ID
        )
        vm_vol_uuid = None
        try:
            vm_vol_uuid = self._config.get(
                config.ENGINE,
                const.VM_DISK_VOL_ID
            )
        except (KeyError, ValueError):
            try:
                vm_vol_uuid = self._cli.StorageDomain.getVolumes(
                    imageID=self._vm_img_uuid,
                    storagepoolID=self._spUUID,
                    storagedomainID=self._sdUUID,
                )[0]
            except ServerError:
                # Ignore error
                pass

        self._vm_vol_uuid = vm_vol_uuid

        self._conf_imgUUID = None
        self._conf_volUUID = None
        self._metadata_imgUUID = self._config.get(
            config.ENGINE,
            const.METADATA_IMAGE_UUID,
        )
        self._metadata_volUUID = self._config.get(
            config.ENGINE,
            const.METADATA_VOLUME_UUID,
        )
        self._lockspace_imgUUID = self._config.get(
            config.ENGINE,
            const.LOCKSPACE_IMAGE_UUID,
        )
        self._lockspace_volUUID = self._config.get(
            config.ENGINE,
            const.LOCKSPACE_VOLUME_UUID,
        )
        self._fake_SD_path = None
        self._fake_file = None
        self._fake_mastersd_uuid = str(uuid.uuid4())
        self._selinux_enabled = selinux.is_selinux_enabled()
        self._fake_master_connection_uuid = str(uuid.uuid4())
Beispiel #56
0
 def test_default_container_context(self):
     exp = ('system_u:object_r:svirt_sandbox_file_t:s0'
            if selinux.is_selinux_enabled() else '')
     self.assertEqual(exp, util.default_container_context())
Beispiel #57
0
    def run(self,
            dbo,
            product,
            version,
            release,
            variant="",
            bugurl="",
            isfinal=False,
            workdir=None,
            outputdir=None,
            buildarch=None,
            volid=None,
            domacboot=True,
            doupgrade=True,
            remove_temp=False,
            installpkgs=None,
            excludepkgs=None,
            size=2,
            add_templates=None,
            add_template_vars=None,
            add_arch_templates=None,
            add_arch_template_vars=None,
            verify=True):

        assert self._configured

        installpkgs = installpkgs or []
        excludepkgs = excludepkgs or []

        # get lorax version
        try:
            import pylorax.version
        except ImportError:
            vernum = "devel"
        else:
            vernum = pylorax.version.num

        if domacboot:
            try:
                runcmd(["rpm", "-q", "hfsplus-tools"])
            except CalledProcessError:
                logger.critical(
                    "you need to install hfsplus-tools to create mac images")
                sys.exit(1)

        # set up work directory
        self.workdir = workdir or tempfile.mkdtemp(prefix="pylorax.work.")
        if not os.path.isdir(self.workdir):
            os.makedirs(self.workdir)

        # set up log directory
        logdir = self.conf.get("lorax", "logdir")
        if not os.path.isdir(logdir):
            os.makedirs(logdir)

        self.init_stream_logging()
        self.init_file_logging(logdir)

        logger.debug("version is %s", vernum)
        logger.debug("using work directory %s", self.workdir)
        logger.debug("using log directory %s", logdir)

        # set up output directory
        self.outputdir = outputdir or tempfile.mkdtemp(prefix="pylorax.out.")
        if not os.path.isdir(self.outputdir):
            os.makedirs(self.outputdir)
        logger.debug("using output directory %s", self.outputdir)

        # do we have root privileges?
        logger.info("checking for root privileges")
        if not os.geteuid() == 0:
            logger.critical("no root privileges")
            sys.exit(1)

        # is selinux disabled?
        # With selinux in enforcing mode the rpcbind package required for
        # dracut nfs module, which is in turn required by anaconda module,
        # will not get installed, because it's preinstall scriptlet fails,
        # resulting in an incomplete initial ramdisk image.
        # The reason is that the scriptlet runs tools from the shadow-utils
        # package in chroot, particularly groupadd and useradd to add the
        # required rpc group and rpc user. This operation fails, because
        # the selinux context on files in the chroot, that the shadow-utils
        # tools need to access (/etc/group, /etc/passwd, /etc/shadow etc.),
        # is wrong and selinux therefore disallows access to these files.
        logger.info("checking the selinux mode")
        if selinux.is_selinux_enabled() and selinux.security_getenforce():
            logger.critical("selinux must be disabled or in Permissive mode")
            sys.exit(1)

        # do we have a proper dnf base object?
        logger.info("checking dnf base object")
        if not isinstance(dbo, dnf.Base):
            logger.critical("no dnf base object")
            sys.exit(1)
        self.inroot = dbo.conf.installroot
        logger.debug("using install root: %s", self.inroot)

        if not buildarch:
            buildarch = get_buildarch(dbo)

        logger.info("setting up build architecture")
        self.arch = ArchData(buildarch)
        for attr in ('buildarch', 'basearch', 'libdir'):
            logger.debug("self.arch.%s = %s", attr, getattr(self.arch, attr))

        logger.info("setting up build parameters")
        self.product = DataHolder(name=product,
                                  version=version,
                                  release=release,
                                  variant=variant,
                                  bugurl=bugurl,
                                  isfinal=isfinal)
        logger.debug("product data: %s", self.product)

        # NOTE: if you change isolabel, you need to change pungi to match, or
        # the pungi images won't boot.
        isolabel = volid or "%s-%s-%s" % (
            self.product.name, self.product.version, self.arch.basearch)

        if len(isolabel) > 32:
            logger.fatal("the volume id cannot be longer than 32 characters")
            sys.exit(1)

        # NOTE: rb.root = dbo.conf.installroot (== self.inroot)
        rb = RuntimeBuilder(product=self.product,
                            arch=self.arch,
                            dbo=dbo,
                            templatedir=self.templatedir,
                            installpkgs=installpkgs,
                            excludepkgs=excludepkgs,
                            add_templates=add_templates,
                            add_template_vars=add_template_vars)

        logger.info("installing runtime packages")
        rb.install()

        # write .buildstamp
        buildstamp = BuildStamp(self.product.name, self.product.version,
                                self.product.bugurl, self.product.isfinal,
                                self.arch.buildarch)

        buildstamp.write(joinpaths(self.inroot, ".buildstamp"))

        if self.debug:
            rb.writepkglists(joinpaths(logdir, "pkglists"))
            rb.writepkgsizes(joinpaths(logdir, "original-pkgsizes.txt"))

        logger.info("doing post-install configuration")
        rb.postinstall()

        # write .discinfo
        discinfo = DiscInfo(self.product.release, self.arch.basearch)
        discinfo.write(joinpaths(self.outputdir, ".discinfo"))

        logger.info("backing up installroot")
        installroot = joinpaths(self.workdir, "installroot")
        linktree(self.inroot, installroot)

        logger.info("generating kernel module metadata")
        rb.generate_module_data()

        logger.info("cleaning unneeded files")
        rb.cleanup()

        if verify:
            logger.info("verifying the installroot")
            if not rb.verify():
                sys.exit(1)
        else:
            logger.info("Skipping verify")

        if self.debug:
            rb.writepkgsizes(joinpaths(logdir, "final-pkgsizes.txt"))

        logger.info("creating the runtime image")
        runtime = "images/install.img"
        compression = self.conf.get("compression", "type")
        compressargs = self.conf.get("compression", "args").split()  # pylint: disable=no-member
        if self.conf.getboolean("compression", "bcj"):
            if self.arch.bcj:
                compressargs += ["-Xbcj", self.arch.bcj]
            else:
                logger.info("no BCJ filter for arch %s", self.arch.basearch)
        rb.create_runtime(joinpaths(installroot, runtime),
                          compression=compression,
                          compressargs=compressargs,
                          size=size)
        rb.finished()

        logger.info("preparing to build output tree and boot images")
        treebuilder = TreeBuilder(product=self.product,
                                  arch=self.arch,
                                  inroot=installroot,
                                  outroot=self.outputdir,
                                  runtime=runtime,
                                  isolabel=isolabel,
                                  domacboot=domacboot,
                                  doupgrade=doupgrade,
                                  templatedir=self.templatedir,
                                  add_templates=add_arch_templates,
                                  add_template_vars=add_arch_template_vars,
                                  workdir=self.workdir)

        logger.info("rebuilding initramfs images")
        dracut_args = [
            "--xz", "--install", "/.buildstamp", "--no-early-microcode"
        ]
        anaconda_args = dracut_args + [
            "--add", "anaconda pollcdrom qemu qemu-net"
        ]

        # ppc64 cannot boot an initrd > 32MiB so remove some drivers
        if self.arch.basearch in ("ppc64", "ppc64le"):
            dracut_args.extend(["--omit-drivers", REMOVE_PPC64_DRIVERS])

            # Only omit dracut modules from the initrd so that they're kept for
            # upgrade.img
            anaconda_args.extend(["--omit", REMOVE_PPC64_MODULES])

        treebuilder.rebuild_initrds(add_args=anaconda_args)

        logger.info("populating output tree and building boot images")
        treebuilder.build()

        # write .treeinfo file and we're done
        treeinfo = TreeInfo(self.product.name, self.product.version,
                            self.product.variant, self.arch.basearch)
        for section, data in treebuilder.treeinfo_data.items():
            treeinfo.add_section(section, data)
        treeinfo.write(joinpaths(self.outputdir, ".treeinfo"))

        # cleanup
        if remove_temp:
            remove(self.workdir)
Beispiel #58
0
def createBrick(brickName,
                mountPoint,
                devNameList,
                fsType=DEFAULT_FS_TYPE,
                raidParams={}):
    def _getDeviceList(devNameList):
        return [
            blivetEnv.devicetree.getDeviceByName(devName.split("/")[-1])
            for devName in devNameList
        ]

    def _createPV(deviceList, alignment):
        for dev in deviceList:
            # bz#1178705: Blivet always creates pv with 1MB dataalignment
            # Workaround: Till blivet fixes the issue, we use lvm pvcreate
            rc, out, err = commands.execCmd([
                _pvCreateCommandPath.cmd, '--dataalignment',
                '%sk' % alignment, dev.path
            ])
            if rc:
                raise ge.GlusterHostStorageDevicePVCreateFailedException(
                    dev.path, alignment, rc, out, err)
        _reset_blivet(blivetEnv)
        return _getDeviceList([dev.name for dev in deviceList])

    def _createVG(vgName, deviceList, stripeSize):
        # bz#1198568: Blivet always creates vg with 1MB stripe size
        # Workaround: Till blivet fixes the issue, use vgcreate command
        devices = ','.join([device.path for device in deviceList])
        rc, out, err = commands.execCmd([
            _vgCreateCommandPath.cmd, '-s',
            '%sk' % stripeSize, vgName, devices
        ])
        if rc:
            raise ge.GlusterHostStorageDeviceVGCreateFailedException(
                vgName, devices, stripeSize, rc, out, err)
        blivetEnv.reset()
        return blivetEnv.devicetree.getDeviceByName(vgName)

    def _createThinPool(poolName, vg, alignment, poolMetaDataSize,
                        poolDataSize):
        metaName = "meta-%s" % poolName
        vgPoolName = "%s/%s" % (vg.name, poolName)
        metaLv = LVMLogicalVolumeDevice(metaName,
                                        parents=[vg],
                                        size=blivet.size.Size(
                                            '%d KiB' % poolMetaDataSize))
        poolLv = LVMLogicalVolumeDevice(poolName,
                                        parents=[vg],
                                        size=blivet.size.Size('%d KiB' %
                                                              poolDataSize))
        blivetEnv.createDevice(metaLv)
        blivetEnv.createDevice(poolLv)
        blivetEnv.doIt()

        # bz#1100514: LVM2 currently only supports physical extent sizes
        # that are a power of 2. Till that support is available we need
        # to use lvconvert to achive that.
        # bz#1179826: blivet doesn't support lvconvert functionality.
        # Workaround: Till the bz gets fixed, lvconvert command is used
        rc, out, err = commands.execCmd([
            _lvconvertCommandPath.cmd, '--chunksize',
            '%sK' % alignment, '--thinpool', vgPoolName, '--poolmetadata',
            "%s/%s" % (vg.name, metaName), '--poolmetadataspar', 'n', '-y'
        ])

        if rc:
            raise ge.GlusterHostStorageDeviceLVConvertFailedException(
                vg.path, alignment, rc, out, err)
        rc, out, err = commands.execCmd(
            [_lvchangeCommandPath.cmd, '--zero', 'n', vgPoolName])
        if rc:
            raise ge.GlusterHostStorageDeviceLVChangeFailedException(
                vgPoolName, rc, out, err)
        _reset_blivet(blivetEnv)
        return blivetEnv.devicetree.getDeviceByName(poolLv.name)

    if os.path.ismount(mountPoint):
        raise ge.GlusterHostStorageMountPointInUseException(mountPoint)

    vgName = "vg-" + brickName
    poolName = "pool-" + brickName
    poolDataSize = 0
    count = 0
    raidType = raidParams.get('type')
    metaDataSizeKib = DEFAULT_METADATA_SIZE_KB
    if raidType == '6':
        count = raidParams['pdCount'] - 2
        alignment = raidParams['stripeSize'] * count
        chunkSize = alignment
    elif raidType == '10':
        count = raidParams['pdCount'] // 2
        alignment = raidParams['stripeSize'] * count
        chunkSize = DEFAULT_CHUNK_SIZE_KB
    else:  # Device type is JBOD
        alignment = DEFAULT_CHUNK_SIZE_KB
        chunkSize = DEFAULT_CHUNK_SIZE_KB

    blivetEnv = blivet.Blivet()
    _reset_blivet(blivetEnv)

    # get the devices list from the device name
    deviceList = _getDeviceList(devNameList)

    # raise an error when any device not actually found in the given list
    notFoundList = set(devNameList).difference(
        set([dev.name for dev in deviceList]))
    if notFoundList:
        raise ge.GlusterHostStorageDeviceNotFoundException(notFoundList)

    # raise an error when any device is used already in the given list
    inUseList = set(devNameList).difference(
        set([not _canCreateBrick(dev) or dev.name for dev in deviceList]))
    if inUseList:
        raise ge.GlusterHostStorageDeviceInUseException(inUseList)

    pvDeviceList = _createPV(deviceList, alignment)
    vg = _createVG(vgName, pvDeviceList, alignment)
    # The following calculation is based on the redhat storage performance doc
    # http://docbuilder.usersys.redhat.com/22522
    # /#chap-Configuring_Red_Hat_Storage_for_Enhancing_Performance

    # create ~16GB metadata LV (metaDataSizeKib) that has a size which is
    # a multiple of RAID stripe width if it is > minimum vg size
    # otherwise allocate a minimum of 0.5% of the data device size
    # and create data LV (poolDataSize) that has a size which is
    # a multiple of stripe width.
    vgSizeKib = int(_getDeviceSize(vg, 'KiB'))
    if _getDeviceSize(vg) < MIN_VG_SIZE:
        metaDataSizeKib = vgSizeKib * MIN_METADATA_PERCENT
    poolDataSize = vgSizeKib - metaDataSizeKib

    metaDataSizeKib = (metaDataSizeKib - (metaDataSizeKib % alignment))
    poolDataSize = (poolDataSize - (poolDataSize % alignment))

    # Creating a thin pool from the data LV and the metadata LV
    # lvconvert --chunksize alignment --thinpool VOLGROUP/thin_pool
    #     --poolmetadata VOLGROUP/metadata_device_name
    pool = _createThinPool(poolName, vg, chunkSize, metaDataSizeKib,
                           poolDataSize)
    # Size of the thin LV should be same as the size of Thinpool to avoid
    # over allocation. Refer bz#1412455 for more info.
    thinlv = LVMThinLogicalVolumeDevice(brickName,
                                        parents=[pool],
                                        size=blivet.size.Size('%d KiB' %
                                                              poolDataSize),
                                        grow=True)
    blivetEnv.createDevice(thinlv)
    blivetEnv.doIt()

    if fsType != DEFAULT_FS_TYPE:
        log.error("fstype %s is currently unsupported" % fsType)
        raise ge.GlusterHostStorageDeviceMkfsFailedException(fsType)

    format = blivet.formats.getFormat(DEFAULT_FS_TYPE,
                                      device=thinlv.path,
                                      mountopts=DEFAULT_MOUNT_OPTIONS)
    format._defaultFormatOptions = ["-f", "-i", "size=512", "-n", "size=8192"]
    if raidParams.get('type') == '6':
        format._defaultFormatOptions += [
            "-d", "sw=%s,su=%sk" % (count, raidParams.get('stripeSize'))
        ]
    blivetEnv.formatDevice(thinlv, format)
    blivetEnv.doIt()

    try:
        os.makedirs(mountPoint)
    except OSError as e:
        if errno.EEXIST != e.errno:
            errMsg = "[Errno %s] %s: '%s'" % (e.errno, e.strerror, e.filename)
            raise ge.GlusterHostStorageDeviceMakeDirsFailedException(
                err=[errMsg])
    thinlv.format.setup(mountpoint=mountPoint)
    blivetEnv.doIt()

    # bz#1230495: lvm devices are invisible and appears only after vgscan
    # Workaround: Till the bz gets fixed, We use vgscan to refresh LVM devices
    rc, out, err = commands.execCmd([_vgscanCommandPath.cmd])
    if rc:
        raise ge.GlusterHostStorageDeviceVGScanFailedException(rc, out, err)
    fstab.FsTab().add(thinlv.path,
                      mountPoint,
                      DEFAULT_FS_TYPE,
                      mntOpts=[DEFAULT_MOUNT_OPTIONS])

    # If selinux is enabled, set correct selinux labels on the brick.
    if selinux.is_selinux_enabled():
        rc, out, err = commands.execCmd([
            _semanageCommandPath.cmd, 'fcontext', '-a', '-t',
            'glusterd_brick_t', mountPoint
        ])
        if rc:
            raise ge.GlusterHostFailedToSetSelinuxContext(
                mountPoint, rc, out, err)
        try:
            # mountPoint can be of 'unicode' type when its passed through
            # jsonrpc. restorecon calls into a C API that needs a char *.
            # Thus, it is necessary to encode unicode to a utf-8 string.
            selinux.restorecon(mountPoint.encode('utf-8'), recursive=True)
        except OSError as e:
            errMsg = "[Errno %s] %s: '%s'" % (e.errno, e.strerror, e.filename)
            raise ge.GlusterHostFailedToRunRestorecon(mountPoint, err=errMsg)
    return _getDeviceDict(thinlv)
Beispiel #59
0
def main():
    module = AnsibleModule(argument_spec=dict(
        policy=dict(required=False),
        state=dict(choices=['enforcing', 'permissive', 'disabled'],
                   required=True),
        configfile=dict(aliases=['conf', 'file'],
                        default='/etc/selinux/config')),
                           supports_check_mode=True)

    if not HAS_SELINUX:
        module.fail_json(msg='libselinux-python required for this module')

    # global vars
    changed = False
    msgs = []
    configfile = module.params['configfile']
    policy = module.params['policy']
    state = module.params['state']
    runtime_enabled = selinux.is_selinux_enabled()
    runtime_policy = selinux.selinux_getpolicytype()[1]
    runtime_state = 'disabled'
    reboot_required = False

    if runtime_enabled:
        # enabled means 'enforcing' or 'permissive'
        if selinux.security_getenforce():
            runtime_state = 'enforcing'
        else:
            runtime_state = 'permissive'

    if not os.path.isfile(configfile):
        module.fail_json(msg="Unable to find file {0}".format(configfile),
                         details="Please install SELinux-policy package, "
                         "if this package is not installed previously.")

    config_policy = get_config_policy(configfile)
    config_state = get_config_state(configfile)

    # check to see if policy is set if state is not 'disabled'
    if state != 'disabled':
        if not policy:
            module.fail_json(
                msg='Policy is required if state is not \'disabled\'')
    else:
        if not policy:
            policy = config_policy

    # check changed values and run changes
    if policy != runtime_policy:
        if module.check_mode:
            module.exit_json(changed=True)
        # cannot change runtime policy
        msgs.append('Running SELinux policy changed from \'%s\' to \'%s\'' %
                    (runtime_policy, policy))
        changed = True

    if policy != config_policy:
        if module.check_mode:
            module.exit_json(changed=True)
        set_config_policy(module, policy, configfile)
        msgs.append(
            'SELinux policy configuration in \'%s\' changed from \'%s\' to \'%s\''
            % (configfile, config_policy, policy))
        changed = True

    if state != runtime_state:
        if runtime_enabled:
            if state == 'disabled':
                if runtime_state != 'permissive':
                    # Temporarily set state to permissive
                    if not module.check_mode:
                        set_state(module, 'permissive')
                    module.warn(
                        'SELinux state temporarily changed from \'%s\' to \'permissive\'. State change will take effect next reboot.'
                        % (runtime_state))
                    changed = True
                else:
                    module.warn(
                        'SELinux state change will take effect next reboot')
                reboot_required = True
            else:
                if not module.check_mode:
                    set_state(module, state)
                msgs.append('SELinux state changed from \'%s\' to \'%s\'' %
                            (runtime_state, state))

                # Only report changes if the file is changed.
                # This prevents the task from reporting changes every time the task is run.
                changed = True
        else:
            module.warn("Reboot is required to set SELinux state to %s" %
                        state)
            reboot_required = True

    if state != config_state:
        if not module.check_mode:
            set_config_state(module, state, configfile)
        msgs.append('Config SELinux state changed from \'%s\' to \'%s\'' %
                    (config_state, state))
        changed = True

    module.exit_json(changed=changed,
                     msg=', '.join(msgs),
                     configfile=configfile,
                     policy=policy,
                     state=state,
                     reboot_required=reboot_required)
Beispiel #60
0
    def __init__(self):
        #
        # mode of operation
        #
        self.testing = False
        self.debug = False

        #
        # minor modes
        #
        self.uevents = False

        #
        # enable/disable functionality
        #
        self.selinux = selinux.is_selinux_enabled()
        self.multipath = True
        self.dmraid = True
        self.ibft = True
        self.noiswmd = False

        self.gfs2 = True
        self.jfs = True
        self.reiserfs = True

        # for this flag to take effect,
        # blockdev.mpath.set_friendly_names(flags.multipath_friendly_names) must
        # be called prior to calling Blivet.reset() or DeviceTree.populate()
        self.multipath_friendly_names = True

        # set to False since automatic updates of a device's information
        # or state should not be necessary by default
        self.auto_dev_updates = False

        # set to False by default since a forced reset for file contexts
        # is ordinary not necessary
        self.selinux_reset_fcon = False

        # set to True since we want to keep these around by default
        self.keep_empty_ext_partitions = True

        # set to False to suppress the default LVM behavior of saving
        # backup metadata in /etc/lvm/{archive,backup}
        self.lvm_metadata_backup = True

        # whether to include nodev filesystems in the devicetree
        self.include_nodev = False

        # whether to enable discard for newly created devices
        # (so far only for LUKS)
        self.discard_new = False

        self.boot_cmdline = {}

        self.update_from_boot_cmdline()
        self.allow_imperfect_devices = True

        # compression option for btrfs filesystems
        self.btrfs_compression = None

        self.debug_threads = False