util/selinux: add setfilecon method
This is basically a re-implementation of `setfilecon(3)` minus the translation of human readable context to raw context. Add test for the new function.
This commit is contained in:
parent
5735357b74
commit
75df59bace
2 changed files with 46 additions and 0 deletions
|
|
@ -1,5 +1,6 @@
|
|||
"""SELinux utility functions"""
|
||||
|
||||
import errno
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
|
@ -57,3 +58,27 @@ def getfilecon(path: str) -> str:
|
|||
label = os.getxattr(path, XATTR_NAME_SELINUX,
|
||||
follow_symlinks=False)
|
||||
return label.decode().strip('\n\0')
|
||||
|
||||
|
||||
def setfilecon(path: str, context: str) -> None:
|
||||
"""
|
||||
Set the security context associated with `path`
|
||||
|
||||
Like `setfilecon`(3), but does not attempt to translate
|
||||
the context via `selinux_trans_to_raw_context`.
|
||||
"""
|
||||
|
||||
try:
|
||||
os.setxattr(path, XATTR_NAME_SELINUX,
|
||||
context.encode(),
|
||||
follow_symlinks=True)
|
||||
except OSError as err:
|
||||
# in case we get a not-supported error, check if
|
||||
# the context we want to set is already set and
|
||||
# ignore the error in that case. This follows the
|
||||
# behavior of `setfilecon(3)`.
|
||||
if err.errno == errno.ENOTSUP:
|
||||
have = getfilecon(path)
|
||||
if have == context:
|
||||
return
|
||||
raise
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
# Tests for the 'osbuild.util.selinux' module.
|
||||
#
|
||||
|
||||
import errno
|
||||
import io
|
||||
from unittest import mock
|
||||
|
||||
from osbuild.util import selinux
|
||||
|
||||
|
|
@ -37,3 +39,22 @@ def test_selinux_config():
|
|||
|
||||
policy = selinux.config_get_policy(cfg)
|
||||
assert policy == 'targeted'
|
||||
|
||||
|
||||
def test_setfilecon():
|
||||
with mock.patch("os.setxattr") as setxattr:
|
||||
|
||||
selinux.setfilecon("/path", "context")
|
||||
setxattr.assert_called_once_with("/path", selinux.XATTR_NAME_SELINUX,
|
||||
b"context", follow_symlinks=True)
|
||||
|
||||
with mock.patch("os.getxattr") as getxattr:
|
||||
with mock.patch("os.setxattr") as setxattr:
|
||||
|
||||
def raise_error(*_args, **_kwargs):
|
||||
raise OSError(errno.ENOTSUP, "Not supported")
|
||||
|
||||
getxattr.return_value = b"context"
|
||||
setxattr.side_effect = raise_error
|
||||
|
||||
selinux.setfilecon("path", "context")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue