#!/usr/bin/perl -w #---------------------------------------------------------------------- # copyright (C) 20102011 Firewall Services # dani@firewall-services.com # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # #---------------------------------------------------------------------- package esmith; use strict; use Errno; use esmith::ConfigDB; use esmith::AccountsDB; use esmith::util; use List::MoreUtils qw(uniq); use Net::LDAP; use Encode; use Text::Unaccent::PurePerl qw(unac_string); my $c = esmith::ConfigDB->open_ro; my $a = esmith::AccountsDB->open_ro; my $i = $c->get('ipasserelle'); my $ip = $i->prop('status') || 'disabled'; my $alias = $i->prop('LdapMailAlias') || 'disabled'; if (($ip eq 'disabled') || ($alias eq 'disabled')){ exit (0); } my $l = $c->get('ldap'); my $status = $l->prop('status') || "disabled"; unless ($status eq "enabled" ){ warn "Not running action script $0, LDAP service not enabled!\n"; exit(0); } my $hostname = $c->get('SystemName') || die("Couldn't determine system name"); $hostname = $hostname->value; my $domain = $c->get('DomainName') || die("Couldn't determine domain name"); $domain = $domain->value; my @accounts; my $account; my $event = shift || die "Event name must be specified"; if ($event eq 'ldap-update' or $event eq 'bootstrap-ldap-save' or $event =~ m/(pseudonym)\-(create|modify|delete)/){ @accounts = ($a->users,$a->groups); push(@accounts, $a->get('admin')); } else{ my @name = @ARGV; die "Account name argument missing." unless scalar (@name) >= 1; foreach my $name (@name){ $account = $a->get($name); die "Account $name not found.\n" unless defined $account; push @accounts, $account; } } my $base = esmith::util::ldapBase ($domain); my $pw = esmith::util::LdapPassword(); my $ldap = Net::LDAP->new('localhost') or die "$@"; $ldap->bind( dn => "cn=root,$base", password => $pw ); my $result; foreach my $acct (@accounts){ my $key = $acct->key; my @pseudo = ("$key"); foreach my $pseudo ($a->pseudonyms){ push (@pseudo, $pseudo->key) if ($pseudo->prop('Account') eq $key); } # Do another loop to include pseudonyms of pseudonyms foreach my $pseudo ($a->pseudonyms){ push (@pseudo, $pseudo->key) if ( grep { $_ eq $pseudo->prop('Account') } @pseudo ); } # Include AltEmailX addresses foreach my $alt qw(1 2 3 4){ push (@pseudo, $acct->prop('AltEmail' . $alt)) if ( ($acct->prop('AltEmail' . $alt) || '') ne '' ); } # Put PreferredMail at the top of the list @pseudo = ($acct->prop('PreferredEmail'), @pseudo) if ( ($acct->prop('PreferredEmail') || '') ne '' ); my @alias = (); foreach (@pseudo){ $_ = $_ . "\@$domain" if $_ !~ /\@/; push (@alias, unac_string(decode('utf-8',$_))); } @alias = uniq(@alias); my $ou = 'Users'; my $dn = 'uid'; if ($acct->prop('type') eq 'group'){ $ou = "Groups"; $dn = "cn"; } $result = $ldap->search(base => "ou=$ou,$base", filter => "$dn=$key"); $result->code && warn "failed to search for entry $dn=$key,ou=$ou,$base: ", $result->error; my @mails = (); foreach my $entry ($result->all_entries()){ push @mails, $entry->get_value('mail'); } my $alias = join('\0', sort @alias); my $mails = join('\0', sort @mails); unless ($alias eq $mails){ $result = $ldap->modify( "$dn=$key,ou=$ou,$base", replace => { mail => \@alias } ); $result->code && warn "failed to modify entry $dn=$key,ou=$ou,$base: ", $result->error; } } $ldap->unbind;