summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@nb.localdomain>2008-10-14 12:28:54 +0200
committerSumit Bose <sbose@nb.localdomain>2008-10-14 12:28:54 +0200
commit2fe09ee550be101df2a12c29eecb9c0d12a1910c (patch)
tree448d63904c622664a136322e6e823ab157341d58
parent1cde6f5091e98765e0f936b96e88b0e0c15ff4aa (diff)
downloadipa_policy-2fe09ee550be101df2a12c29eecb9c0d12a1910c.tar.gz
ipa_policy-2fe09ee550be101df2a12c29eecb9c0d12a1910c.tar.xz
ipa_policy-2fe09ee550be101df2a12c29eecb9c0d12a1910c.zip
added code to worker.c
-rw-r--r--sudoers/Makefile4
-rw-r--r--sudoers/worker.c282
2 files changed, 196 insertions, 90 deletions
diff --git a/sudoers/Makefile b/sudoers/Makefile
index e3866ab..1e7c6cf 100644
--- a/sudoers/Makefile
+++ b/sudoers/Makefile
@@ -1,5 +1,5 @@
-CFLAGS=`xml2-config --cflags`
-LDFLAGS=`xml2-config --libs`
+CFLAGS=-Wall `xml2-config --cflags` `xslt-config --cflags`
+LDFLAGS=`xml2-config --libs` `xslt-config --libs`
worker: worker.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+
diff --git a/sudoers/worker.c b/sudoers/worker.c
index 3d5d637..492fa91 100644
--- a/sudoers/worker.c
+++ b/sudoers/worker.c
@@ -7,100 +7,206 @@
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
+#include <libxml/relaxng.h>
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
-int main(int argc, char **argv) {
-
- int i;
- xmlChar *str;
- xmlDocPtr doc;
- xmlXPathContextPtr xpathCtx;
- xmlXPathObjectPtr xpathObj;
+#define XMLCHARLEN 255
/* 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 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 namespace.
*/
- xmlChar *xpathExpr_rng = (xmlChar *) "//su:RNGfile";
- xmlChar *xpathExpr_xslt = (xmlChar *) "//su:XSLTfile";
- xmlNodeSetPtr nodeset;
-
- if (argc!=2) {
- fprintf(stderr, "missing or to many arguments, I expect a single filename!\n");
- exit(1);
- }
-
- doc = xmlParseFile(argv[1]);
- if (doc==NULL) {
- fprintf(stderr, "Cannot parse document %s!\n", argv[1]);
- exit(1);
- }
-
- /* Create xpath evaluation context */
- xpathCtx = xmlXPathNewContext(doc);
- if(xpathCtx == NULL) {
- fprintf(stderr,"Error: unable to create new XPath context\n");
- xmlFreeDoc(doc);
- exit(1);
- }
-
-
- /* Register a namespace */
- if(xmlXPathRegisterNs(xpathCtx, "su", "http://freeipa.org/xml/rng/sudo/sudoers/1.0") != 0) {
- fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", "", "http://freeipa.org/xml/rng/sudo/sudoers/1.0");
- xmlXPathFreeContext(xpathCtx);
- xmlFreeDoc(doc);
- exit(1);
- }
-
-
- /* Evaluate xpath expression */
- xpathObj = xmlXPathEvalExpression(xpathExpr_xslt, xpathCtx);
- if(xpathObj == NULL) {
- fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr_xslt);
- xmlXPathFreeContext(xpathCtx);
- xmlFreeDoc(doc);
- return(-1);
- }
-
- if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
- printf("Nothing found ...\n");
- } else {
- nodeset=xpathObj->nodesetval;
- for(i=0; i<nodeset->nodeNr; i++) {
- str = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
- printf("--%s--\n", str);
- xmlFree(str);
- }
- }
- /* Evaluate xpath expression */
- xpathObj = xmlXPathEvalExpression(xpathExpr_rng, xpathCtx);
- if(xpathObj == NULL) {
- fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr_rng);
- xmlXPathFreeContext(xpathCtx);
- xmlFreeDoc(doc);
- return(-1);
- }
-
- if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
- printf("Nothing found ...\n");
- } else {
- nodeset=xpathObj->nodesetval;
- for(i=0; i<nodeset->nodeNr; i++) {
- str = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
- printf("--%s--\n", str);
- xmlFree(str);
- }
- }
-
- /* Cleanup */
- xmlXPathFreeObject(xpathObj);
- xmlXPathFreeContext(xpathCtx);
- xmlFreeDoc(doc);
-
-
-
-
- return(0);
+xmlChar *default_namespace_prefix = (xmlChar *) "def";
+
+char * find_value_by_xpath(xmlDocPtr doc, xmlChar * xpathExpr, xmlChar *prefix, xmlChar * namespace)
+{
+
+ xmlXPathContextPtr xpathCtx;
+ xmlXPathObjectPtr xpathObj;
+ char *result=NULL;
+ xmlNodeSetPtr nodeset;
+ int i;
+ xmlChar *str;
+
+ /* Create xpath evaluation context */
+ xpathCtx = xmlXPathNewContext(doc);
+ if (xpathCtx == NULL) {
+ fprintf(stderr, "Error: unable to create new XPath context\n");
+ return(NULL);
+ }
+
+
+ /* Register a namespace */
+ if (xmlXPathRegisterNs (xpathCtx, prefix, namespace) != 0) {
+ fprintf(stderr,
+ "Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n",
+ "my", namespace);
+ xmlXPathFreeContext(xpathCtx);
+ return(NULL);
+ }
+ /* Evaluate xpath expression */
+ xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
+ if (xpathObj == NULL) {
+ fprintf(stderr,
+ "Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr);
+ xmlXPathFreeContext(xpathCtx);
+ return(NULL);
+ }
+
+ if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
+ printf("Nothing found ...\n");
+ xmlXPathFreeObject(xpathObj);
+ xmlXPathFreeContext(xpathCtx);
+ return(NULL);
+ } else if (xmlXPathNodeSetGetLength(xpathObj->nodesetval) != 1 ) {
+ fprintf(stderr,"More than one node found!");
+ xmlXPathFreeObject(xpathObj);
+ xmlXPathFreeContext(xpathCtx);
+ return(NULL);
+ } else {
+ nodeset = xpathObj->nodesetval;
+/* FIXME: only allow one found value */
+ for (i = 0; i < nodeset->nodeNr; i++) {
+ str = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
+ result = strdup((char *) str);
+ xmlFree(str);
+ }
+ }
+
+
+ xmlXPathFreeObject(xpathObj);
+ xmlXPathFreeContext(xpathCtx);
+ return result;
+
+}
+
+int main(int argc, char **argv)
+{
+
+ xmlDocPtr doc;
+ xmlNodePtr rootNode;
+ xmlChar *default_namespace;
+ xmlChar xpathExpr[XMLCHARLEN];
+ char *rngFileName;
+ char *xsltFileName;
+ char *output_file_name;
+ char *output_file_owner;
+ char *output_file_group;
+ char *output_file_permission;
+ xmlRelaxNGValidCtxtPtr rngCtx;
+ xmlDocPtr xsltDoc;
+ xsltStylesheetPtr cur = NULL;
+ xmlDocPtr res;
+ int ret;
+
+ if (argc != 2) {
+ fprintf(stderr,
+ "missing or to many arguments, I expect a single filename!\n");
+ exit(1);
+ }
+
+ doc = xmlParseFile(argv[1]);
+ if (doc == NULL) {
+ fprintf(stderr, "Cannot parse document %s!\n", argv[1]);
+ exit(1);
+ }
+
+ /* find the default namespace */
+ rootNode=xmlDocGetRootElement(doc);
+ if(rootNode==NULL) {
+ fprintf(stderr, "Cannot find root node of document %s!\n", argv[1]);
+ exit(1);
+ }
+ if(xmlStrncasecmp(rootNode->name,(xmlChar *) "IPA", XMLCHARLEN) != 0) {
+ fprintf(stderr, "Name of root node of document %s has to be 'ipa'!\n", argv[1]);
+ exit(1);
+ }
+ if(rootNode->ns->href==NULL) {
+ fprintf(stderr, "Root node of document %s must define a namespace!\n", argv[1]);
+ exit(1);
+ }
+ default_namespace=xmlStrndup(rootNode->ns->href,XMLCHARLEN);
+ if(default_namespace==NULL) {
+ fprintf(stderr, "Cannot copy namespace!\n");
+ exit(1);
+ }
+
+ /* extract XSTLfile and RNGfile from document using XPath */
+ xmlStrPrintf(xpathExpr, XMLCHARLEN, (xmlChar *) "//%s:XSLTfile", default_namespace_prefix);
+ xsltFileName=find_value_by_xpath(doc,xpathExpr, default_namespace_prefix, default_namespace);
+ printf("--%s--\n", xsltFileName);
+ xmlStrPrintf(xpathExpr, XMLCHARLEN, (xmlChar *) "//%s:RNGfile", default_namespace_prefix);
+ rngFileName=find_value_by_xpath(doc,xpathExpr, default_namespace_prefix, default_namespace);
+ printf("--%s--\n", rngFileName);
+
+
+
+ /* validate the document */
+ rngCtx =
+ xmlRelaxNGNewValidCtxt(xmlRelaxNGParse
+ (xmlRelaxNGNewParserCtxt(rngFileName)));
+ if (rngCtx == NULL) {
+ fprintf(stderr, "Failed to create RNG context\n");
+ exit(-1);
+ }
+
+ if (xmlRelaxNGValidateDoc(rngCtx, doc) == 0) {
+ printf("The document is valid.\n");
+ } else {
+ fprintf(stderr, "Error during validation.\n");
+ }
+
+ xmlRelaxNGFreeValidCtxt(rngCtx);
+ free(rngFileName);
+
+
+ /* read the xslt file */
+ xsltDoc = xmlParseFile(xsltFileName);
+ if (xsltDoc == NULL) {
+ fprintf(stderr, "Cannot parse file %s!\n", xsltFileName);
+ exit(1);
+ }
+
+ output_file_name=find_value_by_xpath(xsltDoc,(xmlChar *) "//md:output_file/@name",(xmlChar *) "md", (xmlChar *) "http://freeipa.org/xsl/metadata/1.0");
+ output_file_owner=find_value_by_xpath(xsltDoc,(xmlChar *) "//md:output_file/@owner",(xmlChar *) "md", (xmlChar *) "http://freeipa.org/xsl/metadata/1.0");
+ output_file_group=find_value_by_xpath(xsltDoc,(xmlChar *) "//md:output_file/@group",(xmlChar *) "md", (xmlChar *) "http://freeipa.org/xsl/metadata/1.0");
+ output_file_permission=find_value_by_xpath(xsltDoc,(xmlChar *) "//md:output_file/@permission",(xmlChar *) "md", (xmlChar *) "http://freeipa.org/xsl/metadata/1.0");
+ printf("-%s-\n",output_file_name);
+ printf("-%s-\n",output_file_owner);
+ printf("-%s-\n",output_file_group);
+ printf("-%s-\n",output_file_permission);
+
+ cur = xsltParseStylesheetDoc(xsltDoc);
+ if (cur == NULL) {
+ fprintf(stderr, "Cannot parse stylesheet %s!\n", xsltFileName);
+ exit(1);
+ }
+
+ res = xsltApplyStylesheet(cur, doc, NULL);
+ if (xsltDoc == NULL) {
+ fprintf(stderr, "Cannot apply stylesheet %s!\n", xsltFileName);
+ exit(1);
+ }
+
+ ret = xsltSaveResultToFile(stdout, res, cur);
+ if (ret == -1) {
+ fprintf(stderr, "Cannot save result!\n");
+ exit(1);
+ }
+ xmlFreeDoc(res);
+
+ xsltFreeStylesheet(cur);
+ free(xsltFileName);
+
+ xmlFreeDoc(doc);
+
+
+
+
+ return (0);
}