int oval_probe_query_test(oval_probe_session_t *sess, struct oval_test *test) { struct oval_object *object; struct oval_state_iterator *ste_itr; const char *type, *test_id, *comment; int ret; type = oval_subtype_get_text(oval_test_get_subtype(test)); test_id = oval_test_get_id(test); comment = oval_test_get_comment(test); dI("Evaluating %s test '%s': %s.", type, test_id, comment); 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); ret = oval_probe_query_var_ref(sess, state); if (ret < 1) { oval_state_iterator_free(ste_itr); return ret; } } oval_state_iterator_free(ste_itr); return 0; }
struct oval_test *oval_test_clone(struct oval_definition_model *new_model, struct oval_test *old_test) { __attribute__nonnull__(old_test); struct oval_state_iterator *ste_itr; struct oval_test *new_test = oval_definition_model_get_test(new_model, old_test->id); if (new_test == NULL) { new_test = oval_test_new(new_model, old_test->id); oval_test_set_deprecated(new_test, old_test->deprecated); oval_test_set_version(new_test, old_test->version); oval_test_set_check(new_test, old_test->check); oval_test_set_existence(new_test, old_test->existence); oval_test_set_state_operator(new_test, old_test->state_operator); oval_test_set_subtype(new_test, old_test->subtype); oval_test_set_comment(new_test, old_test->comment); if (old_test->object) { struct oval_object *object = oval_object_clone(new_model, old_test->object); oval_test_set_object(new_test, object); } ste_itr = oval_test_get_states(old_test); while (oval_state_iterator_has_more(ste_itr)) { struct oval_state *ste; ste = oval_state_iterator_next(ste_itr); ste = oval_state_clone(new_model, ste); oval_test_add_state(new_test, ste); } oval_state_iterator_free(ste_itr); struct oval_string_iterator *notes = oval_test_get_notes(old_test); while (oval_string_iterator_has_more(notes)) { char *note = oval_string_iterator_next(notes); oval_test_add_note(new_test, note); } oval_string_iterator_free(notes); } return new_test; }
int oval_probe_query_test(oval_probe_session_t *sess, struct oval_test *test) { struct oval_object *object; struct oval_state_iterator *ste_itr; int ret; oval_subtype_t test_subtype, object_subtype; object = oval_test_get_object(test); if (object == NULL) return 0; test_subtype = oval_test_get_subtype(test); object_subtype = oval_object_get_subtype(object); if (test_subtype != object_subtype) { oscap_seterr(OSCAP_EFAMILY_OVAL, "%s_test '%s' is not compatible with %s_object '%s'.", oval_subtype_to_str(test_subtype), oval_test_get_id(test), oval_subtype_to_str(object_subtype), oval_object_get_id(object)); 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); ret = oval_probe_query_var_ref(sess, state); if (ret < 1) { oval_state_iterator_free(ste_itr); return ret; } } oval_state_iterator_free(ste_itr); return 0; }
static void _oval_result_test_initialize_bindings(struct oval_result_test *rslt_test) { __attribute__nonnull__(rslt_test); struct oval_test *oval_test = oval_result_test_get_test(rslt_test); struct oval_string_map *vm; struct oval_state_iterator *ste_itr; struct oval_iterator *var_itr; vm = oval_string_map_new(); /* Gather bindings pertaining to the referenced states */ /* TODO: cache bindings collected for each state */ ste_itr = oval_test_get_states(oval_test); while (oval_state_iterator_has_more(ste_itr)) { struct oval_state *ste; ste = oval_state_iterator_next(ste_itr); oval_ste_collect_var_refs(ste, vm); } oval_state_iterator_free(ste_itr); var_itr = oval_string_map_values(vm); while (oval_collection_iterator_has_more(var_itr)) { struct oval_variable *var; struct oval_value_iterator *val_itr; struct oval_variable_binding *binding; var = oval_collection_iterator_next(var_itr); binding = oval_variable_binding_new(var, NULL); val_itr = oval_variable_get_values(var); while (oval_value_iterator_has_more(val_itr)) { struct oval_value *val; char *txt; val = oval_value_iterator_next(val_itr); txt = oval_value_get_text(val); txt = oscap_strdup(txt); oval_variable_binding_add_value(binding, txt); } oval_value_iterator_free(val_itr); oval_result_test_add_binding(rslt_test, binding); } oval_collection_iterator_free(var_itr); /* Gather bindings pertaining to the collected object */ struct oval_object *oval_object = oval_test_get_object(oval_test); if (oval_object) { char *object_id = oval_object_get_id(oval_object); struct oval_result_system *sys = oval_result_test_get_system(rslt_test); struct oval_syschar_model *syschar_model = oval_result_system_get_syschar_model(sys); struct oval_syschar *syschar = oval_syschar_model_get_syschar(syschar_model, object_id); /* no syschar if system characteristics was a subset of definitions */ if(syschar) { struct oval_variable_binding_iterator *bindings = oval_syschar_get_variable_bindings(syschar); while (oval_variable_binding_iterator_has_more(bindings)) { struct oval_variable *var; char *var_id; struct oval_variable_binding *binding = oval_variable_binding_iterator_next(bindings); var = oval_variable_binding_get_variable(binding); var_id = oval_variable_get_id(var); /* Don't add bindings that were already * collected from states. Assumtion is made * that object's own bindings don't contain * duplicates. */ if (oval_string_map_get_value(vm, var_id) == NULL) { struct oval_definition_model *definition_model = oval_syschar_model_get_definition_model(syschar_model); struct oval_variable_binding *binding_copy = oval_variable_binding_clone(binding, definition_model); oval_result_test_add_binding(rslt_test, binding_copy); } } oval_variable_binding_iterator_free(bindings); } } oval_string_map_free(vm, NULL); rslt_test->bindings_initialized = true; }
static oval_result_t _oval_result_test_evaluate_items(struct oval_test *test, struct oval_syschar *syschar_object, void **args) { struct oval_sysitem_iterator *collected_items_itr; oval_result_t result; int exists_cnt, error_cnt; bool hasstate; oval_check_t test_check; oval_existence_t test_check_existence; struct oval_state_iterator *ste_itr; exists_cnt = error_cnt = 0; collected_items_itr = oval_syschar_get_sysitem(syschar_object); while (oval_sysitem_iterator_has_more(collected_items_itr)) { struct oval_sysitem *item; char *item_id; oval_syschar_status_t item_status; struct oval_result_item *ritem; item = oval_sysitem_iterator_next(collected_items_itr); if (item == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "Iterator returned null."); oval_sysitem_iterator_free(collected_items_itr); return OVAL_RESULT_ERROR; } item_status = oval_sysitem_get_status(item); if (item_status == SYSCHAR_STATUS_EXISTS) exists_cnt++; if (item_status == SYSCHAR_STATUS_ERROR) error_cnt++; item_id = oval_sysitem_get_id(item); ritem = oval_result_item_new(SYSTEM, item_id); oval_result_item_set_result(ritem, OVAL_RESULT_NOT_EVALUATED); _oval_test_item_consumer(ritem, args); } oval_sysitem_iterator_free(collected_items_itr); test_check = oval_test_get_check(test); test_check_existence = oval_test_get_existence(test); ste_itr = oval_test_get_states(test); hasstate = oval_state_iterator_has_more(ste_itr); oval_state_iterator_free(ste_itr); switch (oval_syschar_get_flag(syschar_object)) { case SYSCHAR_FLAG_ERROR: if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_ERROR; } break; case SYSCHAR_FLAG_NOT_COLLECTED: if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_UNKNOWN; } break; case SYSCHAR_FLAG_NOT_APPLICABLE: if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_NOT_APPLICABLE; } break; case SYSCHAR_FLAG_DOES_NOT_EXIST: if (test_check_existence == OVAL_NONE_EXIST || test_check_existence == OVAL_ANY_EXIST) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_FALSE; } break; case SYSCHAR_FLAG_COMPLETE: result = eval_check_existence(test_check_existence, exists_cnt, error_cnt); if (result == OVAL_RESULT_TRUE && hasstate) { result = eval_check_state(test, args); } break; case SYSCHAR_FLAG_INCOMPLETE: if (test_check_existence == OVAL_ANY_EXIST) { result = OVAL_RESULT_TRUE; } else if (test_check_existence == OVAL_AT_LEAST_ONE_EXISTS && exists_cnt > 0) { result = OVAL_RESULT_TRUE; } else if (test_check_existence == OVAL_NONE_EXIST && exists_cnt > 0) { result = OVAL_RESULT_FALSE; } else if (test_check_existence == OVAL_ONLY_ONE_EXISTS && exists_cnt > 1) { result = OVAL_RESULT_FALSE; } else { result = OVAL_RESULT_UNKNOWN; } if (result == OVAL_RESULT_TRUE && hasstate) { result = eval_check_state(test, args); if (result == OVAL_RESULT_TRUE) { if (test_check != OVAL_CHECK_AT_LEAST_ONE) { result = OVAL_RESULT_UNKNOWN; } } else if (result != OVAL_RESULT_FALSE) { result = OVAL_RESULT_UNKNOWN; } } break; default: { const char *object_id = oval_syschar_get_object(syschar_object) ? oval_object_get_id(oval_syschar_get_object(syschar_object)) : "<UNKNOWN>"; oscap_seterr(OSCAP_EFAMILY_OVAL, "Unknown syschar flag: '%d' when evaluating object: '%s' from test: '%s' ", oval_syschar_get_flag(syschar_object), object_id, oval_test_get_id(test)); return OVAL_RESULT_ERROR; } } return result; }
static oval_result_t eval_check_state(struct oval_test *test, void **args) { struct oval_syschar_model *syschar_model; struct oval_result_item_iterator *ritems_itr; struct oresults item_ores; oval_result_t result; oval_check_t ste_check; oval_operator_t ste_opr; ste_check = oval_test_get_check(test); ste_opr = oval_test_get_state_operator(test); syschar_model = oval_result_system_get_syschar_model(SYSTEM); ores_clear(&item_ores); ritems_itr = oval_result_test_get_items(TEST); while (oval_result_item_iterator_has_more(ritems_itr)) { struct oval_result_item *ritem; struct oval_sysitem *item; oval_syschar_status_t item_status; struct oresults ste_ores; struct oval_state_iterator *ste_itr; oval_result_t item_res; ritem = oval_result_item_iterator_next(ritems_itr); item = oval_result_item_get_sysitem(ritem); item_status = oval_sysitem_get_status(item); switch (item_status) { case SYSCHAR_STATUS_ERROR: case SYSCHAR_STATUS_NOT_COLLECTED: item_res = OVAL_RESULT_ERROR; ores_add_res(&item_ores, item_res); oval_result_item_set_result(ritem, item_res); continue; case SYSCHAR_STATUS_DOES_NOT_EXIST: item_res = OVAL_RESULT_FALSE; ores_add_res(&item_ores, item_res); oval_result_item_set_result(ritem, item_res); continue; default: break; } ores_clear(&ste_ores); ste_itr = oval_test_get_states(test); while (oval_state_iterator_has_more(ste_itr)) { struct oval_state *ste; oval_result_t ste_res; ste = oval_state_iterator_next(ste_itr); ste_res = eval_item(syschar_model, item, ste); ores_add_res(&ste_ores, ste_res); } oval_state_iterator_free(ste_itr); item_res = ores_get_result_byopr(&ste_ores, ste_opr); ores_add_res(&item_ores, item_res); oval_result_item_set_result(ritem, item_res); } oval_result_item_iterator_free(ritems_itr); result = ores_get_result_bychk(&item_ores, ste_check); return result; }
static oval_result_t _oval_result_test_evaluate_items(struct oval_test *test, struct oval_syschar *syschar_object, void **args) { struct oval_sysitem_iterator *collected_items_itr; oval_result_t result; int exists_cnt, error_cnt; bool hasstate; const char *test_id, *object_id, *flag_text; oval_check_t test_check; oval_existence_t test_check_existence; struct oval_state_iterator *ste_itr; oval_syschar_collection_flag_t flag; struct oval_object *object; exists_cnt = error_cnt = 0; test_id = oval_test_get_id(test); collected_items_itr = oval_syschar_get_sysitem(syschar_object); while (oval_sysitem_iterator_has_more(collected_items_itr)) { struct oval_sysitem *item; char *item_id; oval_syschar_status_t item_status; struct oval_result_item *ritem; item = oval_sysitem_iterator_next(collected_items_itr); if (item == NULL) { oscap_seterr(OSCAP_EFAMILY_OVAL, "Iterator returned null."); oval_sysitem_iterator_free(collected_items_itr); return OVAL_RESULT_ERROR; } item_status = oval_sysitem_get_status(item); if (item_status == SYSCHAR_STATUS_EXISTS) exists_cnt++; if (item_status == SYSCHAR_STATUS_ERROR) error_cnt++; item_id = oval_sysitem_get_id(item); ritem = oval_result_item_new(SYSTEM, item_id); oval_result_item_set_result(ritem, OVAL_RESULT_NOT_EVALUATED); _oval_test_item_consumer(ritem, args); } oval_sysitem_iterator_free(collected_items_itr); test_check = oval_test_get_check(test); test_check_existence = oval_test_get_existence(test); ste_itr = oval_test_get_states(test); hasstate = oval_state_iterator_has_more(ste_itr); oval_state_iterator_free(ste_itr); object = oval_syschar_get_object(syschar_object); object_id = object ? oval_object_get_id(object) : "<UNKNOWN>"; switch (test_check_existence) { case OVAL_ALL_EXIST: dI("Test '%s' requires that every object defined by '%s' exists on the system.", test_id, object_id); break; case OVAL_ANY_EXIST: dI("Test '%s' requires that zero or more objects defined by '%s' exist on the system.", test_id, object_id); break; case OVAL_AT_LEAST_ONE_EXISTS: dI("Test '%s' requires that at least one object defined by '%s' exists on the system.", test_id, object_id); break; case OVAL_NONE_EXIST: dI("Test '%s' requires that none of the objects defined by '%s' exist on the system.", test_id, object_id); break; case OVAL_ONLY_ONE_EXISTS: dI("Test '%s' requires that only one object defined by '%s' exists on the system.", test_id, object_id); break; default: oscap_seterr(OSCAP_EFAMILY_OVAL, "Check_existence parameter of test '%s' is unknown. This may indicate a bug in OpenSCAP.", test_id); } dI("%d objects defined by '%s' exist on the system.", exists_cnt, object_id); if (!hasstate) { dI("Test '%s' does not contain any state to compare object with.", test_id); } flag = oval_syschar_get_flag(syschar_object); flag_text = oval_syschar_collection_flag_get_text(flag); switch (flag) { case SYSCHAR_FLAG_ERROR: dI("An error occured while collecting items matching object '%s'. (flag=%s)", object_id, flag_text); if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_ERROR; } break; case SYSCHAR_FLAG_NOT_COLLECTED: dI("No attempt was made to collect items matching object '%s'. (flag=%s)", object_id, flag_text); if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_UNKNOWN; } break; case SYSCHAR_FLAG_NOT_APPLICABLE: dI("Object '%s' is not applicable to the system. (flag=%s)", object_id, flag_text); if (test_check_existence == OVAL_ANY_EXIST && !hasstate) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_NOT_APPLICABLE; } break; case SYSCHAR_FLAG_DOES_NOT_EXIST: dI("No item matching object '%s' was found on the system. (flag=%s)", object_id, flag_text); if (test_check_existence == OVAL_NONE_EXIST || test_check_existence == OVAL_ANY_EXIST) { result = OVAL_RESULT_TRUE; } else { result = OVAL_RESULT_FALSE; } break; case SYSCHAR_FLAG_COMPLETE: dI("All items matching object '%s' were collected. (flag=%s)", object_id, flag_text); result = eval_check_existence(test_check_existence, exists_cnt, error_cnt); if (result == OVAL_RESULT_TRUE && hasstate) { result = eval_check_state(test, args); } break; case SYSCHAR_FLAG_INCOMPLETE: dI("Only some of items matching object '%s' have been collected from the system. It is unknown if other matching items also exist. (flag=%s)", object_id, flag_text); if (test_check_existence == OVAL_ANY_EXIST) { result = OVAL_RESULT_TRUE; } else if (test_check_existence == OVAL_AT_LEAST_ONE_EXISTS && exists_cnt > 0) { result = OVAL_RESULT_TRUE; } else if (test_check_existence == OVAL_NONE_EXIST && exists_cnt > 0) { result = OVAL_RESULT_FALSE; } else if (test_check_existence == OVAL_ONLY_ONE_EXISTS && exists_cnt > 1) { result = OVAL_RESULT_FALSE; } else { result = OVAL_RESULT_UNKNOWN; } if (result == OVAL_RESULT_TRUE && hasstate) { result = eval_check_state(test, args); if (result == OVAL_RESULT_TRUE) { if (test_check != OVAL_CHECK_AT_LEAST_ONE) { result = OVAL_RESULT_UNKNOWN; } } else if (result != OVAL_RESULT_FALSE) { result = OVAL_RESULT_UNKNOWN; } } break; default: { oscap_seterr(OSCAP_EFAMILY_OVAL, "Item corresponding to object '%s' from test '%s' has an unknown flag. This may indicate a bug in OpenSCAP.", object_id, test_id); return OVAL_RESULT_ERROR; } } return result; }
/** * @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; }
xmlNode *oval_test_to_dom(struct oval_test *test, xmlDoc * doc, xmlNode * parent) { xmlNode * test_node=NULL; /* skip unknown test */ oval_subtype_t subtype = oval_test_get_subtype(test); if ( subtype == OVAL_SUBTYPE_UNKNOWN ) { oscap_dlprintf(DBG_E, "Unknown Test %s.\n", oval_test_get_id(test)); return test_node; } /* get test name */ const char *subtype_text = oval_subtype_get_text(subtype); char test_name[strlen(subtype_text) + 6]; sprintf(test_name, "%s_test", subtype_text); /* get family URI */ oval_family_t family = oval_test_get_family(test); const char *family_text = oval_family_get_text(family); char family_uri[strlen((const char *)OVAL_DEFINITIONS_NAMESPACE) + strlen(family_text) + 2]; sprintf(family_uri,"%s#%s", OVAL_DEFINITIONS_NAMESPACE, family_text); /* search namespace & create child */ xmlNs *ns_family = xmlSearchNsByHref(doc, parent, BAD_CAST family_uri); test_node = xmlNewTextChild(parent, ns_family, BAD_CAST test_name, NULL); char *id = oval_test_get_id(test); xmlNewProp(test_node, BAD_CAST "id", BAD_CAST id); char version[10]; *version = '\0'; snprintf(version, sizeof(version), "%d", oval_test_get_version(test)); xmlNewProp(test_node, BAD_CAST "version", BAD_CAST version); oval_existence_t existence = oval_test_get_existence(test); if (existence != OVAL_AT_LEAST_ONE_EXISTS) xmlNewProp(test_node, BAD_CAST "check_existence", BAD_CAST oval_existence_get_text(existence)); oval_check_t check = oval_test_get_check(test); xmlNewProp(test_node, BAD_CAST "check", BAD_CAST oval_check_get_text(check)); oval_operator_t ste_operator = oval_test_get_state_operator(test); if (ste_operator != OVAL_OPERATOR_AND) xmlNewProp(test_node, BAD_CAST "state_operator", BAD_CAST oval_operator_get_text(ste_operator)); char *comm = oval_test_get_comment(test); xmlNewProp(test_node, BAD_CAST "comment", BAD_CAST comm); bool deprecated = oval_test_get_deprecated(test); if (deprecated) xmlNewProp(test_node, BAD_CAST "deprecated", BAD_CAST "true"); struct oval_string_iterator *notes = oval_test_get_notes(test); if (oval_string_iterator_has_more(notes)) { xmlNs *ns_definitions = xmlSearchNsByHref(doc, parent, OVAL_DEFINITIONS_NAMESPACE); xmlNode *notes_node = xmlNewTextChild(test_node, ns_definitions, BAD_CAST "notes", NULL); while (oval_string_iterator_has_more(notes)) { char *note = oval_string_iterator_next(notes); xmlNewTextChild(notes_node, ns_definitions, BAD_CAST "note", BAD_CAST note); } } oval_string_iterator_free(notes); struct oval_object *object = oval_test_get_object(test); if (object) { xmlNode *object_node = xmlNewTextChild(test_node, ns_family, BAD_CAST "object", NULL); xmlNewProp(object_node, BAD_CAST "object_ref", BAD_CAST oval_object_get_id(object)); } struct oval_state_iterator *ste_itr = oval_test_get_states(test); while (oval_state_iterator_has_more(ste_itr)) { struct oval_state *state; state = oval_state_iterator_next(ste_itr); xmlNode *state_node = xmlNewTextChild(test_node, ns_family, BAD_CAST "state", NULL); xmlNewProp(state_node, BAD_CAST "state_ref", BAD_CAST oval_state_get_id(state)); } oval_state_iterator_free(ste_itr); return test_node; }