import HEAD into svn+ssh://svn.samba.org/home/svn/samba/trunk
[metze/old/v3-2-winbind-ndr.git] / examples / LDAP / smbldap-tools / smbldap-migrate-groups.pl
1 #!/usr/bin/perl
2
3 #  This code was developped by IDEALX (http://IDEALX.org/) and
4 #  contributors (their names can be found in the CONTRIBUTORS file).
5 #
6 #                 Copyright (C) 2002 IDEALX
7 #
8 #  This program is free software; you can redistribute it and/or
9 #  modify it under the terms of the GNU General Public License
10 #  as published by the Free Software Foundation; either version 2
11 #  of the License, or (at your option) any later version.
12 #
13 #  This program is distributed in the hope that it will be useful,
14 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #  GNU General Public License for more details.
17 #
18 #  You should have received a copy of the GNU General Public License
19 #  along with this program; if not, write to the Free Software
20 #  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 #  USA.
22
23 # Purpose of smbldap-migrate-groups : to parse a Windows
24 # group dump and populate Unix groups
25 # Reads group dump on stdin
26
27
28 use strict;
29 use FindBin;
30 use FindBin qw($RealBin);
31 use lib "$RealBin/";
32 use smbldap_tools;
33 use smbldap_conf;
34 use Getopt::Std;
35
36 sub process_rec_group
37   {
38     my ($group, $mb) = @_;
39     my @members;
40     
41     if (!(@members = group_get_members($group))) {
42           return 0;
43     }
44
45     foreach my $m (@members) {
46           if ( !($m =~ m/^\*/) ) {
47             push @{$mb}, $m;
48           } else {
49             my $gname = $m;
50             $gname =~ s/^.//;
51             if (!process_rec_group($gname, $mb)) {
52                   print "recursive group not added : $gname\n";
53             }
54           }
55     }
56   }
57
58
59 # given a group dn and a list of members, update the group
60 sub modify_group
61   {
62     my ($group, $dn_line, @members, $recgroup) = @_;
63     my $m;
64     my @new_mb;
65
66     foreach $m (@members) {
67           if ( ($m =~ m/^\*/) ) {
68             my $gname = $m;
69             $gname =~ s/^.//;
70             if (!$recgroup) {
71                   print "recursive group not added : $gname\n";
72             } else {
73                   if (!process_rec_group($gname, \@new_mb)) {
74                     print "recursive group not added : $gname\n";
75                   }
76             }
77           } else {
78             push @new_mb, $m;
79           }
80     }
81
82     # new_mb contains flat members from group dump
83     # now append them to existing members
84     push @new_mb, group_get_members($group);
85     # uniq them
86     my %saw;
87     @saw{@new_mb} = ();
88     @new_mb = keys %saw;
89
90     my $nmb = $#new_mb + 1;
91     print STDERR "Group $group now has $nmb member(s)\n"; 
92     
93     my $mbs;
94     foreach $m (@new_mb) {
95           $mbs .= "memberUid: $m\n";
96     }
97
98     my $mods="$dn_line
99 changetype: modify
100 replace: memberUid
101 $mbs
102 ";
103
104     #print "$mods\n";
105     my $tmpldif =
106           "$mods
107 ";
108
109     die "$0: error while modifying group $group\n"
110           unless (do_ldapmodify($tmpldif) == 0);
111     undef $tmpldif;
112   }
113
114 sub display_group
115   {
116     my ($group, @members) = @_;
117
118     print "Group name $group\n";
119     print "Members\n";
120     my $m;
121     my $i = 0;
122     foreach $m (@members) {
123           print "$m ";
124           if ($i % 5 == 0) {
125             print "\n";
126           }
127           $i++;
128     }
129   }
130
131 sub process_group
132   {
133     my ($group, @members, $nocreate, $noupdate, $recgroup) = @_;
134
135     my $dn_line;
136     if (!defined($dn_line = get_group_dn($group))) {
137           # group not found, create it ?
138           if (!$nocreate) {
139             system "/usr/local/sbin/smbldap-groupadd.pl \"$group\"; sleep 5";
140             if (!defined($dn_line = get_group_dn($group))) {
141                   return 1;
142             }
143             modify_group($group, $dn_line, @members, $recgroup);
144           } else {
145             # don't create
146             print "not created:\n";
147             display_group($group, @members);
148           }
149     } else {
150           # group found, update it ?
151           if (!$noupdate) {
152             modify_group($group, $dn_line, @members, $recgroup);
153           } else {
154             # don't update
155             print "not updated:\n";
156             display_group($group, @members);    
157           }
158     }
159   }
160
161 ###################################################
162
163 my %Options;
164
165 my $ok = getopts('CUr?', \%Options);
166 if ( (!$ok) || ($Options{'?'}) ) {
167   print "Usage: $0 [-CUr?] < group_dump\n";
168   print "  -C       don't create group if it doesn't exist\n";
169   print "  -U       don't update group if it exists\n";
170   print "  -r       recursively process groups\n";
171   exit(1);
172 }
173
174 my $group_name;
175 my $group_desc;
176 my $has_members = 0;
177 my @members = ();
178
179 while (<>) {
180   my $line = $_;
181   chomp($line);
182   next if ( $line =~ m/^\s*$/ );
183
184   if ($group_name eq "") {
185         if ( $line =~ m/^Group name\s+(.+).$/ ) {
186           $group_name = $1;
187           next;
188         }
189   }
190   if ($group_desc eq "") {
191         if ( $line =~ m/^Comment\s+(.*)$/ ) {
192           $group_desc = $1;
193           next;
194       }
195   }
196   next if ( $line =~ m/^-+.$/ );
197   if (!$has_members) {
198       if ( $line =~ m/^Members/ ) {
199           $has_members = 1;
200           next;
201       }
202   } else {
203       if ( $line =~ m/^The command completed successfully/ ) {
204           last;
205       } else {
206           push(@members, split(/\s+/, $line));
207           next;
208       }
209   }
210
211   #print;
212 }
213
214 if ( $#members > -1) {
215     process_group($group_name, @members, $Options{'C'}, $Options{'U'}, $Options{'r'});
216 }
217
218 #print "gn=$group_name\n";
219 #print "gd=$group_desc\n";
220 #my $m;
221 #foreach $m (@members)
222 #{
223 #    print "$m ";
224 #}
225 #print "\n";