diff options
Diffstat (limited to 'libsemanage/src/nodes_file.c')
-rw-r--r-- | libsemanage/src/nodes_file.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/libsemanage/src/nodes_file.c b/libsemanage/src/nodes_file.c new file mode 100644 index 00000000..b80de2d3 --- /dev/null +++ b/libsemanage/src/nodes_file.c @@ -0,0 +1,181 @@ +/* Copyright (C) 2005 Red Hat, Inc. */ + +struct semanage_node; +struct semanage_node_key; +typedef struct semanage_node record_t; +typedef struct semanage_node_key record_key_t; +#define DBASE_RECORD_DEFINED + +struct dbase_file; +typedef struct dbase_file dbase_t; +#define DBASE_DEFINED + +#include <stdlib.h> +#include <stdio.h> +#include <strings.h> +#include <semanage/handle.h> +#include "node_internal.h" +#include "context_internal.h" +#include "database_file.h" +#include "parse_utils.h" +#include "debug.h" + +static int node_print(semanage_handle_t * handle, + semanage_node_t * node, FILE * str) +{ + + char *con_str = NULL; + char *addr = NULL; + char *mask = NULL; + + int proto = semanage_node_get_proto(node); + const char *proto_str = semanage_node_get_proto_str(proto); + semanage_context_t *con = semanage_node_get_con(node); + + if (semanage_node_get_addr(handle, node, &addr) < 0) + goto err; + + if (semanage_node_get_mask(handle, node, &mask) < 0) + goto err; + + if (semanage_context_to_string(handle, con, &con_str) < 0) + goto err; + + if (fprintf + (str, "nodecon %s %s %s %s\n", proto_str, addr, mask, con_str) < 0) + goto err; + + free(addr); + free(mask); + free(con_str); + return STATUS_SUCCESS; + + err: + free(addr); + free(mask); + free(con_str); + ERR(handle, "could not print node to stream"); + return STATUS_ERR; +} + +static int node_parse(semanage_handle_t * handle, + parse_info_t * info, semanage_node_t * node) +{ + + int proto; + char *str = NULL; + semanage_context_t *con = NULL; + + if (parse_skip_space(handle, info) < 0) + goto err; + if (!info->ptr) + goto last; + + /* Header */ + if (parse_assert_str(handle, info, "nodecon") < 0) + goto err; + if (parse_assert_space(handle, info) < 0) + goto err; + + /* Protocol */ + if (parse_fetch_string(handle, info, &str, ' ') < 0) + goto err; + if (!strcasecmp(str, "ipv4")) + proto = SEMANAGE_PROTO_IP4; + else if (!strcasecmp(str, "ipv6")) + proto = SEMANAGE_PROTO_IP6; + else { + ERR(handle, "invalid protocol \"%s\" (%s: %u):\n%s", str, + info->filename, info->lineno, info->orig_line); + goto err; + } + free(str); + str = NULL; + + semanage_node_set_proto(node, proto); + + /* Address */ + if (parse_assert_space(handle, info) < 0) + goto err; + if (parse_fetch_string(handle, info, &str, ' ') < 0) + goto err; + if (semanage_node_set_addr(handle, node, proto, str) < 0) + goto err; + if (parse_assert_space(handle, info) < 0) + goto err; + free(str); + str = NULL; + + /* Netmask */ + if (parse_fetch_string(handle, info, &str, ' ') < 0) + goto err; + if (semanage_node_set_mask(handle, node, proto, str) < 0) + goto err; + if (parse_assert_space(handle, info) < 0) + goto err; + free(str); + str = NULL; + + /* Port context */ + if (parse_fetch_string(handle, info, &str, ' ') < 0) + goto err; + if (semanage_context_from_string(handle, str, &con) < 0) { + ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s", + str, info->filename, info->lineno, info->orig_line); + goto err; + } + if (con == NULL) { + ERR(handle, "<<none>> context is not valid " + "for nodes (%s: %u):\n%s", info->filename, + info->lineno, info->orig_line); + goto err; + } + free(str); + str = NULL; + + if (semanage_node_set_con(handle, node, con) < 0) + goto err; + + if (parse_assert_space(handle, info) < 0) + goto err; + + semanage_context_free(con); + return STATUS_SUCCESS; + + last: + parse_dispose_line(info); + return STATUS_NODATA; + + err: + ERR(handle, "could not parse node record"); + free(str); + semanage_context_free(con); + parse_dispose_line(info); + return STATUS_ERR; +} + +/* NODE RECORD: FILE extension: method table */ +record_file_table_t SEMANAGE_NODE_FILE_RTABLE = { + .parse = node_parse, + .print = node_print, +}; + +int node_file_dbase_init(semanage_handle_t * handle, + const char *fname, dbase_config_t * dconfig) +{ + + if (dbase_file_init(handle, + fname, + &SEMANAGE_NODE_RTABLE, + &SEMANAGE_NODE_FILE_RTABLE, &dconfig->dbase) < 0) + return STATUS_ERR; + + dconfig->dtable = &SEMANAGE_FILE_DTABLE; + return STATUS_SUCCESS; +} + +void node_file_dbase_release(dbase_config_t * dconfig) +{ + + dbase_file_release(dconfig->dbase); +} |