diff options
| author | Sumit Bose <sbose@nb.localdomain> | 2008-09-18 10:46:33 +0200 |
|---|---|---|
| committer | Sumit Bose <sbose@nb.localdomain> | 2008-09-18 10:46:33 +0200 |
| commit | 7bfb88bbf648000b4c2bf853a11ad2bd3f4b2d85 (patch) | |
| tree | b5e5bf2cd5768dd129d23fb76cb30304cd5315e5 | |
| parent | 575f23f9ca93b302cb487c037edcbb8bf7554437 (diff) | |
added fcusack's work
| -rw-r--r-- | sudoers/ipa.rng | 42 | ||||
| -rw-r--r-- | sudoers/netgroup.rng | 49 | ||||
| -rw-r--r-- | sudoers/options.rng | 448 | ||||
| -rw-r--r-- | sudoers/posixGroup.rng | 49 | ||||
| -rw-r--r-- | sudoers/sudoOptions.rng | 73 | ||||
| -rw-r--r-- | sudoers/sudoers.rng | 64 | ||||
| -rw-r--r-- | sudoers/sudoers.xslt | 566 | ||||
| -rw-r--r-- | sudoers/sudoers2xml (renamed from sudoers2xml) | 0 | ||||
| -rw-r--r-- | sudoers/ttygroup.rng | 49 | ||||
| -rw-r--r-- | sudoers/user.rng | 49 | ||||
| -rw-r--r-- | sudoers/username.rng | 11 |
11 files changed, 1400 insertions, 0 deletions
diff --git a/sudoers/ipa.rng b/sudoers/ipa.rng new file mode 100644 index 0000000..759caee --- /dev/null +++ b/sudoers/ipa.rng @@ -0,0 +1,42 @@ +<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 new file mode 100644 index 0000000..24e0171 --- /dev/null +++ b/sudoers/netgroup.rng @@ -0,0 +1,49 @@ +<?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 new file mode 100644 index 0000000..e2782e1 --- /dev/null +++ b/sudoers/options.rng @@ -0,0 +1,448 @@ +<?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/posixGroup.rng b/sudoers/posixGroup.rng new file mode 100644 index 0000000..e3f4d86 --- /dev/null +++ b/sudoers/posixGroup.rng @@ -0,0 +1,49 @@ +<?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 new file mode 100644 index 0000000..c87c02b --- /dev/null +++ b/sudoers/sudoOptions.rng @@ -0,0 +1,73 @@ +<?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 new file mode 100644 index 0000000..6787df7 --- /dev/null +++ b/sudoers/sudoers.rng @@ -0,0 +1,64 @@ +<?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 configuration (/etc/sudoers) </a:doc> + + <include href="username.rng"/> + + <start ns="http://freeipa.org/xml/rng/sudo/sudoers/1.0"> + <element name="sudoers"> + + <oneOrMore> + <element name="command"> + <optional> + <element name="options"> + <ref name="options"/> + </element> + </optional> + + <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"> + <ref name="username_pattern"/> + </element> + </zeroOrMore> + + </element> <!-- command --> + </oneOrMore> + + </element> <!-- sudoers --> + </start> + <define name="options"> + <zeroOrMore> + <choice> + <attribute name="dummy_attribute"/> + </choice> + </zeroOrMore> + </define> +</grammar> + diff --git a/sudoers/sudoers.xslt b/sudoers/sudoers.xslt new file mode 100644 index 0000000..4b19e51 --- /dev/null +++ b/sudoers/sudoers.xslt @@ -0,0 +1,566 @@ +<?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:ipa10="http://freeipa.org/xml/rng/ipa/1.0" + xmlns:user10="http://freeipa.org/xml/rng/user/1.0" + xmlns:group10="http://freeipa.org/xml/rng/posixGroup/1.0" + xmlns:netgroup10="http://freeipa.org/xml/rng/netgroup/1.0" + xmlns:sudoOptions10="http://freeipa.org/xml/rng/sudo/sudoOptions/1.0" + xmlns:sudoers10="http://freeipa.org/xml/rng/sudo/sudoers/1.0"> + + <md:output_file name="/etc/sudoers" owner="root" group="root" permission="440"/> + <xsl:output method="text" indent="no"/> + <xsl:strip-space elements="*"/> + + <xsl:template match="/"> + <xsl:text># IPA generated /etc/sudoers: DO NOT EDIT

</xsl:text> + <xsl:apply-templates select="ipa10:ipa"/> + </xsl:template> + + <xsl:template match="ipa10:ipa"> + <xsl:apply-templates> + <xsl:with-param name="users" select="''"/> + </xsl:apply-templates> + </xsl:template> + + <xsl:template match="user10:user"> + <xsl:param name="users"/> + <xsl:variable name="uids"> + <xsl:call-template name="tokenize"> + <xsl:with-param name="s" select="@uids"/> + </xsl:call-template> + </xsl:variable> + + <xsl:variable name="space"> + <xsl:choose> + <xsl:when test="$users = ''"> + </xsl:when> + <xsl:otherwise> + <xsl:text> </xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:apply-templates> + <xsl:with-param name="users" select="concat($users, $space, $uids)"/> + </xsl:apply-templates> + + </xsl:template> + + <xsl:template match="group10:posixGroup"> + <xsl:param name="users"/> + <xsl:variable name="gids"> + <xsl:call-template name="tokenize"> + <xsl:with-param name="s" select="@gids"/> + <xsl:with-param name="prefix" select="'%'"/> + </xsl:call-template> + </xsl:variable> + + <xsl:variable name="space"> + <xsl:choose> + <xsl:when test="$users = ''"> + </xsl:when> + <xsl:otherwise> + <xsl:text> </xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:apply-templates> + <xsl:with-param name="users" select="concat($users, $space, $gids)"/> + </xsl:apply-templates> + </xsl:template> + + <xsl:template match="netgroup10:netgroup"> + <xsl:param name="users"/> + <xsl:variable name="netgroups"> + <xsl:call-template name="tokenize"> + <!--<xsl:with-param name="s" select="@netgroup"/> --> + <xsl:with-param name="s" select="@groupnames"/> + <xsl:with-param name="prefix" select="'+'"/> + </xsl:call-template> + </xsl:variable> + + <xsl:variable name="space"> + <xsl:choose> + <xsl:when test="$users = ''"> + </xsl:when> + <xsl:otherwise> + <xsl:text> </xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:apply-templates> + <xsl:with-param name="users" select="concat($users, $space, $netgroups)"/> + </xsl:apply-templates> + </xsl:template> + + <xsl:template match="sudoOptions10:sudoOptions"> + <xsl:param name="users"/> + + <xsl:call-template name="defaults"> + <xsl:with-param name="users" select="$users"/> + </xsl:call-template> + <xsl:apply-templates> + <xsl:with-param name="users" select="$users"/> + </xsl:apply-templates> + </xsl:template> + + <xsl:template match="sudoers10:sudoers"> + <xsl:param name="users"/> + <!-- Add this if <sudoers> is allowed to carry option (Defaults) attributes + <xsl:call-template name="defaults"/> + --> + <xsl:apply-templates select="sudoers10:command"> + <xsl:with-param name="users" select="$users"/> + </xsl:apply-templates> + </xsl:template> + + <xsl:template match="sudoers10:command"> + <xsl:param name="users"/> + + <xsl:variable name="runas"> + <xsl:choose> + <xsl:when test="sudoers10:runas"> + <xsl:for-each select="sudoers10:runas"> + <xsl:if test="position() > 1"> + <xsl:text>,</xsl:text> + </xsl:if> + <xsl:value-of select="."/> + </xsl:for-each> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="'ALL'"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:variable name="tags"> + <xsl:choose> + <xsl:when test="sudoers10:tag"> + <xsl:call-template name="tokenize"> + <xsl:with-param name="s" select="sudoers10:tag"/> + <xsl:with-param name="suffix" select="':'"/> + </xsl:call-template> + <!-- Include a trailing space for easier output formatting. --> + <xsl:text> </xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="''"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:variable name="command" select="sudoers10:path"/> + <xsl:variable name="args" select="sudoers10:args"/> + + <!-- + user|%group|+netgroup.USER HOST|+netgroup.HOST = (runas) tags: commands + runas::= user|#uid|%group|+netgroup.USER + --> + <xsl:call-template name="tokenize"> + <xsl:with-param name="s" select="$users"/> + <xsl:with-param name="suffix"> + <xsl:text> </xsl:text> + <xsl:text>ALL</xsl:text> + <xsl:text> = (</xsl:text> + <xsl:value-of select="$runas"/> + <xsl:text>) </xsl:text> + <xsl:value-of select="$tags"/> + <xsl:value-of select="$command"/> + <xsl:text> </xsl:text> + <xsl:value-of select="$args"/> + </xsl:with-param> + <xsl:with-param name="separator" select="'
'"/> + </xsl:call-template> + + <xsl:text>
</xsl:text> + </xsl:template> + + <xsl:template name="defaults"> + <xsl:param name="users"/> + + <xsl:for-each select="@*"> + <xsl:variable name="var" select="name()"/> + <xsl:variable name="val" select="."/> + <xsl:variable name="prefix"> + <xsl:choose> + <xsl:when test="$users = ''"> + <xsl:text>Defaults</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>Defaults:</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:call-template name="tokenize"> + <xsl:with-param name="s" select="$users"/> + <xsl:with-param name="prefix"> + <xsl:choose> + <xsl:when test="$users = ''"> + <xsl:text>Defaults</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>Defaults:</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:with-param> + <xsl:with-param name="suffix"> + <xsl:text> </xsl:text> + + <xsl:choose> + <!-- boolean handling --> + + <xsl:when test="name() = 'always_set_home'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'authenticate'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'env_editor'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'env_reset'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'fqdn'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'ignore_local_sudoers'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'insults'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'log_host'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'log_year'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'long_otp_prompt'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'mail_always'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'mail_badpass'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'mail_no_host'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'mail_no_perms'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'mail_no_user'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'noexec'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'path_info'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'passprompt_override'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'preserve_groups'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'requiretty'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'root_sudo'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'rootpw'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'runaspw'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'set_home'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'set_logname'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'setenv'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'shell_noargs'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'stay_setuid'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'targetpw'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <xsl:when test="name() = 'ttytickets'"> + <xsl:if test=". = 'off'"> + <xsl:text>!</xsl:text> + </xsl:if> + <xsl:value-of select="name()"/> + </xsl:when> + + <!-- boolean/string handling --> + + <xsl:when test="name() = 'syslog'"> + <xsl:choose> + <xsl:when test=". = 'off'"> + <xsl:text>!</xsl:text> + <xsl:value-of select="name()"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="name()"/> + <xsl:text>=</xsl:text> + <xsl:value-of select="."/> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + + <!-- quoted/list handling --> + + <xsl:when test="name() = 'badpass_message'"> + <xsl:value-of select="$var"/> + <xsl:text>= "</xsl:text> + <xsl:value-of select="$val"/> + <xsl:text>"</xsl:text> + </xsl:when> + + <xsl:when test="name() = 'mailsub'"> + <xsl:value-of select="$var"/> + <xsl:text>= "</xsl:text> + <xsl:value-of select="$val"/> + <xsl:text>"</xsl:text> + </xsl:when> + + <xsl:when test="name() = 'passprompt'"> + <xsl:value-of select="$var"/> + <xsl:text>= "</xsl:text> + <xsl:value-of select="$val"/> + <xsl:text>"</xsl:text> + </xsl:when> + + <xsl:when test="name() = 'role'"> + <xsl:value-of select="$var"/> + <xsl:text>= "</xsl:text> + <xsl:value-of select="$val"/> + <xsl:text>"</xsl:text> + </xsl:when> + + <xsl:when test="name() = 'mailerflags'"> + <xsl:value-of select="$var"/> + <xsl:text>= "</xsl:text> + <xsl:value-of select="$val"/> + <xsl:text>"</xsl:text> + </xsl:when> + + <xsl:when test="name() = 'env_check'"> + <xsl:value-of select="$var"/> + <xsl:text>= "</xsl:text> + <xsl:value-of select="$val"/> + <xsl:text>"</xsl:text> + </xsl:when> + + <xsl:when test="name() = 'env_delete'"> + <xsl:value-of select="$var"/> + <xsl:text>= "</xsl:text> + <xsl:value-of select="$val"/> + <xsl:text>"</xsl:text> + </xsl:when> + + <xsl:when test="name() = 'env_keep'"> + <xsl:value-of select="$var"/> + <xsl:text>= "</xsl:text> + <xsl:value-of select="$val"/> + <xsl:text>"</xsl:text> + </xsl:when> + + <!-- default handling --> + <xsl:otherwise> + <xsl:value-of select="name()"/> + <xsl:text>=</xsl:text> + <xsl:value-of select="."/> + </xsl:otherwise> + + </xsl:choose> + + <xsl:text>
</xsl:text> + </xsl:with-param> + <xsl:with-param name="separator" select="''"/> + </xsl:call-template> + + <xsl:text>
</xsl:text> + </xsl:for-each> + </xsl:template> + + <xsl:template name="tokenize"> + <xsl:param name="s" select="."/> + <xsl:param name="delim" select="' '"/> + <xsl:param name="prefix" select="''"/> + <xsl:param name="suffix" select="''"/> + <xsl:param name="separator" select="' '"/> + <xsl:param name="action" select="'output'"/> + <xsl:param name="first" select="true()"/> + + <xsl:choose> + <xsl:when test="contains($s, $delim)"> + <xsl:choose> + <xsl:when test="$action = 'output'"> + <xsl:if test="$first != true()"> + <xsl:value-of select="$separator"/> + </xsl:if> + <xsl:value-of select="$prefix"/> + <xsl:value-of select="substring-before($s, $delim)"/> + <xsl:value-of select="$suffix"/> + </xsl:when> + </xsl:choose> + <xsl:call-template name="tokenize"> + <xsl:with-param name="first" select="false()"/> + <xsl:with-param name="s" select="substring-after($s, $delim)"/> + <xsl:with-param name="delim" select="$delim"/> + <xsl:with-param name="prefix" select="$prefix"/> + <xsl:with-param name="suffix" select="$suffix"/> + <xsl:with-param name="separator" select="$separator"/> + <xsl:with-param name="action" select="$action"/> + </xsl:call-template> + </xsl:when> + <xsl:otherwise> + <xsl:choose> + <xsl:when test="$action = 'output'"> + <xsl:if test="$first != true()"> + <xsl:value-of select="$separator"/> + </xsl:if> + <xsl:value-of select="$prefix"/> + <xsl:value-of select="$s"/> + <xsl:value-of select="$suffix"/> + </xsl:when> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + +</xsl:stylesheet> diff --git a/sudoers2xml b/sudoers/sudoers2xml index 4ce9b18..4ce9b18 100644 --- a/sudoers2xml +++ b/sudoers/sudoers2xml diff --git a/sudoers/ttygroup.rng b/sudoers/ttygroup.rng new file mode 100644 index 0000000..c8dfce6 --- /dev/null +++ b/sudoers/ttygroup.rng @@ -0,0 +1,49 @@ +<?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 new file mode 100644 index 0000000..b0aec32 --- /dev/null +++ b/sudoers/user.rng @@ -0,0 +1,49 @@ +<?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 new file mode 100644 index 0000000..9b3f37f --- /dev/null +++ b/sudoers/username.rng @@ -0,0 +1,11 @@ +<?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> + |
