diff options
Diffstat (limited to 'worker')
-rw-r--r-- | worker/util.h | 14 | ||||
-rw-r--r-- | worker/worker.c | 269 |
2 files changed, 239 insertions, 44 deletions
diff --git a/worker/util.h b/worker/util.h index 618f68a..f3fee31 100644 --- a/worker/util.h +++ b/worker/util.h @@ -19,5 +19,19 @@ void debug_fn(const char *format, ...); } \ } while(0) +#define CHECK_NULL_RETURN(pointer, message) do { \ + if (pointer == NULL) { \ + DEBUG(0, message); \ + return(-1); \ + } \ +} while(0) + +#define CHECK_MINUS_ONE_RETURN(pointer, message) do { \ + if (pointer == -1) { \ + DEBUG(0, message); \ + return(-1); \ + } \ +} while(0) + #endif /* __WORKER_UTIL_H__ */ diff --git a/worker/worker.c b/worker/worker.c index 602b339..52abf5d 100644 --- a/worker/worker.c +++ b/worker/worker.c @@ -2,6 +2,16 @@ #include <string.h> #include <stdlib.h> #include <assert.h> +#include <string.h> +#include <libgen.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <pwd.h> +#include <grp.h> + + #include <libxml/tree.h> #include <libxml/parser.h> @@ -17,6 +27,7 @@ #include "util.h" #define XMLCHARLEN 255 +#define MAXSTR XMLCHARLEN /* If a default namespace is defined * * IMPORTANT: XPath 1.0 has no concept of a default namespace. Unprefixed @@ -32,12 +43,203 @@ xmlChar *default_namespace_prefix = (xmlChar *) "def"; #define XSLT_METADATA_NAMESPACE_PREFIX (xmlChar *) "md" #define XPATH_OUTPUT_HANDLER (xmlChar *) "//md:output_handler/*" -int output_handler_file(xmlNode *node) { - DEBUG(3,("Found file name '%s'.\n",xmlGetProp(node, (xmlChar *) "name"))); + +char *get_output_handler_parameter(xmlNode *node, const char *name, const char *default_value, const int required) { + char *value; + + DEBUG(3,("Search for attribute '%s'.\n",name)); + value = (char *) xmlGetProp(node, (xmlChar *) name); + if (required == 1) { + CHECK_NULL_FATAL(value, ("Cannot find required attribute '%s' for output handler.\n", name)); + DEBUG(3,("Found required attribute '%s' with value '%s'.\n",name, value)); + } else if (required == 0 ) { + if (value == NULL) { + DEBUG(3,("Optional attribute '%s' not found, using default '%s'.\n",name, default_value)); + if (default_value != NULL ) value=strdup(default_value); + } else { + DEBUG(3,("Found optional attribute '%s' with value '%s'.\n",name, value)); + } + } else { + DEBUG(0,("I am not allowed to be here, aborting ...\n")); + exit(-1); + } + + return value; +} + +int output_handler_file(xmlNode *node, const xmlDocPtr doc, const char *xslt_file_name) { + char *name; + char *owner; + char *group; + char *permission; + char *param_name; + char *param_value; + struct stat stat_buffer; + char *dir_name; + char *tmp_file_name; + char *buffer; + int ret; + int fd; + struct passwd *pwd_info; + struct group *grp_info; + xsltStylesheetPtr parsed_stylesheet = NULL; + xmlDocPtr res; + + name=get_output_handler_parameter(node, "name", NULL, 1); + + buffer=strdup(name); + CHECK_NULL_RETURN(buffer ,("strdup failed\n")); + dir_name=dirname(buffer); + if( (ret=stat(dir_name, &stat_buffer)) == -1) { + DEBUG(0,("stat on %s failed: %s\n",dir_name, strerror(errno))); + free(name); + return(-1); + } + if(!S_ISDIR(stat_buffer.st_mode)) { + DEBUG(0,("%s is not a directory!\n",dir_name)); + free(name); + return(-1); + } + free(buffer); + + if( (ret=lstat(name, &stat_buffer)) == -1) { + DEBUG(0,("stat on %s failed: %s\n",name, strerror(errno))); + free(name); + return(-1); + } + if(!S_ISREG(stat_buffer.st_mode)) { + DEBUG(0,("%s is not a regular file!\n",name)); + free(name); + return(-1); + } + + owner=get_output_handler_parameter(node, "owner", "root", 0); + pwd_info=getpwnam(owner); + CHECK_NULL_RETURN(pwd_info, ("Cannot find user %s.\n", owner)); + group=get_output_handler_parameter(node, "group", "root", 0); + grp_info=getgrnam(group); + CHECK_NULL_RETURN(grp_info, ("Cannot find group %s.\n", group)); + + permission=get_output_handler_parameter(node, "permission", "0400", 0); + param_name=get_output_handler_parameter(node, "param_name", NULL, 0); + param_value=get_output_handler_parameter(node, "param_value", NULL, 0); + + /* TODO: create backup copy */ + + tmp_file_name=(char *) malloc(strlen(name)+7); + CHECK_NULL_RETURN(tmp_file_name,("malloc failed.")); + strcpy(tmp_file_name, name); + strcat(tmp_file_name, ".XXXXXX"); + fd=mkstemp(tmp_file_name); + if (fd==-1) { + DEBUG(0,("mkstemp failed with template %s: %s\n",tmp_file_name, strerror(errno))); + free(name); + return(-1); + } + + ret=fchmod(fd, (mode_t) strtol(permission, NULL, 8)); + CHECK_MINUS_ONE_RETURN(ret, ("Cannot chmod temporary file to %s: %s\n", permission, strerror(errno))); + + ret=fchown(fd, pwd_info->pw_uid, grp_info->gr_gid); + CHECK_MINUS_ONE_RETURN(ret, ("Cannot chown temporary file to %s:%s: %s\n", owner, group, strerror(errno))); + + parsed_stylesheet = xsltParseStylesheetFile((xmlChar *) xslt_file_name); + CHECK_NULL_FATAL(parsed_stylesheet, ("Cannot parse stylesheet!\n")); + + res = xsltApplyStylesheet(parsed_stylesheet, doc, NULL); + CHECK_NULL_FATAL(res, ("Cannot apply stylesheet!\n")); + ret = xsltSaveResultToFd(fd, res, parsed_stylesheet); + if (ret == -1) { + DEBUG(0, ("Cannot save result!\n")); + exit(1); + } + xmlFreeDoc(res); + xsltFreeStylesheet(parsed_stylesheet); + + close(fd); + ret=rename(tmp_file_name, name); + CHECK_MINUS_ONE_RETURN(ret, ("Cannot rename %s to %s: %s\n", tmp_file_name, name, strerror(errno) )); + + free(tmp_file_name); + + free(name); + free(owner); + free(group); + free(permission); + free(param_name); + free(param_value); return(0); } -int output_handler_exec_with_args(xmlNode *node) { +int output_handler_exec_with_args(xmlNode *node, const xmlDocPtr doc, const char *xslt_file_name) { + char *command; + char *arguments; + char *user; + char *group; + char *param_name; + char *param_value; + int ret; + struct stat stat_buffer; + struct passwd *pwd_info; + struct group *grp_info; + xsltStylesheetPtr parsed_stylesheet = NULL; + xmlDocPtr res; + xmlChar *result_string; + int result_length; + char *cur; + char *end_of_line; + + command=get_output_handler_parameter(node, "command", NULL, 1); + + if( (ret=stat(command, &stat_buffer)) == -1) { + DEBUG(0,("stat on %s failed: %s\n",command, strerror(errno))); + free(command); + return(-1); + } + + + arguments=get_output_handler_parameter(node, "arguments", NULL, 0); + + user=get_output_handler_parameter(node, "user", "nobody", 0); + pwd_info=getpwnam(user); + CHECK_NULL_RETURN(pwd_info, ("Cannot find user %s.\n", user)); + + group=get_output_handler_parameter(node, "group", "nogroup", 0); + grp_info=getgrnam(group); + CHECK_NULL_RETURN(grp_info, ("Cannot find group %s.\n", group)); + + param_name=get_output_handler_parameter(node, "param_name", NULL, 0); + param_value=get_output_handler_parameter(node, "param_value", NULL, 0); + + parsed_stylesheet = xsltParseStylesheetFile((xmlChar *) xslt_file_name); + CHECK_NULL_FATAL(parsed_stylesheet, ("Cannot parse stylesheet!\n")); + + res = xsltApplyStylesheet(parsed_stylesheet, doc, NULL); + CHECK_NULL_FATAL(res, ("Cannot apply stylesheet!\n")); + ret = xsltSaveResultToString(&result_string, &result_length, res, parsed_stylesheet); + if (ret == -1) { + DEBUG(0, ("Cannot save result!\n")); + exit(1); + } + xmlFreeDoc(res); + xsltFreeStylesheet(parsed_stylesheet); + + cur=(char *)result_string; + DEBUG(3,("last argument to %s: |%s|\n",command, cur)); + while ( (end_of_line = strchr(cur, '\n'))!=NULL ) { + *end_of_line='\0'; + DEBUG(3,("argument to %s: |%s|\n",command, cur)); + cur=end_of_line+1; + }; + + free(result_string); + + free(command); + free(arguments); + free(user); + free(group); + free(param_name); + free(param_value); return(0); } @@ -52,12 +254,16 @@ int print_all_attributes(xmlNode *node) { return(0); } -int find_output_handler(xmlDocPtr doc) { +int find_output_handler(const xmlDocPtr doc, const char *xslt_file_name) { int i; xmlXPathContextPtr xpath_context; xmlXPathObjectPtr xpath_obj; + xmlDocPtr xslt_doc; - xpath_context = xmlXPathNewContext(doc); + xslt_doc = xmlParseFile(xslt_file_name); + CHECK_NULL_FATAL(xslt_doc, ("Cannot parse file %s!\n", xslt_file_name)); + + xpath_context = xmlXPathNewContext(xslt_doc); CHECK_NULL_FATAL(xpath_context, ("Error: unable to create new XPath context\n")); if (xmlXPathRegisterNs(xpath_context, XSLT_METADATA_NAMESPACE_PREFIX, XSLT_METADATA_NAMESPACE) != 0) { @@ -88,9 +294,9 @@ int find_output_handler(xmlDocPtr doc) { DEBUG(3, ("found output_handler: %s\n",(char *) xpath_obj->nodesetval->nodeTab[i]->name)); print_all_attributes(xpath_obj->nodesetval->nodeTab[i]); if ( xmlStrEqual(xpath_obj->nodesetval->nodeTab[i]->name, (xmlChar *) "file" )) { - output_handler_file(xpath_obj->nodesetval->nodeTab[i]); + output_handler_file(xpath_obj->nodesetval->nodeTab[i], doc, xslt_file_name); } else if ( xmlStrEqual(xpath_obj->nodesetval->nodeTab[i]->name, (xmlChar *) "exec_with_args" )) { - output_handler_exec_with_args(xpath_obj->nodesetval->nodeTab[i]); + output_handler_exec_with_args(xpath_obj->nodesetval->nodeTab[i], doc, xslt_file_name); } else { DEBUG(0, ("Unknow outout handler '%s'.\n", xpath_obj->nodesetval->nodeTab[i]->name)); xmlXPathFreeObject(xpath_obj); @@ -168,15 +374,11 @@ int main(int argc, char **argv) xmlChar xpath_expr[XMLCHARLEN]; char *rng_file_name; char *xslt_file_name; - char *output_file_name; - char *output_file_owner; - char *output_file_group; - char *output_file_permission; xmlRelaxNGValidCtxtPtr rng_context; xmlDocPtr xslt_doc; - xsltStylesheetPtr cur = NULL; - xmlDocPtr res; - int ret; +// xsltStylesheetPtr parsed_stylesheet = NULL; +// xmlDocPtr res; +// int ret; if (argc != 2) { DEBUG(0, @@ -243,44 +445,23 @@ int main(int argc, char **argv) xslt_doc = xmlParseFile(xslt_file_name); CHECK_NULL_FATAL(xslt_doc, ("Cannot parse file %s!\n", xslt_file_name)); - find_output_handler(xslt_doc); - output_file_name = - find_value_by_xpath(xslt_doc, - (xmlChar *) "//md:output_handler/md:file/@md:name", - (xmlChar *) "md", - (xmlChar *) "http://freeipa.org/xsl/metadata/1.0"); - output_file_owner = - find_value_by_xpath(xslt_doc, - (xmlChar *) "//md:output_handler/md:file/@md:owner", - (xmlChar *) "md", - (xmlChar *) "http://freeipa.org/xsl/metadata/1.0"); - output_file_group = - find_value_by_xpath(xslt_doc, - (xmlChar *) "//md:output_handler/md:file/@md:group", - (xmlChar *) "md", - (xmlChar *) "http://freeipa.org/xsl/metadata/1.0"); - output_file_permission = find_value_by_xpath(xslt_doc, (xmlChar *) - "//md:output_handler/md:file/@md:permission", - (xmlChar *) "md", (xmlChar *) - "http://freeipa.org/xsl/metadata/1.0"); - DEBUG(0, ("-%s-\n", output_file_name)); - DEBUG(0, ("-%s-\n", output_file_owner)); - DEBUG(0, ("-%s-\n", output_file_group)); - DEBUG(0, ("-%s-\n", output_file_permission)); - - cur = xsltParseStylesheetDoc(xslt_doc); - CHECK_NULL_FATAL(cur, ("Cannot parse stylesheet %s!\n", xslt_file_name)); - res = xsltApplyStylesheet(cur, doc, NULL); + find_output_handler(doc, xslt_file_name); + +/* + parsed_stylesheet = xsltParseStylesheetDoc(xslt_doc); + CHECK_NULL_FATAL(parsed_stylesheet, ("Cannot parse stylesheet %s!\n", xslt_file_name)); + res = xsltApplyStylesheet(parsed_stylesheet, doc, NULL); CHECK_NULL_FATAL(xslt_doc, ("Cannot apply stylesheet %s!\n", xslt_file_name)); - ret = xsltSaveResultToFile(stdout, res, cur); + ret = xsltSaveResultToFile(stdout, res, parsed_stylesheet); if (ret == -1) { DEBUG(0, ("Cannot save result!\n")); exit(1); } xmlFreeDoc(res); - xsltFreeStylesheet(cur); + xsltFreeStylesheet(parsed_stylesheet); +*/ free(xslt_file_name); xmlFreeDoc(doc); |