Пример #1
0
static void build_nomls_vecs()
{
	const void *item;
	const apol_vector_t *v = NULL;
	size_t i, str_len = 0;
	char *str = NULL;
	v = poldiff_get_user_vector(diff);
	for (i = 0; i < apol_vector_get_size(v); ++i) {
		item = apol_vector_get_element(v, i);
		poldiff_user_t *u = (poldiff_user_t *) item;
		const char *name = poldiff_user_get_name(u);
		const apol_vector_t *added_roles = poldiff_user_get_added_roles(u);
		const apol_vector_t *removed_roles = poldiff_user_get_removed_roles(u);
		if (apol_vector_get_size(added_roles) == 0 && apol_vector_get_size(removed_roles) == 0) {
			apol_vector_append(unchanged_users_v, strdup(name));
		} else {
			char *added_roles_str = vector_to_string(added_roles, "", " +");
			char *removed_roles_str = vector_to_string(removed_roles, "-", " ");
			apol_str_appendf(&str, &str_len, "%s %s%s", name, added_roles_str, removed_roles_str);
			free(added_roles_str);
			free(removed_roles_str);
			apol_str_trim(str);
			apol_vector_append(changed_users_v, str);
			str = NULL;
			str_len = 0;
		}
	}
}
Пример #2
0
int apol_userbounds_get_by_query(const apol_policy_t * p, apol_userbounds_query_t * q, apol_vector_t ** v)
{
	qpol_iterator_t *iter;
	int retval = -1;

	*v = NULL;
	if (qpol_policy_get_userbounds_iter(p->p, &iter) < 0) {
		return -1;
	}
	if ((*v = apol_vector_create(NULL)) == NULL) {
		ERR(p, "%s", strerror(errno));
		goto cleanup;
	}
	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		const qpol_userbounds_t *userbounds;
		if (qpol_iterator_get_item(iter, (void **)&userbounds) < 0) {
			goto cleanup;
		}
		if (q != NULL) {
			if (apol_vector_append(*v, (void *)userbounds)) {
				ERR(p, "%s", strerror(ENOMEM));
				goto cleanup;
			}
		}
	}

	retval = 0;
cleanup:
	if (retval != 0) {
		apol_vector_destroy(v);
	}
	qpol_iterator_destroy(&iter);
	return retval;
}
Пример #3
0
int level_new_diff(poldiff_t * diff, poldiff_form_e form, const void *item)
{
	const qpol_level_t *l = item;
	const char *name = NULL;
	poldiff_level_t *pl = NULL;
	apol_policy_t *p;
	qpol_policy_t *q;
	apol_vector_t *v = NULL;
	int error = 0, retval = -1;
	if (form == POLDIFF_FORM_ADDED) {
		p = diff->mod_pol;
		q = diff->mod_qpol;
	} else {
		p = diff->orig_pol;
		q = diff->orig_qpol;
	}
	if (qpol_level_get_name(q, l, &name) < 0 || (pl = make_diff(diff, form, name)) == NULL) {
		error = errno;
		goto cleanup;
	}
	if ((v = level_get_cats(diff, p, l)) == NULL) {
		error = errno;
		ERR(diff, "%s", strerror(error));
		goto cleanup;
	}
	if (form == POLDIFF_FORM_ADDED) {
		apol_vector_destroy(&pl->added_cats);
		if ((pl->added_cats = apol_vector_create_from_vector(v, apol_str_strdup, NULL, free)) == NULL) {
			error = errno;
			ERR(diff, "%s", strerror(error));
			goto cleanup;
		}
	} else if (form == POLDIFF_FORM_REMOVED) {
		apol_vector_destroy(&pl->removed_cats);
		if ((pl->removed_cats = apol_vector_create_from_vector(v, apol_str_strdup, NULL, free)) == NULL) {
			error = errno;
			ERR(diff, "%s", strerror(error));
			goto cleanup;
		}
	}
	if (apol_vector_append(diff->level_diffs->diffs, pl) < 0) {
		error = errno;
		ERR(diff, "%s", strerror(error));
		goto cleanup;
	}
	if (form == POLDIFF_FORM_ADDED) {
		diff->level_diffs->num_added++;
	} else {
		diff->level_diffs->num_removed++;
	}
	retval = 0;
      cleanup:
	apol_vector_destroy(&v);
	if (retval < 0) {
		level_free(pl);
		errno = error;
	}
	return retval;
}
Пример #4
0
int level_deep_diff(poldiff_t * diff, const void *x, const void *y)
{
	const qpol_level_t *l1 = x;
	const qpol_level_t *l2 = y;
	apol_vector_t *v1 = NULL, *v2 = NULL;
	apol_vector_t *added = NULL, *removed = NULL, *unmodified = NULL;
	const char *name;
	poldiff_level_t *l = NULL;
	int retval = -1, error = 0, compval;

	if (qpol_level_get_name(diff->orig_qpol, l1, &name) < 0 ||
	    (v1 = level_get_cats(diff, diff->orig_pol, l1)) == NULL || (v2 = level_get_cats(diff, diff->mod_pol, l2)) == NULL) {
		error = errno;
		goto cleanup;
	}
	apol_vector_sort(v1, apol_str_strcmp, NULL);
	apol_vector_sort(v2, apol_str_strcmp, NULL);
	compval = level_deep_diff_cats(diff, v1, v2, &added, &removed, &unmodified);
	if (compval < 0) {
		error = errno;
		goto cleanup;
	} else if (compval > 0) {
		if ((l = make_diff(diff, POLDIFF_FORM_MODIFIED, name)) == NULL) {
			error = errno;
			goto cleanup;
		}
		apol_vector_destroy(&l->added_cats);
		apol_vector_destroy(&l->removed_cats);
		apol_vector_destroy(&l->unmodified_cats);
		if ((l->added_cats = apol_vector_create_from_vector(added, apol_str_strdup, NULL, free)) == NULL ||
		    (l->removed_cats = apol_vector_create_from_vector(removed, apol_str_strdup, NULL, free)) == NULL ||
		    (l->unmodified_cats = apol_vector_create_from_vector(unmodified, apol_str_strdup, NULL, free)) == NULL) {
			error = errno;
			ERR(diff, "%s", strerror(error));
			goto cleanup;
		}
		apol_vector_sort(l->removed_cats, level_cat_comp, diff->orig_qpol);
		apol_vector_sort(l->added_cats, level_cat_comp, diff->mod_qpol);
		apol_vector_sort(l->unmodified_cats, level_cat_comp, diff->orig_qpol);
		if (apol_vector_append(diff->level_diffs->diffs, l) < 0) {
			error = errno;
			ERR(diff, "%s", strerror(error));
			goto cleanup;
		}
		diff->level_diffs->num_modified++;
	}
	retval = 0;
      cleanup:
	apol_vector_destroy(&v1);
	apol_vector_destroy(&v2);
	apol_vector_destroy(&added);
	apol_vector_destroy(&removed);
	apol_vector_destroy(&unmodified);
	if (retval != 0) {
		level_free(l);
	}
	errno = error;
	return retval;
}
Пример #5
0
int apol_portcon_get_by_query(const apol_policy_t * p, const apol_portcon_query_t * po, apol_vector_t ** v)
{
	qpol_iterator_t *iter;
	int retval = -1, retval2;
	*v = NULL;
	if (qpol_policy_get_portcon_iter(p->p, &iter) < 0) {
		return -1;
	}
	if ((*v = apol_vector_create(NULL)) == NULL) {
		ERR(p, "%s", strerror(errno));
		goto cleanup;
	}
	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		qpol_portcon_t *portcon;
		if (qpol_iterator_get_item(iter, (void **)&portcon) < 0) {
			goto cleanup;
		}
		if (po != NULL) {
			uint16_t low, high;
			uint8_t proto;
			const qpol_context_t *context;
			if (qpol_portcon_get_low_port(p->p,
						      portcon, &low) < 0 ||
			    qpol_portcon_get_high_port(p->p,
						       portcon, &high) < 0 ||
			    qpol_portcon_get_protocol(p->p,
						      portcon, &proto) < 0 || qpol_portcon_get_context(p->p, portcon, &context) < 0)
			{
				goto cleanup;
			}
			if ((po->low >= 0 && ((uint16_t) po->low) != low) ||
			    (po->high >= 0 && ((uint16_t) po->high) != high) || (po->proto >= 0 && ((uint8_t) po->proto) != proto))
			{
				continue;
			}
			retval2 = apol_compare_context(p, context, po->context, po->flags);
			if (retval2 < 0) {
				goto cleanup;
			} else if (retval2 == 0) {
				continue;
			}
		}
		if (apol_vector_append(*v, portcon)) {
			ERR(p, "%s", strerror(ENOMEM));
			goto cleanup;
		}
	}

	retval = 0;
      cleanup:
	if (retval != 0) {
		apol_vector_destroy(v);
	}
	qpol_iterator_destroy(&iter);
	return retval;
}
Пример #6
0
int log_append_model(seaudit_log_t * log, seaudit_model_t * model)
{
	if (apol_vector_append(log->models, model) < 0) {
		int error = errno;
		ERR(log, "%s", strerror(error));
		errno = error;
		return -1;
	}
	return 0;
}
Пример #7
0
apol_policy_path_t *apol_policy_path_create_from_string(const char *path_string)
{
	apol_policy_path_t *p = NULL;
	apol_vector_t *tokens = NULL;
	apol_policy_path_type_e path_type;
	char *s;
	size_t i;
	if (path_string == NULL) {
		errno = EINVAL;
		return NULL;
	}
	if ((tokens = apol_str_split(path_string, ":")) == NULL) {
		return NULL;
	}

	/* first token identifies the path type */
	if (apol_vector_get_size(tokens) < 2) {
		apol_vector_destroy(&tokens);
		return NULL;
	}
	s = apol_vector_get_element(tokens, 0);
	if (strcmp(s, "monolithic") == 0) {
		path_type = APOL_POLICY_PATH_TYPE_MONOLITHIC;
	} else if (strcmp(s, "modular") == 0) {
		path_type = APOL_POLICY_PATH_TYPE_MODULAR;
	} else {
		apol_vector_destroy(&tokens);
		errno = EINVAL;
		return NULL;
	}

	/* second token identifies gives base path */
	s = apol_vector_get_element(tokens, 1);
	if ((p = apol_policy_path_create(path_type, s, NULL)) == NULL) {
		apol_vector_destroy(&tokens);
		return NULL;
	}

	if (path_type == APOL_POLICY_PATH_TYPE_MODULAR) {
		/* remainder are module paths */
		for (i = 2; i < apol_vector_get_size(tokens); i++) {
			s = apol_vector_get_element(tokens, i);
			if ((s = strdup(s)) == NULL || apol_vector_append(p->modules, s) < 0) {
				free(s);
				apol_vector_destroy(&tokens);
				apol_policy_path_destroy(&p);
				return NULL;
			}
		}
		apol_vector_sort_uniquify(p->modules, apol_str_strcmp, NULL);
	}
	return p;
}
Пример #8
0
int apol_filename_trans_query_append_class(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *obj_class)
{
	char *s = NULL;
	if (obj_class == NULL) {
		apol_vector_destroy(&t->classes);
	} else if ((s = strdup(obj_class)) == NULL || (t->classes == NULL && (t->classes = apol_vector_create(free)) == NULL)
		   || apol_vector_append(t->classes, s) < 0) {
		ERR(p, "%s", strerror(errno));
		free(s);
		return -1;
	}
	return 0;
}
Пример #9
0
int apol_permissive_get_by_query(const apol_policy_t * p, apol_permissive_query_t * q, apol_vector_t ** v)
{
	qpol_iterator_t *iter;
	int retval = -1;
	*v = NULL;
	if (qpol_policy_get_permissive_iter(p->p, &iter) < 0) {
		return -1;
	}
	if ((*v = apol_vector_create(NULL)) == NULL) {
		ERR(p, "%s", strerror(errno));
		goto cleanup;
	}
	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		const qpol_permissive_t *permissive;
		if (qpol_iterator_get_item(iter, (void **)&permissive) < 0) {
			goto cleanup;
		}
		if (q != NULL) {
			int compval = apol_compare_permissive(p,
							permissive, q->permissive_name,
							q->flags, &(q->regex));
			if (compval < 0) {
				goto cleanup;
			} else if (compval == 0) {
				continue;
			}
		}
		if (apol_vector_append(*v, (void *)permissive)) {
			ERR(p, "%s", strerror(ENOMEM));
			goto cleanup;
		}
	}

	retval = 0;
      cleanup:
	if (retval != 0) {
		apol_vector_destroy(v);
	}
	qpol_iterator_destroy(&iter);
	return retval;
}
Пример #10
0
/**
 * Given a level, return a vector of its allowed categories (in the
 * form of strings).  These will be sorted in policy order.
 *
 * @param diff Policy diff error handler.
 * @param p Policy from which the level came.
 * @param level Level whose categories to get.
 *
 * @return Vector of category strings for the level.  The caller is
 * responsible for calling apol_vector_destroy().  On error, return
 * NULL.
 */
static apol_vector_t *level_get_cats(const poldiff_t * diff, const apol_policy_t * p, const qpol_level_t * level)
{
	qpol_iterator_t *iter = NULL;
	const qpol_cat_t *cat;
	const char *cat_name;
	apol_vector_t *v = NULL;
	qpol_policy_t *q = apol_policy_get_qpol(p);
	int retval = -1, error = 0;

	if ((v = apol_vector_create(NULL)) == NULL) {
		ERR(diff, "%s", strerror(errno));
		goto cleanup;
	}
	if (qpol_level_get_cat_iter(q, level, &iter) < 0) {
		goto cleanup;
	}
	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		if (qpol_iterator_get_item(iter, (void **)&cat) < 0 || qpol_cat_get_name(q, cat, &cat_name)) {
			error = errno;
			goto cleanup;
		}
		if (apol_vector_append(v, (void *)cat_name) < 0) {
			error = errno;
			ERR(diff, "%s", strerror(error));
			goto cleanup;
		}
	}

	retval = 0;
      cleanup:
	qpol_iterator_destroy(&iter);
	if (retval < 0) {
		apol_vector_destroy(&v);
		errno = error;
		return NULL;
	}
	return v;
}
Пример #11
0
int bool_change_append(seaudit_log_t * log, seaudit_bool_message_t * boolm, const char *name, int value)
{
    char *s = strdup(name);
    seaudit_bool_message_change_t *bc = NULL;
    int error;
    if (s == NULL || apol_bst_insert_and_get(log->bools, (void **)&s, NULL) < 0) {
        error = errno;
        free(s);
        ERR(log, "%s", strerror(error));
        errno = error;
        return -1;
    }
    if ((bc = calloc(1, sizeof(*bc))) == NULL || apol_vector_append(boolm->changes, bc) < 0) {
        error = errno;
        free(s);
        ERR(log, "%s", strerror(error));
        errno = error;
        return -1;
    }
    bc->boolean = s;
    bc->value = value;
    return 0;
}
Пример #12
0
/* process a single node in the xml file */
int sechk_lib_process_xml_node(xmlTextReaderPtr reader, sechk_lib_t * lib)
{
	xmlChar *attrib = NULL;
	int idx;
	sechk_name_value_t *nv = NULL;
	static xmlChar *option = NULL;
	static xmlChar *value = NULL;
	static sechk_module_t *current_module = NULL;

	switch (xmlTextReaderNodeType(reader)) {

	case XML_ELEMENT_DECL:	       /* closing tags */
		if (xmlStrEqual(xmlTextReaderConstName(reader), (xmlChar *) SECHK_PARSE_MODULE_TAG) == 1) {
			current_module = NULL;
		} else if (xmlStrEqual(xmlTextReaderConstName(reader), (xmlChar *) SECHK_PARSE_OPTION_TAG) == 1) {
			free(option);
			option = NULL;
		}
		break;

	case XML_ELEMENT_NODE:	       /* opening tags */

		if (xmlStrEqual(xmlTextReaderConstName(reader), (xmlChar *) SECHK_PARSE_SECHECKER_TAG) == 1) {
			/* parsing the <sechecker> tag */
			attrib = xmlTextReaderGetAttribute(reader, (xmlChar *) SECHK_PARSE_VERSION_ATTRIB);
			if (attrib) {
#ifdef SECHECKER_VERSION
				if (atof((const char *)attrib) > atof(SECHECKER_VERSION)) {
					fprintf(stderr,
						"Error: sechecker version in profile is incorrect: expected %1.1f got %1.1f\n",
						atof(SECHECKER_VERSION), atof((const char *)attrib));
					goto exit_err;
				}
#endif

				free(attrib);
				attrib = NULL;
			} else {
				fprintf(stderr, "Warning: sechecker version is not specified.\n");
			}
		} else if (xmlStrEqual(xmlTextReaderConstName(reader), (xmlChar *) SECHK_PARSE_MODULE_TAG) == 1) {
			/* parsing the <module> tag */
			attrib = xmlTextReaderGetAttribute(reader, (xmlChar *) SECHK_PARSE_NAME_ATTRIB);
			if (attrib) {
				if ((idx = sechk_lib_get_module_idx((const char *)attrib, lib)) == -1) {
					fprintf(stderr, "Warning: module %s not found.\n", (const char *)attrib);
					return 1;	/* not a fatal error */
				} else {
					/* set the values on the existing module */
					current_module = apol_vector_get_element(lib->modules, idx);
					current_module->selected = true;
				}
				free(attrib);
				attrib = NULL;
			} else {
				fprintf(stderr, "Error: module name is not specified.\n");
				goto exit_err;
			}
		} else if (xmlStrEqual(xmlTextReaderConstName(reader), (xmlChar *) SECHK_PARSE_OPTION_TAG) == 1) {
			/* parsing the <option> tag */
			if (!current_module) {
				fprintf(stderr, "Error: 'option' specified outside the scope of a module.\n");
				goto exit_err;
			}
			/* read the name of the option */
			option = xmlTextReaderGetAttribute(reader, (xmlChar *) SECHK_PARSE_NAME_ATTRIB);
			if (!option) {
				fprintf(stderr, "Error: option name is not specified.\n");
				goto exit_err;
			}
			/* clear the options with this name that were set by defualt for this module */
			sechk_lib_module_clear_option(current_module, (char *)option);

		} else if (xmlStrEqual(xmlTextReaderConstName(reader), (xmlChar *) SECHK_PARSE_ITEM_TAG) == 1) {
			/* parsing the <item> tag */
			assert(current_module);
			nv = sechk_name_value_new((char *)option, NULL);
			/* read the value for this name value pair */
			value = xmlTextReaderGetAttribute(reader, (xmlChar *) SECHK_PARSE_VALUE_ATTRIB);
			if (!value) {
				fprintf(stderr, "Error: item value is not specified.\n");
				goto exit_err;
			}
			nv->value = strdup((char *)value);
			free(value);
			value = NULL;
			/* add the nv pair to the module options */
			apol_vector_append(current_module->options, (void *)nv);
			nv = NULL;
		} else if (xmlStrEqual(xmlTextReaderConstName(reader), (xmlChar *) SECHK_PARSE_OUTPUT_TAG) == 1) {
			if (!current_module) {
				fprintf(stderr, "Error: 'output' specified outside the scope of a module.\n");
				goto exit_err;
			}
			attrib = xmlTextReaderGetAttribute(reader, (xmlChar *) SECHK_PARSE_VALUE_ATTRIB);
			if (attrib) {
				if (xmlStrEqual(attrib, (xmlChar *) SECHK_PARSE_OUTPUT_QUIET) == 1) {
					current_module->outputformat = SECHK_OUT_QUIET;
				} else if (xmlStrEqual(attrib, (xmlChar *) SECHK_PARSE_OUTPUT_VERBOSE) == 1) {
					current_module->outputformat = SECHK_OUT_VERBOSE;
				} else if (xmlStrEqual(attrib, (xmlChar *) SECHK_PARSE_OUTPUT_SHORT) == 1) {
					current_module->outputformat = SECHK_OUT_SHORT;
				} else if (xmlStrEqual(attrib, (xmlChar *) SECHK_PARSE_OUTPUT_NONE) == 1) {
					current_module->outputformat = SECHK_OUT_NONE;
				} else {
					fprintf(stderr, "Error: invalid output value %s.\n", attrib);
					goto exit_err;
				}
				free(attrib);
				attrib = NULL;
			} else {
				fprintf(stderr, "Error: output value is not specified.\n");
				goto exit_err;
			}
		}
		break;
	}
	return 0;

      exit_err:
	sechk_name_value_free(nv);
	errno = EIO;
	return -1;
}
Пример #13
0
sechk_lib_t *sechk_lib_new(void)
{
	sechk_lib_t *lib = NULL;
	int retv, error;
	const sechk_module_name_reg_t *reg_list;
	size_t num_known_modules = 0;
	size_t i = 0;
	sechk_module_t *tmp = NULL;

	/* allocate the new sechk_lib_t structure */
	lib = (sechk_lib_t *) calloc(1, sizeof(sechk_lib_t));
	if (!lib) {
		error = errno;
		perror("Error creating module library");
		goto exit_err;
	}

	/* create the module array from the known modules in register list */
	num_known_modules = sechk_register_list_get_num_modules();
	reg_list = sechk_register_list_get_modules();
	lib->modules = apol_vector_create(sechk_module_free);
	if (!lib->modules) {
		error = errno;
		perror("Error adding modules");
		goto exit_err;

	}
	for (i = 0; i < num_known_modules; i++) {
		tmp = sechk_module_new();
		if (!tmp) {
			error = errno;
			perror("Error adding modules");
			goto exit_err;
		}
		tmp->name = strdup(reg_list[i].name);
		if (!tmp->name) {
			error = errno;
			perror("Error adding modules");
			goto exit_err;
		}
		if (apol_vector_append(lib->modules, tmp)) {
			error = errno;
			perror("Error adding modules");
			goto exit_err;
		}
		tmp = NULL;
	}

	/* set the default output format */
	lib->outputformat = SECHK_OUT_SHORT;
	lib->minsev = SECHK_SEV_LOW;

	/* register modules */
	if ((retv = sechk_lib_register_modules(reg_list, lib)) != 0) {
		error = errno;
		perror("Error registering modules");
		goto exit_err;
	}
      exit:
	return lib;

      exit_err:
	sechk_lib_destroy(&lib);
	sechk_module_free(tmp);
	errno = error;
	goto exit;
}
Пример #14
0
int find_domains_register(sechk_lib_t * lib)
{
	sechk_module_t *mod = NULL;
	sechk_fn_t *fn_struct = NULL;

	if (!lib) {
		ERR(NULL, "%s", "No library");
		errno = EINVAL;
		return -1;
	}

	mod = sechk_lib_get_module(mod_name, lib);
	if (!mod) {
		ERR(NULL, "%s", "Module has not been run");
		errno = EINVAL;
		return -1;
	}
	mod->parent_lib = lib;

	/* assign descriptions */
	mod->brief_description = "utility module";
	mod->detailed_description =
		"--------------------------------------------------------------------------------\n"
		"This is a utility module which finds types in a policy that are treated as a    \n"
		"domain.  A type is considered a domain if any of the following is true:\n"
		"\n"
		"   1) it has an attribute associated with domains\n"
		"   2) it is the source of a TE rule for object class other than filesystem\n"
		"   3) it is the default type in a type_transition rule for object class process \n"
		"   4) it is associated with a role other than object_r\n";
	mod->opt_description =
		"Module requirements:\n"
		"   attribute names\n"
		"Module dependencies:\n" "   none\n" "Module options:\n" "   domain_attributes can be set in a profile\n";
	mod->severity = SECHK_SEV_NONE;
	/* assign requirements */
	apol_vector_append(mod->requirements, sechk_name_value_new(SECHK_REQ_POLICY_CAP, SECHK_REQ_CAP_ATTRIB_NAMES));

	/* assign options */
	apol_vector_append(mod->options, sechk_name_value_new("domain_attribute", "domain"));

	/* register functions */
	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_INIT);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = find_domains_init;
	apol_vector_append(mod->functions, fn_struct);

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_RUN);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = find_domains_run;
	apol_vector_append(mod->functions, fn_struct);

	mod->data_free = find_domains_data_free;

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_PRINT);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = find_domains_print;
	apol_vector_append(mod->functions, fn_struct);

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup("get_list");
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = find_domains_get_list;
	apol_vector_append(mod->functions, fn_struct);

	return 0;
}
Пример #15
0
int level_deep_diff_cats(poldiff_t * diff, const apol_vector_t * v1, const apol_vector_t * v2, apol_vector_t ** added,
			 apol_vector_t ** removed, apol_vector_t ** unmodified)
{
	size_t i, j;
	char *cat1, *cat2;
	int compval, retval = -1, error = 0;
	*added = *removed = *unmodified = NULL;
	if ((*added = apol_vector_create(free)) == NULL ||
	    (*removed = apol_vector_create(free)) == NULL || (*unmodified = apol_vector_create(free)) == NULL) {
		error = errno;
		ERR(diff, "%s", strerror(error));
		goto cleanup;
	}
	for (i = j = 0; i < apol_vector_get_size(v1);) {
		if (j >= apol_vector_get_size(v2)) {
			break;
		}
		cat1 = (char *)apol_vector_get_element(v1, i);
		cat2 = (char *)apol_vector_get_element(v2, j);
		compval = strcmp(cat1, cat2);
		if (compval < 0) {
			if ((cat1 = strdup(cat1)) == NULL || apol_vector_append(*removed, cat1) < 0) {
				error = errno;
				ERR(diff, "%s", strerror(error));
				free(cat1);
				goto cleanup;
			}
			i++;
		} else if (compval > 0) {
			if ((cat2 = strdup(cat2)) == NULL || apol_vector_append(*added, cat2) < 0) {
				error = errno;
				ERR(diff, "%s", strerror(error));
				free(cat2);
				goto cleanup;
			}
			j++;
		} else {
			if ((cat1 = strdup(cat1)) == NULL || apol_vector_append(*unmodified, cat1) < 0) {
				error = errno;
				ERR(diff, "%s", strerror(error));
				free(cat1);
				goto cleanup;
			}
			i++;
			j++;
		}
	}
	for (; i < apol_vector_get_size(v1); i++) {
		cat1 = (char *)apol_vector_get_element(v1, i);
		if ((cat1 = strdup(cat1)) == NULL || apol_vector_append(*removed, cat1) < 0) {
			error = errno;
			ERR(diff, "%s", strerror(error));
			free(cat1);
			goto cleanup;
		}
	}
	for (; j < apol_vector_get_size(v2); j++) {
		cat2 = (char *)apol_vector_get_element(v2, j);
		if ((cat2 = strdup(cat2)) == NULL || apol_vector_append(*added, cat2) < 0) {
			error = errno;
			ERR(diff, "%s", strerror(error));
			free(cat2);
			goto cleanup;
		}
	}
	if (apol_vector_get_size(*added) > 0 || apol_vector_get_size(*removed) > 0) {
		retval = 1;
	} else {
		retval = 0;
	}
      cleanup:
	if (retval <= 0) {
		/* if no differences found, then destroy all vectors */
		apol_vector_destroy(added);
		apol_vector_destroy(removed);
		apol_vector_destroy(unmodified);
	}
	if (retval < 0) {
		error = errno;
	}
	return retval;
}
Пример #16
0
/* The register function registers all of a module's functions
 * with the library. */
int attribs_wo_rules_register(sechk_lib_t * lib)
{
    sechk_module_t *mod = NULL;
    sechk_fn_t *fn_struct = NULL;

    if (!lib) {
        ERR(NULL, "%s", "No library");
        errno = EINVAL;
        return -1;
    }

    /* Modules are declared by the config file and their name and options
     * are stored in the module array.  The name is looked up to determine
     * where to store the function structures */
    mod = sechk_lib_get_module(mod_name, lib);
    if (!mod) {
        ERR(NULL, "%s", "Module unknown");
        errno = EINVAL;
        return -1;
    }
    mod->parent_lib = lib;

    /* assign the descriptions */
    mod->brief_description = "attributes not used in any rule";
    mod->detailed_description =
        "--------------------------------------------------------------------------------\n"
        "This module finds attributes in the policy that are not used in any rules; These\n"
        "attributes will get thrown out by the compiler and have no effect on the \n"
        "security environment.  They are unnecessary and should be removed.\n";
    mod->opt_description =
        "Module requirements:\n" "   attribute names\n" "Module dependencies:\n" "   none\n" "Module options:\n"
        "   none\n";
    mod->severity = SECHK_SEV_LOW;
    /* assign requirements */
    if (apol_vector_append(mod->requirements, sechk_name_value_new(SECHK_REQ_POLICY_CAP, SECHK_REQ_CAP_ATTRIB_NAMES)) < 0) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }

    /* register functions */
    fn_struct = sechk_fn_new();
    if (!fn_struct) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }
    fn_struct->name = strdup(SECHK_MOD_FN_INIT);
    if (!fn_struct->name) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }
    fn_struct->fn = attribs_wo_rules_init;
    if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }

    fn_struct = sechk_fn_new();
    if (!fn_struct) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }
    fn_struct->name = strdup(SECHK_MOD_FN_RUN);
    if (!fn_struct->name) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }
    fn_struct->fn = attribs_wo_rules_run;
    if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }

    mod->data_free = NULL;

    fn_struct = sechk_fn_new();
    if (!fn_struct) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }
    fn_struct->name = strdup(SECHK_MOD_FN_PRINT);
    if (!fn_struct->name) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }
    fn_struct->fn = attribs_wo_rules_print;
    if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }

    fn_struct = sechk_fn_new();
    if (!fn_struct) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }
    fn_struct->name = strdup("get_list");
    if (!fn_struct->name) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }
    fn_struct->fn = &attribs_wo_rules_get_list;
    if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
        ERR(NULL, "%s", strerror(ENOMEM));
        errno = ENOMEM;
        return -1;
    }

    return 0;
}
Пример #17
0
/* The register function registers all of a module's functions
 * with the library. */
int roles_wo_types_register(sechk_lib_t * lib)
{
	sechk_module_t *mod = NULL;
	sechk_fn_t *fn_struct = NULL;

	if (!lib) {
		ERR(NULL, "%s", "No library");
		errno = EINVAL;
		return -1;
	}

	/* Modules are declared by the config file and their name and options
	 * are stored in the module array.  The name is looked up to determine
	 * where to store the function structures */
	mod = sechk_lib_get_module(mod_name, lib);
	if (!mod) {
		ERR(NULL, "%s", "Module unknown");
		errno = EINVAL;
		return -1;
	}
	mod->parent_lib = lib;

	/* assign descriptions */
	mod->brief_description = "roles with no types";
	mod->detailed_description =
		"--------------------------------------------------------------------------------\n"
		"This module finds roles in the policy that have no types.  A role with no types \n"
		"cannot form a valid context.\n";
	mod->opt_description =
		"Module requirements:\n" "   none\n" "Module dependencies:\n" "   none\n" "Module options:\n" "   none\n";
	mod->severity = SECHK_SEV_LOW;
	/* register functions */
	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_INIT);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = roles_wo_types_init;
	if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_RUN);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = roles_wo_types_run;
	if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}

	mod->data_free = NULL;

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_PRINT);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = roles_wo_types_print;
	if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}

	return 0;
}
Пример #18
0
/* The register function registers all of a module's functions
 * with the library. */
int attribs_wo_types_register(sechk_lib_t * lib)
{
	sechk_module_t *mod = NULL;
	sechk_fn_t *fn_struct = NULL;

	if (!lib) {
		ERR(NULL, "%s", "No library");
		errno = EINVAL;
		return -1;
	}

	/* Modules are declared by the config file and their name and options
	 * are stored in the module array.  The name is looked up to determine
	 * where to store the function structures */
	mod = sechk_lib_get_module(mod_name, lib);
	if (!mod) {
		ERR(NULL, "%s", "Module unknown");
		errno = EINVAL;
		return -1;
	}
	mod->parent_lib = lib;

	/* assign the descriptions */
	mod->brief_description = "attributes with no types";
	mod->detailed_description =
		"--------------------------------------------------------------------------------\n"
		"This module finds attributes in the policy that are not associated with any\n"
		"types.  Attributes without types can cause type fields in rules to expand to\n"
		"empty sets and thus become unreachable.  This makes for misleading policy source\n" "files.\n";
	mod->opt_description =
		"Module requirements:\n" "   attribute names\n" "Module dependencies:\n" "   none\n" "Module options:\n"
		"   none\n";
	mod->severity = SECHK_SEV_LOW;
	/* assign requirements */
	if (apol_vector_append(mod->requirements, sechk_name_value_new(SECHK_REQ_POLICY_CAP, SECHK_REQ_CAP_ATTRIB_NAMES)) < 0) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}

	/* register functions */
	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_INIT);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = attribs_wo_types_init;
	if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_RUN);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = attribs_wo_types_run;
	if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}

	mod->data_free = NULL;

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_PRINT);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = attribs_wo_types_print;
	if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup("get_list");
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = attribs_wo_types_get_list;
	if (apol_vector_append(mod->functions, (void *)fn_struct) < 0) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}

	return 0;
}
Пример #19
0
/* The register function registers all of a module's functions
 * with the library.  You should not need to edit this function
 * unless you are adding additional functions you need other modules
 * to call. See the note at the bottom of this function to do so. */
int find_node_types_register(sechk_lib_t * lib)
{
	sechk_module_t *mod = NULL;
	sechk_fn_t *fn_struct = NULL;

	if (!lib) {
		ERR(NULL, "%s", "No library");
		errno = EINVAL;
		return -1;
	}

	mod = sechk_lib_get_module(mod_name, lib);
	if (!mod) {
		ERR(NULL, "%s", "Unknown module");
		errno = EINVAL;
		return -1;
	}
	mod->parent_lib = lib;

	/* Modules are declared by the config file and their name and options
	 * are stored in the module array.  The name is looked up to determine
	 * where to store the function structures */

	/* assign the descriptions */
	mod->brief_description = "utility module";
	mod->detailed_description =
		"--------------------------------------------------------------------------------\n"
		"This module finds all types in a policy treated as a node type.  A type is\n"
		"considered a node type if it is used in the context of a nodecon statement or\n"
		"the context of the node initial sid.\n";
	mod->opt_description =
		"  Module requirements:\n" "    none\n" "  Module dependencies:\n" "    none\n" "  Module options:\n" "    none\n";
	mod->severity = SECHK_SEV_NONE;

	/* register functions */
	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_INIT);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = find_node_types_init;
	apol_vector_append(mod->functions, (void *)fn_struct);

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_RUN);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = find_node_types_run;
	apol_vector_append(mod->functions, (void *)fn_struct);

	mod->data_free = NULL;

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup(SECHK_MOD_FN_PRINT);
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = find_node_types_print;
	apol_vector_append(mod->functions, (void *)fn_struct);

	fn_struct = sechk_fn_new();
	if (!fn_struct) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->name = strdup("get_list");
	if (!fn_struct->name) {
		ERR(NULL, "%s", strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}
	fn_struct->fn = find_node_types_get_list;
	apol_vector_append(mod->functions, (void *)fn_struct);

	return 0;
}
Пример #20
0
int apol_role_allow_get_by_query(const apol_policy_t * p, const apol_role_allow_query_t * r, apol_vector_t ** v)
{
	qpol_iterator_t *iter = NULL;
	apol_vector_t *source_list = NULL, *target_list = NULL;
	int retval = -1, source_as_any = 0;
	*v = NULL;

	if (r != NULL) {
		if (r->source != NULL &&
		    (source_list = apol_query_create_candidate_role_list(p, r->source, r->flags & APOL_QUERY_REGEX)) == NULL) {
			goto cleanup;
		}
		if ((r->flags & APOL_QUERY_SOURCE_AS_ANY) && r->source != NULL) {
			target_list = source_list;
			source_as_any = 1;
		} else if (r->target != NULL &&
			   (target_list = apol_query_create_candidate_role_list(p, r->target, r->flags & APOL_QUERY_REGEX)) == NULL)
		{
			goto cleanup;
		}
	}
	if (qpol_policy_get_role_allow_iter(p->p, &iter) < 0) {
		goto cleanup;
	}
	if ((*v = apol_vector_create(NULL)) == NULL) {
		ERR(p, "%s", strerror(errno));
		goto cleanup;
	}
	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		qpol_role_allow_t *rule;
		int match_source = 0, match_target = 0;
		size_t i;
		if (qpol_iterator_get_item(iter, (void **)&rule) < 0) {
			goto cleanup;
		}

		if (source_list == NULL) {
			match_source = 1;
		} else {
			const qpol_role_t *source_role;
			if (qpol_role_allow_get_source_role(p->p, rule, &source_role) < 0) {
				goto cleanup;
			}
			if (apol_vector_get_index(source_list, source_role, NULL, NULL, &i) == 0) {
				match_source = 1;
			}
		}

		/* if source did not match, but treating source symbol
		 * as any field, then delay rejecting this rule until
		 * the target has been checked */
		if (!source_as_any && !match_source) {
			continue;
		}

		if (target_list == NULL || (source_as_any && match_source)) {
			match_target = 1;
		} else {
			const qpol_role_t *target_role;
			if (qpol_role_allow_get_target_role(p->p, rule, &target_role) < 0) {
				goto cleanup;
			}
			if (apol_vector_get_index(target_list, target_role, NULL, NULL, &i) == 0) {
				match_target = 1;
			}
		}
		if (!match_target) {
			continue;
		}

		if (apol_vector_append(*v, rule)) {
			ERR(p, "%s", strerror(ENOMEM));
			goto cleanup;
		}
	}

	retval = 0;
      cleanup:
	if (retval != 0) {
		apol_vector_destroy(v);
	}
	apol_vector_destroy(&source_list);
	if (!source_as_any) {
		apol_vector_destroy(&target_list);
	}
	qpol_iterator_destroy(&iter);
	return retval;
}
Пример #21
0
apol_vector_t *apol_mls_range_get_levels(const apol_policy_t * p, const apol_mls_range_t * range)
{
	qpol_policy_t *q = apol_policy_get_qpol(p);
	apol_vector_t *v = NULL, *catv = NULL;
	const qpol_level_t *l;
	uint32_t low_value, high_value, value;
	int error = 0;
	qpol_iterator_t *iter = NULL, *catiter = NULL;

	if (p == NULL || range == NULL || range->low == NULL) {
		error = EINVAL;
		ERR(p, "%s", strerror(error));
		goto err;
	}
	apol_mls_level_t *low_level, *high_level;
	low_level = range->low;
	if (range->high == NULL) {
		high_level = low_level;
	} else {
		high_level = range->high;
	}
	if (qpol_policy_get_level_by_name(q, apol_mls_level_get_sens(low_level), &l) < 0 ||
	    qpol_level_get_value(q, l, &low_value) < 0) {
		error = errno;
		goto err;
	}
	if (qpol_policy_get_level_by_name(q, apol_mls_level_get_sens(high_level), &l) < 0 ||
	    qpol_level_get_value(q, l, &high_value) < 0) {
		error = errno;
		goto err;
	}
	assert(low_value <= high_value);
	if ((v = apol_vector_create(mls_level_free)) == NULL) {
		error = errno;
		ERR(p, "%s", strerror(error));
		goto err;
	}
	if (qpol_policy_get_level_iter(q, &iter) < 0) {
		error = errno;
		goto err;
	}
	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		const char *name;
		apol_mls_level_t *ml;
		if (qpol_iterator_get_item(iter, (void **)&l) < 0 ||
		    qpol_level_get_value(q, l, &value) < 0 || qpol_level_get_name(q, l, &name) < 0) {
			error = errno;
			goto err;
		}
		if (value < low_value || value > high_value) {
			continue;
		}
		if ((ml = apol_mls_level_create()) == NULL || (apol_mls_level_set_sens(p, ml, name) < 0)) {
			error = errno;
			apol_mls_level_destroy(&ml);
			ERR(p, "%s", strerror(error));
			goto err;
		}

		if (qpol_level_get_cat_iter(q, l, &catiter) < 0 || (catv = apol_vector_create_from_iter(catiter, NULL)) == NULL) {
			error = errno;
			goto err;
		}

		const apol_vector_t *high_cats = apol_mls_level_get_cats(high_level);
		for (size_t i = 0; i < apol_vector_get_size(high_cats); i++) {
			char *cat_name = apol_vector_get_element(high_cats, i);

			size_t j;
			/* do not add categories that are not members of
			   the level */
			if (apol_vector_get_index(catv, cat_name, mls_level_name_to_cat_comp, q, &j) < 0) {
				/* this category is not legal under the given policy */
				continue;
			}
			if (apol_mls_level_append_cats(p, ml, cat_name) < 0) {
				error = errno;
				apol_mls_level_destroy(&ml);
				ERR(p, "%s", strerror(error));
				goto err;
			}
		}

		qpol_iterator_destroy(&catiter);
		apol_vector_destroy(&catv);

		if (apol_vector_append(v, ml) < 0) {
			error = errno;
			apol_mls_level_destroy(&ml);
			ERR(p, "%s", strerror(error));
			goto err;
		}
	}
	apol_vector_sort(v, mls_range_comp, q);
	qpol_iterator_destroy(&iter);
	qpol_iterator_destroy(&catiter);
	apol_vector_destroy(&catv);
	return v;
      err:
	qpol_iterator_destroy(&iter);
	qpol_iterator_destroy(&catiter);
	apol_vector_destroy(&v);
	apol_vector_destroy(&catv);
	errno = error;
	return NULL;
}
Пример #22
0
int apol_filename_trans_get_by_query(const apol_policy_t * p, const apol_filename_trans_query_t * t, apol_vector_t ** v)
{
	apol_vector_t *source_list = NULL, *target_list = NULL, *class_list = NULL, *default_list = NULL;
	int retval = -1, source_as_any = 0, is_regex = 0;
	*v = NULL;
	qpol_iterator_t *iter = NULL;

	if (t != NULL) {
		is_regex = t->flags & APOL_QUERY_REGEX;
		if (t->source != NULL &&
		    (source_list =
		     apol_query_create_candidate_type_list(p, t->source, is_regex,
							   t->flags & APOL_QUERY_SOURCE_INDIRECT,
							   ((t->flags & (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE)) /
							    APOL_QUERY_SOURCE_TYPE))) == NULL) {
			goto cleanup;
		}

		if ((t->flags & APOL_QUERY_SOURCE_AS_ANY) && t->source != NULL) {
			default_list = target_list = source_list;
			source_as_any = 1;
		} else {
			if (t->target != NULL &&
			    (target_list =
			     apol_query_create_candidate_type_list(p, t->target, is_regex,
								   t->flags & APOL_QUERY_TARGET_INDIRECT,
								   ((t->
								     flags & (APOL_QUERY_TARGET_TYPE | APOL_QUERY_TARGET_ATTRIBUTE))
								    / APOL_QUERY_TARGET_TYPE))) == NULL) {
				goto cleanup;
			}
			if (t->default_type != NULL &&
			    (default_list =
			     apol_query_create_candidate_type_list(p, t->default_type, is_regex, 0,
								   APOL_QUERY_SYMBOL_IS_TYPE)) == NULL) {
				goto cleanup;
			}
		}
		if (t->classes != NULL &&
		    apol_vector_get_size(t->classes) > 0 &&
		    (class_list = apol_query_create_candidate_class_list(p, t->classes)) == NULL) {
			goto cleanup;
		}
	}

	if (qpol_policy_get_filename_trans_iter(p->p, &iter) < 0) {
		goto cleanup;
	}

	if ((*v = apol_vector_create(NULL)) == NULL) {
		ERR(p, "%s", strerror(errno));
		goto cleanup;
	}

	for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) {
		int match_source = 0, match_target = 0, match_default = 0;
		size_t i;

		qpol_filename_trans_t *filename_trans;
		if (qpol_iterator_get_item(iter, (void **)&filename_trans) < 0) {
			goto cleanup;
		}

		if (source_list == NULL) {
			match_source = 1;
		} else {
			const qpol_type_t *source_type;
			if (qpol_filename_trans_get_source_type(p->p, filename_trans, &source_type) < 0) {
				goto cleanup;
			}
			if (apol_vector_get_index(source_list, source_type, NULL, NULL, &i) == 0) {
				match_source = 1;
			}
		}

		/* if source did not match, but treating source symbol
		 * as any field, then delay rejecting this filename_trans until
		 * the target and default have been checked */
		if (!source_as_any && !match_source) {
			continue;
		}

		if (target_list == NULL || (source_as_any && match_source)) {
			match_target = 1;
		} else {
			const qpol_type_t *target_type;
			if (qpol_filename_trans_get_target_type(p->p, filename_trans, &target_type) < 0) {
				goto cleanup;
			}
			if (apol_vector_get_index(target_list, target_type, NULL, NULL, &i) == 0) {
				match_target = 1;
			}
		}

		if (!source_as_any && !match_target) {
			continue;
		}

		if (default_list == NULL || (source_as_any && match_source) || (source_as_any && match_target)) {
			match_default = 1;
		} else {
			const qpol_type_t *default_type;
			if (qpol_filename_trans_get_default_type(p->p, filename_trans, &default_type) < 0) {
				goto cleanup;
			}
			if (apol_vector_get_index(default_list, default_type, NULL, NULL, &i) == 0) {
				match_default = 1;
			}
		}

		if (!source_as_any && !match_default) {
			continue;
		}
		/* at least one thing must match if source_as_any was given */
		if (source_as_any && (!match_source && !match_target && !match_default)) {
			continue;
		}

		if (class_list != NULL) {
			const qpol_class_t *obj_class;
			if (qpol_filename_trans_get_object_class(p->p, filename_trans, &obj_class) < 0) {
				goto cleanup;
			}
			if (apol_vector_get_index(class_list, obj_class, NULL, NULL, &i) < 0) {
				continue;
			}
		}

		if (apol_vector_append(*v, filename_trans)) {
			ERR(p, "%s", strerror(ENOMEM));
			goto cleanup;
		}
	}

	retval = 0;
      cleanup:
	if (retval != 0) {
		apol_vector_destroy(v);
	}
	apol_vector_destroy(&source_list);
	if (!source_as_any) {
		apol_vector_destroy(&target_list);
		apol_vector_destroy(&default_list);
	}
	apol_vector_destroy(&class_list);
	qpol_iterator_destroy(&iter);
	return retval;
}
Пример #23
0
static int perform_av_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v)
{
	apol_avrule_query_t *avq = NULL;
	unsigned int rules = 0;
	int error = 0;
	char *tmp = NULL, *tok = NULL, *s = NULL;

	if (!policy || !opt || !v) {
		PyErr_SetString(PyExc_RuntimeError,strerror(EINVAL));
		errno = EINVAL;
		return -1;
	}

	if (!opt->all && !opt->allow && !opt->nallow && !opt->auditallow && !opt->dontaudit) {
		*v = NULL;
		return 0;	       /* no search to do */
	}

	avq = apol_avrule_query_create();
	if (!avq) {
		PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM));
		errno = ENOMEM;
		return -1;
	}

	if (opt->allow || opt->all)
		rules |= QPOL_RULE_ALLOW;
	if (opt->nallow || opt->all)	// Add this regardless of policy capabilities
		rules |= QPOL_RULE_NEVERALLOW;
	if (opt->auditallow || opt->all)
		rules |= QPOL_RULE_AUDITALLOW;
	if (opt->dontaudit || opt->all)
		rules |= QPOL_RULE_DONTAUDIT;
	if (rules != 0)	// Setting rules = 0 means you want all the rules
		apol_avrule_query_set_rules(policy, avq, rules);
	apol_avrule_query_set_regex(policy, avq, opt->useregex);
	if (opt->src_name)
		apol_avrule_query_set_source(policy, avq, opt->src_name, opt->indirect);
	if (opt->tgt_name)
		apol_avrule_query_set_target(policy, avq, opt->tgt_name, opt->indirect);
	if (opt->bool_name)
		apol_avrule_query_set_bool(policy, avq, opt->bool_name);
	if (opt->class_name) {
		if (opt->class_vector == NULL) {
			if (apol_avrule_query_append_class(policy, avq, opt->class_name)) {
				goto err;
			}
		} else {
			size_t i;
	    for (i = 0; i < apol_vector_get_size(opt->class_vector); ++i) {
				char *class_name;
				class_name = apol_vector_get_element(opt->class_vector, i);
				if (!class_name)
					continue;
				if (apol_avrule_query_append_class(policy, avq, class_name)) {
					goto err;
				}
			}
		}
	}

	if (opt->permlist) {
		tmp = strdup(opt->permlist);
		for (tok = strtok(tmp, ","); tok; tok = strtok(NULL, ",")) {
			if (apol_avrule_query_append_perm(policy, avq, tok)) {
				goto err;
			}
			if ((s = strdup(tok)) == NULL || apol_vector_append(opt->perm_vector, s) < 0) {
				goto err;
			}
			s = NULL;
		}
		free(tmp);
		tmp = NULL;
	}

	if (!(opt->semantic) && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) {
		if (apol_syn_avrule_get_by_query(policy, avq, v)) {
			goto err;
		}
	} else {
		if (apol_avrule_get_by_query(policy, avq, v)) {
			goto err;
		}
	}

	apol_avrule_query_destroy(&avq);
	return 0;

err:
	error = errno;
	PyErr_SetString(PyExc_RuntimeError,strerror(error));
	apol_vector_destroy(v);
	apol_avrule_query_destroy(&avq);
	free(tmp);
	free(s);
	errno = error;
	return -1;
}
Пример #24
0
apol_policy_path_t *apol_policy_path_create_from_file(const char *filename)
{
	FILE *f = NULL;
	apol_policy_path_t *path = NULL;
	apol_policy_path_type_e path_type;
	char *line = NULL, *s;
	apol_vector_t *header_tokens = NULL;
	size_t len;
	int read_base = 0, retval = -1, error = 0;

	if (filename == NULL) {
		error = EINVAL;
		goto cleanup;
	}
	if ((f = fopen(filename, "r")) == NULL) {
		error = errno;
		goto cleanup;
	}

	if (apol_getline(&line, &len, f) < 0) {
		error = EIO;
		goto cleanup;
	}
	apol_str_trim(line);
	if (strncmp(line, POLICY_PATH_MAGIC, strlen(POLICY_PATH_MAGIC)) != 0) {
		error = EIO;
		goto cleanup;
	}

	apol_str_trim(line);
	if ((header_tokens = apol_str_split(line, " ")) == NULL) {
		error = errno;
		goto cleanup;
	}
	if (apol_vector_get_size(header_tokens) < 3) {
		error = EIO;
		goto cleanup;
	}
	s = apol_vector_get_element(header_tokens, 1);
	if (atoi(s) == 0 || atoi(s) > POLICY_PATH_MAX_VERSION) {
		error = ENOTSUP;
		goto cleanup;
	}
	s = apol_vector_get_element(header_tokens, 2);
	if (strcmp(s, "monolithic") == 0) {
		path_type = APOL_POLICY_PATH_TYPE_MONOLITHIC;
	} else if (strcmp(s, "modular") == 0) {
		path_type = APOL_POLICY_PATH_TYPE_MODULAR;
	} else {
		error = EIO;
		goto cleanup;
	}

	while (apol_getline(&line, &len, f) >= 0) {
		apol_str_trim(line);
		if (line[0] == '#') {
			continue;
		}
		if (!read_base) {
			/* trying to parse a base policy / monolithic policy line */
			if ((path = apol_policy_path_create(path_type, line, NULL)) == NULL) {
				error = errno;
				goto cleanup;
			}
			read_base = 1;
		} else {
			/* trying to parse a module line */
			if (path_type == APOL_POLICY_PATH_TYPE_MONOLITHIC) {
				error = EIO;
				goto cleanup;
			} else {
				if ((s = strdup(line)) == NULL || apol_vector_append(path->modules, s) < 0) {
					error = errno;
					free(s);
					goto cleanup;
				}
			}
		}
	}
	if (read_base == 0) {
		error = EIO;
		goto cleanup;
	}
	retval = 0;
      cleanup:
	if (f != NULL) {
		fclose(f);
	}
	free(line);
	apol_vector_destroy(&header_tokens);
	if (retval != 0) {
		apol_policy_path_destroy(&path);
		errno = error;
	}
	return path;
}