[augeas-devel] Sudoers lens

David Lutterkort dlutter at redhat.com
Mon Aug 11 21:31:47 UTC 2008


On Mon, 2008-08-11 at 19:07 +0200, Raphaël Pinson wrote:
> 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.

Very nice .. yeah, sudoers is a pretty complex file format. It might
help if you cut&paste the grammar rules from the man page into a comment
at the top of sudoers.aug. That will make it a little clearer what's
going on - especially if you can explain where in the tree which parts
of the file go.

> Here is the code I have so far. It has a few major problems:
> * augparse takes a few seconds to check it

Yeah, the typechecker is pretty slow. From profiling data, most of the
time is spent in typechecking concatenations - and most of the time for
that is in computing the intersection of regular languages.

> * it doesn't support "\" to continue a line. This is the biggest
> issue, and I have no idea how to fix that in augeas.

As long as continuation lines can't happen in the middle of an entry,
and something must be present on the continued line, it should be
possible. There's one wrinkle: backslashes get handled twice, once by
the parser, and once by the regexp engine. Because of that, you need to
write '\\\\' to get a single backslash into regexps. 

For example, /\\\\\n/ matches a backslash followed by a newline. To
demonstrate handling of continuation lines, I just added a test
tests/modules/pass_cont_lines.aug to the repo:

        module Pass_cont_line =
        
        (* Parse a list of words where the list can stretch over multiple lines.
           Mostly there to demonstrate how to deal with continuation lines. *)
        
        let list_elt = [ label "element" . store /[a-z]+/ ]
        
        let ws_cont = /([ \t]+|[ \t]*\\\\\n[ \t]*)/ 
        
        let sep = del ws_cont " "
        let eol = del /[ \t]*\n/ "\n"
        
        let list = list_elt . ( sep . list_elt )* . eol
        
        let exp_tree = { "element" = "a" } { "element" = "b" }
        
        test list get "a  b\n"      = exp_tree
        test list get "a  \\\n b\n" = exp_tree
        test list get "a\\\nb\n"    = exp_tree
        
David





More information about the augeas-devel mailing list