1 /* Copyright (C) 2005 Red Hat, Inc. */ 2 3 struct semanage_node; 4 struct semanage_node_key; 5 typedef struct semanage_node record_t; 6 typedef struct semanage_node_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 "node_internal.h" 18 #include "context_internal.h" 19 #include "database_file.h" 20 #include "parse_utils.h" 21 #include "debug.h" 22 23 static int node_print(semanage_handle_t * handle, 24 semanage_node_t * node, FILE * str) 25 { 26 27 char *con_str = NULL; 28 char *addr = NULL; 29 char *mask = NULL; 30 31 int proto = semanage_node_get_proto(node); 32 const char *proto_str = semanage_node_get_proto_str(proto); 33 semanage_context_t *con = semanage_node_get_con(node); 34 35 if (semanage_node_get_addr(handle, node, &addr) < 0) 36 goto err; 37 38 if (semanage_node_get_mask(handle, node, &mask) < 0) 39 goto err; 40 41 if (semanage_context_to_string(handle, con, &con_str) < 0) 42 goto err; 43 44 if (fprintf 45 (str, "nodecon %s %s %s %s\n", proto_str, addr, mask, con_str) < 0) 46 goto err; 47 48 free(addr); 49 free(mask); 50 free(con_str); 51 return STATUS_SUCCESS; 52 53 err: 54 free(addr); 55 free(mask); 56 free(con_str); 57 ERR(handle, "could not print node to stream"); 58 return STATUS_ERR; 59 } 60 61 static int node_parse(semanage_handle_t * handle, 62 parse_info_t * info, semanage_node_t * node) 63 { 64 65 int proto; 66 char *str = NULL; 67 semanage_context_t *con = NULL; 68 69 if (parse_skip_space(handle, info) < 0) 70 goto err; 71 if (!info->ptr) 72 goto last; 73 74 /* Header */ 75 if (parse_assert_str(handle, info, "nodecon") < 0) 76 goto err; 77 if (parse_assert_space(handle, info) < 0) 78 goto err; 79 80 /* Protocol */ 81 if (parse_fetch_string(handle, info, &str, ' ') < 0) 82 goto err; 83 if (!strcasecmp(str, "ipv4")) 84 proto = SEMANAGE_PROTO_IP4; 85 else if (!strcasecmp(str, "ipv6")) 86 proto = SEMANAGE_PROTO_IP6; 87 else { 88 ERR(handle, "invalid protocol \"%s\" (%s: %u):\n%s", str, 89 info->filename, info->lineno, info->orig_line); 90 goto err; 91 } 92 free(str); 93 str = NULL; 94 95 semanage_node_set_proto(node, proto); 96 97 /* Address */ 98 if (parse_assert_space(handle, info) < 0) 99 goto err; 100 if (parse_fetch_string(handle, info, &str, ' ') < 0) 101 goto err; 102 if (semanage_node_set_addr(handle, node, proto, str) < 0) 103 goto err; 104 if (parse_assert_space(handle, info) < 0) 105 goto err; 106 free(str); 107 str = NULL; 108 109 /* Netmask */ 110 if (parse_fetch_string(handle, info, &str, ' ') < 0) 111 goto err; 112 if (semanage_node_set_mask(handle, node, proto, str) < 0) 113 goto err; 114 if (parse_assert_space(handle, info) < 0) 115 goto err; 116 free(str); 117 str = NULL; 118 119 /* Port context */ 120 if (parse_fetch_string(handle, info, &str, ' ') < 0) 121 goto err; 122 if (semanage_context_from_string(handle, str, &con) < 0) { 123 ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s", 124 str, info->filename, info->lineno, info->orig_line); 125 goto err; 126 } 127 if (con == NULL) { 128 ERR(handle, "<<none>> context is not valid " 129 "for nodes (%s: %u):\n%s", info->filename, 130 info->lineno, info->orig_line); 131 goto err; 132 } 133 free(str); 134 str = NULL; 135 136 if (semanage_node_set_con(handle, node, con) < 0) 137 goto err; 138 139 if (parse_assert_space(handle, info) < 0) 140 goto err; 141 142 semanage_context_free(con); 143 return STATUS_SUCCESS; 144 145 last: 146 parse_dispose_line(info); 147 return STATUS_NODATA; 148 149 err: 150 ERR(handle, "could not parse node record"); 151 free(str); 152 semanage_context_free(con); 153 parse_dispose_line(info); 154 return STATUS_ERR; 155 } 156 157 /* NODE RECORD: FILE extension: method table */ 158 record_file_table_t SEMANAGE_NODE_FILE_RTABLE = { 159 .parse = node_parse, 160 .print = node_print, 161 }; 162 163 int node_file_dbase_init(semanage_handle_t * handle, 164 const char *path_ro, 165 const char *path_rw, 166 dbase_config_t * dconfig) 167 { 168 169 if (dbase_file_init(handle, 170 path_ro, 171 path_rw, 172 &SEMANAGE_NODE_RTABLE, 173 &SEMANAGE_NODE_FILE_RTABLE, &dconfig->dbase) < 0) 174 return STATUS_ERR; 175 176 dconfig->dtable = &SEMANAGE_FILE_DTABLE; 177 return STATUS_SUCCESS; 178 } 179 180 void node_file_dbase_release(dbase_config_t * dconfig) 181 { 182 183 dbase_file_release(dconfig->dbase); 184 } 185