Annotation of embedaddon/sudo/plugins/sudoers/sudoers2ldif, revision 1.1.1.2

1.1       misho       1: #!/usr/bin/env perl
1.1.1.2 ! misho       2: #
        !             3: # Copyright (c) 2007, 2010-2011, 2013 Todd C. Miller <Todd.Miller@courtesan.com>
        !             4: #
        !             5: # Permission to use, copy, modify, and distribute this software for any
        !             6: # purpose with or without fee is hereby granted, provided that the above
        !             7: # copyright notice and this permission notice appear in all copies.
        !             8: #
        !             9: # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            10: # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            11: # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            12: # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            13: # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            14: # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            15: # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            16: #
        !            17: 
1.1       misho      18: use strict;
                     19: 
                     20: #
                     21: # Converts a sudoers file to LDIF format in prepration for loading into
                     22: # the LDAP server.
                     23: #
                     24: 
                     25: # BUGS:
                     26: #   Does not yet handle multiple lines with : in them
                     27: #   Does not yet remove quotation marks from options
                     28: #   Does not yet escape + at the beginning of a dn
                     29: #   Does not yet handle line wraps correctly
                     30: #   Does not yet handle multiple roles with same name (needs tiebreaker)
                     31: #
                     32: # CAVEATS:
                     33: #   Sudoers entries can have multiple RunAs entries that override former ones,
                     34: #      with LDAP sudoRunAs{Group,User} applies to all commands in a sudoRole
                     35: 
                     36: my %RA;
                     37: my %UA;
                     38: my %HA;
                     39: my %CA;
                     40: my $base=$ENV{SUDOERS_BASE} or die "$0: Container SUDOERS_BASE undefined\n";
                     41: my @options=();
                     42: 
                     43: my $did_defaults=0;
                     44: my $order = 0;
                     45: 
                     46: # parse sudoers one line at a time
                     47: while (<>){
                     48: 
                     49:   # remove comment
                     50:   s/#.*//;
                     51: 
                     52:   # line continuation
                     53:   $_.=<> while s/\\\s*$//s;
                     54: 
                     55:   # cleanup newline
                     56:   chomp;
                     57: 
                     58:   # ignore blank lines
                     59:   next if /^\s*$/;
                     60: 
                     61:   if (/^Defaults\s+/i) {
                     62:     my $opt=$';
                     63:     $opt=~s/\s+$//; # remove trailing whitespace
                     64:     push @options,$opt;
1.1.1.2 ! misho      65:   } elsif (/^(\S+)\s+([^=]+)=\s*(.*)/) {
1.1       misho      66: 
                     67:     # Aliases or Definitions
                     68:     my ($p1,$p2,$p3)=($1,$2,$3);
                     69:     $p2=~s/\s+$//; # remove trailing whitespace
                     70:     $p3=~s/\s+$//; # remove trailing whitespace
                     71: 
                     72:     if ($p1 eq "User_Alias") {
                     73:       $UA{$p2}=$p3;
                     74:     } elsif ($p1 eq "Runas_Alias") {
                     75:       $RA{$p2}=$p3;
                     76:     } elsif ($p1 eq "Host_Alias") {
                     77:       $HA{$p2}=$p3;
                     78:     } elsif ($p1 eq "Cmnd_Alias") {
                     79:       $CA{$p2}=$p3;
                     80:     } else {
                     81:       if (!$did_defaults++){
                     82:         # do this once
                     83:         print "dn: cn=defaults,$base\n";
                     84:         print "objectClass: top\n";
                     85:         print "objectClass: sudoRole\n";
                     86:         print "cn: defaults\n";
                     87:         print "description: Default sudoOption's go here\n";
                     88:         print "sudoOption: $_\n" foreach @options;
                     89:         printf "sudoOrder: %d\n", ++$order;
                     90:         print "\n";
                     91:       }
                     92:       # Definition
                     93:       my @users=split /\s*,\s*/,$p1;
                     94:       my @hosts=split /\s*,\s*/,$p2;
                     95:       my @cmds= split /\s*,\s*/,$p3;
                     96:       @options=();
                     97:       print "dn: cn=$users[0],$base\n";
                     98:       print "objectClass: top\n";
                     99:       print "objectClass: sudoRole\n";
                    100:       print "cn: $users[0]\n";
                    101:       # will clobber options
                    102:       print "sudoUser: $_\n"   foreach expand(\%UA,@users);
                    103:       print "sudoHost: $_\n"   foreach expand(\%HA,@hosts);
                    104:       foreach (@cmds) {
                    105:        if (s/^\(([^\)]+)\)\s*//) {
                    106:          my @runas = split(/:\s*/, $1);
                    107:          if (defined($runas[0])) {
                    108:            print "sudoRunAsUser: $_\n" foreach expand(\%RA, split(/,\s*/, $runas[0]));
                    109:          }
                    110:          if (defined($runas[1])) {
                    111:            print "sudoRunAsGroup: $_\n" foreach expand(\%RA, split(/,\s*/, $runas[1]));
                    112:          }
                    113:        }
                    114:       }
                    115:       print "sudoCommand: $_\n" foreach expand(\%CA,@cmds);
                    116:       print "sudoOption: $_\n" foreach @options;
                    117:       printf "sudoOrder: %d\n", ++$order;
                    118:       print "\n";
                    119:     }
                    120: 
                    121:   } else {
                    122:     print "parse error: $_\n";
                    123:   }
                    124: 
                    125: }
                    126: 
                    127: #
                    128: # recursively expand hash elements
                    129: sub expand{
                    130:   my $ref=shift;
                    131:   my @a=();
                    132: 
                    133:   # preen the line a little
                    134:   foreach (@_){
                    135:     # if NOPASSWD: directive found, mark entire entry as not requiring
                    136:     s/NOPASSWD:\s*// && push @options,"!authenticate";
                    137:     s/PASSWD:\s*// && push @options,"authenticate";
                    138:     s/NOEXEC:\s*// && push @options,"noexec";
                    139:     s/EXEC:\s*// && push @options,"!noexec";
                    140:     s/SETENV:\s*// && push @options,"setenv";
                    141:     s/NOSETENV:\s*// && push @options,"!setenv";
                    142:     s/LOG_INPUT:\s*// && push @options,"log_input";
                    143:     s/NOLOG_INPUT:\s*// && push @options,"!log_input";
                    144:     s/LOG_OUTPUT:\s*// && push @options,"log_output";
                    145:     s/NOLOG_OUTPUT:\s*// && push @options,"!log_output";
1.1.1.2 ! misho     146:     s/[[:upper:]]+://; # silently remove other tags
1.1       misho     147:     s/\s+$//; # right trim
                    148:   }
                    149: 
                    150:   # do the expanding
                    151:   push @a,$ref->{$_} ? expand($ref,split /\s*,\s*/,$ref->{$_}):$_ foreach @_;
                    152:   @a;
                    153: }
                    154: 
                    155: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>