Workflow Capabilities

[Previous] [Next]

One feature that Exchange 2000 offers is the ability to set permissions at both the item and property level for documents or other sorts of objects contained in the Exchange 2000 database. This functionality is different from Exchange 5.5, which allows you to set permissions only at the folder level. Imagine what kind of impact this ability will have on your applications. Now you can secure your applications even further when data is stored in even a single folder. This section outlines how to use the new security features in Exchange 2000 and shows you a Web application that allows you to try out these new security features.

NOTE
If you set item level security in Exchange 2000 and the item is replicated to an Exchange 5.5. server, your security will not be enforced since Exchange 5.5 does not support item level security.

Security Features

Exchange 2000 supports native Windows 2000 security descriptors. Using these descriptors, you can allow or deny access to an item or the item's properties, grant this access using Windows 2000 security identifiers, and access and set permissions by viewing and modifying the descriptor in an XML format from WebDAV or ADO/OLEDB. By providing you with an XML representation of the security descriptor, Exchange 2000 makes it very easy for you to work with security settings; you do not have to learn Windows API programming to change permissions. Furthermore, the technology in Exchange 2000 takes your XML descriptor and turns it into the correct binary representation of the descriptor in the Exchange database. You can access the XML formatted descriptor by querying for the property http://schemas.microsoft.com/exchange/security/descriptor . The following code is an example of what is returned on an item when you query for this property from ADO:

 'ADO code Dim oRecord As New ADODB.Record oRecord.Open "file://./backofficestorage/domain/apps/items/exchange.eml" 

Following are the XML results:

 <S:security_descriptor xmlns:S="http://schemas.microsoft.com/security/" xmlns:D="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" D:dt="microsoft.security_descriptor"> <S:revision>1</S:revision> <S:owner S:defaulted="0"> <S:sid> <S:string_sid>S-1-5-21-1659004503-152049171-1202660629-1110 </S:string_sid> <S:nt4_compatible_name>THOMRIZNT5DOM\thomriz</S:nt4_compatible_name> <S:user_principal_name>thomriz@thomriznt5dom.extest.microsoft.com</S:user_ principal_name> <S:display_name>Thomas Rizzo</S:display_name> </S:sid> </S:owner> <S:primary_group S:defaulted="0"> <S:sid> <S:string_sid>S-1-5-21-1659004503-152049171-1202660629-513 </S:string_sid> <S:nt4_compatible_name>THOMRIZNT5DOM\Domain Users </S:nt4_compatible_name> </S:sid> </S:primary_group> <S:dacl S:defaulted="1" S:protected="0" S:autoinherited="1"> <S:revision>2</S:revision> <S:effective_aces> <S:access_allowed_ace S:inherited="1"> <S:access_mask>1fcfff</S:access_mask> <S:sid> <S:string_sid>S-1-5-21-1659004503-152049171-1202660629-1110 </S:string_sid> <S:nt4_compatible_name>THOMRIZNT5DOM\thomriz</S:nt4_compatible_name> <S:user_principal_name>thomriz@thomriznt5dom.extest.microsoft.com </S:user_principal_name> <S:display_name>Thomas Rizzo</S:display_name> </S:sid> </S:access_allowed_ace> <S:access_allowed_ace S:inherited="1"> <S:access_mask>1fcfff</S:access_mask> <S:sid> <S:string_sid>S-1-5-21-1659004503-152049171-1202660629-1105 </S:string_sid> <S:nt4_compatible_name>THOMRIZNT5DOM\Domain EXServers </S:nt4_compatible_name> </S:sid> </S:access_allowed_ace> <S:access_allowed_ace S:inherited="1"> <S:access_mask>1fcfff</S:access_mask> <S:sid> <S:string_sid>S-1-5-21-1659004503-152049171-1202660629-500 </S:string_sid> <S:nt4_compatible_name>THOMRIZNT5DOM\Administrator</S:nt4_compatible_name> <S:display_name>Administrator</S:display_name> </S:sid> </S:access_allowed_ace> <S:access_allowed_ace S:inherited="1"> <S:access_mask>1fcfff</S:access_mask> <S:sid> <S:string_sid>S-1-5-21-1659004503-152049171-1202660629-519 </S:string_sid> <S:nt4_compatible_name>THOMRIZNT5DOM\Enterprise Admins </S:nt4_compatible_name> </S:sid> </S:access_allowed_ace> <S:access_allowed_ace S:inherited="1"> <S:access_mask>1fcfff</S:access_mask> <S:sid> <S:string_sid>S-1-5-21-1659004503-152049171-1202660629-512 </S:string_sid> <S:nt4_compatible_name>THOMRIZNT5DOM\Domain Admins </S:nt4_compatible_name> </S:sid> </S:access_allowed_ace> <S:access_allowed_ace S:inherited="1"> <S:access_mask>12088f</S:access_mask> <S:sid> <S:string_sid>S-1-1-0</S:string_sid> <S:nt4_compatible_name>\Everyone</S:nt4_compatible_name> </S:sid> </S:access_allowed_ace> </S:effective_aces> </S:dacl> </S:security_descriptor> 

This XML code is for a non-folder security descriptor—specifically, for an item. A folder security descriptor is a little bit different, but as you can see in the XML structure shown in the code above, a security descriptor is made up of a Discretionary Access Control List (DACL) which in turn is made up of Access Control Entries (ACE). Each ACE in the DACL either grants or denies a trustee a certain set of rights to the object. The access mask, which you see defined in the XML, describes the set of rights that are granted or denied to a user. Access masks are 32-bit numbers where the upper 16 bits describe generic rights and the lower 16 bits describe object specific rights.

Tables 19-12, 19-13, and 19-14 outline the different sets of access rights you can have: standard access rights, access rights on folders, and on non-folders (items), respectively. Values from each table can be combined and put into the access mask to create the correct security descriptor for the user.

Table 19-12. Standard rights (Non-Exchange, Windows 2000).

Name Value (Hex) Description
fsdrightDelete 0x00010000 Delete
fsdrightReadControl 0x00020000 Read access to security descriptor and owner
fsdrightWriteSD 0x00040000 Write DACL permissions
fsdrightWriteOwner 0x00080000 Used to assign write owner
fsdrightSynchronize 0x00100000 Used to synchronize access to the object

If you were to create an access mask with all the properties in Table 19-12, the value would be 0x1F0000.

Table 19-13. Folder rights.

Name Value (Hex) Description
fsdrightListContents 0x00000001 Right to list contents of the directory.
fsdrightCreateItem 0x00000002 Right to add a file to the folder.
fsdrightCreateContainer 0x00000004 Right to add a subfolder
fsdrightReadProperty 0x00000008 Right to read extended attributes
fsdrightWriteProperty 0x00000010 Right to write extended attributes
fsdrightReadAttributes 0x00000080 Right to read file attributes. Currently unused.
fsdrightWriteAttributes 0x00000100 Right to change file attributes. Currently unused.
fsdrightWriteOwnProperty 0x00000200 Right to modify own items (Exchange specific property)
fsdrightDeleteOwnItem 0x00000400 Right to delete own items
fsdrightViewItem 0x00000800 Right to view items (Exchange specific)
fsdrightOwner 0x00004000 Owner of the folder. Provided for backwards compatability.
fsdrightContact 0x00008000 Contact for the folder. Provided for backwards compatability.

If a user has all rights in Table 19-13, the value of the mask would be 0xCFFF.

Table 19-14. Item rights.

Name Value (Hex) Description
fsdrightReadBody 0x00000001 Right to read data from a file.
fsdrightWriteBody 0x00000002 Right to write data to a file.
fsdrightAppendMessage 0x00000004 Same as fsdrightWriteBody. Not currently used.
fsdrightReadProperty 0x00000008 Right to read extended attributes.
fsdrightWriteProperty 0x00000010 Right to write extended attributes.
fsdrightExecute 0x00000020 Right to execute a file. Currently not used.
fsdrightReadAttributes 0x00000080 Right to read file attributes.
fsdrightWriteAttributes 0x00000100 Right to change file attributes.
fsdrightWriteOwnProperty 0x00000200 Right to modify own item (Exchange-specific).
fsdrightDeleteOwnItem 0x00000400 Right to delete own item (Exchange-specific).
fsdrightViewItem 0x00000800 Right to view item (Exchange-specific).

If a user has all the rights in Table 19-14, the value would be 0x0FBF.

As you can see in the preceding XML code example, you can have an access_allowed_ACE, which contains the access mask for the rights you are going to allow for the user on the item or folder. You can also have an access_denied_ACE, which specifies an access mask that contains the rights you are going to deny for the user on the folder or item. If the user has all rights, as in the preceding XML example, the access mask will be 1FCFFF, which means all rights from all the tables above are granted to the user. Creating the access mask is just a matter of adding the hexidecimal values from the tables together and creating the ACE for the user. We'll see an example on how to create an ACE later in this chapter using the XMLDOM.

One fact you need to know even before we drill down into a sample application is that there are certain rights that the user needs to be able to access the security descriptor. These rights are fsdrightReadControl, fsdrightWriteSD, and fsdrightWriteOwner.

Sample Security Application

One of the sample applications included on the companion CD will, I know, make using the XML security descriptor much easier for you. The security sample application is a Web application that highly leverages the XMLDOM, XSL as well as WebDAV to show you how to work with and set the XML security descriptors in Exchange 2000. Figure 19-15 shows the main interface for the security application.

click to view at full size.

Figure 19-15. The main interface for the security application.

One task to try when working with the security application is restricting who can view items in an Exchange folder. The way to do this in the application is included in the next bit of code. As you can see in Figure 19-16, the user can view the document named ADO and Exchange 2000. However, after applying the setting that denies this user access to the document, as shown in Figure 19-17, the user can no longer see that specific document but can see all the other documents contained in the folder. Figure 19-17 shows what the user sees after applying the security change.

The application works by combining the XMLDOM, XSL, and WebDAV to get, display, and set both item and property_level security in Exchange. As you can see from the following code snippet, when you click the OK button to retrieve the security for an object in Exchange, the application does a PROPFIND on the http://schemas.microsoft.com/exchange/security/descriptor property. The application then uses XSL to display the HTML that you see in the browser.

click to view at full size.

Figure 19-16. Before applying the security settings, the user can view the full list of documents.

click to view at full size.

Figure 19-17. After applying the security settings, the user can no longer view the restricted files.

 function cmdGetSec.onclick() { var strReqBody = ""; if(txtUrl.value == "") { alert("Please Enter or select a valid URL."); return; } strReqBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<propfind xmlns=\"DAV:\">" + "<prop xmlns:r=\"http://schemas.microsoft.com/exchange/security/\">" + " <r:descriptor/>" + "</prop>" + "</propfind>" DAVRequest.open("PROPFIND", txtUrl.value, false); DAVRequest.setRequestHeader("Content-Type", "text/xml"); DAVRequest.setRequestHeader("Depth", "0"); DAVRequest.setRequestHeader("Translate", "f"); DAVRequest.send(strReqBody); if(chkMultiStatusForErr(DAVRequest) >= 0) { xmlResponse = DAVRequest.responseXml; perm_entries_dest.innerHTML = xmlResponse.transformNode(xslPerm_Entries); ace_entries_dest.innerHTML = "<div/>"; ace_edit_dest.innerHTML = "<div/>"; add_dest.innerHTML = "<DIV/>"; xmlResponse.transformNodeToObject(xslAceEntries.documentElement, xmlAceEntries); HiLitePermsTable(); propfindForResources(); cmdAdd.disabled = false; cmdRemove.disabled = true; cmdAceApply.disabled = true; cmdAceCancel.disabled = true; strOwner = owner.innerText;      }      } 

To add a new Access Control Entry, all the application does is take your entered data and turn it into a new XML node that it adds to the XML security descriptor. To do this, the application fills in the required properties to correctly generate a new ACE such as NT4 compatible name, the access mask, as well as the ACE type. The code that does the XML work is shown here:

 function addAce(strUserName, strMask, strPropName, strApplyTo, _ strRoleProp, strRoleScope, fbAllow) { // Basic variable declarations. var baseNode = null; var nodeFirstAce = null; var nodeSubNode = null; var nodeNewNode = null; var nOrder = 0; nOrder = getAceOrder(strUserName, null, strPropName, strApplyTo, strRoleProp, strRoleScope, fbAllow); while(nOrder > -1) { removeAce(nOrder); nOrder = getAceOrder(strUserName, strMask, strPropName, strApplyTo, strRoleProp, strRoleScope, fbAllow); } // Establish the base node. baseNode = xmlAceEntries.documentElement; // Create the ace node. nodeNewNode = xmlAceEntries.createNode(1, "ace", "");      // Add the NT4_Compatible_Name sub node. nodeSubNode = xmlAceEntries.createNode(1, "NT4_Compatible_Name", ""); nodeSubNode.text = strUserName; nodeNewNode.appendChild(nodeSubNode); // Add the Access_Mask sub node. nodeSubNode = xmlAceEntries.createNode(1, "Access_Mask", ""); nodeSubNode.text = strMask; nodeNewNode.appendChild(nodeSubNode); // Add the Ace_Type sub node. nodeSubNode = xmlAceEntries.createNode(1, "Ace_Type", ""); nodeSubNode.text = getAceType(strPropName, fbAllow); nodeNewNode.appendChild(nodeSubNode); // Add the Apply_To sub node. nodeSubNode = xmlAceEntries.createNode(1, "Apply_To", ""); nodeSubNode.text = strApplyTo; nodeNewNode.appendChild(nodeSubNode); // Add the Property_Name sub node. nodeSubNode = xmlAceEntries.createNode(1, "Property_Name", ""); nodeSubNode.text = strPropName; nodeNewNode.appendChild(nodeSubNode); if(strRoleScope != null && strRoleScope != "") { nodeSubNode = xmlAceEntries.createNode(1, "Role_Scope", ""); nodeSubNode.text = strRoleScope; nodeNewNode.appendChild(nodeSubNode); } if(strRoleProp != null && strRoleProp != "") { nodeSubNode = xmlAceEntries.createNode(1, "Role_Property", ""); nodeSubNode.text = strRoleProp; nodeNewNode.appendChild(nodeSubNode); } baseNode = xmlAceEntries.documentElement; baseNode.appendChild(nodeNewNode); refreshAceList();      } 

To set the security, the application does a PROPPATCH to the same property but with the new security descriptor formatted as XML and the new security added as XML nodes.

 function cmdAceApply.onclick() { var xmldomAce = new ActiveXObject("Microsoft.XMLDOM"); var xmlAccessMaskNode = null; var xmlAceTypeNodes = null; var xmlAceTypeNode = null; var xmlUserNameNode = null; var xmlApplyToNode = null; var xmlPropNode = null; cmdAceApply.disabled = true; cmdAceCancel.disabled = true; addAcesOutstandingAcesToXML(); xmlAceEntries.transformNodeToObject(xslProppatch.documentElement, xmldomProppatch); DAVRequest.open("PROPPATCH", txtUrl.value, false); DAVRequest.setRequestHeader("Content-Type", "text/xml"); DAVRequest.setRequestHeader("Translate", "f"); DAVRequest.send(xmldomProppatch); if(chkMultiStatusForErr(DAVRequest) >= 0) { HiLitePermsTable(); if(nCurrentAce > -1) { xmldomAce.loadXML( xmlAceEntries.childNodes(0).childNodes(nCurrentAce).xml); ace_entries_dest.innerHTML = xmldomAce.transformNode(xslDips_ACE_Info); ace_edit_dest.innerHTML = xmldomAce.transformNode(xslACE_Edit.documentElement); perm_entries_dest.innerHTML = xmldomProppatch.transformNode(xslPerm_Entries); HiLiteRow(thetable, nCurrentAce+1); } } cmdGetSec.onclick(); return ""; } 



Programming Microsoft Outlook and Microsoft Exchange
Programming Microsoft Outlook and Microsoft Exchange, Second Edition (DV-MPS Programming)
ISBN: 0735610193
EAN: 2147483647
Year: 2000
Pages: 184

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net