示例#1
0
static struct oval_variable *oval_probe_variable_objgetvar(struct oval_object *obj)
{
        struct oval_entity  *ent;
        struct oval_object_content *con;
        struct oval_object_content_iterator *cit;
	struct oval_variable *var;
        char *ent_name;

	var = NULL;
        cit = oval_object_get_object_contents(obj);

	while (oval_object_content_iterator_has_more(cit)) {
                con = oval_object_content_iterator_next(cit);

                if (oval_object_content_get_type(con) != OVAL_OBJECTCONTENT_ENTITY)
                        continue;

                ent = oval_object_content_get_entity(con);
                ent_name = oval_entity_get_name(ent);

                if (strcmp(ent_name, "var_ref") != 0)
                        continue;

                var = oval_entity_get_variable(ent);
                break;
        }

        oval_object_content_iterator_free(cit);

        return(var);
}
示例#2
0
struct oval_entity *oval_entity_clone(struct oval_definition_model *new_model, struct oval_entity *old_entity) {
	struct oval_entity *new_entity = oval_entity_new(new_model);
	oval_datatype_t datatype = oval_entity_get_datatype(old_entity);
	oval_entity_set_datatype(new_entity, datatype);
	int mask = oval_entity_get_mask(old_entity);
	oval_entity_set_mask(new_entity, mask);
	bool xsi_nil = oval_entity_get_xsi_nil(old_entity);
	oval_entity_set_xsi_nil(new_entity, xsi_nil);
	char *name = oval_entity_get_name(old_entity);
	oval_entity_set_name(new_entity, name);
	oval_operation_t operation = oval_entity_get_operation(old_entity);
	oval_entity_set_operation(new_entity, operation);
	oval_entity_type_t type = oval_entity_get_type(old_entity);
	oval_entity_set_type(new_entity, type);
	struct oval_value *value = oval_entity_get_value(old_entity);
	if (value) {
		oval_entity_set_value(new_entity, oval_value_clone(value));
	}
	struct oval_variable *old_variable = oval_entity_get_variable(old_entity);
	if (old_variable) {
		oval_entity_set_variable(new_entity, oval_variable_clone(new_model, old_variable));
	}
	oval_entity_varref_type_t reftype = oval_entity_get_varref_type(old_entity);
	oval_entity_set_varref_type(new_entity, reftype);
	return new_entity;
}
示例#3
0
static inline oval_result_t _evaluate_sysent_with_variable(struct oval_syschar_model *syschar_model, struct oval_entity *state_entity, struct oval_sysent *item_entity, oval_operation_t state_entity_operation, struct oval_state_content *content)
{
	oval_syschar_collection_flag_t flag;
	oval_result_t ent_val_res;

	struct oval_variable *state_entity_var;
	if ((state_entity_var = oval_entity_get_variable(state_entity)) == NULL) {
		oscap_seterr(OSCAP_EFAMILY_OVAL, "OVAL internal error: found NULL variable");
		return -1;
	}

	if (0 != oval_syschar_model_compute_variable(syschar_model, state_entity_var)) {
		return -1;
	}

	flag = oval_variable_get_collection_flag(state_entity_var);
	switch (flag) {
	case SYSCHAR_FLAG_COMPLETE:
	case SYSCHAR_FLAG_INCOMPLETE:{
		struct oresults var_ores;
		struct oval_value_iterator *val_itr;

		ores_clear(&var_ores);

		val_itr = oval_variable_get_values(state_entity_var);
		while (oval_value_iterator_has_more(val_itr)) {
			struct oval_value *var_val;
			char *state_entity_val_text = NULL;
			oval_result_t var_val_res;

			var_val = oval_value_iterator_next(val_itr);
			state_entity_val_text = oval_value_get_text(var_val);
			if (state_entity_val_text == NULL) {
				dE("Found NULL variable value text.\n");
				ores_add_res(&var_ores, OVAL_RESULT_ERROR);
				break;
			}
			oval_datatype_t state_entity_val_datatype = oval_value_get_datatype(var_val);

			var_val_res = oval_ent_cmp_str(state_entity_val_text, state_entity_val_datatype, item_entity, state_entity_operation);
			ores_add_res(&var_ores, var_val_res);
		}
		oval_value_iterator_free(val_itr);

		oval_check_t var_check = oval_state_content_get_var_check(content);
		ent_val_res = ores_get_result_bychk(&var_ores, var_check);
		} break;
	case SYSCHAR_FLAG_ERROR:
	case SYSCHAR_FLAG_DOES_NOT_EXIST:
	case SYSCHAR_FLAG_NOT_COLLECTED:
	case SYSCHAR_FLAG_NOT_APPLICABLE:
		ent_val_res = OVAL_RESULT_ERROR;
		break;
	default:
		ent_val_res = -1;
	}

	return ent_val_res;
}
示例#4
0
static SEXP_t *oval_entity_to_sexp(struct oval_entity *ent)
{
	SEXP_t *elm, *elm_name;
	SEXP_t *r0, *r1, *r2;
	oval_datatype_t datatype;
	oval_entity_varref_type_t vr_type;

	elm_name = SEXP_list_new(r0 = SEXP_string_newf("%s", oval_entity_get_name(ent)),
				 /* operation */
				 r1 = SEXP_string_new(":operation", 10),
				 r2 = SEXP_number_newu_32(oval_entity_get_operation(ent)), NULL);
	SEXP_vfree(r0, r1, r2, NULL);

        if (oval_entity_get_mask(ent)) {
            SEXP_list_add(elm_name, r0 = SEXP_string_new("mask", 4));
            SEXP_free(r0);
        }

	elm = SEXP_list_new(NULL);
	datatype = oval_entity_get_datatype(ent);
	probe_ent_setdatatype(elm, datatype);

	vr_type = oval_entity_get_varref_type(ent);
	if (vr_type == OVAL_ENTITY_VARREF_ATTRIBUTE
	    || vr_type == OVAL_ENTITY_VARREF_ELEMENT) {
		/* var_ref */
		struct oval_variable *var;

		var = oval_entity_get_variable(ent);
		SEXP_list_add(elm_name, r0 = SEXP_string_new(":var_ref", 8));
		SEXP_list_add(elm_name, r1 = SEXP_string_newf("%s", oval_variable_get_id(var)));
		SEXP_list_add(elm, elm_name);
		SEXP_vfree(r0, r1, elm_name, NULL);
	} else {
		/* value */
		struct oval_value *val;

		SEXP_list_add(elm, elm_name);
		SEXP_free(elm_name);
		val = oval_entity_get_value(ent);

		if (datatype != OVAL_DATATYPE_RECORD
		    && val != NULL) {
			SEXP_t *val_sexp;

			val_sexp = oval_value_to_sexp(val, datatype);
			if (val_sexp != NULL) {
				SEXP_list_add(elm, val_sexp);
				SEXP_free(val_sexp);
			}
		}
	}

	return (elm);
}
示例#5
0
static int oval_probe_query_var_ref(oval_probe_session_t *sess, struct oval_state *state)
{
	struct oval_state_content_iterator *contents = oval_state_get_contents(state);
	while (oval_state_content_iterator_has_more(contents)) {
		struct oval_state_content *content = oval_state_content_iterator_next(contents);
		struct oval_entity * entity = oval_state_content_get_entity(content);
		if (oval_entity_get_varref_type(entity) == OVAL_ENTITY_VARREF_ATTRIBUTE) {
			oval_syschar_collection_flag_t flag;
			struct oval_variable *var = oval_entity_get_variable(entity);
			const char *state_id = oval_state_get_id(state);
			oval_variable_type_t var_type = oval_variable_get_type(var);
			const char *var_type_text = oval_variable_type_get_text(var_type);
			const char *var_id = oval_variable_get_id(var);
			dI("State '%s' references %s '%s'.", state_id,
			   var_type_text, var_id);

			int ret = oval_probe_query_variable(sess, var);
			if (ret == -1) {
				oval_state_content_iterator_free(contents);
				return ret;
			}

			flag = oval_variable_get_collection_flag(var);
			switch (flag) {
			case SYSCHAR_FLAG_COMPLETE:
			case SYSCHAR_FLAG_INCOMPLETE:
				break;
			default:
				oval_state_content_iterator_free(contents);
				return 0;
			}
		}
	}
	oval_state_content_iterator_free(contents);
	return 1;
}
示例#6
0
/**
 * @returns 0 on success; -1 on error; 1 on warning
 */
static int oval_probe_query_criteria(oval_probe_session_t *sess, struct oval_criteria_node *cnode) {
	int ret;

	switch (oval_criteria_node_get_type(cnode)) {
	/* Criterion node is the final node that has a reference to a test */
	case OVAL_NODETYPE_CRITERION:{
		/* There should be a test .. */
		struct oval_test *test;
		struct oval_object *object;
		struct oval_state_iterator *ste_itr;

		test = oval_criteria_node_get_test(cnode);
		if (test == NULL)
			return 0;
		object = oval_test_get_object(test);
		if (object == NULL)
			return 0;
		/* probe object */
		ret = oval_probe_query_object(sess, object, 0, NULL);
		if (ret == -1)
			return ret;
		/* probe objects referenced like this: test->state->variable->object */
		ste_itr = oval_test_get_states(test);
		while (oval_state_iterator_has_more(ste_itr)) {
			struct oval_state *state = oval_state_iterator_next(ste_itr);
			struct oval_state_content_iterator *contents = oval_state_get_contents(state);
			while (oval_state_content_iterator_has_more(contents)) {
				struct oval_state_content *content = oval_state_content_iterator_next(contents);
				struct oval_entity * entity = oval_state_content_get_entity(content);
				if (oval_entity_get_varref_type(entity) == OVAL_ENTITY_VARREF_ATTRIBUTE) {
					oval_syschar_collection_flag_t flag;
					struct oval_variable *var = oval_entity_get_variable(entity);

					ret = oval_probe_query_variable(sess, var);
					if (ret == -1) {
						oval_state_content_iterator_free(contents);
						oval_state_iterator_free(ste_itr);
						return ret;
					}

					flag = oval_variable_get_collection_flag(var);
					switch (flag) {
					case SYSCHAR_FLAG_COMPLETE:
					case SYSCHAR_FLAG_INCOMPLETE:
						break;
					default:
						oval_state_content_iterator_free(contents);
						oval_state_iterator_free(ste_itr);
						return 0;
					}
				}
			}
			oval_state_content_iterator_free(contents);
		}
		oval_state_iterator_free(ste_itr);

		return 0;

		}
		break;
                /* Criteria node is type of set that contains more criterias. Criteria node
                 * child can be also type of criteria, criterion or extended definition */
        case OVAL_NODETYPE_CRITERIA:{
                        /* group of criterion nodes, get subnodes, continue recursive */
                        struct oval_criteria_node_iterator *cnode_it = oval_criteria_node_get_subnodes(cnode);
                        if (cnode_it == NULL)
                                return 0;
                        /* we have subnotes */
                        struct oval_criteria_node *node;
                        while (oval_criteria_node_iterator_has_more(cnode_it)) {
                                node = oval_criteria_node_iterator_next(cnode_it);
                                ret = oval_probe_query_criteria(sess, node);
                                if (ret != 0) {
                                        oval_criteria_node_iterator_free(cnode_it);
                                        return ret;
                                }
                        }
                        oval_criteria_node_iterator_free(cnode_it);
			return 0;
                }
                break;
                /* Extended definition contains reference to definition, we need criteria of this
                 * definition to be evaluated completely */
        case OVAL_NODETYPE_EXTENDDEF:{
                        struct oval_definition *oval_def = oval_criteria_node_get_definition(cnode);
			struct oval_criteria_node *node =  oval_definition_get_criteria(oval_def);
			if (node == NULL) {
				oscap_seterr(OSCAP_EFAMILY_OSCAP, "Could not find extended definition: %s.",
					oval_definition_get_id(oval_def));
				return -1;
			}
                        return oval_probe_query_criteria(sess, node);
                }
                break;
        case OVAL_NODETYPE_UNKNOWN:
                break;
        }

	/* we shouldn't get here */
        return -1;
}
示例#7
0
int oval_state_to_sexp(void *sess, struct oval_state *state, SEXP_t **out_sexp)
{
	SEXP_t *ste, *ste_name, *ste_ent;
	SEXP_t *r0, *r1, *r2, *r3, *r4;
	char buffer[128];
	size_t buflen;
	const char *subtype_name;
	struct oval_state_content_iterator *contents;

        subtype_name = oval_subtype_to_str(oval_state_get_subtype(state));

	if (subtype_name == NULL) {
		dI("FAIL: unknown subtype: %d", oval_state_get_subtype(state));
		return (-1);
	}

	buflen = snprintf(buffer, sizeof buffer, "%s_state", subtype_name);
	_A(buflen < sizeof buffer);

	ste_name = SEXP_list_new(r0 = SEXP_string_new(buffer, buflen),
				 r1 = SEXP_string_new(":id", 3),
				 r2 = SEXP_string_newf("%s", oval_state_get_id(state)),
				 r3 = SEXP_string_new(":operator", 9),
				 r4 = SEXP_number_newu(oval_state_get_operator(state)),
				 NULL);

	ste = SEXP_list_new(ste_name, NULL);
	SEXP_vfree(r0, r1, r2, r3, r4, ste_name, NULL);

	contents = oval_state_get_contents(state);
	while (oval_state_content_iterator_has_more(contents)) {
		oval_check_t ochk;
		oval_existence_t oext;
		oval_entity_varref_type_t vr_type;
		struct oval_entity *ent;
		struct oval_state_content *content = oval_state_content_iterator_next(contents);
		struct oval_record_field_iterator *rf_itr;

		ent = oval_state_content_get_entity(content);
		ste_ent = oval_entity_to_sexp(ent);
		if (ste_ent == NULL) {
			goto fail;
		}

		rf_itr = oval_state_content_get_record_fields(content);
		while (oval_record_field_iterator_has_more(rf_itr)) {
			struct oval_record_field *rf;
			SEXP_t *rf_sexp;

			rf = oval_record_field_iterator_next(rf_itr);
			rf_sexp = oval_record_field_STATE_to_sexp(rf);

			SEXP_list_add(ste_ent, rf_sexp);
			SEXP_free(rf_sexp);
		}
		oval_record_field_iterator_free(rf_itr);

		ochk = oval_state_content_get_var_check(content);
		if (ochk != OVAL_CHECK_UNKNOWN) {
			probe_ent_attr_add(ste_ent, "var_check", r0 = SEXP_number_newu_32(ochk));
			SEXP_free(r0);
		}

		ochk = oval_state_content_get_ent_check(content);
		if (ochk != OVAL_CHECK_UNKNOWN) {
			probe_ent_attr_add(ste_ent, "entity_check", r0 = SEXP_number_newu_32(ochk));
			SEXP_free(r0);
		}

		oext = oval_state_content_get_check_existence(content);
		if (oext != OVAL_EXISTENCE_UNKNOWN) {
			probe_ent_attr_add(ste_ent, "check_existence", r0 = SEXP_number_newu_32(oext));
			SEXP_free(r0);
		}

		vr_type = oval_entity_get_varref_type(ent);
		if (vr_type == OVAL_ENTITY_VARREF_ATTRIBUTE
		    || vr_type == OVAL_ENTITY_VARREF_ELEMENT) {
			SEXP_t *val_lst;
			struct oval_variable *var;
			oval_datatype_t dt;

			var = oval_entity_get_variable(ent);
			dt = oval_entity_get_datatype(ent);

			if (oval_varref_elm_to_sexp(sess, var, dt, &val_lst, NULL) != 0)
				goto fail;

			SEXP_list_add(ste_ent, val_lst);
			SEXP_free(val_lst);
		}

		SEXP_list_add(ste, ste_ent);
		SEXP_free(ste_ent);
	}
	oval_state_content_iterator_free(contents);

	*out_sexp = ste;
	return (0);

 fail:
	oval_state_content_iterator_free(contents);
	SEXP_vfree(ste, ste_ent, NULL);
	return (-1);
}
示例#8
0
int oval_object_to_sexp(void *sess, const char *typestr, struct oval_syschar *syschar, SEXP_t **out_sexp)
{
	unsigned int ent_cnt, varref_cnt;
	int ret;
	SEXP_t *obj_sexp, *elm, *varrefs, *ent_lst, *lst, *stmp;
	SEXP_t *r0, *r1, *r2, *obj_attr, sm0, sm1;

	struct oval_object *object;
	struct oval_object_content_iterator *cit;
	struct oval_behavior_iterator *bit;
	struct oval_object_content *content;
	struct oval_entity *entity;

	char obj_name[128];
	const char *obj_id;

	object = oval_syschar_get_object(syschar);

	/*
	 * Object name & attributes (id)
	 */
	ret = snprintf(obj_name, sizeof obj_name, "%s_object", typestr);
	if (ret<0 || (unsigned int) ret > sizeof obj_name) {
		dE("obj_name length too short");
		return -1;
	}

	// even though it returns const char* it has to be freed :-(
	char *obj_over = (char*)oval_schema_version_to_cstr(oval_object_get_platform_schema_version(object));
	obj_id   = oval_object_get_id(object);
	obj_attr = probe_attr_creat("id", SEXP_string_new_r(&sm0, obj_id, strlen(obj_id)),
	                            "oval_version", SEXP_string_new_r(&sm1, obj_over, strlen(obj_over)),
	                            NULL);
	free(obj_over);

	obj_sexp = probe_obj_new(obj_name, obj_attr);

	SEXP_free_r(&sm0);
	SEXP_free_r(&sm1);
	SEXP_free(obj_attr);

	/*
	 * Object content
	 */

	ent_lst = SEXP_list_new(NULL);
	varrefs = NULL;
	ent_cnt = varref_cnt = 0;

	cit = oval_object_get_object_contents(object);
	while (oval_object_content_iterator_has_more(cit)) {
		oval_check_t ochk;
		oval_entity_varref_type_t vr_type;

		content = oval_object_content_iterator_next(cit);
		elm = NULL;
		lst = ent_lst;

		switch (oval_object_content_get_type(content)) {
		case OVAL_OBJECTCONTENT_ENTITY:
			entity = oval_object_content_get_entity(content);
			elm = oval_entity_to_sexp(entity);
			if (elm == NULL)
				break;

			ochk = oval_object_content_get_varCheck(content);
			if (ochk != OVAL_CHECK_UNKNOWN) {
				probe_ent_attr_add(elm, "var_check",
						   r0 = SEXP_number_newu_32(ochk));
				SEXP_free(r0);
			}
			ret = 0;
			vr_type = oval_entity_get_varref_type(entity);
			if (vr_type == OVAL_ENTITY_VARREF_ATTRIBUTE) {
				const char *var_id = oval_variable_get_id(oval_entity_get_variable(entity));
				const char *field_name = oval_object_content_get_field_name(content);
				dI("Object '%s' references variable '%s' in '%s' field.", obj_id, var_id, field_name);
				ret = oval_varref_attr_to_sexp(sess, entity, syschar, &stmp);

				if (ret == 0) {
					if (varrefs == NULL)
						varrefs = SEXP_list_new(NULL);

					SEXP_list_add(varrefs, stmp);
					SEXP_free(stmp);
					// todo: don't add duplicates
					++varref_cnt;

					lst = obj_sexp;
					++ent_cnt;
				}
			} else if (vr_type == OVAL_ENTITY_VARREF_ELEMENT) {
				SEXP_t *val_lst;
				struct oval_variable *var;
				oval_datatype_t dt;

				var = oval_entity_get_variable(entity);
				dt = oval_entity_get_datatype(entity);
				ret = oval_varref_elm_to_sexp(sess, var, dt, &val_lst, syschar);

				if (ret == 0) {
					SEXP_list_add(elm, val_lst);
					SEXP_free(val_lst);
				}
			}

			if (ret != 0) {
				SEXP_t s_flag;
				SEXP_number_newi_32_r(&s_flag, SYSCHAR_FLAG_DOES_NOT_EXIST);
				probe_item_attr_add(obj_sexp, "skip_eval", &s_flag);
				SEXP_free_r(&s_flag);

				SEXP_free(elm);
				SEXP_free(ent_lst);
				if (varrefs != NULL)
					SEXP_free(varrefs);
				oval_object_content_iterator_free(cit);

				*out_sexp = obj_sexp;

				return (0);
			}

			break;

		case OVAL_OBJECTCONTENT_SET:
			elm = oval_set_to_sexp(oval_object_content_get_setobject(content));
			break;

		case OVAL_OBJECTCONTENT_FILTER: {
			struct oval_filter *filter = oval_object_content_get_filter(content);
			struct oval_state *ste = oval_filter_get_state(filter);
			const char *ste_id = oval_state_get_id(ste);
			oval_filter_action_t action = oval_filter_get_filter_action(filter);
			const char *action_text = oval_filter_action_get_text(action);
			dI("Object '%s' has a filter that %ss items conforming to state '%s'.",
					obj_id, action_text, ste_id);
			elm = oval_filter_to_sexp(filter);
			}
			break;

		case OVAL_OBJECTCONTENT_UNKNOWN:
			break;
		}

		if (elm == NULL) {
			SEXP_free(obj_sexp);
			SEXP_free(ent_lst);
			if (varrefs != NULL)
				SEXP_free(varrefs);
			oval_object_content_iterator_free(cit);

			return -1;
		}

		SEXP_list_add(lst, elm);
		SEXP_free(elm);
	}

	if (varrefs != NULL) {
		// todo: SEXP_list_push()
		stmp = SEXP_list_new(r0 = SEXP_string_new("varrefs", 7),
				     r1 = SEXP_number_newu(varref_cnt), r2 = SEXP_number_newu(ent_cnt), NULL);
		SEXP_vfree(r0, r1, r2, NULL);

		r0 = SEXP_list_join(stmp, varrefs);
		SEXP_list_add(obj_sexp, r0);
		SEXP_vfree(stmp, varrefs, r0, NULL);
	}

	stmp = SEXP_list_join(obj_sexp, ent_lst);
	SEXP_free(obj_sexp);
	SEXP_free(ent_lst);
	obj_sexp = stmp;

	oval_object_content_iterator_free(cit);

	/*
	 * Object behaviors
	 */

	bit = oval_object_get_behaviors(object);
	if (oval_behavior_iterator_has_more(bit)) {
		elm = oval_behaviors_to_sexp(bit);
		SEXP_list_add(obj_sexp, elm);
		SEXP_free(elm);
	}
	oval_behavior_iterator_free(bit);

	*out_sexp = obj_sexp;

	return (0);
}
示例#9
0
static int oval_varref_attr_to_sexp(void *sess, struct oval_entity *entity, struct oval_syschar *syschar, SEXP_t **out_sexp)
{
	unsigned int val_cnt = 0;
	SEXP_t *val_lst, *val_sexp, *varref, *id_sexp, *val_cnt_sexp;
	oval_datatype_t dt;
	struct oval_variable *var;
	struct oval_value_iterator *vit;
	struct oval_value *val;
	oval_syschar_collection_flag_t flag;
	char msg[100];
	int ret = 0;

	var = oval_entity_get_variable(entity);
	if (oval_probe_query_variable(sess, var) != 0) {
		dE("Can't convert variable reference to SEXP.");
		return -1;
	}

	flag = oval_variable_get_collection_flag(var);
	switch (flag) {
	case SYSCHAR_FLAG_COMPLETE:
	case SYSCHAR_FLAG_INCOMPLETE:
		vit = oval_variable_get_values(var);
		if (oval_value_iterator_has_more(vit))
			break;
		oval_value_iterator_free(vit);
		/* fall through */
	case SYSCHAR_FLAG_DOES_NOT_EXIST:
		snprintf(msg, sizeof(msg), "Referenced variable has no values (%s).", oval_variable_get_id(var));
		dI("%s", msg);
		ret = 1;
		break;
	default:
		snprintf(msg, sizeof(msg), "There was a problem processing referenced variable (%s).", oval_variable_get_id(var));
		dW("%s", msg);
		ret = 1;
	}

	if (ret) {
		oval_syschar_add_new_message(syschar, msg, OVAL_MESSAGE_LEVEL_WARNING);
		oval_syschar_set_flag(syschar, SYSCHAR_FLAG_DOES_NOT_EXIST);
		return ret;
	}

	val_lst = SEXP_list_new(NULL);

	while (oval_value_iterator_has_more(vit)) {
		val = oval_value_iterator_next(vit);

		dt = oval_entity_get_datatype(entity);
		val_sexp = oval_value_to_sexp(val, dt);
		if (val_sexp == NULL) {
			oval_syschar_add_new_message(syschar, "Failed to convert variable value.", OVAL_MESSAGE_LEVEL_ERROR);
			oval_syschar_set_flag(syschar, SYSCHAR_FLAG_ERROR);
			SEXP_free(val_lst);
			oval_value_iterator_free(vit);
			return -1;
		}

		SEXP_list_add(val_lst, val_sexp);
		SEXP_free(val_sexp);
		++val_cnt;
	}
	oval_value_iterator_free(vit);

	id_sexp = SEXP_string_newf("%s", oval_variable_get_id(var));
	val_cnt_sexp = SEXP_number_newu(val_cnt);

	varref = SEXP_list_new(id_sexp, val_cnt_sexp, val_lst, NULL);

	SEXP_free(id_sexp);
	SEXP_free(val_cnt_sexp);
	SEXP_free(val_lst);

	*out_sexp = varref;
	return 0;
}