summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@nb.localdomain>2008-10-20 11:14:54 +0200
committerSumit Bose <sbose@nb.localdomain>2008-10-20 11:14:54 +0200
commit98824689e3f11cac83e9ee785ecd76616490d21c (patch)
tree68cc9207523a5e5e361f42edc4f4251e7be6f543
parentbc009a849c81888f45f123f3bea473df8fd494f6 (diff)
downloadipa_policy-98824689e3f11cac83e9ee785ecd76616490d21c.tar.gz
ipa_policy-98824689e3f11cac83e9ee785ecd76616490d21c.tar.xz
ipa_policy-98824689e3f11cac83e9ee785ecd76616490d21c.zip
added ipaaction example
-rw-r--r--ipaaction/ipaaction.rng89
-rw-r--r--ipaaction/ipaaction.xslt100
-rw-r--r--ipaaction/ipaaction_example_policy.xml33
-rw-r--r--sudoers/policy_metadata.rng7
-rw-r--r--sudoers/sudoers.rng5
-rw-r--r--sudoers/sudoers.xslt6
-rw-r--r--sudoers/sudoers_example_policy.xml3
-rw-r--r--worker/worker.c119
8 files changed, 308 insertions, 54 deletions
diff --git a/ipaaction/ipaaction.rng b/ipaaction/ipaaction.rng
new file mode 100644
index 0000000..983786b
--- /dev/null
+++ b/ipaaction/ipaaction.rng
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grammar ns="http://freeipa.org/xml/rng/ipaaction/1.0"
+xmlns="http://relaxng.org/ns/structure/1.0"
+datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
+xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
+xmlns:pa="http://freeipa.org/xml/rng/ns/plugable_architecture/1.0">
+
+ <a:documentation>IPA Actions</a:documentation>
+
+ <a:documentation>The following section can be used to register the RNG schema file for the UI</a:documentation>
+ <a:name>ipaaction</a:name>
+ <a:description>Handles IPA action policies</a:description>
+ <a:author>sbose@redhat.com</a:author>
+ <a:xslt>ipaaction.xsl</a:xslt>
+ <a:version>0.1</a:version>
+
+ <define name="rng_filename"><value>ipaaction.rng</value></define>
+ <define name="xslt_filename"><value>ipaaction.xslt</value></define>
+ <define name="application_name"><value>ipaaction</value></define>
+ <include href="policy_metadata.rng"/>
+
+ <start ns="http://freeipa.org/xml/rng/ipaaction/1.0">
+ <element name="ipa">
+ <a:documentation>Doc test.</a:documentation>
+
+ <ref name="policy_metadata"/>
+
+ <element name="ipaaction">
+ <oneOrMore>
+ <choice>
+ <element name="file">
+ <choice>
+ <element name="data">
+ <data type="base64Binary"/>
+ </element>
+ <element name="url">
+ <data type="anyURI"/>
+ </element>
+ </choice>
+ <element name="path">
+ <data type="string">
+ <param name="pattern">/.*</param>
+ </data>
+ </element>
+ <element name="owner">
+ <text/>
+ </element>
+ <element name="group">
+ <text/>
+ </element>
+ <element name="access">
+ <text/>
+ </element>
+ <optional>
+ <element name="selinux_context">
+ <text/>
+ </element>
+ </optional>
+ <optional>
+ <element name="condition">
+ <data type="string">
+ <param name="pattern">/.*</param>
+ </data>
+ </element>
+ </optional>
+ </element> <!-- file -->
+ <element name="run">
+ <element name="command">
+ <data type="string">
+ <param name="pattern">/.*</param>
+ </data>
+ </element>
+ <optional>
+ <element name="user">
+ <text/>
+ </element>
+ </optional>
+ <optional>
+ <element name="schedule">
+ <text/>
+ </element>
+ </optional>
+ </element> <!-- run -->
+ </choice>
+ </oneOrMore>
+ </element> <!-- ipaaction -->
+ </element> <!-- ipa -->
+ </start>
+</grammar>
diff --git a/ipaaction/ipaaction.xslt b/ipaaction/ipaaction.xslt
new file mode 100644
index 0000000..cb4be34
--- /dev/null
+++ b/ipaaction/ipaaction.xslt
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:md="http://freeipa.org/xsl/metadata/1.0"
+ xmlns:xd="http://www.pnp-software.com/XSLTdoc"
+ xmlns:ipaaction="http://freeipa.org/xml/rng/ipaaction/1.0">
+
+ <md:output_handler>
+ <xd:doc>Here we have two different kind of handlers 'download' and 'exec'.</xd:doc>
+ <download param_name="output_selector" param_value="file"/>
+ <xd:doc>TODO: we have to decide what the client application should do. It would be possible to call an external program like 'curl' or 'wget' or the call libcurl to download a file. I would vote for using 'curl' or 'libcurl' because it seem that curl supports more methods than wget. Download should be done by user nobody into a teporary file and then moved and chowned to the destination.</xd:doc>
+ <exec param_name="output_selector" param_value="run"/>
+ <xd:doc>TODO: we have to decide how the client application should call the applied program or script. If no 'user' is specifed the default user should be 'nobody'.</xd:doc>
+ </md:output_handler>
+
+ <xsl:param name="output_selector"/>
+
+ <xsl:output method="text" indent="no"/>
+ <xsl:strip-space elements="*"/>
+
+ <xsl:template match="/">
+ <xsl:text># IPA generated script for ipaaction policy. DO NOT EDIT&#xA;&#xA;</xsl:text>
+ <xsl:apply-templates select="ipaaction:ipa"/>
+ </xsl:template>
+
+ <xsl:template match="ipaaction:ipa">
+ <xsl:apply-templates>
+ <xsl:with-param name="ipaaction:ipaaction"/>
+ </xsl:apply-templates>
+ </xsl:template>
+
+ <xsl:template match="ipaaction:metadata">
+ </xsl:template>
+
+ <xsl:template match="ipaaction:ipaaction">
+ <xsl:choose>
+ <xsl:when test="$output_selector='file'">
+ <xsl:apply-templates select="ipaaction:file"/>
+ </xsl:when>
+ <xsl:when test="$output_selector='run'">
+ <xsl:apply-templates select="ipaaction:run"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text># unknown output_selector&#xA;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="ipaaction:file">
+ <xsl:choose>
+ <xsl:when test="name(./*[1])='url'">
+ <xsl:text>su - nobody 'curl -o /tmp/SAFE_TEMP_FILE </xsl:text>
+ <xsl:value-of select="ipaaction:url"/>
+ <xsl:text>'&#xA;</xsl:text>
+ </xsl:when>
+ <xsl:when test="name(./*[1])='data'">
+ <xsl:text>cat &#x3C;&#x3C; EOF | base64 -d > /tmp/SAFE_TEMP_FILE&#xA;</xsl:text>
+ <xsl:value-of select="ipaaction:data"/>
+ <xsl:text>&#xA;EOF&#xA;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text># unknown element: </xsl:text>
+ <xsl:value-of select="name(./*[1])"/>
+ <xsl:text>&#xA;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:text>mv /tmp/SAFE_TEMP_FILE </xsl:text>
+ <xsl:value-of select="ipaaction:path"/>
+ <xsl:text>&#xA;</xsl:text>
+
+ <xsl:text>chown </xsl:text>
+ <xsl:value-of select="ipaaction:owner"/>
+ <xsl:text>:</xsl:text>
+ <xsl:value-of select="ipaaction:group"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="ipaaction:path"/>
+ <xsl:text>&#xA;</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="ipaaction:run">
+ <xsl:variable name="user">
+ <xsl:choose>
+ <xsl:when test="ipaaction:user != ''">
+ <xsl:value-of select="ipaaction:user"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>nobody</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text>su - </xsl:text>
+ <xsl:value-of select="$user"/>
+ <xsl:text> '</xsl:text>
+ <xsl:value-of select="ipaaction:command"/>
+ <xsl:text>'&#xA;</xsl:text>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/ipaaction/ipaaction_example_policy.xml b/ipaaction/ipaaction_example_policy.xml
new file mode 100644
index 0000000..7198992
--- /dev/null
+++ b/ipaaction/ipaaction_example_policy.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ipa xmlns="http://freeipa.org/xml/rng/ipaaction/1.0">
+ <metadata>
+ <name>simple ipaaction example</name>
+ <author>sbose@redhat.com</author>
+ <version>0.7071</version>
+ <RNGfile>ipaaction.rng</RNGfile>
+ <XSLTfile>ipaaction.xslt</XSLTfile>
+ <app>ipaaction</app>
+ </metadata>
+
+ <ipaaction>
+ <file>
+ <url>http://my.server.org/something.txt</url>
+ <path>/tmp/something.txt</path>
+ <owner>nobody</owner>
+ <group>nogroup</group>
+ <access>0444</access>
+ </file>
+ <run>
+ <command>/bin/rm /tmp/something.txt</command>
+ <user>admin</user>
+ </run>
+ <file>
+ <data>VGhpcyBpcyBhIHRlc3QK</data>
+ <path>/tmp/something_other.txt</path>
+ <owner>nobody</owner>
+ <group>nogroup</group>
+ <access>0444</access>
+ </file>
+ </ipaaction>
+
+</ipa>
diff --git a/sudoers/policy_metadata.rng b/sudoers/policy_metadata.rng
index ca5ac19..404d64d 100644
--- a/sudoers/policy_metadata.rng
+++ b/sudoers/policy_metadata.rng
@@ -8,7 +8,7 @@ xmlns:pa="http://freeipa.org/xml/rng/ns/plugable_architecture/1.0">
<define name="policy_metadata">
<element name="metadata">
- <a:doc>The metadata information should be generic for all policies. The RelaxNG schema can be found in a separate file (this file :) and can be included by the schema file of a specific policy with the externalRef pattern. With this separation the policy and the metadata schema can be modified independently and the metadata schema can be used by the UI to render a separate page for the metadata of a policy.</a:doc>
+ <a:doc>The metadata information should be generic for all policies. The RelaxNG schema can be found in a separate file (this file :) and can be included by the schema file of a specific policy with the include pattern. With this separation the policy and the metadata schema can be modified independently and the metadata schema can be used by the UI to render a separate page for the metadata of a policy.</a:doc>
<element name="name">
<text/>
@@ -34,6 +34,11 @@ xmlns:pa="http://freeipa.org/xml/rng/ns/plugable_architecture/1.0">
<ref name="xslt_filename"/>
</element>
+ <element name="app" pa:label="Name of the application">
+ <a:doc>should be added automatically from RelaxNG metadata</a:doc>
+ <ref name="application_name"/>
+ </element>
+
<optional>
<element name="mergeStrategyXML" pa:label="Howto merge with other policies">
<choice>
diff --git a/sudoers/sudoers.rng b/sudoers/sudoers.rng
index d916e2d..3526252 100644
--- a/sudoers/sudoers.rng
+++ b/sudoers/sudoers.rng
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<grammar ns="http://freeipa.org/xml/rng/sudo/sudoers/1.0"
+<grammar ns="http://freeipa.org/xml/rng/sudo/1.0"
xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
@@ -16,9 +16,10 @@ xmlns:pa="http://freeipa.org/xml/rng/ns/plugable_architecture/1.0">
<define name="rng_filename"><value>sudoers.rng</value></define>
<define name="xslt_filename"><value>sudoers.xslt</value></define>
+ <define name="application_name"><value>sudo</value></define>
<include href="policy_metadata.rng"/>
- <start ns="http://freeipa.org/xml/rng/sudo/sudoers/1.0">
+ <start ns="http://freeipa.org/xml/rng/sudo/1.0">
<element name="ipa">
<a:documentation>Doc test.</a:documentation>
diff --git a/sudoers/sudoers.xslt b/sudoers/sudoers.xslt
index f767335..3690f81 100644
--- a/sudoers/sudoers.xslt
+++ b/sudoers/sudoers.xslt
@@ -3,9 +3,11 @@
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:md="http://freeipa.org/xsl/metadata/1.0"
- xmlns:sudoers="http://freeipa.org/xml/rng/sudo/sudoers/1.0">
+ xmlns:sudoers="http://freeipa.org/xml/rng/sudo/1.0">
- <md:output_file name="/etc/sudoers" owner="root" group="root" permission="440"/>
+ <md:output_handler>
+ <file name="/etc/sudoers" owner="root" group="root" permission="440"/>
+ </md:output_handler>
<xsl:output method="text" indent="no"/>
<xsl:strip-space elements="*"/>
diff --git a/sudoers/sudoers_example_policy.xml b/sudoers/sudoers_example_policy.xml
index 10d097a..1323ff1 100644
--- a/sudoers/sudoers_example_policy.xml
+++ b/sudoers/sudoers_example_policy.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
-<ipa xmlns="http://freeipa.org/xml/rng/sudo/sudoers/1.0">
+<ipa xmlns="http://freeipa.org/xml/rng/sudo/1.0">
<metadata>
<name>simple sudoers example, allowing mount/umount of a CD-ROM</name>
<author>sbose@redhat.com</author>
<version>0.7071</version>
<RNGfile>sudoers.rng</RNGfile>
<XSLTfile>sudoers.xslt</XSLTfile>
+ <app>sudo</app>
</metadata>
<ipaconfig>
diff --git a/worker/worker.c b/worker/worker.c
index 492fa91..23c3de3 100644
--- a/worker/worker.c
+++ b/worker/worker.c
@@ -17,65 +17,64 @@
#define XMLCHARLEN 255
/* 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.
+ * 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";
-char * find_value_by_xpath(xmlDocPtr doc, xmlChar * xpathExpr, xmlChar *prefix, xmlChar * namespace)
+char *find_value_by_xpath(xmlDocPtr doc, xmlChar * xpathExpr,
+ xmlChar * prefix, xmlChar * namespace)
{
xmlXPathContextPtr xpathCtx;
xmlXPathObjectPtr xpathObj;
- char *result=NULL;
- xmlNodeSetPtr nodeset;
- int i;
- xmlChar *str;
-
+ char *result = NULL;
+
/* Create xpath evaluation context */
xpathCtx = xmlXPathNewContext(doc);
if (xpathCtx == NULL) {
fprintf(stderr, "Error: unable to create new XPath context\n");
- return(NULL);
+ return (NULL);
}
/* Register a namespace */
- if (xmlXPathRegisterNs (xpathCtx, prefix, namespace) != 0) {
+ if (xmlXPathRegisterNs(xpathCtx, prefix, namespace) != 0) {
fprintf(stderr,
"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n",
"my", namespace);
xmlXPathFreeContext(xpathCtx);
- return(NULL);
+ return (NULL);
}
/* Evaluate xpath expression */
xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
if (xpathObj == NULL) {
fprintf(stderr,
- "Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr);
+ "Error: unable to evaluate xpath expression \"%s\"\n",
+ xpathExpr);
xmlXPathFreeContext(xpathCtx);
- return(NULL);
+ return (NULL);
}
if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
printf("Nothing found ...\n");
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
- return(NULL);
- } else if (xmlXPathNodeSetGetLength(xpathObj->nodesetval) != 1 ) {
- fprintf(stderr,"More than one node found!");
+ return (NULL);
+ } else if (xmlXPathNodeSetGetLength(xpathObj->nodesetval) != 1) {
+ fprintf(stderr, "More than one node found!");
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
- return(NULL);
+ return (NULL);
} else {
- nodeset = xpathObj->nodesetval;
-/* FIXME: only allow one found value */
- for (i = 0; i < nodeset->nodeNr; i++) {
- str = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
- result = strdup((char *) str);
- xmlFree(str);
- }
+ result =
+ (char *) xmlNodeListGetString(doc,
+ xpathObj->nodesetval->
+ nodeTab[0]->xmlChildrenNode, 1);
}
@@ -89,7 +88,7 @@ int main(int argc, char **argv)
{
xmlDocPtr doc;
- xmlNodePtr rootNode;
+ xmlNodePtr rootNode;
xmlChar *default_namespace;
xmlChar xpathExpr[XMLCHARLEN];
char *rngFileName;
@@ -117,33 +116,44 @@ int main(int argc, char **argv)
}
/* find the default namespace */
- rootNode=xmlDocGetRootElement(doc);
- if(rootNode==NULL) {
- fprintf(stderr, "Cannot find root node of document %s!\n", argv[1]);
+ rootNode = xmlDocGetRootElement(doc);
+ if (rootNode == NULL) {
+ fprintf(stderr, "Cannot find root node of document %s!\n",
+ argv[1]);
exit(1);
}
- if(xmlStrncasecmp(rootNode->name,(xmlChar *) "IPA", XMLCHARLEN) != 0) {
- fprintf(stderr, "Name of root node of document %s has to be 'ipa'!\n", argv[1]);
+ if (xmlStrncasecmp(rootNode->name, (xmlChar *) "IPA", XMLCHARLEN) != 0) {
+ fprintf(stderr,
+ "Name of root node of document %s has to be 'ipa'!\n",
+ argv[1]);
exit(1);
}
- if(rootNode->ns->href==NULL) {
- fprintf(stderr, "Root node of document %s must define a namespace!\n", argv[1]);
+ if (rootNode->ns->href == NULL) {
+ fprintf(stderr,
+ "Root node of document %s must define a namespace!\n",
+ argv[1]);
exit(1);
}
- default_namespace=xmlStrndup(rootNode->ns->href,XMLCHARLEN);
- if(default_namespace==NULL) {
+ default_namespace = xmlStrndup(rootNode->ns->href, XMLCHARLEN);
+ if (default_namespace == NULL) {
fprintf(stderr, "Cannot copy namespace!\n");
exit(1);
}
/* extract XSTLfile and RNGfile from document using XPath */
- xmlStrPrintf(xpathExpr, XMLCHARLEN, (xmlChar *) "//%s:XSLTfile", default_namespace_prefix);
- xsltFileName=find_value_by_xpath(doc,xpathExpr, default_namespace_prefix, default_namespace);
+ xmlStrPrintf(xpathExpr, XMLCHARLEN, (xmlChar *) "//%s:XSLTfile",
+ default_namespace_prefix);
+ xsltFileName =
+ find_value_by_xpath(doc, xpathExpr, default_namespace_prefix,
+ default_namespace);
printf("--%s--\n", xsltFileName);
- xmlStrPrintf(xpathExpr, XMLCHARLEN, (xmlChar *) "//%s:RNGfile", default_namespace_prefix);
- rngFileName=find_value_by_xpath(doc,xpathExpr, default_namespace_prefix, default_namespace);
+ xmlStrPrintf(xpathExpr, XMLCHARLEN, (xmlChar *) "//%s:RNGfile",
+ default_namespace_prefix);
+ rngFileName =
+ find_value_by_xpath(doc, xpathExpr, default_namespace_prefix,
+ default_namespace);
printf("--%s--\n", rngFileName);
-
+
/* validate the document */
@@ -172,14 +182,27 @@ int main(int argc, char **argv)
exit(1);
}
- output_file_name=find_value_by_xpath(xsltDoc,(xmlChar *) "//md:output_file/@name",(xmlChar *) "md", (xmlChar *) "http://freeipa.org/xsl/metadata/1.0");
- output_file_owner=find_value_by_xpath(xsltDoc,(xmlChar *) "//md:output_file/@owner",(xmlChar *) "md", (xmlChar *) "http://freeipa.org/xsl/metadata/1.0");
- output_file_group=find_value_by_xpath(xsltDoc,(xmlChar *) "//md:output_file/@group",(xmlChar *) "md", (xmlChar *) "http://freeipa.org/xsl/metadata/1.0");
- output_file_permission=find_value_by_xpath(xsltDoc,(xmlChar *) "//md:output_file/@permission",(xmlChar *) "md", (xmlChar *) "http://freeipa.org/xsl/metadata/1.0");
- printf("-%s-\n",output_file_name);
- printf("-%s-\n",output_file_owner);
- printf("-%s-\n",output_file_group);
- printf("-%s-\n",output_file_permission);
+ output_file_name =
+ find_value_by_xpath(xsltDoc, (xmlChar *) "//md:output_handler/file/@name",
+ (xmlChar *) "md", (xmlChar *)
+ "http://freeipa.org/xsl/metadata/1.0");
+ output_file_owner =
+ find_value_by_xpath(xsltDoc, (xmlChar *) "//md:output_handler/file/@owner",
+ (xmlChar *) "md", (xmlChar *)
+ "http://freeipa.org/xsl/metadata/1.0");
+ output_file_group =
+ find_value_by_xpath(xsltDoc, (xmlChar *) "//md:output_handler/file/@group",
+ (xmlChar *) "md", (xmlChar *)
+ "http://freeipa.org/xsl/metadata/1.0");
+ output_file_permission =
+ find_value_by_xpath(xsltDoc,
+ (xmlChar *) "//md:output_handler/file/@permission",
+ (xmlChar *) "md", (xmlChar *)
+ "http://freeipa.org/xsl/metadata/1.0");
+ printf("-%s-\n", output_file_name);
+ printf("-%s-\n", output_file_owner);
+ printf("-%s-\n", output_file_group);
+ printf("-%s-\n", output_file_permission);
cur = xsltParseStylesheetDoc(xsltDoc);
if (cur == NULL) {