[206] | 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 |
|
---|
| 20 | use strict;
|
---|
| 21 | use Net::LDAP::LDIF;
|
---|
| 22 | use Getopt::Long;
|
---|
| 23 |
|
---|
| 24 |
|
---|
| 25 | ##############################################################################
|
---|
| 26 | ## local variables
|
---|
| 27 |
|
---|
| 28 | my ( $domain, $domsid, $changetype );
|
---|
| 29 | my ( $ldif, $ldif2 );
|
---|
| 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 );
|
---|
| 35 |
|
---|
| 36 |
|
---|
| 37 | ##############################################################################
|
---|
| 38 | ## Print the option usage
|
---|
| 39 |
|
---|
| 40 | sub 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 |
|
---|
| 94 | if (!$result && ($#ARGV != -1)) {
|
---|
| 95 | usage();
|
---|
| 96 | exit 1;
|
---|
| 97 | }
|
---|
| 98 |
|
---|
| 99 | if ( defined($options{'help'}) ) {
|
---|
| 100 | usage();
|
---|
| 101 | exit 0;
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 |
|
---|
| 105 | if ( !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';
|
---|
| 113 | if ( 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 |
|
---|
| 123 | if ( "$changetype" eq "add" ) {
|
---|
| 124 | $ldif2 = Net::LDAP::LDIF->new ($options{'output'}, "w") or die $!;
|
---|
| 125 | }
|
---|
| 126 | elsif ( "$changetype" eq "modify" ) {
|
---|
| 127 | open( OUTPUT, ">$options{'output'}" ) or die $!;
|
---|
| 128 | }
|
---|
| 129 | else {
|
---|
| 130 | print "Bad changetype!\n";
|
---|
| 131 | exit 1;
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | ##
|
---|
| 135 | ## process LDIF
|
---|
| 136 | ##
|
---|
| 137 |
|
---|
| 138 | while ( !$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 |
|
---|