#!/usr/bin/perl -w

=head1 NAME

findInGroups.pl
 v1.0  15-Nov-2016

=head1 DESCRIPTION

A script for finding a user in Groups and Mailing Lists

The script is launched from command line as:
  perl findInGroups.pl account@domain

     
=head1 AUTHORS

Roman Prokhorov <roma@communigatepro.ru>

=cut


use strict;
use Data::Dumper;
use CLI;  #get one from communigatepro.ru/CGPerl

####  YOU SHOLD REDEFINE THESE VARIABLES !!!

my $CGServerAddress='127.0.0.1';  #IP or domain name;
my $Login='postmaster';
my $Password='pass';

my $checkForwarders=1; # check Forwarders pointing to the account 
my $checkLists=1;      # look for in mailing lists
my $checkAllDomains=0; # check either all or only local domain

#### end of the customizeable variables list

if(@ARGV != 1) {
  die "Usage: ./findInGroups.pl account\@domain\n";
}

my $cli = new CGP::CLI( { PeerAddr => $CGServerAddress,
                          PeerPort => 106,
                          login    => $Login,
                          password => $Password } )
   || die "*** Can't login to CGPro CLI: ".$CGP::ERR_STRING."\n";

my $addr=checkAddress($ARGV[0]);
unless($addr) {
  $cli->Logout();
  die " $ARGV[0] is not a local account\n";
}

my($username,$domainname,$account);

if($addr=~/(.*)\@(.*)/) {
  ($username,$domainname)=($1,$2);
  $account="$username\@$domainname";
} else {
  ($username,$domainname)=($addr,"");
  $account=$username;
}
print "Account: $account\n";


if($checkAllDomains) { processAllDomains();} else {processDomain($domainname);}

print "Done.\n";
$cli->Logout();
exit;


sub processAllDomains {
  my $DomainList = $cli->ListDomains();
  unless($DomainList) {
    $cli->Logout();
    die "*** Can't get the domain list: ".$cli->getErrMessage.", quitting";
  }  
  foreach(@$DomainList) {
    processDomain($_);
  }
}         

sub processDomain {
  my $domain=$_[0];

  my $groupList = $cli->ListGroups($domain);
  unless($groupList) {
    print "*** Can't get groups for '$domain': ".$cli->getErrMessage."\n";
    return;
  }  
  foreach(@$groupList) {
    my $name=$_;   
    $name.='@'.$domain if($domain);
    my $settings=$cli->GetGroup($name);
    unless($settings) {
      print "*** GetGroup failed for $name:".$cli->getErrMessage."\n";
      next;
    }
    my $members=$settings->{Members};
    foreach(@$members) {
      my ($a0,$a)=($_,$_);      
      $a.='@'.$domain if($domain && $a!~/\@/);     
      $a=checkAddress($a);
      if($a && $a eq $account) {
         print "Group '$name': $a0\n";
      }
    }
  }
    
  if($checkForwarders) {
    my $ForwardersList = $cli->ListForwarders($domain);
    unless($ForwardersList) {
      print "*** ListForwarders failed for '$domain': ".$cli->getErrMessage."\n";
      return;
    }  
    foreach(@$ForwardersList) {
      my $name=$_;
      $name.='@'.$domain if($domain);
      my $a=$cli->GetForwarder($name);
      unless($a) {
        print  "*** GetForwarder failed for $name: ".$cli->getErrMessage."\n";
        next;
      }
      my $a0=$a;
      $a.='@'.$domain if($domain && $a!~/\@/);
      $a=checkAddress($a);
      if($a && $a eq $account) {
        print "Forwarder '$name': $a0\n";
      }
    }
  }
  
  if($checkLists) {
    my $ListsList = $cli->ListLists($domain);
    unless($ListsList) {
      print "*** ListLists failed for '$domain': ".$cli->getErrMessage."\n";
      return;
    }
    foreach(@$ListsList) {
      my $name=$_;
      $name.='@'.$domain if($domain);
      my $l=$cli->ListSubscribers($name);
      unless($l) {
        print  "*** ListSubscribers failed for $name: ".$cli->getErrMessage."\n";
        next;
      }
      foreach(@$l) {
        my ($a0,$a)=($_,$_);    
        $a.='@'.$domain if($domain && $a!~/\@/);     
        $a=checkAddress($a);
        if($a && $a eq $account) {
           print "List '$name': $a0\n";
        }
      }
    }    
  }
  
}

sub checkAddress {
  my $data=$cli->Route($_[0],"mail");
  return undef unless($data);
  return undef if($data->[0] ne 'LOCAL');
  return $data->[1];
}

__END__
