I was working on some additional functionality for AdFind to decode the replication metadata in a little more readable format than the default XML format you get with msDS-ReplAttributeMetaData and ran into an issue with DS_REPL_ATTR_META_DATA_BLOB.
The structure is defined on MSDN – http://msdn2.microsoft.com/en-us/library/ms676250.aspx
It looks like
typedef struct {
DWORD oszAttributeName;
DWORD dwVersion;
FILETIME ftimeLastOriginatingChange;
UUID uuidLastOriginatingDsaInvocationID;
USN usnOriginatingChange;
USN usnLocalChange;
DWORD oszLastOriginatingDsaDN; } DS_REPL_ATTR_META_DATA_BLOB;
The code sample shows
DS_REPL_ATTR_META_DATA_BLOB *pdsReplAttrMetaDataBlob;
// Retrieve the replication data into pdsReplAttrMetaDataBlob.
LPWSTR pwszAttributeName = (LPWSTR)((LPBYTE)pdsReplAttrMetaDataBlob + pdsReplAttrMetaDataBlob->oszAttributeName);
LPWSTR pwszLastOriginatingDsaDN = (LPWSTR)((LPBYTE)pdsReplAttrMetaDataBlob + pdsReplAttrMetaDataBlob->oszLastOriginatingDsaDN);
The issue I encountered is that if the DSA GUID can’t be resolved to a DN (i.e. deleted) then oszLastOriginatingDsaDN returns 0 instead of an offset into the string block at the end of the blob. That means the sample code provided will return a garbage value because it will be pointing to the beginning of the blob which absolutely is not the correct place to be pointing to and the resulting string will simply be a decode of the binary at the beginning of the blob to whatever Unicode string it works out to be.
The fix is simple, you need to validate that the offset has a value before setting the string to the blob+offset. If the offset is 0, then determine what you want to output in lieu of the correct DN because you don’t have a choice – you don’t have the correct DN.
I haven’t checked the other attributes yet that are also decoded through the repl BLOB structures but I would not be entirely surprised if the same issue crops up in the others.
I have fired a note off to a couple of my friends at MSFT who can get something done on this. I figure it could go one of two ways. The documentation could be corrected and/or the blob returned from the server could be corrected to actually send an offset as documented that simply points to a null string.
Personally, this latter solution is probably the correct long term action though the docs need to be updated for current implementations… If anyone used the code from the MSDN site unmodified they have a ticking time bomb. This is a realistic possibility because it seems that a lot of code slingers writing AD code don’t test against fully beat up directories, they spin up a simple domain/forest that hasn’t gone through any real churn and if their code works there it must work anywhere… right? If a DC hasn’t been removed from the domain and a change to the given test object(s) wasn’t/weren’t originated on that DC then they would not have run into this issue. The fallout of this could vary wildly from nothing to odd output to application crash. You cannot guess unless you understand how the value is used in the program.
joe