summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--selinux_booleans/selinux_booleans.xsl4
-rw-r--r--worker/util.h14
-rw-r--r--worker/worker.c269
3 files changed, 241 insertions, 46 deletions
diff --git a/selinux_booleans/selinux_booleans.xsl b/selinux_booleans/selinux_booleans.xsl
index 5da169e..7b6a01f 100644
--- a/selinux_booleans/selinux_booleans.xsl
+++ b/selinux_booleans/selinux_booleans.xsl
@@ -26,8 +26,8 @@ MA 02111-1307, USA.
xmlns:seb="http://freeipa.org/xml/rng/selinux_booleans/1.0">
<md:output_handler>
- <exec_with_args command_name="/usr/sbin/setsebool" user="root"/>
- <file name="/tmp/dummy"/>
+ <md:file md:name="/tmp/dummy"/>
+ <md:exec_with_args md:command="/usr/sbin/setsebool" md:user="root" md:group="root"/>
</md:output_handler>
<xsl:param name="output_selector"/>
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);