Requirements
The following list outlines the recommended hardware, software,
network infrastructure, and service packs that are required:
- You must use an Exchange 2003 or Exchange 2000 server on which you have
installed either Service Pack 2, or Service Pack 1 and the post-Service Pack 1
Exchange 2000 hotfix. For more information about Service Packs, see the
"References" section.
- You must use ADSI code to access the user object
information from the Active Directory.
- You must start the Exchange 2003 or Exchange 2000 information store where
the user's mailbox exists (the store must be running and mounted).
In an Exchange 2003 or Exchange 2000 organization or Windows Server 2003 or Windows 2000 domain
environment, a mailbox includes two parts:
- The Active Directory Mailbox Enabled User. This is just a
user object in the Active Directory that has several mail and mailbox-related
properties set on it.
- The Mailbox Folder in the Exchange information store. This
is the location where the user's mail is stored and where several
mailbox-specific properties are set.
The msExchMailboxSecurityDescriptor Attribute
The mailbox rights are stored on a security descriptor property
on the mailbox in the information store. The attribute on the Active Directory
user object that is named
msExchMailboxSecurityDescriptor is designed to reflect the mailbox rights on the user's
mailbox.
This attribute exists on the user object in the Active
Directory and stores a partial copy of the user's mailbox security descriptor.
This attribute is not back linked to the user's mailbox security descriptor. In
other words, if
msExchMailboxSecurityDescriptor is modified directly, the actual mailbox security descriptor on
the user's mailbox in the information store is not updated. If the user's
mailbox security descriptor is modified from ADUnC or as demonstrated in the
code in this article,
msExchMailboxSecurityDescriptor is automatically updated to reflect these changes.
Changes that you make on
msExchMailboxSecurityDescriptor are reflected on the user's mailbox security descriptor only if
you set this attribute
before you create the mailbox in the web store.
For more information, click the following article number to view the article in the Microsoft Knowledge Base:
304935
How to set Exchange Server 2000 and 2003 mailbox rights at the time of mailbox creation
Note that the Exchange 2003 or Exchange 2000 mailbox for an Active
Directory mailbox enabled user is created in an Exchange store when the user
tries to access the mailbox for the first time or when any mail is sent to this
mailbox.
Another limitation of
msExchMailboxSecurityDescriptor is that it does not reflect any of the inherited access control
entries (ACEs) on the security descriptor of the mailbox itself. Therefore,
Microsoft does not recommend that you modify the mailbox rights on a mailbox by
reading
msExchMailboxSecurityDescriptor. Other ways of reading a user's mailbox rights are more accurate
than using this directory attribute.
The IExchangeMailbox Interface
You can use the
IExchangeMailbox interface to work with the mailbox rights on an Exchange 2003 or Exchange 2000 mailbox. The Exchange 2003 or Exchange 2000 server must be configured as listed in
"Requirements" for the following to work:
- To expose mailbox rights
- For the IExchangeMailbox interface to be present
- To run the sample code
This interface belongs to the CDOEXM library (Cdoexm.dll
version 6.0.4720.13).
NOTE: Do not try to manually copy Cdoexm.dll and then use the
regsvr32 command to register this .dll file, because this results in
compatibility issues.
The
IExchangeMailbox interface inherits all the properties and methods of the
IMailboxStore interface and introduces one additional property that is named
MailboxRights. You can query for the
IExchangeMailbox interface only from ADSI interfaces and not from the
CDO.Person object.
The
MailboxRights property exposes the security descriptor on the Exchange 2000
Mailbox in the information store, which you can work with by using the
IADsSecurityDescriptor interface in the ADSI library. You can handle this security
descriptor like you handle the security descriptor on any other type of object
(for example, users in the Active Directory or files in a folder). For more
information about security descriptors and interfaces in the ADSI library that
are exposed to programmatically manipulate a security descriptor, see the
"References" section of this article.
If the mailbox for this mailbox
enabled user object has not been created in the information store yet,
IExchangeMailbox interface manipulates the
msExchMailboxSecurityDescriptor attribute instead. This explains why you see a limited set of
rights when you use this interface or ADUnC to view the mailbox rights for a
mailbox enabled user before their mailbox has been created in the information
store. After the mailbox has been created, you see a lot more mailbox rights.
These additional rights are the inherited rights on the mailbox from the parent
store object in the Exchange information store.
Set Up the Visual Basic Environment
- Start Microsoft Visual Basic 6.0 on your Exchange 2003 or Exchange 2000 server.
- Open a new Standard EXE project: on the File menu, click New, and then double-click Standard EXE.
- On the Project menu, click References, and then select Active DS Type Library and
Microsoft CDO for Exchange Management.
- In the Source view of the form, paste the code that follows
these steps in the place of (overwrite) the Form_Load() subroutine.
- Change the values that are set for the two variables,
sUserADsPath and sTrustee:
- Set sUserADsPath to the LDAP path for the Active Directory User object whose mailbox rights you want to view or
modify.
- Set sTrustee to the name of the account that you want
to add an ACE onto the mailbox's security descriptor, and allow this account
Full Mailbox Access. Set sTrustee in the form domainName\UserName.
IMPORTANT: Because this sample demonstrates how to read and modify the
mailbox rights, and how to add an access control entry (ACE) for full mailbox
access to the specified trustee, test this code on a test user first.
The Visual Basic Sample Code
CONST ADS_ACEFLAG_INHERIT_ACE = 2
CONST ADS_RIGHT_DS_CREATE_CHILD = 1
CONST ADS_ACETYPE_ACCESS_ALLOWED = 0
CONST ADS_ACETYPE_ACCESS_DENIED = 1
CONST ADS_ACETYPE_SYSTEM_AUDIT = 2
CONST ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = 5
CONST ADS_ACETYPE_ACCESS_DENIED_OBJECT = 6
CONST ADS_ACETYPE_SYSTEM_AUDIT_OBJECT = 7
CONST ADS_ACETYPE_SYSTEM_ALARM_OBJECT = 8
'********************************************************************
'*
'* Function AddAce(dacl, TrusteeName, gAccessMask, gAceType,
'* gAceFlags, gFlags, gObjectType, gInheritedObjectType)
'*
'* Purpose: Adds an ACE to a DACL
'* Input: dacl Object's Discretionary Access Control List
'* TrusteeName SID or Name of the trustee user account
'* gAccessMask Access Permissions
'* gAceType ACE Types
'* gAceFlags Inherit ACEs from the owner of the ACL
'* gFlags ACE has an object type or inherited object type
'* gObjectType Used for Extended Rights
'* gInheritedObjectType
'*
'* Output: Object - New DACL with the ACE added
'*
'********************************************************************
Function AddAce(dacl, TrusteeName, gAccessMask, gAceType, gAceFlags, gFlags, gObjectType, gInheritedObjectType)
Dim Ace1
' Create a new ACE object.
Set Ace1 = CreateObject("AccessControlEntry")
Ace1.AccessMask = gAccessMask
Ace1.AceType = gAceType
Ace1.AceFlags = gAceFlags
Ace1.Flags = gFlags
Ace1.Trustee = TrusteeName
'See whether ObjectType must be set.
If CStr(gObjectType) <> "0" Then
Ace1.ObjectType = gObjectType
End If
'See whether InheritedObjectType must be set.
If CStr(gInheritedObjectType) <> "0" Then
Ace1.InheritedObjectType = gInheritedObjectType
End If
dacl.AddAce Ace1
' Destroy objects.
Set Ace1 = Nothing
End Function
Private Sub Form_Load()
Dim objUser As IADsUser
Dim oSecurityDescriptor As New SecurityDescriptor
Dim dacl As New AccessControlList
Dim ace As New AccessControlEntry
' ********************************************************************
' You will need to change this variable according to your environment.
'
sUserADsPath = "LDAP://ServerName/CN=User1,CN=Users,DC=DomainName,DC=com"
sTrustee = "DomainName\UserName"
' ********************************************************************
' Get directory user object.
Set objUser = GetObject(sUserADsPath)
' Get the Mailbox security descriptor (SD).
Set oSecurityDescriptor = objUser.MailboxRights
' Extract the discretionary access control list (ACL) by using the IADsSecurityDescriptor.
' Interface
Set dacl = oSecurityDescriptor.DiscretionaryAcl
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The following block of code demonstrates how to read all the ACEs on a
' DACL for the Exchange 2000 mailbox.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Debug.Print "Here are the existing ACEs in the mailbox's DACL:"
' Enumerate all the access control entries (ACEs) in the ACL using the IADsAccessControlList.
' Interface, therefore, displaying the current mailbox rights.
Debug.Print "Trustee, AccessMask, ACEType, ACEFlags, Flags, ObjectType, InheritedObjectType"
Debug.Print "------- ---------- ------- -------- ----- ---------- -------------------"
Debug.Print
For Each ace In dacl
' Display all the properties of the ACEs by using the IADsAccessControlEntry interface.
Debug.Print ace.Trustee & ", " & ace.AccessMask & ", " & ace.AceType & ", " & ace.AceFlags & ", " & ace.Flags & ", " & ace.ObjectType & ", " & ace.InheritedObjectType
Next
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The following block of code demonstrates how to add a new ACE to the
' DACL for the Exchange 2000 mailbox with the Trustee specified in
' sTrustee, which permits "Full Control" over this mailbox.
' This is the same task that is performed by ADUnC when you follow these
' steps to modify the properties of a user: on the Exchange Advanced tab,
' under Mailbox Rights, click Add, select the Trustee, and then select the
' Full Mailbox Access Rights check box.
' Similarly, you can also remove ACEs from this ACL by using the IADsAccessControlEntry interfaces.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Template: AddAce(TrusteeName, gAccessMask, gAceType, gAceFlags, gFlags, gObjectType, gInheritedObjectType)
AddAce dacl, sTrustee, ADS_RIGHT_DS_CREATE_CHILD, _
ADS_ACETYPE_ACCESS_ALLOWED, ADS_ACEFLAG_INHERIT_ACE, 0, 0, 0
' Add the modified DACL to the security descriptor.
oSecurityDescriptor.DiscretionaryAcl = dacl
' Save new SD onto the user.
objUser.MailboxRights = oSecurityDescriptor
' Commit changes from the property cache to the information store.
objUser.SetInfo
MsgBox "Done viewing and modifying the Mailbox security descriptor"
End Sub
The Visual Basic Script Code
CONST ADS_ACEFLAG_INHERIT_ACE = 2
CONST ADS_RIGHT_DS_CREATE_CHILD = 1
CONST ADS_ACETYPE_ACCESS_ALLOWED = 0
CONST ADS_ACETYPE_ACCESS_DENIED = 1
CONST ADS_ACETYPE_SYSTEM_AUDIT = 2
CONST ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = 5
CONST ADS_ACETYPE_ACCESS_DENIED_OBJECT = 6
CONST ADS_ACETYPE_SYSTEM_AUDIT_OBJECT = 7
CONST ADS_ACETYPE_SYSTEM_ALARM_OBJECT = 8
Dim objUser
Dim oSecurityDescriptor
Dim dacl
Dim ace
' ********************************************************************
' Change this variable according to your environment.
'
sUserADsPath = "LDAP://ServerName/CN=User1,CN=Users,DC=DomainName,DC=com"
sTrustee = "DomainName\UserName"
' ********************************************************************
'Get directory user object.
Set objUser = GetObject(sUserADsPath)
' Get the Mailbox security descriptor (SD).
Set oSecurityDescriptor = objUser.MailboxRights
' Extract the Discretionary Access Control List (DACL) using the IADsSecurityDescriptor.
' Interface.
Set dacl = oSecurityDescriptor.DiscretionaryAcl
Set ace = CreateObject("AccessControlEntry")
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The following block of code demonstrates how to read all the
' ACEs on a DACL for the Exchange 2000 mailbox.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
wscript.echo "Here are the existing ACEs in the mailbox's DACL:"
' Enumerate all the Access Control Entries (ACE) in the DACL using the IADsAccessControlList.
' Interface, therefore, displaying the current mailbox rights.
'wscript.echo "Trustee, AccessMask, ACEType, ACEFlags, Flags, ObjectType, InheritedObjectType"
For Each ace In dacl
' Display all the properties of the ACEs using the IADsAccessControlEntry interface.
msgbox ace.Trustee & ", " & ace.AccessMask & ", " & ace.AceType & ", " & ace.AceFlags & ", " & ace.Flags & ", " & ace.ObjectType & ", " & ace.InheritedObjectType
Next
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' The following block of code demonstrates adding a new ACE to the DACL
' for the Exchange 2003/2000 mailbox with the Trustee specified in sTrustee,
' which permits full control over this mailbox.
' This is the same task that is performed by ADUnC when you follow these
' steps to modify the properties of a user: on the Exchange Advanced tab,
' under Mailbox Rights, click Add, select the Trustee, and then select the
' Full Mailbox Access Rights check box.
' Similarly, you can also remove ACEs from this ACL by using the IADsAccessControlEntry interfaces.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Template: AddAce(TrusteeName, gAccessMask, gAceType, gAceFlags, gFlags, gObjectType, gInheritedObjectType)
AddAce dacl, sTrustee, ADS_RIGHT_DS_CREATE_CHILD, _
ADS_ACETYPE_ACCESS_ALLOWED, ADS_ACEFLAG_INHERIT_ACE, 0, 0, 0
' Add the modified DACL to the security descriptor.
oSecurityDescriptor.DiscretionaryAcl = dacl
' Save new SD onto the user.
objUser.MailboxRights = oSecurityDescriptor
' Commit changes from the property cache to the information store.
objUser.SetInfo
MsgBox "Done viewing and modifying the mailboxsecurity descriptor"
'********************************************************************
'*
'* Function AddAce(dacl, TrusteeName, gAccessMask, gAceType,
'* gAceFlags, gFlags, gObjectType, gInheritedObjectType)
'*
'* Purpose: Adds an ACE to a DACL
'* Input: dacl Object's Discretionary Access Control List
'* TrusteeName SID or Name of the trustee user account
'* gAccessMask Access Permissions
'* gAceType ACE Types
'* gAceFlags Inherit ACEs from the owner of the ACL
'* gFlags ACE has an object type or inherited object type
'* gObjectType Used for Extended Rights
'* gInheritedObjectType
'*
'* Output: Object - New DACL with the ACE added
'*
'********************************************************************
Function AddAce(dacl, TrusteeName, gAccessMask, gAceType, gAceFlags, gFlags, gObjectType, gInheritedObjectType)
Dim Ace1
' Create a new ACE object.
Set Ace1 = CreateObject("AccessControlEntry")
Ace1.AccessMask = gAccessMask
Ace1.AceType = gAceType
Ace1.AceFlags = gAceFlags
Ace1.Flags = gFlags
Ace1.Trustee = TrusteeName
'See whether ObjectType must be set
If CStr(gObjectType) <> "0" Then
Ace1.ObjectType = gObjectType
End If
'See whether InheritedObjectType must be set.
If CStr(gInheritedObjectType) <> "0" Then
Ace1.InheritedObjectType = gInheritedObjectType
End If
dacl.AddAce Ace1
' Destroy objects.
Set Ace1 = Nothing
End Function