HOWTO: Search for a RightsGUID or a SchemaIDGuid (301920)
The information in this article applies to:
- Microsoft Windows 2000 Server
- Microsoft Windows 2000 Advanced Server
- Microsoft Active Directory Services Interface, System Component
- Microsoft Active Directory Client Extension
- Microsoft Visual C++, 32-bit Editions 6.0
This article was previously published under Q301920 SUMMARY
This article illustrates how to use an Active Directory Services Interfaces (ADSI) Lightweight Directory Access Protocol (LDAP) query to locate either an extended right or a schema object using its RightsGUID or SchemaIDGuid.
MORE INFORMATION
The code that is provided in this article searches the Extended Rights container for the matching RightsGUID. If this search is not successful, the code performs a second LDAP search on the Schema container, searching for a SchemaIDGuid.
The sample demonstrates how to:
- Properly encode binary data into an LDAP query by using the ADsEncodeBinaryData API.
- Use the IDirectorySearch interface.
- Use Active Template Library (ATL) Smart Pointers to manager reference counting of interface pointers.
Steps to Use the Code Contained in this Article- Create an empty Windows 32 console application in Visual Studio.
- Click the FileView tab.
- From the File menu, click New, and select C++ Source File.
- In the File Name edit control, type main.cpp and click OK.
- Copy the code from the "Main.cpp Code" section of this article and paste it into the Visual C++ project.
- From the Project menu, click Settings. Click the Link tab.
- Add adsiid.lib and activeds.lib to the Object/Library Modules.
- Click the Debug tab.
- In the Program Arguments edit control type {59ba2f42-79a2-11d0-9020-00c04fc2d3cf}, and then click OK.
- Press CTRL+F5 to build and execute the project.
Visual C++ Code
The following Visual C++ Code illustrates how to find an extended right or a schema object when given a GUID.
Main.cpp Code
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <stdio.h>
#include <atlbase.h>
#include <objbase.h>
#include <activeds.h>
#include <winnt.h>
//
// main.cpp : Defines the entry point for the console application.
//
/////////////////////////////////////////////////////////////////////////////////
// Helper Functions
// ShowError -> Displays and Error Message
// PrintGUIDFromVariant -> Displays a guid in StringFromGUID2 format using a variant
//
// ****************************************************************
// PrintGUIDFromVariant
// Prints out a GUID in string format.
// ****************************************************************
VOID
PrintGUIDFromVariant(VARIANT varGUID)
{
HRESULT hr;
void HUGEP *pArray;
WCHAR szGUID[40];
LPGUID pGUID;
DWORD dwLen = sizeof(GUID);
hr = SafeArrayAccessData( V_ARRAY(&varGUID), &pArray );
pGUID = (LPGUID)pArray;
// Convert GUID to string.
::StringFromGUID2(*pGUID, szGUID, 40);
// Print the GUID
wprintf(L",%s",szGUID);
SafeArrayUnaccessData( V_ARRAY(&varGUID) );
VariantClear(&varGUID);
}
//******************************************************************
// Simple Error display function.
// ShowError
//******************************************************************
void ShowError( char *szRoutine, HRESULT hr )
{
LPTSTR pMessage;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
hr,
0,
(char *) &pMessage,
100,
NULL );
MessageBox( NULL, pMessage, szRoutine, NULL );
LocalFree( pMessage );
}
//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// Main process for this sample.
//
// Locate either the Extended Right or class/attribute in the schema that matches
// the GUID passed in argv[1]
//
// Schema ID GUID of the user object
// {BF967ABA-0DE6-11D0-A285-00AA003049E2}
//
// Rights GUID of a the General-Information extended right
// {59ba2f42-79a2-11d0-9020-00c04fc2d3cf}
//
int main(int argc, char* argv[])
{
HRESULT hr = CoInitialize(NULL);
CComPtr <IADs> pIADsObj;
CComBSTR bObject = argv[1];
CComBSTR bQueryString;
BOOL bFindSchemaIDGUID = TRUE;
BOOL bFound = FALSE;
if ( argc < 2 )
{
printf("Must enter a GUID in the form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}.\nTerminating program...\n");
return 0;
}
//
// Verify that the string starts with a '{'
//
char *arg = argv[1];
char szRightsGUID[40];
if( (argv[1][0] != '{') || (strlen( argv[1] ) > 40) )
{
printf("Must enter a GUID in the form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}.\nTerminating program...\n");
return 0;
}
else
{
//
// We need a copy of the GUID without the "{}"s, strip them
// The form of GUID string used in the RightsGUID property of an extended right.
//
char *pSpot = szRightsGUID;
char *p;
for( p = (char *)argv[1];*p;p++ )
{
if( (*p != '{') && (*p != '}') )
{
*pSpot = *p;
pSpot++;
}
}
*pSpot = NULL;
}
//
// Convert the GUID into its binary form
//
CLSID inputGUID;
CLSIDFromString( bObject.m_str, &inputGUID );
//
// Binary encode the GUID to use in an LDAP search of the Schema container
//
LPOLESTR pEncodedGUID;
ADsEncodeBinaryData( (PBYTE)&inputGUID, sizeof(CLSID), &pEncodedGUID);
//
// Prepare to search the Extended Rights container via
// the ConfigurationNamingContext value of the RootDSE object
//
CComPtr <IADs> pRootDSE;
CComPtr <IADs> pIADsExtendedRights;
CComBSTR bLDAPQueryStr;
hr = ADsGetObject(L"LDAP://RootDSE", IID_IADs, (void **) &pRootDSE);
CComBSTR bExtendedRightsLDAPpath;
VARIANT vVarTmp;
VariantInit(&vVarTmp);
hr = pRootDSE->Get(L"configurationNamingContext", &vVarTmp);
bExtendedRightsLDAPpath = L"LDAP://CN=Extended-Rights,";
bExtendedRightsLDAPpath.AppendBSTR( vVarTmp.bstrVal);
//
// Retrieve an IADs object interface for the Extended Rights Container
// and QI for an IDirectorySearch interface
//
hr=ADsGetObject( bExtendedRightsLDAPpath.m_str, IID_IADs, (void **)&pIADsExtendedRights);
CComQIPtr <IDirectorySearch, &IID_IDirectorySearch> pISearchExtendedRights(pIADsExtendedRights);
pIADsExtendedRights.Release();
//
// Buid the query string...
//
bLDAPQueryStr = TEXT("(RightsGUID=");
bLDAPQueryStr.Append( szRightsGUID );
bLDAPQueryStr.Append( ")");
//
// Setup the Attributes and search preferences
//
// Perform a subtree search
//
ADS_SEARCHPREF_INFO prefInfo[2];
prefInfo[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
prefInfo[0].vValue.dwType = ADSTYPE_INTEGER;
prefInfo[0].vValue.Integer = ADS_SCOPE_SUBTREE;
//
// Set the maximum records returned to 1000 ( maximum for AD )
//
prefInfo [1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE ;
prefInfo [1].vValue.dwType = ADSTYPE_INTEGER;
prefInfo [1].vValue.Integer = 1000;
//
// Set the preferences...
//
hr = pISearchExtendedRights->SetSearchPreference( prefInfo, 2);
//
// Prepare a list of atrributes to return in the query...
// in our case, we want the Common Name and the SchemaIDGuid
//
LPWSTR pszAttr[] = { L"cn"};
ADS_SEARCH_HANDLE hSearch;
DWORD dwCount= sizeof(pszAttr)/sizeof(LPWSTR);
//
// Open schema container, and request and IDirectorySearch interface from it
// Uset the LDAP://RootDSE to obtain the LDAP path to the Schema container
//
hr=pISearchExtendedRights->ExecuteSearch(bLDAPQueryStr.m_str, pszAttr, dwCount, &hSearch );
if (!SUCCEEDED(hr))
{
pISearchExtendedRights.Release();
ShowError("Error executing LDAP search:\n", hr);
}
//
// Now enumerate the result
//
ADS_SEARCH_COLUMN col;
// "0---------1---------2---------3----5"
while( pISearchExtendedRights->GetNextRow(hSearch) != S_ADS_NOMORE_ROWS )
{
// Get attributes
//
// CN
//
hr = pISearchExtendedRights->GetColumn( hSearch, pszAttr[0], &col );
if ( SUCCEEDED(hr) )
{
printf("Found Extended Right: %S\nThat matched RightsGUID: %s\n",(LPWSTR)col.pADsValues->CaseIgnoreString, argv[1]);
pISearchExtendedRights->FreeColumn( &col );
bFindSchemaIDGUID = FALSE;
bFound=TRUE;
}
}
pISearchExtendedRights->CloseSearchHandle( hSearch );
pISearchExtendedRights.Release();
//
// Check to see if the GUID passed to the console application was a
// RightsGUID that matched an Extended Right.
//
// If the RightsGUID search failed, then try to search for a
// SchemaIDGUID in the schema...
//
if( bFindSchemaIDGUID )
{
//
// Setup the query into the Schema to find the matching SchemaIDGuid
//
bLDAPQueryStr = L"";
bLDAPQueryStr = L"(schemaIDGuid=";
bLDAPQueryStr.Append( pEncodedGUID );
bLDAPQueryStr.Append( L")");
//
// Declare an IADs object and build the path to the
// the schema container.
//
CComPtr <IADs> pIADsSchema;
CComBSTR bSchemaLDAPpath;
VARIANT vVar;
VariantInit( &vVar );
hr = pRootDSE->Get(L"schemaNamingContext", &vVar );
bSchemaLDAPpath = L"LDAP://";
bSchemaLDAPpath.AppendBSTR( vVar.bstrVal );
hr = ADsGetObject(bSchemaLDAPpath.m_str, IID_IADs, (void **)&pIADsSchema);
pRootDSE.Release();
CComQIPtr <IDirectorySearch, &IID_IDirectorySearch> pISearch(pIADsSchema);
pIADsSchema.Release(); // Release the IADs interface for the schema container...
//
// Setup the IDirecrtory Search preferences and prepare to retrieve the data
//
//
// Perform a subtree search
//
ADS_SEARCHPREF_INFO prefInfo2[2];
prefInfo2[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
prefInfo2[0].vValue.dwType = ADSTYPE_INTEGER;
prefInfo2[0].vValue.Integer = ADS_SCOPE_SUBTREE;
//
// Set the maximum records returned to 1000 ( maximum for AD )
//
prefInfo2[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE ;
prefInfo2[1].vValue.dwType = ADSTYPE_INTEGER;
prefInfo2[1].vValue.Integer = 1000;
//
// Bind the preferences to the search object...
//
hr = pISearch->SetSearchPreference( prefInfo2, 2);
//
// Prepare a list of atrributes to return in the query...
// in our case, we want the Common Name
//
LPWSTR pszAttr2[] = { L"cn"};
ADS_SEARCH_HANDLE hSearch2;
DWORD dwCount2= sizeof(pszAttr2)/sizeof(LPWSTR);
//
// Execute the search query
//
hr=pISearch->ExecuteSearch(bLDAPQueryStr.m_str, pszAttr2, dwCount2, &hSearch2 );
if (!SUCCEEDED(hr))
{
pISearch.Release();
ShowError("Error executing LDAP search:\n", hr);
goto cleanup;
}
//
// Now enumerate the result
//
ADS_SEARCH_COLUMN col2;
// "0---------1---------2---------3----5"
while( pISearch->GetNextRow(hSearch2) != S_ADS_NOMORE_ROWS )
{
// Get attributes
//
// CN
//
hr = pISearch->GetColumn( hSearch2, pszAttr[0], &col2 );
if ( SUCCEEDED(hr) )
{
printf("Found Property: %S \nMatched Schema ID GUID: %s\n",(LPWSTR)col2.pADsValues->CaseIgnoreString, argv[1]);
pISearch->FreeColumn( &col2 );
bFound=TRUE;
}
}
////////////
// Clean-up
////////////
pISearch->CloseSearchHandle(hSearch2);
pISearch.Release();
}
else
{
pRootDSE.Release();
}
if( !bFound ) printf("Could not find a matching RightsGUID or SchmaIdGUID for %s\n", argv[1]);
cleanup:
//
// Clean UP the rest....
//
pIADsObj.Release();
CoUninitialize( );
return 0;
}
REFERENCESFor additional information, click the article number below
to view the article in the Microsoft Knowledge Base:
302515 HOWTO: Find All Extended Rights that Apply to a Schema Class Object Using Visual C++
302514 HOWTO: Find Extended Rights that Apply to a Schema Class Object Using Visual Basic Script
For more information on the rightsGUID, see:
For more information on schemaIDGUID, see:
For more information on AdsEncodeBinaryData, see:
Modification Type: | Minor | Last Reviewed: | 7/13/2004 |
---|
Keywords: | kbDSWADSI2003Swept kbhowto KB301920 kbAudDeveloper |
---|
|