Unlocking the black box that is AD RMS Part 5

All right folks, this will be the final scenario that we cover.

Scenario:This scenario will involve protecting a document and assigning Read rights to Group3@contoso.local, which is a distribution group in contoso.local containing as a member acontact object representing UserGG from fabrikam.local. The contact object will be populated with UserGG’s email address of UserGG@fabrikam.local.
Author: UserA@contoso.local
Consumer: UserGG@contoso.local
Captures:Scenario 4 Captures
Let’s begin…

  1. Client searches registry to see if service connection point (SCP) has been hardcoded. It checks the following keys:
    • HKLMSoftwareMicrosoftMSDRMServiceLocationActivation – This is a hardcoded location for client activation.
    • HKLMSoftwareMicrosoftMSDRMServiceLocationEnterprise – This is the hardcoded location to obtain a CLC.
    • HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocation – This is where previously discovered service locations are stored for Office 2010.
    • HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocation – This is where previously discovered service locations are stored for Office 2013.
  2. Client contacts contoso.local AD RMS cluster via the licensing pipeline (https://adrms.contoso.local/_wmcs/licensing) stored in the protected document and requests a EUL. Client is redirected to license.asmx and acquisition of EUL begins.
  3. AD RMS Server in contoso.local makes the following queries to the global catalog in contoso.local:
    1. Resolve the group membership for the UserGG contact object in the contoso.local domain.
      • Filter: (& (| (mail=UserGG@fabrikam.local)(proxyAddresses=smtp:UserGG@fabrikam.local))(|(objectcategory=computer)(objectcategory=person)))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )

      This search will return the contact object in the contoso.local domain that exists with the UserC@fabrikam.local email address.  This search also allows the AD RMS server to verify UserC isn’t AKA UserA@contoso.local.

    2. Check contoso.local to see if a user, computer, or contact object exists with the SID of the consumer (UserGG@fabrikam.local).
      • Filter: ( & ( | (objectSid=ConsumerSID) (sIDHistory=ConsumerSID) ) ( | (objectCategory=Computer) (objectCategory=Person) ) )
        Attributes: mail,objectSid,sIDHistory,proxyAddresses,memberOf,primaryGroupID,distinguishedName,uSNChanged,msExchOriginatingForest,msExchDynamicDLBaseDN, msExchDynamicDLFilter,userPrincipalName,sAMAccountName

      This search will return zero results as no such object exists.  This search also is being used to check whether or not the authenticated user is AKA Group3@contoso.local

    3. Check contoso.local to see if a user, computer, or contact object exists with the consumer’s email address (UserGG@fabrikam.local).
      • Filter: (& (| (mail=UserGG@fabrikam.local)(proxyAddresses=smtp:UserGG@fabrikam.local))(|(objectcategory=computer)(objectcategory=person)))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )

      This search will return the contact object in the contoso.local domain that exists with the UserGG@fabrikam.local email address. This contact object is used to represent UserGG from the fabrikam.local domain.  This search also is being used to check whether or not email address represented in the consumer’s RAC is linked to an object with the group2@contoso.local email address.

    4. Check contoso.local to see whether or not Group2@contoso.local is a valid group.
      • Filter: (& (| (mail=group3@contoso.local)(proxyAddresses=smtp:group3@contoso.local))(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )

      This search will return Group3 distribution group object in the contoso.local domain.  This check is being used to determine if the Group3 is a valid group.

    5. Check contoso.local for consumer’s (UserGG@fabrikam.local) SID to see if a user, computer, or contact object exists in the contoso.local domain with the MemberOf attribute populated with group3@contoso.local’s SID.
      • Filter: ( & ( | (objectSid=ConsumerSID9) (sIDHistory=ConsumerSID) ) ( | (objectCategory=Computer) (objectCategory=Person) ) )
        Attributes: mail,objectSid,sIDHistory,proxyAddresses,memberOf,primaryGroupID,distinguishedName,uSNChanged,msExchOriginatingForest,msExchDynamicDLBaseDN, msExchDynamicDLFilter,userPrincipalName,sAMAccountName

      This search will return zero results as no such object exists.  This check is being used to determine if the authenticated user is a valid user in the contoso.local forest, which it is not.

    6. Check contoso.local for any group or contact object with msExchOriginatingForest (think group expansion here) that is a member of Group2.
      • Filter: (|(&(objectCategory=group)(memberOf=<GUID=<GroupGUID>))(&(objectCategory=contact)(memberOf=<GroupGUID>)(msExchOriginatingForest Present)))
        Attributes: ( mail )( distinguishedName )( msExchOriginatingForest )

      This search will return zero results as no such object exists.  This check is being used to determine whether the authenticated user is a member of the group.

    7. Resolve the group membership of the Group3 group object in contoso.local.
        • Filter: (& (| (mail=group3@contoso.local)(proxyAddresses=smtp:group3@contoso.local))(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
          Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )

      This search will return Group3 distribution group object in the contoso.local domain.  This check is again used to determine if Group2 is a valid group.

    8. Resolve the group membership for the UserGG contact object in the contoso.local domain.
      • Filter: (& (| (mail=UserGG@fabrikam.local)(proxyAddresses=smtp:UserGG@fabrikam.local))(|(objectcategory=computer)(objectcategory=person)))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )

      This search will return the contact object in the contoso.local domain that exists with the UserGG@fabrikam.local email address.  This verified that the contact object representing UserGG is a member of Group3.

    9. Check contoso.local to see if a user, computer, or contact object exists with the SID of the consumer (UserGG@fabrikam.local).
      • Filter: ( & ( | (objectSid=ConsumerSID) (sIDHistory=ConsumerSID) ) ( | (objectCategory=Computer) (objectCategory=Person) ) )
        Attributes: mail,objectSid,sIDHistory,proxyAddresses,memberOf,primaryGroupID,distinguishedName,uSNChanged,msExchOriginatingForest,msExchDynamicDLBaseDN, msExchDynamicDLFilter,userPrincipalName,sAMAccountName

      This search will return zero results as no such object exists.  This check is is being used to verify whether or or not the authenticated user is AKA the publisher (userA@contoso.local).

    10. Resolve the group membership for the UserGG contact object in the contoso.local domain.
      • Filter: (& (| (mail=UserGG@fabrikam.local)(proxyAddresses=smtp:UserGG@fabrikam.local))(|(objectcategory=computer)(objectcategory=person)))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )

      This search will return the contact object in the contoso.local domain that exists with the UserGG@fabrikam.local email address.  This check is being used to verify whether or not the contact object representing UserGG is AKA as the publisher (userA@contoso.local).

    11. Check to see whether the publisher (UserA@fabrikam.local) is a valid group.
      • Filter: (& (| (mail=UserA@contoso.local)(proxyAddresses=smtp:UserA@contoso.local))(|(objectcategory=group)(objectcategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )

      This search will return zero results as UserA is not a group or contact object with msExchOriginatingForest populated.

    12. Run the same query again for some reason.
      • Filter: (& (| (mail=UserA@fabrikam.local)(proxyAddresses=smtp:UserA@fabrikam.local))(|(objectcategory=group)(objectcategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )

      This search will return zero results as UserA is not a group or contact object with msExchOriginatingForest populated.

  4. After confirming group membership with the 9th LDAP query listed in the previous step, AD RMS Server in contoso.local issues EUL and sends back to client in fabrikam.local.
  5. Client receives EUL, consumes it, and contents are displayed in Microsoft Office application with appropriate rights applied.

I found a few articles from Microsoft stating that msDS-SourceObjectDN was required when doing group membership in this manner. The articles were specific to Microsoft Exchange IRM, so it is possible additional queries are performed when Microsoft Exchange is involved. For the purposes above, the attribute was not required for consumption.

Unlocking the black box that is AD RMS Part 4

For this point forward, we will be using an AD RMS client that has already activated and obtained a rights account certificate.

Scenario:This scenario will involve protecting a document and assigning Read rights to Group1, which is a distribution group in fabrikam.local containing UserC. We will also create a contact object in contoso.local representing Group1. We will populate the mail attribute with Group1.fabrikam.local and the msExchOriginatingForest attribute with the value of fabrikam.local for this contact object. The msExchOriginating forest is an indicator to the AD RMS service that the contact object represents a group in another forest and that the AD RMS service needs to contact the AD RMS cluster in that forest to start group expansion.
Author: UserA@contoso.local
Consumer: UserC@contoso.local
Captures: Scenario 3 Captures

Let’s begin…

  1. Client searches registry to see if service connection point (SCP) has been hardcoded. It checks the following keys:
    • HKLMSoftwareMicrosoftMSDRMServiceLocationActivation – This is a hardcoded location for client activation.
    • HKLMSoftwareMicrosoftMSDRMServiceLocationEnterprise – This is the hardcoded location to obtain a CLC.
    • HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocation – This is where previously discovered service locations are stored for Office 2010.
    • HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocation – This is where previously discovered service locations are stored for Office 2013.
  2. Client contacts contoso.local AD RMS cluster via the licensing pipeline (https://adrms.contoso.local/_wmcs/licensing) stored in the protected document and requests a EUL. Client is redirected to license.asmx and acquisition of EUL begins.
  3. AD RMS Server in contoso.local makes the following queries to the global catalog in contoso.local:
    1. Check contoso.local to see if a user object has both the author’s email address (UserA.contoso.local) and the consumer’s email address (UserC@contoso.local).
      • Filter: (& (| (mail=UserC@fabrikam.local)(proxyAddresses=smtp:UserC@fabrikam.local))(|(objectcategory=computer)(objectcategory=person)))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    2. Check contoso.local to see if a distribution list or contact object with msOriginatingForest exists in contoso.local that matches UserC’s SID and has the group1@fabrikam.local email address. I’m not sure how this query would ever ring true, because the SID it is querying with is the SID it retrieved from the authenticated user. Maybe for SIDHistory?
      • Filter: (& (| (objectSID=)(sIDHistory=)(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    3. Check contoso.local to see if a user object exists with both UserC@fabrikam.local and Group1@fabrikam.local as an email address. This is checking to see whether a user object has both consumer’s email address and the distribution group email address.
      • Filter: (& (| (mail=UserC@fabrikam.local)(proxyAddresses=smtp:UserC@fabrikam.local))(|(objectcategory=computer)(objectcategory=person)))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    4. Check contoso.local to see whether or not Group1@fabrikam.local is a valid group. This query comes back as successful since Group1@fabrikam.local is a valid contact object with msOriginatingForest populated.
      • Filter: (& (| (mail=group1@fabrikam.local)(proxyAddresses=smtp:group1@fabrikam.local))(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    5. Check contoso.local for consumer’s SID to see whether or not the consumer is a valid user in the contoso.local forest.
      • Filter: ( & ( | (objectSid=S-1-5-21-2502964694-2714205513-579894926-1109) (sIDHistory=S-1-5-21-2502964694-2714205513-579894926-1109) ) ( | (objectCategory=Computer) (objectCategory=Person) ) )
        Attributes: mail,objectSid,sIDHistory,proxyAddresses,memberOf,primaryGroupID,distinguishedName,uSNChanged,msExchOriginatingForest,msExchDynamicDLBaseDN, msExchDynamicDLFilter,userPrincipalName,sAMAccountName
  4. AD RMS Server in contoso.local consumer msOriginatingForest from Group1 contact object and query global catalog in fabrikam.local for AD RMS SCP.
  5. Domain controller in fabrikam.local responds with AD RMS SCP.
  6. AD RMS Server in contoso.local contacts certification pipeline in fabrikam.local AD RMS cluster (https://adrms.fabrikam.local/certification/) Server.asmx and requests a service location for group expansion.
  7. AD RMS Server in fabrikam.local responds with group expansion service URL (https://adrms.fabrikam.local/groupexpansion/groupexpansion.asmx).
  8. AD RMS Server in contoso.local contacts group expansion pipeline in fabrikam.local and request group expansion for Group1@fabrikam.local.
  9. AD RMS Server in fabrikam.local queries global catalog in fabrikam.local with the following queries:
    1. Query to find the SID of group1@fabrikam.local. This is done to gather the SID, which will then be used when checking group membership of the consumer.
      • Filter: (& (| (mail=group1@fabrikam.local(proxyAddresses=smtp:group1@fabrikam.local))(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    2. Query to find the consumer’s user account (UserC@fabrikam.local) and then check to see if the SID of the distribution group (Group1@fabrikam.local) is included in the MemberOf attribute of the user.
      • Filter: (& (| (mail=UserC@fabrikam.local)(proxyAddresses=smtp:UserC@fabrikam.local))(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    3. Query to discover the consumer’s (UserC@fabrikam.local) primary group. Again, not sure why this is done.
      • Filter: ( & (objectCategory=CN=Group,CN=Schema,CN=Configuration,DC=fabrikam,DC=local) (objectSid=S-1-5-21-2502964694-2714205513-579894926-513) )
        Attributes: distinguishedName
  10. AD RMS Server in fabrikam.local returns message to AD RMS Server in contoso.local that consumer (UserC@fabrikam.local) is valid member of the distribution group (group1@fabrikam.local).
  11. AD RMS Server in contoso.local then performs the following queries against the global catalog in contoso.local.
    1. Check to see if contoso.local has a distribution group or contact object with msExchOriginatingForest populated that has a SID matching the consumer’s SID (UserC@fabrikam.local) and has an email address of the author (UserA@contoso.local).
      • Filter: (& (| (objectSID=)(sIDHistory=)(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    2. Check to see if contoso.local has a user object that has both the consumer email address (UserC@fabrikam.local) and author’s email address (UserA@contoso.local).
      • Filter: (& (| (mail=UserC@fabrikam.local)(proxyAddresses=smtp:UserC@fabrikam.local))(|(objectcategory=computer)(objectcategory=person)))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    3. Check to see if the object associated with the author’s email address (UserA@contoso.local) is a group or contact object with msOriginatingForest populated.
      • Filter: (& (| (mail=UserA@contoso.local)(proxyAddresses=smtp:UserA@contoso.local))(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    4. Run the same check as above to see if the object associated with the author’s email address (UserA@contoso.local) is a group or contact object with msOriginatingForest populated. Not sure why this is done twice.
      • Filter: (& (| (mail=UserA@contoso.local)(proxyAddresses=smtp:UserA@contoso.local))(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
  12. AD RMS Server in contoso.local issues EUL and sends back to client in fabrikam.local.
  13. Client receives EUL and saves it to C:UsersUserNameAppDataLocalMicrosoftDRM for Office 2010 and C:UsersUserNameAppDataLocalMicrosoftMISPC for Office 2013.

Unlocking the black box that is AD RMS Part 3

Let’s continue and we’ll introduce the second forest with its own AD RMS cluster.

Scenario: Client InterForest Activation and Consumption of Protected Content. In this scenario UserA in contoso.local (UserA@contoso.local) has protected a document and given UserB in fabrikam.local (UserB@fabrikam.local) the Read right. The steps below describe UserB’s process to activate, certify, and consume the content protected by UserA.
Author: UserA@contoso.local
Consumer: UserB@fabrikam.local
Captures: Scenario 2 Captures

  1. Client searches registry to see if service connection point (SCP) has been hardcoded. It checks the following keys:
    1. HKLMSoftwareMicrosoftMSDRMServiceLocationActivation – This is a hardcoded location for client activation.
    2. HKLMSoftwareMicrosoftMSDRMServiceLocationEnterprise – This is the hardcoded location to obtain a CLC.
    3. HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocation – This is where previously discovered service locations are stored for Office 2010.
    4. HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocation – This is where previously discovered service locations are stored for Office 2013.
  2. Client contacts contoso.local AD RMS cluster via the licensing pipeline (https://adrms.contoso.local/_wmcs/licensing) stored in the protected document metadata and hits the ServiceLocator.asmx file and requests service location for certification.
  3. AD RMS Server in contoso.local checks for presence of GICURL registry entry in HKLMSoftwareMicrosoftDRMS. This registry entry is used when you opt not to use an AD RMS SCP. Presence of this entry will override SCP discovery for both local and cross-forest clients.
  4. When the entry is not found, the AD RMS Server in contoso.local identifies that user belongs to fabrikam.local since the user was forced to authenticate to access the ServiceLocator.asmx and then queries global catalog in fabrikam.local for AD RMS SCP and returns to the client (https://adrms.fabrikam.local/_wmcs/certification).
  5. Client receives back a referral to the fabrikam.local SCP (https://adrms.fabrikam.local/_wmcs/certification) and writes the information to a registry entry under the registry key:
    • HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocation – For office 2010
    • HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocation – For office 2013
  6. Client contacts contoso.local AD RMS cluster via the licensing pipeline (https://adrms.contoso.local/_wmcs/licensing) stored in the protected document metadata and hits the ServiceLocator.asmx file and requests service location for obtaining a CLC.
  7. AD RMS Server in contoso.local identifies that user belongs to fabrikam.local since the user was forced to authenticate to access the ServiceLocator.asmx returns the client’s AD RMS SCP for the clients’s domain to the client (https://adrms.fabrikam.local/_wmcs/certification).
  8. Client receives back a referral to the fabrikam.local SCP (https://adrms.fabrikam.local/_wmcs/certification) and writes the information to a registry entry under the registry key:
    • HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocation – For office 2010
    • HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocation – For office 2013
  9. Client then contacts the SCP URL returned in the previous step, hits the ServiceLocator.asmx, and requests a service location for obtaining a CLC.
  10. AD RMS Server in fabrikam.local returns the licensing pipeline (https://adrms.fabrikam.local/_wmcs/licensing) information to the client.
  11. Client receives back the licensing URL and writes it to a registry entry in the registry key:
      Office 2010

    • HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocation
    • HKCUSoftwareMicrosoftOffice14.0CommonDRMCachedCorpLicenseServer
    • Office 2013

    • HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocation
    • HKCUSoftwareMicrosoftOffice15.0CommonDRMCachedCorpLicenseServer
  12. Client connects to fabrikam.local licensing pipeline and is directed to ServiceLocator.asmx and requests a service location URL for activation (obtain copy of SLC public key and perform machine activation).
  13. Fabrikam.local AD RMS Server returns activation pipeline (http(s)://adrms.fabrikam.local/_wmcs/certification).
  14. Client writes this information to a series of registry entries in the following key:
    • HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocation – For office 2010
    • HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocation – For office 2013
  15. Client contacts fabrikam.local activation URL and hits Server.asmx to obtain a copy of the SLC’s public key.
  16. Client receives a copy of the SLC public key and performs machine activation generating a machine key in C:UsersUsernameAppDataLocalMicrosoftDRM.
  17. Client contacts fabrikam.local certification URL https://adrms.fabrikam.local/_wmcs/certification) and hits certification.asmx to obtain a RAC.
  18. AD RMS Server checks it’s database to see if it has a copy of the user’s RAC, if not it generates one using the following process.
    1. AD RMS Server queries a DC in its local domain for the user’s email address using the user’s SID as an identifier. The following query is used:
      • Filter = ( & ( | (objectSid=User’sSID) (sIDHistory=User’sSID) ) ( | (objectCategory=CN=Computer,CN=Schema,CN=Configuration,DC=domain,DC=com) (objectCategory=CN=Person,CN=Schema,CN=Configuration,DC=domain,DC=com) ) )
        Attributes = mail,objectSid,sIDHistory,proxyAddresses,memberOf,primaryGroupID,distinguishedName,uSNChanged,msExchOriginatingForest,msExchDynamicDLBaseDN, msExchDynamicDLFilter,userPrincipalName,sAMAccountName
    2. AD RMS Server queries a DC in its local domain for the user’s primary group. I’m unsure as to why it does this. The debug logs say something about establishing immediate group membership. The following query is used:
      • Filter = ( & (objectCategory=CN=Group,CN=Schema,CN=Configuration,DC=domain,DC=com)(objectSid=PrimaryGroup’sSID) )
        Attributes = distinguishedName
    3. AD RMS Server generates a RAC with the ID field populated with the user’s email address and sends back to user.
  19. Client receives RAC from fabrikam.local AD RMS server and saves it to C:UsersUserNameAppDataLocalMicrosoftDRM for Office 2010 and C:UsersUserNameAppDataLocalMicrosoftMISPC for Office 2013.
  20. Client contacts fabrikam.local CLC Service URL (https://adrms.fabrikam.local/_wmcs/licensing) and hits publish.asmx and requests a CLC.
  21. Fabrikam.local AD RMS Server creates a CLC and sends it to the user.
  22. Client receives CLC from fabrikam.local AD RMS serverand saves it to C:UsersUserNameAppDataLocalMicrosoftDRM for Office 2010 and C:UsersUserNameAppDataLocalMicrosoftMISPC for Office 2013.
  23. Client contacts contoso.local AD RMS server and request EUL.
  24. AD RMS Server in contoso.local contacts global catalog in contoso.local and performs the following queries:
    1. Check to see if the user exists in contoso.local and has an email address of UserA@contoso.local. This check is essentially checking to see whether a user exists in the author’s forest that matches the consumer’s SID and the author’s email address. This check probably exists to see whether or not the consumer should be issued full rights (author rights) to the doc.
      • Filter: (& (| (objectSID=SIDOfAuthenticatedUser)(sIDHistory=SIDOfAuthenticatedUser)(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    2. Check to see if a user object exists in contoso.local with the UserC@fabrikam.local as an email address. This check is looking for a user object with both the UserC@fabrikam.local email address and the author’s email address (UserA@fabrikam.local). Again, probably exists for the same reason as the previous query.
      • Filter: (& (| (mail=UserC@fabrikam.local)(proxyAddresses=smtp:UserC@fabrikam.local))(|(objectcategory=computer)(objectcategory=person)))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    3. Check to see if the a distribution group or contact with msExchOriginatingForest attribute populated exists with the email address of UserC@fabrikam.local exists. This check is looking to see if the AD RMS server needs to examine group membership of a group local to the contoso.local domain or perform group expansion a group in another domain.
      • Filter: (& (| (mail=UserC@fabrikam.local)(proxyAddresses=smtp:UserC@fabrikam.local))(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
    4. Run the same check as the previous step. Not sure why, debug log has the same message that it’s not a valid group.
      • Filter: (& (| (mail=UserC@fabrikam.local)(proxyAddresses=smtp:UserC@fabrikam.local))(|(objectCategory=group)(objectCategory=msExchDynamicDistributionList)(&(objectCategory=contact)(msExchOriginatingForest Present))))
        Attributes: ( mail )( objectSid )( sIDHistory )( proxyAddresses )( memberOf )( primaryGroupId )( distinguishedName )( uSNChanged )( msExchOriginatingForest )( msExchDynamicDLBaseDN )( msExchDynamicDLFilter )( userPrincipalName )( sAMAccountName )
  25. AD RMS Server in contoso.local consumes RAC and issues EUL.
  26. Client receives EUL and saves it to C:UsersUserNameAppDataLocalMicrosoftDRM for Office 2010 and C:UsersUserNameAppDataLocalMicrosoftMISPC for Office 2013.

Unlocking the black box that is AD RMS Part 2

Let’s begin shall we. I’ve included a copy of the captures I used to gather the information below.

Scenario: Client IntraForest Activation and Creation of Protected Content
Author: UserA@contoso.local
Consumer: UserB@contoso.local
Captures: Scenario 1 Captures

  1. Client searches registry to see if service connection point (SCP) has been hardcoded. It checks the following keys:
    1. HKLMSoftwareMicrosoftMSDRMServiceLocationActivation – This is a hardcoded location for client activation.
    2. HKLMSoftwareMicrosoftMSDRMServiceLocationEnterprise – This is the hardcoded location to obtain a CLC.
    3. HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocation – This is where previously discovered service locations are stored for Office 2010.
    4. HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocation – This is where previously discovered service locations are stored for Office 2013.
  2. Client then queries contoso.local global catalog for an AD RMS SCP with the following query:
    • Filter: (& (objectClass=serviceConnectionPoint)(keywords=MSRMRootCluster)(keywords=1.0))
      Attributes: ( serviceBindingInformation )
  3. Domain controller in client’s domain returns the AD RMS SCP information. This value is normally http(s)://RMSClusterDNSName/_wmcs/certification.
  4. Client connects to SCP which exists in AD RMS server and is directed to ServiceLocator.asmx and requests a service location URL for obtaining a CLC.
  5. AD RMS returns the Contoso.local AD RMS cluster’s licensing pipeline which is normally set to http(s)://RMSClusterDNSName/_wmcs/licensing
  6. Client writes this information to the following registry entries/keys:
      Office 2010

    • HKCUSoftwareMicrosoftOffice14.0CommonDRMCachedCorpLicenseServer
    • HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocations
    • Office 2013

    • HKCUSoftwareMicrosoftOffice15.0CommonDRMCachedCorpLicenseServer
    • HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocations
  7. Client connects to SCP which exists in AD RMS server and is directed to ServiceLocator.asmx and requests a service location URL for activation (obtaining a copy SLC public key).
  8. AD RMS Server returns activation pipeline which is normally set to http(s)://RMSClusterDNSName/_wmcs/certification.
  9. Client writes this information to a series of registry entries in the following key:
    • HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocations – Office 2010
    • HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocations – Office 2013
  10. Client connects to SCP which exists in AD RMS server and is directed to ServiceLocator.asmx and requests a service location URL for performing certification (obtaining a RAC)
  11. AD RMS Server returns certification pipeline which is normally set to http(s)://RMSClusterDNSName/_wmcs/certification.
  12. Client writes this information to a series of registry entries in the following key:
    • HKCUSoftwareMicrosoftOffice14.0CommonDRMServiceLocations – Office 2010
    • HKCUSoftwareMicrosoftOffice15.0CommonDRMServiceLocations – Office 2013
  13. Client contacts Activation URL (which is normally http(s)://RMSClusterDNSName/_wmcs/certification) and hits Server.asmx to obtain a copy of the SLC’s public key.
  14. AD RMS Server returns a copy of the SLC’s public key to the client.
  15. Client receives a copy of the SLC public key and performs machine activation generating a machine key in C:UsersUserNameAppDataLocalMicrosoftDRM for Office 2010 and C:UsersUserNameAppDataLocalMicrosoftMISPC for Office 2013.
  16. Client contacts Certification URL (which is normally http(s)://RMSClusterDNSName/_wmcs/certification) and hits Certification.asmx to obtain a RAC.
  17. AD RMS Server checks it’s database to see if it has a copy of the user’s RAC, if not it generates one using the following process.
    1. AD RMS Server queries a DC in its local domain for the user’s email address using the user’s SID as an identifier. The following query is used:
      • Filter = ( & ( | (objectSid=User’sSID) (sIDHistory=User’sSID) ) ( | (objectCategory=CN=Computer,CN=Schema,CN=Configuration,DC=domain,DC=com) (objectCategory=CN=Person,CN=Schema,CN=Configuration,DC=domain,DC=com) ) )
        Attributes = mail,objectSid,sIDHistory,proxyAddresses,memberOf,primaryGroupID,distinguishedName,uSNChanged,msExchOriginatingForest,msExchDynamicDLBaseDN, msExchDynamicDLFilter,userPrincipalName,sAMAccountName
    2. AD RMS Server queries a DC in its local domain for the user’s primary group. I’m unsure as to why it does this. The debug logs say something about establishing immediate group membership. The following query is used:
      • Filter = ( & (objectCategory=CN=Group,CN=Schema,CN=Configuration,DC=domain,DC=com)(objectSid=PrimaryGroup’sSID) )
        Attributes = distinguishedName
    3. AD RMS Server generates a RAC with the ID field populated with the user’s email address and sends back to user.
  18. Client receives RAC and saves it to C:UsersUserNameAppDataLocalMicrosoftDRM for Office 2010 and C:UsersUserNameAppDataLocalMicrosoftMISPC for Office 2013.
  19. Client contacts CLC Service URL (which is normally http(s)://RMSClusterDNSName/_wmcs/licensing and hits publish.asmx and requests a CLC.
  20. AD RMS Server creates a CLC and sends it to the user.
  21. Client receives CLC and saves it to C:UsersUserNameAppDataLocalMicrosoftDRM for Office 2010 and C:UsersUserNameAppDataLocalMicrosoftMISPC for Office 2013.

Client Activation and Creation of protected content is complete.