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 |
|
---|