diff options
Diffstat (limited to 'worker/worker.c')
-rw-r--r-- | worker/worker.c | 909 |
1 files changed, 33 insertions, 876 deletions
diff --git a/worker/worker.c b/worker/worker.c index efd7706..85430bd 100644 --- a/worker/worker.c +++ b/worker/worker.c @@ -1,818 +1,42 @@ +/** + * Author: Sumit Bose <sbose@redhat.com> + * + * Copyright (C) 2008 Red Hat + * + * 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; version 2 only + * + * 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 Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; see the file COPYING.LGPL. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + #define _GNU_SOURCE -#include <stdio.h> #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 <sys/wait.h> - - - -#include <libxml/tree.h> -#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> - -#include <curl/curl.h> - -#include <selinux/selinux.h> -#include <selinux/context.h> +#include "helpers.h" #include "util.h" +#include "xml_helper.h" +#include "ipaaction.h" +#include "output_handler.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 - * 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 *default_namespace_prefix = (xmlChar *) "def"; - -#define XSLT_METADATA_NAMESPACE (xmlChar *) "http://freeipa.org/xsl/metadata/1.0" -#define XSLT_METADATA_NAMESPACE_PREFIX (xmlChar *) "md" -#define XPATH_OUTPUT_HANDLER (xmlChar *) "//md:output_handler/md:*" - -int open_temporary_file(char *name, const char *permission, const uid_t uid, const gid_t gid, const char *selinux_context_string) { - int fd; - int ret; - - fd=mkstemp(name); - if (fd==-1) { - DEBUG(0,("mkstemp failed with template %s: %s\n",name, strerror(errno))); - return -1; - } - - ret=fchmod(fd, (mode_t) strtol(permission, NULL, 8)); - CHECK(ret, -1, ("Cannot chmod temporary file to %s: %s\n", permission, strerror(errno)), return -1); - - ret=fchown(fd, uid, gid); - CHECK(ret, -1, ("Cannot chown temporary file to uid %d and gid %d: %s\n", uid, gid, strerror(errno)), return -1); - - if (selinux_context_string != NULL ) { - - ret=fsetfilecon(fd, (security_context_t ) selinux_context_string); - CHECK(ret, -1, ("fsetfilecon failed: %s\n",strerror(errno)), return -1); - - } - - return fd; -} - -int exec_command(const char *command, const uid_t uid, const gid_t gid, char *arguments, char *extra_args) { - char *argv[10]; /* FIXME */ - int c=0; - int i; - char *cur; - char *next_arg; - pid_t pid; - int ret; - int status; - int stdout_pipe[2]; - int stderr_pipe[2]; - char buffer[255]; - - argv[c++]=strdup(command); - if (arguments!=NULL) { - cur=arguments; - while( (next_arg=strchr(cur, ' '))!=NULL) { - argv[c++]=strndup(cur, next_arg-cur); - cur=next_arg+1; - } - argv[c++]=strdup(cur); - } - if (extra_args!=NULL) { - cur=extra_args; - while( (next_arg=strchr(cur, ' '))!=NULL) { - argv[c++]=strndup(cur, next_arg-cur); - cur=next_arg+1; - } - argv[c++]=strdup(cur); - } - argv[c++]=NULL; - - for(i=0;i<c;i++){ - DEBUG(3,("argument array element %d: |%s|\n",i, argv[i])); - } - - ret=pipe(stdout_pipe); - CHECK(ret, -1, ("pipe failed: %s\n",strerror(errno)), return -1); - ret=pipe(stderr_pipe); - CHECK(ret, -1, ("pipe failed: %s\n",strerror(errno)), return -1); - - pid=fork(); - CHECK(pid, -1, ("fork failed: %s",strerror(errno)), return -1); - if (!pid) { /* FIXME: missing error checking */ - - close(stdout_pipe[0]); - close(stderr_pipe[0]); - - ret=dup2(stdout_pipe[1], STDOUT_FILENO); - CHECK(ret, -1, ("dup2 failed: %s\n",strerror(errno)), exit(1)); - ret=dup2(stderr_pipe[1], STDERR_FILENO); - CHECK(ret, -1, ("dup2 failed: %s\n",strerror(errno)), exit(1)); - close(STDIN_FILENO); - - ret=chdir("/"); - CHECK(ret, -1, ("chdir to / failed: %s\n",strerror(errno)), exit(1)); - ret=setgid(gid); - CHECK(ret, -1, ("setgid failed: %s\n",strerror(errno)), exit(1)); - ret=setuid(uid); - CHECK(ret, -1, ("setuid failed: %s\n",strerror(errno)), exit(1)); - - execv(command, argv); - } - - close(stdout_pipe[1]); - close(stderr_pipe[1]); - - *buffer='\0'; - ret=read(stdout_pipe[0], &buffer, 255); - buffer[ret]='\0'; - DEBUG(3,("stdout from child: >>%s<<\n",buffer)); - *buffer='\0'; - ret=read(stderr_pipe[0], &buffer, 255); - buffer[ret]='\0'; - DEBUG(3,("stderr from child: >>%s<<\n",buffer)); - - ret = waitpid(pid, & status, 0); - if (WIFEXITED(status)) { - DEBUG(3,("Child terminated normally with exit status %d\n",WEXITSTATUS(status))); - } else { - DEBUG(1,("Child terminated not normally.\n")); - } - - - for(i=0;i<c;i++){ - free(argv[i]); - } - return WEXITSTATUS(status); -} - -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"); - open_temporary_file(tmp_file_name, permission, pwd_info->pw_uid, grp_info->gr_gid, NULL); - /* - 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, 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", "nobody", 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; - while ( (end_of_line = strchr(cur, '\n'))!=NULL ) { - *end_of_line='\0'; - DEBUG(3,("found argument to %s: |%s|\n",command, cur)); - ret=exec_command(command, pwd_info->pw_uid, grp_info->gr_gid, arguments, cur); - DEBUG(3,("exec_command retrun value: %d\n",ret)); - cur=end_of_line+1; - }; - - free(result_string); - - free(command); - free(arguments); - free(user); - free(group); - free(param_name); - free(param_value); - return 0; -} - -int print_all_attributes(xmlNode *node) { - xmlAttr *cur; - - cur=node->properties; - while(cur!=NULL) { - DEBUG(3, ("found attribute '%s' with value '%s'.\n", cur->name, XML_GET_CONTENT(cur->children))); - cur=cur->next; - } - return 0; -} - -int find_output_handler(const xmlDocPtr doc, const char *xslt_file_name) { - int i; - xmlXPathContextPtr xpath_context; - xmlXPathObjectPtr xpath_obj; - xmlDocPtr xslt_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) { - DEBUG(0, - ("Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", - XSLT_METADATA_NAMESPACE_PREFIX, XSLT_METADATA_NAMESPACE)); - xmlXPathFreeContext(xpath_context); - return (0); - } - - xpath_obj = xmlXPathEvalExpression(XPATH_OUTPUT_HANDLER, xpath_context); - if (xpath_obj == NULL) { - DEBUG(0, - ("Error: unable to evaluate xpath expression \"%s\"\n", - XPATH_OUTPUT_HANDLER)); - xmlXPathFreeContext(xpath_context); - return (0); - } - - if (xmlXPathNodeSetIsEmpty(xpath_obj->nodesetval)) { - DEBUG(0, ("Nothing found for %s\n", XPATH_OUTPUT_HANDLER)); - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return (0); - } - - for (i=0; i<xmlXPathNodeSetGetLength(xpath_obj->nodesetval); i++) { - 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], 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], doc, xslt_file_name); - } else { - DEBUG(0, ("Unknow outout handler '%s'.\n", xpath_obj->nodesetval->nodeTab[i]->name)); - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return (-1); - } - } - - - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return 0; -} - -char *find_name_by_xpath(xmlDocPtr doc, xmlChar * xpath_expr, xmlChar * prefix, - xmlChar * namespace) -{ - - xmlXPathContextPtr xpath_context; - xmlXPathObjectPtr xpath_obj; - char *result = NULL; - - /* Create xpath evaluation context */ - xpath_context = xmlXPathNewContext(doc); - CHECK_NULL_FATAL(xpath_context, - ("Error: unable to create new XPath context\n")); - /* Register a namespace */ - if (xmlXPathRegisterNs(xpath_context, prefix, namespace) != 0) { - DEBUG(0, - ("Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", - prefix , namespace)); - xmlXPathFreeContext(xpath_context); - return (NULL); - } - /* Evaluate xpath expression */ - xpath_obj = xmlXPathEvalExpression(xpath_expr, xpath_context); - if (xpath_obj == NULL) { - DEBUG(0, - ("Error: unable to evaluate xpath expression \"%s\"\n", - xpath_expr)); - xmlXPathFreeContext(xpath_context); - return (NULL); - } - - if (xmlXPathNodeSetIsEmpty(xpath_obj->nodesetval)) { - DEBUG(0, ("Nothing found for %s\n", xpath_expr)); - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return (NULL); - } else if (xmlXPathNodeSetGetLength(xpath_obj->nodesetval) != 1) { - DEBUG(0, ("More than one node found for %s!", xpath_expr)); - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return (NULL); - } else { - result = strdup((char *) xpath_obj->nodesetval->nodeTab[0]->name); - } - - - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return result; - -} - -char *find_value_by_xpath(const xmlDocPtr doc, const xmlChar * xpath_expr, const xmlChar * prefix, - const xmlChar * namespace) -{ - - xmlXPathContextPtr xpath_context; - xmlXPathObjectPtr xpath_obj; - char *result = NULL; - - /* Create xpath evaluation context */ - xpath_context = xmlXPathNewContext(doc); - CHECK_NULL_FATAL(xpath_context, - ("Error: unable to create new XPath context\n")); - /* Register a namespace */ - if (xmlXPathRegisterNs(xpath_context, prefix, namespace) != 0) { - DEBUG(0, - ("Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", - prefix , namespace)); - xmlXPathFreeContext(xpath_context); - return (NULL); - } - /* Evaluate xpath expression */ - xpath_obj = xmlXPathEvalExpression(xpath_expr, xpath_context); - if (xpath_obj == NULL) { - DEBUG(0, - ("Error: unable to evaluate xpath expression \"%s\"\n", - xpath_expr)); - xmlXPathFreeContext(xpath_context); - return (NULL); - } - - if (xmlXPathNodeSetIsEmpty(xpath_obj->nodesetval)) { - DEBUG(0, ("Nothing found for %s\n", xpath_expr)); - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return (NULL); - } else if (xmlXPathNodeSetGetLength(xpath_obj->nodesetval) != 1) { - DEBUG(0, ("More than one node found for %s!", xpath_expr)); - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return (NULL); - } else { - result = - (char *) xmlNodeListGetString(doc, - xpath_obj->nodesetval->nodeTab[0]-> - xmlChildrenNode, 1); - } - - - xmlXPathFreeObject(xpath_obj); - xmlXPathFreeContext(xpath_context); - return result; - -} - -int check_ipaaction_condition(const xmlDocPtr doc, const xmlChar *default_namespace) { - char *condition; - char *user; - char *group; - struct passwd *pwd_info; - struct group *grp_info; - int ret; - char *arguments; - - condition = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:condition/def:command", - default_namespace_prefix, default_namespace); - if ( condition==NULL ) { - DEBUG(3, ("No condition found for current ipaaction.\n")); - return 0; - } - DEBUG(3, ("Found condition for current ipaaction: |%s|\n", condition)); - - user = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:condition/def:user", - default_namespace_prefix, default_namespace); - if (user==NULL) { - DEBUG(3, ("User for condition not found, using default")); - user=strdup("nobody"); - } - DEBUG(3, ("Found user for condition: %s\n", user)); - pwd_info=getpwnam(user); - CHECK(pwd_info, NULL, ("Cannot find user %s.\n", user), return -1); - - group = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:condition/def:group", - default_namespace_prefix, default_namespace); - if (group==NULL) { - DEBUG(3, ("Group for condition not found, using default\n")); - group=strdup("nobody"); - } - DEBUG(3, ("Found group for condition: %s\n", group)); - grp_info=getgrnam(group); - CHECK(grp_info, NULL, ("Cannot find group %s.\n", group), return -1); - - arguments=strchr(condition,' '); - if (arguments!=NULL) { - *arguments++='\0'; - } - - ret=exec_command(condition, pwd_info->pw_uid, grp_info->gr_gid, arguments, NULL); - - free(group); - free(user); - free(condition); - - return ret; -} - -int ipaaction_file(const xmlDocPtr doc, const xmlChar *default_namespace) { - char *url; - char *data; - char *path; - char *owner; - char *group; - char *access; - char *selinux_context; - //char **acl; - char *cleanup; - struct passwd *pwd_info; - struct group *grp_info; - CURL *curl_context; - CURLcode curl_result; - char *tmp_file_name; - FILE *output_file; - int fd; - int ret; - struct stat stat_buffer; - - url = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:file/def:url", - default_namespace_prefix, default_namespace); - DEBUG(3, ("Found the following ipaaction file url: |%s|\n", url)); - data = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:file/def:data", - default_namespace_prefix, default_namespace); - DEBUG(3, ("Found the following ipaaction file data: |%s|\n", data)); - if (url==NULL && data==NULL) { - DEBUG(0,("Found no url or data element for ipaaction file. This should never happen.\n")); - return -1; - } - if (url!=NULL && data!=NULL) { - DEBUG(0,("Only url or data element are allowed for ipaaction file, not both. This should never happen.\n")); - return -1; - } - - path = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:file/def:path", - default_namespace_prefix, default_namespace); - CHECK(path, NULL, ("Path for ipaaction file not found.\n"), return -1); - DEBUG(3, ("Found path for ipaaction file: %s\n", path)); - ret=stat(path, &stat_buffer); - CHECK(ret, 0, ("Destination file %s alread exists.\n", path), return -1); - - owner = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:file/def:owner", - default_namespace_prefix, default_namespace); - if (owner==NULL) { - DEBUG(3, ("Owner for ipaaction file not found, using default\n")); - owner=strdup("root"); - } - DEBUG(3, ("Found owner for ipaaction file: %s\n", owner)); - pwd_info=getpwnam(owner); - CHECK(pwd_info, NULL, ("Cannot find user %s.\n", owner), return -1); - - group = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:file/def:group", - default_namespace_prefix, default_namespace); - if (group==NULL) { - DEBUG(3, ("Group for ipaaction file not found, using default\n")); - group=strdup("root"); - } - DEBUG(3, ("Found group for ipaaction file: %s\n", group)); - grp_info=getgrnam(group); - CHECK(grp_info, NULL, ("Cannot find group %s.\n", group), return -1); - - access = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:file/def:access", - default_namespace_prefix, default_namespace); - if (access==NULL) { - DEBUG(3, ("Access permissions for ipaaction file not found, using default\n")); - group=strdup("0400"); - } - DEBUG(3, ("Found access permissions for ipaaction file: %s\n", access)); - - selinux_context = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:file/def:selinux_context", - default_namespace_prefix, default_namespace); - if (selinux_context==NULL) { - DEBUG(3, ("SELinux file context for ipaaction file not found, using none\n")); - selinux_context=NULL; - } - DEBUG(3, ("Found SELinux file context for ipaaction file: %s\n", selinux_context)); - - cleanup = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:file/def:cleanup", - default_namespace_prefix, default_namespace); - if (cleanup==NULL) { - DEBUG(3, ("No cleanup information for ipaaction file not found, assuming no\n")); - cleanup=strdup("no"); - } - DEBUG(3, ("Found cleanup information for ipaaction file: %s\n", cleanup)); - - - tmp_file_name=(char *) malloc(strlen(path)+7); - CHECK(tmp_file_name,NULL, ("malloc failed."), return -1); - strcpy(tmp_file_name, path); - strcat(tmp_file_name, ".XXXXXX"); - fd=open_temporary_file(tmp_file_name, access, pwd_info->pw_uid, grp_info->gr_gid, selinux_context); - CHECK(fd, -1, ("Failed to open temporary file.\n"), return -1); - output_file=fdopen(fd,"w"); - CHECK(output_file, NULL, ("fdopen failed: %s\n", strerror(errno)), return -1); - if (url!=NULL) { - curl_context=curl_easy_init(); - CHECK(curl_context, NULL, ("curl_easy_init failed.\n"), return -1); - curl_result=curl_easy_setopt(curl_context, CURLOPT_URL, url); - DEBUG(3,("curl result: %d\n",curl_result)); - curl_result=curl_easy_setopt(curl_context, CURLOPT_WRITEDATA, output_file); - DEBUG(3,("curl result: %d\n",curl_result)); - - curl_result=curl_easy_perform(curl_context); - DEBUG(3,("curl result: %d\n",curl_result)); - - curl_easy_cleanup(curl_context); - } - - fclose(output_file); /* this should close fd, too */ - ret=rename(tmp_file_name, path); - CHECK_MINUS_ONE_RETURN(ret, ("Cannot rename %s to %s: %s\n", tmp_file_name, path, strerror(errno) )); - free(tmp_file_name); - - return 0; -} - -int ipaaction_run(const xmlDocPtr doc, const xmlChar *default_namespace) { - char *command; - char *user; - char *group; - struct passwd *pwd_info; - struct group *grp_info; - int ret; - char *arguments; - - command = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:run/def:command", - default_namespace_prefix, default_namespace); - CHECK(command, NULL, - ("No command in ipaaction run section found, this should neven happen.\n"), - return -1); - DEBUG(3, ("Found command for current ipaaction: |%s|\n", command)); - - user = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:run/def:user", - default_namespace_prefix, default_namespace); - if (user==NULL) { - DEBUG(3, ("User for ipaaction run command not found, using default")); - user=strdup("nobody"); - } - DEBUG(3, ("Found user for ipaaction run command: %s\n", user)); - pwd_info=getpwnam(user); - CHECK(pwd_info, NULL, ("Cannot find user %s.\n", user), return -1); - - group = find_value_by_xpath(doc, - (xmlChar *) "//def:ipa/def:ipaaction/def:run/def:group", - default_namespace_prefix, default_namespace); - if (group==NULL) { - DEBUG(3, ("Group for ipaaction run command not found, using default\n")); - group=strdup("nobody"); - } - DEBUG(3, ("Found group for ipaaction run command: %s\n", group)); - grp_info=getgrnam(group); - CHECK(grp_info, NULL, ("Cannot find group %s.\n", group), return -1); - - arguments=strchr(command,' '); - if (arguments!=NULL) { - *arguments++='\0'; - } - - ret=exec_command(command, pwd_info->pw_uid, grp_info->gr_gid, arguments, NULL); - - free(group); - free(user); - free(command); - - return ret; - - return 0; -} - -int handle_ipaaction(const xmlDocPtr doc, const xmlChar *default_namespace) { - int ret; - - ret=check_ipaaction_condition(doc, default_namespace); - if (ret!=0) { - DEBUG(0,("IPA action condition failed\n")); - return -1; - } - - ret=ipaaction_file(doc, default_namespace); - if (ret!=0) { - DEBUG(0,("IPA action file failed\n")); - return -1; - } - - ret=ipaaction_run(doc, default_namespace); - if (ret!=0) { - DEBUG(0,("IPA action run failed\n")); - return -1; - } - - return 0; -} int main(int argc, char **argv) { - xmlDocPtr doc; - xmlNodePtr root_node; xmlChar *default_namespace; - xmlChar xpath_expr[XMLCHARLEN]; - char *rng_file_name; char *xslt_file_name; - xmlRelaxNGValidCtxtPtr rng_context; - xmlDocPtr xslt_doc; char *ipa_policy_type; + char *policy_file_name; if (argc != 2) { DEBUG(0, @@ -820,89 +44,22 @@ int main(int argc, char **argv) exit(1); } - doc = xmlParseFile(argv[1]); - CHECK_NULL_FATAL(doc, ("Cannot parse document %s!\n", argv[1])); - - /* find the default namespace */ - root_node = xmlDocGetRootElement(doc); - CHECK_NULL_FATAL(root_node, - ("Cannot find root node of document %s!\n", argv[1])); - if (xmlStrncasecmp(root_node->name, (xmlChar *) "IPA", XMLCHARLEN) != 0) { - DEBUG(0, - ("Name of root node of document %s has to be 'ipa'!\n", argv[1])); - exit(1); - } - CHECK_NULL_FATAL(root_node->ns->href, - ("Root node of document %s must define a namespace!\n", - argv[1])); - default_namespace = xmlStrndup(root_node->ns->href, XMLCHARLEN); - CHECK_NULL_FATAL(default_namespace, ("Cannot copy namespace!\n")); - DEBUG(3, ("Default namespace of %s is %s\n", argv[1], default_namespace)); - - - xmlStrPrintf(xpath_expr, XMLCHARLEN, (xmlChar *) "//%s:ipa/*[2]", - default_namespace_prefix); - ipa_policy_type = find_name_by_xpath(doc, xpath_expr, default_namespace_prefix, default_namespace); - CHECK_NULL_FATAL(ipa_policy_type, ("Type of IPA policy not found.\n")); - DEBUG(3, ("Found IPA policy type: %s\n", ipa_policy_type)); - if ( strncmp(ipa_policy_type, "ipaconfig",9) != 0 && - strncmp(ipa_policy_type, "iparole",7) != 0 && - strncmp(ipa_policy_type, "ipaaction",9) != 0) { - DEBUG(0,("unknown IPA ploicy type\n")); - exit(1); - } - - xmlStrPrintf(xpath_expr, XMLCHARLEN, (xmlChar *) "//%s:RNGfile", - default_namespace_prefix); - rng_file_name = - find_value_by_xpath(doc, xpath_expr, default_namespace_prefix, - default_namespace); - CHECK_NULL_FATAL(rng_file_name, - ("Name of RELANX NG schema file not found.\n")); - DEBUG(3, ("Found name of RELAX NG schema file: %s\n", rng_file_name)); - - - - /* validate the document */ - rng_context = - xmlRelaxNGNewValidCtxt(xmlRelaxNGParse - (xmlRelaxNGNewParserCtxt(rng_file_name))); - CHECK_NULL_FATAL(rng_context, ("Failed to create RNG context\n")); - if (xmlRelaxNGValidateDoc(rng_context, doc) == 0) { - DEBUG(0, ("The document is valid.\n")); - } else { - DEBUG(0, ("Error during validation.\n")); - exit(1); - } - - xmlRelaxNGFreeValidCtxt(rng_context); - free(rng_file_name); + policy_file_name=strdup(argv[1]); + validate_policy(policy_file_name, &default_namespace, &ipa_policy_type, &xslt_file_name); if ( strncmp( ipa_policy_type, "ipaaction", 9)==0) { - handle_ipaaction(doc, default_namespace); + handle_ipaaction(policy_file_name, default_namespace); } else { - xmlStrPrintf(xpath_expr, XMLCHARLEN, (xmlChar *) "//%s:XSLTfile", - default_namespace_prefix); - xslt_file_name = - find_value_by_xpath(doc, xpath_expr, default_namespace_prefix, - default_namespace); - CHECK_NULL_FATAL(xslt_file_name, ("Name of XSLT file not found.\n")); - DEBUG(3, ("Found name of XSLT file: %s\n", xslt_file_name)); - - /* read the xslt file */ - xslt_doc = xmlParseFile(xslt_file_name); - CHECK_NULL_FATAL(xslt_doc, ("Cannot parse file %s!\n", xslt_file_name)); - find_output_handler(doc, xslt_file_name); + find_output_handler(policy_file_name, xslt_file_name); free(xslt_file_name); } - xmlFreeDoc(doc); - + free(ipa_policy_type); + free(default_namespace); + free(policy_file_name); - - - return (0); + return 0; } |