[augeas-devel] Sudoers lens

Raphaël Pinson raphink at gmail.com
Mon Aug 11 17:07:24 UTC 2008


Hi guys,


I've been trying to have a look at a lens for sudoers. I expected it to be
challenging, and so it is. Thankfully, man sudoers is one of the best
conffile docs ever.

Here is the code I have so far. It has a few major problems:
* augparse takes a few seconds to check it
* it doesn't support "\" to continue a line. This is the biggest issue, and
I have no idea how to fix that in augeas.


sudoers.aug :

=========================================================
(* Sudoers module for Augeas                  *)
(* Author: Raphael Pinson <raphink at gmail.com> *)
(*                                            *)
(* Reference: `man sudoers`                   *)


module Sudoers =
  autoload xfm

    (* Define useful shortcuts *)

    let eol       = del /[ \t]*\n/ "\n"

    (* Define separators *)
    let sep_com = del /[ \t]*,[ \t]*/ ", "
    let sep_eq  = del /[ \t]*=[ \t]*/ " = "
    let sep_spc = del /[ \t]+/ " "
    let sep_col = del /[ \t]*:[ \t]*/ " : "

    (* Define fields *)
    (* sto_to_com does not begin or end with a space *)
    let sto_to_com_cmnd = store /([^,=:#() \t\n][^,=:#()\n]*[^,=:#()
\t\n])|[^,=:#() \t\n]/
    let sto_to_com      = store /[^,=:#() \t\n]+/
    let sto_to_com_user = store ( /[^,=:#() \t\n]+/ -
/(User|Runas|Host|Cmnd)_Alias|Defaults/ )
    let sto_to_eq  = store /[^,=:#() \t\n]+/
    let sto_to_spc = store /[^() \t\n]+/


    (* define comments and empty lines *)
    let comment =
        let value_to_eol = del /[ \t]*/ " " . store /([^ \t\n].*[^ \t\n]|[^
\t\n])/ in
        [ label "comment" . del /[ \t]*#/ "# " .  value_to_eol? . eol ]

    let empty   = [ del /[ \t]*\n/ "" ]


    (* define aliases *)

    (* General definitions *)
    let alias_field (kw:string) (sto:lens) = [ label kw . sto ]
    let alias_list  (kw:string) (sto:lens) = alias_field kw sto . ( sep_com
. alias_field kw sto )*
    let alias_entry (kw:string) (field:string) (sto:lens) = [ key kw .
sep_spc . sto_to_eq . sep_eq . alias_list field sto . eol ]

    (* TODO: go further in user definitions *)
    let user_alias  = alias_entry "User_Alias" "user" sto_to_com
    let runas_alias = alias_entry "Runas_Alias" "runas_user" sto_to_com
    let host_alias  = alias_entry "Host_Alias" "host" sto_to_com
    let cmnd_alias  = alias_entry "Cmnd_Alias" "command" sto_to_com_cmnd

    let alias = user_alias | runas_alias | host_alias | cmnd_alias


    (* define defaults *)
    let default_type     =
        let value = store /(@|:|>)[^ \t\n]+/ in
        [ label "type" . value ]
    let parameter        = [ label "parameter" . sto_to_com ]
    let parameter_list   = parameter . ( sep_com . parameter )*
    let defaults = [ key "Defaults" . default_type? . sep_spc .
parameter_list . eol ]


    (* define spec *)

    let runas_spec = Util.del_str "(" . alias_list "runas_user" sto_to_com .
Util.del_str ")" . sep_spc
    let tag_spec   = [ label "tag" . store /(NO)?(PASSWD|EXEC|SETENV)/ .
Util.del_str ":" ] . sep_spc
    let cmnd       = sto_to_com
    let cmnd_spec  = [ label "command" .  runas_spec? . tag_spec* . cmnd ]
    let cmnd_spec_list = cmnd_spec . ( sep_com . cmnd_spec )*

    let spec_list = [ seq "list" . alias_list "host" sto_to_com . sep_eq .
cmnd_spec_list ]

    let spec = [ label "spec" . counter "list"
                              . alias_list "user" sto_to_com_user . sep_spc
                              . spec_list
                              . ( sep_col . spec_list )* . eol ]


    let lns = ( empty | comment | alias | defaults | spec  )*

    let filter = (incl "/etc/sudoers")
        . Util.stdexcl

    let xfm = transform lns filter

=========================================================

test_sudoers.aug

=========================================================

module Test_sudoers =

   let conf = "
Host_Alias LOCALNET = 192.168.0.0/24, localhost

# User alias specification

# Cmnd alias specification

Cmnd_Alias DEBIAN_TOOLS = /usr/bin/apt-get, /usr/bin/auto-get,
/usr/bin/dpkg, /usr/bin/dselect, /usr/sbin/dpkg-reconfigure

Cmnd_Alias PBUILDER = /usr/sbin/pbuilder

Cmnd_Alias ICAL = /bin/cat /home/rpinson/.kde/share/apps/korganizer/std.ics

Defaults at LOCALNET        !lecture,tty_tickets,!fqdn

# User privilege specification
root    ALL=(ALL) ALL

# Members of the admin group may gain root privileges
%admin  ALL=(ALL) ALL, NOPASSWD: DEBIAN_TOOLS
%pbuilder       LOCALNET = NOPASSWD: PBUILDER
www-data ALL=(rpinson) NOEXEC: ICAL : localhost = NOPASSWD:
/usr/bin/test
"

   test Sudoers.lns get conf =
      {}
      { "Host_Alias" = "LOCALNET"
          { "host" = "192.168.0.0/24" }
          { "host" = "localhost" } }
      {}
      { "comment" = "User alias specification" }
      {}
      { "comment" = "Cmnd alias specification" }
      {}
      { "Cmnd_Alias" = "DEBIAN_TOOLS"
          { "command" = "/usr/bin/apt-get" }
          { "command" = "/usr/bin/auto-get" }
          { "command" = "/usr/bin/dpkg" }
          { "command" = "/usr/bin/dselect" }
          { "command" = "/usr/sbin/dpkg-reconfigure" } }
      {}
      { "Cmnd_Alias" = "PBUILDER"
          { "command" = "/usr/sbin/pbuilder" } }
      {}
      { "Cmnd_Alias" = "ICAL"
          { "command" = "/bin/cat
/home/rpinson/.kde/share/apps/korganizer/std.ics" } }
      {}
      { "Defaults"
          { "type"      = "@LOCALNET" }
          { "parameter" = "!lecture" }
          { "parameter" = "tty_tickets" }
          { "parameter" = "!fqdn" } }
      {}
      { "comment" = "User privilege specification" }
      { "spec"
          { "user" = "root" }
          { "1"
              { "host" = "ALL" }
              { "command" = "ALL"
                  { "runas_user"  = "ALL" } } } }
      {}
      { "comment" = "Members of the admin group may gain root privileges" }
      { "spec"
          { "user"    = "%admin" }
          { "1"
              { "host" = "ALL" }
              { "command" = "ALL"
                  { "runas_user" = "ALL" } }
              { "command" = "DEBIAN_TOOLS"
                  { "tag"  = "NOPASSWD" } } } }
      { "spec"
          { "user"    = "%pbuilder" }
          { "1"
              { "host" = "LOCALNET" }
              { "command" = "PBUILDER"
                  { "tag" = "NOPASSWD" } } } }
      { "spec"
          { "user"    = "www-data" }
          { "1"
              { "host" = "ALL" }
              { "command" = "ICAL"
                  { "runas_user" = "rpinson" }
                  { "tag" = "NOEXEC" } } }
          { "2"
              { "host" = "localhost" }
              { "command" = "/usr/bin/test"
                  { "tag" = "NOPASSWD" } } } }


=========================================================
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/augeas-devel/attachments/20080811/f6914951/attachment.htm>


More information about the augeas-devel mailing list