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 int avc_reset_callback(uint32_t event __attribute__((unused)), 14 security_id_t ssid __attribute__((unused)), 15 security_id_t tsid __attribute__((unused)), 16 security_class_t tclass __attribute__((unused)), 17 access_vector_t perms __attribute__((unused)), 18 access_vector_t *out_retained __attribute__((unused))) 19{ 20 flush_class_cache(); 21 return 0; 22} 23 24static void avc_init_once(void) 25{ 26 selinux_enabled = is_selinux_enabled(); 27 if (selinux_enabled == 1) { 28 if (avc_open(NULL, 0)) 29 return; 30 avc_add_callback(avc_reset_callback, AVC_CALLBACK_RESET, 31 0, 0, 0, 0); 32 } 33} 34 35int selinux_check_access(const char *scon, const char *tcon, const char *class, const char *perm, void *aux) { 36 int rc; 37 security_id_t scon_id; 38 security_id_t tcon_id; 39 security_class_t sclass; 40 access_vector_t av; 41 42 __selinux_once(once, avc_init_once); 43 44 if (selinux_enabled != 1) 45 return 0; 46 47 rc = avc_context_to_sid(scon, &scon_id); 48 if (rc < 0) 49 return rc; 50 51 rc = avc_context_to_sid(tcon, &tcon_id); 52 if (rc < 0) 53 return rc; 54 55 (void) avc_netlink_check_nb(); 56 57 sclass = string_to_security_class(class); 58 if (sclass == 0) { 59 rc = errno; 60 avc_log(SELINUX_ERROR, "Unknown class %s", class); 61 if (security_deny_unknown() == 0) 62 return 0; 63 errno = rc; 64 return -1; 65 } 66 67 av = string_to_av_perm(sclass, perm); 68 if (av == 0) { 69 rc = errno; 70 avc_log(SELINUX_ERROR, "Unknown permission %s for class %s", perm, class); 71 if (security_deny_unknown() == 0) 72 return 0; 73 errno = rc; 74 return -1; 75 } 76 77 return avc_has_perm (scon_id, tcon_id, sclass, av, NULL, aux); 78} 79 80int selinux_check_passwd_access(access_vector_t requested) 81{ 82 int status = -1; 83 char *user_context; 84 if (is_selinux_enabled() == 0) 85 return 0; 86 if (getprevcon_raw(&user_context) == 0) { 87 security_class_t passwd_class; 88 struct av_decision avd; 89 int retval; 90 91 passwd_class = string_to_security_class("passwd"); 92 if (passwd_class == 0) 93 return 0; 94 95 retval = security_compute_av_raw(user_context, 96 user_context, 97 passwd_class, 98 requested, 99 &avd); 100 101 if ((retval == 0) && ((requested & avd.allowed) == requested)) { 102 status = 0; 103 } 104 freecon(user_context); 105 } 106 107 if (status != 0 && security_getenforce() == 0) 108 status = 0; 109 110 return status; 111} 112 113hidden_def(selinux_check_passwd_access) 114 115int checkPasswdAccess(access_vector_t requested) 116{ 117 return selinux_check_passwd_access(requested); 118} 119