我需要找到本地计算机(连接到Active Directory)属于使用WinAPI / C ++的OU的名称。有什么想法吗?
答案 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就是你想要的。