use
vars
qw ($VERSION
$Version
$DEBUG
);
Win32::OLE->Initialize(Win32::OLE::COINIT_OLEINITIALIZE);
use
Win32::Exchange::Const;
Win32::OLE->Option(
'_Unique'
=> 1);
my
$Version
;
my
$VERSION
=
$Version
=
"0.039"
;
my
$DEBUG
= 1;
sub
new {
my
$server
;
my
$ver
=
""
;
if
(
scalar
(
@_
) == 1) {
if
(
$_
[0] eq
"5.5"
||
$_
[0] eq
"6.0"
) {
$ver
=
$_
[0];
}
else
{
$server
=
$_
[0];
}
}
elsif
(
scalar
(
@_
) == 2) {
if
(
$_
[0] eq
"Win32::Exchange::Mailbox"
) {
if
(
$_
[1] eq
"5.5"
||
$_
[1] eq
"6.0"
) {
$ver
=
$_
[1];
}
else
{
$server
=
$_
[1];
}
}
else
{
_ReportArgError(
"new"
,
scalar
(
@_
));
}
}
else
{
_ReportArgError(
"new"
,
scalar
(
@_
));
return
0;
}
my
$class
=
"Win32::Exchange::Mailbox"
;
my
$ldap_provider
= {};
if
(
$ver
eq
""
) {
my
%version
;
if
(!Win32::Exchange::GetVersion(
$server
,\
%version
)) {
return
undef
;
}
else
{
$ver
=
$version
{
'ver'
}
}
}
if
(
$ver
eq
"5.5"
) {
if
(
$ldap_provider
= Win32::OLE->new(
'ADsNamespaces'
)) {
return
bless
$ldap_provider
,
$class
;
}
else
{
_DebugComment(
"Failed creating ADsNamespaces object\n"
,1);
return
undef
;
}
}
elsif
(
$ver
eq
"6.0"
) {
if
(
$ldap_provider
= Win32::OLE->new(
'CDO.Person'
)) {
return
bless
$ldap_provider
,
$class
;
}
else
{
_DebugComment(
"Failed creating CDO.Person object\n"
,1);
return
undef
;
}
}
else
{
_DebugComment(
"Unable to verify version information for version: $ver\n"
,1);
return
undef
;
}
}
sub
DESTROY {
my
$object
=
shift
;
bless
$object
,
"Win32::OLE"
;
return
undef
;
}
sub
GetLDAPPath {
my
$ldap_provider
;
my
$server_name
;
my
$ldap_path
;
my
$return_point
;
if
(
scalar
(
@_
) == 3) {
$server_name
=
$_
[0];
$ldap_path
=
"LDAP://$server_name"
;
$return_point
= 1;
}
elsif
(
scalar
(
@_
) == 4) {
$ldap_provider
=
$_
[0];
$server_name
=
$_
[1];
$return_point
= 2;
}
else
{
_ReportArgError(
"GetLDAPPath"
,
scalar
(
@_
));
return
0;
}
my
$result
;
if
(Win32::Exchange::_AdodbExtendedSearch(
$server_name
,
"LDAP://$server_name"
,
"(&(objectClass=Computer)(rdn=$server_name))"
,
"rdn,distinguishedName"
,
$result
)) {
_DebugComment(
"result = $result\n"
,2);
if
(
$result
=~ /cn=.*,cn=Servers,cn=Configuration,ou=(.*),o=(.*)/) {
my
$returned_ou
= $1;
my
$returned_o
= $2;
$_
[
$return_point
]=
$returned_o
;
$_
[(
$return_point
+1)]=
$returned_ou
;
_DebugComment(
"ou=$returned_ou\no=$returned_o\n"
,2);
return
1;
}
else
{
_DebugComment(
"result = $result\n"
,2);
_DebugComment(
"result from ADODB search failed to produce an acceptable match\n"
,1);
return
0;
}
}
else
{
_DebugComment(
"ADODB search failed\n"
,1);
return
0;
}
}
sub
CreateMailbox {
my
$error_num
;
my
$error_name
;
my
$mbx
;
my
$provider
=
$_
[0];
bless
$provider
,
"Win32::OLE"
;
Win32::OLE->LastError(0);
my
$type
= Win32::OLE->QueryObjectType(
$provider
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"failed querying OLE Object for Exchange Server Determination for CreateMailbox ($error_num)\n"
,1);
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
if
(
$type
eq
"IPerson"
) {
if
(
$mbx
= _E2KCreateMailbox(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
bless
$mbx
,
"Win32::Exchange::Mailbox"
;
return
$mbx
;
}
}
else
{
if
(
$mbx
= _E55CreateMailbox(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
bless
$mbx
,
"Win32::Exchange::Mailbox"
;
return
$mbx
;
}
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
sub
_E55CreateMailbox {
my
$ldap_provider
;
my
$information_store_server
;
my
$mailbox_alias_name
;
my
$org
;
my
$ou
;
my
$error_num
;
my
$error_name
;
my
$container
=
""
;
my
$recipients_path
;
if
(
scalar
(
@_
) > 2) {
$ldap_provider
=
$_
[0];
$information_store_server
=
$_
[1];
$mailbox_alias_name
=
$_
[2];
if
(
scalar
(
@_
) == 3) {
if
(
$ldap_provider
->GetLDAPPath(
$information_store_server
,
$org
,
$ou
)) {
_DebugComment(
"returned -> o=$org,ou=$ou\n"
,3);
}
else
{
_DebugComment(
"Error Returning from GetLDAPPath\n"
,1);
return
0;
}
}
elsif
(
scalar
(
@_
) == 4) {
$container
=
$_
[4];
}
elsif
(
scalar
(
@_
) == 5) {
$org
=
$_
[3];
$ou
=
$_
[4];
}
else
{
_ReportArgError(
"CreateMailbox [5.5] ("
.
scalar
(
@_
));
return
0;
}
}
else
{
_ReportArgError(
"CreateMailbox [5.5] ("
.
scalar
(
@_
));
return
0;
}
if
(
$container
ne
""
) {
$recipients_path
=
"LDAP://$information_store_server/$container"
;
}
else
{
$recipients_path
=
"LDAP://$information_store_server/cn=Recipients,ou=$ou,o=$org"
;
}
_DebugComment(
"path to create mailbox in: $recipients_path\n"
,3);
bless
$ldap_provider
,
"Win32::OLE"
;
my
$original_ole_warn_value
=
$Win32::OLE::Warn
;
$Win32::OLE::Warn
= 0;
my
$Recipients
=
$ldap_provider
->GetObject(
""
,
$recipients_path
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Failed opening recipients path ($recipients_path)\nError: $error_num ($error_name)\n"
,1);
return
0;
}
$Recipients
->GetObject(
"organizationalPerson"
,
"cn=$mailbox_alias_name"
);
if
(!ErrorCheck(
"0x80072030"
,
$error_num
,
$error_name
)) {
if
(
$error_num
eq
"0x00000000"
) {
_DebugComment(
"$error_num - Mailbox already exists on $information_store_server\n"
,1);
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
0;
}
else
{
_DebugComment(
"Unable to lookup object $mailbox_alias_name on $information_store_server ($error_num)\n"
,1);
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
0;
}
}
_DebugComment(
" Box Does Not Exist (This is good)\n"
,3);
bless
$ldap_provider
,
"Win32::Exchange::Mailbox"
;
my
$new_mailbox
=
$Recipients
->Create(
"organizationalPerson"
,
"cn=$mailbox_alias_name"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error creating Mailbox -> $error_num ($error_name)\n"
,1);
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
0;
}
my
%attrs
;
$attrs
{
'uid'
}=
$mailbox_alias_name
;
$attrs
{
'mailPreferenceOption'
}=
"0"
;
$attrs
{
'MAPI-Recipient'
}=
'TRUE'
;
$attrs
{
'MDB-Use-Defaults'
}=
"TRUE"
;
$attrs
{
'givenName'
}=
"Exchange"
;
$attrs
{
'sn'
}=
"Mailbox"
;
$attrs
{
'cn'
}=
"Exchange $mailbox_alias_name Mailbox"
;
$attrs
{
'Home-MTA'
}=
"cn=Microsoft MTA,cn=$information_store_server,cn=Servers,cn=Configuration,ou=$ou,o=$org"
;
$attrs
{
'Home-MDB'
}=
"cn=Microsoft Private MDB,cn=$information_store_server,cn=Servers,cn=Configuration,ou=$ou,o=$org"
;
foreach
my
$attr
(
keys
%attrs
) {
$new_mailbox
->Put(
$attr
=>
$attrs
{
$attr
});
}
$new_mailbox
->SetInfo;
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error setting attribute on mailbox -> $error_num ($error_name)\n"
,1);
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
0;
}
_DebugComment(
" -Mailbox created...\n"
,3);
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
$new_mailbox
;
}
sub
_E2KCreateMailbox {
my
$error_num
;
my
$error_name
;
my
$provider
;
my
$info_store_server
;
my
$pdc
;
my
$nt_pdc
;
my
$mailbox_alias_name
;
my
$mail_domain
;
my
$storage_group
;
my
$mb_store
;
my
$mailbox_ldap_path
;
if
(
scalar
(
@_
) >4) {
$provider
=
$_
[0];
$info_store_server
=
$_
[1];
$nt_pdc
=
$_
[2];
$mailbox_alias_name
=
$_
[3];
if
(
scalar
(
@_
) == 5) {
}
elsif
(
scalar
(
@_
) == 6) {
$mailbox_ldap_path
=
$_
[5]
}
elsif
(
scalar
(
@_
) == 7) {
$storage_group
=
$_
[5];
$mb_store
=
$_
[6];
}
else
{
_ReportArgError(
"CreateMailbox [E2K] ("
.
scalar
(
@_
));
return
0;
}
}
else
{
_ReportArgError(
"CreateMailbox [E2K] ("
.
scalar
(
@_
));
return
0;
}
Win32::Exchange::_StripBackslashes(
$nt_pdc
,
$pdc
);
my
$user_dist_name
;
if
(!Win32::Exchange::_AdodbExtendedSearch(
$mailbox_alias_name
,
"LDAP://$pdc"
,
"(samAccountName=$mailbox_alias_name)"
,
"samAccountName,distinguishedName"
,
$user_dist_name
)) {
_DebugComment(
"Error querying distinguished name for user in CreateMailbox (E2K)\n"
,1);
return
0;
}
_DebugComment(
"user_dist_name = $user_dist_name\n"
,3);
bless
$provider
,
"Win32::OLE"
;
my
$user_account
=
$provider
->DataSource->Open(
"LDAP://$pdc/$user_dist_name"
,
undef
,adModeReadWrite);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Failed opening NT user account for new mailbox creation on $pdc ($error_num)\n"
,1);
return
0;
}
my
$info_store
=
$provider
->GetInterface(
"IMailboxStore"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Failed opening mailbox interface on $pdc ($error_num)\n"
,1);
if
(
$error_num
eq
"0x80004002"
) {
_DebugComment(
"Error: No such interface supported.\n Note: Make sure you have the Exchange System Manager loaded on this system\n"
,2);
}
return
0;
}
if
(
$mailbox_ldap_path
eq
""
) {
if
(!Win32::Exchange::LocateMailboxStore(
$info_store_server
,
$storage_group
,
$mb_store
,
$mailbox_ldap_path
)) {
return
0;
}
}
_DebugComment(
"$mailbox_ldap_path\n"
,3);
$info_store
->CreateMailbox(
$mailbox_ldap_path
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Failed creating mailbox for $mailbox_alias_name ($error_num) $error_name\n"
,1);
return
0;
}
$provider
->DataSource->Save();
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Failed saving mailbox for $mailbox_alias_name ($error_num) $error_name\n"
,1);
return
0;
}
return
$provider
;
}
sub
DeleteMailbox {
my
$error_num
;
my
$error_name
;
my
$provider
=
$_
[0];
bless
$provider
,
"Win32::OLE"
;
Win32::OLE->LastError(0);
my
$type
= Win32::OLE->QueryObjectType(
$provider
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"failed querying OLE Object for Exchange Server Determination for DeleteMailbox\n"
,1);
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
my
$rtn
= 0;
if
(
$type
eq
"IPerson"
) {
if
(_E2KDeleteMailbox(
@_
)) {
$rtn
= 1;
}
}
else
{
if
(_E55DeleteMailbox(
@_
)) {
$rtn
= 1;
}
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
$rtn
;
}
sub
_E2KDeleteMailbox {
if
(
scalar
(
@_
) != 1) {
_ReportArgError(
"DeleteMailbox [E2K]"
,
scalar
(
@_
));
return
0;
}
my
$mailbox
=
$_
[0];
my
$error_num
;
my
$error_name
;
bless
$mailbox
,
"Win32::OLE"
;
my
$interface
=
$mailbox
->GetInterface(
"IMailboxStore"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error getting IMailboxStore interface for user mailbox deletion [E2K]\n"
,1);
bless
$mailbox
,
"Win32::Exchange::Mailbox"
;
return
0;
}
$interface
->DeleteMailbox();
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error deleting user mailbox (DeleteMailbox) [E2K]\n"
,1);
bless
$mailbox
,
"Win32::Exchange::Mailbox"
;
return
0;
}
$mailbox
->Datasource->Save();
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error deleting user mailbox (Save) [E2K]\n"
,1);
bless
$mailbox
,
"Win32::Exchange::Mailbox"
;
return
0;
}
_DebugComment(
"Mailbox deleted successfully"
,1);
return
1;
}
sub
_E55DeleteMailbox {
my
$ldap_provider
;
my
$information_store_server
;
my
$mailbox_alias_name
;
my
$error_num
;
my
$error_name
;
my
$find_mb
;
if
(
scalar
(
@_
) > 2) {
$ldap_provider
=
$_
[0];
$information_store_server
=
$_
[1];
$mailbox_alias_name
=
$_
[2];
}
else
{
_ReportArgError(
"DeleteMailbox [5.5] "
,
scalar
(
@_
));
return
0;
}
my
$recipients_path
;
my
$exch_mb_dn
;
my
$path
;
my
$Recipients
=
$ldap_provider
->GetMailboxContainer(
$information_store_server
,
$mailbox_alias_name
);
bless
$ldap_provider
,
"Win32::OLE"
;
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Failed opening recipients path on $information_store_server\n"
,1);
return
0;
}
bless
$Recipients
,
"Win32::OLE"
;
my
$original_ole_warn_value
=
$Win32::OLE::Warn
;
$Win32::OLE::Warn
= 0;
$Recipients
->Delete(
"organizationalPerson"
,
"cn=$mailbox_alias_name"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Unable to Get the mailbox object where the rdn == $mailbox_alias_name on $information_store_server ($error_num)\n"
,1);
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
0;
}
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
1;
}
sub
GetMailbox {
my
$error_num
;
my
$error_name
;
my
$mbx
;
my
$provider
=
$_
[0];
bless
$provider
,
"Win32::OLE"
;
Win32::OLE->LastError(0);
my
$type
= Win32::OLE->QueryObjectType(
$provider
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"failed querying OLE Object for Exchange Server Determination for CreateMailbox\n"
,1);
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
if
(
$type
eq
"IPerson"
) {
if
(
$mbx
= _E2KGetMailbox(
@_
)) {
bless
$mbx
,
"Win32::Exchange::Mailbox"
;
return
$mbx
;
}
}
else
{
if
(
$mbx
= _E55GetMailbox(
@_
)) {
bless
$mbx
,
"Win32::Exchange::Mailbox"
;
return
$mbx
;
}
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
sub
_E55GetMailbox {
my
$ldap_provider
;
my
$information_store_server
;
my
$mailbox_alias_name
;
my
$org
;
my
$ou
;
my
$error_num
;
my
$error_name
;
my
$find_mb
;
if
(
scalar
(
@_
) > 2) {
$ldap_provider
=
$_
[0];
$information_store_server
=
$_
[1];
$mailbox_alias_name
=
$_
[2];
if
(
scalar
(
@_
) == 3) {
if
(
$ldap_provider
->GetLDAPPath(
$information_store_server
,
$org
,
$ou
)) {
_DebugComment(
"returned -> o=$org,ou=$ou\n"
,3);
}
else
{
_DebugComment(
"Error Returning from GetLDAPPath\n"
,1);
return
0;
}
}
elsif
(
scalar
(
@_
) == 4) {
$find_mb
=
$_
[3];
}
elsif
(
scalar
(
@_
) == 5) {
$org
=
$_
[3];
$ou
=
$_
[4];
}
else
{
_ReportArgError(
"GetMailbox [5.5]"
,
scalar
(
@_
));
return
0;
}
}
else
{
_ReportArgError(
"GetMailbox [5.5] "
,
scalar
(
@_
));
return
0;
}
my
$recipients_path
;
my
$exch_mb_dn
;
if
(
$find_mb
== 1) {
if
(Win32::Exchange::_AdodbExtendedSearch(
$mailbox_alias_name
,
"LDAP://$information_store_server"
,
"(&(objectClass=organizationalPerson)(rdn=$mailbox_alias_name))"
,
"rdn,distinguishedName"
,1,
$exch_mb_dn
)) {
$recipients_path
=
"LDAP://$information_store_server/$exch_mb_dn"
;
}
else
{
_DebugComment(
"Error locating Exchange Mailbox on the server.\n"
,1);
return
0;
}
}
else
{
$recipients_path
=
"LDAP://$information_store_server/cn=$mailbox_alias_name,cn=Recipients,ou=$ou,o=$org"
;
}
bless
$ldap_provider
,
"Win32::OLE"
;
my
$Recipients
=
$ldap_provider
->GetObject(
""
,
$recipients_path
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Failed opening recipients path on $information_store_server\n"
,1);
return
0;
}
my
$original_ole_warn_value
=
$Win32::OLE::Warn
;
$Win32::OLE::Warn
= 0;
my
$mailbox
=
$Recipients
->GetObject(
"organizationalPerson"
,
"cn=$mailbox_alias_name"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Unable to Get the mailbox object where the rdn == $mailbox_alias_name on $information_store_server ($error_num)\n"
,1);
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
0;
}
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
$mailbox
;
}
sub
_E2KGetMailbox {
my
$error_num
;
my
$error_name
;
my
$provider
;
my
$mailbox_alias_name
;
my
$nt_dc
;
my
$dc
;
if
(
scalar
(
@_
) == 3) {
$provider
=
$_
[0];
$nt_dc
=
$_
[1];
$mailbox_alias_name
=
$_
[2];
}
else
{
_ReportArgError(
"GetMailbox [E2K]"
,
scalar
(
@_
));
return
0;
}
Win32::Exchange::_StripBackslashes (
$nt_dc
,
$dc
);
my
$user_dist_name
;
if
(!Win32::Exchange::_AdodbExtendedSearch(
$mailbox_alias_name
,
"LDAP://$dc"
,
"(samAccountName=$mailbox_alias_name)"
,
"samAccountName,distinguishedName"
,
$user_dist_name
)) {
_DebugComment(
"Error querying distinguished name for user in GetMailbox (E2K)\n"
,1);
return
0;
}
bless
$provider
,
"Win32::OLE"
;
$provider
->DataSource->Open(
"LDAP://$dc/$user_dist_name"
,
undef
,adModeReadWrite);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Failed opening AD user account for mailbox retrieval on $dc ($error_num)\n"
,1);
return
0;
}
my
$user_obj_path
=
$provider
->DataSource->{SourceURL};
my
$user_obj
= Win32::OLE->GetObject(
$user_obj_path
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Failed opening SourceURL for GetMailbox ($error_num)\n"
,1);
return
0;
}
if
(
$user_obj
->{homeMDB} eq
""
) {
_DebugComment(
"Error performing GetMailbox.. mailbox does not exist ($error_num)\n"
,2);
return
0;
}
else
{
$provider
->DataSource->Save();
return
$provider
;
}
}
sub
SetAttributes {
my
$error_num
;
my
$error_name
;
my
$provider
=
$_
[0];
bless
$provider
,
"Win32::OLE"
;
Win32::OLE->LastError(0);
my
$type
= Win32::OLE->QueryObjectType(
$provider
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"failed querying OLE Object type for Exchange Server Determination during call to SetAttributes\n"
,1);
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
my
$rtn
;
if
(
$type
eq
"IPerson"
) {
if
(
$rtn
= _E2KSetAttributes(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
$rtn
;
}
}
else
{
if
(
$rtn
= _E55SetAttributes(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
$rtn
;
}
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
sub
_E55SetAttributes {
my
$error_num
;
my
$error_name
;
my
$mailbox
;
my
%attrs
;
if
(
scalar
(
@_
) == 2) {
$mailbox
=
$_
[0];
if
(
ref
(
$_
[1]) ne
"HASH"
) {
_DebugComment(
"second object passed to SetAttributes was not a HASH reference -> $error_num ($error_name)\n"
,1);
return
0;
}
else
{
%attrs
= %{
$_
[1]};
}
}
else
{
_ReportArgError(
"SetAttributes [E55]"
,
scalar
(
@_
));
return
0;
}
my
$original_ole_warn_value
=
$Win32::OLE::Warn
;
$Win32::OLE::Warn
=0;
bless
$mailbox
,
"Win32::OLE"
;
foreach
my
$attr
(
keys
%attrs
) {
$mailbox
->Put(
$attr
=>
$attrs
{
$attr
});
}
$mailbox
->SetInfo();
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error setting attribute on mailbox -> $error_num ($error_name)\n"
,1);
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
0;
}
$Win32::OLE::Warn
=
$original_ole_warn_value
;
return
1;
}
sub
_E2KSetAttributes {
my
$error_num
;
my
$error_name
;
my
%attrs
;
my
$user_account
;
my
$mailbox
;
if
(
scalar
(
@_
) == 2) {
$user_account
=
$_
[0];
if
(
ref
(
$_
[1]) ne
"HASH"
) {
_DebugComment(
"second object passed to SetAttributes was not a HASH reference -> $error_num ($error_name)\n"
,1);
return
0;
}
else
{
%attrs
= %{
$_
[1]};
}
}
else
{
_ReportArgError(
"SetAttributes [2K]"
,
scalar
(
@_
));
return
0;
}
bless
$user_account
,
"Win32::OLE"
;
foreach
my
$interface
(
keys
%attrs
) {
my
$mailbox_interface
=
$user_account
->GetInterface(
$interface
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error getting mailbox interface -> $error_num ($error_name)\n"
,1);
return
0;
}
foreach
my
$attr
(
keys
%{
$attrs
{
$interface
}}) {
$mailbox_interface
->{
$attr
} =
$attrs
{
$interface
}{
$attr
};
}
$user_account
->DataSource->Save();
}
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error setting attribute on mailbox -> $error_num ($error_name)\n"
,1);
return
0;
}
return
1;
}
sub
GetOwner {
my
$error_num
;
my
$error_name
;
my
$provider
=
$_
[0];
bless
$provider
,
"Win32::OLE"
;
Win32::OLE->LastError(0);
my
$type
= Win32::OLE->QueryObjectType(
$provider
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"failed querying OLE Object type for GetOwner\n"
,1);
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
my
$rtn
;
if
(
$type
eq
"IPerson"
) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
else
{
if
(
$rtn
= _E55GetOwner(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
$rtn
;
}
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
sub
_E55GetOwner {
my
$error_num
;
my
$error_name
;
my
$mailbox
;
my
$returned_sid_type
;
if
(
scalar
(
@_
) > 1) {
$mailbox
=
$_
[0];
if
(
scalar
(
@_
) == 2) {
$returned_sid_type
= ADS_SID_WINNT_PATH;
}
elsif
(
scalar
(
@_
) == 3) {
$returned_sid_type
=
$_
[2];
}
else
{
_ReportArgError(
"GetOwner [5.5]"
,
scalar
(
@_
));
return
0;
}
}
else
{
_ReportArgError(
"GetOwner [5.5]"
,
scalar
(
@_
));
return
0;
}
bless
$mailbox
,
"Win32::OLE"
;
my
$sid
= Win32::OLE->new(
"ADsSID"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error creating ADsSID object -> $error_num ($error_name)\n"
,1);
return
0;
}
$mailbox
->GetInfoEx([
"Assoc-NT-Account"
],0);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error populating the property cache for Assoc-NT-Account -> $error_num ($error_name)\n"
,1);
return
0;
}
$sid
->SetAs(ADS_SID_HEXSTRING,
$mailbox
->{
'Assoc-NT-Account'
});
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error creating ADsSID object -> $error_num ($error_name)\n"
,1);
return
0;
}
my
$siduser
=
$sid
->GetAs(
$returned_sid_type
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
if
(ErrorCheck(
"0x80070534"
,
$error_num
,
$error_name
)) {
_DebugComment(
"there was an error validating the SID from the Domain Controller (the account doesn't seem to exist anymore) -> $error_num ($error_name)\n"
,1);
return
0;
}
_DebugComment(
"error getting SID to prepare for output -> $error_num ($error_name)\n"
,1);
return
0;
}
$_
[1] =
$siduser
;
return
1;
}
sub
SetOwner {
my
$error_num
;
my
$error_name
;
my
$dc
;
if
(
scalar
(
@_
) != 2) {
_ReportArgError(
"SetOwner [5.5]"
,
scalar
(
@_
));
return
0;
}
my
$new_mailbox
=
$_
[0];
my
$username
=
$_
[1];
if
(
$username
=~ /(.*)\\(.*)/) {
$dc
=$1;
$username
= $2;
}
else
{
_DebugComment(
"error parsing username to extract domain and username\n"
,1);
return
0;
}
my
$sid
= Win32::OLE->new(
"ADsSID"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error creating security object (ADsSID) -> $error_num ($error_name)\n"
,1);
return
0;
}
$sid
->SetAs(ADS_SID_WINNT_PATH,
"WinNT://$dc/$username,user"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error setting security object at an ADS_SID_WINNT_PATH -> $error_num ($error_name)\n"
,1);
return
0;
}
my
$sidHex
=
$sid
->GetAs(ADS_SID_HEXSTRING);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error converting security object at an ADS_SID_HEXSTRING -> $error_num ($error_name)\n"
,1);
return
0;
}
bless
$new_mailbox
,
"Win32::OLE"
;
$new_mailbox
->Put(
"Assoc-NT-Account"
,
$sidHex
);
$new_mailbox
->SetInfo;
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error setting owner information on mailbox -> $error_num ($error_name)\n"
,1);
bless
$new_mailbox
,
"Win32::Exchange::Mailbox"
;
return
0;
}
bless
$new_mailbox
,
"Win32::Exchange::Mailbox"
;
return
1;
}
sub
_E55GetPerms {
if
(
scalar
(
@_
) != 2) {
_ReportArgError(
"GetPerms [5.5]"
,
scalar
(
@_
));
return
0;
}
if
(
ref
(
$_
[1]) ne
"ARRAY"
) {
_DebugComment(
"permissions list must be an array reference (e55)\n"
,1);
return
0;
}
my
$mailbox
=
$_
[0];
my
$sec
= Win32::OLE->CreateObject(
"ADsSecurity"
);
my
$error_num
;
my
$error_name
;
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error creating security object (ADSSecurity) -> $error_num ($error_name)\n"
,1);
if
(
$error_num
eq
"0x80004002"
) {
_DebugComment(
"Error: No such interface supported.\n Note: Make sure you have the ADSSecurity.DLL from the ADSI SDK regisered on this system\n"
,2);
}
return
0;
}
bless
$mailbox
,
"Win32::OLE"
;
my
$sd
=
$sec
->GetSecurityDescriptor(
$mailbox
->{ADsPath});
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error querying security descriptor for mailbox -> $error_num ($error_name)\n"
,1);
return
0;
}
my
$dacl
=
$sd
->{DiscretionaryAcl};
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error querying discretionary acl for mailbox -> $error_num ($error_name)\n"
,1);
return
0;
}
@{
$_
[1]} = Win32::OLE::in(
$dacl
);
return
1;
}
sub
SetPerms {
my
$error_num
;
my
$error_name
;
my
$provider
=
$_
[0];
bless
$provider
,
"Win32::OLE"
;
Win32::OLE->LastError(0);
my
$type
= Win32::OLE->QueryObjectType(
$provider
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"failed querying OLE Object type for Exchange Server Determination during call to SetAttributes\n"
,1);
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
my
$rtn
;
if
(
$type
eq
"IPerson"
) {
if
(
$rtn
= _E2KSetPerms(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
$rtn
;
}
}
else
{
if
(
$rtn
= _E55SetPerms(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
$rtn
;
}
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
sub
_E55SetPerms {
if
(
scalar
(
@_
) != 2) {
_ReportArgError(
"SetPerms [5.5]"
,
scalar
(
@_
));
return
0;
}
if
(
ref
(
$_
[1]) ne
"ARRAY"
) {
_DebugComment(
"permissions list must be an array reference (e55)\n"
,1);
return
0;
}
my
$new_mailbox
=
$_
[0];
my
@perms_list
= @{
$_
[1]};
my
$sec
= Win32::OLE->CreateObject(
"ADsSecurity"
);
my
$error_num
;
my
$error_name
;
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error creating security object (ADSSecurity) -> $error_num ($error_name)\n"
,1);
if
(
$error_num
eq
"0x80004002"
) {
_DebugComment(
"Error: No such interface supported.\n Note: Make sure you have the ADSSecurity.DLL from the ADSI SDK regisered on this system\n"
,2);
}
return
0;
}
bless
$new_mailbox
,
"Win32::OLE"
;
my
$sd
=
$sec
->GetSecurityDescriptor(
$new_mailbox
->{ADsPath});
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error querying security descriptor for mailbox -> $error_num ($error_name)\n"
,1);
return
0;
}
my
$dacl
=
$sd
->{DiscretionaryAcl};
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error querying discretionary acl for mailbox -> $error_num ($error_name)\n"
,1);
return
0;
}
foreach
my
$userid
(
@perms_list
) {
_DebugComment(
" -Setting perms for $userid\n"
,3);
my
$ace
= Win32::OLE->CreateObject(
"AccessControlEntry"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error creating access control entry for mailbox -> $error_num ($error_name)\n"
,1);
return
0;
}
my
%properties
;
$properties
{Trustee}=
$userid
;
$properties
{AccessMask}=ADS_RIGHT_EXCH_MODIFY_USER_ATT | ADS_RIGHT_EXCH_MAIL_SEND_AS | ADS_RIGHT_EXCH_MAIL_RECEIVE_AS;
$properties
{AceType}=ADS_ACETYPE_ACCESS_ALLOWED;
foreach
my
$property
(
keys
%properties
) {
$ace
->LetProperty(
$property
,
$properties
{
$property
});
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error setting $property for mailbox -> $error_num ($error_name)\n"
,1);
return
0;
}
}
$dacl
->AddAce(
$ace
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error adding access control entry to perms list -> $error_num ($error_name)\n"
,1);
return
0;
}
}
$sd
->LetProperty(
"DiscretionaryAcl"
,
$dacl
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error setting discretionary acl on security security descriptor -> $error_num ($error_name)\n"
,1);
return
0;
}
$sec
->SetSecurityDescriptor(
$sd
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error setting security descriptor on security object -> $error_num ($error_name)\n"
,1);
return
0;
}
$new_mailbox
->SetInfo;
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error setting permissions on mailbox -> $error_num ($error_name)\n"
,1);
return
0;
}
return
1;
}
sub
_E2KSetPerms {
my
$error_num
;
my
$error_name
;
if
(
scalar
(
@_
) != 2) {
_ReportArgError(
"SetPerms [2K]"
,
scalar
(
@_
));
return
0;
}
if
(
ref
(
$_
[1]) ne
"ARRAY"
) {
_DebugComment(
"permissions list must be an array reference (e2k)\n"
,1);
return
0;
}
my
$cdo_user_obj
=
$_
[0];
my
@perms_list
= @{
$_
[1]};
bless
$cdo_user_obj
,
"Win32::OLE"
;
my
$ldap_user_path
=
$cdo_user_obj
->{DataSource}->{SourceURL};
my
$ldap_user_obj
= Win32::OLE->GetObject(
$ldap_user_path
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error querying Source URL for CDO.Person object ($error_num)\n"
,1);
return
0;
}
my
$sd
=
$ldap_user_obj
->{
'MailboxRights'
};
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error querying MailboxRights property ($error_num)\n"
,1);
_DebugComment(
"- make sure you are using Exchange 2000 SP1+hotfix or higher [server & client]\n"
,2);
return
0;
}
my
$dacl
=
$sd
->{DiscretionaryAcl};
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error getting DiscretionaryAcl ($error_num)\n"
,1);
return
0;
}
foreach
my
$user_account
(
@perms_list
) {
my
$domain
;
my
$username
;
if
(
$user_account
=~ /(.*)\\(.*)/) {
$domain
= $1;
$username
= $2;
}
else
{
_DebugComment(
"error parsing user object (expected DOMAIN\\Username) -> $error_num ($error_name)\n"
,1);
return
0;
}
my
$Ace
= Win32::OLE->new(
"AccessControlEntry"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error creating new ACE ($error_num)\n"
,1);
return
0;
}
my
%properties
;
$properties
{AccessMask}=ADS_RIGHT_DS_CREATE_CHILD;
$properties
{AceType}=ADS_ACETYPE_ACCESS_ALLOWED;
$properties
{AceFlags}=ADS_ACEFLAG_INHERIT_ACE;
$properties
{Flags}=0;
$properties
{Trustee}=
$user_account
;
$properties
{ObjectType}=0;
$properties
{InheritedObjectType}=0;
foreach
my
$property
(
keys
%properties
) {
if
(
$property
=~ /(ObjectType|InheritedObjectType)/ &&
$properties
{
$property
} == 0) {
next
;
}
$Ace
->LetProperty(
$property
,
$properties
{
$property
});
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error setting $property ($error_num)\n"
,1);
return
0;
}
}
$dacl
->AddAce(
$Ace
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error adding AccessControlEntry to AccessControlList: ($error_num)\n"
,1);
return
0;
}
}
$sd
->LetProperty(
'DiscretionaryAcl'
,
$dacl
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error setting AccessControlList to Security Descriptor: ($error_num)\n"
,1);
return
0;
}
$ldap_user_obj
->LetProperty(
'MailboxRights'
,
$sd
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error modfying Mailbox Security entry: ($error_num)\n"
,1);
return
0;
}
$ldap_user_obj
->SetInfo();
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error setting information to Mailbox Security entry: ($error_num)\n"
,1);
return
0;
}
return
1;
}
sub
MailEnable {
my
$error_num
;
my
$error_name
;
my
$provider
=
$_
[0];
bless
$provider
,
"Win32::OLE"
;
Win32::OLE->LastError(0);
my
$type
= Win32::OLE->QueryObjectType(
$provider
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"failed querying OLE Object type for Exchange Server Determination during call to MailEnable\n"
,1);
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
my
$rtn
;
if
(
$type
eq
"IPerson"
) {
if
(
$rtn
= _E2KMailEnable(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
$rtn
;
}
}
else
{
if
(
$rtn
= _E55MailEnable(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
$rtn
;
}
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
sub
_E2KMailEnable {
my
$user_obj
;
my
$interface
;
my
$smtp_address
=
""
;
my
$error_num
;
my
$error_name
;
if
(
scalar
(
@_
) > 0) {
$user_obj
=
$_
[0];
if
(
scalar
(
@_
) == 2) {
$smtp_address
=
$_
[1];
}
elsif
(
scalar
(
@_
) > 2) {
_ReportArgError(
"MailEnable (E2K)"
,
scalar
(
@_
));
return
0;
}
}
else
{
_ReportArgError(
"MailEnable (E2K)"
,
scalar
(
@_
));
return
0;
}
$interface
=
$user_obj
->GetInterface(
"IMailRecipient"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error querying mailbox interface during MailEnable (E2K) -> $error_num ($error_name)\n"
,1);
return
0;
}
if
(
$smtp_address
eq
""
) {
$interface
->MailEnable();
}
else
{
$interface
->MailEnable(
$smtp_address
);
}
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error performing MailEnable on AD user object (E2K) -> $error_num ($error_name)\n"
,1);
return
0;
}
$user_obj
->Datasource->Save();
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error performing Save on AD User object during MailEnable (E2K) -> $error_num ($error_name)\n"
,1);
return
0;
}
else
{
return
1;
}
}
sub
_E55MailEnable {
return
0;
}
sub
AddDLMembers {
my
$error_num
;
my
$error_name
;
my
$provider
=
$_
[0];
bless
$provider
,
"Win32::OLE"
;
Win32::OLE->LastError(0);
my
$type
= Win32::OLE->QueryObjectType(
$provider
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"failed querying OLE Object type for Exchange Server Determination during call to SetAttributes\n"
,1);
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
my
$rtn
;
if
(
$type
eq
"IPerson"
) {
if
(
$rtn
= _E2KAddDLMembers(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
$rtn
;
}
}
else
{
if
(
$rtn
= _E55AddDLMembers(
@_
)) {
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
$rtn
;
}
}
bless
$provider
,
"Win32::Exchange::Mailbox"
;
return
0;
}
sub
_E55AddDLMembers {
my
$ldap_provider
;
my
$server_name
;
my
$exch_dl_name
;
my
@new_members
;
my
$ou
;
my
$org
;
my
$find_dl
;
if
(
scalar
(
@_
) > 3) {
$ldap_provider
=
$_
[0];
$server_name
=
$_
[1];
$exch_dl_name
=
$_
[2];
if
(
ref
(
$_
[3]) ne
"ARRAY"
) {
_DebugComment(
"members list must be an array reference\n"
,1);
return
0;
}
@new_members
=@{
$_
[3]};
if
(
scalar
(
@_
) < 6) {
if
(
$ldap_provider
->GetLDAPPath(
$server_name
,
$org
,
$ou
)) {
_DebugComment(
"returned -> o=$org,ou=$ou\n"
,3);
}
else
{
_DebugComment(
"Error Returning from GetLDAPPath\n"
,1);
return
0;
}
if
(
scalar
(
@_
) == 5) {
$find_dl
=
$_
[4];
}
}
elsif
(
scalar
(
@_
) == 6) {
$org
=
$_
[4];
$ou
=
$_
[5];
}
else
{
_ReportArgError(
"AddDLMembers [5.5]"
,
scalar
(
@_
));
return
0;
}
}
else
{
_ReportArgError(
"AddDLMembers [5.5]"
,
scalar
(
@_
));
return
0;
}
my
$temp_exch_dl
;
my
$original_ole_warn_value
=
$Win32::OLE::Warn
;
bless
$ldap_provider
,
"Win32::OLE"
;
my
$exch_dl_dn
;
my
$exch_dl_path
;
my
$temp_dl_path
;
my
$exch_dl
;
if
(
$exch_dl_name
=~ /^cn=.
*ou
=.
*o
=.*/) {
$exch_dl_path
=
"LDAP://$server_name/$exch_dl_name"
;
$exch_dl_dn
=
$exch_dl_name
;
}
else
{
if
(
$find_dl
== 1) {
if
(Win32::Exchange::_AdodbExtendedSearch(
$exch_dl_name
,
"LDAP://$server_name"
,
"(&(objectClass=groupOfNames)(cn=$exch_dl_name))"
,
"cn,distinguishedName"
,
$exch_dl_dn
)) {
$exch_dl_path
=
"LDAP://$server_name/$exch_dl_dn"
;
}
else
{
_DebugComment(
"Error locating Exchange DL on the server. Member addition cannot proceed.\n"
,1);
return
0;
}
}
else
{
$exch_dl_path
=
"LDAP://$server_name/cn=$exch_dl_name,cn=Distribution Lists,ou=$ou,o=$org"
;
$exch_dl_dn
=
"cn=$exch_dl_name,cn=Distribution Lists,ou=$ou,o=$org"
;
}
}
$exch_dl
=
$ldap_provider
->GetObject(
""
,
$exch_dl_path
);
my
$error_num
;
my
$error_name
;
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error querying distribution list ($exch_dl_name) -> $error_num ($error_name)\n"
,1);
return
0;
}
my
$exch_members
=
$exch_dl
->{
'member'
};
if
(
ref
(
$exch_members
) eq
"ARRAY"
) {
_DebugComment(
" -Array (2 or more members exist)\n"
,3);
}
else
{
_DebugComment(
" -(Less than 2 members are named in this distribution list)\n"
,3);
my
$temp_exch_dl
=
$exch_members
;
undef
(
$exch_members
);
if
(
$temp_exch_dl
) {
_DebugComment(
" -1 member exists\n"
,3);
push
(
@$exch_members
,
$temp_exch_dl
);
}
else
{
_DebugComment(
" -0 members exists\n"
,3);
}
}
my
$exch_mb_dn
;
foreach
my
$username
(
@new_members
) {
_DebugComment(
" -Adding $username to Distribution List: $exch_dl_name\n"
,2);
if
(
$username
=~ /^cn=.
*ou
=.
*o
=.*$/) {
$exch_mb_dn
=
$username
;
}
else
{
if
(
$find_dl
== 1) {
if
(!Win32::Exchange::_AdodbExtendedSearch(
$username
,
"LDAP://$server_name"
,
"(&(objectClass=organizationalPerson)(rdn=$username))"
,
"rdn,distinguishedName"
,
$exch_mb_dn
)) {
_DebugComment(
"Error locating Exchange mailbox on the server. Member addition cannot proceed.\n"
,1);
return
0;
}
}
else
{
$exch_mb_dn
=
"cn=$username,cn=Recipients,ou=$ou,o=$org"
;
}
}
my
$duplicate
;
foreach
my
$dup
(
@$exch_members
) {
if
(
lc
(
$dup
) eq
lc
(
$exch_mb_dn
)) {
_DebugComment(
"Error adding user ($username) to distribution list [they are already a member]\n"
,1);
$duplicate
= 1;
last
;
}
}
if
(
$duplicate
!= 1) {
push
(
@$exch_members
,
$exch_mb_dn
);
}
}
$exch_dl
->Put(
'member'
,
$exch_members
);
$exch_dl
->SetInfo;
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"error setting new member for distribution list ($exch_dl_name) -> $error_num ($error_name)\n"
,1);
return
0;
}
return
1;
}
sub
_E2KAddDLMembers {
if
(
scalar
(
@_
) != 3) {
_ReportArgError(
"AddDLMembers (E2K)"
,
scalar
(
@_
));
return
0;
}
if
(
ref
(
$_
[2]) ne
"ARRAY"
) {
_DebugComment(
"Third argument is the list of users you want to add to this DL, and should be an array reference, but instead, it was a(an): "
.
ref
(
$_
[2]).
" reference\n"
,1);
return
0;
}
my
$error_num
;
my
$error_name
;
my
$group_dn
;
my
$user_dn
;
my
$provider
=
$_
[0];
my
$group
=
$_
[1];
my
@user_list
= @{
$_
[2]};
if
(!Win32::Exchange::_AdodbExtendedSearch(
$group
,
"LDAP://RootDSE/dnsHostName"
,
"(&(objectClass=group)(samAccountName=$group))"
,
"samAccountName,distinguishedName"
,
$group_dn
)) {
_DebugComment(
"Failed Adodb search for dist list\n"
,1);
return
0;
}
foreach
my
$username
(
@user_list
) {
_DebugComment(
"Adding $username to $group\n"
,4);
if
(!Win32::Exchange::_AdodbExtendedSearch(
$username
,
"LDAP://RootDSE/dnsHostName"
,
"(&(objectClass=user)(samAccountName=$username))"
,
"samAccountName,distinguishedName"
,
$user_dn
)) {
_DebugComment(
"Failed Adodb search for user: $username\n"
,1);
return
0;
}
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Failed Getting RootDSE ($error_num)\n"
,1);
return
0;
}
my
$dc
=
$RootDSE
->Get(
"dnsHostName"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error getting RootDSE dns host name ($error_num)\n"
,1);
return
0;
}
my
@dc_array
=
split
(/\./,
$dc
);
my
$ldap_obj
= Win32::OLE->new(
"ADsNamespaces"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error creating new ADsNamespaces object ($error_num)\n"
,1);
return
0;
}
my
$group_obj
=
$ldap_obj
->GetObject(
""
,
"LDAP://$dc_array[0]/$group_dn"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error opening distribution list on $dc_array[0] ($error_num)\n"
,1);
return
0;
}
$group_obj
->Add(
"LDAP://$dc_array[0]/$user_dn"
);
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
if
(
$error_num
eq
"0x80071392"
) {
_DebugComment(
"Error adding user ($username) to distribution list [they are already a member]\n"
,1);
}
else
{
_DebugComment(
"Error adding user ($username) to distribution list ($error_num)\n"
,1);
return
0;
}
}
$group_obj
->SetInfo;
if
(!ErrorCheck(
"0x00000000"
,
$error_num
,
$error_name
)) {
_DebugComment(
"Error committing addition to distribution list ($error_num)\n"
,1);
return
0;
}
}
return
1;
}
sub
_ReportArgError {
my
$rtn
= Win32::Exchange::_ReportArgError(
$_
[0],
$_
[1]);
return
$rtn
;
}
sub
_DebugComment {
my
$rtn
= Win32::Exchange::_DebugComment(
$_
[0],
$_
[1],
$DEBUG
);
return
$rtn
;
}
sub
ErrorCheck {
my
$rtn
= Win32::Exchange::ErrorCheck(
$_
[0],
$_
[1],
$_
[2]);
return
$rtn
;
}
1;