Ejemplo n.º 1
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)
Ejemplo n.º 2
0
def restoreSecurityContext_api(path, recursive=False):
    """
    restorecon() wrapper.
      path - can be a single string or a list
      returns True if successful or False if there was a problem
    """

    try:
        logger = TCSLogger.TCSLogger.getInstance(6)
    except TCSLogger.SingletonException:
        logger = TCSLogger.TCSLogger.getInstance()

    if type(path).__name__ == 'str':
        if os.path.exists(path):
            contextCurrent = ""
            notes = ""
            rpath = os.path.realpath(path)
            if rpath != path:
                notes = "(%s)" % rpath
            myerror = None
            try:
                contextCurrent = selinux.getfilecon(rpath)[1]
            except:
                pass
            try:
                # unfortunately not all RH5 boxes have 'restorecon' as part of the python bindings.  Since we never
                # do this recursively, we'll explicitly do the matchpathcon/lsetfilecon ourselves.
                mode = os.stat(rpath)[stat.ST_MODE]
                status, contextRestore = selinux.matchpathcon(rpath, mode)

                if status == 0:
                    # On the advice of our inhouse SELinux experts, we are intentially disregarding a potential 'user' mismatch
                    # We know that especially for daemon processes in targetted mode we could be either user_u or system_u
                    # depending on how the daemon started.

                    if contextRestore.split(':')[1:] != contextCurrent.split(
                            ':')[1:]:
                        selinux.lsetfilecon(rpath, contextRestore)
                        if notes:
                            msg = """OS Lockdown reset context of '%s' (actually '%s') to '%s'""" % (
                                path, notes, contextRestore)
                        else:
                            msg = """OS Lockdown reset context of '%s' to '%s'""" % (
                                path, contextRestore)

                        logger.info(MODULE_NAME, msg)
                else:
                    myerror = "Unable to get default context for '%s'" % path

            except OSError, err:
                myerror = err

            if myerror != None:
                logger.error(MODULE_NAME, str(myerror))
                return False
        else:
            msg = """OS Lockdown trying to restore context of '%s' which does not exist.""" % (
                path)
            logger.warn(MODULE_NAME, msg)
Ejemplo n.º 3
0
    def set_context_if_different(self, path, context, changed):

        if not HAVE_SELINUX or not self.selinux_enabled():
            return changed
        cur_context = self.selinux_context(path)
        new_context = list(cur_context)
        # Iterate over the current context instead of the
        # argument context, which may have selevel.

        (is_nfs, nfs_context) = self.is_nfs_path(path)
        if is_nfs:
            new_context = nfs_context
        else:
            for i in range(len(cur_context)):
                if len(context) > i:
                    if context[i] is not None and context[i] != cur_context[i]:
                        new_context[i] = context[i]
                    if context[i] is None:
                        new_context[i] = cur_context[i]

        if cur_context != new_context:
            try:
                if self.check_mode:
                    return True
                rc = selinux.lsetfilecon(self._to_filesystem_str(path),
                                         str(':'.join(new_context)))
            except OSError:
                self.fail_json(path=path, msg='invalid selinux context', new_context=new_context, cur_context=cur_context, input_was=context)
            if rc != 0:
                self.fail_json(path=path, msg='set selinux context failed')
            changed = True
        return changed
Ejemplo n.º 4
0
    def _set_secontext(self, entry, path=None):
        """ set the SELinux context of the file on disk according to the
        config"""
        if not HAS_SELINUX:
            return True

        if path is None:
            path = entry.get("name")
        context = entry.get("secontext")
        if not context:
            # no context listed
            return True

        if context == '__default__':
            try:
                selinux.restorecon(path)
                rv = True
            except OSError:
                err = sys.exc_info()[1]
                self.logger.error("POSIX: Failed to restore SELinux context "
                                  "for %s: %s" % (path, err))
                rv = False
        else:
            try:
                rv = selinux.lsetfilecon(path, context) == 0
            except OSError:
                err = sys.exc_info()[1]
                self.logger.error("POSIX: Failed to restore SELinux context "
                                  "for %s: %s" % (path, err))
                rv = False
        return rv
Ejemplo n.º 5
0
def set_file_context(path, context, root=None):
    """ Set the SELinux file context of a file.

        Arguments:

            path        filename string
            context     context string

        Keyword Arguments:

            root        an optional chroot string

        Return Value:

            True if successful, False if not.
    """
    if root is None:
        root = '/'

    full_path = os.path.normpath("%s/%s" % (root, path))
    if context is None or not os.access(full_path, os.F_OK):
        return False

    try:
        rc = (selinux.lsetfilecon(full_path, context) == 0)
    except OSError as e:
        log.info("failed to set SELinux context for %s: %s", full_path, e)
        rc = False

    return rc
Ejemplo n.º 6
0
    def _set_secontext(self, entry, path=None):
        """ set the SELinux context of the file on disk according to the
        config"""
        if not HAS_SELINUX:
            return True

        if path is None:
            path = entry.get("name")
        context = entry.get("secontext")
        if not context:
            # no context listed
            return True

        if context == '__default__':
            try:
                selinux.restorecon(path)
                rv = True
            except OSError:
                err = sys.exc_info()[1]
                self.logger.error("POSIX: Failed to restore SELinux context "
                                  "for %s: %s" % (path, err))
                rv = False
        else:
            try:
                rv = selinux.lsetfilecon(path, context) == 0
            except OSError:
                err = sys.exc_info()[1]
                self.logger.error("POSIX: Failed to restore SELinux context "
                                  "for %s: %s" % (path, err))
                rv = False
        return rv
Ejemplo n.º 7
0
Archivo: base.py Proyecto: fennm/bcfg2
    def _set_secontext(self, entry, path=None):  # pylint: disable=R0911
        """ set the SELinux context of the file on disk according to the
        config"""
        if not HAS_SELINUX:
            return True

        if path is None:
            path = entry.get("name")
        context = entry.get("secontext")
        if not context:
            # no context listed
            return True
        secontext = selinux.lgetfilecon(path)[1].split(":")[2]
        if secontext in Bcfg2.Options.setup.secontext_ignore:
            return True
        try:
            if context == '__default__':
                selinux.restorecon(path)
                return True
            else:
                return selinux.lsetfilecon(path, context) == 0
        except OSError:
            err = sys.exc_info()[1]
            if err.errno == errno.EOPNOTSUPP:
                # Operation not supported
                if context != '__default__':
                    self.logger.debug("POSIX: Failed to set SELinux context "
                                      "for %s: %s" % (path, err))
                    return False
                return True
            err = sys.exc_info()[1]
            self.logger.error("POSIX: Failed to set or restore SELinux "
                              "context for %s: %s" % (path, err))
            return False
Ejemplo n.º 8
0
def set_file_context(path, context, root=None):
    """ Set the SELinux file context of a file.

        Arguments:

            path        filename string
            context     context string

        Keyword Arguments:

            root        an optional chroot string

        Return Value:

            True if successful, False if not.
    """
    if root is None:
        root = '/'

    full_path = os.path.normpath("%s/%s" % (root, path))
    if context is None or not os.access(full_path, os.F_OK):
        return False

    try:
        rc = (selinux.lsetfilecon(full_path, context) == 0)
    except OSError as e:
        log.info("failed to set SELinux context for %s: %s", full_path, e)
        rc = False

    return rc
Ejemplo n.º 9
0
    def _set_secontext(self, entry, path=None):  # pylint: disable=R0911
        """ set the SELinux context of the file on disk according to the
        config"""
        if not HAS_SELINUX:
            return True

        if path is None:
            path = entry.get("name")
        context = entry.get("secontext")
        if not context:
            # no context listed
            return True
        secontext = selinux.lgetfilecon(path)[1].split(":")[2]
        if secontext in Bcfg2.Options.setup.secontext_ignore:
            return True
        try:
            if context == '__default__':
                selinux.restorecon(path)
                return True
            else:
                return selinux.lsetfilecon(path, context) == 0
        except OSError:
            err = sys.exc_info()[1]
            if err.errno == errno.EOPNOTSUPP:
                # Operation not supported
                if context != '__default__':
                    self.logger.debug("POSIX: Failed to set SELinux context "
                                      "for %s: %s" % (path, err))
                    return False
                return True
            err = sys.exc_info()[1]
            self.logger.error("POSIX: Failed to set or restore SELinux "
                              "context for %s: %s" % (path, err))
            return False
Ejemplo n.º 10
0
    def set_context_if_different(self, path, context, changed):

        if not HAVE_SELINUX or not self.selinux_enabled():
            return changed
        cur_context = self.selinux_context(path)
        new_context = list(cur_context)
        # Iterate over the current context instead of the
        # argument context, which may have selevel.

        for i in range(len(cur_context)):
            if len(context) > i:
                if context[i] is not None and context[i] != cur_context[i]:
                    new_context[i] = context[i]
                if context[i] is None:
                    new_context[i] = cur_context[i]

        if cur_context != new_context:
            try:
                if self.check_mode:
                    return True
                rc = selinux.lsetfilecon(self._to_filesystem_str(path),
                                         str(':'.join(new_context)))
            except OSError:
                self.fail_json(path=path,
                               msg='invalid selinux context',
                               new_context=new_context,
                               cur_context=cur_context,
                               input_was=context)
            if rc != 0:
                self.fail_json(path=path, msg='set selinux context failed')
            changed = True
        return changed
Ejemplo n.º 11
0
def setFileContext(fn, con, instroot = '/'):
    full_path = os.path.normpath("%s/%s" % (instroot, fn))
    rc = False
    if con is not None and os.access(full_path, os.F_OK):
        try:
            rc = (selinux.lsetfilecon(full_path, con) == 0)
        except OSError as e:
            log.info("failed to set SELinux context for %s: %s" % (full_path, e))
    return rc
Ejemplo n.º 12
0
def setFileContext(fn, con, instroot = '/'):
    full_path = os.path.normpath("%s/%s" % (instroot, fn))
    rc = False
    if con is not None and os.access(full_path, os.F_OK):
        try:
            rc = (selinux.lsetfilecon(full_path, con) == 0)
        except OSError as e:
            log.info("failed to set SELinux context for %s: %s" % (full_path, e))
    return rc
Ejemplo n.º 13
0
 def chcon(self, context):
     # If dir returns whether to recusively set context
     try:
         try:
             selinux.lsetfilecon(self.path, context)
             LOG.info('Setting selinux context of %s to %s', self.path,
                      context)
             return True
         except OSError as e:
             if self.is_dir and e.errno == 95:
                 # Operation not supported, assume NFS mount and skip
                 LOG.info('Setting selinux context not supported for %s',
                          self.path)
                 return False
             else:
                 raise
     except Exception:
         LOG.exception('Could not set selinux context of %s to %s:',
                       self.path, context)
         raise
Ejemplo n.º 14
0
    def _chown_chmod_chcon(self,
                           temp_file_path,
                           dest_path,
                           file_info,
                           strict_ownership=1):
        if file_info['filetype'] != 'symlink':
            uid = file_info.get('uid')
            if uid is None:
                if 'username' in file_info:
                    # determine uid

                    try:
                        user_record = pwd.getpwnam(file_info['username'])
                        uid = user_record[2]
                    except Exception:
                        e = sys.exc_info()[1]
                        #Check if username is an int
                        try:
                            uid = int(file_info['username'])
                        except ValueError:
                            raise_with_tb(
                                cfg_exceptions.UserNotFound(
                                    file_info['username']),
                                sys.exc_info()[2])
                else:
                    #default to root (3.2 sats)
                    uid = 0

            gid = file_info.get('gid')
            if gid is None:
                if 'groupname' in file_info:
                    # determine gid
                    try:
                        group_record = grp.getgrnam(file_info['groupname'])
                        gid = group_record[2]
                    except Exception:
                        e = sys.exc_info()[1]
                        try:
                            gid = int(file_info['groupname'])
                        except ValueError:
                            raise_with_tb(
                                cfg_exceptions.GroupNotFound(
                                    file_info['groupname']),
                                sys.exc_info()[2])

                else:
                    #default to root (3.2 sats)
                    gid = 0

        try:
            if file_info['filetype'] != 'symlink':
                os.chown(temp_file_path, uid, gid)

                mode = '600'
                if 'filemode' in file_info:
                    if file_info['filemode'] is "":
                        mode = '000'
                    else:
                        mode = file_info['filemode']

                mode = int(str(mode), 8)
                os.chmod(temp_file_path, mode)

            if 'selinux_ctx' in file_info:
                sectx = file_info.get('selinux_ctx')
                if sectx is not None and sectx is not "":
                    log_debug(1, "selinux context: " + sectx)
                    try:
                        if lsetfilecon(temp_file_path, sectx) < 0:
                            raise Exception(
                                "failed to set selinux context on %s" %
                                dest_path)
                    except OSError:
                        e = sys.exc_info()[1]
                        raise_with_tb(
                            Exception(
                                "failed to set selinux context on %s" %
                                dest_path, e),
                            sys.exc_info()[2])

        except OSError:
            e = sys.exc_info()[1]
            if e.errno == errno.EPERM and not strict_ownership:
                sys.stderr.write(
                    "cannonical file ownership and permissions lost on %s\n" %
                    dest_path)
            else:
                raise
Ejemplo n.º 15
0
def set_selinux_context(path, context):
    """ Sets selinux context, returns False on error and None if selinux is not available """
    if context == get_selinux_context(path):
        return True
    else:
        return not bool(selinux.lsetfilecon(path, ':'.join(context)))
Ejemplo n.º 16
0
def lsetfilecon(path, context):
    selinux.lsetfilecon(path, context)
Ejemplo n.º 17
0
    def _chown_chmod_chcon(self, temp_file_path, dest_path, file_info, strict_ownership=1):
        if file_info['filetype'] != 'symlink':
            uid = file_info.get('uid')
            if uid is None:
                if 'username' in file_info:
                    # determine uid

                    try:
                        user_record = pwd.getpwnam(file_info['username'])
                        uid = user_record[2]
                    except Exception:
                        e = sys.exc_info()[1]
                        #Check if username is an int
                        try:
                            uid = int(file_info['username'])
                        except ValueError:
                            raise_with_tb(cfg_exceptions.UserNotFound(file_info['username']), sys.exc_info()[2])
                else:
                    #default to root (3.2 sats)
                    uid = 0

            gid = file_info.get('gid')
            if gid is None:
                if 'groupname' in file_info:
                    # determine gid
                    try:
                        group_record = grp.getgrnam(file_info['groupname'])
                        gid = group_record[2]
                    except Exception:
                        e = sys.exc_info()[1]
                        try:
                            gid = int(file_info['groupname'])
                        except ValueError:
                            raise_with_tb(cfg_exceptions.GroupNotFound(file_info['groupname']), sys.exc_info()[2])

                else:
                    #default to root (3.2 sats)
                    gid = 0

        try:
            if file_info['filetype'] != 'symlink':
                os.chown(temp_file_path, uid, gid)

                mode = '600'
                if 'filemode' in file_info:
                    if file_info['filemode'] is "":
                        mode='000'
                    else:
                        mode = file_info['filemode']

                mode = int(str(mode), 8)
                os.chmod(temp_file_path, mode)

            if 'selinux_ctx' in file_info:
                sectx = file_info.get('selinux_ctx')
                if sectx is not None and sectx is not "":
                    log_debug(1, "selinux context: " + sectx);
                    try:
                        if lsetfilecon(temp_file_path, sectx) < 0:
                            raise Exception("failed to set selinux context on %s" % dest_path)
                    except OSError:
                        e = sys.exc_info()[1]
                        raise_with_tb(Exception("failed to set selinux context on %s" % dest_path, e), sys.exc_info()[2])

        except OSError:
            e = sys.exc_info()[1]
            if e.errno == errno.EPERM and not strict_ownership:
                sys.stderr.write("cannonical file ownership and permissions lost on %s\n" % dest_path)
            else:
                raise
Ejemplo n.º 18
0
                os.symlink(srcpath, _dsttmp)
            except OSError, 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)


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
Ejemplo n.º 19
0
 def trySetfilecon(src, dest):
     try:
         selinux.lsetfilecon(dest, selinux.lgetfilecon(src)[1])
     except OSError:
         log.error("Could not set selinux context on file %s" % dest)
Ejemplo n.º 20
0
                mode = '600'
                if file_info.has_key('filemode'):
                    if file_info['filemode'] is "":
                        mode='000'
                    else:
                        mode = file_info['filemode']

                mode = string.atoi(str(mode), 8)
                os.chmod(temp_file_path, mode)

            if file_info.has_key('selinux_ctx'):
                sectx = file_info.get('selinux_ctx')
                if sectx is not None and sectx is not "":
                    log_debug(1, "selinux context: " + sectx);
                    try:
                        if lsetfilecon(temp_file_path, sectx) < 0:
                            raise Exception("failed to set selinux context on %s" % dest_path)
                    except OSError, e:
                        raise Exception("failed to set selinux context on %s" % dest_path, e), None, sys.exc_info()[2]

        except OSError, e:
            if e.errno == errno.EPERM and not strict_ownership:
                sys.stderr.write("cannonical file ownership and permissions lost on %s\n" % dest_path)
            else:
                raise



    def _normalize_path_to_root(self, path):
        if self.transaction_root:
            path = utils.normalize_path(self.transaction_root + os.sep + path)
Ejemplo n.º 21
0
def lsetfilecon(filename, context):
    if __enabled < 0:
        return
    if not context:
        return 0
    return selinux.lsetfilecon(filename, context)
Ejemplo n.º 22
0
                mode = '600'
                if file_info.has_key('filemode'):
                    if file_info['filemode'] is "":
                        mode = '000'
                    else:
                        mode = file_info['filemode']

                mode = string.atoi(str(mode), 8)
                os.chmod(temp_file_path, mode)

            if file_info.has_key('selinux_ctx'):
                sectx = file_info.get('selinux_ctx')
                if sectx is not None and sectx is not "":
                    log_debug(1, "selinux context: " + sectx)
                    try:
                        if lsetfilecon(temp_file_path, sectx) < 0:
                            raise Exception(
                                "failed to set selinux context on %s" %
                                dest_path)
                    except OSError, e:
                        raise Exception(
                            "failed to set selinux context on %s" % dest_path,
                            e), None, sys.exc_info()[2]

        except OSError, e:
            if e.errno == errno.EPERM and not strict_ownership:
                sys.stderr.write(
                    "cannonical file ownership and permissions lost on %s\n" %
                    dest_path)
            else:
                raise
Ejemplo n.º 23
0
 def trySetfilecon(src, dest):
     try:
         selinux.lsetfilecon(dest, selinux.lgetfilecon(src)[1])
     except:
         log.error("Could not set selinux context on file %s" % dest)
Ejemplo n.º 24
0
def lsetfilecon(filename, context):
    if __enabled < 0:
        return
    if not context:
        return 0
    return selinux.lsetfilecon(filename, context)