2010-11-18 9 views
1

J'essaie actuellement d'exécuter une requête LDAP en C++ pour obtenir l'attribut memberOf d'un utilisateur donné. J'ai une fonction écrite qui obtient avec succès l'attribut s'ils sont seulement dans un groupe. Le problème est que quand ils sont dans plus d'un groupe, il ne renvoie que le premier. Quand je regarde l'utilisateur dans le navigateur Active Directory, je peux voir qu'il dit qu'ils ont 2 entrées pour memberOf, mais quand j'utilise ma fonction, je reçois seulement le premier. Y at-il un moyen de modifier ma fonction pour retirer toutes les entrées ou suis-je complètement sur le mauvais chemin?C++ LDAP Requête pour localiser memberOf

bool FindADMembership(CStringArray* pUserArray,IDirectorySearch *pContainerToSearch, CString sAMAccountName){ 

if(pContainerToSearch==NULL||pUserArray==NULL) 
    return false; 

CString strSearchFilter; 
strSearchFilter.Format("(&(objectClass=user)(objectCategory=person)(sAMAccountName=%s))", sAMAccountName); 
BSTR b = strSearchFilter.AllocSysString(); 
LPOLESTR pszSearchFilter = b; 
ADS_SEARCHPREF_INFO SearchPrefs; 
SearchPrefs.dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; 
SearchPrefs.vValue.dwType = ADSTYPE_INTEGER; 
SearchPrefs.vValue.Integer = ADS_SCOPE_SUBTREE; 
DWORD dwNumPrefs = 1; 

LPOLESTR pszColumn = NULL;  
ADS_SEARCH_COLUMN col; 
HRESULT hr; 

IADs *pObj = NULL; 
IADs * pIADs = NULL; 

ADS_SEARCH_HANDLE hSearch = NULL; 
hr = pContainerToSearch->SetSearchPreference(&SearchPrefs, dwNumPrefs); 
if (FAILED(hr)) 
    return false; 


LPOLESTR pszNonVerboseList[] = {L"memberOf"}; 
LPOLESTR szName = new OLECHAR[MAX_PATH]; 
int iCount = 0; 


hr = pContainerToSearch->ExecuteSearch(pszSearchFilter, pszNonVerboseList,sizeof(pszNonVerboseList)/sizeof(LPOLESTR),&hSearch); 
if (SUCCEEDED(hr)) 
{  
    hr = pContainerToSearch->GetFirstRow(hSearch); 
    if (SUCCEEDED(hr)) 
    { 
     while(hr != S_ADS_NOMORE_ROWS) 
     { 
      iCount++; 
      while(pContainerToSearch->GetNextColumnName(hSearch, &pszColumn) != S_ADS_NOMORE_COLUMNS) 
      { 
       hr = pContainerToSearch->GetColumn(hSearch, pszColumn, &col); 
       if (SUCCEEDED(hr)) 
       { 
        if (0==wcscmp(L"memberOf", pszColumn)) 
        { 
         wcscpy(szName,col.pADsValues->CaseIgnoreString); 
         pUserArray->Add(szName); 
        } 

        pContainerToSearch->FreeColumn(&col); 
       } 
       FreeADsMem(pszColumn); 
      } 


      hr = pContainerToSearch->GetNextRow(hSearch); 
     } 

    } 
    else 
     return false; 

    pContainerToSearch->CloseSearchHandle(hSearch); 
} 
else 
    return false; 

return true; } 

Edit:

Après avoir travaillé sur ce ici le code à itérer les résultats

if (0==wcscmp(L"memberOf", pszColumn)) { 
    for(int i = 0; i < col.dwNumValues; i++) 
    { 
     wcscpy(szName, col.pADsValues[i].CaseIgnoreString); 
     pUserArray->Add(szName); 
    } 
} 

Répondre

1

Vous devez vérifier le nombre de valeurs et la boucle sur eux pour obtenir chacun à leur tour - pADSValues est un tableau pouvant contenir plus d'une chaîne. Le nombre est retourné dans dwNumValues.

if (0==wcscmp(L"memberOf", pszColumn)) 
{ 
    // This code should actually be a loop for i = 0 to dwNumValues - 1 
    // with each loop checking the next array entry in the list pADsValues 
    wcscpy(szName,col.pADsValues->CaseIgnoreString); 
    pUserArray->Add(szName); 
} 

Voir docs here.