Imported Debian patch 1.6.8p5-1
[debian/sudo] / sudoers2ldif
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 # $Sudo: sudoers2ldif,v 1.2 2004/02/13 02:08:27 aaron Exp $
9 #
10
11 # BUGS:
12 #   Does not yet handle multiple lines with : in them
13 #   Does not yet handle runas (xxx) syntax.
14 #   Does not yet remove quotation marks from options
15 #   Does not yet escape + at the beginning of a dn
16 #   Does not yet handle line wraps correctly
17 #   Does not yet handle multiple roles with same name (needs tiebreaker)
18
19 my %UA;
20 my %HA;
21 my %CA;
22 my $base=$ENV{SUDOERS_BASE} or die "$0: Container SUDOERS_BASE undefined\n";
23 my @options=();
24
25 my $did_defaults=0;
26
27 # parse sudoers one line at a time
28 while (<>){
29
30   # remove comment
31   s/#.*//;
32
33   # line continuation
34   $_.=<> while s/\\\s*$//s;
35
36   # cleanup newline
37   chomp;
38
39   # ignore blank lines
40   next if /^\s*$/;
41
42   if (/^Defaults\s+/i) {
43     my $opt=$';
44     $opt=~s/\s+$//; # remove trailing whitespace
45     push @options,$opt;
46   } elsif (/^(\S+)\s+(.+)=\s*(.*)/) {
47
48     # Aliases or Definitions
49     my ($p1,$p2,$p3)=($1,$2,$3);
50     $p2=~s/\s+$//; # remove trailing whitespace
51     $p3=~s/\s+$//; # remove trailing whitespace
52
53     if      ($p1 eq "User_Alias") {
54       $UA{$p2}=$p3;
55     } elsif ($p1 eq "Host_Alias") {
56       $HA{$p2}=$p3;
57     } elsif ($p1 eq "Cmnd_Alias") {
58       $CA{$p2}=$p3;
59     } else {
60       if (!$did_defaults++){
61         # do this once
62         print "dn: cn=defaults,$base\n";
63         print "objectClass: top\n";
64         print "objectClass: sudoRole\n";
65         print "cn: defaults\n";
66      print "description: Default sudoOption's go here\n";
67         print "sudoOption: $_\n" foreach @options;
68         print "\n";
69       }
70       # Definition
71       my @users=split /\s*,\s*/,$p1;
72       my @hosts=split /\s*,\s*/,$p2;
73       my @cmds= split /\s*,\s*/,$p3;
74       @options=();
75       print "dn: cn=$users[0],$base\n";
76       print "objectClass: top\n";
77       print "objectClass: sudoRole\n";
78       print "cn: $users[0]\n";
79       # will clobber options
80       print "sudoUser: $_\n"   foreach expand(\%UA,@users);
81       print "sudoHost: $_\n"   foreach expand(\%HA,@hosts);
82       print "sudoCommand: $_\n" foreach expand(\%CA,@cmds);
83       print "sudoOption: $_\n" foreach @options;
84       print "\n";
85     }
86
87   } else {
88     print "parse error: $_\n";
89   }
90
91 }
92
93 #
94 # recursively expand hash elements
95 sub expand{
96   my $ref=shift;
97   my @a=();
98
99   # preen the line a little
100   foreach (@_){
101     # if NOPASSWD: directive found, mark entire entry as not requiring
102     s/NOPASSWD:\s*// && push @options,"!authenticate";
103     s/PASSWD:\s*// && push @options,"authenticate";
104     s/NOEXEC:\s*// && push @options,"noexec";
105     s/EXEC:\s*// && push @options,"!noexec";
106     s/\w+://; # silently remove other directives
107     s/\s+$//; # right trim
108   }
109
110   # do the expanding
111   push @a,$ref->{$_} ? expand($ref,split /\s*,\s*/,$ref->{$_}):$_ foreach @_;
112   @a;
113 }
114
115