syncing examples
[bbaumbach/samba-autobuild/.git] / examples / LDAP / convertSambaAccount
1 #!/usr/bin/perl  -w
2 ##
3 ## Convert an LDIF file containing sambaAccount entries
4 ## to the new sambaSamAccount objectclass
5 ##
6 ## Copyright Gerald (Jerry) Carter      2003
7 ##
8 ## Usage: convertSambaAccount --sid=<Domain SID> \
9 ##       --input=<input ldif> --output=<output ldif> \
10 ##       --changetype=[modify|add]
11 ##
12
13
14 use strict;
15 use Net::LDAP::LDIF;
16 use Getopt::Long;
17
18
19 ##############################################################################
20 ## local variables
21
22 my ( $domain, $domsid, $changetype );
23 my ( $ldif, $ldif2 );
24 my ( $entry, @objclasses, $obj );
25 my ( $is_samba_account, $is_samba_group );
26 my ( %attr_map, %group_attr_map, $key );
27 my ( @dels, $deletion, @adds, $addition );
28 my ( $result, %options );
29
30
31 ##############################################################################
32 ## Print the option usage
33
34 sub usage {
35
36         print "convertSambaAccount <options>\n";
37         print "Options:\n";
38         print "  --help         print this help message\n";
39         print "  --input        input LDIF filename\n";
40         print "  --output       output LDIF filename\n";
41         print "  --sid          domain SID\n";
42         print "  --changetype   [modify|add] (default is 'add')\n";
43 }
44
45
46 ##############################################################################
47 ##                               MAIN DRIVER                                ##
48 ##############################################################################
49
50 ##
51 ## hashes to map old attribute names to new ones 
52 ##
53
54 %attr_map = ( 
55         lmPassword      => 'sambaLMPassword',
56         ntPassword      => 'sambaNTPassword',
57         pwdLastSet      => 'sambaPwdLastSet',
58         pwdMustChange   => 'sambaPwdMustChange',
59         pwdCanChange    => 'sambaPwdCanChange',
60         homeDrive       => 'sambaHomeDrive',
61         smbHome         => 'sambaHomePath',
62         scriptPath      => 'sambaLogonScript',
63         profilePath     => 'sambaProfilePath',
64         kickoffTime     => 'sambaKickoffTime',
65         logonTime       => 'sambaLogonTime',
66         logoffTime      => 'sambaLogoffTime',
67         userWorkstations        => 'sambaUserWorkstations',
68         domain          => 'sambaDomainName',
69         acctFlags       => 'sambaAcctFlags',
70 );
71
72 %group_attr_map = (
73         ntSid           => 'sambaSID',
74         ntGroupType     => 'sambaGroupType',
75 );
76
77 ##
78 ## process command line args
79 ##
80
81 $result = GetOptions(\%options,
82                         "help", 
83                         "input=s", 
84                         "output=s", 
85                         "sid=s",
86                         "changetype=s");
87
88 if (!$result && ($#ARGV != -1)) {
89         usage();
90         exit 1;
91 }
92
93 if ( defined($options{'help'}) ) {
94         usage();
95         exit 0;
96 }
97
98
99 if ( !defined( $options{'sid'} ) ) {
100         print "You must provide a domain sid\n";
101         exit 1;
102 }
103
104 $domsid = $options{'sid'};
105
106 $changetype = 'add';
107 if ( defined( $options{'changetype'} ) ) {
108         $changetype = $options{'changetype'};
109 }
110
111 ##
112 ## open files
113 ##
114
115 $ldif = Net::LDAP::LDIF->new ($options{'input'}, "r") or die $!;
116
117 if ( "$changetype" eq "add" ) {
118         $ldif2 = Net::LDAP::LDIF->new ($options{'output'}, "w") or die $!;
119 }
120 elsif ( "$changetype" eq "modify" ) {
121         open( OUTPUT, ">$options{'output'}" ) or die $!;
122 }
123 else {
124         print "Bad changetype!\n";
125         exit 1;
126 }
127
128 ##
129 ## process LDIF 
130 ##
131
132 while ( !$ldif->eof ) {
133         undef ( $entry );
134         $entry = $ldif->read_entry();
135
136         ## skip entry if we find an error
137         if ( $ldif->error() ) {
138                 print "Error msg: ",$ldif->error(),"\n";
139                 print "Error lines:\n",$ldif->error_lines(),"\n";
140                 next;
141         }
142
143         ##
144         ## check to see if we have anything to do on this
145         ## entry.  If not just write it out
146         ##
147         @objclasses = $entry->get_value( "objectClass" );
148         undef ( $is_samba_account );
149         undef ( $is_samba_group );
150         @adds = ();
151         @dels = ();
152         foreach $obj ( @objclasses ) {
153                 if ( "$obj" eq "sambaAccount" ) {
154                         $is_samba_account = 1;
155                 } elsif ( "$obj" eq "sambaGroupMapping" ) {
156                         $is_samba_group = 1;
157                 }
158         }
159
160         if ( defined ( $is_samba_account ) ) {
161                 ##
162                 ## start editing the sambaAccount
163                 ##
164
165                 @dels = ( 'objectclass: sambaAccount', 'rid' );
166                 @adds = ('objectclass: sambaSamAccount', "sambaSID: " .  ${domsid} . "-" . ${entry}->get_value( 'rid' ) );
167                 $entry->delete( 'objectclass' => [ 'sambaAccount' ] );
168                 $entry->add( 'objectclass' => 'sambaSamAccount' );
169
170                 $entry->add( 'sambaSID' => $domsid."-".$entry->get_value( "rid" ) );
171                 $entry->delete( 'rid' );
172         
173                 if ( $entry->get_value( "primaryGroupID" ) ) {
174                         push @adds, "sambaPrimaryGroupSID: " . $domsid."-".$entry->get_value( "primaryGroupID" );
175                         push @dels, "primaryGroupID";
176                         $entry->add( 'sambaPrimaryGroupSID' => $domsid."-".$entry->get_value( "primaryGroupID" ) );
177                         $entry->delete( 'primaryGroupID' );
178                 }
179         
180
181                 foreach $key ( keys %attr_map ) {
182                         if ( defined($entry->get_value($key)) ) {
183                                 push @adds, "$attr_map{$key}: " . $entry->get_value($key);
184                                 push @dels, "$key";
185                                 $entry->add( $attr_map{$key} => $entry->get_value($key) );
186                                 $entry->delete( $key );
187                         }
188                 }
189         } elsif ( defined ( $is_samba_group ) ) {
190                 foreach $key ( keys %group_attr_map ) {
191                         if ( defined($entry->get_value($key)) ) {
192                                 push @adds, "$group_attr_map{$key}: " . $entry->get_value($key);
193                                 push @dels, "$key";
194                                 $entry->add( $group_attr_map{$key} => $entry->get_value($key) );
195                                 $entry->delete( $key );
196                         }
197                 }
198         }
199         
200         ## see if we should write full entries or only the changes
201         
202         if ( "$changetype" eq "add" ) {
203                 $ldif2->write_entry( $entry );
204         }
205         else {
206                 if ( defined ( $is_samba_account ) || defined ( $is_samba_group ) ){
207                         if ( @adds + @dels > 0 ) {
208                                 print OUTPUT "dn: " . $entry->dn . "\n";
209                                 foreach $addition (@adds) {
210                                         $addition =~ /(^\w+):/;
211                                         print OUTPUT "add: " . $1  . "\n";
212                                         print OUTPUT "$addition\n-\n";
213                                 }
214                                 foreach $deletion (@dels) {
215                                         if ( $deletion =~ /^(\w+):\s(.*)/ ) {
216                                                 print OUTPUT "delete: $1\n$1: $2\n-\n";
217                                         } else {
218                                                 print OUTPUT "delete: $deletion\n-\n"
219                                         }
220                                 }
221                                 print OUTPUT "\n"
222                         }
223                 }
224         }
225 }
226
227