Exchange Server and Security


Exchange 2000 Server and Exchange Server 2003 offer the ability to set permissions not only at the folder level but also at the item and property levels for documents or other objects contained in the Exchange information store. This means that you can secure your applications even further when data is stored in a single folder. We'll discuss the security features in Exchange and look at a Web application that allows you to try out these security features.

Note  

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

Security Features

Exchange Server supports native Windows security descriptors. Using these descriptors, you can allow or deny access to an item or the item's properties, grant this access using Windows security identifiers, and access and set permissions by viewing and modifying the descriptor in an XML format from WebDAV or ADO/OLE DB (which we discussed in Chapter 16). By providing you with an XML representation of the security descriptor, Exchange makes it 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 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 http://schemas.microsoft.com/exchange/ security/descriptor property. 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" strSec = oRecord.Fields( _             "http://schemas.microsoft.com/exchange/security/descriptor").value 

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:userprincipal_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 nonfolder security descriptor ” specifically , an item. A folder security descriptor is a bit different, but as you can see in the XML structure shown in the code, a security descriptor is made up of a Discretionary Access Control List (DACL), which in turn is made up of Access Control Entries (ACEs). 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 in which the upper 16 bits describe generic rights and the lower 16 bits describe object-specific rights.

Some quick points about what you see in the XML that is returned. The defaulted flag tells whether the DACL was a default DACL. For example, on item creation, a default DACL was used rather than someone specifying it. This affects how inherited ACEs are treated in the DACL. The protected flag specifies whether the DACL of the security descriptor will inherit any aces from its parent. It gets changed by an application program or when you deselect the Allow Inheritable Permissions From The Parent To Propagate check box in the Security Settings dialog box. If you want to set up custom security on your folder and not inherit from your parent, you set the protected flag to 1 for your DACL. This causes all inherited ACEs to be ignored. The autoinherited flag specifies whether the DACL can have ACEs automatically propagated to child objects. The primary group tag is for POSIX compatibility.

We need to discuss three other blocks: effective_aces , subcontainer_inheritable , and subitem_inheritable . The descriptor section for effective_aces applies to the item in question, and subcontainer_inheritable applies to subfolders and is present only in the security descriptor for folders. The subitems_inheritable section applies to items and messages and is present only in the security descriptor of a folder. When a folder or item is created, by default it gets the permissions that appear in the subcontainer/subitem block of the security descriptor of its parent folder. If the no_propagate_inherit attribute is set in the ACE, it applies only to the immediate sublevel and will not appear in the subcontainer_inheritable block of the new folder.

A quick comment about working with security in Exchange. How you create the format for your security descriptor will depend on whether you are working in a MAPI public folder top-level hierarchy (TLH) or a non-MAPI TLH. A MAPI TLH requires that you create your security descriptor using the MAPI canonical format. This is what clients , such as Outlook, expect to see; the importance of this requirement cannot be overemphasized. If you create your security descriptor using the Windows canonical format, you will break Outlook! It is also possible to lock yourself out from being able to modify existing items or folders. Therefore, you must be very careful when you work with security descriptors. I highly recommend that you just take advantage of the Security Module that ships with the Exchange SDK. It understands how to correctly create both MAPI and Windows canonical formats and includes code to make sure you don't do any harm when working with security descriptors. You can find more information on the Security Module later in this chapter.

Note  

You might be wondering whether you should ever go through the M: drive to set security for your applications. In Exchange 2003, the M: drive is turned off by default, and you should try to keep it that way. However, if you turn the M: drive on, there are some security issues you should know about. For example, if you are working in non-MAPI folder trees ”which are essentially not in the MAPI-based public folder hierarchy ”you can use this method to set your security. If you are in the MAPI TLH and set security using Windows Explorer through the M: drive, you will break MAPI client applications such as Outlook and affect their ability to view and set permissions. This is because Windows Explorer formats the ACLs as Windows canonical and not MAPI canonical. In other words, do not set permissions using the M: drive for MAPI folders.

Tables 17-8, 17-9, and 17-10 describe the kinds of access rights you can have: standard access rights, access rights on folders, and access rights on nonfolders (items), respectively. You can combine values in each table and put them into the access mask to create the correct security descriptor for the user.

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

Table 17-8: Standard Rights (Non-Exchange, Windows)

Access Right

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 a user were to have all rights in Table 17-9, the value of the mask would be 0xCFFF .

Table 17-9: Folder Rights

Access Right

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 property).

fsdrightOwner

0x00004000

Owner of the folder. Provided for backward compatibility.

fsdrightContact

0x00008000

Contact for the folder. Provided for backward compatibility.

If a user were to have all the rights in Table 17-10, the value would be 0x0FBF .

Table 17-10: Item Rights

Access Right

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 property).

fsdrightDeleteOwnItem

0x00000400

Right to delete own item (Exchange-specific property).

fsdrightViewItem

0x00000800

Right to view item (Exchange-specific property).

In the preceding XML code example, you can have an access_allowed_ace , which contains the access mask for the rights you will 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 will 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 0x1FCFFF , which means all rights from the three previous tables are granted to the user. Creating the access mask is just a matter of adding together the hexadecimal values from the tables 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.

Before we drill down into a sample application, you need to know that there are certain rights the user needs in order to access the security descriptor: fsdrightReadControl , fsdrightWriteSD , and fsdrightWriteOwner .

A Sample Security Application

The security sample application included with the book's companion content makes using the XML security descriptor much easier. It is a Web application that leverages XMLDOM, XSL, and WebDAV to show you how to work with and set the XML security descriptors in Exchange. Figure 17-18 shows the main interface for the security application.

click to expand
Figure 17-18: The main interface for the security application

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

click to expand
Figure 17-19: Before you apply the security settings, the user can view the full list of documents.
click to expand
Figure 17-20: After you apply the security settings, the user can no longer view the restricted files.

The application works by combining XMLDOM, XSL, and WebDAV to get, display, and set item-level 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.

 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 ACE, 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 a Windows-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 2003
Programming MicrosoftВ® OutlookВ® and Microsoft Exchange 2003, Third Edition (Pro-Developer)
ISBN: 0735614644
EAN: 2147483647
Year: 2003
Pages: 227
Authors: Thomas Rizzo

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