Auto-Configuring a File
In this sudoers example, we demonstrate a technique for auto-configuring system files.
Here is the sudoers portion of a sample files.cfg. (Or maybe we put this portion in its own separate #include file and have the statement
#include <files/sudoers_files.cfg>
in the top-level files.cfg.)
Pay particularly close attention to the #verbatim directive in the section
"User alias specification."
///////////////////////////////////////////////////////////////////////////
#if sudo
/etc/sudoers mode 400 uid 0
# if linux
gid 0
# else
gid 1
# endif
#fix
# sudoers file.
#
[text omitted here for brevity]
# if ! seville
#####################################################################
##
# User alias specification
##
User_Alias GURUS=brahms,mozart,bach,liszt
User_Alias FULLTIMERS=mahler,janacek,albeniz,schubert,smetana
User_Alias PARTTIMERS=\
#verbatim <files/sudo_parttimers_files.cfg>
[/pikt/lib/programs/MakeSudoParttimers.pkt]
# if milan
User_Alias CODERADMIN=borodin
# endif
# endif
#####################################################################
[text omitted here for brevity]
#####################################################################
##
# User specification
##
# if seville
root ALL=ALL
mozart ALUMSRVR=PSWD,ALIASCHG,WHOS,ACCTA
jpedrell0 ALUMSRVR=PSWD,ALIASCHG,WHOS,ACCTA
cs_mozart ALUMSRVR=PSWD,ALIASCHG,WHOS,ACCTA
# else
# if solaris
# root and users in group wheel can run anything on any machine
root ALL=ALL
%wheel ALL=ALL
# endif
# gurus can run anything on any machine
#GURUS ALL=ALL
# fulltimers can run lp administrative commands on the perf systems
# and print servers
GURUS PERFSYSTEMS=LP:\
PRINTSERVERS=LP
FULLTIMERS PERFSYSTEMS=LP:\
PRINTSERVERS=LP
# parttimers can run lp administrative commands on the print servers
PARTTIMERS PRINTSERVERS=LP
# gurus & fulltimers can kill any job on any machine;
# deactivated for now; want to think about this one some more
#GURUS ALL=KILL
#FULLTIMERS ALL=KILL
[text omitted here for brevity]
# endif
#####################################################################
#unfix
#endif // sudo
///////////////////////////////////////////////////////////////////////////
By now, you should understand how piktc installs customized versions of the /etc/sudoers file to the sudo systems. Lines between '#if seville ... #endif' directives appear in the sudoers file on the seville system only, for example.
Of special interest are the lines
User_Alias PARTTIMERS=\
#verbatim <files/sudo_parttimers_files.cfg>
[/pikt/lib/programs/MakeSudoParttimers.pkt]
The contents of the sudo_parttimers_files.cfg file are
larry,moe,curly,sporty,ginger,baby,posh,scary,
john,paul,george,ringo
In the client-side target /etc/sudoers, then, the final result would be
User_Alias PARTTIMERS=\
larry,moe,curly,sporty,ginger,baby,posh,scary,
john,paul,george,ringo
which is in a form acceptable to the sudo program.
Why on earth would you want to go to the trouble of isolating the PARTTIMERS list in its own separate include file? The reason is that we can have a script update this list for us automatically. The script could be written in Perl, Python, or some other scripting language. Here is a Pikt script version, MakeSudoParttimers.pkt, to update the parttimers list:
# if piktmaster
MakeSudoParttimers // output a comma-separated list of CA user accounts
// suitable for use as sudo_parttimers_files.cfg
path "=prgdir/MakeSudoParttimers.pkt"
mode 750 uid 0 gid 1
#!=pikt
init
input proc "=ssh moscow /opt/mailman/bin/list_members labs"
dat $mem 1
begin
set $pt = ""
rule // dispose of "@..."
set #i = #index($mem, "\@")
if #i
set $user = $left($mem, #i-1)
else
set $user = $mem
endif
rule // keep resolving dotted alias until we have a simple
// user name
set $aliases = " "
while $user =~ "\\."
if #find($aliases, " $user ")
output mail "Can't resolve alias $user:
circular reference"
next // bypass this user
else
set $aliases .= "$user "
endif
set $match = $command("=ypmatch $user aliases 2>&1")
if $match !~ "no such key"
set $user = $match
// dispose of "@..." that might result from
// resolving dotted alias
set #i = #index($user, "\@")
if #i
set $user = $left($user, #i-1)
endif
else
output mail "Can't resolve alias $user:
no such key"
next // go on to next list member
endif
endwhile
rule // dispose of "@..." that might result from
// resolving dotted alias
set #i = #index($user, "\@")
if #i
set $user = $left($user, #i-1)
endif
rule // append this user to list
set $pt .= "$user,"
end
if #length($pt)
set $pt = $chop($pt) // chop off trailing comma
output $pt
else
if #defined(%pt)
set $pt = %pt
output $pt
else
output "ERROR"
endif
=execwait "echo '$script() error' |
=mailx -s '$script() error' =piktdebug"
endif
# endif // piktmaster
The Pikt script language has much to recommend it:
-
a clean, uncluttered syntax
-
free-form, flexible layout
-
keyword synonyms
-
automatic previous-line (@foo) and prior-run (%foo) value references
-
a built-in input loop (much like Awk's)
-
many standard input and output options.
-
automatic logging of everything of consequence
-
a cautious approach to script execution (no assumed variable defaults; serious errors trigger automatic script shutdown)
On the other hand, scripting language preference is often a highly personal, even emotional matter. Pikt, the scripting language, is just the first among equals in PIKT, the sysadmin toolkit. Use of other languages within the PIKT system is supported and even encouraged.
Returning to the sudoers configuration, the #verbatim directive says to include file content, or process output, "as is". If we are preprocessing this with a 'piktc -I ...' command, we incorporate output from the MakeSudoParttimers.pkt script directly into the sudoers file, and also update the on-disk sudo_parttimers_files.cfg file. If we omit the -I option from the piktc command, we simply reference the on-disk file. You might think of the on-disk file as a sort of data cache for the MakeSudoParttimers.pkt program (which might take a while to run, so we wouldn't want to run it every time).
Again, why go to all this trouble, and introduce all this complexity? The reason is that the PARTTIMERS change constantly. We found it very hard to keep the static sudoers files up-to-date. Using the auto-configuring files technique, PIKT can manage the changes for us automatically.
|