def selinux_setfilecon(storage, label): """ Wrapper for selinux.setfilecon. Libvirt may be able to relabel existing storage someday, we can fold that into this. """ if have_selinux(): selinux.setfilecon(storage, label)
def _compile(self, args, executable, env): self._copy_src(self.COMPILE_LEVEL) with open("/dev/null", "r") as stdin: setfscreatecon(self.filecon(self.COMPILE_LEVEL)) setexeccon(self.execcon(self.COMPILE_LEVEL)) p = Popen( args, bufsize=-1, executable=executable, stdin=stdin, stdout=PIPE, stderr=STDOUT, close_fds=True, cwd=self._tempdir, env=env) setexeccon(None) setfscreatecon(None) stdout, _ = p.communicate() code = p.wait() setfilecon(self._tempdir, self.filecon(self.RUN_LEVEL)) if code != EX_OK: return (code, stdout) setfilecon( join(self._tempdir, self.target_filename), self.filecon(self.RUN_LEVEL)) return (code,)
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
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 __save_as(self, filename = None): global has_selinux """Save the current version to the given filename""" if filename == None: filename = self.file dprint("Saving UserDatabase to %s\n", filename) try: os.rename(filename, filename + ".bak") backup = 1 except: backup = 0 pass try: f = open(filename, 'w') except: if backup == 1: try: os.rename(filename + ".bak", filename) dprint("Restore from %s.bak\n", filename) except: dprint("Failed to restore from %s.bak\n", filename) raise SystemDatabaseException( _("Could not open %s for writing") % filename) try: f.write(self.doc.serialize("UTF-8", format=1)) f.close() except: if backup == 1: try: os.rename(filename + ".bak", filename) dprint("Restore from %s.bak\n", filename) except: dprint("Failed to restore from %s.bak\n", filename) raise SystemDatabaseException( _("Failed to save UserDatabase to %s") % filename) if has_selinux: if selinux.is_selinux_enabled() > 0: rc, con = selinux.matchpathcon(filename, 0) if rc == 0: selinux.setfilecon(filename, con) self.modified = 0
def test_atomic_write_relabel(tmpdir): path = str(tmpdir.join("file")) # Create old file with non-default label. fileUtils.atomic_write(path, b"old") selinux.setfilecon(path, "unconfined_u:object_r:etc_t:s0") fileUtils.atomic_write(path, b"new", relabel=True) with open(path, "rb") as f: assert f.read() == b"new" assert stat.S_IMODE(os.stat(path).st_mode) == 0o644 # The label depends on the enviroment and selinux policy: # - Locally we get: "unconfined_u:object_r:user_tmp_t:s0" # - In mock we get: "unconfined_u:object_r:mock_var_lib_t:s0" # So lets check what selinux.restorecon(path, force=True) is creating. control = str(tmpdir.ensure("control")) selinux.restorecon(control, force=True) assert selinux.getfilecon(path)[1] == selinux.getfilecon(control)[1]
def set_password(user, password): """Set the password for a particular user""" for filename in PASSWD_FILES: if not os.path.exists(filename): continue # Get the selinux file context before we do anything with the file if SELINUX: selinux_context = selinux.getfilecon(filename) tmpfile = _create_temp_password_file(user, password, filename) bakfile = '{0}.bak.{1}'.format(filename, os.getpid()) os.rename(filename, bakfile) os.rename(tmpfile, filename) os.remove(bakfile) # Update selinux context after the file replace if SELINUX: selinux.setfilecon(filename, selinux_context[1]) return raise PasswordError((500, "No password file found"))
def compile(self, args): self._copy_src(self.RUN_LEVEL) setfilecon(self._tempdir, self.filecon(self.RUN_LEVEL)) return (EX_OK,)
if selinuxIsEnabled: try: # not sure at this point if we're updating Security Blanket or OS Lockdown, so # do a quick check... # If upgrading Security Blanket start with *that* contexts, otherwise use OS Lockdown context. if os.path.isfile( '/usr/share/security-blanket/sb_utils/auth/Affirm.pyo'): startingContext = selinux.getfilecon( "/usr/share/security-blanket")[1] else: startingContext = selinux.getfilecon( "/usr/share/oslockdown")[1] selinux.setfilecon(candidate1, startingContext.replace("_rw_t", "_py_t")) selinux.setfilecon(candidate2, startingContext.replace("_rw_t", "_licso_t")) os.chmod(candidate1, 0700) os.chmod(candidate2, 0700) except (NameError, AttributeError), e: logging.getLogger('AutoUpdate').error(e) sys.path.append(candidatedir) import AutoupdateComms except Exception, e: raise AutoUpdateError(e) class Shim: