summaryrefslogtreecommitdiffstats
path: root/worker/ipaaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'worker/ipaaction.c')
-rw-r--r--worker/ipaaction.c272
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;
+}