diff options
author | Sumit Bose <sbose@redhat.com> | 2009-01-19 19:26:25 +0100 |
---|---|---|
committer | Sumit Bose <sbose@redhat.com> | 2009-01-19 19:26:25 +0100 |
commit | 0240837c572c6bc1139884ece7be1ea09c61c01f (patch) | |
tree | 529b7ffeb04d5acb540b28fba2bf746c30592d6a | |
parent | 999096b1e43e5325d536ca13690c68a877abee7e (diff) | |
download | ipa_policy-0240837c572c6bc1139884ece7be1ea09c61c01f.tar.gz ipa_policy-0240837c572c6bc1139884ece7be1ea09c61c01f.tar.xz ipa_policy-0240837c572c6bc1139884ece7be1ea09c61c01f.zip |
added basic policy collection support
-rw-r--r-- | policy_collection/policy_collection.rng | 22 | ||||
-rw-r--r-- | policy_collection/policy_collection_example.xml | 24 | ||||
-rw-r--r-- | worker/Makefile.am | 2 | ||||
-rw-r--r-- | worker/policy_collection.c | 118 | ||||
-rw-r--r-- | worker/policy_collection.h | 34 | ||||
-rw-r--r-- | worker/worker.c | 21 | ||||
-rw-r--r-- | worker/xml_helper.c | 75 |
7 files changed, 269 insertions, 27 deletions
diff --git a/policy_collection/policy_collection.rng b/policy_collection/policy_collection.rng new file mode 100644 index 0000000..7ab94a8 --- /dev/null +++ b/policy_collection/policy_collection.rng @@ -0,0 +1,22 @@ +<grammar xmlns="http://relaxng.org/ns/structure/1.0" +datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" +xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"> + <start> + <element name="policy_collection"> + <oneOrMore> + <element name="template"> + <element name="name"> + <text/> + </element> + <element name="ordered_policies"> + <oneOrMore> + <element name="file"> + <text/> + </element> + </oneOrMore> + </element> + </element> + </oneOrMore> + </element> + </start> +</grammar> diff --git a/policy_collection/policy_collection_example.xml b/policy_collection/policy_collection_example.xml new file mode 100644 index 0000000..8074736 --- /dev/null +++ b/policy_collection/policy_collection_example.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<policy_collection> + <template> + <name>sudo.rng</name> + <ordered_policies> + <file>234523.xml</file> + <file>432623465324.xml</file> + </ordered_policies> + </template> + <template> + <name>ipaaction.rng</name> + <ordered_policies> + <file>36572436.xml</file> + <file>2456143746.xml</file> + </ordered_policies> + </template> + <template> + <name>pam_selinux.rng</name> + <ordered_policies> + <file>323465327234.xml</file> + <file>67458123665.xml</file> + </ordered_policies> + </template> +</policy_collection> diff --git a/worker/Makefile.am b/worker/Makefile.am index 58e651d..5046e08 100644 --- a/worker/Makefile.am +++ b/worker/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = worker -worker_SOURCES = worker.c debug.c helpers.c ipaaction.c xml_helper.c output_handler.c +worker_SOURCES = worker.c debug.c helpers.c ipaaction.c xml_helper.c output_handler.c policy_collection.c if WITH_SSSD worker_SOURCES += sbus_client.c endif diff --git a/worker/policy_collection.c b/worker/policy_collection.c new file mode 100644 index 0000000..fa310f5 --- /dev/null +++ b/worker/policy_collection.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) Sumit Bose 2009 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <string.h> + +#include <libxml/tree.h> +#include <libxml/parser.h> +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> + +#include "util.h" +#include "policy_collection.h" + + +int load_policy_collection(const char *filename, + struct policy_collection **pc_array) { + int ret=-1; + int i; + int pol_file_counter; + int policy_count; + xmlDocPtr doc=NULL; + xmlXPathContextPtr xpath_context=NULL; + xmlXPathObjectPtr xpath_obj=NULL; + xmlNodePtr template_node_ptr; + xmlNodePtr policy_node_ptr; + + + doc = xmlParseFile(filename); + CHECK(doc, NULL, ("Cannot parse document %s!\n", filename), return -1); + + ret=validate_with_rng(doc, "policy_collection.rng"); + CHECK(ret, -1, ("Validation of %s failed!\n", filename), goto cleanup); + ret=-1; + + xpath_context = xmlXPathNewContext(doc); + CHECK(xpath_context, NULL, ("Error: unable to create new XPath context\n"), + goto cleanup); + + xpath_obj = xmlXPathEvalExpression(XPATH_POLICY_COLLECTION_TEMPLATE, + xpath_context); + CHECK(xpath_obj, NULL, ("Unable to evaluate xpath expression \"%s\"\n", + XPATH_POLICY_COLLECTION_TEMPLATE), goto cleanup); + + policy_count = xmlXPathNodeSetGetLength(xpath_obj->nodesetval); + DEBUG(3,("Found %d policy templates in policy collection %s.\n", + policy_count, filename)); + + *pc_array = malloc(sizeof(struct policy_collection) * (policy_count+1)); + CHECK(*pc_array, NULL, ("Malloc failed\n"), goto cleanup); + + for (i=0; i<policy_count; i++) { + template_node_ptr = xpath_obj->nodesetval->nodeTab[i]->children; + do { + if (xmlStrEqual(template_node_ptr->name,(xmlChar *) "name")) { + DEBUG(3,("Found name: %s\n", template_node_ptr->children->content)); + (*pc_array)[i].name = strdup(template_node_ptr->children->content); + } + + if (xmlStrEqual(template_node_ptr->name,(xmlChar *) "ordered_policies")) { + policy_node_ptr = template_node_ptr->children; + pol_file_counter = 0; + do { + if (xmlStrEqual(policy_node_ptr->name, (xmlChar *) "file")) { + DEBUG(3,("Found policy file: %s\n", policy_node_ptr->children->content)); + (*pc_array)[i].files[pol_file_counter++]=strdup(policy_node_ptr->children->content); + } + policy_node_ptr = policy_node_ptr->next; + } while ( policy_node_ptr != template_node_ptr->last); + (*pc_array)[i].files[pol_file_counter]=NULL; + } + + template_node_ptr = template_node_ptr->next; + } while ( template_node_ptr != xpath_obj->nodesetval->nodeTab[i]->last); + } + + (*pc_array)[i].name=NULL; + + ret=0; + +cleanup: + xmlXPathFreeObject(xpath_obj); + xmlXPathFreeContext(xpath_context); + xmlFreeDoc(doc); + xmlCleanupParser(); + return ret; +} + +int free_policy_collection(struct policy_collection **pc_array) { + int poli_c; + int file_c; + + poli_c=0; + while ((*pc_array)[poli_c].name != NULL) { + free((*pc_array)[poli_c].name); + file_c=0; + while ((*pc_array)[poli_c].files[file_c] != NULL) { + free((*pc_array)[poli_c].files[file_c]); + file_c++; + } + poli_c++; + } + free(*pc_array); +} diff --git a/worker/policy_collection.h b/worker/policy_collection.h new file mode 100644 index 0000000..46ca4fd --- /dev/null +++ b/worker/policy_collection.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) Sumit Bose 2009 + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef _POLICY_COLLECTION_H_ +#define _POLICY_COLLECTION_H_ + +#define XPATH_POLICY_COLLECTION_TEMPLATE "//template" + +#define MAX_POLICY_FILES 256 + +struct policy_collection { + char *name; + char *files[MAX_POLICY_FILES]; +}; + +int load_policy_collection(const char *filename, struct policy_collection **pc_array); +int free_policy_collection(struct policy_collection **pc_array); + +#endif /* _POLICY_COLLECTION_H_ */ diff --git a/worker/worker.c b/worker/worker.c index bb6860f..7d72f22 100644 --- a/worker/worker.c +++ b/worker/worker.c @@ -22,6 +22,7 @@ #include "helpers.h" #include "util.h" #include "xml_helper.h" +#include "policy_collection.h" #ifdef WITH_SSSD #include "sbus_client.h" #endif @@ -33,9 +34,13 @@ int main(int argc, const char *argv[]) int opt_once=0; int opt; int opt_check; + int poli_c; + int file_c; poptContext pc; char *policy_file_name=NULL; int ret=0; + struct policy_collection *pc_array; + struct poptOption long_options[] = { POPT_AUTOHELP @@ -93,6 +98,21 @@ int main(int argc, const char *argv[]) setup_xml_search_path("../policy_metadata/"); if ( policy_file_name != NULL ) { + load_policy_collection("policy_collection_example.xml", &pc_array); + + poli_c=0; + while (pc_array[poli_c].name != NULL) { + DEBUG(3,("Schema name for policy collection #%d: %s\n",poli_c, pc_array[poli_c].name)); + + file_c=0; + while (pc_array[poli_c].files[file_c] != NULL) { + DEBUG(3,(" policy file: %s\n",pc_array[poli_c].files[file_c])); + file_c++; + } + poli_c++; + } + + ret=process_policy(policy_file_name); if ( ret == -1 ) { DEBUG(0,("Invalid policy, aborting.\n")); @@ -110,6 +130,7 @@ int main(int argc, const char *argv[]) } cleanup: + free_policy_collection(&pc_array); free_xml_search_path(); free(policy_file_name); diff --git a/worker/xml_helper.c b/worker/xml_helper.c index bf6672e..1680d3b 100644 --- a/worker/xml_helper.c +++ b/worker/xml_helper.c @@ -38,7 +38,7 @@ /* If a default namespace is defined * * IMPORTANT: XPath 1.0 has no concept of a default namespace. Unprefixed - * names in XPath only match names which have no namespace. So, if the + * names in XPath only match names which have no namespace. So, if the * document uses a default namespace, it is required to associate a non-empty * prefix with the default namespace via register-namespace and add that * prefix to names in XPath expressions intended to match nodes in the default @@ -46,10 +46,54 @@ */ xmlChar *default_namespace_prefix = (xmlChar *) "def"; + +/** + * \brief Validate a XML document with the help of an RELAX NG file + * + * An already parsed XML ducument can be validated against a RELAX NG schema + * file. + * + * \param doc pointer to the already parsed XML document + * \param rng_file_name the name of the RELAX NG shcema file + * + * \return 0 if the XML document is valid with respect to the RELAX NG schema + * file, -1 if an error occured or the document is not valid. + * + */ +int validate_with_rng(xmlDocPtr doc, const char *rng_file_name) { + int ret=-1; + + xmlRelaxNGParserCtxtPtr rng_parser_context=NULL; + xmlRelaxNGPtr rng_schema=NULL; + xmlRelaxNGValidCtxtPtr rng_context=NULL; + + rng_parser_context = xmlRelaxNGNewParserCtxt(rng_file_name); + + CHECK(rng_parser_context, NULL, ("Failed to parse RNG file\n"), goto cleanup); + rng_schema = xmlRelaxNGParse(rng_parser_context); + CHECK(rng_schema, NULL, ("Failed to create RNG schema\n"), goto cleanup); + rng_context = xmlRelaxNGNewValidCtxt(rng_schema); + CHECK(rng_context, NULL, ("Failed to create RNG context\n"), goto cleanup); + if (xmlRelaxNGValidateDoc(rng_context, doc) == 0) { + DEBUG(3, ("The document is valid.\n")); + ret=0; + } else { + DEBUG(0, ("Error during validation.\n")); + goto cleanup; + } + +cleanup: + xmlRelaxNGFreeValidCtxt(rng_context); + xmlRelaxNGFree(rng_schema); + xmlRelaxNGFreeParserCtxt(rng_parser_context); + + return ret; +} + /** * \brief Validate a XML policy file * - * Call this function bedore any further processing of a XML policy file. It + * Call this function before any further processing of a XML policy file. It * will extract the name of the RELAX NG schema file from the metadata section * together with other information and validate the file accordingly. * @@ -65,11 +109,9 @@ xmlChar *default_namespace_prefix = (xmlChar *) "def"; */ int validate_policy(const char *policy_file_name, char **ipa_policy_type, char **xslt_file_name) { + int ret; xmlDocPtr doc=NULL; char *rng_file_name=NULL; - xmlRelaxNGParserCtxtPtr rng_parser_context=NULL; - xmlRelaxNGPtr rng_schema=NULL; - xmlRelaxNGValidCtxtPtr rng_context=NULL; xmlChar xpath_expr[XMLCHARLEN]; doc = xmlParseFile(policy_file_name); @@ -82,21 +124,8 @@ int validate_policy(const char *policy_file_name, char **ipa_policy_type, char * CHECK(rng_file_name, NULL, ("Name of RELANX NG schema file not found.\n"), goto failed); DEBUG(3, ("Found name of RELAX NG schema file: %s\n", rng_file_name)); - - /* validate the document */ - rng_parser_context = xmlRelaxNGNewParserCtxt(rng_file_name); - CHECK(rng_parser_context, NULL, ("Failed to parse RNG file\n"), goto failed); - rng_schema = xmlRelaxNGParse(rng_parser_context); - CHECK(rng_schema, NULL, ("Failed to create RNG schema\n"), goto failed); - rng_context = xmlRelaxNGNewValidCtxt(rng_schema); - CHECK(rng_context, NULL, ("Failed to create RNG context\n"), goto failed); - if (xmlRelaxNGValidateDoc(rng_context, doc) == 0) { - DEBUG(3, ("The document is valid.\n")); - } else { - DEBUG(0, ("Error during validation.\n")); - goto failed; - } - + ret=validate_with_rng(doc, rng_file_name); + CHECK(ret, -1, ("Validation failed for %s\n", policy_file_name), goto failed); xmlStrPrintf(xpath_expr, XMLCHARLEN, (xmlChar *) "//%s:ipa/*[2]", default_namespace_prefix); @@ -118,9 +147,6 @@ int validate_policy(const char *policy_file_name, char **ipa_policy_type, char * DEBUG(3, ("Found name of XSLT file: %s\n", *xslt_file_name)); } - xmlRelaxNGFreeValidCtxt(rng_context); - xmlRelaxNGFree(rng_schema); - xmlRelaxNGFreeParserCtxt(rng_parser_context); free(rng_file_name); xmlFreeDoc(doc); @@ -128,9 +154,6 @@ int validate_policy(const char *policy_file_name, char **ipa_policy_type, char * return 0; failed: - xmlRelaxNGFreeValidCtxt(rng_context); - xmlRelaxNGFree(rng_schema); - xmlRelaxNGFreeParserCtxt(rng_parser_context); free(rng_file_name); xmlFreeDoc(doc); |