[RFC PATCH 2/3] libselinux: add security_is_policy_capabilty_enabled()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Allow userspace (e.g. object managers like systemd) to obtain the state of a policy capability via a library call.
---
 libselinux/include/selinux/selinux.h          |  3 +
 .../security_is_policy_capability_enabled.3   | 27 ++++++++
 libselinux/src/polcap.c                       | 64 +++++++++++++++++++
 libselinux/src/selinux_internal.h             |  1 +
 libselinux/src/selinuxswig_python_exception.i |  9 +++
 5 files changed, 104 insertions(+)
 create mode 100644 libselinux/man/man3/security_is_policy_capability_enabled.3
 create mode 100644 libselinux/src/polcap.c

diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h
index fe46e681..b46f152d 100644
--- a/libselinux/include/selinux/selinux.h
+++ b/libselinux/include/selinux/selinux.h
@@ -354,6 +354,9 @@ extern int security_disable(void);
 /* Get the policy version number. */
 extern int security_policyvers(void);
 
+/* Get the state of a policy capability. */
+extern int security_is_policy_capability_enabled(const char *name);
+
 /* Get the boolean names */
 extern int security_get_boolean_names(char ***names, int *len);
 
diff --git a/libselinux/man/man3/security_is_policy_capability_enabled.3 b/libselinux/man/man3/security_is_policy_capability_enabled.3
new file mode 100644
index 00000000..18c53b67
--- /dev/null
+++ b/libselinux/man/man3/security_is_policy_capability_enabled.3
@@ -0,0 +1,27 @@
+.TH "security_is_policy_capability_enabled" "3" "9 January 2020" "cgzones@xxxxxxxxxxxxxx" "SELinux API documentation"
+.SH "NAME"
+security_is_policy_capability_enabled \- get the state of a SELinux policy
+capability
+.
+.SH "SYNOPSIS"
+.B #include <selinux/selinux.h>
+.sp
+.BI "int security_is_policy_capability_enabled(const char *" name ");"
+.
+.SH "DESCRIPTION"
+.BR security_is_policy_capability_enabled ()
+returns 1 if the SELinux policy capability with the given name is enabled,
+0 if it is disabled, and \-1 on error.
+.SH "NOTES"
+The parameter
+.IR name
+is case insensitive.
+
+If the the current kernel does not support the given policy capability \-1 is returned and
+.BR errno
+is set to
+.BR ENOTSUP
+\&.
+.
+.SH "SEE ALSO"
+.BR selinux "(8)"
diff --git a/libselinux/src/polcap.c b/libselinux/src/polcap.c
new file mode 100644
index 00000000..801231cf
--- /dev/null
+++ b/libselinux/src/polcap.c
@@ -0,0 +1,64 @@
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "policy.h"
+#include "selinux_internal.h"
+
+int security_is_policy_capability_enabled(const char *name)
+{
+	int fd, enabled;
+	ssize_t ret;
+	char path[PATH_MAX];
+	char buf[20];
+	DIR *polcapdir;
+	struct dirent *dentry;
+
+	if (!selinux_mnt) {
+		errno = ENOENT;
+		return -1;
+	}
+
+	snprintf(path, sizeof path, "%s/policy_capabilities", selinux_mnt);
+	polcapdir = opendir(path);
+	if (!polcapdir)
+		return -1;
+
+	while ((dentry = readdir(polcapdir)) != NULL) {
+		if (strcmp(dentry->d_name, ".") == 0 || strcmp(dentry->d_name, "..") == 0)
+			continue;
+
+		if (strcasecmp(name, dentry->d_name) != 0)
+			continue;
+
+		snprintf(path, sizeof path, "%s/policy_capabilities/%s", selinux_mnt, dentry->d_name);
+		fd = open(path, O_RDONLY | O_CLOEXEC);
+		if (fd < 0)
+		    goto err;
+
+		memset(buf, 0, sizeof buf);
+		ret = read(fd, buf, sizeof buf - 1);
+		close(fd);
+		if (ret < 0)
+			goto err;
+
+		if (sscanf(buf, "%d", &enabled) != 1)
+			goto err;
+
+		closedir(polcapdir);
+		return !!enabled;
+	}
+
+	if (errno == 0)
+		errno = ENOTSUP;
+err:
+	closedir(polcapdir);
+	return -1;
+}
+
+hidden_def(security_is_policy_capability_enabled)
diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h
index 8b4bed2f..7ca1c329 100644
--- a/libselinux/src/selinux_internal.h
+++ b/libselinux/src/selinux_internal.h
@@ -9,6 +9,7 @@ hidden_proto(selinux_mkload_policy)
     hidden_proto(security_disable)
     hidden_proto(security_policyvers)
     hidden_proto(security_load_policy)
+    hidden_proto(security_is_policy_capability_enabled)
     hidden_proto(security_get_boolean_active)
     hidden_proto(security_get_boolean_names)
     hidden_proto(security_set_boolean)
diff --git a/libselinux/src/selinuxswig_python_exception.i b/libselinux/src/selinuxswig_python_exception.i
index cf658259..bd107295 100644
--- a/libselinux/src/selinuxswig_python_exception.i
+++ b/libselinux/src/selinuxswig_python_exception.i
@@ -665,6 +665,15 @@
 }
 
 
+%exception security_is_policy_capability_enabled {
+  $action
+  if (result < 0) {
+     PyErr_SetFromErrno(PyExc_OSError);
+     SWIG_fail;
+  }
+}
+
+
 %exception security_get_boolean_names {
   $action
   if (result < 0) {
-- 
2.25.0.rc2




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux