home *** CD-ROM | disk | FTP | other *** search
- // attributes.cpp : Defines the entry point for the console application.
- //
- #include <objbase.h>
- #include <wchar.h>
- #include <activeds.h>
- //Make sure you define UNICODE
- //Need to define version 5 for Windows 2000
- #define _WIN32_WINNT 0x0500
-
-
- ///////////////////////////////////////////////////////////
- // PLEASE READ: You must run on Windows 2000 machine to run this sample
- ////////////////////////////////////////////////////////////
- #include <sddl.h>
-
- HRESULT FindAttributesOrClasses(IDirectorySearch *pSchemaNC, //IDirectorySearch pointer to schema naming context.
- LPOLESTR szFilter, //Filter for finding specific attributes.
- //NULL returns all attributeSchema objects.
- LPOLESTR *pszPropertiesToReturn, //Properties to return for attributeSchema objects found
- //NULL returns all set properties.
- BOOL bIsAttributeQuery, //TRUE queries for attributes;FALSE for classes
- BOOL bIsVerbose //TRUE means all properties for the found objects are displayed.
- //FALSE means only the ldapDisplayName with cn in parentheses:
- //example: l (Locality-Name)
- );
-
-
-
-
- void wmain( int argc, wchar_t *argv[ ])
- {
-
- //Handle the command line arguments.
- LPOLESTR pszBuffer = new OLECHAR[MAX_PATH*2];
- wcscpy(pszBuffer, L"");
-
- BOOL bIsAttributeQuery = TRUE;
- BOOL bReturnVerbose = FALSE;
- LPOLESTR szType = L"attribute";
- if (1==argc||(_wcsicmp(argv[1],L"/?") == 0))
- {
- wprintf(L"This program queries the schema for the specified classes or attributes.\n");
- wprintf(L"Syntax: getschemainfo [/C|/A][/V][querystring]\n");
- wprintf(L"where /C specifies to query for classes.\n");
- wprintf(L" /A specifies to query for attributes.\n");
- wprintf(L" /V specifies that all properties for the found classes or attributes should be returned.\n");
- wprintf(L" querystring is the query criteria in ldap query format.\n");
- wprintf(L"Defaults: If neither /A or /C is specified, the query is against both.\n");
- wprintf(L" If no /V is specified, the query returns only the ldapDisplayName and cn of the items found.\n");
- wprintf(L" If no querystring is specified, the query returns all classes and/or attributes.\n");
- wprintf(L"Example: getschemainfo /A (IsSingleValued=TRUE)\n");
- wprintf(L"Returns all single-valued attributes in the schema.\n");
- wprintf(L"Common querystrings:\n");
- wprintf(L"For attributes:\n");
- wprintf(L"(cn=Street-Address) to find the attribute with CN of Street-Address.\n");
- wprintf(L"(ldapdisplayname=street) to find the attribute with ldapdisplayname of street.\n");
- wprintf(L"(IsSingleValued=TRUE) for single-valued attributes.\n");
- wprintf(L"(IsSingleValued=FALSE) for mulit-valued attributes.\n");
- wprintf(L"(systemFlags:1.2.840.113556.1.4.804:=00000001) for non-replicated attributes\n");
- wprintf(L"(systemFlags:1.2.840.113556.1.4.804:=00000004) for constructed attributes\n");
- wprintf(L"(searchFlags=1) for indexed attributes.\n");
- wprintf(L"(isMemberOfPartialAttributeSet=TRUE) for attributes included in the global catalog\n");
- return;
- }
- for (int i = 1;i<argc;i++)
- {
- if (_wcsicmp(argv[i],L"/C") == 0)
- {
- bIsAttributeQuery = FALSE;
- szType = L"class";
- }
- else if (_wcsicmp(argv[i],L"/A") == 0)
- {
- bIsAttributeQuery = TRUE;
- szType = L"attribute";
- }
- else if (_wcsicmp(argv[i],L"/V") == 0)
- {
- bReturnVerbose = TRUE;
- }
- else
- {
- wcscpy(pszBuffer,argv[i]);
- }
- }
- if (_wcsicmp(pszBuffer,L"") == 0)
- wprintf(L"\nFinding all %sSchema objects in the schema...\n\n",szType);
- else
- wprintf(L"\nFinding %sSchema objects based on query: %s...\n\n",szType, pszBuffer);
-
- //Intialize COM
- CoInitialize(NULL);
- HRESULT hr = S_OK;
- //Get rootDSE and the domain container's DN.
- IADs *pObject = NULL;
- IDirectorySearch *pSchemaNC = NULL;
- LPOLESTR szPath = new OLECHAR[MAX_PATH];
- VARIANT var;
- hr = ADsOpenObject(L"LDAP://rootDSE",
- NULL,
- NULL,
- ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
- IID_IADs,
- (void**)&pObject);
- if (FAILED(hr))
- {
- wprintf(L"Could not execute query. Could not bind to LDAP://rootDSE.\n");
- if (pObject)
- pObject->Release();
- return;
- }
- if (SUCCEEDED(hr))
- {
- hr = pObject->Get(L"schemaNamingContext",&var);
- if (SUCCEEDED(hr))
- {
- wcscpy(szPath,L"LDAP://");
- wcscat(szPath,var.bstrVal);
- hr = ADsOpenObject(szPath,
- NULL,
- NULL,
- ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
- IID_IDirectorySearch,
- (void**)&pSchemaNC);
-
- if (SUCCEEDED(hr))
- {
- hr = FindAttributesOrClasses(pSchemaNC, //IDirectorySearch pointer to schema naming context.
- pszBuffer,
- NULL,
- bIsAttributeQuery,
- bReturnVerbose
- );
- if (SUCCEEDED(hr))
- {
- if (S_FALSE==hr)
- wprintf(L"No %sSchema object could be found based on the query: %s\n",szType,pszBuffer);
- }
- else if (0x8007203e==hr)
- wprintf(L"Could not execute query. An invalid filter was specified.\n");
- else
- wprintf(L"Query failed to run. HRESULT: %x\n",hr);
- }
- else
- {
- wprintf(L"Could not execute query. Could not bind to the schema container.\n");
- }
- if (pSchemaNC)
- pSchemaNC->Release();
- }
- VariantClear(&var);
- }
- if (pObject)
- pObject->Release();
-
-
-
-
-
- // Uninitialize COM
- CoUninitialize();
- return;
- }
-
-
-
-
-
- HRESULT FindAttributesOrClasses(IDirectorySearch *pSchemaNC, //IDirectorySearch pointer to schema naming context.
- LPOLESTR szFilter, //Filter for finding specific attributes.
- //NULL returns all attributeSchema objects.
- LPOLESTR *pszPropertiesToReturn, //Properties to return for attributeSchema objects found
- //NULL returns all set properties unless bIsVerbose is FALSE.
- BOOL bIsAttributeQuery, //TRUE queries for attributes;FALSE for classes
- BOOL bIsVerbose //TRUE means all properties for the found objects are displayed.
- //FALSE means only the ldapDisplayName with cn in parentheses:
- //example: l (Locality-Name)
- )
- {
- if (!pSchemaNC)
- return E_POINTER;
- //Create search filter
- LPOLESTR pszSearchFilter = new OLECHAR[MAX_PATH*2];
- LPOLESTR szCategory = NULL;
- if (bIsAttributeQuery)
- szCategory = L"attributeSchema";
- else
- szCategory = L"classSchema";
-
-
- if (szFilter)
- wsprintf(pszSearchFilter, L"(&(objectCategory=%s)%s)",szCategory,szFilter);
- else
- wsprintf(pszSearchFilter, L"(objectCategory=%s)",szCategory);
-
- //Attributes are one-level deep in the Schema container so only need to search one level.
- ADS_SEARCHPREF_INFO SearchPrefs;
- SearchPrefs.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
- SearchPrefs.vValue.dwType = ADSTYPE_INTEGER;
- SearchPrefs.vValue.Integer = ADS_SCOPE_ONELEVEL;
- DWORD dwNumPrefs = 1;
-
- // COL for iterations
- LPOLESTR pszColumn = NULL;
- ADS_SEARCH_COLUMN col;
- HRESULT hr;
-
- // Interface Pointers
- IADs *pObj = NULL;
- IADs * pIADs = NULL;
-
- // Handle used for searching
- ADS_SEARCH_HANDLE hSearch = NULL;
-
- // Set the search preference
- hr = pSchemaNC->SetSearchPreference( &SearchPrefs, dwNumPrefs);
- if (FAILED(hr))
- return hr;
-
- LPOLESTR pszBool = NULL;
- DWORD dwBool;
- PSID pObjectSID = NULL;
- LPOLESTR szSID = NULL;
- LPOLESTR szDSGUID = new WCHAR [39];
- LPGUID pObjectGUID = NULL;
- FILETIME filetime;
- SYSTEMTIME systemtime;
- DATE date;
- VARIANT varDate;
- LARGE_INTEGER liValue;
- LPOLESTR *pszPropertyList = NULL;
- LPOLESTR pszNonVerboseList[] = {L"lDAPDisplayName",L"cn"};
-
- LPOLESTR szCNValue = new OLECHAR[MAX_PATH];
- LPOLESTR szLDAPDispleyNameValue = new OLECHAR[MAX_PATH];
-
- int iCount = 0;
- DWORD x = 0L;
-
-
-
- if (!bIsVerbose)
- {
- //Return non-verbose list properties only
- hr = pSchemaNC->ExecuteSearch(pszSearchFilter,
- pszNonVerboseList,
- sizeof(pszNonVerboseList)/sizeof(LPOLESTR),
- &hSearch
- );
- }
- else
- {
- if (!pszPropertiesToReturn)
- {
- //Return all properties.
- hr = pSchemaNC->ExecuteSearch(pszSearchFilter,
- NULL,
- 0L,
- &hSearch
- );
- }
- else
- {
- //specified subset.
- pszPropertyList = pszPropertiesToReturn;
- //Return specified properties
- hr = pSchemaNC->ExecuteSearch(pszSearchFilter,
- pszPropertyList,
- sizeof(pszPropertyList)/sizeof(LPOLESTR),
- &hSearch
- );
- }
- }
- if ( SUCCEEDED(hr) )
- {
- // Call IDirectorySearch::GetNextRow() to retrieve the next row
- //of data
- hr = pSchemaNC->GetFirstRow( hSearch);
- if (SUCCEEDED(hr))
- {
- while( hr != S_ADS_NOMORE_ROWS )
- {
- //Keep track of count.
- iCount++;
- if (bIsVerbose)
- wprintf(L"----------------------------------\n");
- // loop through the array of passed column names,
- // print the data for each column
-
- while( pSchemaNC->GetNextColumnName( hSearch, &pszColumn ) != S_ADS_NOMORE_COLUMNS )
- {
- hr = pSchemaNC->GetColumn( hSearch, pszColumn, &col );
- if ( SUCCEEDED(hr) )
- {
- // Print the data for the column and free the column
- if(bIsVerbose)
- {
- // Get the data for this column
- wprintf(L"%s\n",col.pszAttrName);
- switch (col.dwADsType)
- {
- case ADSTYPE_DN_STRING:
- for (x = 0; x< col.dwNumValues; x++)
- {
- wprintf(L" %s\r\n",col.pADsValues[x].DNString);
- }
- break;
- case ADSTYPE_CASE_EXACT_STRING:
- case ADSTYPE_CASE_IGNORE_STRING:
- case ADSTYPE_PRINTABLE_STRING:
- case ADSTYPE_NUMERIC_STRING:
- case ADSTYPE_TYPEDNAME:
- case ADSTYPE_FAXNUMBER:
- case ADSTYPE_PATH:
- case ADSTYPE_OBJECT_CLASS:
- for (x = 0; x< col.dwNumValues; x++)
- {
- wprintf(L" %s\r\n",col.pADsValues[x].CaseIgnoreString);
- }
- break;
- case ADSTYPE_BOOLEAN:
- for (x = 0; x< col.dwNumValues; x++)
- {
- dwBool = col.pADsValues[x].Boolean;
- pszBool = dwBool ? L"TRUE" : L"FALSE";
- wprintf(L" %s\r\n",pszBool);
- }
- break;
- case ADSTYPE_INTEGER:
- for (x = 0; x< col.dwNumValues; x++)
- {
- wprintf(L" %d\r\n",col.pADsValues[x].Integer);
- }
- break;
- case ADSTYPE_OCTET_STRING:
- if ( _wcsicmp(col.pszAttrName,L"objectSID") == 0 )
- {
- for (x = 0; x< col.dwNumValues; x++)
- {
- pObjectSID = (PSID)(col.pADsValues[x].OctetString.lpValue);
- //Convert SID to string.
- ConvertSidToStringSid(pObjectSID, &szSID);
- wprintf(L" %s\r\n",szSID);
- LocalFree(szSID);
- }
- }
- else if ( (_wcsicmp(col.pszAttrName,L"objectGUID") == 0)
- || (_wcsicmp(col.pszAttrName,L"schemaIDGUID") == 0)
- || (_wcsicmp(col.pszAttrName,L"attributeSecurityGUID") == 0) )
- {
- for (x = 0; x< col.dwNumValues; x++)
- {
- //Cast to LPGUID
- pObjectGUID = (LPGUID)(col.pADsValues[x].OctetString.lpValue);
- //Convert GUID to string.
- ::StringFromGUID2(*pObjectGUID, szDSGUID, 39);
- //Print the GUID
- wprintf(L" %s\r\n",szDSGUID);
- }
- }
- else if ( _wcsicmp(col.pszAttrName,L"oMObjectClass") == 0 )
- {
- //TODO:
- wprintf(L" TODO:No conversion for this.");
- }
- else
- wprintf(L" Value of type Octet String. No Conversion.");
- break;
- case ADSTYPE_UTC_TIME:
- for (x = 0; x< col.dwNumValues; x++)
- {
- systemtime = col.pADsValues[x].UTCTime;
- if (SystemTimeToVariantTime(&systemtime,
- &date) != 0)
- {
- //Pack in variant.vt
- varDate.vt = VT_DATE;
- varDate.date = date;
- VariantChangeType(&varDate,&varDate,VARIANT_NOVALUEPROP,VT_BSTR);
- wprintf(L" %s\r\n",varDate.bstrVal);
- VariantClear(&varDate);
- }
- else
- wprintf(L" Could not convert UTC-Time.\n",pszColumn);
- }
- break;
- case ADSTYPE_LARGE_INTEGER:
- for (x = 0; x< col.dwNumValues; x++)
- {
- liValue = col.pADsValues[x].LargeInteger;
- filetime.dwLowDateTime = liValue.LowPart;
- filetime.dwHighDateTime = liValue.HighPart;
- if((filetime.dwHighDateTime==0) && (filetime.dwLowDateTime==0))
- {
- wprintf(L" No value set.\n");
- }
- else
- {
- //Check for properties of type LargeInteger that represent time
- //if TRUE, then convert to variant time.
- if ((0==wcscmp(L"accountExpires", col.pszAttrName))|
- (0==wcscmp(L"badPasswordTime", col.pszAttrName))||
- (0==wcscmp(L"lastLogon", col.pszAttrName))||
- (0==wcscmp(L"lastLogoff", col.pszAttrName))||
- (0==wcscmp(L"lockoutTime", col.pszAttrName))||
- (0==wcscmp(L"pwdLastSet", col.pszAttrName))
- )
- {
- //Handle special case for Never Expires where low part is -1
- if (filetime.dwLowDateTime==-1)
- {
- wprintf(L" Never Expires.\n");
- }
- else
- {
- if (FileTimeToLocalFileTime(&filetime, &filetime) != 0)
- {
- if (FileTimeToSystemTime(&filetime,
- &systemtime) != 0)
- {
- if (SystemTimeToVariantTime(&systemtime,
- &date) != 0)
- {
- //Pack in variant.vt
- varDate.vt = VT_DATE;
- varDate.date = date;
- VariantChangeType(&varDate,&varDate,VARIANT_NOVALUEPROP,VT_BSTR);
- wprintf(L" %s\r\n",varDate.bstrVal);
- VariantClear(&varDate);
- }
- else
- {
- wprintf(L" FileTimeToVariantTime failed\n");
- }
- }
- else
- {
- wprintf(L" FileTimeToSystemTime failed\n");
- }
-
- }
- else
- {
- wprintf(L" FileTimeToLocalFileTime failed\n");
- }
- }
- }
- else
- {
- //Print the LargeInteger.
- wprintf(L" high: %d low: %d\r\n",filetime.dwHighDateTime, filetime.dwLowDateTime);
- }
- }
- }
- break;
- case ADSTYPE_NT_SECURITY_DESCRIPTOR:
- for (x = 0; x< col.dwNumValues; x++)
- {
- wprintf(L" Security descriptor.\n");
- }
- break;
- default:
- wprintf(L"Unknown type %d.\n",col.dwADsType);
- }
- }
- else
- {
- //Verbose handles only the two single-valued attributes: cn and ldapdisplayname
- //so this is a special case.
- if (0==wcscmp(L"cn", pszColumn))
- {
- wcscpy(szCNValue,col.pADsValues->CaseIgnoreString);
- }
- if (0==wcscmp(L"lDAPDisplayName", pszColumn))
- {
- wcscpy(szLDAPDispleyNameValue,col.pADsValues->CaseIgnoreString);
- }
- }
- pSchemaNC->FreeColumn( &col );
- }
- FreeADsMem( pszColumn );
- }
- if (!bIsVerbose)
- wprintf(L"%s (%s)\n",szLDAPDispleyNameValue,szCNValue);
- //Get the next row
- hr = pSchemaNC->GetNextRow( hSearch);
- }
-
- }
- // Close the search handle to clean up
- pSchemaNC->CloseSearchHandle(hSearch);
- }
- if (SUCCEEDED(hr) && 0==iCount)
- hr = S_FALSE;
-
- return hr;
- }
-
-