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