Getting Email List from Windows Domain
David C.M. Weber
david.weber at BACKBONESECURITY.COM
Mon Feb 28 15:34:59 GMT 2005
Just another update. Made the shell script a bit more "intelligent" in
its cacheing. The ASP script will not propagate disabled email boxes
anymore either. Oversight on my part.
--------Begin ASP Script----------
<%
' Written by David CM Weber (rotinom at gmail dot com)
' This code is freely distributable
'
' This script (when used with the appropriate client portion) will allow
a
' sendmail/Linux box to retrieve all valid email addresses within an
Exchange
' organization. It will then place them into a format appropriate for
sendmail
' to use as an access list
' Start of the "main" function
' All this does, is essentially access the Active Directory via
LDAP, and get
' a handle to the tree, so that objects can be examined and
iterated through.
Dim rootDSE, domainObject
' This will bind subsequent LDAP queries to the
' Root Directory Service Entry (RootDSE, DUH!) located on the
' default domain controller
Set rootDSE = GetObject("LDAP://RootDSE")
' Get the defaultNamingContext property of the RootDSE. This is
' basically your domains name (e.g.: mycompany.com )
domainContainer = rootDSE.Get("defaultNamingContext")
' Make a new object bound to LDAP://mycompany.com/ so we can
' recurse through the containers and enumerate the email
addresses
Set domainObject = GetObject("LDAP://" & domainContainer)
' Export the users
ExportEmail(domainObject)
' End of the "main" function
' This is the guts of the whole program. This will recursively
' search the entire active directory tree, and print out emails
' which are associated with either user objects, or group objects
' oObject will either be an Organizational Unit (OU) or a Container
Sub ExportEmail(oObject)
Dim oUser
' iterate through each sub-object in this object
For Each oUser in oObject
Select Case oUser.Class
' Is it a user object?
Case "user"
print_user_emails(oUser)
'Is it a group object?
Case "group"
print_group_emails(oUser)
' If it is an OU or a container
Case "organizationalUnit" , "container"
' Check to see if there are any users or
groups in the
' container
If UsersGroupsinOU (oUser) then
' Call the ExportEmail function
recursively
ExportEmail(oUser)
End if
End select
Next
End Sub
' This function will enumerate the individual email addresses
' associated with a particular user
Function print_user_emails(oUser)
' Just verify that it is a user w/ an email box
' and also that the account is enabled (disabled accounts are
not email
' enabled, even if they have an exchange mailbox)
If oUser.mail <> "" and oUser.AccountDisabled = FALSE then
for each email in oUser.proxyAddresses
print_email(email)
next
End if
end Function
' This function will enumerate the individual email addresses
' associated with a particular group
Function print_group_emails(oGroup)
' Verify whether it is a mail-enabled group
If oGroup.mailNickname <> "" then
for each email in oGroup.proxyAddresses
print_email(email)
next
End if
end FUnction
' This function will print out an email address stored in an objects
"proxyAddresses" fields
Function print_email(email)
' We are only interested in SMTP email addresses. Not X400,
MSMail, etc.
' So, we only parse the SMTP addresses
if Instr(email, "SMTP:") <> 0 or Instr(email, "smtp:") <> 0
then
dim n, e
' locate the ":"
n = InStr(1, email, ":", 1)
' Cut off everything to the right of the ":"
e = Right(email, Len(email) - n)
'Write the results to the HTML document. The format is:
' email at address.com <tab> <tab> ACCEPT <LF>
' in an attempt to make it semi-legible.
response.write("To:" & e & Chr(9) & "RELAY" & Chr(10))
end if
end Function
' This function determines whether there is an object of interest within
a
' container/OU object. Objects of interest are:
' OU's
' Containers
' Groups
' Users
'
' OU's and Groups will cause a recursive call to the function, whereas a
' group or user will simply return an affirmative (true) result.
Function UsersGroupsinOU (oObject)
Dim oUser
UsersGroupsinOU = False
for Each oUser in oObject
Select Case oUser.Class
Case "organizationalUnit" , "container"
UsersGroupsinOU = UsersGroupsinOU(oUser)
Case "user"
UsersGroupsinOU = True
Case "group"
UsersGroupsinOU = True
End select
Next
End Function
%>
--------End ASP Script------------
--------Begin Shell Script--------
#gen_email.sh
#
# Written by David CM Weber (rotinom at gmail dot com)
# This code is freely distributable
#
# This will generate an access file based on email addresses
# found on an exchange "back end" server.
#
# Please see the companion script for the exchange
# server portion.
# Flag to determine whether we should update or not
update_db=0
# The location of the companion asp script (on some windows domain
controller)
email_http_location="https://IIS_Server_with_ASP_Script/EmailList/defaul
t.asp"
# the name of the file that you are downloading
dl_filename="/etc/mail/update/default.asp"
# the name of the "old" file that you wish to use (for caching of email
addresses)
dl_filename_old="/etc/mail/update/default.asp.old"
# Location of the access file (usually /etc/mail/access)
access_file="/etc/mail/access"
# location of the access.db file (usually /etc/mail/access/access.db)
access_db="/etc/mail/access.db"
# Location of the old "real" access file. Use this to add manual
"blacklists"
# and to make otherwise static changes to the access file
access_header="/etc/mail/access_header"
#Location of the cached access header. We keep this around to check
# if it has changed. This allows the caching to work if there's a local
# "static" change, as well as a remote "dynamic" change
access_header_old="/etc/mail/update/access_header.old"
# Warning to put at the top of the created access file
header_warning="#*** WARNING! DO NOT EDIT THIS FILE DIRECTLY!
***\n#Instead, edit $access_header to make your changes\n\n\n"
# Separator to place between the static & dynamic content of the access
file
separator="\n\n# --- BEGIN ADDRESSES AUTOMATICALLY GATHERED FROM
EXCHANGE SERVER ---"
# ------------ Begin Script --------------
# compare the old & new access_header
cmp $access_header $access_header_old &> /dev/null
if [ $? -ne 0 ] # Test exit status of "cmp" command.
then
update_db=1
fi
# Retrieve the asp results
wget -O $dl_filename $email_http_location &> /dev/null
# compare the old & new email list
cmp $dl_filename $dl_filename_old &> /dev/null
if [ $? -ne 0 ] # Test exit status of "cmp" command.
then
update_db=1
fi
# update the files, if the update flag was set (not null)
if [ $update_db -eq 1 ]
then
# General note: > overwrites a current or createsa new file,
# and >> appends an existing one
# Insert the warning text
echo -e $header_warning > $access_file
# Insert the static content
cat $access_header >> $access_file
# Insert the separator
echo -e $separator >> $access_file
# Insert the dynamic content
cat $dl_filename >> $access_file
# keep cached versions of the last data
cp -f $dl_filename $dl_filename_old &> /dev/null
cp -f $access_header $access_header_old &> /dev/null
# Create the access.db file based on the access file
makemap hash $access_db < $access_file
fi
# remove the downloaded file
rm -f $dl_filename
--------End Shell Script----------
------------------------ MailScanner list ------------------------
To unsubscribe, email jiscmail at jiscmail.ac.uk with the words:
'leave mailscanner' in the body of the email.
Before posting, read the MAQ (http://www.mailscanner.biz/maq/) and
the archives (http://www.jiscmail.ac.uk/lists/mailscanner.html).
Support MailScanner development - buy the book off the website!
More information about the MailScanner
mailing list