static int user_extra_parse( semanage_handle_t* handle, parse_info_t* info, semanage_user_extra_t* user_extra) { char* str = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* User string */ if (parse_assert_str(handle, info, "user") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* Extract name */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_user_extra_set_name(handle, user_extra, str) < 0) goto err; free(str); str = NULL; /* Prefix string */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_assert_str(handle, info, "prefix") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* Extract prefix */ if (parse_fetch_string(handle, info, &str, ';') < 0) goto err; if (semanage_user_extra_set_prefix(handle, user_extra, str) < 0) goto err; free(str); str = NULL; /* Semicolon */ if (parse_skip_space(handle, info) < 0) goto err; if (parse_assert_ch(handle, info, ';') < 0) goto err; return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse user extra data"); free(str); parse_dispose_line(info); return STATUS_ERR; }
void parse_release(parse_info_t * info) { parse_close(info); parse_dispose_line(info); free(info); }
int parse_skip_space(semanage_handle_t * handle, parse_info_t * info) { size_t buf_len = 0; ssize_t len; int lineno = info->lineno; char *buffer = NULL; char *ptr; if (info->ptr) { while (*(info->ptr) && isspace(*(info->ptr))) info->ptr++; if (*(info->ptr)) return STATUS_SUCCESS; } parse_dispose_line(info); while (info->file_stream && ((len = getline(&buffer, &buf_len, info->file_stream)) > 0)) { lineno++; /* Eat newline, preceding whitespace */ if (buffer[len - 1] == '\n') buffer[len - 1] = '\0'; ptr = buffer; while (*ptr && isspace(*ptr)) ptr++; /* Skip comments and blank lines */ if ((*ptr) && *ptr != '#') { char *tmp = strdup(buffer); if (!tmp) goto omem; info->lineno = lineno; info->working_copy = buffer; info->orig_line = tmp; info->ptr = ptr; return STATUS_SUCCESS; } } free(buffer); buffer = NULL; return STATUS_SUCCESS; omem: ERR(handle, "out of memory, could not allocate buffer"); free(buffer); return STATUS_ERR; }
static int bool_parse(semanage_handle_t * handle, parse_info_t * info, semanage_bool_t * boolean) { int value = 0; char *str = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* Extract name */ if (parse_fetch_string(handle, info, &str, '=') < 0) goto err; if (semanage_bool_set_name(handle, boolean, str) < 0) goto err; free(str); str = NULL; /* Assert = */ if (parse_skip_space(handle, info) < 0) goto err; if (parse_assert_ch(handle, info, '=') < 0) goto err; /* Extract value */ if (parse_skip_space(handle, info) < 0) goto err; if (parse_optional_str(info, "true") != STATUS_NODATA) value = 1; else if (parse_optional_str(info, "TRUE") != STATUS_NODATA) value = 1; else if (parse_optional_str(info, "false") != STATUS_NODATA) value = 0; else if (parse_optional_str(info, "FALSE") != STATUS_NODATA) value = 0; else if (parse_fetch_int(handle, info, &value, ' ') < 0) goto err; if (value != 0 && value != 1) { ERR(handle, "invalid boolean value for \"%s\": %u " "(%s: %u)\n%s", semanage_bool_get_name(boolean), value, info->filename, info->lineno, info->orig_line); goto err; } semanage_bool_set_value(boolean, value); if (parse_assert_space(handle, info) < 0) goto err; return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse boolean record"); free(str); parse_dispose_line(info); return STATUS_ERR; }
static int user_base_parse(semanage_handle_t * handle, parse_info_t * info, semanage_user_base_t * user) { int islist = 0; char *str = NULL; char *start; char *name_str = NULL; if (parse_skip_space(handle, info) < 0) goto err; if (!info->ptr) goto last; /* Parse user header */ if (parse_assert_str(handle, info, "user") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* Parse user name */ if (parse_fetch_string(handle, info, &name_str, ' ') < 0) goto err; if (semanage_user_base_set_name(handle, user, name_str) < 0) { free(name_str); goto err; } free(name_str); if (parse_assert_space(handle, info) < 0) goto err; if (parse_assert_str(handle, info, "roles") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; islist = (parse_optional_ch(info, '{') != STATUS_NODATA); /* For each role, loop */ do { char delim; if (parse_skip_space(handle, info) < 0) goto err; if (parse_assert_noeof(handle, info) < 0) goto err; start = info->ptr; while (*(info->ptr) && *(info->ptr) != ';' && *(info->ptr) != '}' && !isspace(*(info->ptr))) info->ptr++; delim = *(info->ptr); *(info->ptr)++ = '\0'; if (semanage_user_base_add_role(handle, user, start) < 0) goto err; if (delim && !isspace(delim)) { if (islist && delim == '}') break; else if (!islist && delim == ';') goto skip_semicolon; else goto err; } if (parse_skip_space(handle, info) < 0) goto err; if (parse_optional_ch(info, ';') != STATUS_NODATA) goto skip_semicolon; if (parse_optional_ch(info, '}') != STATUS_NODATA) islist = 0; } while (islist); /* Handle mls */ /* Parse level header */ if (parse_skip_space(handle, info) < 0) goto err; if (parse_optional_str(info, "level") == STATUS_NODATA) goto semicolon; if (parse_assert_space(handle, info) < 0) goto err; /* NOTE: does not allow spaces/multiline */ if (parse_fetch_string(handle, info, &str, ' ') < 0) goto err; if (semanage_user_base_set_mlslevel(handle, user, str) < 0) goto err; free(str); str = NULL; /* Parse range header */ if (parse_assert_space(handle, info) < 0) goto err; if (parse_assert_str(handle, info, "range") < 0) goto err; if (parse_assert_space(handle, info) < 0) goto err; /* NOTE: does not allow spaces/multiline */ if (parse_fetch_string(handle, info, &str, ';') < 0) goto err; if (semanage_user_base_set_mlsrange(handle, user, str) < 0) goto err; free(str); str = NULL; /* Check for semicolon */ semicolon: if (parse_skip_space(handle, info) < 0) goto err; if (parse_assert_ch(handle, info, ';') < 0) goto err; skip_semicolon: return STATUS_SUCCESS; last: parse_dispose_line(info); return STATUS_NODATA; err: ERR(handle, "could not parse user record"); free(str); parse_dispose_line(info); 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; }