Fixes to sudoers2ldif

Aaron Peschel <[email protected]>
Newsgroups gmane.comp.tools.sudo.devel
Message-ID <CANKmw4S6dwRtuUTBjLhv8WZSnoXe7yt+PAi5vcs1EkYfZPDjAg@mail.gmail.com>
* Fixes documented bug with duplicate role names.
* Parses assignments preceded by "Default" tag to eliminate whitespace.
  * (Not documented in script, but documented in this mail list.)
* Replaces leading tabs with spaces, for consistency.

--- sudo-1.8.15/plugins/sudoers/sudoers2ldif.orig       2015-10-31
16:34:59.000000000 -0700
+++ sudo-1.8.15/plugins/sudoers/sudoers2ldif    2016-02-02
11:12:33.000000000 -0800
@@ -27,11 +27,10 @@ use strict;
 #   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
+#       with LDAP sudoRunAs{Group,User} applies to all commands in a sudoRole

 my %RA;
 my %UA;
@@ -42,6 +41,8 @@ my @options=();

 my $did_defaults=0;
 my $order = 0;
+my %seen_users;
+my $assignment= qr/^(\S+)\s+(.+)=\s*(.*)/;

 # parse sudoers one line at a time
 while (<>){
@@ -61,11 +62,14 @@ while (<>){
   if (/^Defaults\s+/i) {
     my $opt=$';
     $opt=~s/\s+$//; # remove trailing whitespace
-    push @options,$opt;
-  } elsif (/^(\S+)\s+([^=]+)=\s*(.*)/) {
+    if (/$assignment/) {
+        $opt = join('', parse_assignment($opt));
+    }
+    push @options, $opt;
+  } elsif (/$assignment/) {

     # Aliases or Definitions
-    my ($p1,$p2,$p3)=($1,$2,$3);
+    my ($p1,$p2,$p3)=parse_assignment($');
     $p2=~s/\s+$//; # remove trailing whitespace
     $p3=~s/\s+$//; # remove trailing whitespace

@@ -91,26 +95,33 @@ while (<>){
       }
       # Definition
       my @users=split /\s*,\s*/,$p1;
+      my $username = @users[0];
+      if ($seen_users{$username}) {
+          $seen_users{$username} += 1;
+          $username = sprintf("%s_%s", $username, $seen_users{$username});
+      } else {
+          $seen_users{$username} = 1;
+      }
       my @hosts=split /\s*,\s*/,$p2;
       my @cmds= split /\s*,\s*/,$p3;
       @options=();
-      print "dn: cn=$users[0],$base\n";
+      print "dn: cn=$username,$base\n";
       print "objectClass: top\n";
       print "objectClass: sudoRole\n";
-      print "cn: $users[0]\n";
+      print "cn: $username\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]));
-         }
-       }
+        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;
@@ -124,6 +135,12 @@ while (<>){

 }

+sub parse_assignment{
+    my $line=shift;
+    $line=~/$assignment/;
+    return ($1,$2,$3);
+}
+
 #
 # recursively expand hash elements
 sub expand{

____________________________________________________________
sudo-workers mailing list <[email protected]>
For list information, options, or to unsubscribe, visit:
https://www.sudo.ws/mailman/listinfo/sudo-workers
sudoers2ldif.patch (application/octet-stream, 3.2 KB)
--- sudo-1.8.15/plugins/sudoers/sudoers2ldif.orig	2015-10-31 16:34:59.000000000 -0700
+++ sudo-1.8.15/plugins/sudoers/sudoers2ldif	2016-02-02 11:12:33.000000000 -0800
@@ -27,11 +27,10 @@ use strict;
 #   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
+#       with LDAP sudoRunAs{Group,User} applies to all commands in a sudoRole
 
 my %RA;
 my %UA;
@@ -42,6 +41,8 @@ my @options=();
 
 my $did_defaults=0;
 my $order = 0;
+my %seen_users;
+my $assignment= qr/^(\S+)\s+(.+)=\s*(.*)/;
 
 # parse sudoers one line at a time
 while (<>){
@@ -61,11 +62,14 @@ while (<>){
   if (/^Defaults\s+/i) {
     my $opt=$';
     $opt=~s/\s+$//; # remove trailing whitespace
-    push @options,$opt;
-  } elsif (/^(\S+)\s+([^=]+)=\s*(.*)/) {
+    if (/$assignment/) {
+        $opt = join('', parse_assignment($opt));
+    }
+    push @options, $opt;
+  } elsif (/$assignment/) {
 
     # Aliases or Definitions
-    my ($p1,$p2,$p3)=($1,$2,$3);
+    my ($p1,$p2,$p3)=parse_assignment($');
     $p2=~s/\s+$//; # remove trailing whitespace
     $p3=~s/\s+$//; # remove trailing whitespace
 
@@ -91,26 +95,33 @@ while (<>){
       }
       # Definition
       my @users=split /\s*,\s*/,$p1;
+      my $username = @users[0];
+      if ($seen_users{$username}) {
+          $seen_users{$username} += 1;
+          $username = sprintf("%s_%s", $username, $seen_users{$username});
+      } else {
+          $seen_users{$username} = 1;
+      }
       my @hosts=split /\s*,\s*/,$p2;
       my @cmds= split /\s*,\s*/,$p3;
       @options=();
-      print "dn: cn=$users[0],$base\n";
+      print "dn: cn=$username,$base\n";
       print "objectClass: top\n";
       print "objectClass: sudoRole\n";
-      print "cn: $users[0]\n";
+      print "cn: $username\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]));
-	  }
-	}
+        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;
@@ -124,6 +135,12 @@ while (<>){
 
 }
 
+sub parse_assignment{
+    my $line=shift;
+    $line=~/$assignment/;
+    return ($1,$2,$3);
+}
+
 #
 # recursively expand hash elements
 sub expand{
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.