diff options
Diffstat (limited to 'worker/ipaaction.c')
-rw-r--r-- | worker/ipaaction.c | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/worker/ipaaction.c b/worker/ipaaction.c new file mode 100644 index 0000000..b7ef871 --- /dev/null +++ b/worker/ipaaction.c @@ -0,0 +1,272 @@ +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.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 "util.h" +#include "helpers.h" +#include "xml_helper.h" + + +int check_ipaaction_condition(const xmlDocPtr doc, const xmlChar *default_namespace) { + int ret; + char *condition; + char *user; + char *group; + 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)); + + 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)); + + arguments=strchr(condition,' '); + if (arguments!=NULL) { + *arguments++='\0'; + } + + ret=exec_command(condition, user, group, arguments, NULL); + + free(arguments); + 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; + 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)); + + 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)); + + 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, owner, group, 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) { + int ret; + char *command; + char *user; + char *group; + 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)); + + 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)); + + arguments=strchr(command,' '); + if (arguments!=NULL) { + *arguments++='\0'; + } + + ret=exec_command(command, user, group, arguments, NULL); + + free(arguments); + free(group); + free(user); + free(command); + + return ret; + + return 0; +} + +int handle_ipaaction(const char *policy_name, const xmlChar *default_namespace) { + int ret; + xmlDocPtr doc; + + doc = xmlParseFile(policy_name); + CHECK(doc, NULL, ("Cannot parse document %s!\n", policy_name), exit(1)); + + 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; + } + + xmlFreeDoc(doc); + + return 0; +} |