void CDlgIDirectoryObject::ShowAttributes() { ADS_OBJECT_INFO *pInfo; HRESULT hr; hr = m_pDirObject->GetObjectInformation(&pInfo); if (!SUCCEEDED(hr) ) { return; } ///////////////////////////////////////////// // Show the attributes in the UI ///////////////////////////////////////////// USES_CONVERSION; m_sRDN = OLE2T(pInfo->pszRDN); m_sDN = OLE2T(pInfo->pszObjectDN); m_sParent = OLE2T(pInfo->pszParentDN); m_sClass = OLE2T(pInfo->pszClassName); m_sSchema = OLE2T(pInfo->pszSchemaDN); /////////////////////////////////////////////////////////// // Do not forget to clean-up the memory using FreeADsMem! ////////////////////////////////////////////////////////// FreeADsMem( pInfo ); }
HRESULT CADsSearch::Execute( LPCTSTR pszFilter ) { USES_CONVERSION; HRESULT hr; if ( !m_pSearch ) { return E_UNEXPECTED; } m_hSearch = NULL; ////////////////////////////////////////////// // Set the search preference if any /////////////////////////////////////////////// if ( m_dwPrefCount ) { hr = m_pSearch->SetSearchPreference( m_srchInfo, m_dwPrefCount); if ( !SUCCEEDED(hr) ) { return hr; } } if ( m_sColumnList.IsEmpty() ) { hr = m_pSearch->ExecuteSearch( T2OLE(pszFilter), NULL, -1, &m_hSearch ); } else // Columns is specified { unsigned int count, xx; LPWSTR *pColumns = NULL; POSITION pos; CString s; count = m_sColumnList.GetCount(); pColumns = (LPWSTR*)AllocADsMem( sizeof(LPWSTR)*count); pos = m_sColumnList.GetHeadPosition(); for(xx=0; xx < count; xx++) { s = m_sColumnList.GetAt(pos); pColumns[xx] = T2OLE(s); m_sColumnList.GetNext(pos); } hr = m_pSearch->ExecuteSearch( T2OLE(pszFilter), pColumns, count, &m_hSearch ); if ( pColumns ) { FreeADsMem( pColumns ); } } return hr; }
static int smpd_build_spn_list() { HRESULT hr; IDirectoryObject *pSCP = NULL; ADS_ATTR_INFO *pPropEntries = NULL; IDirectorySearch *pSearch = NULL; ADS_SEARCH_HANDLE hSearch = NULL; LPWSTR pszDN; /* distinguished name of SCP. */ LPWSTR pszServiceDNSName; /* service DNS name. */ LPWSTR pszClass; /* name of service class. */ USHORT usPort; /* service port. */ WCHAR pszSearchString[SMPD_MAX_NAME_LENGTH]; char temp_str[SMPD_MAX_NAME_LENGTH]; char temp_str2[SMPD_MAX_NAME_LENGTH]; smpd_host_spn_node_t *iter; /* double t1, t2; */ static int initialized = 0; if (initialized) { return SMPD_SUCCESS; } initialized = 1; /* t1 = PMPI_Wtime(); */ CoInitialize(NULL); /* Get an IDirectorySearch pointer for the Global Catalog. */ hr = GetGCSearch(&pSearch); if (FAILED(hr) || pSearch == NULL) { smpd_err_printf("GetGC failed 0x%x\n", hr); goto Cleanup; } /* Set up a deep search. Thousands of objects are not expected in this example, therefore query for 1000 rows per page.*/ ADS_SEARCHPREF_INFO SearchPref[2]; DWORD dwPref = sizeof(SearchPref)/sizeof(ADS_SEARCHPREF_INFO); SearchPref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; SearchPref[0].vValue.dwType = ADSTYPE_INTEGER; SearchPref[0].vValue.Integer = ADS_SCOPE_SUBTREE; SearchPref[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE; SearchPref[1].vValue.dwType = ADSTYPE_INTEGER; SearchPref[1].vValue.Integer = 1000; hr = pSearch->SetSearchPreference(SearchPref, dwPref); if (FAILED(hr)) { smpd_err_printf("Failed to set search prefs: hr:0x%x\n", hr); goto Cleanup; } /* Execute the search. From the GC get the distinguished name of the SCP. Use the DN to bind to the SCP and get the other properties. */ LPWSTR rgszDN[] = {L"distinguishedName"}; /* Search for a match of the product GUID. */ swprintf(pszSearchString, L"keywords=%s", SMPD_SERVICE_VENDOR_GUIDW); hr = pSearch->ExecuteSearch(pszSearchString, rgszDN, 1, &hSearch); /*hr = pSearch->ExecuteSearch(L"keywords=5722fe5f-cf46-4594-af7c-0997ca2e9d72", rgszDN, 1, &hSearch);*/ if (FAILED(hr)) { smpd_err_printf("ExecuteSearch failed: hr:0x%x\n", hr); goto Cleanup; } /* Loop through the results. Each row should be an instance of the service identified by the product GUID. Add logic to select from multiple service instances. */ while (SUCCEEDED(hr = pSearch->GetNextRow(hSearch))) { if (hr == S_ADS_NOMORE_ROWS) { DWORD dwError = ERROR_SUCCESS; WCHAR szError[512]; WCHAR szProvider[512]; ADsGetLastError(&dwError, szError, 512, szProvider, 512); if (ERROR_MORE_DATA == dwError) { continue; } goto Cleanup; } ADS_SEARCH_COLUMN Col; hr = pSearch->GetColumn(hSearch, L"distinguishedName", &Col); pszDN = AllocADsStr(Col.pADsValues->CaseIgnoreString); pSearch->FreeColumn(&Col); /* Bind to the DN to get the other properties. */ LPWSTR lpszLDAPPrefix = L"LDAP://"; DWORD dwSCPPathLength = (DWORD)(wcslen(lpszLDAPPrefix) + wcslen(pszDN) + 1); LPWSTR pwszSCPPath = (LPWSTR)malloc(sizeof(WCHAR) * dwSCPPathLength); if (pwszSCPPath) { wcscpy(pwszSCPPath, lpszLDAPPrefix); wcscat(pwszSCPPath, pszDN); } else { smpd_err_printf("Failed to allocate a buffer\n"); goto Cleanup; } /*wprintf(L"pszDN = %s\n", pszDN);*/ /*FreeADsStr(pszDN);*/ hr = ADsGetObject(pwszSCPPath, IID_IDirectoryObject, (void**)&pSCP); free(pwszSCPPath); if (SUCCEEDED(hr)) { /* Properties to retrieve from the SCP object. */ LPWSTR rgszAttribs[]= { {L"serviceClassName"}, {L"serviceDNSName"}, /*{L"serviceDNSNameType"},*/ {L"serviceBindingInformation"} }; DWORD dwAttrs = sizeof(rgszAttribs)/sizeof(LPWSTR); DWORD dwNumAttrGot; hr = pSCP->GetObjectAttributes(rgszAttribs, dwAttrs, &pPropEntries, &dwNumAttrGot); if (FAILED(hr)) { smpd_err_printf("GetObjectAttributes Failed. hr:0x%x\n", hr); goto Cleanup; } pszServiceDNSName = NULL; pszClass = NULL; iter = (smpd_host_spn_node_t*)malloc(sizeof(smpd_host_spn_node_t)); if (iter == NULL) { smpd_err_printf("Unable to allocate memory to store an SPN entry.\n"); goto Cleanup; } iter->next = NULL; iter->host[0] = '\0'; iter->spn[0] = '\0'; iter->dnshost[0] = '\0'; /* Loop through the entries returned by GetObjectAttributes and save the values in the appropriate buffers. */ for (int i = 0; i < (LONG)dwAttrs; i++) { if ((wcscmp(L"serviceDNSName", pPropEntries[i].pszAttrName) == 0) && (pPropEntries[i].dwADsType == ADSTYPE_CASE_IGNORE_STRING)) { pszServiceDNSName = AllocADsStr(pPropEntries[i].pADsValues->CaseIgnoreString); /*wprintf(L"pszServiceDNSName = %s\n", pszServiceDNSName);*/ } /* if ((wcscmp(L"serviceDNSNameType", pPropEntries[i].pszAttrName) == 0) && (pPropEntries[i].dwADsType == ADSTYPE_CASE_IGNORE_STRING)) { pszServiceDNSNameType = AllocADsStr(pPropEntries[i].pADsValues->CaseIgnoreString); wprintf(L"pszServiceDNSNameType = %s\n", pszServiceDNSNameType); } */ if ((wcscmp(L"serviceClassName", pPropEntries[i].pszAttrName) == 0) && (pPropEntries[i].dwADsType == ADSTYPE_CASE_IGNORE_STRING)) { pszClass = AllocADsStr(pPropEntries[i].pADsValues->CaseIgnoreString); /*wprintf(L"pszClass = %s\n", pszClass);*/ } if ((wcscmp(L"serviceBindingInformation", pPropEntries[i].pszAttrName) == 0) && (pPropEntries[i].dwADsType == ADSTYPE_CASE_IGNORE_STRING)) { usPort=(USHORT)_wtoi(pPropEntries[i].pADsValues->CaseIgnoreString); /*wprintf(L"usPort = %d\n", usPort);*/ } } wcstombs(iter->dnshost, pszServiceDNSName, SMPD_MAX_NAME_LENGTH); wcstombs(temp_str, pszClass, SMPD_MAX_NAME_LENGTH); /*MPIU_Snprintf(iter->spn, SMPD_MAX_NAME_LENGTH, "%s/%s:%d", temp_str, iter->dnshost, usPort);*/ wcstombs(temp_str2, pszDN, SMPD_MAX_NAME_LENGTH); MPIU_Snprintf(iter->spn, SMPD_MAX_NAME_LENGTH, "%s/%s/%s", temp_str, iter->dnshost, temp_str2); MPIU_Strncpy(iter->host, iter->dnshost, SMPD_MAX_NAME_LENGTH); strtok(iter->host, "."); iter->next = spn_list; spn_list = iter; if (pszServiceDNSName != NULL) { FreeADsStr(pszServiceDNSName); } if (pszClass != NULL) { FreeADsStr(pszClass); } } FreeADsStr(pszDN); } Cleanup: /* iter = spn_list; while (iter != NULL) { printf("host : %s\n", iter->host); printf("dnshost: %s\n", iter->dnshost); printf("spn : %s\n", iter->spn); iter = iter->next; } fflush(stdout); */ if (pSCP) { pSCP->Release(); pSCP = NULL; } if (pPropEntries) { FreeADsMem(pPropEntries); pPropEntries = NULL; } if (pSearch) { if (hSearch) { pSearch->CloseSearchHandle(hSearch); hSearch = NULL; } pSearch->Release(); pSearch = NULL; } CoUninitialize(); /* t2 = PMPI_Wtime(); smpd_dbg_printf("build_spn_list took %0.6f seconds\n", t2-t1); */ return SMPD_SUCCESS; }
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 int allocFilter = MAX_PATH*2; LPOLESTR pszSearchFilter = new OLECHAR[allocFilter]; if ( !pszSearchFilter ) { delete [] pszSearchFilter; return E_OUTOFMEMORY; } LPOLESTR szCategory = NULL; if (bIsAttributeQuery) szCategory = L"attributeSchema"; else szCategory = L"classSchema"; wcscpy_s(pszSearchFilter, allocFilter, L"(&(objectCategory=attributeSchema)%s)"); BOOL bBufferOK=false; // Check for buffer overrun... if (szFilter) { if ( IS_BUFFER_ENOUGH(allocFilter,pszSearchFilter, szCategory) > 0 ) { swprintf_s(pszSearchFilter, allocFilter, L"(&(objectCategory=%s)%s)",szCategory,szFilter); bBufferOK=true; } } else { if ( IS_BUFFER_ENOUGH(allocFilter,pszSearchFilter, szCategory) > 0 ) { swprintf_s(pszSearchFilter, allocFilter,L"(objectCategory=%s)",szCategory); bBufferOK=true; } } if( !bBufferOK) { delete [] pszSearchFilter; wprintf(L"Filter is too large - aborting"); return E_FAIL; } //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; 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]; LPOLESTR szDSGUID = new WCHAR [39]; if ( !szCNValue || !szLDAPDispleyNameValue || !szDSGUID ) { if ( szDSGUID ) delete [] szDSGUID; if ( szCNValue ) delete [] szCNValue; if ( szLDAPDispleyNameValue ) delete [] szLDAPDispleyNameValue; if ( pszSearchFilter ) delete [] pszSearchFilter; return E_OUTOFMEMORY; } 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"); } 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_s(szCNValue,MAX_PATH,col.pADsValues->CaseIgnoreString); } if (0==wcscmp(L"lDAPDisplayName", pszColumn)) { wcscpy_s(szLDAPDispleyNameValue,MAX_PATH,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; delete [] szDSGUID; delete [] szCNValue; delete [] szLDAPDispleyNameValue; delete [] pszSearchFilter; return hr; }
HRESULT ExchangeAdmin::CreateExchangeMailBox(LPCWSTR lpwstrNewUser, LPCWSTR lpwstrNewUserPwd, LPCWSTR lpwstrlogonuser, LPCWSTR lpwstrLogonUsrPwd) { HRESULT hr = S_OK; // Get Logon user DN wstring LogonUserDN; wstring legacyName; wstring msExchHomeSvrName; Zimbra::MAPI::Util::GetUserDNAndLegacyName(m_strServer.c_str(), lpwstrlogonuser, lpwstrLogonUsrPwd, LogonUserDN, legacyName); Zimbra::MAPI::Util::GetmsExchHomeServerName(m_strServer.c_str(), lpwstrlogonuser, lpwstrLogonUsrPwd, msExchHomeSvrName); Zimbra::Util::ScopedInterface<IDirectoryObject> pLogonContainer; Zimbra::Util::ScopedInterface<IADsUser> pIAdUser; Zimbra::Util::ScopedInterface<IADs> pIAds; wstring strContainer = L"LDAP://"; strContainer += LogonUserDN.c_str(); dloge("strContainer %S msExchHomeSvrName: %S", strContainer.c_str(), msExchHomeSvrName.c_str()); // Get loggedin user container hr = ADsOpenObject(strContainer.c_str(), NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pLogonContainer.getptr()); if (FAILED(hr)) { if (hr == 0x8007052e) // credentials are not valid { hr = ADsOpenObject((LPTSTR)strContainer.c_str(), lpwstrlogonuser, lpwstrLogonUsrPwd, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pLogonContainer.getptr()); if (FAILED(hr)||(pLogonContainer.get()==NULL)) throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): ADsOpenObject Failed.", ERR_ADOBJECT_OPEN, __LINE__, __FILE__); } else { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject Failed.", ERR_ADOBJECT_OPEN, __LINE__, __FILE__); } } ADS_ATTR_INFO *pAttrInfo = NULL; DWORD dwReturn; LPWSTR pAttrNames[] = { L"mail", L"homeMDB", L"homeMTA" }; DWORD dwNumAttr = sizeof (pAttrNames) / sizeof (LPWSTR); wstring strLogonHomeMDB; wstring strLogonHomeMTA; wstring strLogonMail; // Get attribute values requested. Its not necessary the order is same as requested. if (FAILED(hr = pLogonContainer->GetObjectAttributes(pAttrNames, dwNumAttr, &pAttrInfo, &dwReturn))) throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): GetObjectAttributes Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); for (DWORD idx = 0; idx < dwReturn; idx++) { if (_wcsicmp(pAttrInfo[idx].pszAttrName, L"mail") == 0) strLogonMail = pAttrInfo[idx].pADsValues->Email.Address; else if (_wcsicmp(pAttrInfo[idx].pszAttrName, L"homeMTA") == 0) strLogonHomeMTA = pAttrInfo[idx].pADsValues->DNString; else if (_wcsicmp(pAttrInfo[idx].pszAttrName, L"homeMDB") == 0) strLogonHomeMDB = pAttrInfo[idx].pADsValues->DNString; } // Use FreeADsMem for all memory obtained from the ADSI call. FreeADsMem(pAttrInfo); wstring twtsrlogonuserDN = LogonUserDN; size_t nPos = twtsrlogonuserDN.find(_T("DC="), 0); wstring wstrServerDN = twtsrlogonuserDN.substr(nPos); wstring wstrADSPath = _T("LDAP://CN=Users,") + wstrServerDN; ADSVALUE cnValue; ADSVALUE classValue; ADSVALUE sAMValue; ADSVALUE uPNValue; ADSVALUE controlValue; ADS_ATTR_INFO attrInfo[] = { { L"objectClass", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &classValue, 1 }, { L"cn", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &cnValue, 1 }, { L"sAMAccountName", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &sAMValue, 1 }, { L"userPrincipalName", ADS_ATTR_UPDATE, ADSTYPE_CASE_IGNORE_STRING, &uPNValue, 1 }, {L"userAccountControl", ADS_ATTR_UPDATE, ADSTYPE_INTEGER,&controlValue, 1}, }; DWORD dwAttrs = sizeof (attrInfo) / sizeof (ADS_ATTR_INFO); classValue.dwType = ADSTYPE_CASE_IGNORE_STRING; classValue.CaseIgnoreString = L"user"; //int UF_ACCOUNTDISABLE = 0x0002; int UF_PASSWD_NOTREQD = 0x0020; //int UF_PASSWD_CANT_CHANGE = 0x0040; int UF_NORMAL_ACCOUNT = 0x0200; int UF_DONT_EXPIRE_PASSWD = 0x10000; //int UF_PASSWORD_EXPIRED = 0x800000; controlValue.dwType = ADSTYPE_INTEGER; controlValue.Integer=UF_NORMAL_ACCOUNT | UF_PASSWD_NOTREQD |UF_DONT_EXPIRE_PASSWD; cnValue.dwType = ADSTYPE_CASE_IGNORE_STRING; cnValue.CaseIgnoreString = (LPWSTR)lpwstrNewUser; sAMValue.dwType = ADSTYPE_CASE_IGNORE_STRING; sAMValue.CaseIgnoreString = (LPWSTR)lpwstrNewUser; wstring wstrMail; size_t nPosMail = strLogonMail.find(_T("@"), 0); wstrMail = strLogonMail.substr(nPosMail); wstrMail = lpwstrNewUser + wstrMail; LPWSTR upnval = (LPWSTR)wstrMail.c_str(); uPNValue.dwType = ADSTYPE_CASE_IGNORE_STRING; uPNValue.CaseIgnoreString = upnval; Zimbra::Util::ScopedInterface<IDirectoryObject> pDirContainer; Zimbra::Util::ScopedInterface<IDispatch> pDisp; Zimbra::Util::ScopedInterface<IADsUser> pIADNewUser; wstring wstrLoggedUserName(LogonUserDN); size_t snPos = 0; size_t enPos = 0; if ((snPos = wstrLoggedUserName.find(L"CN=")) != wstring::npos) { if ((enPos = wstrLoggedUserName.find(L",", snPos)) != wstring::npos) wstrLoggedUserName = wstrLoggedUserName.substr(snPos + 3, (enPos - (snPos + 3))); } // get dir container if (FAILED(hr = ADsOpenObject(wstrADSPath.c_str(), wstrLoggedUserName.c_str(), lpwstrLogonUsrPwd, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pDirContainer.getptr()))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); wstring wstrUserCN = L"CN="; wstrUserCN += lpwstrNewUser; dloge("CreateDSObject: %S",wstrUserCN.c_str()); if (FAILED(hr = pDirContainer->CreateDSObject((LPWSTR)wstrUserCN.c_str(), attrInfo, dwAttrs, pDisp.getptr()))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): CreateDSObject Failed.", ERR_CREATE_EXCHMBX,__LINE__, __FILE__); if (FAILED(hr = pDisp->QueryInterface(IID_IADsUser, (void **)pIADNewUser.getptr()))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): QueryInterface Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); CComVariant varProp; varProp.Clear(); // set samAccount varProp = lpwstrNewUser; if (FAILED(hr = pIADNewUser->Put(CComBSTR(L"sAMAccountName"), varProp))) throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(sAMAccountName) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if(FAILED(hr = pIADNewUser->SetInfo())) throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(sAMAccountName) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); // set userAccountControl varProp.Clear(); hr = pIADNewUser->Get(CComBSTR(L"userAccountControl"), &varProp); varProp = varProp.lVal & ~(ADS_UF_ACCOUNTDISABLE); if (FAILED(hr = pIADNewUser->Put(CComBSTR(L"userAccountControl"), varProp))) throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(userAccountControl) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(userAccountControl) Failed."); // set Account enabled if (FAILED(hr = pIADNewUser->put_AccountDisabled(VARIANT_FALSE))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): put_AccountDisabled Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - put_AccountDisabled Failed."); // set password if (FAILED(hr = pIADNewUser->SetPassword(CComBSTR(lpwstrNewUserPwd)))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): SetPassword Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - SetPassword Failed."); // user account password does not expire varProp.Clear(); VARIANT var; VariantInit(&var); if (!FAILED(hr = pIADNewUser->Get(CComBSTR(L"userAccountControl"), &var))) { V_I4(&var) |= ADS_UF_DONT_EXPIRE_PASSWD; if (FAILED(hr = pIADNewUser->Put(CComBSTR(L"userAccountControl"), var))) { throw ExchangeAdminException(hr,L"CreateExchangeMailBox(): Put(userAccountControl) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - userAccountControl Failed."); varProp.Clear(); // set the homeMDB; if (!strLogonHomeMDB.empty()) { varProp = strLogonHomeMDB.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("homeMDB"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(homeMDB) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(homeMDB) Failed."); varProp.Clear(); if (!strLogonHomeMTA.empty()) { varProp = strLogonHomeMTA.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("homeMTA"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(homeMTA) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(homeMTA) Failed."); varProp.Clear(); if (!msExchHomeSvrName.empty()) { varProp = msExchHomeSvrName.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchHomeServerName"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(msExchHomeServerName) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(msExchHomeServerName) Failed."); varProp.Clear(); varProp.Clear(); wstring newUsrLegacyName=legacyName; size_t nwpos=newUsrLegacyName.rfind(L"cn="); if(nwpos !=wstring::npos) { newUsrLegacyName = newUsrLegacyName.substr(0,nwpos); newUsrLegacyName += L"cn="; newUsrLegacyName += lpwstrNewUser; } if (!newUsrLegacyName.empty()) { varProp = newUsrLegacyName.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("legacyExchangeDN"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(legacyExchangeDN) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(legacyExchangeDN) Failed."); // set nickname varProp.Clear(); varProp = lpwstrNewUser; if (FAILED(hr = pIADNewUser->Put(CComBSTR("mailNickname"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(mailNickname) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(mailNickname) Failed."); // set the displayName varProp.Clear(); varProp = lpwstrNewUser; if (FAILED(hr = pIADNewUser->Put(CComBSTR("displayName"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(displayName) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(displayName) Failed."); // set the mail atrribute varProp.Clear(); varProp = wstrMail.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("mail"), varProp))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put(mail) Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - Put(mail) Failed."); // set email if (FAILED(hr = pIADNewUser->put_EmailAddress(CComBSTR(wstrMail.c_str())))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): put_EmailAddress Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - put_EmailAddress Failed."); varProp.Clear(); wstrMail=L"SMTP:"+wstrMail; varProp = wstrMail.c_str(); if (FAILED(hr = pIADNewUser->Put(CComBSTR("proxyAddresses"),varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): proxyAddressess Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - proxyAddressess Failed."); // add to Domain Admins group BSTR bstrADSPath; if (FAILED(hr = pIADNewUser->get_ADsPath(&bstrADSPath))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): get_ADsPath Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); wstring wstrGroup = _T("LDAP://CN=Domain Admins,CN=Users,") + wstrServerDN; Zimbra::Util::ScopedInterface<IADsGroup> pGroup; if (FAILED(hr = ADsGetObject(wstrGroup.c_str(), IID_IADsGroup, (void **)pGroup.getptr()))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsGetObject Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if (FAILED(hr = ADsOpenObject(wstrGroup.c_str(), wstrLoggedUserName.c_str(), lpwstrLogonUsrPwd, ADS_SECURE_AUTHENTICATION, IID_IADsGroup, (void **)pGroup.getptr()))) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); if (SUCCEEDED(hr = pGroup->Add(bstrADSPath))) { if (FAILED(hr = pGroup->SetInfo())) throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): pGroup SetInfo Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } else { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): pGroup Add Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } GUID guid; if(FAILED(hr = CoCreateGuid(&guid))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): CoCreateGuid Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } BYTE *str; hr = UuidToString((UUID *)&guid, (RPC_WSTR *)&str); if (hr != RPC_S_OK) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): UuidToString Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } varProp.Clear(); //BYTE bytArr[]="3429bb3084703348b8023e94fabf16ea"; PutBinaryIntoVariant(&varProp,str,16); RpcStringFree((RPC_WSTR *)&str); if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchMailboxGuid"), varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchMailboxGuid Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - msExchMailboxGuid Failed."); if (FAILED(hr = ADsOpenObject(strContainer.c_str(), NULL, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectoryObject, (void **)pIAdUser.getptr()))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): ADsOpenObject2 Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if (FAILED(hr = pIAdUser->QueryInterface(IID_IADs, (void**) pIAds.getptr()))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): pIAdUser->QueryInterface Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } varProp.Clear(); if( FAILED(hr= pIAds->Get(CComBSTR("msExchMailboxSecurityDescriptor"),&varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get msExchMailboxSecurityDescriptor Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchMailboxSecurityDescriptor"), varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchMailboxSecurityDescriptor Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - msExchMailboxSecurityDescriptor Failed."); varProp.Clear(); if( FAILED(hr=pIAds->Get(CComBSTR("msExchPoliciesIncluded"),&varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get msExchPoliciesIncluded Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchPoliciesIncluded"), varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchPoliciesIncluded Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - msExchPoliciesIncluded Failed."); varProp.Clear(); if( FAILED(hr= pIAds->Get(CComBSTR("msExchUserAccountControl"),&varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get msExchUserAccountControl Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if (FAILED(hr = pIADNewUser->Put(CComBSTR("msExchUserAccountControl"), varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put msExchUserAccountControl Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - msExchUserAccountControl Failed."); varProp.Clear(); if(FAILED(hr = pIAds->GetEx(CComBSTR("showInAddressBook"), &varProp ))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Get showInAddressBook Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->Put(CComBSTR("showInAddressBook"), varProp))) { throw ExchangeAdminException(hr, L"CreateExchangeMailBox(): Put showInAddressBook Failed.", ERR_CREATE_EXCHMBX, __LINE__, __FILE__); } if(FAILED(hr = pIADNewUser->SetInfo())) ThrowSetInfoException(hr, L"SetInfo - showInAddressBook Failed."); return hr; }
//////////////////////////////////////////// // OnExecute // Demonstrate: // IDirectorySearch::ExecuteSearch // IDirectorySearch::GetNextRow // IDirectorySearch::GetColumn // IDirectorySearch::SetSearchPreference // ///////////////////////////////////////////// void CDlgIDirectorySearch::OnExecute() { ASSERT( m_pSearch ); CWaitCursor wait; UpdateData(TRUE); // Get data from the Dialog Box HRESULT hr; ADS_SEARCH_HANDLE hSearch; ADS_SEARCH_COLUMN col; CString s; int idx=0; int nCount; LPWSTR *pszAttr=NULL; POSITION pos; USES_CONVERSION; ///////////////////////////////// // Reset the Total Number ////////////////////////////////// SetDlgItemText( IDC_TOTAL, _T("")); ///////////////////////////////////////////// // Get the attribute list, and preparing.. /////////////////////////////////////////// CStringList sAttrList; m_cListView.DeleteAllItems(); // Reset the UI while( m_cListView.DeleteColumn(0)) { ; } ////////////////////////////////////////////////// // Preparing for attribute list // and columns to display CString sTemp; m_cAttrList.GetWindowText(s); // we need to add adspath, so that we can refer to this object later when user dblclk the item if ( !s.IsEmpty() ) { sTemp = s; sTemp.MakeLower(); if ( s.Find(_T("adspath"),0) == -1 ) { s += _T(",ADsPath"); } } // convert to string list for easy manipulation StringToStringList( s, sAttrList ); nCount = sAttrList.GetCount(); idx=0; if ( nCount ) { pszAttr = (LPWSTR*) AllocADsMem( nCount * sizeof(LPWSTR)); pos = sAttrList.GetHeadPosition(); while ( pos != NULL ) { s = sAttrList.GetAt(pos); pszAttr[idx] = T2OLE(s); sAttrList.GetNext(pos ); idx++; } } else { nCount = -1; } ///////////////////////////////////////// // BEGIN Set the preferences /////////////////////////////////////// DWORD dwCountPref = 0; ADS_SEARCHPREF_INFO prefInfo[ MAX_SEARCH_PREF ]; ADS_SORTKEY *pSortKey = NULL; if ( m_bEnableFilter == FALSE ) { // Reset the preference m_pSearch->SetSearchPreference( prefInfo, dwCountPref ); } else // Preferences are specified { //////////////////////// // Timeout Pref //////////////////////////// if ( m_nTimeOut != 0 ) { prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_TIMEOUT; prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER; prefInfo[dwCountPref].vValue.Integer = m_nTimeOut; dwCountPref++; } ////////////////////////////// // Search Scope ///////////////////////////// idx = m_CADsSearchScope.GetCurSel(); if ( idx != CB_ERR ) { prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER; prefInfo[dwCountPref].vValue.Integer = idx; dwCountPref++; } /////////////////////////////////////////////////// // Cache Result. The default is to cache the result ///////////////////////////////////////////////// if ( !m_bCacheResult ) { prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; prefInfo[dwCountPref].vValue.dwType = ADSTYPE_BOOLEAN; prefInfo[dwCountPref].vValue.Boolean = FALSE; dwCountPref++; } ////////////////////////////////////////////////// // Page Size /////////////////////////////////////////////////// if ( m_nPageSize > 0 ) { prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_PAGESIZE; prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER;; prefInfo[dwCountPref].vValue.Integer = m_nPageSize; dwCountPref++; } //////////////////////////////////////////////// // Chase Referrals /////////////////////////////////////////////// idx = m_cChaseReferrals.GetCurSel(); if ( idx != CB_ERR ) { prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_CHASE_REFERRALS; prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER; switch( idx ) { case 0: prefInfo[dwCountPref].vValue.Integer = ADS_CHASE_REFERRALS_NEVER; break; case 1: prefInfo[dwCountPref].vValue.Integer = ADS_CHASE_REFERRALS_SUBORDINATE; break; case 2: prefInfo[dwCountPref].vValue.Integer = ADS_CHASE_REFERRALS_EXTERNAL; break; default: prefInfo[dwCountPref].vValue.Integer = ADS_CHASE_REFERRALS_EXTERNAL; } dwCountPref++; } /////////////////////////////////////////////// // Sort On //////////////////////////////////////////////// if ( !m_sSortOn.IsEmpty() ) { CStringList sList; UINT nCount; prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_SORT_ON; prefInfo[dwCountPref].vValue.dwType = ADSTYPE_PROV_SPECIFIC; StringToStringList( m_sSortOn, sList ); nCount = sList.GetCount(); if ( nCount > 0 ) { POSITION pos; pos= sList.GetHeadPosition(); pSortKey = (ADS_SORTKEY *) LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, sizeof(ADS_SORTKEY) * nCount ); idx = 0; while( pos != NULL ) { pSortKey[idx].pszAttrType = T2OLE(sList.GetAt(pos)); pSortKey[idx].pszReserved = NULL; pSortKey[idx].fReverseorder =0; // Next idx++; sList.GetNext( pos ); } prefInfo[dwCountPref].vValue.ProviderSpecific.dwLength = sizeof(ADS_SORTKEY) * nCount; prefInfo[dwCountPref].vValue.ProviderSpecific.lpValue = (LPBYTE) pSortKey; dwCountPref++; } } ////////////////////////////////////////////// // Size Limit ////////////////////////////////////////////// if ( m_nSizeLimit > 0 ) { prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT; prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER; prefInfo[dwCountPref].vValue.Integer = m_nSizeLimit; dwCountPref++; } ////////////////////////////////////////////////// // A Synchronous /////////////////////////////////////////////////// if ( m_bAsynch ) { prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_ASYNCHRONOUS; prefInfo[dwCountPref].vValue.dwType = ADSTYPE_BOOLEAN; prefInfo[dwCountPref].vValue.Integer = TRUE; dwCountPref++; } ///////////////////////////////////////////////////// // Attribute Type Only ////////////////////////////////////////////////////// if ( m_bAttrib ) { prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_ATTRIBTYPES_ONLY; prefInfo[dwCountPref].vValue.dwType = ADSTYPE_BOOLEAN; prefInfo[dwCountPref].vValue.Integer = TRUE; dwCountPref++; } ///////////////////////////////////////////////////// // Derefence Alias ////////////////////////////////////////////////////// if ( m_nDeref != CB_ERR ) { prefInfo[dwCountPref].dwSearchPref = ADS_SEARCHPREF_DEREF_ALIASES; prefInfo[dwCountPref].vValue.dwType = ADSTYPE_INTEGER; prefInfo[dwCountPref].vValue.Integer = m_nDeref; dwCountPref++; } /////////////////////////////////////////////// // Now Set the selected preferences ////////////////////////////////////////////// hr = m_pSearch->SetSearchPreference( prefInfo, dwCountPref ); } ///////////////////////////////////////// // END Set the preferences /////////////////////////////////////// //////////////////////////////////////// // Execute the Search ////////////////////////////////////// DWORD dwCount=0; hr = m_pSearch->ExecuteSearch(T2OLE(m_sFilter), pszAttr, nCount, &hSearch ); //////////////////////////////// //// cleanup //////////////////////////////// if ( pszAttr ) { FreeADsMem( pszAttr ); } if ( pSortKey ) { LocalFree( pSortKey ); } if ( !SUCCEEDED(hr) ) { AfxMessageBox(GetErrorMessage(hr)); return; } //////////////////////////////////////////////////////// // Enumerate the rows //////////////////////////////////////////////////////// sAttrList.RemoveAll(); ///////////////////////////////////////////////////////// // Retrieve the column names returned from the server /////////////////////////////////////////////////////////// LPWSTR pszColumn; hr = m_pSearch->GetFirstRow( hSearch ); if ( !SUCCEEDED(hr) ) { return; } idx=0; while( (hr=m_pSearch->GetNextColumnName( hSearch, &pszColumn )) != S_ADS_NOMORE_COLUMNS ) { s = OLE2T( pszColumn ); m_cListView.InsertColumn(idx, s, LVCFMT_LEFT, 150 ); // adding columns to the UI sAttrList.AddTail(s); FreeADsMem( pszColumn ); idx++; } ///////////////////////////////////////////// // Start iterating the result set //////////////////////////////////////////// int nCol; CStringList sValueList; do { nCol=0; pos = sAttrList.GetHeadPosition(); while( pos != NULL ) { s = sAttrList.GetAt(pos); //column name // Get the Name and display it in the list hr = m_pSearch->GetColumn( hSearch, T2OLE(s), &col ); if ( SUCCEEDED(hr) ) { s =_T(""); if ( col.dwADsType != ADSTYPE_INVALID ) // if we request for attrib only, no value will be returned { ADsToStringList(col.pADsValues, col.dwNumValues, sValueList ); StringListToString( sValueList, s ); } if ( nCol ) { m_cListView.SetItemText(0,nCol, s); } else { m_cListView.InsertItem(0, s); } m_pSearch->FreeColumn( &col ); } nCol++; sAttrList.GetNext(pos); } dwCount++; ///////////////////////////// //Display the total so far //////////////////////////////// s.Format("%ld object(s)", dwCount ); SetDlgItemText( IDC_TOTAL, s ); } while( (hr=m_pSearch->GetNextRow( hSearch)) != S_ADS_NOMORE_ROWS ); m_pSearch->CloseSearchHandle( hSearch ); }
HRESULT FindUsers(IDirectorySearch *pContainerToSearch, //IDirectorySearch pointer to Partitions container. LPOLESTR szFilter, //Filter for finding specific crossrefs. //NULL returns all attributeSchema objects. LPOLESTR *pszPropertiesToReturn, //Properties to return for crossRef objects found //NULL returns all set properties. unsigned long ulNumPropsToReturn, // Number of property strings in pszPropertiesToReturn BOOL bIsVerbose //TRUE means all properties for the found objects are displayed. //FALSE means only the RDN ) { if (!pContainerToSearch) return E_POINTER; //Create search filter LPOLESTR pszSearchFilter = new OLECHAR[MAX_PATH*2]; if ( !pszSearchFilter ) return E_OUTOFMEMORY; wchar_t szFormat[] = L"(&(objectClass=user)(objectCategory=person)%s)"; // Check the buffer first if ( IS_BUFFER_ENOUGH(MAX_PATH*2, szFormat, szFilter) > 0 ) { //Add the filter. swprintf_s(pszSearchFilter, MAX_PATH*2, szFormat,szFilter); } else { wprintf(L"The filter is too large for buffer, aborting..."); delete [] pszSearchFilter; return FALSE; } //Specify subtree search ADS_SEARCHPREF_INFO SearchPrefs; SearchPrefs.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; SearchPrefs.vValue.dwType = ADSTYPE_INTEGER; SearchPrefs.vValue.Integer = ADS_SCOPE_SUBTREE; 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 = pContainerToSearch->SetSearchPreference( &SearchPrefs, dwNumPrefs); if (FAILED(hr)) { delete [] pszSearchFilter; 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"name",L"distinguishedName"}; unsigned long ulNonVbPropsCount = 2; LPOLESTR szName = new OLECHAR[MAX_PATH]; LPOLESTR szDN = new OLECHAR[MAX_PATH]; if ( !szName || !szDN ) { delete [] pszSearchFilter; if ( szDN ) delete [] szDN; if ( szName ) delete [] szName ; return E_OUTOFMEMORY; } int iCount = 0; DWORD x = 0L; if (!bIsVerbose) { //Return non-verbose list properties only hr = pContainerToSearch->ExecuteSearch(pszSearchFilter, pszNonVerboseList, ulNonVbPropsCount, &hSearch ); } else { if (!pszPropertiesToReturn) { //Return all properties. hr = pContainerToSearch->ExecuteSearch(pszSearchFilter, NULL, -1L, &hSearch ); } else { //specified subset. pszPropertyList = pszPropertiesToReturn; //Return specified properties hr = pContainerToSearch->ExecuteSearch(pszSearchFilter, pszPropertyList, sizeof(pszPropertyList)/sizeof(LPOLESTR), &hSearch ); } } if ( SUCCEEDED(hr) ) { // Call IDirectorySearch::GetNextRow() to retrieve the next row //of data hr = pContainerToSearch->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( pContainerToSearch->GetNextColumnName( hSearch, &pszColumn ) != S_ADS_NOMORE_COLUMNS ) { hr = pContainerToSearch->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) ) { 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 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"); } 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"name", pszColumn)) { szName[0]=L'\0'; if( IS_BUFFER_ENOUGH(MAX_PATH, szName, col.pADsValues->CaseIgnoreString) > 0 ) { wcscpy_s(szName,MAX_PATH,col.pADsValues->CaseIgnoreString); } } if (0==wcscmp(L"distinguishedName", pszColumn)) { szDN[0]=L'\0'; if( IS_BUFFER_ENOUGH(MAX_PATH, szDN, col.pADsValues->CaseIgnoreString) > 0 ) { wcscpy_s(szDN,MAX_PATH,col.pADsValues->CaseIgnoreString); } } } pContainerToSearch->FreeColumn( &col ); } FreeADsMem( pszColumn ); } if (!bIsVerbose) wprintf(L"%s\n DN: %s\n\n",szName,szDN); //Get the next row hr = pContainerToSearch->GetNextRow( hSearch); } } // Close the search handle to clean up pContainerToSearch->CloseSearchHandle(hSearch); } if (SUCCEEDED(hr) && 0==iCount) hr = S_FALSE; delete [] pszSearchFilter; delete [] szName; delete [] szDN; return hr; }
void CDlgIDirectoryObject::OnGet() { CStringList sList; UINT nCount; HRESULT hr; UpdateData(TRUE); StringToStringList(m_sAttributes, sList ); nCount = sList.GetCount(); if ( nCount == 0 ) { return; } /////////////////////////////////////// // Now build the Attribute Names List /////////////////////////////////////// POSITION pos; DWORD dwNumAttr; LPWSTR *pAttrNames=NULL; ADS_ATTR_INFO *pAttrInfo; DWORD dwReturn; USES_CONVERSION; pAttrNames = (LPWSTR*) AllocADsMem( sizeof(LPWSTR) * nCount ); pos = sList.GetHeadPosition(); dwNumAttr = 0; while( pos != NULL ) { pAttrNames[dwNumAttr] = T2OLE(sList.GetAt(pos)); dwNumAttr++; sList.GetNext(pos); } ///////////////////////////////////////// // Get attributes value requested // Note: The order is not necessarily the same as // requested via pAttrNames. /////////////////////////////////////////// hr = m_pDirObject->GetObjectAttributes( pAttrNames, dwNumAttr, &pAttrInfo, &dwReturn ); if ( SUCCEEDED(hr) ) { DWORD idx; CString sDisplay; CStringList sValueList; UINT nCount; POSITION pos; m_cValueList.ResetContent(); for( idx=0; idx < dwReturn; idx++) { ADsToStringList( pAttrInfo[idx].pADsValues, pAttrInfo[idx].dwNumValues, sValueList ); sDisplay = OLE2T(pAttrInfo[idx].pszAttrName); sDisplay += _T(":"); m_cValueList.AddString( sDisplay ); nCount = sValueList.GetCount(); if ( nCount == 0 ) // can not find/convert the value { m_cValueList.AddString(_T(" > [No Value]")); continue; } else { pos = sValueList.GetHeadPosition(); while( pos != NULL ) { sDisplay = _T(" > "); sDisplay += sValueList.GetAt(pos); m_cValueList.AddString( sDisplay ); sValueList.GetNext(pos); } } } sValueList.RemoveAll(); } /////////////////////////////////////////////////////////// // Use FreADsMem for all memory obtained from ADSI call ///////////////////////////////////////////////////////////// FreeADsMem( pAttrInfo ); FreeADsMem( pAttrNames ); }