1c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <unistd.h> 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/types.h> 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <errno.h> 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "selinux_internal.h" 79c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh#include <selinux/avc.h> 87bdc38ccb21133155658279895b10ceb347b0b5aStephen Smalley#include "avc_internal.h" 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 109c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walshstatic pthread_once_t once = PTHREAD_ONCE_INIT; 112fa21cc840bce76274ba5d1b9ddbb0abebfaf06dStephen Smalleystatic int selinux_enabled; 129c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh 139c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walshstatic void avc_init_once(void) 149c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh{ 152fa21cc840bce76274ba5d1b9ddbb0abebfaf06dStephen Smalley selinux_enabled = is_selinux_enabled(); 162fa21cc840bce76274ba5d1b9ddbb0abebfaf06dStephen Smalley if (selinux_enabled == 1) 172fa21cc840bce76274ba5d1b9ddbb0abebfaf06dStephen Smalley avc_open(NULL, 0); 189c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh} 199c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh 209eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleyint selinux_check_access(const char *scon, const char *tcon, const char *class, const char *perm, void *aux) { 21c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh int rc; 229c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh security_id_t scon_id; 239c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh security_id_t tcon_id; 249c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh security_class_t sclass; 259c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh access_vector_t av; 269c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh 279c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh __selinux_once(once, avc_init_once); 289c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh 292fa21cc840bce76274ba5d1b9ddbb0abebfaf06dStephen Smalley if (selinux_enabled != 1) 302fa21cc840bce76274ba5d1b9ddbb0abebfaf06dStephen Smalley return 0; 312fa21cc840bce76274ba5d1b9ddbb0abebfaf06dStephen Smalley 32c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh rc = avc_context_to_sid(scon, &scon_id); 33c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh if (rc < 0) 34c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh return rc; 35c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh 36c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh rc = avc_context_to_sid(tcon, &tcon_id); 37c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh if (rc < 0) 38c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh return rc; 39c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh 40c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh sclass = string_to_security_class(class); 41c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh if (sclass == 0) { 42c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh rc = errno; 437bdc38ccb21133155658279895b10ceb347b0b5aStephen Smalley avc_log(SELINUX_ERROR, "Unknown class %s", class); 44c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh if (security_deny_unknown() == 0) 45c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh return 0; 46c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh errno = rc; 47c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh return -1; 48c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh } 49c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh 50c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh av = string_to_av_perm(sclass, perm); 51c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh if (av == 0) { 52c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh rc = errno; 537bdc38ccb21133155658279895b10ceb347b0b5aStephen Smalley avc_log(SELINUX_ERROR, "Unknown permission %s for class %s", perm, class); 54c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh if (security_deny_unknown() == 0) 55c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh return 0; 56c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh errno = rc; 57c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh return -1; 58c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh } 59c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh 60c7d749efe2fa6f1e765b0bc215476d533f1b4d7bDan Walsh return avc_has_perm (scon_id, tcon_id, sclass, av, NULL, aux); 619c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh} 629c46a0a3153124753e3afbd2090fea65a09e1df1Dan Walsh 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint selinux_check_passwd_access(access_vector_t requested) 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int status = -1; 669eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalley char *user_context; 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (is_selinux_enabled() == 0) 6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (getprevcon_raw(&user_context) == 0) { 7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle security_class_t passwd_class; 7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct av_decision avd; 7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle passwd_class = string_to_security_class("passwd"); 7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (passwd_class == 0) 7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = security_compute_av_raw(user_context, 7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_context, 8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle passwd_class, 8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle requested, 8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &avd); 8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((retval == 0) && ((requested & avd.allowed) == requested)) { 8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle status = 0; 8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle freecon(user_context); 8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (status != 0 && security_getenforce() == 0) 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle status = 0; 9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return status; 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(selinux_check_passwd_access) 9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint checkPasswdAccess(access_vector_t requested) 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return selinux_check_passwd_access(requested); 10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 102