Rt logins email2ldap
Jump to navigation
Jump to search
Introduction
- First script : Rename email addresses to AD/LDAP usernames
- Second script: Notify users their login changed
Rename email addresses to AD/LDAP usernames
rt_logins_email2ldap
#!/usr/bin/perl # Name: rt_logins_email2ldap # Description: # This script checks the users logins in a LDAP or AD directory and # rename the RT email logins with these logins. # # It does also some clean-up in the RT User database. # # It might be useful for you if: # - you use LDAP/AD authentication on RT # - it was setup before the automatic user creation with LDAP/AD # logins # # Run rt_logins_email2ldap -h for additionnal information # # Author: Christophe Sahut <christophe.sahut {at} sgs {dot} com> # License: This module is free software; you can redistribute it # and/or modify it under the GPLv2 licence. # # Version 0.01: 21 Jan 2010 : initial release # use strict; use Getopt::Std; use Net::LDAP; use lib qw(/opt/rt/lib); use RT; use RT::Queues; use RT::User; RT::LoadConfig(); RT::Init(); my $VERSION = '0.01'; my ($ldapserver,$ldapuser,$ldappass,$ldapbase,$ldapfilter,$ldapnet_ldap_args,$ldapattr_map_name,@myexceptions,$domain); # CONFIGURATION ############################################################################### # > General ############################################################################### # Local account to ignore (root,Nobody,RT_System are ignored by default): #@myexceptions = qw(local1 local2 local3); # The domain used for your email addresses $domain = '@foobar.com'; ############################################################################### # > LDAP : # This configuration is not necessary if you already use RT-Authen-ExternalAuth ############################################################################### #$ldapserver = 'server'; #$ldapuser = 'cn=user,ou=foo,dc=bar' ; #$ldappass = 'pass' ; #$ldapbase = 'base' ; #$ldapfilter = '(objectClass=organizationalPerson)(!(sAMAccountName=adm*))'; #$ldapnet_ldap_args = '[port=>"3268", version=>"3"]'; #$ldapattr_map_name = 'sAMAccountName'; ############################################################################### # sub usage {{{ sub usage() { print STDERR << "EOF"; rt_logins_email2ldap Version ${VERSION} This program cleans up RT User DB and can rename email accounts to LDAP/AD logins. You can run it without arguments, it'll show you the potential problems you might have to resolve before running this script on your RT DB. usage: $0 [-hawv] [-f file] -v : verbose mode, displays what would be done if -w is used -a : Run on all the users (default runs for privileged users only) -w : WRITE the changes to the db -f file : write old/new usernames to file, to be used as an input of send_login_modif_notification.pl -h : this (help) message Recommended usage: * Run these commands: rt_logins_email2ldap # Check the potential problems and fix them. Such as: - duplicate logins in the directory for the same email - user with LDAP login already existing in RT rt_logins_email2ldap -v # Check what would be done To check the real changes: rt_logins_email2ldap -v | grep -v "LoginOK\\|External\\|Local" * Add to \@myexceptions variable the local privileged accounts you don't want to rename. * Run again the two previous commands * Backup your user table (something like "create table users_backup as select * from users;" ) rt_logins_email2ldap -v -f privileged.txt -w # Rename the privileged accounts, write the output into privileged.txt rt_logins_email2ldap -v # Check what would be done To check the real changes: rt_logins_email2ldap -v | grep -v "LoginOK\\|External\\|Local" Do the same with -a option to run the script on all the users rt_logins_email2ldap -v -a -f all.txt -w # Rename all the accounts, write the output into all.txt rt_logins_email2ldap -v -a # Check what has been done If an unprivileged user with something\@domain.com email address exists, and another privileged user with the same email address, we assume that the privileged user should have the LDAP login. That's why the script is run first on privileged users, and then on all the users. EOF exit; } # }}} # sub return_ldap_login {{{ # This function takes an email as argument and returns the ldap login sub return_ldap_login { my $email = shift(@_) ; my $return = 0; my ($entry,$ldaplogin); my $ldap = Net::LDAP->new($ldapserver,@$ldapnet_ldap_args) or die "$@"; my $mesg = $ldap->bind($ldapuser, password => $ldappass ); my $result = $ldap->search ( base => $ldapbase, filter => "(&$ldapfilter(mail=$email))", attrs => "['$ldapattr_map_name']" ); my @entries = $result->entries; # Many times the same email for different sAMAccountNames $return = 1 if (@entries > 1); foreach $entry (@entries) { $ldaplogin .= $entry->get_value($ldapattr_map_name).","; } $ldaplogin =~ s/,$//; return ($return,$ldaplogin); } # }}} # Main {{{ # Get configuration from RT Config # Only managing first source for now my $service = @$RT::ExternalAuthPriority[0]; my $config = $RT::ExternalSettings->{$service}; $ldapserver = $config->{'server'} unless $ldapserver; $ldapuser = $config->{'user'} unless $ldapuser; $ldappass = $config->{'pass'} unless $ldappass; $ldapbase = $config->{'base'} unless $ldapbase; $ldapfilter = $config->{'filter'} unless $ldapfilter; $ldapnet_ldap_args = $config->{'net_ldap_args'} unless $ldapnet_ldap_args; $ldapattr_map_name = $config->{'attr_map'}->{'Name'} unless $ldapattr_map_name; my @exceptions = (qw(root Nobody RT_System), @myexceptions); # Options my %options = (); getopts("vawhf:",\%options) or usage(); my $write=$options{w}?1:0; my $verbose=$options{v}?1:0; usage() if $options{h}; my ($return,$message,$emailnotificationlist); my $users = RT::Users->new(RT->SystemUser); open(FILE,"> ".$options{f}) if $options{f}; if ($options{a}){ $users->UnLimit(); } else { $users->LimitToPrivileged(); } while ( my $user = $users->Next ) { # LOCAL ACCOUNTS (exceptions): skipping to the next entry if ( grep {$_ eq $user->Name} @exceptions) { print "[Local] [".$user->Name." -> don't touch: local account / exception] Email:".$user->EmailAddress."\n" if($verbose); next; } # One of our domain email addresses if ($user->EmailAddress =~ m/$domain/i ){ my $cleanedemail = $user->EmailAddress; # Protection of @ sign $cleanedemail =~ s/@/\\@/; # Keep only first email if account contains several emails $cleanedemail =~ s/([^,]*),.*/$1/; # Remove spaces $cleanedemail =~ s/\ //g; # Get LDAP/AD login my ($return,$exist) = return_ldap_login("$cleanedemail"); # Remove the protection on @ sign $cleanedemail =~ s/\\//g; if ( $return == 1 ){ print STDERR "[DUPLICATES] [".$user->Name." -> ".$exist." ??? Check your ldap filter, at least 2 accounts with the same ".$user->EmailAddress." email were found in your directory.\n"; next; } # One of our addresses but no entry in LDAP : disabling account because probably wrong # It's renamed because if the RT login is already a valid AD login, it'll cause trouble for other valid emails/logins if ( $exist eq "" ) { print "[DisableRename] [".$user->Name." -> disabled + renamed -disablednotinDirectory] Email:".$user->EmailAddress."\n" if($verbose); if ($write) { ($return,$message)=$user->SetName($user->Name."-disablednotindirectory"); print "--> Setting name ".$message."\n"; ($return,$message)=$user->SetDisabled(1); print "---> Disabling user: ".$message."\n"; } } elsif (lc($exist) eq lc($user->Name)){ # Login already LDAP/AD login, doing nothing print "[LoginOK] [".$user->Name." -> already LDAP login] Email:".$user->EmailAddress."\n" if($verbose); } else { # One of our email addresses and not the good LDAP login but a good LDAP entry exists for this email address in the directory # Check if LDAP login already used in RT my $tempuser = RT::User->new(RT->SystemUser); $tempuser->Load($exist); if ( $tempuser->Id ) { # It's already used ! # Keep privileged user, rename and disable this one: in the furture, merge these entries ? if($tempuser->Privileged and ! $user->Privileged) { print "[Disable] [".$user->Name." -> disabled ] Keeping ".$tempuser->Name." with Id ".$tempuser->Id." Email:".$user->EmailAddress."\n" if($verbose); if ($write) { $exist .= "-disablednotprivileged"; ($return,$message)=$user->SetName($exist); print "--> Setting name ".$message."\n"; ($return,$message)=$user->SetDisabled(1); print "---> Disabling user: ".$message."\n"; } } else { # LDAP login used: to be managed manually. # Login to RT, cehck the two accounts, rename login of one of them and disable it print "[LOGIN USED] [".$user->Name.": LDAP login \"".$exist."\" already used by user with id ".$user->Id.". You should check manually which one you want to keep...]\n"; } } else { # LDAP login not used yet: rename to LDAP login print "[Rename] [".$user->Name." -> ". $exist ."] Email:".$user->EmailAddress."\n" if($verbose); print FILE $user->Name.";".$exist.";".$cleanedemail."\n" if $options{f}; if ($write) { ($return,$message)=$user->SetName($exist); print "--> Setting name ".$message."\n"; } $emailnotificationlist .= $cleanedemail.";"; } } } # Extenal email addresses and looks like an email address : keep it as it is, probably external users elsif ($user->EmailAddress =~ m/.*\@.*\..*/) { print "[External] [".$user->Name." -> Don't touch: external email] Email:".$user->EmailAddress."\n" if($verbose); } # Strange entry : doesn't look like an email else { print "[Disable] [".$user->Name." -> disabled] Email:".$user->EmailAddress."\n" if($verbose); if ($write) { ($return,$message)=$user->SetDisabled(1); print "--> Disabling user: ".$message."\n"; } } } print "\nPeople to notify: ".$emailnotificationlist."\n" if $options{f}; close(FILE)if $options{f}; #}}}
Notify users their login changed
send_login_modif_notification.pl
#!/usr/bin/perl use strict; use Mail::Mailer; use Getopt::Std; my %options = (); getopts("f:",\%options) or usage(); my $RTURL="http://rt.foobar.com"; my $RTADMINS="Mr Foo, Mr Bar"; my $someexceptions="account1, account2"; my $domain="foobar.com"; my $mydirectory="Active Directory"; open(FILE,"< ".$options{f}) or die "File ".$options{f}." not found"; while(<FILE>){ my ($oldlogin,$newlogin,$email) = split(';',$_); my $mailer = Mail::Mailer->new(); $mailer->open({ From => 'RT System <rt-noreply@'.$domain.'>', To => $email, Subject => "$mydirectory authentication on $RTURL", }) or die "open impossible : $!\n"; print $mailer " Dear RT user, $RTURL is now linked to $mydirectory. Your login on this system was \"$oldlogin\" and is now your $mydirectory login \"$newlogin\". Your old local password will still work for a couple of weeks and will then be disabled, your $mydirectory password will be the only one to work. Please logout and login with this new login and your $mydirectory password. Note the local accounts such as $someexceptions will still work with the local password. Don't hesitate to contact us if you have any trouble. Best regards, $RTADMINS "; close($mailer); print "Email sent to $email\n"; }