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

1.1     ! misho       1: #!/usr/bin/env perl
        !             2: use strict;
        !             3: 
        !             4: #
        !             5: # Converts a sudoers file to LDIF format in prepration for loading into
        !             6: # the LDAP server.
        !             7: #
        !             8: 
        !             9: # BUGS:
        !            10: #   Does not yet handle multiple lines with : in them
        !            11: #   Does not yet remove quotation marks from options
        !            12: #   Does not yet escape + at the beginning of a dn
        !            13: #   Does not yet handle line wraps correctly
        !            14: #   Does not yet handle multiple roles with same name (needs tiebreaker)
        !            15: #
        !            16: # CAVEATS:
        !            17: #   Sudoers entries can have multiple RunAs entries that override former ones,
        !            18: #      with LDAP sudoRunAs{Group,User} applies to all commands in a sudoRole
        !            19: 
        !            20: my %RA;
        !            21: my %UA;
        !            22: my %HA;
        !            23: my %CA;
        !            24: my $base=$ENV{SUDOERS_BASE} or die "$0: Container SUDOERS_BASE undefined\n";
        !            25: my @options=();
        !            26: 
        !            27: my $did_defaults=0;
        !            28: my $order = 0;
        !            29: 
        !            30: # parse sudoers one line at a time
        !            31: while (<>){
        !            32: 
        !            33:   # remove comment
        !            34:   s/#.*//;
        !            35: 
        !            36:   # line continuation
        !            37:   $_.=<> while s/\\\s*$//s;
        !            38: 
        !            39:   # cleanup newline
        !            40:   chomp;
        !            41: 
        !            42:   # ignore blank lines
        !            43:   next if /^\s*$/;
        !            44: 
        !            45:   if (/^Defaults\s+/i) {
        !            46:     my $opt=$';
        !            47:     $opt=~s/\s+$//; # remove trailing whitespace
        !            48:     push @options,$opt;
        !            49:   } elsif (/^(\S+)\s+(.+)=\s*(.*)/) {
        !            50: 
        !            51:     # Aliases or Definitions
        !            52:     my ($p1,$p2,$p3)=($1,$2,$3);
        !            53:     $p2=~s/\s+$//; # remove trailing whitespace
        !            54:     $p3=~s/\s+$//; # remove trailing whitespace
        !            55: 
        !            56:     if ($p1 eq "User_Alias") {
        !            57:       $UA{$p2}=$p3;
        !            58:     } elsif ($p1 eq "Runas_Alias") {
        !            59:       $RA{$p2}=$p3;
        !            60:     } elsif ($p1 eq "Host_Alias") {
        !            61:       $HA{$p2}=$p3;
        !            62:     } elsif ($p1 eq "Cmnd_Alias") {
        !            63:       $CA{$p2}=$p3;
        !            64:     } else {
        !            65:       if (!$did_defaults++){
        !            66:         # do this once
        !            67:         print "dn: cn=defaults,$base\n";
        !            68:         print "objectClass: top\n";
        !            69:         print "objectClass: sudoRole\n";
        !            70:         print "cn: defaults\n";
        !            71:         print "description: Default sudoOption's go here\n";
        !            72:         print "sudoOption: $_\n" foreach @options;
        !            73:         printf "sudoOrder: %d\n", ++$order;
        !            74:         print "\n";
        !            75:       }
        !            76:       # Definition
        !            77:       my @users=split /\s*,\s*/,$p1;
        !            78:       my @hosts=split /\s*,\s*/,$p2;
        !            79:       my @cmds= split /\s*,\s*/,$p3;
        !            80:       @options=();
        !            81:       print "dn: cn=$users[0],$base\n";
        !            82:       print "objectClass: top\n";
        !            83:       print "objectClass: sudoRole\n";
        !            84:       print "cn: $users[0]\n";
        !            85:       # will clobber options
        !            86:       print "sudoUser: $_\n"   foreach expand(\%UA,@users);
        !            87:       print "sudoHost: $_\n"   foreach expand(\%HA,@hosts);
        !            88:       foreach (@cmds) {
        !            89:        if (s/^\(([^\)]+)\)\s*//) {
        !            90:          my @runas = split(/:\s*/, $1);
        !            91:          if (defined($runas[0])) {
        !            92:            print "sudoRunAsUser: $_\n" foreach expand(\%RA, split(/,\s*/, $runas[0]));
        !            93:          }
        !            94:          if (defined($runas[1])) {
        !            95:            print "sudoRunAsGroup: $_\n" foreach expand(\%RA, split(/,\s*/, $runas[1]));
        !            96:          }
        !            97:        }
        !            98:       }
        !            99:       print "sudoCommand: $_\n" foreach expand(\%CA,@cmds);
        !           100:       print "sudoOption: $_\n" foreach @options;
        !           101:       printf "sudoOrder: %d\n", ++$order;
        !           102:       print "\n";
        !           103:     }
        !           104: 
        !           105:   } else {
        !           106:     print "parse error: $_\n";
        !           107:   }
        !           108: 
        !           109: }
        !           110: 
        !           111: #
        !           112: # recursively expand hash elements
        !           113: sub expand{
        !           114:   my $ref=shift;
        !           115:   my @a=();
        !           116: 
        !           117:   # preen the line a little
        !           118:   foreach (@_){
        !           119:     # if NOPASSWD: directive found, mark entire entry as not requiring
        !           120:     s/NOPASSWD:\s*// && push @options,"!authenticate";
        !           121:     s/PASSWD:\s*// && push @options,"authenticate";
        !           122:     s/NOEXEC:\s*// && push @options,"noexec";
        !           123:     s/EXEC:\s*// && push @options,"!noexec";
        !           124:     s/SETENV:\s*// && push @options,"setenv";
        !           125:     s/NOSETENV:\s*// && push @options,"!setenv";
        !           126:     s/LOG_INPUT:\s*// && push @options,"log_input";
        !           127:     s/NOLOG_INPUT:\s*// && push @options,"!log_input";
        !           128:     s/LOG_OUTPUT:\s*// && push @options,"log_output";
        !           129:     s/NOLOG_OUTPUT:\s*// && push @options,"!log_output";
        !           130:     s/\w+://; # silently remove other directives
        !           131:     s/\s+$//; # right trim
        !           132:   }
        !           133: 
        !           134:   # do the expanding
        !           135:   push @a,$ref->{$_} ? expand($ref,split /\s*,\s*/,$ref->{$_}):$_ foreach @_;
        !           136:   @a;
        !           137: }
        !           138: 
        !           139: 

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