1 /* Copyright (C) 2005 Red Hat, Inc. */ 2 3 struct semanage_fcontext; 4 struct semanage_fcontext_key; 5 typedef struct semanage_fcontext record_t; 6 typedef struct semanage_fcontext_key record_key_t; 7 #define DBASE_RECORD_DEFINED 8 9 struct dbase_file; 10 typedef struct dbase_file dbase_t; 11 #define DBASE_DEFINED 12 13 #include <stdlib.h> 14 #include <stdio.h> 15 #include <strings.h> 16 #include <semanage/handle.h> 17 #include "fcontext_internal.h" 18 #include "context_internal.h" 19 #include "database_file.h" 20 #include "parse_utils.h" 21 #include "debug.h" 22 23 static const char *type_str(int type) 24 { 25 switch (type) { 26 default: 27 case SEMANAGE_FCONTEXT_ALL: 28 return " "; 29 case SEMANAGE_FCONTEXT_REG: 30 return "--"; 31 case SEMANAGE_FCONTEXT_DIR: 32 return "-d"; 33 case SEMANAGE_FCONTEXT_CHAR: 34 return "-c"; 35 case SEMANAGE_FCONTEXT_BLOCK: 36 return "-b"; 37 case SEMANAGE_FCONTEXT_SOCK: 38 return "-s"; 39 case SEMANAGE_FCONTEXT_LINK: 40 return "-l"; 41 case SEMANAGE_FCONTEXT_PIPE: 42 return "-p"; 43 } 44 } 45 46 static int fcontext_print(semanage_handle_t * handle, 47 semanage_fcontext_t * fcontext, FILE * str) 48 { 49 50 char *con_str = NULL; 51 52 const char *expr = semanage_fcontext_get_expr(fcontext); 53 int type = semanage_fcontext_get_type(fcontext); 54 const char *print_str = type_str(type); 55 const char *tstr = semanage_fcontext_get_type_str(type); 56 semanage_context_t *con = semanage_fcontext_get_con(fcontext); 57 58 if (fprintf(str, "%s %s ", expr, print_str) < 0) 59 goto err; 60 61 if (con != NULL) { 62 if (semanage_context_to_string(handle, con, &con_str) < 0) 63 goto err; 64 if (fprintf(str, "%s\n", con_str) < 0) 65 goto err; 66 free(con_str); 67 con_str = NULL; 68 } else { 69 if (fprintf(str, "<<none>>\n") < 0) 70 goto err; 71 } 72 return STATUS_SUCCESS; 73 74 err: 75 ERR(handle, "could not print file context for " 76 "%s (%s) to stream", expr, tstr); 77 free(con_str); 78 return STATUS_ERR; 79 } 80 81 static int fcontext_parse(semanage_handle_t * handle, 82 parse_info_t * info, semanage_fcontext_t * fcontext) 83 { 84 85 char *str = NULL; 86 semanage_context_t *con = NULL; 87 88 if (parse_skip_space(handle, info) < 0) 89 goto err; 90 if (!info->ptr) 91 goto last; 92 93 /* Regexp */ 94 if (parse_fetch_string(handle, info, &str, ' ') < 0) 95 goto err; 96 if (semanage_fcontext_set_expr(handle, fcontext, str) < 0) 97 goto err; 98 free(str); 99 str = NULL; 100 101 /* Type */ 102 if (parse_assert_space(handle, info) < 0) 103 goto err; 104 if (parse_fetch_string(handle, info, &str, ' ') < 0) 105 goto err; 106 if (!strcasecmp(str, "-s")) 107 semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_SOCK); 108 else if (!strcasecmp(str, "-p")) 109 semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_PIPE); 110 else if (!strcasecmp(str, "-b")) 111 semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_BLOCK); 112 else if (!strcasecmp(str, "-l")) 113 semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_LINK); 114 else if (!strcasecmp(str, "-c")) 115 semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_CHAR); 116 else if (!strcasecmp(str, "-d")) 117 semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_DIR); 118 else if (!strcasecmp(str, "--")) 119 semanage_fcontext_set_type(fcontext, SEMANAGE_FCONTEXT_REG); 120 else 121 goto process_context; 122 free(str); 123 str = NULL; 124 125 /* Context */ 126 if (parse_assert_space(handle, info) < 0) 127 goto err; 128 if (parse_fetch_string(handle, info, &str, ' ') < 0) 129 goto err; 130 131 process_context: 132 if (semanage_context_from_string(handle, str, &con) < 0) { 133 ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s", 134 str, info->filename, info->lineno, info->orig_line); 135 goto err; 136 } 137 free(str); 138 str = NULL; 139 140 if (con && semanage_fcontext_set_con(handle, fcontext, con) < 0) 141 goto err; 142 143 if (parse_assert_space(handle, info) < 0) 144 goto err; 145 146 semanage_context_free(con); 147 return STATUS_SUCCESS; 148 149 last: 150 parse_dispose_line(info); 151 return STATUS_NODATA; 152 153 err: 154 ERR(handle, "could not parse file context record"); 155 free(str); 156 semanage_context_free(con); 157 parse_dispose_line(info); 158 return STATUS_ERR; 159 } 160 161 /* FCONTEXT RECORD: FILE extension: method table */ 162 record_file_table_t SEMANAGE_FCONTEXT_FILE_RTABLE = { 163 .parse = fcontext_parse, 164 .print = fcontext_print, 165 }; 166 167 int fcontext_file_dbase_init(semanage_handle_t * handle, 168 const char *path_ro, 169 const char *path_rw, 170 dbase_config_t * dconfig) 171 { 172 173 if (dbase_file_init(handle, 174 path_ro, 175 path_rw, 176 &SEMANAGE_FCONTEXT_RTABLE, 177 &SEMANAGE_FCONTEXT_FILE_RTABLE, 178 &dconfig->dbase) < 0) 179 return STATUS_ERR; 180 181 dconfig->dtable = &SEMANAGE_FILE_DTABLE; 182 return STATUS_SUCCESS; 183 } 184 185 void fcontext_file_dbase_release(dbase_config_t * dconfig) 186 { 187 188 dbase_file_release(dconfig->dbase); 189 } 190