Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/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};
- #}}}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement