#!/usr/bin/perl # $Id: smbldap-migrate-groups,v 1.5 2005/01/08 12:04:45 jtournier Exp $ # # This code was developped by IDEALX (http://IDEALX.org/) and # contributors (their names can be found in the CONTRIBUTORS file). # # Copyright (C) 2002 IDEALX # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, # USA. # Purpose of smbldap-migrate-groups : to parse a Windows # group dump and populate Unix groups # Reads group dump on stdin use strict; use FindBin; use FindBin qw($RealBin); use lib "$RealBin/"; use smbldap_tools; use Getopt::Std; sub process_rec_group { my ($group, $mb) = @_; my @members; if (!(@members = group_get_members($group))) { return 0; } foreach my $m (@members) { if ( !($m =~ m/^\*/) ) { push @{$mb}, $m; } else { my $gname = $m; $gname =~ s/^.//; if (!process_rec_group($gname, $mb)) { print "recursive group not added : $gname\n"; } } } } # given a group dn and a list of members, update the group sub modify_group { my ($group, $dn_line, @members, $recgroup) = @_; my $m; my @new_mb; foreach $m (@members) { if ( ($m =~ m/^\*/) ) { my $gname = $m; $gname =~ s/^.//; if (!$recgroup) { print "recursive group not added : $gname\n"; } else { if (!process_rec_group($gname, \@new_mb)) { print "recursive group not added : $gname\n"; } } } else { push @new_mb, $m; } } # new_mb contains flat members from group dump # now append them to existing members push @new_mb, group_get_members($group); # uniq them my %saw; @saw{@new_mb} = (); @new_mb = keys %saw; my $nmb = $#new_mb + 1; print STDERR "Group $group now has $nmb member(s)\n"; my $mbs; foreach $m (@new_mb) { $mbs .= "memberUid: $m\n"; } my $mods="$dn_line changetype: modify replace: memberUid $mbs "; #print "$mods\n"; my $tmpldif = "$mods "; die "$0: error while modifying group $group\n" unless (do_ldapmodify($tmpldif) == 0); undef $tmpldif; } sub display_group { my ($group, @members) = @_; print "Group name $group\n"; print "Members\n"; my $m; my $i = 0; foreach $m (@members) { print "$m "; if ($i % 5 == 0) { print "\n"; } $i++; } } sub process_group { my ($group, @members, $nocreate, $noupdate, $recgroup) = @_; my $dn_line; if (!defined($dn_line = get_group_dn($group))) { # group not found, create it ? if (!$nocreate) { system "/usr/local/sbin/smbldap-groupadd \"$group\"; sleep 5"; if (!defined($dn_line = get_group_dn($group))) { return 1; } modify_group($group, $dn_line, @members, $recgroup); } else { # don't create print "not created:\n"; display_group($group, @members); } } else { # group found, update it ? if (!$noupdate) { modify_group($group, $dn_line, @members, $recgroup); } else { # don't update print "not updated:\n"; display_group($group, @members); } } } ################################################### my %Options; my $ok = getopts('CUr?', \%Options); if ( (!$ok) || ($Options{'?'}) ) { print "Usage: $0 [-CUr?] < group_dump\n"; print " -C don't create group if it doesn't exist\n"; print " -U don't update group if it exists\n"; print " -r recursively process groups\n"; exit(1); } my $group_name; my $group_desc; my $has_members = 0; my @members = (); while (<>) { my $line = $_; chomp($line); next if ( $line =~ m/^\s*$/ ); if ($group_name eq "") { if ( $line =~ m/^Group name\s+(.+).$/ ) { $group_name = $1; next; } } if ($group_desc eq "") { if ( $line =~ m/^Comment\s+(.*)$/ ) { $group_desc = $1; next; } } next if ( $line =~ m/^-+.$/ ); if (!$has_members) { if ( $line =~ m/^Members/ ) { $has_members = 1; next; } } else { if ( $line =~ m/^The command completed successfully/ ) { last; } else { push(@members, split(/\s+/, $line)); next; } } #print; } if ( $#members > -1) { process_group($group_name, @members, $Options{'C'}, $Options{'U'}, $Options{'r'}); } #print "gn=$group_name\n"; #print "gd=$group_desc\n"; #my $m; #foreach $m (@members) #{ # print "$m "; #} #print "\n";