From 2fe09ee550be101df2a12c29eecb9c0d12a1910c Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Tue, 14 Oct 2008 12:28:54 +0200 Subject: added code to worker.c --- sudoers/worker.c | 282 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 194 insertions(+), 88 deletions(-) (limited to 'sudoers/worker.c') 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 #include #include +#include +#include +#include +#include +#include -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; inodeNr; 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; inodeNr; 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); } -- cgit