(Final?) krb5.Conf Lexer/Parser Proposal

Theodore Ts'o tytso at MIT.EDU
Sat Jan 7 17:51:43 EST 2006

On Sat, Jan 07, 2006 at 03:14:30PM -0500, Joseph Calzaretta wrote:
> 1) when you try to decide how to programmatically manipulate the tree 
> (adding/moving/deleting nodes) and to flush the information back out 
> to the appropriate [chained] configuration file[s], via a reasonably 
> simple and consistent API.  Since Ted has moved in the direction of 
> eliminating programmatic editing and flushing of the profile 
> information, I imagine he wouldn't see this as a problem at all and 
> would say that people should just edit the file[s] via their favorite 
> text editor.  Those of us who are looking toward an "all-singing, 
> all-dancing" profile library, however, might have more of a 
> problem.  (Note the word "might")

The reason why I eliminated the editing API's from my fork was
precisely because of some of these difficulties, but they arise not
just from the chained configuration file, but from the fact that as
currently implemented, they only attempt to modify the first file in a
multiple file, chained configuration.  This can lead to surprises
starting right there.

For example, if you call profile_update_relation() with a null
new_value, in an attempt to delete a relation, and that relation is in
the global file, and not in the (first) user-specific config file,
profile_update_relation() will do nothing; it can't.  

And if the GUI program tries to display all of the sections and
relations using the currently defined API's, if there is more than one
file present, it will return all of them in one combined mass, with no
way in the current API to distinguish which section or relation came
from which combined file.  Inherently, the implementation does its
best to abstract this away from the program.  Hence, if the a GUI
program tries to use the profile library to display the the results
from multiple configuration files, and then tries to edit them, *it*
*will* *fail*.  It can't possibly succeed, because the API is simply
not adequate to the task.


The problem occurs with or without the finalizer support; it happens
from the simple fact of having chained configuration files, and no
clean way to support it in the API.

Since for my purposes, the power and flexibility of having a
(read-only) system config file and a user-configurable, individualized
config file was more important, and I *knew* the shortcomings in the
read/write API's, I decided to remove them all in my initial
implementation.  Thinking about this some more, if I was going to add
it, it would be in separate library, separate from the core
functionality (since most applications would probably not need it),
and it would only allow the calling application to open one file at a
time, thus removing the inherent ambiguities and traps in the current

> 2) when trying to understand via text editor exactly what's going on 
> in multiple large files with finalizers peppered throughout.  A 
> particularly full-featured GUI tool could mitigate that complexity by 
> explicitly showing which subtrees are overriden by which 
> nodes.  (e.g., "Oh, no wonder I'm not seeing any of the kdcs for that 
> realm, the whole realms section has been overriden by a near-copy in 
> a different configuration file in the chain!  I'll just fix that, 
> click, done.")  In either case, it's much easier to understand what's 
> going on without the finalizer.  Not that simplicity necessarily 
> trumps power, (i.e., "Everything should be as simple as possible, but 
> no more so.")  It's just that there's a real tradeoff in this case.

What a full-featured GUI tool would probably have to do is to have
multiple panes, with a pane for each separate config file, and a
separate pane for so people could see the final (effective) combined
result.  For bonus points, each config file would be display in a
particular color, and in the combined file view, each line would be
color-coded to show which config file it came from.  

Note that this could _almost_ be done in the current API's, but to do
this, each profile file would have to be opened separately, and then
application would have to manually calculate which finalized sections
would shadow each other.  So a huge amount of the work would have to
be done outside of the current profile library, due to limitations in
r/w API's.

As far as complexity in the text editor case, I suspect there are
different levels of complexity which are considered acceptable by
those who edit config files by hand.  I may be jaded, but compared to
many Unix/Linux configuration files, this is downright simple in
comparison --- especially when compared to those applications who
believe in Turing equivalent config files, like emacs or sawfish.  It
all depends on what metrics you are using, I suppose.

Still, probably the most useful thing that in a text-only world would
be a tool which shows what the results of combining a certain set of
config files would be.  The combined tool would show the finalizers,
so that it would be obvious to the user that a finalizer had been
involved, somehow.  If it was really desirable, it would be possible
to do something like this:

1: [libdefaults]
1:    ticket_lifetime = 18000
2:    ticket_lifetime = 36000
1: [realms]
1:    ATHENA.MIT.EDU = {
1:	kdc = kerberos-2.mit.edu:88
2:	kdc = kerberos.mit.edu:88
2:	kdc = kerberos-1.mit.edu:88
2:	kdc = kerberos-2.mit.edu:
1:	admin_server = kerberos-2.mit.edu:88
2:	admin_server = kerberos.mit.edu:88
1:    }
1:    THUNK.ORG = final {
1:	kdc = thunk.org:88
1:	admin_server = thunk.org
1:    }

... with a legend telling the user which file (1) and (2) were, of
course.  (And I've used the "= final {" syntax instead of the closing
'*' because I do accept the criticism that the trailing '*' is too
TECO-like, and an explicit keyword is probably better.)

Note though that that if you had more than 2 or 3 files --- for
example, if you had four levels of global defaults, site-wide
settings, machine-specific settings, user-specific settings --- then
this sort of annotated output becomes very important even *without*
the finalizer.  The inherent complexity comes from the chained
configuration files, and the finalizer is only a small part of it.  

						- Ted

P.S.  Alexis noted that if we are trying to make the format easy to
edit, that programs such as the ones I have proposed that show the
combined result of multiple files shouldn't be necessary.  I disagree.
*If* there is a desire for multiple levels of configuration files,
that kind of power is going to add complexity, and there is no way to
get around it.  The individual format text file itself is not where
the complexity is after all, but rather in allowing combination in the
first place.  Joe is right, though --- the real question is what is
the right tradeoff between simplicity and power.  

More information about the krbdev mailing list