3
## Convert an LDIF file containing sambaAccount entries
4
## to the new sambaSamAccount objectclass
6
## Copyright Gerald (Jerry) Carter 2003
8
## Usage: convertSambaAccount --sid=<Domain SID> \
9
## --input=<input ldif> --output=<output ldif> \
10
## --changetype=[modify|add]
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
16
## Note the "-LL" so no additional comments are generated
25
##############################################################################
28
my ( $domain, $domsid, $changetype );
30
my ( $entry, @objclasses, $obj );
31
my ( $is_samba_account, $is_samba_group );
32
my ( %attr_map, %group_attr_map, $key );
33
my ( @dels, $deletion, @adds, $addition );
34
my ( $result, %options );
37
##############################################################################
38
## Print the option usage
42
print "convertSambaAccount <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";
52
##############################################################################
54
##############################################################################
57
## hashes to map old attribute names to new ones
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',
80
ntGroupType => 'sambaGroupType',
84
## process command line args
87
$result = GetOptions(\%options,
94
if (!$result && ($#ARGV != -1)) {
99
if ( defined($options{'help'}) ) {
105
if ( !defined( $options{'sid'} ) ) {
106
print "You must provide a domain sid\n";
110
$domsid = $options{'sid'};
113
if ( defined( $options{'changetype'} ) ) {
114
$changetype = $options{'changetype'};
121
$ldif = Net::LDAP::LDIF->new ($options{'input'}, "r") or die $!;
123
if ( "$changetype" eq "add" ) {
124
$ldif2 = Net::LDAP::LDIF->new ($options{'output'}, "w") or die $!;
126
elsif ( "$changetype" eq "modify" ) {
127
open( OUTPUT, ">$options{'output'}" ) or die $!;
130
print "Bad changetype!\n";
138
while ( !$ldif->eof ) {
140
$entry = $ldif->read_entry();
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";
150
## check to see if we have anything to do on this
151
## entry. If not just write it out
153
@objclasses = $entry->get_value( "objectClass" );
154
undef ( $is_samba_account );
155
undef ( $is_samba_group );
158
foreach $obj ( @objclasses ) {
159
if ( "$obj" eq "sambaAccount" ) {
160
$is_samba_account = 1;
161
} elsif ( "$obj" eq "sambaGroupMapping" ) {
166
if ( defined ( $is_samba_account ) ) {
168
## start editing the sambaAccount
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' );
176
$entry->add( 'sambaSID' => $domsid."-".$entry->get_value( "rid" ) );
177
$entry->delete( 'rid' );
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' );
187
foreach $key ( keys %attr_map ) {
188
if ( defined($entry->get_value($key)) ) {
189
push @adds, "$attr_map{$key}: " . $entry->get_value($key);
191
$entry->add( $attr_map{$key} => $entry->get_value($key) );
192
$entry->delete( $key );
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);
200
$entry->add( $group_attr_map{$key} => $entry->get_value($key) );
201
$entry->delete( $key );
206
## see if we should write full entries or only the changes
208
if ( "$changetype" eq "add" ) {
209
$ldif2->write_entry( $entry );
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";
220
foreach $deletion (@dels) {
221
if ( $deletion =~ /^(\w+):\s(.*)/ ) {
222
print OUTPUT "delete: $1\n$1: $2\n-\n";
224
print OUTPUT "delete: $deletion\n-\n"