Figure 3 Common Distinguished Name Monikers
Identifier |
Description |
Common Name (cn) |
This is the descriptor that is most often used for objects under organizational objects. Most objects will use this identifier for their object name. For example, cn=bgates is an object with the common name (cn) of bgates. |
Organization (o) |
Most objects with this identifier are objects of the Organization class. For example, o=microsoft is an organization called Microsoft within the hierarchy. |
Organizational Unit (ou) |
Most objects with this identifier are objects of the Organizational Unit class. For example, ou=operatingsystems is an organizational unit (usually under an organization) called Operating Systems. |
Locality (l) |
This represents a city or area. Most objects with this identifier are objects of the Locality class. For example, l=boston is a locality called Boston. |
Country (c) |
This is the top-level organizational element and signifies that this is an object of the type country class. For example, c=us describes the object that represents the U.S. in the hierarchy. |
Figure 11 The IADs Interface
Property |
Description |
Name |
The object's relative name |
Class |
The name of the object's schema class |
GUID |
The GUID of the object as stored in the underlying directory store |
ADsPath |
The object's ADsPath that uniquely identifies this object from all others |
Parent |
The ADsPath string for the parent of the object |
Schema |
The ADsPath string to the schema class object for this object |
Method |
Description |
GetInfo |
Loads the property values of this object from the underlying directory store |
SetInfo |
Persists the changes on this object to the underlying directory store |
Get |
Gets the value for a property by name |
Put |
Sets the value for a property by name |
GetEx |
Gets the value for a single or multivalued property by name |
PutEx |
Sets the value for a single or multivalued property by name |
GetInfoEx |
Loads specific property values of this object from the underlying directory store |
Figure 12 Publication Schema
PublicationItem Class |
|
Attribute |
Value |
Common name |
MSJ-DR-PublicationItem |
LDAP display name |
mSJ-DRPublicationItem |
OID |
{YourRootClassOID}.1 |
Class category |
auxiliary |
Object category |
MSJ-DR-PublicationItem |
Parent class |
top |
Auxiliary classes |
none |
Possible superiors |
none |
Mandatory attributes |
none |
Optional attributes |
MSJ-DRPublicationDate description, notes |
Publisher Class |
|
Attribute |
Value |
Common name |
MSJ-DR-Publisher |
LDAP display name |
mSJ-DRPublisher |
OID |
{YourRootClassOID}.2 |
Class category |
structural |
Object category |
MSJ-DR-Publisher |
Parent class |
organizationalUnit |
Auxiliary classes |
none |
Possible superiors |
container |
Mandatory attributes |
ou objectClass |
Optional attributes |
streetaddress city st postalCode telephoneNumber description notes |
Publication Class |
|
Attribute |
Value |
Common name |
MSJ-DR-Publication |
LDAP display name |
mSJ-DRPublication |
OID |
{YourRootClassOID}.3 |
Class category |
structural |
Object category |
MSJ-DR-Publication |
Parent class |
container |
Auxiliary classes |
MSJ-DR-PublicationItem |
Possible superiors |
MSJ-DR-Publisher |
Mandatory attributes |
cn objectClass |
Optional attributes |
MSJ-DRPublishedInterval MSJ-DRIsPeriodical |
Volume Class |
|
Attribute |
Value |
Common name |
MSJ-DR-Volume |
LDAP display name |
mSJ-DRVolume |
OID |
{YourRootClassOID}.4 |
Class category |
structural |
Object category |
MSJ-DR-Volume |
Parent class |
container |
Auxiliary classes |
MSJ-DR-PublicationItem |
Possible superiors |
MSJ-DR-Publication |
Mandatory attributes |
cn objectClass |
Optional attributes |
none |
Issue Class |
|
Attribute |
Value |
Common name |
MSJ-DR-Issue |
LDAP display name |
mSJ-DRIssue |
OID |
{YourRootClassOID}.5 |
Class category |
structural |
Object category |
MSJ-DR-Issue |
Parent class |
container |
Auxiliary classes |
MSJ-DR-PublicationItem |
Possible superiors |
MSJ-DR-Publication MSJ-DR-Volume |
Mandatory attributes |
cn objectClass |
Optional attributes |
none |
Article Class |
|
Attribute |
Value |
Common name |
MSJ-DR-Article |
LDAP display name |
mSJ-DRArticle |
OID |
{YourRootClassOID}.6 |
Class category |
structural |
Object category |
MSJ-DR-Article |
Parent class |
container |
Auxiliary classes |
MSJ-DR-PublicationItem |
Possible superiors |
MSJ-DR-Publication MSJ-DR-Volume MSJ-DR-Issue |
Mandatory attributes |
cn objectClass |
Optional attributes |
url MSJ-DRAbstractURL MSJ-DRStartPageNumber MSJ-DREndPageNumber MSJ-DRAuthors |
PublicationDate Attribute |
|
Attribute |
Value |
Common name |
MSJ-DR-PublicationDate |
LDAP display name |
mSJ-DRPublicationDate |
OID |
{YourRootAttributeOID}.1 |
Syntax |
UTCTime |
Minimum |
|
Maximum |
|
Is multivalued? |
FALSE |
Is indexed? |
TRUE |
PublishedInterval Attribute |
|
Attribute |
Value |
Common name |
MSJ-DR-PublishedInterval |
LDAP display name |
mSJ-DRPublishedInterval |
OID |
{YourRootAttributeOID}.2 |
Syntax |
Integer |
Minimum |
|
Maximum |
|
Is multivalued? |
FALSE |
Is indexed? |
FALSE |
IsPeriodical Attribute |
|
Attribute |
Value |
Common name |
MSJ-DR-IsPeriodical |
LDAP display name |
mSJ-DRIsPeriodical |
OID |
{YourRootAttributeOID}.3 |
Syntax |
Boolean |
Minimum |
|
Maximum |
|
Is multivalued? |
FALSE |
Is indexed? |
FALSE |
AbstractURL Attribute |
|
Attribute |
Value |
Common name |
MSJ-DR-AbstractURL |
LDAP display name |
mSJ-DRAbstractURL |
OID |
{YourRootAttributeOID}.4 |
Syntax |
Unicode String |
Minimum |
|
Maximum |
|
Is multivalued? |
FALSE |
Is indexed? |
FALSE |
StartPageNumber Attribute |
|
Attribute |
Value |
Common name |
MSJ-DR-StartPageNumber |
LDAP display name |
mSJ-DRStartPageNumber |
OID |
{YourRootAttributeOID}.5 |
Syntax |
Integer |
Minimum |
|
Maximum |
|
Is multivalued? |
FALSE |
Is indexed? |
FALSE |
EndPageNumber Attribute |
|
Attribute |
Value |
Common name |
MSJ-DR-EndPageNumber |
LDAP display name |
mSJ-DREndPageNumber |
OID |
{YourRootAttributeOID}.6 |
Syntax |
Integer |
Minimum |
|
Maximum |
|
Is multivalued? |
FALSE |
Is indexed? |
FALSE |
Authors Attribute |
|
Attribute |
Value |
Common name |
MSJ-DR-Authors |
LDAP display name |
mSJ-DRAuthors |
OID |
{YourRootAttributeOID}.7 |
Syntax |
Unicode String |
Minimum |
|
Maximum |
|
Is multivalued? |
TRUE |
Is indexed? |
FALSE |
Figure 14 Viewing Objects
/////////////////////////////////////////////////////////////////////////
// How to iterate through the objects created in the previous
// example of creating new objects
/////////////////////////////////////////////////////////////////////////
void CMSJADSIDlg::OnBtnShowobjects()
{
HRESULT hr;
IADsContainer* pContainer = NULL;
IADs* pAD = NULL;
IDispatch* pDisp = NULL;
// Validate Connection
if (!m_pContainer)
{
AddToLog("Container not open, Please Open Container First");
return;
}
// Get the Root Container
hr = m_pContainer->GetObject( L"container",
L"CN=DocRepo",
&pDisp);
if (FAILED(hr))
{
AddToLog("Failed to Get the Container Object, please restart!");
return;
}
hr = pDisp->QueryInterface( IID_IADsContainer, (void**) &pContainer );
hr = pDisp->QueryInterface (IID_IADs, (void**) &pAD);
pDisp->Release();
// Show the Hierarchy Below the the Container (Recursive Function)
BSTR bstrName;
_variant_t varDesc;
pAD->get_Name(&bstrName);
pAD->Get(L"description", &varDesc);
if (varDesc.vt == VT_BSTR)
{
AddToLog(CString(bstrName) + " : " + varDesc.bstrVal );
}
else
{
AddToLog(CString(bstrName));
}
SysFreeString(bstrName);
pAD->Release();
ShowHierarchy(pContainer);
}
// Recursive Function to Dump all Objects to the Log
void CMSJADSIDlg::ShowHierarchy(IADsContainer *pContainer)
{
static short nIndent = 0;
IEnumVARIANT* pEnum;
LPUNKNOWN pUnk;
IDispatch* pDisp;
ULONG lFetch;
IADs* pAD;
IADsContainer* pNewContainer;
BSTR bstrName, bstrSchema;
_variant_t var, varDesc;
// Start Indenting
nIndent += 2;
// Create Indentation
CString csIndent;
for (int x = 0; x < nIndent; x++) csIndent += " ";
// Get the Enumeration Interface
pContainer->get__NewEnum(&pUnk);
pUnk->QueryInterface(IID_IEnumVARIANT, (void**) &pEnum);
pUnk->Release();
// Now Enumerate
HRESULT hr = pEnum->Next(1, &var, &lFetch);
while(hr == S_OK)
{
if (lFetch == 1)
{
pDisp = V_DISPATCH(&var);
pDisp->QueryInterface(IID_IADs, (void**)&pAD);
pAD->get_Name(&bstrName);
pAD->Get(L"description", &varDesc);
if (varDesc.vt == VT_BSTR)
{
AddToLog(csIndent + bstrName + " : " + varDesc.bstrVal );
}
else
{
AddToLog(CString(bstrName));
}
SysFreeString(bstrName);
// Recurse if Necessary
pAD->get_Schema(&bstrSchema);
IADsClass* pCls;
ADsGetObject(bstrSchema, IID_IADsClass, (void**)&pCls);
SysFreeString(bstrSchema);
VARIANT_BOOL isContainer;
pCls->get_Container(&isContainer);
if(isContainer)
{
pAD->QueryInterface( IID_IADsContainer,
(void**) &pNewContainer);
ShowHierarchy(pNewContainer);
pNewContainer->Release();
}
pCls->Release();
// Release the Object
pAD->Release();
}
hr = pEnum->Next(1, &var, &lFetch);
};
pEnum->Release();
// Reduce the index if possible
nIndent -= 2;
return;
}
Figure 15 Searching for Objects
/////////////////////////////////////////////////////////////////////////
// Example of how to search for objects in the Active Directory
/////////////////////////////////////////////////////////////////////////
void CMSJADSIDlg::OnBtnSearch()
{
UpdateData();
HRESULT hr;
IDirectorySearch* pSearch = NULL;
ADS_SEARCH_HANDLE hSearch;
long nFound = 0;
ADS_SEARCH_COLUMN col;
// Validate Connection
if (!m_pContainer)
{
AddToLog("Container not open, Please Open Container First");
return;
}
// Get IDirectorySearch Object
hr = m_pContainer->QueryInterface(IID_IDirectorySearch,
(void**) &pSearch);
if (FAILED(hr))
{
AddToLog("Failed to Get Search Interface!");
return;
}
// Set Search Defaults, to search the entire subtree
ADS_SEARCHPREF_INFO prefInfo[1];
prefInfo[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
prefInfo[0].vValue.dwType = ADSTYPE_INTEGER;
prefInfo[0].vValue.Integer = ADS_SCOPE_SUBTREE;
hr = pSearch->SetSearchPreference( prefInfo, 1);
// Execute Search
LPWSTR pszAttr[] = { L"Name", L"description" };
DWORD dwCount = sizeof(pszAttr)/sizeof(LPWSTR);
hr = pSearch->ExecuteSearch(
m_csSearchCriteria.AllocSysString(),
pszAttr,
dwCount,
&hSearch
);
// Display Contents
if (SUCCEEDED(hr))
{
while( SUCCEEDED(hr = pSearch->GetNextRow(hSearch)) &&
hr != S_ADS_NOMORE_ROWS )
{
CString csLogItem;
// Get Name
if ( SUCCEEDED(pSearch->GetColumn( hSearch,
pszAttr[0],
&col ) ) )
{
csLogItem = CString("Found: ") +
col.pADsValues->CaseIgnoreString;
pSearch->FreeColumn( &col );
}
// Get Description
if ( SUCCEEDED(pSearch->GetColumn( hSearch,
pszAttr[1],
&col ) ) )
{
csLogItem += CString(" : ") +
col.pADsValues->CaseIgnoreString;
pSearch->FreeColumn( &col );
}
AddToLog(csLogItem);
nFound++;
}
pSearch->CloseSearchHandle(hSearch);
}
CString csTemp;
csTemp.Format("Found %d Items...", nFound);
AddToLog(csTemp);
}