]> git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/selinux-utils.c
Merge branch 'pager/less-quirk' of https://github.com/t-8ch/util-linux
[thirdparty/util-linux.git] / lib / selinux-utils.c
1 /*
2 * No copyright is claimed. This code is in the public domain; do with
3 * it what you wish.
4 *
5 * Written by Karel Zak <kzak@redhat.com> [January 2021]
6 */
7 #include <selinux/context.h>
8 #include <selinux/selinux.h>
9 #include <selinux/label.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <errno.h>
14
15 #include "selinux-utils.h"
16
17 /* set the SELinux security context used for _creating_ a new file system object
18 *
19 * returns 0 on success,
20 * or <0 on error
21 */
22 int ul_setfscreatecon_from_file(char *orig_file)
23 {
24 if (is_selinux_enabled() > 0) {
25 char *scontext = NULL;
26
27 if (getfilecon(orig_file, &scontext) < 0)
28 return -1;
29 if (setfscreatecon(scontext) < 0) {
30 freecon(scontext);
31 return -1;
32 }
33 freecon(scontext);
34 }
35 return 0;
36 }
37
38 /* returns 1 if user has access to @class and @perm ("passwd", "chfn")
39 * or 0 on error,
40 * or 0 if has no access -- in this case sets @user_cxt to user-context
41 */
42 int ul_selinux_has_access(const char *classstr, const char *perm, char **user_cxt)
43 {
44 char *user;
45 int rc;
46
47 if (user_cxt)
48 *user_cxt = NULL;
49
50 if (getprevcon(&user) != 0)
51 return 0;
52
53 rc = selinux_check_access(user, user, classstr, perm, NULL);
54 if (rc != 0 && user_cxt)
55 *user_cxt = user;
56 else
57 freecon(user);
58
59 return rc == 0 ? 1 : 0;
60 }
61
62 /* Gets the default context for @path and @st_mode.
63 *
64 * returns 0 on success,
65 * or <0 on error
66 */
67 int ul_selinux_get_default_context(const char *path, int st_mode, char **cxt)
68 {
69 struct selabel_handle *hnd;
70 struct selinux_opt options[SELABEL_NOPT] = {};
71 int rc = 0;
72
73 *cxt = NULL;
74
75 hnd = selabel_open(SELABEL_CTX_FILE, options, SELABEL_NOPT);
76 if (!hnd)
77 return -errno;
78
79 if (selabel_lookup(hnd, cxt, path, st_mode) != 0)
80 rc = -errno
81 ;
82 selabel_close(hnd);
83
84 return rc;
85 }