19feac613ddd7601d35a6bea7a28135662048d348Dan Walsh/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <unistd.h>
3f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <sys/types.h>
4f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdlib.h>
5f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <errno.h>
6f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "selinux_internal.h"
7f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <selinux/avc.h>
83dd432b3ec510b319beb4b2efd11d89d7daffbcfStephen Smalley#include "avc_internal.h"
9f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
10f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic pthread_once_t once = PTHREAD_ONCE_INIT;
118aeb5c5fd002c09d32f3151c17c645b85d1bb8e5Stephen Smalleystatic int selinux_enabled;
12f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
13f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic void avc_init_once(void)
14f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{
158aeb5c5fd002c09d32f3151c17c645b85d1bb8e5Stephen Smalley	selinux_enabled = is_selinux_enabled();
168aeb5c5fd002c09d32f3151c17c645b85d1bb8e5Stephen Smalley	if (selinux_enabled == 1)
178aeb5c5fd002c09d32f3151c17c645b85d1bb8e5Stephen Smalley		avc_open(NULL, 0);
18f074036424618c130dacb3464465a8b40bffef5Stephen Smalley}
19f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
20ab40ea9bfd71b50138f1482c4764a65ac17d8cafStephen Smalleyint selinux_check_access(const char * scon, const char * tcon, const char *class, const char *perm, void *aux) {
219feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	int rc;
22f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	security_id_t scon_id;
23f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	security_id_t tcon_id;
24f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	security_class_t sclass;
25f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	access_vector_t av;
26f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
27f074036424618c130dacb3464465a8b40bffef5Stephen Smalley	__selinux_once(once, avc_init_once);
28f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
298aeb5c5fd002c09d32f3151c17c645b85d1bb8e5Stephen Smalley	if (selinux_enabled != 1)
308aeb5c5fd002c09d32f3151c17c645b85d1bb8e5Stephen Smalley		return 0;
318aeb5c5fd002c09d32f3151c17c645b85d1bb8e5Stephen Smalley
329feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	rc = avc_context_to_sid(scon, &scon_id);
339feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	if (rc < 0)
349feac613ddd7601d35a6bea7a28135662048d348Dan Walsh		return rc;
359feac613ddd7601d35a6bea7a28135662048d348Dan Walsh
369feac613ddd7601d35a6bea7a28135662048d348Dan Walsh       rc = avc_context_to_sid(tcon, &tcon_id);
379feac613ddd7601d35a6bea7a28135662048d348Dan Walsh       if (rc < 0)
389feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	       return rc;
399feac613ddd7601d35a6bea7a28135662048d348Dan Walsh
409feac613ddd7601d35a6bea7a28135662048d348Dan Walsh       sclass = string_to_security_class(class);
419feac613ddd7601d35a6bea7a28135662048d348Dan Walsh       if (sclass == 0) {
429feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	       rc = errno;
433dd432b3ec510b319beb4b2efd11d89d7daffbcfStephen Smalley	       avc_log(SELINUX_ERROR, "Unknown class %s", class);
449feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	       if (security_deny_unknown() == 0)
459feac613ddd7601d35a6bea7a28135662048d348Dan Walsh		       return 0;
469feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	       errno = rc;
479feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	       return -1;
489feac613ddd7601d35a6bea7a28135662048d348Dan Walsh       }
499feac613ddd7601d35a6bea7a28135662048d348Dan Walsh
509feac613ddd7601d35a6bea7a28135662048d348Dan Walsh       av = string_to_av_perm(sclass, perm);
519feac613ddd7601d35a6bea7a28135662048d348Dan Walsh       if (av == 0) {
529feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	       rc = errno;
533dd432b3ec510b319beb4b2efd11d89d7daffbcfStephen Smalley	       avc_log(SELINUX_ERROR, "Unknown permission %s for class %s", perm, class);
549feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	       if (security_deny_unknown() == 0)
559feac613ddd7601d35a6bea7a28135662048d348Dan Walsh		       return 0;
569feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	       errno = rc;
579feac613ddd7601d35a6bea7a28135662048d348Dan Walsh	       return -1;
589feac613ddd7601d35a6bea7a28135662048d348Dan Walsh       }
599feac613ddd7601d35a6bea7a28135662048d348Dan Walsh
609feac613ddd7601d35a6bea7a28135662048d348Dan Walsh       return avc_has_perm (scon_id, tcon_id, sclass, av, NULL, aux);
61f074036424618c130dacb3464465a8b40bffef5Stephen Smalley}
62f074036424618c130dacb3464465a8b40bffef5Stephen Smalley
63