Share via


Clearing up MSMQ certificates from Active Directory

Some people have found a problem where Active Directory contains too many MSMQ certificates for a particular user account, usually if that's the one they use for installing all their MSMQ machines.

As you know, MSMQ uses certificates for authentication and encryption of messages.

MSMQ generates a certificate for each machine on the first login by the user. The private part of this certificate is stored locally in the secure cert store. The public part of the certificate is stored in Active Directory as an attribute of the user object. Since we need a certificate per machine, this attribute will have as many certificates as the number of machines on which the user previously logged in. The digest is a hash of an individual certificate, and lets MSMQ quickly identify the user for a given certificate.

MSMQ stores all the certificates in a single binary stream (BLOB), and it may appear as a single entity but in fact it contains many individual certificates.
The digests are stored as multi-valued attributes, and you will see multiple entries if there are multiple digests. Typically, there are as many certificates as there are digests.

On the sender, if a message is authenticated, MSMQ signs the message with the private part of the certificate and provides the identity of the sender in the message along with the certificate. On the receiving side, MSMQ looks at the incoming message, picks out the certificate, generates the digest, and looks up the user object that contains this digest. It then matches the user’s identity in the message with the one found in AD, and verifies the signature of the message before finally deciding that the message is indeed authentic or not.

There are two attributes, mSMQDigests and mSMGSignCertificates.

MSMQ-Digests
An array of digests of the corresponding certificates in attribute mSMQ-Sign-Certificates. They are used for mapping a digest into a certificate.

MSMQ-Sign-Certificates
This attribute contains a number of certificates. A user can generate a certificate per computer. For each certificate we also keep a digest.

It is possible for a domain account to be used to log on to so many different machines (about 820 seems to be the magic number) that the blob gets too big and exceeds the JET limitation for non-linked multi valued attributes. Once you hit the limit you'll start seeing errors - 0x80072024 / ERROR_DS_ADMIN_LIMIT_EXCEEDED.

If you are in this situation then there is no programmable solution exposed through MSMQ.

There are, though, some workarounds with varying levels of "recommended".

Note - if you delete these certificates and digests, MSMQ will no longer find these digests/certificates/users in the AD and can no longer verify the authenticity of messages sent from these accounts. Queues that are marked as requiring authentication will not be able to accept incoming messages.

The slow and laborious but supported workarounds:

1)  in AD Users and Computers, find the User Object
    - right-click, bring up Properties
    - select the "Message Queuing User Certificates" tab
    - highlight the first certificate row
    - press Remove
    - repeat for all certificates.
 
An administrator can use this method to clear out certificates for many users, during the one login session.

2) when logged on as the affected user
 
    - Open Computer Management, Services and Applications, Message Queuing
    - Click Properties
    - In the Message Queuing Properties dialog box, click the User Certificate tab
    - under User certificates, click Remove.
    - In the Personal Certificates dialog box, click the applicable user certificate, and then click Remove. 
 
I recommend that, as far as possible, you use one of these methods to maintain MSMQ User Certificates.

The "quick and dirty, use at your own risk" workaround:

3) use Windows' LDFIDE command line tool. LDIFDE reads in an input file and makes changes to AD according to the instructions in the file. You need to create an LDIF input file using the correct LDIF syntax, to delete the msMQDigests and msMQDigests attributes for the affected users. LDIF files follow the standard syntax described in RFC 2849. The syntax as used for Microsoft Active Directory is exactly the same as used for any LDAP directory, such as Sun One Directory, OpenLDAP and Novell eDirectory (ie, it isn't some weird Microsoft-proprietary thing)
 
For example, to clear out all MSMQ Certificates for user "TestUser" in the "BigDomain.Org" domain, create a plain text file:
 
1) DelCerts.ldf
 
dn: CN=TestUser,CN=Users,DC=BigDomain,DC=org
changetype: modify
delete: mSMQSignCertificates
-

dn: CN=TestUser,CN=Users,DC=BigDomain,DC=org
changetype: modify
delete: mSMQDigests
-
 
Note especially the line with the hyphen "-"; this is required and must be followed by one blank line before the end of the file.
 
This file is then used as input to LDIFDE, like this:
 
C:\>ldifde -i -f DelCerts.ldf
Connecting to "PrimaryDC.BigDomain.org"
Logging in as current user using SSPI
Importing directory from file "input.ldf"
Loading entries..
2 entry modified successfully.
The command has completed successfully
C:\>
 
You could potentially create one file for ALL user accounts you want to clean up but it's probably safer to begin with doing one account at a time. As a batch-style command-line tool, it could potentially make many changes before you have the chance to pause it.
 
For your environment, you will need to change the Distinguished Name (DN) to the correct value for your users.

In AD, if an Object's attribute has no value, then there is no instance of that attribute assigned to the Object. So, a user who has never logged in to a MSMQ machine has no mSMQSignCertificates or mSMQDigests at all. The next time they log in to an MSMQ machine, then an instance of the attribute will be created on the user Object, and populated with the right value.

CAUTION: This procedure has not been formally tested and is not supported by Microsoft. You should make a full backup of all your AD data before you try this procedure and be ready to recover if necessary.

[[Thanks to Uday Hegde, Yoel Arnon]]

Comments

  • Anonymous
    November 28, 2008
    Hi, How do you create a message queue active directory user certificate via an automated process? I would like to generate this without having to logon to the machine with the user account. thanks

  • Anonymous
    November 28, 2008
    Hi John, See the MQRegisterCertificate function and the MSMQApplication.RegisterCertificate method on MSDN. This function and this method have parameters that allow the automatic creation and registration of internal user certificates. Cheers John Breakwell

  • Anonymous
    July 09, 2009
    Hi John, We apply the above mentioned solution in one of the Test Env. and it worked for us. Now This problem is coming more frequently to our all other environments. I consider reinstalling MSMQ package on WS 2k3, and for some time everything run fine. When more user tried to connnect to server it Server application start failing with below message:- An error occurred while receiving a message from the queue: The Message Queuing service is not available (-1072824309, 0xc00e000b). Ensure that MSMQ is installed and running. Make sure the queue is available to receive from. What could be the reason to this problem? After reinstallation i found Msg in event log "The Message Queuing service is online with Active Directory and fully operational."

  • Anonymous
    July 09, 2009
    Hi Sutikshan, The 0xc00e000b error may be load-related. Have you checked how busy the machine is at these times? You don't mention how many users are connecting to the server? Is it tens, hundreds, thousands? Cheers John Breakwell (MSFT)

  • Anonymous
    July 10, 2009
    The comment has been removed

  • Anonymous
    July 11, 2009
    The comment has been removed

  • Anonymous
    September 08, 2009
    The comment has been removed

  • Anonymous
    December 07, 2009
    Can you complete the clean up using VB Script?  I am thinking something like this: Const ADS_PROPERTY_DELETE = 4 Dim objGroup Dim Digest Set objGroup = GetObject("LDAP://CN=TestUser,CN=Users,DC=BigDomain,DC=org") For Each Digest in objGroup.mSMQDigests WScript.Echo "Deleting MSMG Digest: " & Digest objGroup.PutEx ADS_PROPERTY_DELETE, "mSMQDigests", array(Digest)    objGroup.SetInfo Next objGroup.PutEx ADS_PROPERTY_DELETE, "mSMQSignCertificates", objGroup.mSMQSignCertificates objGroup.SetInfo I am afraid to test this though in case of failure.

  • Anonymous
    December 07, 2009
    Hi Eric, If you don't have a test environment then just download one. If you go to the Windows Server 2008 R2 Trial Software page ( http://www.microsoft.com/windowsserver2008/en/us/trial-software.aspx) you can download an 180-day trial version. Cheers John Breakwell (MSFT)