使用C ++获取本地计算机所属的OU(组织单位)名称

时间:2012-01-24 20:15:34

标签: c++ winapi active-directory ou

我需要找到本地计算机(连接到Active Directory)属于使用WinAPI / C ++的OU的名称。有什么想法吗?

3 个答案:

答案 0 :(得分:3)

理论上,这很简单:使用ADsOpenObject连接到服务器,实例化IDirectorySearch并调用其ExecuteSearch方法,然后使用GetFirstRow和{{3遍历结果数据(但对于此查询,您只需要一行)。

然而,实际上,所有这些都是COM - 所以期望那些半打(左右)函数调用在至少一百行COM-cruftiness中丢失(当代码是固定的时候)如果它接近1000行,并且其中大多数与Active Directory没有明显的连接,请不要感到惊讶。

我应该补充一点,几乎肯定有其他方法可以做到这一点 - 我记得,MS提供了至少两种或三种不同的方式来访问LDAP类型的数据。当我为此编写一些代码时,我最初试图找到哪个是最干净的,但却沮丧地放弃了。对于最干净的人似乎没有希望 - 至少在那个时候,我选择了“丑陋但有些记录”。

答案 1 :(得分:2)

对于使用C或C ++访问Active Directory的简单WINAPI(非COME)方式,请参阅Lightweight Directory Access Protocol


void AfficheErreurLdap(char *fonction, ULONG rc);

/*
*
*       Fonction d'entrée du programme 
*
*/

void main(int argc, char* argv[])
{
  LDAP *pSessionLdap;    // Pointeur vers la session LDAP
  char *pHote;           // Pointeur vers la chaîne représentant le nom de l'hôte   
  char *pUtilisateur;    // Pointeur vers la chaîne représentant l'utilisateur  
  char *pMotDePasse;     // Pointeur vers la chaîne représentant le mot de passe
  char *pRacineLdap;     // Pointeur vers la racine Ldap
  ULONG rc;                // Récupération du code de retour des appels
  LDAPMessage   *pResultat; // Pointeur vers le message résultat de la réquête LDAP
  LDAPMessage   *pEntree;     // Utilisée lors du parcours du résultat pour l'affichage

  char *pDN;                 // Pointeur vers le DN d'une entrée du résultat
  char *pAttribut;     // Pointeur vers la chaîne représentant l'attribut
  BerElement *pBer = NULL;// "curseur" interne à l'API LDAP pour le parcours des elts 
  char **pValeurs;            // Valeurs de l'attribut lors de l'affichage du résultat
  int    i;                             // Indice pour la parcours des valeurs  d'attribut

  /* Analyse des Paramètres de lancement et affichage d’un message d’erreur si incorrect */
  if (argc != 5)
  {
    fprintf(stderr,"Syntaxe :\n\tex_cldap_1 Hote Utilisateur MotDePasse RacineLdap\n");
    exit (1);
  }
  /* Récupération des paramètres des lancement  */
  pHote = argv[1];
  pUtilisateur = argv[2];
  pMotDePasse = argv[3];
  pRacineLdap = argv[4];

  /* Ouverture de la session LDAP et récupération du handle de session */
  pSessionLdap = ldap_open( pHote, 389);    /* 389 est le numéro de port standard LDAP */

  if ( pSessionLdap == NULL ) 
  {
    // En cas d'erreur : affichage du message d'erreur adéquat 
    perror( "ldap_open" );
    exit( 2 );
  }

  printf("Ouverture de la session réalisée\n");

  /* Authentification du client                                                                                                             */
  /* Pour l'exemple, l'authentification est faite en tant qu'anonyme    */
  rc = ldap_simple_bind_s(pSessionLdap, pUtilisateur, pMotDePasse);
  if ( rc != LDAP_SUCCESS ) 
  {
    // Erreur lors de l'authentification, on termine après affichage d'un message
    AfficheErreurLdap("ldap_simple_bind_s", rc);

    exit( 3 );
  }

  printf("Authentification réalisée\n");

  /*                                                                                                                                */
  /* Recherche des données dans l'annuaire                  */
  /*                                                                                                                                */
  rc = ldap_search_s(pSessionLdap,            // Session LDAP
    pRacineLdap,                    // Base de la recherche
    LDAP_SCOPE_SUBTREE, // Sccpe : LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE  
    "(objectClass=*)",      // Filtre de recherche
    NULL,                               // Attributs que l'on souhaite visualiser
    0,                                      // Indique si l'on souhaite uniquement les types (1) ou 
    // Les attributs et les valeurs (0)
    &pResultat ) ;              // Pointeur vers le résultat

  if (rc != LDAP_SUCCESS ) 
  {
    // Erreur lors de la recherche, on termine après affichage du message d'erreur
    AfficheErreurLdap("ldap_search_s", rc);
    exit (4);
  }

  printf("Requête réalisée\n");


  /* On va maintenant parcourir le résultat et afficher les couples */
  /* attributs, valeurs                                                                                                                         */

  pEntree = ldap_first_entry( pSessionLdap, pResultat );

  while (pEntree != NULL)
  {
    // Récupération du DN, et affichage de celui-ci
    pDN = ldap_get_dn( pSessionLdap, pEntree );
    if ( pDN != NULL ) 
    {
      printf( "dn: %s\n", pDN );

      // Libération de la mémoire allouée par l'API LDAP
      ldap_memfree( pDN );  
    }


    // Pour chaque attribut, on va lire le couple attribut, valeur 
    pAttribut = ldap_first_attribute( pSessionLdap, pEntree, &pBer );
    while (  pAttribut != NULL)
    {
      // Récupération des valeurs associées à un attribut 
      pValeurs = ldap_get_values( pSessionLdap, pEntree, pAttribut);

      if (pValeurs  != NULL ) 
      {
        for ( i = 0; pValeurs[i] != NULL; i++ ) 
          printf( "%s: %s\n", pAttribut, pValeurs[i]);

        // Libération des valeurs lues 
        ldap_value_free( pValeurs ); 
      }

      // Libération de la mémoire utilisée par l'attribut 
      ldap_memfree( pAttribut );    

      // Lecture de l'attribut suivant
      pAttribut = ldap_next_attribute( pSessionLdap, pEntree, pBer );
    }

    // Passage à la ligne dans l'affichage
    printf( "\n\n" );

    // Récupération de l'entrée suivante de l'annuaire
    pEntree = ldap_next_entry( pSessionLdap, pEntree );
  }

  // Libération du message de résultat
  ldap_msgfree( pResultat );

  /* Fin de la session LDAP     */
  ldap_unbind( pSessionLdap );
}


/*
*
* Fonction permettant d'afficher les erreurs des opérations LDAP 
*
*
*/
void AfficheErreurLdap(char *fonction, ULONG rc)
{
  fprintf(stderr,"Erreur LDAP dans la fonction '%s', Code : %ld (0x%xld)\n", fonction, rc,rc);
}

答案 2 :(得分:0)

    ///////////////IDirectorySearch///////////////////////////////////////////////////////////
CComPtr<IDirectorySearch> pDSSearch;

hr = ADsGetObject( L"LDAP://DC=forest,DC=internal", 
    IID_IDirectorySearch, 
    (void**) &pDSSearch );

if ( !SUCCEEDED(hr) )
{
    return 0;
}

LPWSTR pszAttr[] = { L"description", L"Name", L"distinguishedname" };
ADS_SEARCH_HANDLE hSearch;
DWORD dwCount = 0;
ADS_SEARCH_COLUMN col;
DWORD dwAttrNameSize = sizeof(pszAttr)/sizeof(LPWSTR);

// Search for all objects with the 'cn' property  TESTCOMP.
hr = pDSSearch->ExecuteSearch(L"(&(objectClass=computer)(cn=TESTCOMP))",pszAttr ,dwAttrNameSize,&hSearch );

LPWSTR pszColumn;
while( pDSSearch->GetNextRow( hSearch) != S_ADS_NOMORE_ROWS )
{
    // Get the property.
    hr = pDSSearch->GetColumn( hSearch, L"distinguishedname", &col );

    // If this object supports this attribute, display it.
    if ( SUCCEEDED(hr) )
    { 
        if (col.dwADsType == ADSTYPE_CASE_IGNORE_STRING)
            wprintf(L"The description property:%s\r\n", col.pADsValues->CaseIgnoreString); 
        pDSSearch->FreeColumn( &col );
    }
    else
        puts("description property NOT available");
    puts("------------------------------------------------");
    dwCount++;
}
pDSSearch->CloseSearchHandle(hSearch);
///////////////IDirectorySearch///////////////////////////////////////////////////////////

在此搜索中,您将获得

(*((COL).pADsValues))。DNString &#34; CN = testcomp隔离,OU = OUnit3,OU = OUnit,DC =森林,DC =内部&#34;

所以这是你的TESTCOMP之路,我相信OUnit3就是你想要的。