4

WinAPI / C ++を使用して、ローカルコンピューター(Active Directoryに接続されている)が属するOUの名前を確認する必要があります。何か案は?

4

3 に答える 3

2

理論的には、これは非常に単純です。サーバーに接続しADsOpenObject、をインスタンス化してそのメソッドIDirectorySearchを呼び出し、を使用して結果データをウォークスルーします(ただし、このクエリでは、1行しか期待できません)。ExecuteSearchGetFirstRowGetNextRow

ただし、実際には、これはすべてCOMです。したがって、これらの半ダース(またはそれ以上)の関数呼び出しは、少なくとも100行のCOMの無愛想さでほとんど失われると予想されます(そして、コードが堅固で堅牢になるまでに、 1000回線に近づいても驚かないでください。そのほとんどは、Active Directoryへの目立った接続がありません)。

これを行うには、ほぼ確実に他の方法があることを付け加えておきます。覚えているように、MSはLDAPタイプのデータにアクセスするための少なくとも2つまたは3つの異なる方法を提供します。このためのコードを書いたとき、私は最初にどれが最もクリーンであるかを見つけようとしましたが、欲求不満で諦めました。最もクリーンなものへの希望はないようでした。少なくともその時点では、私は「醜いが、いくらか文書化されている」と決心しました。

于 2012-01-24T21:21:52.287 に答える
1

CまたはC++でActiveDirectoryにアクセスするための単純なWINAPI(COMではない)方法については、ライトウェイトディレクトリアクセスプロトコルを参照してください。


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);
}
于 2012-01-25T04:52:57.940 に答える
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 "CN = TESTCOMP、OU = OUnit3、OU = OUnit、DC = forest、DC = internal"

これがあなたのTESTCOMPへの道であり、OUnit3があなたが望むものだと私は信じています。

于 2018-06-01T09:11:05.157 に答える