Home | History | Annotate | Download | only in src
      1 /* Copyright (C) 2017 Mellanox Technologies Inc. */
      2 
      3 struct semanage_ibpkey;
      4 struct semanage_ibpkey_key;
      5 typedef struct semanage_ibpkey record_t;
      6 typedef struct semanage_ibpkey_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 "ibpkey_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 ibpkey_print(semanage_handle_t *handle,
     24 			semanage_ibpkey_t *ibpkey, FILE *str)
     25 {
     26 	char *con_str = NULL;
     27 	char *subnet_prefix_str = NULL;
     28 
     29 	int low = semanage_ibpkey_get_low(ibpkey);
     30 	int high = semanage_ibpkey_get_high(ibpkey);
     31 
     32 	if (semanage_ibpkey_get_subnet_prefix(handle, ibpkey, &subnet_prefix_str) != 0)
     33 		goto err;
     34 
     35 	semanage_context_t *con = semanage_ibpkey_get_con(ibpkey);
     36 
     37 	if (fprintf(str, "ibpkeycon %s ", subnet_prefix_str) < 0)
     38 		goto err;
     39 
     40 	if (low == high) {
     41 		if (fprintf(str, "%d ", low) < 0)
     42 			goto err;
     43 	} else {
     44 		if (fprintf(str, "%d - %d ", low, high) < 0)
     45 			goto err;
     46 	}
     47 
     48 	if (semanage_context_to_string(handle, con, &con_str) < 0)
     49 		goto err;
     50 	if (fprintf(str, "%s\n", con_str) < 0)
     51 		goto err;
     52 
     53 	free(subnet_prefix_str);
     54 	free(con_str);
     55 	return STATUS_SUCCESS;
     56 
     57 err:
     58 	ERR(handle, "could not print ibpkey range (%s) %u - %u to stream",
     59 	    subnet_prefix_str, low, high);
     60 	free(subnet_prefix_str);
     61 	free(con_str);
     62 	return STATUS_ERR;
     63 }
     64 
     65 static int ibpkey_parse(semanage_handle_t *handle,
     66 			parse_info_t *info, semanage_ibpkey_t *ibpkey)
     67 {
     68 	int low, high;
     69 	char *str = NULL;
     70 	semanage_context_t *con = NULL;
     71 
     72 	if (parse_skip_space(handle, info) < 0)
     73 		goto err;
     74 	if (!info->ptr)
     75 		goto last;
     76 
     77 	/* Header */
     78 	if (parse_assert_str(handle, info, "ibpkeycon") < 0)
     79 		goto err;
     80 	if (parse_assert_space(handle, info) < 0)
     81 		goto err;
     82 
     83 	/* Subnet Prefix */
     84 	if (parse_fetch_string(handle, info, &str, ' ') < 0)
     85 		goto err;
     86 	if (semanage_ibpkey_set_subnet_prefix(handle, ibpkey, str) < 0)
     87 		goto err;
     88 	free(str);
     89 	str = NULL;
     90 
     91 	/* Range/Pkey */
     92 	if (parse_assert_space(handle, info) < 0)
     93 		goto err;
     94 	if (parse_fetch_int(handle, info, &low, '-') < 0)
     95 		goto err;
     96 
     97 	/* If range (-) does not follow immediately, require a space
     98 	 * In other words, the space here is optional, but only
     99 	 * in the ranged case, not in the single ibpkey case,
    100 	 * so do a custom test
    101 	 */
    102 	if (*info->ptr && *info->ptr != '-') {
    103 		if (parse_assert_space(handle, info) < 0)
    104 			goto err;
    105 	}
    106 
    107 	if (parse_optional_ch(info, '-') != STATUS_NODATA) {
    108 		if (parse_skip_space(handle, info) < 0)
    109 			goto err;
    110 		if (parse_fetch_int(handle, info, &high, ' ') < 0)
    111 			goto err;
    112 		if (parse_assert_space(handle, info) < 0)
    113 			goto err;
    114 		semanage_ibpkey_set_range(ibpkey, low, high);
    115 	} else {
    116 		semanage_ibpkey_set_pkey(ibpkey, low);
    117 	}
    118 	/* Pkey context */
    119 	if (parse_fetch_string(handle, info, &str, ' ') < 0)
    120 		goto err;
    121 	if (semanage_context_from_string(handle, str, &con) < 0) {
    122 		ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
    123 		    str, info->filename, info->lineno, info->orig_line);
    124 		goto err;
    125 	}
    126 	if (!con) {
    127 		ERR(handle, "<<none>> context is not valid for ibpkeys (%s: %u):\n%s",
    128 		    info->filename,
    129 		    info->lineno, info->orig_line);
    130 		goto err;
    131 	}
    132 	free(str);
    133 	str = NULL;
    134 
    135 	if (semanage_ibpkey_set_con(handle, ibpkey, con) < 0)
    136 		goto err;
    137 
    138 	if (parse_assert_space(handle, info) < 0)
    139 		goto err;
    140 
    141 	semanage_context_free(con);
    142 	return STATUS_SUCCESS;
    143 
    144 last:
    145 	parse_dispose_line(info);
    146 	return STATUS_NODATA;
    147 
    148 err:
    149 	ERR(handle, "could not parse ibpkey record");
    150 	free(str);
    151 	semanage_context_free(con);
    152 	parse_dispose_line(info);
    153 	return STATUS_ERR;
    154 }
    155 
    156 /* IBPKEY RECORD: FILE extension: method table */
    157 record_file_table_t SEMANAGE_IBPKEY_FILE_RTABLE = {
    158 	.parse = ibpkey_parse,
    159 	.print = ibpkey_print,
    160 };
    161 
    162 int ibpkey_file_dbase_init(semanage_handle_t *handle,
    163 			   const char *path_ro,
    164 			   const char *path_rw,
    165 			   dbase_config_t *dconfig)
    166 {
    167 	if (dbase_file_init(handle,
    168 			    path_ro,
    169 			    path_rw,
    170 			    &SEMANAGE_IBPKEY_RTABLE,
    171 			    &SEMANAGE_IBPKEY_FILE_RTABLE, &dconfig->dbase) < 0)
    172 		return STATUS_ERR;
    173 
    174 	dconfig->dtable = &SEMANAGE_FILE_DTABLE;
    175 	return STATUS_SUCCESS;
    176 }
    177 
    178 void ibpkey_file_dbase_release(dbase_config_t *dconfig)
    179 {
    180 	dbase_file_release(dconfig->dbase);
    181 }
    182