summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@nb.localdomain>2008-10-08 11:42:22 +0200
committerSumit Bose <sbose@nb.localdomain>2008-10-08 11:42:22 +0200
commit9765f5729bca58fd9bc57d315377ce143891d774 (patch)
tree3cbdb3f182cc7e37343832b7f8bf05624732652b
parent3af8a59bbae275bfd9031729b661c512b4641a72 (diff)
downloadipa_policy-9765f5729bca58fd9bc57d315377ce143891d774.tar.gz
ipa_policy-9765f5729bca58fd9bc57d315377ce143891d774.tar.xz
ipa_policy-9765f5729bca58fd9bc57d315377ce143891d774.zip
more metadata and policy fixes
-rw-r--r--sudoers/ipa.rng42
-rw-r--r--sudoers/netgroup.rng49
-rw-r--r--sudoers/options.rng448
-rw-r--r--sudoers/policy_metadata.rng31
-rw-r--r--sudoers/posixGroup.rng49
-rw-r--r--sudoers/sudoOptions.rng73
-rw-r--r--sudoers/sudoers.rng874
-rw-r--r--sudoers/ttygroup.rng49
-rw-r--r--sudoers/user.rng49
-rw-r--r--sudoers/username.rng11
-rwxr-xr-xsudoers/validate.py89
11 files changed, 463 insertions, 1301 deletions
diff --git a/sudoers/ipa.rng b/sudoers/ipa.rng
deleted file mode 100644
index 759caee..0000000
--- a/sudoers/ipa.rng
+++ /dev/null
@@ -1,42 +0,0 @@
-<grammar xmlns="http://relaxng.org/ns/structure/1.0"
- xmlns:a="http://freeipa.org/xml/rng/ns/annotations/1.0">
- <a:doc> top (root) level IPA pattern </a:doc>
-
- <!-- this simply allows any valid XML to be enclosed in <ipa> -->
- <start ns="http://freeipa.org/xml/rng/ipa/1.0">
- <element name="ipa">
- <!-- note that text is not allowed -->
- <zeroOrMore>
- <ref name="anyElement" />
- </zeroOrMore>
- </element>
- </start>
-
- <!--
- This allows anything in ANOTHER namespace.
- The way nsName works requires that this be in each schema (grammar);
- it cannot be included.
- -->
- <define name="anyElement">
- <element>
- <anyName>
- <except>
- <nsName />
- <nsName ns="" />
- <nsName ns="http://freeipa.org/xml/rng/ipa/1.0" />
- </except>
- </anyName>
- <zeroOrMore>
- <choice>
- <attribute>
- <anyName />
- </attribute>
- <text/>
- <ref name="anyElement" />
- </choice>
- </zeroOrMore>
- </element>
- </define>
-
-</grammar>
-
diff --git a/sudoers/netgroup.rng b/sudoers/netgroup.rng
deleted file mode 100644
index 24e0171..0000000
--- a/sudoers/netgroup.rng
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<grammar xmlns="http://relaxng.org/ns/structure/1.0"
- datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
- xmlns:a="http://freeipa.org/xml/rng/ns/annotations/1.0">
-
- <a:doc> netgroup configuration</a:doc>
-
- <start ns="http://freeipa.org/xml/rng/netgroup/1.0">
- <element name="netgroup">
- <ref name="options"/>
- <ref name="anyElement"/>
- </element>
-
- </start>
-
- <define name="options">
- <zeroOrMore>
- <choice>
- <attribute name="groupnames">
- <text/>
- </attribute>
- </choice>
- </zeroOrMore>
- </define>
- <!--
- This allows anything in another namespace.
- The way nsName works requires that this be in each schema (grammar);
- it cannot be included.
- -->
- <define name="anyElement">
- <element>
- <anyName>
- <except>
- <nsName/>
- <nsName ns=""/>
- </except>
- </anyName>
- <zeroOrMore>
- <choice>
- <attribute>
- <anyName/>
- </attribute>
- <text/>
- <ref name="anyElement"/>
- </choice>
- </zeroOrMore>
- </element>
- </define>
-</grammar>
diff --git a/sudoers/options.rng b/sudoers/options.rng
deleted file mode 100644
index e2782e1..0000000
--- a/sudoers/options.rng
+++ /dev/null
@@ -1,448 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<grammar xmlns="http://relaxng.org/ns/structure/1.0"
- datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
- xmlns:a="http://freeipa.org/xml/rng/ns/annotations/1.0">
-
- <include href="username.rng"/>
-
- <define name="options">
- <oneOrMore>
- <choice>
-
- <!-- flag options -->
-
- <attribute name="always_set_home" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="authenticate" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="env_editor" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="env_reset" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="fqdn" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
-<!--
- this option is ignored by sudo
- <attribute name="ignore_dot" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
--->
-
-<!-- global option only -->
- <attribute name="ignore_local_sudoers" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="insults" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="log_host" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="log_year" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="long_otp_prompt" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="mail_always" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="mail_badpass" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="mail_no_host" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="mail_no_perms" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="mail_no_user" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="noexec" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="path_info" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="passprompt_override" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="preserve_groups" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="requiretty" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="root_sudo" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="rootpw" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="runaspw" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="set_home" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="set_logname" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="setenv" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="shell_noargs" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="stay_setuid" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="targetpw" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="tty_tickets" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <!-- integer options -->
-
- <attribute name="passwd_tries" a:defaultValue="3">
- <data type="integer">
- <param name="minInclusive"> 1 </param>
- <param name="maxInclusive"> 65535 </param> <!-- ??? -->
- </data>
- </attribute>
-
- <!-- integer/boolean options -->
-
- <attribute name="loglinelen" a:defaultValue="80">
- <data type="integer">
- <param name="minInclusive"> 0 </param>
- <param name="maxInclusive"> 65535 </param> <!-- ??? -->
- </data>
- </attribute>
-
- <attribute name="passwd_timeout" a:defaultValue="0">
- <data type="integer">
- <param name="minInclusive"> 0 </param>
- <param name="maxInclusive"> 65535 </param> <!-- ??? -->
- </data>
- </attribute>
-
- <attribute name="timestamp_timeout" a:defaultValue="5">
- <data type="integer">
- <param name="minInclusive"> -1 </param>
- <param name="maxInclusive"> 65535 </param> <!-- ??? -->
- </data>
- </attribute>
-
- <attribute name="umask" a:defaultValue="0022">
- <data type="string">
- <param name="pattern">(0[0-7]{3})</param>
- </data>
- </attribute>
-
- <!-- string options -->
- <attribute name="badpass_message" a:defaultValue="Sorry, try again.">
- <text/>
- </attribute>
-
- <attribute name="editor" a:defaultValue="/PATH/TO/VI">
- <!-- NOTE: absolute path not required -->
- <text/>
- </attribute>
-
- <attribute name="mailsub"
- a:defaultValue="*** SECURITY information for %h ***">
- <text/>
- </attribute>
-
- <attribute name="noexec_file" a:defaultValue="/PATH/TO/SUDO_NOEXEC.SO">
- <data type="string">
- <param name="pattern">/.*</param>
- </data>
- </attribute>
-
- <attribute name="passprompt" a:defaultValue="Password:">
- <text/>
- </attribute>
-
- <attribute name="role" a:defaultValue="">
- <text/>
- </attribute>
-
- <attribute name="runas_default" a:defaultValue="root">
- <ref name="username_pattern"/>
- </attribute>
-
- <attribute name="syslog_badpri" a:defaultValue="alert">
- <choice>
- <value>emerg</value>
- <value>alert</value>
- <value>crit</value>
- <value>err</value>
- <value>warning</value>
- <value>notice</value>
- <value>info</value>
- <value>debug</value>
- </choice>
- </attribute>
-
- <attribute name="syslog_goodpri" a:defaultValue="notice">
- <choice>
- <value>emerg</value>
- <value>alert</value>
- <value>crit</value>
- <value>err</value>
- <value>warning</value>
- <value>notice</value>
- <value>info</value>
- <value>debug</value>
- </choice>
- </attribute>
-
- <attribute name="timestampdir" a:defaultValue="/var/db/sudo">
- <data type="string">
- <param name="pattern">/.*</param>
- </data>
- </attribute>
-
- <attribute name="timestampowner" a:defaultValue="root">
- <ref name="username_pattern"/>
- </attribute>
-
- <attribute name="type" a:defaultValue="">
- <text/>
- </attribute>
-
- <!-- string/boolean options -->
-
-<!-- possibly bad option for us -->
- <attribute name="exempt_group" a:defaultValue="off">
- <text/>
- </attribute>
-
- <attribute name="lecture" a:defaultValue="once">
- <choice>
- <value>always</value>
- <value>never</value>
- <value>once</value>
- </choice>
- </attribute>
-
- <attribute name="lecture_file" a:defaultValue="built-in">
- <data type="string">
- <param name="pattern">(/.*|built-in)</param>
- </data>
- </attribute>
-
-<!-- possibly bad for us -->
- <attribute name="listpw" a:defaultValue="any">
- <choice>
- <value>all</value>
- <value>always</value>
- <value>any</value>
- <value>never</value>
- </choice>
- </attribute>
-
- <attribute name="logfile" a:defaultValue="off">
- <data type="string">
- <param name="pattern">(/.*|off)</param>
- </data>
- </attribute>
-
- <attribute name="mailerflags" a:defaultValue="-t">
- <text/>
- </attribute>
-
- <attribute name="mailerpath" a:defaultValue="/PATH/TO/SENDMAIL">
- <text/>
- </attribute>
-
- <attribute name="syslog" a:defaultValue="authpriv">
- <choice>
- <value>auth</value>
- <value>authpriv</value>
- <value>daemon</value>
- <value>user</value>
- <value>local0</value>
- <value>local1</value>
- <value>local2</value>
- <value>local3</value>
- <value>local4</value>
- <value>local5</value>
- <value>local6</value>
- <value>local7</value>
- <value>off</value>
- </choice>
- </attribute>
-
- <attribute name="verifypw" a:defaultValue="all">
- <choice>
- <value>all</value>
- <value>always</value>
- <value>any</value>
- <value>never</value>
- </choice>
- </attribute>
-
- <!-- list/boolean options -->
-
- <attribute name="env_check" a:defaultValue="">
- <list>
- <oneOrMore>
- <data type="string"/>
- </oneOrMore>
- </list>
- </attribute>
-
- <attribute name="env_delete" a:defaultValue="">
- <list>
- <oneOrMore>
- <data type="string"/>
- </oneOrMore>
- </list>
- </attribute>
-
- <attribute name="env_keep" a:defaultValue="">
- <list>
- <oneOrMore>
- <data type="string"/>
- </oneOrMore>
- </list>
- </attribute>
-
- </choice>
- </oneOrMore>
- </define> <!-- options -->
-</grammar>
-
diff --git a/sudoers/policy_metadata.rng b/sudoers/policy_metadata.rng
index 5deb0e8..810d32c 100644
--- a/sudoers/policy_metadata.rng
+++ b/sudoers/policy_metadata.rng
@@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
-<element name="metadata"
-xmlns="http://relaxng.org/ns/structure/1.0"
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
xmlns:a="http://freeipa.org/xml/rng/ns/annotations/1.0"
xmlns:ui="http://freeipa.org/xml/rng/ns/ui/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>
<element name="name">
@@ -21,14 +23,17 @@ xmlns:ui="http://freeipa.org/xml/rng/ns/ui/1.0">
<text/>
</element>
- <element name="neededAssociation" ui:label="What kind of association is needed">
- <choice>
- <value ui:label="Host only">host</value>
- <value ui:label="User only">user</value>
- <value ui:label="Host and User">hostAndUser</value>
- </choice>
+ <element name="RNGfile" ui:label="Name of the RELAX NG file">
+ <a:doc>should be added automatically from RelaxNG metadata</a:doc>
+ <ref name="rng_filename"/>
+ </element>
+
+ <element name="XSLTfile" ui:label="Name of the XSLT file">
+ <a:doc>should be added automatically from RelaxNG metadata</a:doc>
+ <ref name="xslt_filename"/>
</element>
+<optional>
<element name="mergeStrategyXML" ui:label="Howto merge with other policies">
<choice>
<value ui:label="Use only this policy">exclusive</value>
@@ -45,13 +50,11 @@ xmlns:ui="http://freeipa.org/xml/rng/ns/ui/1.0">
</choice>
</element>
- <element name="XSLTfile" ui:label="Name of the XSLT file">
- <a:doc>should be added automatically from RelaxNG metadata</a:doc>
- <text/>
- </element>
-
<element name="description" ui:label="Description, what should the policy do and why, maybe a changelog">
<text/>
- <element>
+ </element>
+</optional>
</element>
+</define>
+</grammar>
diff --git a/sudoers/posixGroup.rng b/sudoers/posixGroup.rng
deleted file mode 100644
index e3f4d86..0000000
--- a/sudoers/posixGroup.rng
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<grammar xmlns="http://relaxng.org/ns/structure/1.0"
- datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
- xmlns:a="http://freeipa.org/xml/rng/ns/annotations/1.0">
-
- <a:doc> posixGroup configuration</a:doc>
-
- <start ns="http://freeipa.org/xml/rng/posixGroup/1.0">
- <element name="posixGroup">
- <ref name="options"/>
- <ref name="anyElement"/>
- </element>
-
- </start>
-
- <define name="options">
- <zeroOrMore>
- <choice>
- <attribute name="gids">
- <text/>
- </attribute>
- </choice>
- </zeroOrMore>
- </define>
- <!--
- This allows anything in another namespace.
- The way nsName works requires that this be in each schema (grammar);
- it cannot be included.
- -->
- <define name="anyElement">
- <element>
- <anyName>
- <except>
- <nsName/>
- <nsName ns=""/>
- </except>
- </anyName>
- <zeroOrMore>
- <choice>
- <attribute>
- <anyName/>
- </attribute>
- <text/>
- <ref name="anyElement"/>
- </choice>
- </zeroOrMore>
- </element>
- </define>
-</grammar>
diff --git a/sudoers/sudoOptions.rng b/sudoers/sudoOptions.rng
deleted file mode 100644
index c87c02b..0000000
--- a/sudoers/sudoOptions.rng
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<grammar xmlns="http://relaxng.org/ns/structure/1.0"
- datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
- xmlns:a="http://freeipa.org/xml/rng/ns/annotations/1.0">
-
- <a:doc> Sudo options configuration (Defaults) </a:doc>
-
- <include href="options.rng"/>
-
- <start ns="http://freeipa.org/xml/rng/sudo/sudoOptions/1.0">
- <element name="sudoOptions">
- <ref name="options"/>
- <!-- we can enclose anything -->
- <!--
- NOTE: This allows only a single element to be enclosed.
- The problem with allowing multiple elements is, how to
- resolve conflicting configs?
-
- <sudoOptions ...>
- <posixGroup name="wheel">
- <sudoers .../>
- </posixGroup>
- <posixGroup name="staff">
- <sudoers .../>
- </posixGroup>
- <posixUser name="user">
- <sudoers .../>
- </posixGroup>
- </sudoOptions>
-
- If user foo is in both groups, and (e.g.) conflicting
- options are used in the <sudoers> element, which applies?
- For the <posixUser> case, we could simply say it is more
- specific and it wins, but not so easy for the groups case.
-
- NOTE: This is a general problem. Even if sudoOptions allows only
- a single element, what about other grouping elements?
- -->
- <ref name="anyElement"/>
- </element>
- </start>
-
- <!--
- This allows anything in another namespace.
- The way nsName works requires that this be in each schema (grammar);
- it cannot be included.
- -->
- <define name="anyElement">
- <zeroOrMore>
- <element>
- <anyName>
- <except>
- <nsName/>
- <nsName ns=""/>
-<!--
- <nsName ns="http://freeipa.org/xml/rng/sudo/sudoOptions/1.0"/>
--->
- </except>
- </anyName>
- <zeroOrMore>
- <choice>
- <attribute>
- <anyName/>
- </attribute>
- <text/>
- <ref name="anyElement"/>
- </choice>
- </zeroOrMore>
- </element>
- </zeroOrMore>
- </define>
-</grammar>
-
diff --git a/sudoers/sudoers.rng b/sudoers/sudoers.rng
index e865118..9720a68 100644
--- a/sudoers/sudoers.rng
+++ b/sudoers/sudoers.rng
@@ -13,443 +13,461 @@ xmlns:ui="http://freeipa.org/xml/rng/ns/ui/1.0">
<a:xslt>sudoers.xsl</a:xslt>
<a:version>0.5</a:version>
- <start ns="http://freeipa.org/xml/rng/sudo/sudoers/1.0">
+ <define name="rng_filename"><value>sudoers.rng</value></define>
+ <define name="xslt_filename"><value>sudoers.xslt</value></define>
+ <include href="policy_metadata.rng"/>
+
+ <start>
<element name="ipa">
<a:documentation>Doc test.</a:documentation>
- <zeroOrMore>
- <externalRef href="policy_association.rng"/>
- </zeroOrMore>
+ <ref name="policy_metadata"/>
- <externalRef href="policy_metadata.rng"/>
+ <element name="ipaconfig">
- <a:documentation>Here the definition for the generic part of the policy starts.</a:documentation>
- <oneOrMore>
- <element name="sudoers">
- <optional>
- <element name="option">
- <oneOrMore>
- <choice>
- <!-- flag options -->
- <element name="always_set_home" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="authenticate" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="env_editor" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="env_reset" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="fqdn" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <!--
- this option is ignored by sudo
- <element name="ignore_dot" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
--->
- <!-- global option only -->
- <element name="ignore_local_sudoers" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="insults" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="log_host" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="log_year" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="long_otp_prompt" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="mail_always" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="mail_badpass"
- a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="mail_no_host"
- a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="mail_no_perms"
- a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="mail_no_user" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="noexec" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="path_info" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="passprompt_override" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="preserve_groups" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="requiretty" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="root_sudo" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="rootpw" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="runaspw" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="set_home" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="set_logname" a:defaultValue="on">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="setenv" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="shell_noargs" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="stay_setuid" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="targetpw" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <element name="tty_tickets" a:defaultValue="off">
- <choice>
- <value>on</value>
- <value>off</value>
- </choice>
- </element>
- <!-- integer options -->
- <element name="passwd_tries" a:defaultValue="3">
- <data type="integer">
- <param name="minInclusive">1</param>
- <param name="maxInclusive">65535</param>
- <!-- ??? -->
- </data>
- </element>
- <!-- integer/boolean options -->
- <element name="loglinelen" a:defaultValue="80">
- <data type="integer">
- <param name="minInclusive">0</param>
- <param name="maxInclusive">65535</param>
- <!-- ??? -->
- </data>
- </element>
- <element name="passwd_timeout" a:defaultValue="0">
- <data type="integer">
- <param name="minInclusive">0</param>
- <param name="maxInclusive">65535</param>
- <!-- ??? -->
- </data>
- </element>
- <element name="timestamp_timeout" a:defaultValue="5">
- <data type="integer">
- <param name="minInclusive">-1</param>
- <param name="maxInclusive">65535</param>
- <!-- ??? -->
- </data>
- </element>
- <element name="umask" a:defaultValue="0022">
- <data type="string">
- <param name="pattern">(0[0-7]{3})</param>
- </data>
- </element>
- <!-- string options -->
- <element name="badpass_message" a:defaultValue="Sorry, try again.">
- <text />
- </element>
- <element name="editor" a:defaultValue="/PATH/TO/VI">
- <!-- NOTE: absolute path not required -->
- <text />
- </element>
- <element name="mailsub" a:defaultValue="*** SECURITY information for %h ***">
- <text />
- </element>
- <element name="noexec_file" a:defaultValue="/PATH/TO/SUDO_NOEXEC.SO">
- <data type="string">
- <param name="pattern">/.*</param>
- </data>
- </element>
- <element name="passprompt" a:defaultValue="Password:">
- <text />
- </element>
- <element name="role" a:defaultValue="">
- <text />
- </element>
- <element name="runas_default" a:defaultValue="root">
- <data type="string">
- <param name="pattern">
- [A-Za-z0-9_-]{1,16}</param>
- </data>
- </element>
- <element name="syslog_badpri" a:defaultValue="alert">
- <choice>
- <value>emerg</value>
- <value>alert</value>
- <value>crit</value>
- <value>err</value>
- <value>warning</value>
- <value>notice</value>
- <value>info</value>
- <value>debug</value>
- </choice>
- </element>
- <element name="syslog_goodpri" a:defaultValue="notice">
- <choice>
- <value>emerg</value>
- <value>alert</value>
- <value>crit</value>
- <value>err</value>
- <value>warning</value>
- <value>notice</value>
- <value>info</value>
- <value>debug</value>
- </choice>
- </element>
- <element name="timestampdir" a:defaultValue="/var/db/sudo">
- <data type="string">
- <param name="pattern">/.*</param>
- </data>
- </element>
- <element name="timestampowner" a:defaultValue="root">
- <data type="string">
- <param name="pattern">
- [A-Za-z0-9_-]{1,16}</param>
- </data>
- </element>
- <element name="type" a:defaultValue="">
- <text />
- </element>
- <!-- string/boolean options -->
- <!-- possibly bad option for us -->
- <element name="exempt_group" a:defaultValue="off">
- <text />
- </element>
- <element name="lecture" a:defaultValue="once">
- <choice>
- <value>always</value>
- <value>never</value>
- <value>once</value>
- </choice>
- </element>
- <element name="lecture_file" a:defaultValue="built-in">
- <data type="string">
- <param name="pattern">(/.*|built-in)</param>
- </data>
- </element>
- <!-- possibly bad for us -->
- <element name="listpw" a:defaultValue="any">
- <choice>
- <value>all</value>
- <value>always</value>
- <value>any</value>
- <value>never</value>
- </choice>
- </element>
- <element name="logfile" a:defaultValue="off">
- <data type="string">
- <param name="pattern">(/.*|off)</param>
- </data>
- </element>
- <element name="mailerflags" a:defaultValue="-t">
- <text />
- </element>
- <element name="mailerpath" a:defaultValue="/PATH/TO/SENDMAIL">
- <text />
- </element>
- <element name="syslog" a:defaultValue="authpriv">
- <choice>
- <value>auth</value>
- <value>authpriv</value>
- <value>daemon</value>
- <value>user</value>
- <value>local0</value>
- <value>local1</value>
- <value>local2</value>
- <value>local3</value>
- <value>local4</value>
- <value>local5</value>
- <value>local6</value>
- <value>local7</value>
- <value>off</value>
- </choice>
- </element>
- <element name="verifypw" a:defaultValue="all">
- <choice>
- <value>all</value>
- <value>always</value>
- <value>any</value>
- <value>never</value>
- </choice>
- </element>
- <!-- list/boolean options -->
- <element name="env_check" a:defaultValue="">
- <list>
- <oneOrMore>
- <data type="string" />
- </oneOrMore>
- </list>
- </element>
- <element name="env_delete" a:defaultValue="">
- <list>
- <oneOrMore>
- <data type="string" />
- </oneOrMore>
- </list>
- </element>
- <element name="env_keep" a:defaultValue="">
- <list>
- <oneOrMore>
- <data type="string" />
- </oneOrMore>
- </list>
- </element>
- </choice>
- </oneOrMore>
- </element>
- </optional>
- <zeroOrMore>
- <element name="command">
- <element name="path">
- <text />
- </element>
- <zeroOrMore>
- <element name="args">
- <text />
+ <a:documentation>Here the definition for the sudo specific part of the policy starts.</a:documentation>
+ <oneOrMore>
+ <element name="sudoers">
+ <oneOrMore>
+ <element name="subject">
+ <element name="name">
+ <text/>
</element>
- </zeroOrMore>
- <zeroOrMore>
- <element name="tag">
+ <element name="type">
<choice>
- <value>NOPASSWD</value>
- <value>PASSWD</value>
- <value>NOEXEC</value>
- <value>EXEC</value>
- <value>SETENV</value>
- <value>NOSETENV</value>
+ <value>posixUser</value>
+ <value>posixGroup</value>
+ <value>netgroup</value>
+ <value>IPAgroup</value>
+ <value>ALL</value>
</choice>
</element>
- </zeroOrMore>
- <!-- XXX actually needs to be user,group,netgroup -->
- <zeroOrMore>
- <element name="runas">
- <data type="string">
- <param name="pattern">[A-Za-z0-9_-]{1,16}</param>
- </data>
- </element>
- </zeroOrMore>
+ </element>
+ </oneOrMore>
+
+ <oneOrMore>
+ <choice>
+ <element name="command">
+ <element name="path">
+ <text />
+ </element>
+ <zeroOrMore>
+ <element name="args">
+ <text />
+ </element>
+ </zeroOrMore>
+ <zeroOrMore>
+ <element name="tag">
+ <choice>
+ <value>NOPASSWD</value>
+ <value>PASSWD</value>
+ <value>NOEXEC</value>
+ <value>EXEC</value>
+ <value>SETENV</value>
+ <value>NOSETENV</value>
+ </choice>
+ </element>
+ </zeroOrMore>
+ <!-- XXX actually needs to be user,group,netgroup -->
+ <zeroOrMore>
+ <element name="runas">
+ <data type="string">
+ <param name="pattern">[A-Za-z0-9_-]{1,16}</param>
+ </data>
+ </element>
+ </zeroOrMore>
+ </element> <!-- command -->
+
+ <element name="option">
+ <oneOrMore>
+ <choice>
+ <!-- flag options -->
+ <element name="always_set_home" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="authenticate" a:defaultValue="on">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="env_editor" a:defaultValue="on">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="env_reset" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="fqdn" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <!--
+ this option is ignored by sudo
+ <element name="ignore_dot" a:defaultValue="on">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
</element>
- <!-- command -->
- </zeroOrMore>
- </element>
- <!-- sudoers -->
- </oneOrMore>
- </element>
- <!-- ipa -->
+ -->
+ <!-- global option only -->
+ <element name="ignore_local_sudoers" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="insults" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="log_host" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="log_year" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="long_otp_prompt" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="mail_always" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="mail_badpass"
+ a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="mail_no_host"
+ a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="mail_no_perms"
+ a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="mail_no_user" a:defaultValue="on">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="noexec" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="path_info" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="passprompt_override" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="preserve_groups" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="requiretty" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="root_sudo" a:defaultValue="on">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="rootpw" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="runaspw" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="set_home" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="set_logname" a:defaultValue="on">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="setenv" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="shell_noargs" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="stay_setuid" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="targetpw" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="tty_tickets" a:defaultValue="off">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <!-- integer options -->
+ <element name="passwd_tries" a:defaultValue="3">
+ <data type="integer">
+ <param name="minInclusive">1</param>
+ <param name="maxInclusive">65535</param>
+ <!-- ??? -->
+ </data>
+ </element>
+ <!-- integer/boolean options -->
+ <element name="loglinelen" a:defaultValue="80">
+ <data type="integer">
+ <param name="minInclusive">0</param>
+ <param name="maxInclusive">65535</param>
+ <!-- ??? -->
+ </data>
+ </element>
+ <element name="passwd_timeout" a:defaultValue="0">
+ <data type="integer">
+ <param name="minInclusive">0</param>
+ <param name="maxInclusive">65535</param>
+ <!-- ??? -->
+ </data>
+ </element>
+ <element name="timestamp_timeout" a:defaultValue="5">
+ <data type="integer">
+ <param name="minInclusive">-1</param>
+ <param name="maxInclusive">65535</param>
+ <!-- ??? -->
+ </data>
+ </element>
+ <element name="umask" a:defaultValue="0022">
+ <data type="string">
+ <param name="pattern">(0[0-7]{3})</param>
+ </data>
+ </element>
+ <!-- string options -->
+ <element name="badpass_message" a:defaultValue="Sorry, try again.">
+ <text />
+ </element>
+ <element name="editor" a:defaultValue="/PATH/TO/VI">
+ <!-- NOTE: absolute path not required -->
+ <text />
+ </element>
+ <element name="mailsub" a:defaultValue="*** SECURITY information for %h ***">
+ <text />
+ </element>
+ <element name="noexec_file" a:defaultValue="/PATH/TO/SUDO_NOEXEC.SO">
+ <data type="string">
+ <param name="pattern">/.*</param>
+ </data>
+ </element>
+ <element name="passprompt" a:defaultValue="Password:">
+ <text />
+ </element>
+ <element name="role" a:defaultValue="">
+ <text />
+ </element>
+ <element name="runas_default" a:defaultValue="root">
+ <data type="string">
+ <param name="pattern">
+ [A-Za-z0-9_-]{1,16}</param>
+ </data>
+ </element>
+ <element name="syslog_badpri" a:defaultValue="alert">
+ <choice>
+ <value>emerg</value>
+ <value>alert</value>
+ <value>crit</value>
+ <value>err</value>
+ <value>warning</value>
+ <value>notice</value>
+ <value>info</value>
+ <value>debug</value>
+ </choice>
+ </element>
+ <element name="syslog_goodpri" a:defaultValue="notice">
+ <choice>
+ <value>emerg</value>
+ <value>alert</value>
+ <value>crit</value>
+ <value>err</value>
+ <value>warning</value>
+ <value>notice</value>
+ <value>info</value>
+ <value>debug</value>
+ </choice>
+ </element>
+ <element name="timestampdir" a:defaultValue="/var/db/sudo">
+ <data type="string">
+ <param name="pattern">/.*</param>
+ </data>
+ </element>
+ <element name="timestampowner" a:defaultValue="root">
+ <data type="string">
+ <param name="pattern">
+ [A-Za-z0-9_-]{1,16}</param>
+ </data>
+ </element>
+ <element name="type" a:defaultValue="">
+ <text />
+ </element>
+ <!-- string/boolean options -->
+ <!-- possibly bad option for us -->
+ <element name="exempt_group" a:defaultValue="off">
+ <text />
+ </element>
+ <element name="lecture" a:defaultValue="once">
+ <choice>
+ <value>always</value>
+ <value>never</value>
+ <value>once</value>
+ </choice>
+ </element>
+ <element name="lecture_file" a:defaultValue="built-in">
+ <data type="string">
+ <param name="pattern">(/.*|built-in)</param>
+ </data>
+ </element>
+ <!-- possibly bad for us -->
+ <element name="listpw" a:defaultValue="any">
+ <choice>
+ <value>all</value>
+ <value>always</value>
+ <value>any</value>
+ <value>never</value>
+ </choice>
+ </element>
+ <element name="logfile" a:defaultValue="off">
+ <data type="string">
+ <param name="pattern">(/.*|off)</param>
+ </data>
+ </element>
+ <element name="mailerflags" a:defaultValue="-t">
+ <text />
+ </element>
+ <element name="mailerpath" a:defaultValue="/PATH/TO/SENDMAIL">
+ <text />
+ </element>
+ <element name="syslog" a:defaultValue="authpriv">
+ <choice>
+ <value>auth</value>
+ <value>authpriv</value>
+ <value>daemon</value>
+ <value>user</value>
+ <value>local0</value>
+ <value>local1</value>
+ <value>local2</value>
+ <value>local3</value>
+ <value>local4</value>
+ <value>local5</value>
+ <value>local6</value>
+ <value>local7</value>
+ <value>off</value>
+ </choice>
+ </element>
+ <element name="verifypw" a:defaultValue="all">
+ <choice>
+ <value>all</value>
+ <value>always</value>
+ <value>any</value>
+ <value>never</value>
+ </choice>
+ </element>
+ <!-- list/boolean options -->
+ <element name="env_check" a:defaultValue="">
+ <list>
+ <oneOrMore>
+ <data type="string" />
+ </oneOrMore>
+ </list>
+ </element>
+ <element name="env_delete" a:defaultValue="">
+ <list>
+ <oneOrMore>
+ <data type="string" />
+ </oneOrMore>
+ </list>
+ </element>
+ <element name="env_keep" a:defaultValue="">
+ <list>
+ <oneOrMore>
+ <data type="string" />
+ </oneOrMore>
+ </list>
+ </element>
+ </choice>
+ </oneOrMore>
+ </element>
+ </choice>
+ </oneOrMore>
+ </element> <!-- sudoers -->
+ </oneOrMore>
+ </element> <!-- ipaconfig -->
+ </element> <!-- ipa -->
</start>
</grammar>
diff --git a/sudoers/ttygroup.rng b/sudoers/ttygroup.rng
deleted file mode 100644
index c8dfce6..0000000
--- a/sudoers/ttygroup.rng
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<grammar xmlns="http://relaxng.org/ns/structure/1.0"
- datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
- xmlns:a="http://freeipa.org/xml/rng/ns/annotations/1.0">
-
- <a:doc> ttygroup configuration</a:doc>
-
- <start ns="http://freeipa.org/xml/rng/ttygroup/1.0">
- <element name="ttygroup">
- <ref name="options"/>
- <ref name="anyElement"/>
- </element>
-
- </start>
-
- <define name="options">
- <zeroOrMore>
- <choice>
- <attribute name="terminals">
- <text/>
- </attribute>
- </choice>
- </zeroOrMore>
- </define>
- <!--
- This allows anything in another namespace.
- The way nsName works requires that this be in each schema (grammar);
- it cannot be included.
- -->
- <define name="anyElement">
- <element>
- <anyName>
- <except>
- <nsName/>
- <nsName ns=""/>
- </except>
- </anyName>
- <zeroOrMore>
- <choice>
- <attribute>
- <anyName/>
- </attribute>
- <text/>
- <ref name="anyElement"/>
- </choice>
- </zeroOrMore>
- </element>
- </define>
-</grammar>
diff --git a/sudoers/user.rng b/sudoers/user.rng
deleted file mode 100644
index b0aec32..0000000
--- a/sudoers/user.rng
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<grammar xmlns="http://relaxng.org/ns/structure/1.0"
- datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
- xmlns:a="http://freeipa.org/xml/rng/ns/annotations/1.0">
-
- <a:doc> user configuration</a:doc>
-
- <start ns="http://freeipa.org/xml/rng/user/1.0">
- <element name="user">
- <ref name="options"/>
- <ref name="anyElement"/>
- </element>
-
- </start>
-
- <define name="options">
- <zeroOrMore>
- <choice>
- <attribute name="uids">
- <text/>
- </attribute>
- </choice>
- </zeroOrMore>
- </define>
- <!--
- This allows anything in another namespace.
- The way nsName works requires that this be in each schema (grammar);
- it cannot be included.
- -->
- <define name="anyElement">
- <element>
- <anyName>
- <except>
- <nsName/>
- <nsName ns=""/>
- </except>
- </anyName>
- <zeroOrMore>
- <choice>
- <attribute>
- <anyName/>
- </attribute>
- <text/>
- <ref name="anyElement"/>
- </choice>
- </zeroOrMore>
- </element>
- </define>
-</grammar>
diff --git a/sudoers/username.rng b/sudoers/username.rng
deleted file mode 100644
index 9b3f37f..0000000
--- a/sudoers/username.rng
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<grammar xmlns="http://relaxng.org/ns/structure/1.0"
- datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
- xmlns:a="http://freeipa.org/xml/rng/ns/annotations/1.0">
- <define name="username_pattern" combine="choice">
- <data type="string">
- <param name="pattern">[A-Za-z0-9_-]{1,16}</param>
- </data>
- </define>
-</grammar>
-
diff --git a/sudoers/validate.py b/sudoers/validate.py
deleted file mode 100755
index 9844e92..0000000
--- a/sudoers/validate.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/python
-
-import os, sys
-import re
-from lxml import etree
-
-def decompose(tag):
- """
- Separate a tag (element name) into its namespace and unadorned tag.
- """
- m = re.match('\{([^}]+)\}(.*)', tag)
- try:
- return (m.group(1), m.group(2))
- except:
- return (None, tag)
-
-def validate(root, parent_ns=None):
- """
- Recursively validate an XML Element object.
- """
- # In order to allow "ipa global" patterns to enclose domain- or
- # service-specific patterns (whose names are arbitrary and cannot be
- # known beforehand since end users can add new ones at will), all of
- # the ipa-provided global shemas contain a pattern which allows any
- # valid XML (in some other namespace) to be present at the level at which
- # the global pattern groups the service-specific elements. The simplest
- # example is the top level <ipa> pattern which simply allows anything to
- # be enclosed inside of it.
- #
- # The downside of this is that those "anything" elements will always
- # validate as long as they are valid XML.
- #
- # So we have to walk the element tree and for each child element in
- # a different namespace, revalidate it with the correct schema. It
- # doesn't seem to really matter if we go breadth-first or depth-first.
-
- # only operate on elements, not comments or other stuff we don't know about
- if type(root) is not etree._Element:
- return True
-
- # Is this a new namespace?
- (ns, tag) = decompose(root.tag)
- if parent_ns == ns:
- # Same ns, therefore this element has already been validated. Just descend.
- for e in root:
- if validate(e, ns) == False:
- return False
- return True
-
- # We found a new namespace; load the schema.
- # To keep the example simple, we just use the tag to find the schema.
- # IRL we would parse the ns to locate the schema in a local cache.
- print "found namespace %s" % tag
- parser = etree.RelaxNG(etree.parse(file("%s.rng" % tag)))
-
- # What we actually came here for; validate this element tree.
- # Obviously, on error we would actually do something useful here.
- try:
- parser.assertValid(root)
- except:
- return False
-
- # Descend.
- for e in root:
- if validate(e, ns) == False:
- return False
-
- return True
-
-def main(argv=None):
- if argv is None:
- argv = sys.argv
-
- try:
- xmldoc = argv[1]
- except:
- xmldoc = "ipa.xml"
-
- root = etree.parse(file(xmldoc)).getroot()
- if validate(root):
- print "XML is valid"
- sys.exit(0)
- else:
- print "try again, loser!"
- sys.exit(1)
-
-if __name__ == "__main__":
- sys.exit(main())
-