Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Centos 7 getadsmtp.pl outputing blank

by gml_perl (Initiate)
on Jun 13, 2018 at 10:14 UTC ( #1216545=perlquestion: print w/replies, xml ) Need Help??
gml_perl has asked for the wisdom of the Perl Monks concerning the following question:

I am running getadsmtp.pl script to pull email addresses from the active directory on Centos 7 perl version v5.16.3 but it not outputing anything. I have the same script running on Ubuntu 14 perl version 5.10.0 and Centos 6.5 perl version 5.10.1 perfectly. Can you assist?

getadsmtp.pl code

#!/usr/bin/perl -T -w # Version 1.01 # This script will pull all users' SMTP addresses from your Active Dir +ectory # (including primary and secondary email addresses) and list them in t +he # format "user@example.com OK" which Postfix uses with relay_recipient +_maps. # Be sure to double-check the path to perl above. # This requires Net::LDAP to be installed. To install Net::LDAP, at a + shell # type "perl -MCPAN -e shell" and then "install Net::LDAP" use Net::LDAP; use Net::LDAP::Control::Paged; use Net::LDAP::Constant ( "LDAP_CONTROL_PAGED" ); # Enter the path/file for the output $VALID = "/etc/postfix/ad_28vegas"; # Enter the FQDN of your Active Directory domain controllers below $dc1="srvleon.verpakt.com"; $dc2="srvdeon.verpakt.com"; # Enter the LDAP container for your userbase. # The syntax is CN=Users,dc=example,dc=com # This can be found by installing the Windows 2000 Support Tools # then running ADSI Edit. # In ADSI Edit, expand the "Domain NC [domaincontroller1.example.com]" + & # you will see, for example, DC=example,DC=com (this is your base). # The Users Container will be specified in the right pane as # CN=Users depending on your schema (this is your container). # You can double-check this by clicking "Properties" of your user # folder in ADSI Edit and examining the "Path" value, such as: # LDAP://domaincontroller1.example.com/CN=Users,DC=example,DC=com # which would be $hqbase="cn=Users,dc=example,dc=com" # Note: You can also use just $hqbase="dc=example,dc=com" $hqbase="ou=28vegas,ou=Verpakt casino's,dc=verpakt,dc=com"; # Enter the username & password for a valid user in your Active Direct +ory # with username in the form cn=username,cn=Users,dc=example,dc=com # Make sure the user's password does not expire. Note that this user # does not require any special privileges. # You can double-check this by clicking "Properties" of your user in # ADSI Edit and examining the "Path" value, such as: # LDAP://domaincontroller1.example.com/CN=user,CN=Users,DC=example,DC= +com # which would be $user="cn=user,cn=Users,dc=example,dc=com" # Note: You can also use the UPN login: "user\@example.com" $user="cn=debian,cn=Users,dc=verpakt,dc=com"; $passwd="Yuuthw1"; # Connecting to Active Directory domain controllers $noldapserver=0; $ldap = Net::LDAP->new($dc1) or $noldapserver=1; if ($noldapserver == 1) { $ldap = Net::LDAP->new($dc2) or die "Error connecting to specified domain controllers $@ \n"; } $mesg = $ldap->bind ( dn => $user, password =>$passwd); if ( $mesg->code()) { die ("error:", $mesg->code(),"\n"); } # How many LDAP query results to grab for each paged round # Set to under 1000 for Active Directory $page = Net::LDAP::Control::Paged->new( size => 990 ); @args = ( base => $hqbase, # Play around with this to grab objects such as Contacts, Public Folde +rs, etc. # A minimal filter for just users with email would be: # filter => "(&(sAMAccountName=*)(mail=*))" filter => "(& (mailnickname=*) (| (&(objectCategory=person) (objectClass=user)(!(homeMDB=*))(!(msExchHomeServe +rName=*))) (&(objectCategory=person)(objectClass=user)(|(home +MDB=*) (msExchHomeServerName=*)))(&(objectCategory=person +)(objectClass=contact)) (objectCategory=group)(objectCategory=publicFolder +) ))", control => [ $page ], attrs => "proxyAddresses", ); my $cookie; while(1) { # Perform search my $mesg = $ldap->search( @args ); # Filtering results for proxyAddresses attributes foreach my $entry ( $mesg->entries ) { my $name = $entry->get_value( "cn" ); # LDAP Attributes are multi-valued, so we have to print each one. foreach my $mail ( $entry->get_value( "proxyAddresses" ) ) { # Test if the Line starts with one of the following lines: # proxyAddresses: [smtp|SMTP]: # and also discard this starting string, so that $mail is only th +e # address without any other characters... if ( $mail =~ s/^(smtp|SMTP)://gs ) { push(@valid, $mail." OK\n"); } } } # Only continue on LDAP_SUCCESS $mesg->code and last; # Get cookie from paged control my($resp) = $mesg->control( LDAP_CONTROL_PAGED ) or last; $cookie = $resp->cookie or last; # Set cookie in paged control $page->cookie($cookie); } if ($cookie) { # We had an abnormal exit, so let the server know we do not want any + more $page->cookie($cookie); $page->size(0); $ldap->search( @args ); # Also would be a good idea to die unhappily and inform OP at this p +oint die("LDAP query unsuccessful"); } # Only write the file once the query is successful open VALID, ">$VALID" or die "CANNOT OPEN $VALID $!"; print VALID @valid; # Add additional restrictions, users, etc. to the output file below. #print VALID "user\@example.com OK\n"; #print VALID "user1\@example.com 550 User unknown.\n"; #print VALID "bad.example.com 550 User does not exist.\n"; close VALID;

Replies are listed 'Best First'.
Re: Centos 7 getadsmtp.pl outputing blank
by haukex (Canon) on Jun 13, 2018 at 10:49 UTC

    I skimmed your code, and nothing obvious jumps out at me (the style of the code could be improved by adding strict, but it doesn't look like that's likely to be the source of the problem). Have you verified that you're using the same version of Net::LDAP on all these machines? (/path/to/perl -MNet::LDAP -le 'print $Net::LDAP::VERSION') Are you using exactly the same code on all the machines, or have you modified some of the variables? If so, that's another place I'd look.

    If you could provide a more detailed description of the problem - for example, is the file named in $VALID created, or not, and if it is created, are you saying that it is empty? You can also add debugging statements inside the loops that are fetching the data to see what the LDAP server is returning (before the code filters it with the regex). Often a simple print is enough, or use Data::Dumper with $Data::Dumper::Useqq=1; to see hidden whitespace and other control characters.

    Update: Also, how are you running the script, from the command line? Because otherwise (e.g. if you're running it from some kind of task scheduler like cron), the output (error messages) might get swallowed there.

      Perl version for the successful script is 0.4001 and where it is failing 0.65. I am using the same code on both servers and files named $valid are all created but empty. I am running the script from the command line there is no need for a cron we just run it manually each time we create new AD users. I am not so sure how to include Data::Dumper or print statements into the code.

        I am not so sure how to include Data::Dumper or print statements into the code.

        So I take it you're not a Perl programmer? I would suggest you read perlintro, it's not very long and it'll give you a good idea of Perl's syntax. Then, you can insert use Data::Dumper; above the line use Net::LDAP;, and at various places in the code, insert print Dumper($variable); or print Dumper(\@array); statements to get debug output, which you can compare across the two machines, or post here for feedback, if you like.

        Just for example, you might insert print Dumper($mail); inside the loop foreach my $mail ( $entry->get_value( "proxyAddresses" ) ) { ... } to see which, if any, mail addresses you are getting and whether they match the pattern /^(smtp|SMTP):/. You can repeat this for the other loops to see how many times those loops get executed, etc.

        Perl version for the successful script is 0.4001 and where it is failing 0.65.

        Have you had a chance to investigate poj's suggestion?

Re: Centos 7 getadsmtp.pl outputing blank
by poj (Monsignor) on Jun 13, 2018 at 12:21 UTC

    At version 0.58 (Dec 2013) the example code in LDAP::Control::Paged was changed (bug fix RT#91210: Paged.pm: fix example code) from what you have to this.

    my $cookie; while (1) { # Perform search my $mesg = $ldap->search( @args ); # add you code here for # Filtering results for proxyAddresses attributes # Only continue on LDAP_SUCCESS $mesg->code and last; # Get cookie from paged control my($resp) = $mesg->control( LDAP_CONTROL_PAGED ) or last; $cookie = $resp->cookie; # Only continue if cookie is nonempty (= we're not done) last if (!defined($cookie) || !length($cookie)); # Set cookie in paged control $page->cookie($cookie); } if (defined($cookie) && length($cookie)) { # We had an abnormal exit, so let the server know we do not want an +y more $page->cookie($cookie); $page->size(0); $ldap->search( @args ); }

    I'm not sure it's relevant but probably worth a try.

    poj

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1216545]
Approved by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (6)
As of 2018-12-10 11:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How many stories does it take before you've heard them all?







    Results (48 votes). Check out past polls.

    Notices?
    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!