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 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 = ''
        if selinux_ctx == None:
            selinux_ctx = ''

        ret['selinux_ctx'] = selinux_ctx

        return ret
Ejemplo n.º 3
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.º 4
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.º 5
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'] & int('07777', 8))

        #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 = ''
        if selinux_ctx == None:
            selinux_ctx = ''

        ret['selinux_ctx'] = selinux_ctx

        return ret
Ejemplo n.º 6
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 = ''

        cur_sectx = lgetfilecon(path)[1]
        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.path.abspath(os.readlink(path))
                newlink = os.path.abspath(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
Ejemplo n.º 7
0
def get_selinux_context(path):
    """ Returns selinux context, False on error and None if selinux is not available """
    ret_code, context = selinux.lgetfilecon(path)
    if ret_code != -1:
        return context.split(':', 3)
    else:
        return False
Ejemplo n.º 8
0
 def _update(self):
     try:
         statinfo = os.stat(self.path)
         self.is_dir = stat.S_ISDIR(statinfo.st_mode)
         self.uid = statinfo.st_uid
         self.gid = statinfo.st_gid
         self.secontext = selinux.lgetfilecon(self.path)[1]
     except Exception:
         LOG.exception('Could not update metadata for %s', self.path)
         raise
Ejemplo n.º 9
0
    def _gather_data(self, path):
        """ Get data on the existing state of <path> -- e.g., whether
        or not it exists, owner, group, permissions, etc. """
        try:
            ondisk = os.lstat(path)
        except OSError:
            self.logger.debug("POSIX: %s does not exist" % path)
            return (False, None, None, None, None, None)

        try:
            owner = str(ondisk[stat.ST_UID])
        except OSError:
            err = sys.exc_info()[1]
            self.logger.debug("POSIX: Could not get current owner of %s: %s" %
                              (path, err))
            owner = None
        except KeyError:
            self.logger.error('POSIX: User resolution failed for %s' % path)
            owner = None

        try:
            group = str(ondisk[stat.ST_GID])
        except (OSError, KeyError):
            err = sys.exc_info()[1]
            self.logger.debug("POSIX: Could not get current group of %s: %s" %
                              (path, err))
            group = None
        except KeyError:
            self.logger.error('POSIX: Group resolution failed for %s' % path)
            group = None

        try:
            mode = oct_mode(ondisk[stat.ST_MODE])[-4:]
        except (OSError, KeyError, TypeError):
            err = sys.exc_info()[1]
            self.logger.debug("POSIX: Could not get current permissions of "
                              "%s: %s" % (path, err))
            mode = None

        if HAS_SELINUX:
            try:
                secontext = selinux.lgetfilecon(path)[1].split(":")[2]
            except (OSError, KeyError):
                err = sys.exc_info()[1]
                self.logger.debug("POSIX: Could not get current SELinux "
                                  "context of %s: %s" % (path, err))
                secontext = None
        else:
            secontext = None

        if HAS_ACLS and not stat.S_ISLNK(ondisk[stat.ST_MODE]):
            acls = self._list_file_acls(path)
        else:
            acls = None
        return (ondisk, owner, group, mode, secontext, acls)
Ejemplo n.º 10
0
Archivo: base.py Proyecto: fennm/bcfg2
    def _gather_data(self, path):
        """ Get data on the existing state of <path> -- e.g., whether
        or not it exists, owner, group, permissions, etc. """
        try:
            ondisk = os.lstat(path)
        except OSError:
            self.logger.debug("POSIX: %s does not exist" % path)
            return (False, None, None, None, None, None)

        try:
            owner = str(ondisk[stat.ST_UID])
        except OSError:
            err = sys.exc_info()[1]
            self.logger.debug("POSIX: Could not get current owner of %s: %s" %
                              (path, err))
            owner = None
        except KeyError:
            self.logger.error('POSIX: User resolution failed for %s' % path)
            owner = None

        try:
            group = str(ondisk[stat.ST_GID])
        except (OSError, KeyError):
            err = sys.exc_info()[1]
            self.logger.debug("POSIX: Could not get current group of %s: %s" %
                              (path, err))
            group = None
        except KeyError:
            self.logger.error('POSIX: Group resolution failed for %s' % path)
            group = None

        try:
            mode = oct_mode(ondisk[stat.ST_MODE])[-4:]
        except (OSError, KeyError, TypeError):
            err = sys.exc_info()[1]
            self.logger.debug("POSIX: Could not get current permissions of "
                              "%s: %s" % (path, err))
            mode = None

        if HAS_SELINUX:
            try:
                secontext = selinux.lgetfilecon(path)[1].split(":")[2]
            except (OSError, KeyError):
                err = sys.exc_info()[1]
                self.logger.debug("POSIX: Could not get current SELinux "
                                  "context of %s: %s" % (path, err))
                secontext = None
        else:
            secontext = None

        if HAS_ACLS and not stat.S_ISLNK(ondisk[stat.ST_MODE]):
            acls = self._list_file_acls(path)
        else:
            acls = None
        return (ondisk, owner, group, mode, secontext, acls)
 def selinux_context(self, path):
     context = self.selinux_initial_context()
     if not HAVE_SELINUX or not self.selinux_enabled():
         return context
     try:
         ret = selinux.lgetfilecon(self._to_filesystem_str(path))
     except OSError, e:
         if e.errno == errno.ENOENT:
             self.fail_json(path=path, msg='path %s does not exist' % path)
         else:
             self.fail_json(path=path, msg='failed to retrieve selinux context')
Ejemplo n.º 12
0
 def selinux_context(self, path):
     context = self.selinux_initial_context()
     if not HAVE_SELINUX or not self.selinux_enabled():
         return context
     try:
         ret = selinux.lgetfilecon(self._to_filesystem_str(path))
     except OSError, e:
         if e.errno == errno.ENOENT:
             self.fail_json(path=path, msg='path %s does not exist' % path)
         else:
             self.fail_json(path=path, msg='failed to retrieve selinux context')
Ejemplo n.º 13
0
def copyfile(src, dest):
    src = _native_string(src, encoding=_encodings['fs'], errors='strict')
    dest = _native_string(dest, encoding=_encodings['fs'], errors='strict')
    (rc, ctx) = selinux.lgetfilecon(src)
    if rc < 0:
        raise OSError(_("copyfile: Failed getting context of \"%s\".") % src)

    setfscreate(ctx)
    try:
        shutil.copyfile(src, dest)
    finally:
        setfscreate()
Ejemplo n.º 14
0
def copyfile(src, dest):
    src = _native_string(src, encoding=_encodings["fs"], errors="strict")
    dest = _native_string(dest, encoding=_encodings["fs"], errors="strict")
    (rc, ctx) = selinux.lgetfilecon(src)
    if rc < 0:
        raise OSError(_('copyfile: Failed getting context of "%s".') % src)

    setfscreate(ctx)
    try:
        shutil.copyfile(src, dest)
    finally:
        setfscreate()
Ejemplo n.º 15
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

        ret['selinux_ctx'] = lgetfilecon(path)[1]
        if ret['selinux_ctx'] == None:
            ret['selinux_ctx'] = ''

        return ret
Ejemplo n.º 16
0
def rename(src, dest):
    src = _native_string(src, encoding=_encodings['fs'], errors='strict')
    (rc, ctx) = selinux.lgetfilecon(src)
    if rc < 0:
        raise OSError(_("rename: Failed getting context of \"%s\".") % src)

    setfscreate(ctx)
    try:
        os.rename(
            _unicode_encode(src, encoding=_encodings['fs'], errors='strict'),
            _unicode_encode(dest, encoding=_encodings['fs'], errors='strict'))
    finally:
        setfscreate()
Ejemplo n.º 17
0
def restorecon_single(path):
    try:
        mode = os.lstat(path)[stat.ST_MODE]
    except FileNotFoundError:
        path = os.path.realpath(os.path.expanduser(path))
        mode = os.lstat(path)[stat.ST_MODE]

    context_default = matchpathcon(path, mode)

    context_old = selinux.lgetfilecon(path)

    if context_old != context_default:
        lsetfilecon(path, context_default)
Ejemplo n.º 18
0
def rename(src, dest):
	src = _unicode_encode(src, encoding=_encodings['fs'], errors='strict')
	dest = _unicode_encode(dest, encoding=_encodings['fs'], errors='strict')
	(rc, ctx) = selinux.lgetfilecon(src)
	if rc < 0:
		src = _unicode_decode(src, encoding=_encodings['fs'], errors='replace')
		raise OSError(_("rename: Failed getting context of \"%s\".") % src)

	setfscreate(ctx)
	try:
		os.rename(src,dest)
	finally:
		setfscreate()
Ejemplo n.º 19
0
def rename(src, dest):
    src = _native_string(src, encoding=_encodings["fs"], errors="strict")
    (rc, ctx) = selinux.lgetfilecon(src)
    if rc < 0:
        raise OSError(_('rename: Failed getting context of "%s".') % src)

    setfscreate(ctx)
    try:
        os.rename(
            _unicode_encode(src, encoding=_encodings["fs"], errors="strict"),
            _unicode_encode(dest, encoding=_encodings["fs"], errors="strict"),
        )
    finally:
        setfscreate()
Ejemplo n.º 20
0
def symlink(target, link, reflnk):
    target = _native_string(target, encoding=_encodings['fs'], errors='strict')
    link = _native_string(link, encoding=_encodings['fs'], errors='strict')
    reflnk = _native_string(reflnk, encoding=_encodings['fs'], errors='strict')
    (rc, ctx) = selinux.lgetfilecon(reflnk)
    if rc < 0:
        raise OSError(
         _("symlink: Failed getting context of reference symlink \"%s\".") \
         % reflnk)

    setfscreate(ctx)
    try:
        os.symlink(target, link)
    finally:
        setfscreate()
Ejemplo n.º 21
0
def symlink(target, link, reflnk):
    reflnk = _native_string(reflnk, encoding=_encodings["fs"], errors="strict")
    (rc, ctx) = selinux.lgetfilecon(reflnk)
    if rc < 0:
        raise OSError(
            _('symlink: Failed getting context of reference symlink "%s".') % reflnk
        )

    setfscreate(ctx)
    try:
        os.symlink(
            _unicode_encode(target, encoding=_encodings["fs"], errors="strict"),
            _unicode_encode(link, encoding=_encodings["fs"], errors="strict"),
        )
    finally:
        setfscreate()
Ejemplo n.º 22
0
def rename(src, dest):
    src = _native_string(src, encoding=_encodings['fs'], errors='strict')
    dest = _native_string(dest, encoding=_encodings['fs'], errors='strict')
    (rc, ctx) = selinux.lgetfilecon(src)
    if rc < 0:
        if sys.hexversion < 0x3000000:
            src = _unicode_decode(src,
                                  encoding=_encodings['fs'],
                                  errors='replace')
        raise OSError(_("rename: Failed getting context of \"%s\".") % src)

    setfscreate(ctx)
    try:
        os.rename(src, dest)
    finally:
        setfscreate()
Ejemplo n.º 23
0
def symlink(target, link, reflnk):
	target = _unicode_encode(target, encoding=_encodings['fs'], errors='strict')
	link = _unicode_encode(link, encoding=_encodings['fs'], errors='strict')
	reflnk = _unicode_encode(reflnk, encoding=_encodings['fs'], errors='strict')
	(rc, ctx) = selinux.lgetfilecon(reflnk)
	if rc < 0:
		reflnk = _unicode_decode(reflnk, encoding=_encodings['fs'],
			errors='replace')
		raise OSError(
			_("symlink: Failed getting context of reference symlink \"%s\".") \
			% reflnk)

	setfscreate(ctx)
	try:
		os.symlink(target, link)
	finally:
		setfscreate()
Ejemplo n.º 24
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, e:
            if e.errno == errno.ENOENT:
                run_restorecon = True
            else:
                raise
Ejemplo n.º 25
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
Ejemplo n.º 26
0
    def _verify(self, path):
        """Verify the selinux context on given path is as expected."""
        fn = Pathname(path, prefix=self._prefix)
        try:
            mode = os.lstat(fn)[stat.ST_MODE]
            status, expected = selinux.matchpathcon(path, mode)
        except OSError:
            fn = Pathname(os.path.realpath(os.path.expanduser(fn)),
                          prefix=None)
            try:
                mode = os.lstat(fn)[stat.ST_MODE]
                status, expected = selinux.matchpathcon(path, mode)
            except OSError as e:
                sys.stderr.write('Verifying "{}" failed with {}\n'.format(
                    path, os.strerror(int(e.errno))))
                return False

        if status != 0:
            sys.stderr.write('Verifying "{}" failed with {}\n'.format(
                path, os.strerror(int(status))))
            return False

        try:
            _, actual = selinux.lgetfilecon(fn)
        except OSError as e:
            if e.errno != errno.ENODATA:
                sys.stderr.write('Verifying "{}" failed with {}\n'.format(
                    path, os.strerror(int(e.errno))))
                return False
            actual = None

        if expected != actual:
            sys.stderr.write(
                "{} incorrect context: actual({}) expected({})\n".format(
                    path, actual, expected))
            return False
        return True
Ejemplo n.º 27
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.º 28
0
 def _update(self):
     statinfo = os.stat(self.path)
     self.is_dir = stat.S_ISDIR(statinfo.st_mode)
     self.uid = statinfo.st_uid
     self.gid = statinfo.st_gid
     self.secontext = selinux.lgetfilecon(self.path)[1]
Ejemplo n.º 29
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.º 30
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 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_sum = utils.sha256_file(src)
            dst_sum = utils.sha256_file(dst)
            if src_sum != dst_sum:
                status.append('modified')

        return {
                    "status"            :   ','.join(status),
                    "owner"             :   owner_status,
                    "group"             :   group_status,
                    "mode"              :   perm_status,
                    "selinux"           :   selinux_status,
                    "file"              :   file,
               }
Ejemplo n.º 31
0
def lgetfilecon(filename):
    if __enabled < 0:
        return
    return selinux.lgetfilecon(filename)
Ejemplo n.º 32
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 = ''
        owner_result = ''
        group_result = ''
        perm_result = ''
        result = ''

        stat_err = 0

        try:
            cur_stat = os.lstat(path)
        except:
            stat_err = 1

        if file_struct['filetype'] != 'symlink':
            if not stat_err:
                 #check for owner differences
                 cur_uid = cur_stat[stat.ST_UID]
                 try:
                     cur_user = pwd.getpwuid(cur_uid)[0]
                 except KeyError:
                     #Orphan UID with no name,return unknown
                     cur_user = "******" % (cur_uid,)
            else:
                 cur_user = "******"

            if cur_user == file_struct['username']:
                 owner_result = ""

            else:
                 owner_result = "User name differ: actual: [%s], expected: [%s]\n" % (cur_user, file_struct['username'])

            if not stat_err:
                #check for group differences
                cur_gid = cur_stat[stat.ST_GID]
                try:
                    cur_group = grp.getgrgid(cur_gid)[0]
                except KeyError:
                    #Orphan GID with no name,return unknown
                    cur_group = "unknown(GID %d)" % (cur_gid,)
            else:
                cur_group = "missing"

            if cur_group == file_struct['groupname']:
                group_result = ""
            else:
                group_result = "Group name differ: actual: [%s], expected: [%s]\n" % (cur_group, file_struct['groupname'])

            #check for permissions differences
            if not stat_err:
                cur_perm = format(stat.S_IMODE(cur_stat[stat.ST_MODE]), 'o')
            else:
                cur_perm = "missing"

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

            #perm_status gets displayed with the verbose option.
            if cur_perm == str(file_struct['filemode']):
                perm_result = ""
            else:
                perm_result = "File mode differ: actual: [%s], expected: [%s]\n" % (cur_perm, file_struct['filemode'])

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

        if cur_sectx == None:
            cur_sectx = ''

        if 'selinux_ctx' in file_struct 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'] == 'directory':
            if os.path.isdir(file_struct['path']):
                result = ''
            else:
                result = "Deployed directory is no longer a directory!"
        elif 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 = sys.exc_info()[1]
                if e.errno == 22:
                    result = "Deployed symlink is no longer a symlink!"
                else:
                    raise e
        else:
            result = ''.join(diff(temp_file, path, display_diff=get_config('display_diff'),
                is_binary=False if file_struct['is_binary'] == 'N' else True))

        if temp_file:
            os.unlink(temp_file)
        return owner_result + group_result + perm_result + sectx_result + result
Ejemplo n.º 33
0
def lgetfilecon(filename):
    if __enabled < 0:
        return
    return selinux.lgetfilecon(filename)
Ejemplo n.º 34
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 = ''
        owner_result = ''
        group_result = ''
        perm_result = ''
        result = ''

        stat_err = 0

        try:
            cur_stat = os.lstat(path)
        except:
            stat_err = 1

        if file_struct['filetype'] != 'symlink':
            if not stat_err:
                #check for owner differences
                cur_uid = cur_stat[stat.ST_UID]
                try:
                    cur_user = pwd.getpwuid(cur_uid)[0]
                except KeyError:
                    #Orphan UID with no name,return unknown
                    cur_user = "******" % (cur_uid, )
            else:
                cur_user = "******"

            if cur_user == file_struct['username']:
                owner_result = ""

            else:
                owner_result = "User name differ: actual: [%s], expected: [%s]\n" % (
                    cur_user, file_struct['username'])

            if not stat_err:
                #check for group differences
                cur_gid = cur_stat[stat.ST_GID]
                try:
                    cur_group = grp.getgrgid(cur_gid)[0]
                except KeyError:
                    #Orphan GID with no name,return unknown
                    cur_group = "unknown(GID %d)" % (cur_gid, )
            else:
                cur_group = "missing"

            if cur_group == file_struct['groupname']:
                group_result = ""
            else:
                group_result = "Group name differ: actual: [%s], expected: [%s]\n" % (
                    cur_group, file_struct['groupname'])

            #check for permissions differences
            if not stat_err:
                cur_perm = str(oct(stat.S_IMODE(cur_stat[stat.ST_MODE])))
            else:
                cur_perm = "missing"

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

            #perm_status gets displayed with the verbose option.
            if cur_perm == str(file_struct['filemode']):
                perm_result = ""
            else:
                perm_result = "File mode differ: actual: [%s], expected: [%s]\n" % (
                    cur_perm, file_struct['filemode'])

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

        if cur_sectx == None:
            cur_sectx = ''

        if 'selinux_ctx' in file_struct 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'] == 'directory':
            if os.path.isdir(file_struct['path']):
                result = ''
            else:
                result = "Deployed directory is no longer a directory!"
        elif 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 = sys.exc_info()[1]
                if e.errno == 22:
                    result = "Deployed symlink is no longer a symlink!"
                else:
                    raise e
        else:
            result = ''.join(
                diff(temp_file, path, display_diff=get_config('display_diff')))

        if temp_file:
            os.unlink(temp_file)
        return owner_result + group_result + perm_result + sectx_result + result
Ejemplo n.º 35
0
 def _get_secontext(self):
     if os.path.exists(self.secontext_marker_path):
         return selinux.lgetfilecon(self.secontext_marker_path)[1]
     else:
         return None