HRESULT GetGC(IDirectorySearch **ppDS) { HRESULT hr; IEnumVARIANT *pEnum = NULL; IADsContainer *pCont = NULL; VARIANT var; IDispatch *pDisp = NULL; ULONG lFetch; // Set IDirectorySearch pointer to NULL. *ppDS = NULL; // First, bind to the GC: namespace container object. hr = ADsOpenObject(TEXT("GC:"), NULL, NULL, ADS_SECURE_AUTHENTICATION, // Use Secure Authentication. IID_IADsContainer, (void**)&pCont); if (FAILED(hr)) { _tprintf(TEXT("ADsOpenObject failed: 0x%x\n"), hr); goto cleanup; } // Get an enumeration interface for the GC container to enumerate the // contents. The actual GC is the only child of the GC container. hr = ADsBuildEnumerator(pCont, &pEnum); if (FAILED(hr)) { _tprintf(TEXT("ADsBuildEnumerator failed: 0x%x\n"), hr); goto cleanup; } // Now enumerate. There is only one child of the GC: object. hr = pEnum->Next(1, &var, &lFetch); if (FAILED(hr)) { _tprintf(TEXT("ADsEnumerateNext failed: 0x%x\n"), hr); goto cleanup; } // Get the IDirectorySearch pointer. if ((hr == S_OK) && (lFetch == 1)) { pDisp = V_DISPATCH(&var); hr = pDisp->QueryInterface(IID_IDirectorySearch, (void**)ppDS); } cleanup: if (pEnum) ADsFreeEnumerator(pEnum); if (pCont) pCont->Release(); if (pDisp) (pDisp)->Release(); return hr; }
HRESULT CreateUserIADsContainer(void) { HRESULT hr; IADsContainer *pCont = NULL; IDispatch *pDisp=NULL; IADsUser *pIADsUser=NULL; /////////////////////////////////////////////////// // Create a user using IADsContainer::Create //////////////////////////////////////////////////// hr = ADsGetObject( L"WinNT://seyitb-dev", IID_IADsContainer, (void**) &pCont ); if (FAILED(hr) ) return hr; hr = pCont->Create(L"user", L"AliceW", &pDisp ); pCont->Release(); if(FAILED(hr) ) return hr; hr = pDisp->QueryInterface( IID_IADsUser, (void**) &pIADsUser ); if (FAILED(hr)) return hr; //do NOT hard code your password into the source code in production code //take user input instead pIADsUser->SetPassword(L"MysEcret1"); hr = pIADsUser->SetInfo(); // Commit if(SUCCEEDED(hr)) wprintf(L"User created successfully\n"); pIADsUser->Release(); return hr; }
static HRESULT GetGCSearch(IDirectorySearch **ppDS) { HRESULT hr; IEnumVARIANT *pEnum = NULL; IADsContainer *pCont = NULL; IDispatch *pDisp = NULL; VARIANT var; ULONG lFetch; *ppDS = NULL; /* Bind to the GC: namespace container object. The true GC DN is a single immediate child of the GC: namespace, which must be obtained using enumeration. */ hr = ADsOpenObject(L"GC:", NULL, NULL, ADS_SECURE_AUTHENTICATION, /* Use Secure Authentication. */ IID_IADsContainer, (void**)&pCont); if (FAILED(hr)) { smpd_err_printf("ADsOpenObject failed: 0x%x\n", hr); goto cleanup; } /* Get an enumeration interface for the GC container. */ hr = ADsBuildEnumerator(pCont, &pEnum); if (FAILED(hr)) { smpd_err_printf("ADsBuildEnumerator failed: 0x%x\n", hr); goto cleanup; } /* Now enumerate. There is only one child of the GC: object. */ hr = ADsEnumerateNext(pEnum, 1, &var, &lFetch); if (FAILED(hr)) { smpd_err_printf("ADsEnumerateNext failed: 0x%x\n", hr); goto cleanup; } if ((hr == S_OK) && (lFetch == 1)) { pDisp = V_DISPATCH(&var); hr = pDisp->QueryInterface(IID_IDirectorySearch, (void**)ppDS); } cleanup: if (pEnum) { ADsFreeEnumerator(pEnum); pEnum = NULL; } if (pCont) { pCont->Release(); pCont = NULL; } if (pDisp) { pDisp->Release(); pDisp = NULL; } return hr; }
HRESULT EnumAllObject(LPWSTR pszADsPath, int indent) { ULONG cElementFetched = 0L; IEnumVARIANT * pEnumVariant = NULL; VARIANT VariantArray[MAX_ENUM]; HRESULT hr = S_OK; IADsContainer * pADsContainer = NULL; DWORD dwObjects = 0, dwEnumCount = 0, i = 0; BOOL fContinue = TRUE; hr = ADsGetObject( pszADsPath, IID_IADsContainer, (void **)&pADsContainer ); if (FAILED(hr)) { printf("\"%S\" is not a valid container object.\n", pszADsPath); goto exitpoint; } hr = ADsBuildEnumerator( pADsContainer, &pEnumVariant ); if (FAILED(hr)) { printf("ADsBuildEnumerator failed with %lx\n", hr); goto exitpoint; } fContinue = TRUE; while (fContinue) { IADs *pObject; hr = ADsEnumerateNext( pEnumVariant, MAX_ENUM, VariantArray, &cElementFetched ); if (FAILED(hr)) { printf("ADsEnumerateNext failed with %lx\n", hr); goto exitpoint; } if (hr == S_FALSE) { fContinue = FALSE; } dwEnumCount++; for (i = 0; i < cElementFetched; i++) { IDispatch *pDispatch = NULL; BSTR bstrADsPath = NULL; pDispatch = VariantArray[i].pdispVal; hr = V_DISPATCH(VariantArray + i)->QueryInterface(IID_IADs, (void **)&pObject); if (SUCCEEDED(hr)) { pObject->get_ADsPath(&bstrADsPath); printf("%S\n", bstrADsPath); EnumAllObject(bstrADsPath, indent + 2); } pObject->Release(); VariantClear(VariantArray + i); SysFreeString(bstrADsPath); } dwObjects += cElementFetched; } printf("Total Number of Objects enumerated is %d\n", dwObjects); exitpoint: if (pEnumVariant) { ADsFreeEnumerator(pEnumVariant); } if (pADsContainer) { pADsContainer->Release(); } return(hr); }
//---------------------------------------------------------------------------- // // EnumDeletedObjects() // // Enumerates all of the objects in the Deleted Objects container. // //---------------------------------------------------------------------------- HRESULT EnumDeletedObjects( PWCHAR SearchFilter, BOOLEAN Restore, PDWORD ItemsFound ) { HRESULT hr; IADsContainer *pDeletedObjectsCont = NULL; IDirectorySearch *pSearch = NULL; // Set the attributes to retrieve. LPWSTR rgAttributes[] = {L"cn", L"distinguishedName", L"lastKnownParent"}; *ItemsFound = 0; hr = GetDeletedObjectsContainer(&pDeletedObjectsCont); if(FAILED(hr)) { goto cleanup; } hr = pDeletedObjectsCont->QueryInterface(IID_IDirectorySearch, (LPVOID*)&pSearch); if(FAILED(hr)) { goto cleanup; } ADS_SEARCH_HANDLE hSearch; // Only search for direct children of the container. ADS_SEARCHPREF_INFO rgSearchPrefs[3]; rgSearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; rgSearchPrefs[0].vValue.dwType = ADSTYPE_INTEGER; rgSearchPrefs[0].vValue.Integer = ADS_SCOPE_ONELEVEL; // Search for deleted objects. rgSearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_TOMBSTONE; rgSearchPrefs[1].vValue.dwType = ADSTYPE_BOOLEAN; rgSearchPrefs[1].vValue.Boolean = TRUE; // Set the page size. rgSearchPrefs[2].dwSearchPref = ADS_SEARCHPREF_PAGESIZE; rgSearchPrefs[2].vValue.dwType = ADSTYPE_INTEGER; rgSearchPrefs[2].vValue.Integer = 1000; // Set the search preference hr = pSearch->SetSearchPreference(rgSearchPrefs, ARRAYSIZE(rgSearchPrefs)); if(FAILED(hr)) { goto cleanup; } // Execute the search hr = pSearch->ExecuteSearch( SearchFilter, rgAttributes, ARRAYSIZE(rgAttributes), &hSearch); if(SUCCEEDED(hr)) { // Call IDirectorySearch::GetNextRow() to retrieve the next row of data while(S_OK == (hr = pSearch->GetNextRow(hSearch))) { ADS_SEARCH_COLUMN col; UINT i; // Enumerate the retrieved attributes. for(i = 0; i < ARRAYSIZE(rgAttributes); i++) { hr = pSearch->GetColumn(hSearch, rgAttributes[i], &col); if(SUCCEEDED(hr)) { switch(col.dwADsType) { case ADSTYPE_CASE_IGNORE_STRING: case ADSTYPE_DN_STRING: case ADSTYPE_PRINTABLE_STRING: case ADSTYPE_NUMERIC_STRING: case ADSTYPE_OCTET_STRING: wprintf(L"%s: ", rgAttributes[i]); for(DWORD x = 0; x < col.dwNumValues; x++) { wprintf(col.pADsValues[x].CaseIgnoreString); if((x + 1) < col.dwNumValues) { wprintf(L","); } } wprintf(L"\n"); break; } pSearch->FreeColumn(&col); } } (*ItemsFound)++; wprintf(L"\n"); if( Restore ) { WCHAR answer[MAX_PATH]; wprintf(L"Do you want to restore this object (y/n)? "); fflush( stdout ); _getws( answer ); if( towupper( answer[0] ) == 'Y' ) { ADS_SEARCH_COLUMN colDn, colPn; pSearch->GetColumn(hSearch, rgAttributes[1], &colDn); pSearch->GetColumn(hSearch, rgAttributes[2], &colPn); hr = RestoreDeletedObject( colDn.pADsValues[0].CaseIgnoreString, colPn.pADsValues[0].CaseIgnoreString ); if( FAILED( hr )) { wprintf(L"\nRestore failed: %d\n", hr ); } else { wprintf(L"\nRestore succeeded.\n"); } pSearch->FreeColumn(&colDn); pSearch->FreeColumn(&colPn); } wprintf(L"\n"); } } // Close the search handle to clean up. pSearch->CloseSearchHandle(hSearch); } cleanup: if(pDeletedObjectsCont) { pDeletedObjectsCont->Release(); } if(pSearch) { pSearch->Release(); } return hr; }