- if (use_selinux()) {
- r = label_fix_selinux(path, ignore_enoent, ignore_erofs);
- if (r < 0)
- return r;
- }
-
- if (use_smack()) {
- r = smack_relabel_in_dev(path);
- if (r < 0)
- return r;
- }
-
- return r;
-}
-
-void label_finish(void) {
-
-#ifdef HAVE_SELINUX
- if (!use_selinux())
- return;
-
- if (label_hnd)
- selabel_close(label_hnd);
-#endif
-}
-
-int label_get_create_label_from_exe(const char *exe, char **label) {
-
- int r = 0;
-
-#ifdef HAVE_SELINUX
- security_context_t mycon = NULL, fcon = NULL;
- security_class_t sclass;
-
- if (!use_selinux()) {
- *label = NULL;
- return 0;
- }
-
- r = getcon(&mycon);
- if (r < 0)
- goto fail;
-
- r = getfilecon(exe, &fcon);
- if (r < 0)
- goto fail;
-
- sclass = string_to_security_class("process");
- r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
- if (r == 0)
- log_debug("SELinux Socket context for %s will be set to %s", exe, *label);
-
-fail:
- if (r < 0 && security_getenforce() == 1)
- r = -errno;
-
- freecon(mycon);
- freecon(fcon);
-#endif
-
- return r;
-}
-
-int label_get_our_label(char **label) {
- int r = -EOPNOTSUPP;
-
-#ifdef HAVE_SELINUX
- char *l = NULL;
-
- r = getcon(&l);
- if (r < 0)
- return r;
-
- *label = l;
-#endif
-
- return r;
-}
-
-int label_get_child_mls_label(int socket_fd, const char *exe, char **label) {
- int r = -EOPNOTSUPP;
-
-#ifdef HAVE_SELINUX
-
- _cleanup_security_context_free_ security_context_t mycon = NULL, peercon = NULL, fcon = NULL, ret = NULL;
- _cleanup_context_free_ context_t pcon = NULL, bcon = NULL;
- security_class_t sclass;
-
- const char *range = NULL;
-
- assert(socket_fd >= 0);
- assert(exe);
- assert(label);
-
- r = getcon(&mycon);
- if (r < 0) {
- r = -EINVAL;
- goto out;
- }
-
- r = getpeercon(socket_fd, &peercon);
- if (r < 0) {
- r = -EINVAL;
- goto out;
- }
-
- r = getexeccon(&fcon);
- if (r < 0) {
- r = -EINVAL;
- goto out;
- }
-
- if (!fcon) {
- /* If there is no context set for next exec let's use context
- of target executable */
- r = getfilecon(exe, &fcon);
- if (r < 0) {
- r = -errno;
- goto out;
- }
- }
-
- bcon = context_new(mycon);
- if (!bcon) {
- r = -ENOMEM;
- goto out;
- }
-
- pcon = context_new(peercon);
- if (!pcon) {
- r = -ENOMEM;
- goto out;
- }
-
- range = context_range_get(pcon);
- if (!range) {
- r = -errno;
- goto out;
- }
-
- r = context_range_set(bcon, range);
- if (r) {
- r = -errno;
- goto out;
- }
-
- freecon(mycon);
- mycon = context_str(bcon);
- if (!mycon) {
- r = -errno;
- goto out;
- }
-
- sclass = string_to_security_class("process");
- r = security_compute_create(mycon, fcon, sclass, &ret);
- if (r < 0) {
- r = -EINVAL;
- goto out;
- }
-
- *label = ret;
- r = 0;
-
-out:
- if (r < 0 && security_getenforce() == 1)
- return r;
-#endif
- return r;
-}
-
-int label_context_set(const char *path, mode_t mode) {
- int r = 0;
-
-#ifdef HAVE_SELINUX
- security_context_t filecon = NULL;
-
- if (!use_selinux() || !label_hnd)
- return 0;
-
- r = selabel_lookup_raw(label_hnd, &filecon, path, mode);
- if (r < 0 && errno != ENOENT)
- r = -errno;
- else if (r == 0) {
- r = setfscreatecon(filecon);
- if (r < 0) {
- log_error("Failed to set SELinux file context on %s: %m", path);
- r = -errno;
- }
-
- freecon(filecon);
- }
-
- if (r < 0 && security_getenforce() == 0)
- r = 0;
-#endif
-
- return r;
-}
-
-int label_socket_set(const char *label) {
-
-#ifdef HAVE_SELINUX
- if (!use_selinux())
- return 0;
-
- if (setsockcreatecon((security_context_t) label) < 0) {
- log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
- "Failed to set SELinux context (%s) on socket: %m", label);
-
- if (security_getenforce() == 1)
- return -errno;
- }
-#endif
-
- return 0;
-}
-
-void label_context_clear(void) {
-
-#ifdef HAVE_SELINUX
- PROTECT_ERRNO;
-
- if (!use_selinux())
- return;
-
- setfscreatecon(NULL);
-#endif
-}
-
-void label_socket_clear(void) {
-
-#ifdef HAVE_SELINUX
- PROTECT_ERRNO;
-
- if (!use_selinux())
- return;
-
- setsockcreatecon(NULL);
-#endif
-}
-
-void label_free(const char *label) {
-
-#ifdef HAVE_SELINUX
- if (!use_selinux())
- return;
-
- freecon((security_context_t) label);
-#endif
-}
-
-static int label_mkdir_selinux(const char *path, mode_t mode) {
- int r = 0;
-
-#ifdef HAVE_SELINUX
- /* Creates a directory and labels it according to the SELinux policy */
- security_context_t fcon = NULL;
-
- if (!label_hnd)
- return 0;
-
- if (path_is_absolute(path))
- r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFDIR);
- else {
- _cleanup_free_ char *newpath;
-
- newpath = path_make_absolute_cwd(path);
- if (!newpath)
- return -ENOMEM;
-
- r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFDIR);
- }
-
- if (r == 0)
- r = setfscreatecon(fcon);
-
- if (r < 0 && errno != ENOENT) {
- log_error("Failed to set security context %s for %s: %m", fcon, path);
-
- if (security_getenforce() == 1) {
- r = -errno;
- goto finish;
- }
- }
-
- r = mkdir(path, mode);
- if (r < 0)
- r = -errno;
-
-finish:
- setfscreatecon(NULL);
- freecon(fcon);
-#endif
-
- return r;
-}
-
-int label_mkdir(const char *path, mode_t mode) {
- int r;
-
- if (use_selinux()) {
- r = label_mkdir_selinux(path, mode);