This step-by-step article describes how to add an access
control entry (ACE) to a folder item in Exchange 2000 Server Web Storage
System.
The Web Storage System is a database technology that you can
use to store, share, and manage heterogeneous data, such as e-mail messages,
Web pages, multimedia files, and Microsoft Office 2000 documents. The Web
Storage System is organized similar to a conventional file system, in a
hierarchy of folders. Each folder in the Web Storage System can contain any
number of items, which includes other folders. You can access items in the Web
Storage System by using many protocols and application programming interfaces
(APIs), which include Hypertext Transfer Protocol (HTTP) and World Wide Web
Distributed Authoring and Versioning (WebDAV), Microsoft ActiveX Data Objects
(ADO) 2.5, OLE DB 2.5, Collaboration Data Objects for Microsoft Exchange 2000
Server (CDOEX), Messaging Application Programming Interface (MAPI), through the
file system, and by using other industry-standard wire protocols.
A
Microsoft Windows security descriptor defines access rights to a securable
object through definition of the object's owner and through a set of access
control entries (ACEs) in the descriptor's discretionary access control list
(DACL). Each ACE in the DACL either grants or denies a trustee a certain set of
access rights to the securable object. The set of rights granted or denied by a
particular ACE is contained in its access mask. The access mask is a 32-bit
number in which the upper 16 bits define standard and generic access rights and
the lower 16 bits define access rights that are object
specific.
Requirements
The following list outlines the recommended hardware, software,
network infrastructure, and service packs that you need:
- Microsoft Windows 2000
- Microsoft Exchange 2000 Server
- Microsoft Visual Basic 6.0 with Service Pack 5
(SP5)
- Microsoft XML 2.0
How to add an access control entry to a Web Storage System folder item
For the purpose of this article, it is assumed that Microsoft
Exchange 2000 Server is installed and that the Web Storage System functions
appropriately. Therefore, the user can visit a public folder and post and edit
items in the folder in Internet Explorer by typing the address in the following
format:
http://Server_Name/Public_Folder_Virtual_Directory_Name/Public_Folder_Name
How to create a Visual Basic project
- Make sure that Microsoft Visual Basic 6.0 SP5 and Internet
Explorer 5 or later are installed.
- Start Microsoft Visual Basic 6.0 SP5.
- In the New Project dialog box, double-click Standard EXE to create a new project.
- On the Project menu, click References.
- In the References dialog box, click to select the Microsoft XML, Version 2.0 check box, and then click OK.
How to copy the sample code to your project
- On the View menu, click Code.
- In the Visual Basic code window, paste the following code:
Const User_AuthFldAllow = &H1208AB
Const User_AuthFldDeny = &HDC914
Const User_AuthSitAllow = &H120EA9
Const User_AuthSitDeny = &H1F0716
Const Grp_AuthFldAllow = &H1208AB
Const Grp_AuthFldDeny = &HDC914
Const Grp_AuthSitAllow = &H120EA9
Const Grp_AuthSitDeny = &H1F0716
Private Function AddACE(ByVal Name As String, ByVal UserType As String, ByVal Allow As Long, ByVal Deny As Long) As String
Dim strXML As String
strXML = " <?xml version=""1.0""?>" & vbCrLf & _
" <add xmlns:S='http://schemas.microsoft.com/security/'>" & vbCrLf & _
" <S:access_allowed_ace S:inherited=""0"">" & vbCrLf & _
" <S:access_mask>" & Hex(Allow) & "</S:access_mask>" & vbCrLf & _
" <S:sid>" & vbCrLf & _
" <S:type>" & UserType & "</S:type>" & vbCrLf & _
" <S:nt4_compatible_name>" & Name & "</S:nt4_compatible_name>" & vbCrLf & _
" </S:sid>" & vbCrLf & _
" </S:access_allowed_ace>" & vbCrLf & _
" <S:access_denied_ace S:inherited=""0"">" & vbCrLf & _
" <S:access_mask>" & Hex(Deny) & "</S:access_mask>" & vbCrLf & _
" <S:sid>" & vbCrLf & _
" <S:nt4_compatible_name>" & Name & "</S:nt4_compatible_name>" & vbCrLf & _
" </S:sid>" & vbCrLf & _
" </S:access_denied_ace>" & vbCrLf & _
" </add>" & vbCrLf
AddACE = strXML
End Function
Public Function AddAuthorACE(ByVal FdPath As String, ByVal NTName As String, ByVal UserType As String)
Dim xmlReq As MSXML.XMLHTTPRequest
Dim query As String
Dim XMLDOM As MSXML.DOMDocument
Dim XMLRoot As MSXML.DOMDocument
Dim strNewNode As String
Dim xmlNode As MSXML.IXMLDOMNode
Dim effacesnode As MSXML.IXMLDOMNode
Dim subconacesnode As MSXML.IXMLDOMNode
Dim subitemacesnode As MSXML.IXMLDOMNode
Dim xmlNewACEDom As MSXML.DOMDocument
Dim xmlNewNode As MSXML.IXMLDOMNode
Set xmlReq = CreateObject("Microsoft.XMLHTTP")
Set XMLDOM = CreateObject("Microsoft.XMLDOM")
'Get the current Security Descriptor of the folder
xmlReq.open "PROPFIND", FdPath, False
xmlReq.setRequestHeader "Content-Type", "text/xml"
xmlReq.setRequestHeader "Depth", "0"
query = "<?xml version='1.0'?>"
query = query + "<a:propfind xmlns:a='DAV:'>"
query = query + "<a:prop xmlns:ex='http://schemas.microsoft.com/exchange/security/'>"
query = query + "<ex:descriptor/>"
query = query + "</a:prop>"
query = query + "</a:propfind>"
xmlReq.send (query)
Set XMLDOM = xmlReq.responseXML
'Greate the empty Security Descriptor ready to upgrade
query = ""
query = "<?xml version='1.0'?>"
query = query + "<a:propertyupdate xmlns:a='DAV:' xmlns:e='http://schemas.microsoft.com/exchange/security/'>"
query = query + "<a:set><a:prop><e:descriptor>"
query = query + "</e:descriptor></a:prop></a:set></a:propertyupdate>"
Set XMLRoot = CreateObject("Microsoft.XMLDOM")
XMLRoot.loadXML query
'Load the Security Descriptor from the current schema
Set xmlNode = XMLRoot.documentElement.selectSingleNode("//e:descriptor")
xmlNode.appendChild XMLDOM.documentElement.selectSingleNode("//S:security_descriptor")
Set effacesnode = XMLRoot.documentElement.selectSingleNode("//S:effective_aces")
Set subconacesnode = XMLRoot.documentElement.selectSingleNode("//S:subcontainer_inheritable_aces")
Set subitemacesnode = XMLRoot.documentElement.selectSingleNode("//S:subitem_inheritable_aces")
Set xmlNewACEDom = CreateObject("Microsoft.XMLDOM")
'Add the Access Permission for User/group
If UserType = "user" Then
strNewNode = AddACE(NTName, UserType, User_AuthFldAllow, User_AuthFldDeny)
Else
strNewNode = AddACE(NTName, UserType, Grp_AuthFldAllow, Grp_AuthFldDeny)
End If
xmlNewACEDom.loadXML strNewNode
Set xmlNewNode = xmlNewACEDom.documentElement.selectSingleNode("S:access_denied_ace")
effacesnode.insertBefore xmlNewNode, effacesnode.firstChild
Set xmlNewNode = xmlNewACEDom.documentElement.selectSingleNode("S:access_allowed_ace")
effacesnode.insertBefore xmlNewNode, effacesnode.firstChild
'Add the sub-container inheritable permission for user/group
If UserType = "user" Then
strNewNode = AddACE(NTName, UserType, User_AuthFldAllow, User_AuthFldDeny)
Else
strNewNode = AddACE(NTName, UserType, Grp_AuthFldAllow, Grp_AuthFldDeny)
End If
xmlNewACEDom.loadXML strNewNode
Set xmlNewNode = xmlNewACEDom.documentElement.selectSingleNode("S:access_denied_ace")
subconacesnode.insertBefore xmlNewNode, subconacesnode.firstChild
Set xmlNewNode = xmlNewACEDom.documentElement.selectSingleNode("S:access_allowed_ace")
subconacesnode.insertBefore xmlNewNode, subconacesnode.firstChild
'Add the sub-item inheritable Permission for user/group
If UserType = "user" Then
strNewNode = AddACE(NTName, UserType, User_AuthSitAllow, User_AuthSitDeny)
Else
strNewNode = AddACE(NTName, UserType, Grp_AuthSitAllow, Grp_AuthSitDeny)
End If
xmlNewACEDom.loadXML strNewNode
Set xmlNewNode = xmlNewACEDom.documentElement.selectSingleNode("S:access_denied_ace")
subitemacesnode.insertBefore xmlNewNode, subitemacesnode.firstChild
Set xmlNewNode = xmlNewACEDom.documentElement.selectSingleNode("S:access_allowed_ace")
subitemacesnode.insertBefore xmlNewNode, subitemacesnode.firstChild
xmlReq.open "PROPPATCH", FdPath, False
xmlReq.setRequestHeader "Content-Type", "text/xml"
xmlReq.setRequestHeader "Depth", "0"
xmlReq.send (XMLRoot.documentElement.xml)
End Function
- On the View Menu, click Object, and then drag a button from the Toolbox to the Form object.
- Double-click the button that you dragged in step 3 to
trigger a function named Command1_Click.
- Paste the following line into the function Command1_Click that you generated in step 4:
AddAuthorACE "http://MyExchangeServer/Public/MyFolder", "MYDOMAIN\user1", "user"
Note You must replace the hyperlink and account mentioned earlier to
your own link and account. - Run the project and note that the user who you want has
Author permissions on the folder.
More information
- The access mask for users and groups to obtain permission
has been defined at the beginning of this article. The access mask is a 32-bit
number in which the upper 16 bits define standard and generic access rights and
the lower 16 bits define access rights that are object specific. For more
information about mask Web Storage System security roles visit the following
Microsoft Web site:
- Folder item security descriptors includes three main parts:
- effective_aces: contains the ACE for effective
permission set on the folder.
- subcontainer_inheritable_aces: by default, the sub
folders in this folder inherits the ACE from this part.
- subitem_inheritable_aces: by default, the sub items in
this folder inherits the ACE from this part.
- To prevent the user or group from accessing the folder,
remove the corresponding ACEs from the folder security descriptor.
- An ACE typically contains both access_denied_ace and
access_allowed_ace so that the permission set of the user can be identified by
the system clearly.
- When new items are created in folders, the new items are
secured by using the ACEs present in the subitem_inheritable_aces section of
the parent folder's discretionary access control list (ACL). In a sense, the
item inherits a "virtual" descriptor from its parent folder. If the parent
folder's descriptor changes, the item automatically inherits the changes. When
you set the descriptor for an item, the "virtual" inheritance is no longer
used, and the item's descriptor is used to control access. Therefore, if you
make changes to the parent folder's descriptor, items that have had their
descriptors set directly do not inherit these changes.
Frequently asked questions
Q1: What type of URL should I use? File or HTTP?A1: When you use the Exchange OLE DB (ExOLEDB) provider or XML
descriptor, you can use URLs from either the file or HTTP schemes.
Q2: Does MAPI still function?A2: Yes. All forms written by using Microsoft Visual C++ and MAPI
continues to function as before.
Q3: Can I change the inherited permission from the parent folder?A3: No. You cannot change the inherited ACE on the folder level. You
have to edit the subcontainer_inheritable_aces ACE in the parent
folder.
Troubleshooting
In some scenarios, it is possible that after you run the code,
the ACE is still not added when you open Microsoft Outlook or Microsoft
Exchange Manager to review. The security descriptor may be corrupted under such
scenario. You may have to test the code on a newly created folder
instead.