+++ /dev/null
-#!/usr/bin/env perl
-use strict;
-
-#
-# Converts a sudoers file to LDIF format in prepration for loading into
-# the LDAP server.
-#
-
-# BUGS:
-# Does not yet handle multiple lines with : in them
-# Does not yet remove quotation marks from options
-# Does not yet escape + at the beginning of a dn
-# Does not yet handle line wraps correctly
-# Does not yet handle multiple roles with same name (needs tiebreaker)
-#
-# CAVEATS:
-# Sudoers entries can have multiple RunAs entries that override former ones,
-# with LDAP sudoRunAs{Group,User} applies to all commands in a sudoRole
-
-my %RA;
-my %UA;
-my %HA;
-my %CA;
-my $base=$ENV{SUDOERS_BASE} or die "$0: Container SUDOERS_BASE undefined\n";
-my @options=();
-
-my $did_defaults=0;
-
-# parse sudoers one line at a time
-while (<>){
-
- # remove comment
- s/#.*//;
-
- # line continuation
- $_.=<> while s/\\\s*$//s;
-
- # cleanup newline
- chomp;
-
- # ignore blank lines
- next if /^\s*$/;
-
- if (/^Defaults\s+/i) {
- my $opt=$';
- $opt=~s/\s+$//; # remove trailing whitespace
- push @options,$opt;
- } elsif (/^(\S+)\s+(.+)=\s*(.*)/) {
-
- # Aliases or Definitions
- my ($p1,$p2,$p3)=($1,$2,$3);
- $p2=~s/\s+$//; # remove trailing whitespace
- $p3=~s/\s+$//; # remove trailing whitespace
-
- if ($p1 eq "User_Alias") {
- $UA{$p2}=$p3;
- } elsif ($p1 eq "Runas_Alias") {
- $RA{$p2}=$p3;
- } elsif ($p1 eq "Host_Alias") {
- $HA{$p2}=$p3;
- } elsif ($p1 eq "Cmnd_Alias") {
- $CA{$p2}=$p3;
- } else {
- if (!$did_defaults++){
- # do this once
- print "dn: cn=defaults,$base\n";
- print "objectClass: top\n";
- print "objectClass: sudoRole\n";
- print "cn: defaults\n";
- print "description: Default sudoOption's go here\n";
- print "sudoOption: $_\n" foreach @options;
- print "\n";
- }
- # Definition
- my @users=split /\s*,\s*/,$p1;
- my @hosts=split /\s*,\s*/,$p2;
- my @cmds= split /\s*,\s*/,$p3;
- @options=();
- print "dn: cn=$users[0],$base\n";
- print "objectClass: top\n";
- print "objectClass: sudoRole\n";
- print "cn: $users[0]\n";
- # will clobber options
- print "sudoUser: $_\n" foreach expand(\%UA,@users);
- print "sudoHost: $_\n" foreach expand(\%HA,@hosts);
- foreach (@cmds) {
- if (s/^\(([^\)]+)\)\s*//) {
- my @runas = split(/:\s*/, $1);
- if (defined($runas[0])) {
- print "sudoRunAsUser: $_\n" foreach expand(\%RA, split(/,\s*/, $runas[0]));
- }
- if (defined($runas[1])) {
- print "sudoRunAsGroup: $_\n" foreach expand(\%RA, split(/,\s*/, $runas[1]));
- }
- }
- }
- print "sudoCommand: $_\n" foreach expand(\%CA,@cmds);
- print "sudoOption: $_\n" foreach @options;
- print "\n";
- }
-
- } else {
- print "parse error: $_\n";
- }
-
-}
-
-#
-# recursively expand hash elements
-sub expand{
- my $ref=shift;
- my @a=();
-
- # preen the line a little
- foreach (@_){
- # if NOPASSWD: directive found, mark entire entry as not requiring
- s/NOPASSWD:\s*// && push @options,"!authenticate";
- s/PASSWD:\s*// && push @options,"authenticate";
- s/NOEXEC:\s*// && push @options,"noexec";
- s/EXEC:\s*// && push @options,"!noexec";
- s/SETENV:\s*// && push @options,"setenv";
- s/NOSETENV:\s*// && push @options,"!setenv";
- s/\w+://; # silently remove other directives
- s/\s+$//; # right trim
- }
-
- # do the expanding
- push @a,$ref->{$_} ? expand($ref,split /\s*,\s*/,$ref->{$_}):$_ foreach @_;
- @a;
-}
-
-