#!/usr/bin/python3 """ Set SELinux file contexts Sets correct SELinux labels for every file in the tree, according to the SELinux policy installed inside the tree. Uses the host's `setfiles` program and the tree's `file_contexts`, usually /etc/selinux//contexts/files/file_contexts where is the value set in /etc/selinux/config (usually "targeted" but may also be "minimum" or "mls"). This stage may set or modify xattrs for any file inside the tree, but should not need to create files, modify file contents, or read any files other than `file_contexts`. This stage should run after all other stages that create (or move) files, since labels for newly-created files are determined by the host's SELinux policy and may not match the tree's policy. """ import os import subprocess import sys import osbuild.api SCHEMA = """ "additionalProperties": false, "required": ["file_contexts"], "properties": { "file_contexts": { "type": "string", "description": "Path to the active SELinux policy's `file_contexts`" }, "labels": { "type": "object", "description": "Labels to set of the specified files or folders", "items": { "type": "object" } } } """ def main(tree, options): file_contexts = os.path.join(f"{tree}", options["file_contexts"]) labels = options.get("labels", {}) subprocess.run(["setfiles", "-F", "-r", f"{tree}", f"{file_contexts}", f"{tree}"], check=True) for path, label in labels.items(): fullpath = os.path.join(tree, path.lstrip("/")) subprocess.run(["chcon", "-v", label, fullpath], check=True) if __name__ == '__main__': args = osbuild.api.arguments() r = main(args["tree"], args["options"]) sys.exit(r)