1#!/usr/bin/perl -w 2 3# Created by P.Wieleba@iem.pw.edu.pl in 2004 4 5use strict; 6use Getopt::Std; 7use FindBin; 8use FindBin qw($RealBin); 9use lib "$RealBin/"; 10use smbldap_tools; 11 12# function declaration 13sub exist_in_tab; 14sub add_to_tab; 15 16# smbldap-migrate-unix-groups (-? or -h for help) 17# 18# 19 20my %Options; 21 22my $ok = getopts('G:nv?ha', \%Options); 23 24if ( (!$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 34my $INFILE = undef; 35 36if ( $Options{'G'} ) { 37 open($INFILE,$Options{'G'}) or 38 die "I cannot open file: " . $Options{'G'} . "\n"; 39} 40 41my $ldap_master=connect_ldap_master(); 42 43while ( 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 102sub 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 128sub 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); 149sub 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 163sub 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 179smbldap-migrate-unix-groups - Migrate unix groups to LDAP 180 181=head1 SYNOPSIS 182 183smbldap-migrate-unix-groups [-G file] [-n] [-v] [-h] [-?] [-a] 184 185=head1 DESCRIPTION 186 187This command processes one file as defined by option and 188creates new or changes existing ldap group entry. 189New attributes are added, and existing are changed. 190None 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 216