32bb043a8d038847be607ba0ff316348d8dc4a40
[samba] / examples / LDAP / smbldap-tools-0.9.1 / doc / smbldap-migrate-unix-groups
1 #!/usr/bin/perl -w
2
3 # Created by P.Wieleba@iem.pw.edu.pl in 2004
4
5 use strict;
6 use Getopt::Std;
7 use FindBin;
8 use FindBin qw($RealBin);
9 use lib "$RealBin/";
10 use smbldap_tools;
11
12 # function declaration
13 sub exist_in_tab;
14 sub add_to_tab;
15
16 # smbldap-migrate-unix-groups (-? or -h for help)
17 #
18 #
19
20 my %Options;
21
22 my $ok = getopts('G:nv?ha', \%Options);
23
24 if ( (!$ok) || ($Options{'?'}) || ($Options{'h'}) || (!keys(%Options)) ) {
25   print "Usage: $0 [-Gnv?ha]\n";
26   print "  -?|-h      show this help message\n";
27   print "  -G file    import group file\n";
28   print "  -v         displays modified entries to STDOUT\n";
29   print "  -n         do everything execpt updating LDAP\n";
30   print "  -a         adds sambaGroupMapping objectClass\n";
31   exit (1);
32 }
33
34 my $INFILE = undef;
35
36 if ( $Options{'G'} ) {
37   open($INFILE,$Options{'G'}) or
38     die "I cannot open file: " . $Options{'G'} . "\n";
39 }
40
41 my $ldap_master=connect_ldap_master();
42
43 while ( my $line=<$INFILE> ) {
44   chop($line);
45   next if ( $line =~ /^\s*$/ ); # whitespace
46   next if ( $line =~ /^#/ );
47   next if ( $line =~ /^\+/ );
48   my $entry = undef;
49   if ($Options{'G'}) {
50     my($group, $pwd, $gid, $users) = split(/:/,$line);
51     # if user is not in LDAP new entry will be created
52     $entry = get_group_entry($ldap_master,$group);
53     $entry = migrate_group($entry,$group, $pwd, $gid, $users);
54   }
55         
56   if ($entry) {
57     # if used "-a" and sambaGroupMapping doesn't exist.
58     if ( $Options{'a'} and !exist_in_tab([$entry->get_value('objectClass')],'sambaGroupMapping') ) {
59       my @objectClass = $entry->get_value( 'objectClass' );
60       $entry->replace( 'objectclass' => [add_to_tab(\@objectClass,'sambaGroupMapping')] );
61
62       # the below part comes from smbldap-groupadd and
63       # maybe it should be replaced by a new subroutine.
64       my $groupGidNumber = $entry->get_value('gidNumber');
65       # as rid we use 2 * gid + 1001
66       my $group_rid = 2*$groupGidNumber+1001;
67       # let's test if this SID already exist
68       my $group_sid = "$config{SID}-$group_rid";
69       my $test_exist_sid=does_sid_exist($group_sid,$config{groupsdn});
70       if ($test_exist_sid->count == 1) {
71         warn "Group SID already owned by\n";
72                                 # there should not exist more than one entry, but ...
73         foreach my $entry ($test_exist_sid->all_entries) {
74           my $dn= $entry->dn;
75           chomp($dn);
76           warn "$dn\n";
77         }
78       } else {
79         $entry->replace( 'sambaSID' => $group_sid );
80         $entry->replace( 'sambaGroupType' => group_type_by_name('domain') );
81       }
82     }
83
84     if ($Options{'v'}) {
85       $entry->dump();
86     }
87     if (!$Options{'n'}) {
88       my $mesg = $entry->update($ldap_master);
89       if ($mesg->is_error()) {
90         print "Error: " . $mesg->error() . "\n";
91       }
92     }
93
94   }
95 }
96
97 $INFILE and close($INFILE);
98 # take down the session
99 $ldap_master and $ldap_master->unbind;
100
101 # returns updated $entry
102 sub migrate_group
103   {
104     my($entry,$group, $pwd, $gid, $users) = @_;
105
106     # posixGroup MUST ( cn $ gidNumber )
107     my @objectClass = $entry->get_value( 'objectClass' );
108     $entry->replace( 'objectClass' => [add_to_tab(\@objectClass,'posixGroup')] );
109
110     $entry->replace( 'cn' => $group );
111     ($pwd)       and $entry->replace( 'userPassword'  => "{crypt}" . $pwd );
112     ($gid ne "") and $entry->replace( 'gidNumber'     => $gid );
113
114     my @users = split(',',$users);
115     # choose only unique users
116     my %unique_users;
117     foreach my $user (@users) {
118       $unique_users{$user} = 1;
119     }
120     @users = keys(%unique_users);
121     ($users) and $entry->replace( 'memberUid' => [ @users ] );
122
123     return $entry;
124   }
125
126 # creates a _new_entry_ if group doesn't exist in ldap
127 # else return's ldap user entry
128 sub get_group_entry
129   {
130     my($ldap_master,$group) = @_;
131         
132     # do not use try read_user_entry()
133     my $mesg = $ldap_master->search( base => $config{groupsdn},
134                                      scope => 'one',
135                                      filter => "(cn=$group)"
136                                    );
137     my $entry;
138     if ( $mesg->count() != 1 ) {
139       $entry = Net::LDAP::Entry->new();
140       $entry->dn("cn=$group,$config{groupsdn}");
141     } else {
142       $entry = $mesg->entry(0); # ????
143     }
144     return $entry;
145   }
146
147 # Check if a $text element exists in @table
148 # eg. exist_in_tab(\@table,$text);
149 sub exist_in_tab
150   {
151     my($ref_tab,$text) = @_;
152     my @tab = @$ref_tab;
153
154     foreach my $elem (@tab) {
155       if ( lc($elem) eq lc($text) ) {
156         return 1;
157       }
158     }
159     return 0;
160   }
161
162 # Add $text to tab if it doesn't exist there
163 sub add_to_tab
164   {
165     my($ref_tab,$text) = @_;
166     my @tab = @$ref_tab;
167         
168     if ( !exist_in_tab(\@tab,$text) ) {
169       push(@tab,$text);
170     }
171     return @tab;
172   }
173
174
175 ########################################
176
177 =head1 NAME
178
179 smbldap-migrate-unix-groups - Migrate unix groups to LDAP
180
181 =head1 SYNOPSIS
182
183 smbldap-migrate-unix-groups [-G file] [-n] [-v] [-h] [-?] [-a]
184
185 =head1 DESCRIPTION
186
187 This command processes one file as defined by option and
188 creates new or changes existing ldap group entry.
189 New attributes are added, and existing are changed.
190 None of the existing attributes is deleted.
191
192 -G group_file
193        Processes group_file and uptades LDAP. Creates new ldap group
194        entry or just adds posixGroup objectclass and corresponding
195        attributes to the ldap group entry or just uptades their values.
196
197 -h     show the help message
198
199 -?     the same as -h
200
201 -v     displayes modified entries to STDOUT
202
203 -n     do everything execpt updating LDAP. It is useful when used
204        with -v switch.
205
206 -a     adds sambaGroupMapping objectClass, generates sambaSID
207        and adds sambaGroupType attribute
208
209 =cut
210
211 #'
212
213 # The End
214
215