1struct semanage_fcontext; 2struct semanage_fcontext_key; 3typedef struct semanage_fcontext record_t; 4typedef struct semanage_fcontext_key record_key_t; 5#define DBASE_RECORD_DEFINED 6 7#include <stdlib.h> 8#include <string.h> 9#include "fcontext_internal.h" 10#include "context_internal.h" 11#include "debug.h" 12 13struct semanage_fcontext { 14 15 /* Matching expression */ 16 char *expr; 17 18 /* Type of object */ 19 int type; 20 21 /* Context */ 22 semanage_context_t *con; 23}; 24 25struct semanage_fcontext_key { 26 27 /* Matching expression */ 28 char *expr; 29 30 /* Type of object */ 31 int type; 32}; 33 34/* Key */ 35int semanage_fcontext_key_create(semanage_handle_t * handle, 36 const char *expr, 37 int type, semanage_fcontext_key_t ** key_ptr) 38{ 39 40 semanage_fcontext_key_t *tmp_key = 41 (semanage_fcontext_key_t *) malloc(sizeof(semanage_fcontext_key_t)); 42 43 if (!tmp_key) { 44 ERR(handle, "out of memory, could not " 45 "create file context key"); 46 return STATUS_ERR; 47 } 48 tmp_key->expr = strdup(expr); 49 if (!tmp_key->expr) { 50 ERR(handle, "out of memory, could not create file context key."); 51 free(tmp_key); 52 return STATUS_ERR; 53 } 54 tmp_key->type = type; 55 56 *key_ptr = tmp_key; 57 return STATUS_SUCCESS; 58} 59 60hidden_def(semanage_fcontext_key_create) 61 62int semanage_fcontext_key_extract(semanage_handle_t * handle, 63 const semanage_fcontext_t * fcontext, 64 semanage_fcontext_key_t ** key_ptr) 65{ 66 67 if (semanage_fcontext_key_create(handle, fcontext->expr, 68 fcontext->type, key_ptr) < 0) { 69 ERR(handle, "could not extract key from " 70 "file context %s (%s)", fcontext->expr, 71 semanage_fcontext_get_type_str(fcontext->type)); 72 return STATUS_ERR; 73 } 74 75 return STATUS_SUCCESS; 76} 77 78hidden_def(semanage_fcontext_key_extract) 79 80void semanage_fcontext_key_free(semanage_fcontext_key_t * key) 81{ 82 free(key->expr); 83 free(key); 84} 85 86hidden_def(semanage_fcontext_key_free) 87 88int semanage_fcontext_compare(const semanage_fcontext_t * fcontext, 89 const semanage_fcontext_key_t * key) 90{ 91 92 int rv = strcmp(fcontext->expr, key->expr); 93 if (rv != 0) 94 return rv; 95 else { 96 if (fcontext->type < key->type) 97 return -1; 98 99 else if (key->type < fcontext->type) 100 return 1; 101 102 else 103 return 0; 104 } 105} 106 107hidden_def(semanage_fcontext_compare) 108 109int semanage_fcontext_compare2(const semanage_fcontext_t * fcontext, 110 const semanage_fcontext_t * fcontext2) 111{ 112 113 int rv = strcmp(fcontext->expr, fcontext2->expr); 114 if (rv != 0) 115 return rv; 116 else { 117 if (fcontext->type < fcontext2->type) 118 return -1; 119 120 else if (fcontext2->type < fcontext->type) 121 return 1; 122 123 else 124 return 0; 125 } 126} 127 128hidden_def(semanage_fcontext_compare2) 129 130static int semanage_fcontext_compare2_qsort(const semanage_fcontext_t ** 131 fcontext, 132 const semanage_fcontext_t ** 133 fcontext2) 134{ 135 136 return semanage_fcontext_compare2(*fcontext, *fcontext2); 137} 138 139/* Create */ 140int semanage_fcontext_create(semanage_handle_t * handle, 141 semanage_fcontext_t ** fcontext) 142{ 143 144 semanage_fcontext_t *tmp_fcontext = 145 (semanage_fcontext_t *) malloc(sizeof(semanage_fcontext_t)); 146 147 if (!tmp_fcontext) { 148 ERR(handle, "out of memory, could not create " 149 "file context record"); 150 return STATUS_ERR; 151 } 152 153 tmp_fcontext->expr = NULL; 154 tmp_fcontext->type = SEMANAGE_FCONTEXT_ALL; 155 tmp_fcontext->con = NULL; 156 *fcontext = tmp_fcontext; 157 158 return STATUS_SUCCESS; 159} 160 161hidden_def(semanage_fcontext_create) 162 163/* Regexp */ 164const char *semanage_fcontext_get_expr(const semanage_fcontext_t * fcontext) 165{ 166 167 return fcontext->expr; 168} 169 170hidden_def(semanage_fcontext_get_expr) 171 172int semanage_fcontext_set_expr(semanage_handle_t * handle, 173 semanage_fcontext_t * fcontext, const char *expr) 174{ 175 176 char *tmp_expr = strdup(expr); 177 if (!tmp_expr) { 178 ERR(handle, "out of memory, " "could not set regexp string"); 179 return STATUS_ERR; 180 } 181 free(fcontext->expr); 182 fcontext->expr = tmp_expr; 183 return STATUS_SUCCESS; 184} 185 186hidden_def(semanage_fcontext_set_expr) 187 188/* Type */ 189int semanage_fcontext_get_type(const semanage_fcontext_t * fcontext) 190{ 191 192 return fcontext->type; 193} 194 195hidden_def(semanage_fcontext_get_type) 196 197const char *semanage_fcontext_get_type_str(int type) 198{ 199 200 switch (type) { 201 case SEMANAGE_FCONTEXT_ALL: 202 return "all files"; 203 case SEMANAGE_FCONTEXT_REG: 204 return "regular file"; 205 case SEMANAGE_FCONTEXT_DIR: 206 return "directory"; 207 case SEMANAGE_FCONTEXT_CHAR: 208 return "character device"; 209 case SEMANAGE_FCONTEXT_BLOCK: 210 return "block device"; 211 case SEMANAGE_FCONTEXT_SOCK: 212 return "socket"; 213 case SEMANAGE_FCONTEXT_LINK: 214 return "symbolic link"; 215 case SEMANAGE_FCONTEXT_PIPE: 216 return "named pipe"; 217 default: 218 return "????"; 219 } 220} 221 222hidden_def(semanage_fcontext_get_type_str) 223 224void semanage_fcontext_set_type(semanage_fcontext_t * fcontext, int type) 225{ 226 227 fcontext->type = type; 228} 229 230hidden_def(semanage_fcontext_set_type) 231 232/* Context */ 233semanage_context_t *semanage_fcontext_get_con(const semanage_fcontext_t * 234 fcontext) 235{ 236 237 return fcontext->con; 238} 239 240hidden_def(semanage_fcontext_get_con) 241 242int semanage_fcontext_set_con(semanage_handle_t * handle, 243 semanage_fcontext_t * fcontext, 244 semanage_context_t * con) 245{ 246 247 semanage_context_t *newcon; 248 249 if (semanage_context_clone(handle, con, &newcon) < 0) { 250 ERR(handle, "out of memory, could not set file context"); 251 return STATUS_ERR; 252 } 253 254 semanage_context_free(fcontext->con); 255 fcontext->con = newcon; 256 return STATUS_SUCCESS; 257} 258 259hidden_def(semanage_fcontext_set_con) 260 261/* Deep copy clone */ 262int semanage_fcontext_clone(semanage_handle_t * handle, 263 const semanage_fcontext_t * fcontext, 264 semanage_fcontext_t ** fcontext_ptr) 265{ 266 267 semanage_fcontext_t *new_fcontext = NULL; 268 if (semanage_fcontext_create(handle, &new_fcontext) < 0) 269 goto err; 270 271 if (semanage_fcontext_set_expr(handle, new_fcontext, fcontext->expr) < 272 0) 273 goto err; 274 275 new_fcontext->type = fcontext->type; 276 277 if (fcontext->con && 278 (semanage_context_clone(handle, fcontext->con, &new_fcontext->con) < 279 0)) 280 goto err; 281 282 *fcontext_ptr = new_fcontext; 283 return STATUS_SUCCESS; 284 285 err: 286 ERR(handle, "could not clone file context record"); 287 semanage_fcontext_free(new_fcontext); 288 return STATUS_ERR; 289} 290 291hidden_def(semanage_fcontext_clone) 292 293/* Destroy */ 294void semanage_fcontext_free(semanage_fcontext_t * fcontext) 295{ 296 297 if (!fcontext) 298 return; 299 300 free(fcontext->expr); 301 semanage_context_free(fcontext->con); 302 free(fcontext); 303} 304 305hidden_def(semanage_fcontext_free) 306 307/* Record base functions */ 308record_table_t SEMANAGE_FCONTEXT_RTABLE = { 309 .create = semanage_fcontext_create, 310 .key_extract = semanage_fcontext_key_extract, 311 .key_free = semanage_fcontext_key_free, 312 .clone = semanage_fcontext_clone, 313 .compare = semanage_fcontext_compare, 314 .compare2 = semanage_fcontext_compare2, 315 .compare2_qsort = semanage_fcontext_compare2_qsort, 316 .free = semanage_fcontext_free, 317}; 318