LDAP connectivity to multiple domains, Can it be stored locally and queried once a day?

What I am trying to accomplish is we have an application that uses ldap.  It ask for information through LDAP and I need to know if there is a application/distro that can

1) use cron to make a VPN connection to remote domains (All clients that we have, have VPN.)
2) while connected query AD, and pull down user info.
3) store the info locally MySQL?
4) disconnect from VPN when finished by Cron or when finished.
5) Act as ldap server to the primary application.  ( I can tell the application to use anything as the ldap server.. Proven to work)

I just need to use this for multiple domains so we can host it in house.
Thanks for any help here.  I know there has to be someone besides me out there that needs or has done something like this.

Thanks again in advance!!

Casey
LVL 10
Casey HermanCitrix EngineerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

fishadrCommented:
You can use LDAPsearch.exe to query and directory that you have permissions for.

However I would script the solution and search AD and then insert the results in to SQL.

The following VBScript example connects to a DC and does LDAP look ups:
You need to search AD for an object that matches  i.e.

' Determine configuration context and DNS domain from RootDSE object.
Set oRoot = GetObject("LDAP://RootDSE")
sConfig = oRoot.Get("ConfigurationNamingContext")
Set oCommand = CreateObject("ADODB.Command")
Set oConnection = CreateObject("ADODB.Connection")
oConnection.Provider = "ADsDSOObject"
oConnection.Open = "Active Directory Provider"
oCommand.ActiveConnection = oConnection
sQuery = "<LDAP://" & sConfig & ">;(ObjectClass=nTDSDSA);AdsPath;subtree"
oCommand.CommandText = sQuery
oCommand.Properties("Page Size") = 10000
oCommand.Properties("Cache Results") = False
Set oResults = oCommand.Execute
sQuery= "<LDAP://Server1,dc=microsoft,dc=com>;(&(ObjectCategory=person)(samaccountname=*));DistinguishedName,LastLogon,Name,cn;subtree"
oCommand.CommandText = sQuery
On Error Resume Next
Err.Clear
Set oResults = oCommand.Execute
If Err.Number <> 0 Then
    Err.Clear
    On Error GoTo 0
  Else
    On Error GoTo 0
    Do Until oResults.EOF
      On Error Resume Next
      sAdsPath = oResults.Fields("Name")
      oResults.MoveNext
Loop
End If

More scripting resources can be found here:
http://www.microsoft.com/technet/scriptcenter/scripts/ad/search/default.mspx?mfr=true
http://www.microsoft.com/technet/scriptcenter/scripts/ad/users/default.mspx?mfr=true

Casey HermanCitrix EngineerAuthor Commented:
I am going to run this in linux so I would need to convert a similar script to perl then or something similar?

fishadrCommented:
Now you are talking.


use Net::LDAP;
use Net::LDAP::Util;

# Connect to AD make sure to specify version 3. Some versions of perl-ldap default to version 2
# and this method does not work unless version 3 is used.

$yourAdserver="DC1";
$ldap = new Net::LDAP("$yourAdserver",debug => 0,version=>3 ) or die "New failed:$@";

# Do an anonymous bind. Depending upon how you AD is setup you May have to do an authenticated bind.
$result=$ldap->ldapbind() || die "Bind Failed:$@";

# Some error trapping
$err=$result->code;
if ($err){
    $errname=Net::LDAP::Util::ldap_error_name($err);
    $errtxt=Net::LDAP::Util::ldap_error_text($err);
    if ($errtxt){
        print "($err) $errtxt\n";
    }
    else
    {
        if ($errname){
            print "($err) $errname\n";
        }
        else
        {
        print "ERR: $err\n";
        }
    }
    exit;

}

# The combination of the search base and filter determine which object that you
# retrieve

# set search filter to groups of objects. This is what you want to enumerate NT groups.

$filter="(objectClass=person)";

# Set the search base to the DN of the object that you want to retrieve. BTW, using this method on
# groups with less than 1000 members works as well.

$base='CN=Administrator,OU=Users,DC=Mycompany,DC=com';

# Set the initial attribute indexes and name

$found=1;
$startr=0;
$endr=-1;
$startattr="member";

while($found){

# Create the attribute range specification
$startr     =$endr+1;
$endr       =$startr+999;
$attr       ="$startattr;range=$startr-$endr";
$saveattr   =$attr;
@attr       =("$attr");

# Perform the search
$result =$mesg = $ldap->search(base => "$base",filter => $filter,
attrs   => [@attr],
scope   => "sub") or die "search died";

# Some error trapping
$err=$result->code;
if ($err){
    if (!($err == 1)){
    $errname=Net::LDAP::Util::ldap_error_name($err);
    $errtxt=Net::LDAP::Util::ldap_error_text($err);
    if ($errtxt){
        print "($err) $errtxt\n";
    }
    else
    {
        if ($errname){
        print "($err) $errname\n";
        }
    else
        {
        print "ERR: $err\n";
        }
    }
    }
    else
        {
        print "COUNT=$cnt\n";
        }
    exit;
}

$found=0;

# OK, get the attribute range...so we can update the value of the attribute
# on the next pass

foreach $entry ($mesg->all_entries) {
    @attr=$entry->attributes;
    foreach(@attr){
        $curattr=$_;
    }
}

# Print out the current chunk of members
foreach $entry ($mesg->all_entries) {
    $ar=$entry->get("$curattr");
    foreach(@$ar){
        $cnt++;
        print "$_\n";
    }
    $found=1;
    if (!@$ar[0]){
        $found=0;
    }
}


# Check to see if we got the last chunk. If we did print toe total and set
# the found flag so we don't search for anymore members

if ($curattr=~/\;range=/){
    if ($curattr=~/\-\*/){
        print "LASTCOUNT:$cnt\n";
        $found=0;
    }
}
}

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Casey HermanCitrix EngineerAuthor Commented:
What I was thinking now with the above script, draw the domain information that I need to a file.  Skip the Mysql part of it.  Use another script to do check then if the name is not there then an add to the local LDAP.

Casey
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Databases

From novice to tech pro — start learning today.