1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2#include <unistd.h>
3#include <sys/types.h>
4#include <stdlib.h>
5#include <errno.h>
6#include "selinux_internal.h"
7#include <selinux/avc.h>
8#include "avc_internal.h"
9
10static pthread_once_t once = PTHREAD_ONCE_INIT;
11static int selinux_enabled;
12
13static void avc_init_once(void)
14{
15	selinux_enabled = is_selinux_enabled();
16	if (selinux_enabled == 1)
17		avc_open(NULL, 0);
18}
19
20int selinux_check_access(const char * scon, const char * tcon, const char *class, const char *perm, void *aux) {
21	int rc;
22	security_id_t scon_id;
23	security_id_t tcon_id;
24	security_class_t sclass;
25	access_vector_t av;
26
27	__selinux_once(once, avc_init_once);
28
29	if (selinux_enabled != 1)
30		return 0;
31
32	rc = avc_context_to_sid(scon, &scon_id);
33	if (rc < 0)
34		return rc;
35
36       rc = avc_context_to_sid(tcon, &tcon_id);
37       if (rc < 0)
38	       return rc;
39
40       sclass = string_to_security_class(class);
41       if (sclass == 0) {
42	       rc = errno;
43	       avc_log(SELINUX_ERROR, "Unknown class %s", class);
44	       if (security_deny_unknown() == 0)
45		       return 0;
46	       errno = rc;
47	       return -1;
48       }
49
50       av = string_to_av_perm(sclass, perm);
51       if (av == 0) {
52	       rc = errno;
53	       avc_log(SELINUX_ERROR, "Unknown permission %s for class %s", perm, class);
54	       if (security_deny_unknown() == 0)
55		       return 0;
56	       errno = rc;
57	       return -1;
58       }
59
60       return avc_has_perm (scon_id, tcon_id, sclass, av, NULL, aux);
61}
62
63