handle.c revision a401a8762294d90e17fcaf83f4447ac6f246ba70
1/* Author: Joshua Brindle <jbrindle@tresys.co 2 * Jason Tang <jtang@tresys.com> 3 * 4 * Copyright (C) 2004-2005 Tresys Technology, LLC 5 * Copyright (C) 2005 Red Hat, Inc. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/* This file implements only the publicly-visible handle functions to libsemanage. */ 23 24#include <selinux/selinux.h> 25 26#include <stdarg.h> 27#include <assert.h> 28#include <stdlib.h> 29#include <stdio.h> 30#include <string.h> 31#include <sys/time.h> 32 33#include "direct_api.h" 34#include "handle.h" 35#include "debug.h" 36#include "semanage_conf.h" 37#include "semanage_store.h" 38 39#define SEMANAGE_COMMIT_READ_WAIT 5 40 41semanage_handle_t *semanage_handle_create(void) 42{ 43 semanage_handle_t *sh = NULL; 44 const char *conf_name = NULL; 45 46 /* Allocate handle */ 47 if ((sh = calloc(1, sizeof(semanage_handle_t))) == NULL) 48 goto err; 49 50 if ((conf_name = semanage_conf_path()) == NULL) 51 goto err; 52 53 if ((sh->conf = semanage_conf_parse(conf_name)) == NULL) 54 goto err; 55 56 /* Link to sepol handle */ 57 sh->sepolh = sepol_handle_create(); 58 if (!sh->sepolh) 59 goto err; 60 sepol_msg_set_callback(sh->sepolh, semanage_msg_relay_handler, sh); 61 62 /* By default do not rebuild the policy on commit 63 * If any changes are made, this flag is ignored */ 64 sh->do_rebuild = 0; 65 66 /* By default always reload policy after commit if SELinux is enabled. */ 67 sh->do_reload = (is_selinux_enabled() > 0); 68 69 /* By default do not create store */ 70 sh->create_store = 0; 71 72 /* Set timeout: some default value for now, later use config */ 73 sh->timeout = SEMANAGE_COMMIT_READ_WAIT; 74 75 /* Set callback */ 76 sh->msg_callback = semanage_msg_default_handler; 77 sh->msg_callback_arg = NULL; 78 79 return sh; 80 81 err: 82 semanage_handle_destroy(sh); 83 return NULL; 84} 85 86void semanage_set_rebuild(semanage_handle_t * sh, int do_rebuild) 87{ 88 89 assert(sh != NULL); 90 91 sh->do_rebuild = do_rebuild; 92 return; 93} 94 95void semanage_set_reload(semanage_handle_t * sh, int do_reload) 96{ 97 98 assert(sh != NULL); 99 100 sh->do_reload = do_reload; 101 return; 102} 103 104void semanage_set_create_store(semanage_handle_t * sh, int create_store) 105{ 106 107 assert(sh != NULL); 108 109 sh->create_store = create_store; 110 return; 111} 112 113void semanage_set_disable_dontaudit(semanage_handle_t * sh, int disable_dontaudit) 114{ 115 assert(sh != NULL); 116 117 sepol_set_disable_dontaudit(sh->sepolh, disable_dontaudit); 118 return; 119} 120 121int semanage_is_connected(semanage_handle_t * sh) 122{ 123 assert(sh != NULL); 124 return sh->is_connected; 125} 126 127void semanage_select_store(semanage_handle_t * sh, char *storename, 128 enum semanage_connect_type storetype) 129{ 130 131 assert(sh != NULL); 132 133 /* This just sets the storename to what the user requests, no 134 verification of existance will be done until connect */ 135 sh->conf->store_path = strdup(storename); 136 assert(sh->conf->store_path); /* no way to return failure */ 137 sh->conf->store_type = storetype; 138 139 return; 140} 141 142int semanage_is_managed(semanage_handle_t * sh) 143{ 144 assert(sh != NULL); 145 if (sh->is_connected) { 146 ERR(sh, "Already connected."); 147 return -1; 148 } 149 switch (sh->conf->store_type) { 150 case SEMANAGE_CON_DIRECT: 151 return semanage_direct_is_managed(sh); 152 default: 153 ERR(sh, 154 "The connection type specified within your semanage.conf file has not been implemented yet."); 155 /* fall through */ 156 } 157 return -1; 158} 159 160int semanage_mls_enabled(semanage_handle_t * sh) 161{ 162 assert(sh != NULL); 163 switch (sh->conf->store_type) { 164 case SEMANAGE_CON_DIRECT: 165 return semanage_direct_mls_enabled(sh); 166 default: 167 ERR(sh, 168 "The connection type specified within your semanage.conf file has not been implemented yet."); 169 /* fall through */ 170 } 171 return -1; 172} 173 174int semanage_connect(semanage_handle_t * sh) 175{ 176 assert(sh != NULL); 177 switch (sh->conf->store_type) { 178 case SEMANAGE_CON_DIRECT:{ 179 if (semanage_direct_connect(sh) < 0) { 180 return -1; 181 } 182 break; 183 } 184 default:{ 185 ERR(sh, 186 "The connection type specified within your semanage.conf file has not been implemented yet."); 187 return -1; 188 } 189 } 190 sh->is_connected = 1; 191 return 0; 192} 193 194int semanage_access_check(semanage_handle_t * sh) 195{ 196 assert(sh != NULL); 197 switch (sh->conf->store_type) { 198 case SEMANAGE_CON_DIRECT: 199 return semanage_direct_access_check(sh); 200 default: 201 return -1; 202 } 203 204 return -1; /* unreachable */ 205} 206 207hidden_def(semanage_access_check) 208 209int semanage_disconnect(semanage_handle_t * sh) 210{ 211 assert(sh != NULL && sh->funcs != NULL 212 && sh->funcs->disconnect != NULL); 213 if (!sh->is_connected) { 214 return 0; 215 } 216 if (sh->funcs->disconnect(sh) < 0) { 217 return -1; 218 } 219 sh->is_in_transaction = 0; 220 sh->is_connected = 0; 221 sh->modules_modified = 0; 222 return 0; 223} 224 225void semanage_handle_destroy(semanage_handle_t * sh) 226{ 227 if (sh == NULL) 228 return; 229 230 if (sh->funcs != NULL && sh->funcs->destroy != NULL) 231 sh->funcs->destroy(sh); 232 semanage_conf_destroy(sh->conf); 233 sepol_handle_destroy(sh->sepolh); 234 free(sh); 235} 236 237hidden_def(semanage_handle_destroy) 238 239/********************* public transaction functions *********************/ 240int semanage_begin_transaction(semanage_handle_t * sh) 241{ 242 assert(sh != NULL && sh->funcs != NULL 243 && sh->funcs->begin_trans != NULL); 244 if (!sh->is_connected) { 245 ERR(sh, "Not connected."); 246 return -1; 247 } 248 if (sh->is_in_transaction) { 249 return 0; 250 } 251 252 if (sh->funcs->begin_trans(sh) < 0) { 253 return -1; 254 } 255 sh->is_in_transaction = 1; 256 return 0; 257} 258 259hidden_def(semanage_begin_transaction) 260 261int semanage_commit(semanage_handle_t * sh) 262{ 263 int retval; 264 assert(sh != NULL && sh->funcs != NULL && sh->funcs->commit != NULL); 265 if (!sh->is_in_transaction) { 266 ERR(sh, 267 "Will not commit because caller does not have a transaction lock yet."); 268 return -1; 269 } 270 retval = sh->funcs->commit(sh); 271 sh->is_in_transaction = 0; 272 sh->modules_modified = 0; 273 return retval; 274} 275