#active-directory #ldap #openldap
#active-directory #ldap #openldap
Вопрос:
Я пытаюсь выполнить поиск в Active Directory по всем атрибутам учетной записи компьютера. Все атрибуты полностью перечислены в PowerShell, но когда я использую ldap-search и открываю ldap на C , я получаю только частичные результаты, даже если значение заполнено в каталоге.
Во многих сообщениях предлагалось проверить, привязаны ли вы к порту 3268, который является глобальным каталогом, и изменить его на порт 389, который является портом ldap. Но я привязан к порту ldap, и я также попытался специально указать требуемый атрибут. Но я все равно не получаю атрибут.
Это поисковый запрос, который я использовал для поиска ldap
ldapsearch -x -h example.com -D "CN=Administrator,CN=Users,DC=example,DC=com" -w "passw"
-b "DC=example,DC=com" "(objectclass=computer)" '*'
Это код c , который я использовал из oracle docs:
#include <stdio.h>
#include "ldap.h"
/* Change these as needed. */
#define HOSTNAME "localhost"
#define PORTNUMBER LDAP_PORT
#define BASEDN "dc=example,dc=com"
#define SCOPE LDAP_SCOPE_SUBTREE
#define FILTER "(objectclass=computer)"
int main( int argc, char **argv )
{
LDAP *ld;
LDAPMessage *res, *msg;
LDAPControl **serverctrls;
BerElement *ber;
char *a, *dn, *matched_msg = NULL, *error_msg = NULL;
char **vals, **referrals;
int version, i, rc, parse_rc, msgtype, num_entries = 0,
num_refs = 0;
/* Get a handle to an LDAP connection. */
if ( (ld = ldap_init( HOSTNAME, PORTNUMBER )) == NULL ) {
perror( "ldap_init" );
return( 1 );
}
version = LDAP_VERSION3;
if ( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, amp;version ) !=
LDAP_SUCCESS ) {
rc = ldap_get_lderrno( ld, NULL, NULL );
fprintf( stderr, "ldap_set_option: %sn", ldap_err2string( rc ) );
ldap_unbind( ld );
return( 1 );
}
/* Bind to the server anonymously. */
rc = ldap_simple_bind_s( ld,"cn=Administrator,cn=users,dc=example,dc=net", "passw" );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "ldap_simple_bind_s: %sn", ldap_err2string( rc ) );
ldap_get_lderrno( ld, amp;matched_msg, amp;error_msg );
if ( error_msg != NULL amp;amp; *error_msg != '' ) {
fprintf( stderr, "%sn", error_msg );
}
if ( matched_msg != NULL amp;amp; *matched_msg != '' ) {
fprintf( stderr, "Part of the DN that matches an existing entry: %sn", matched_msg );
}
ldap_unbind_s( ld );
return( 1 );
}
/* Perform the search operation. */
rc = ldap_search_ext_s( ld, BASEDN, SCOPE, FILTER, NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, amp;res );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "ldap_search_ext_s: %sn", ldap_err2string( rc ) );
if ( error_msg != NULL amp;amp; *error_msg != '' ) {
fprintf( stderr, "%sn", error_msg );
}
if ( matched_msg != NULL amp;amp; *matched_msg != '' ) {
fprintf( stderr, "Part of the DN that matches an existing entry: %sn", matched_msg );
}
ldap_unbind_s( ld );
return( 1 );
}
num_entries = ldap_count_entries( ld, res );
num_refs = ldap_count_references( ld, res );
/* Iterate through the results. An LDAPMessage structure sent back from
a search operation can contain either an entry found by the search,
a search reference, or the final result of the search operation. */
for ( msg = ldap_first_message( ld, res ); msg != NULL; msg = ldap_next_message( ld, msg ) ) {
/* Determine what type of message was sent from the server. */
msgtype = ldap_msgtype( msg );
switch( msgtype ) {
/* If the result was an entry found by the search, get and print the
attributes and values of the entry. */
case LDAP_RES_SEARCH_ENTRY:
/* Get and print the DN of the entry. */
if (( dn = ldap_get_dn( ld, res )) != NULL ) {
printf( "dn: %sn", dn );
ldap_memfree( dn );
}
/* Iterate through each attribute in the entry. */
for ( a = ldap_first_attribute( ld, res, amp;ber );
a != NULL; a = ldap_next_attribute( ld, res, ber ) ) {
/* Get and print all values for each attribute. */
if (( vals = ldap_get_values( ld, res, a )) != NULL ) {
for ( i = 0; vals[ i ] != NULL; i ) {
printf( "%s: %sn", a, vals[ i ] );
}
ldap_value_free( vals );
}
ldap_memfree( a );
}
if ( ber != NULL ) {
ber_free( ber, 0 );
}
printf( "n" );
break;
case LDAP_RES_SEARCH_REFERENCE:
/* The server sent a search reference encountered during the
search operation. */
/* Parse the result and print the search references.
Ideally, rather than print them out, you would follow the
references. */
parse_rc = ldap_parse_reference( ld, msg, amp;referrals, NULL, 0 );
if ( parse_rc != LDAP_SUCCESS ) {
fprintf( stderr, "ldap_parse_result: %sn", ldap_err2string( parse_rc ) );
ldap_unbind( ld );
return( 1 );
}
if ( referrals != NULL ) {
for ( i = 0; referrals[ i ] != NULL; i ) {
printf( "Search reference: %snn", referrals[ i ] );
}
ldap_value_free( referrals );
}
break;
case LDAP_RES_SEARCH_RESULT:
/* Parse the final result received from the server. Note the last
argument is a non-zero value, which indicates that the
LDAPMessage structure will be freed when done. (No need
to call ldap_msgfree().) */
parse_rc = ldap_parse_result( ld, msg, amp;rc, amp;matched_msg, amp;error_msg, NULL, amp;serverctrls, 0 );
if ( parse_rc != LDAP_SUCCESS ) {
fprintf( stderr, "ldap_parse_result: %sn", ldap_err2string( parse_rc ) );
ldap_unbind( ld );
return( 1 );
}
/* Check the results of the LDAP search operation. */
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "ldap_search_ext: %sn", ldap_err2string( rc ) );
if ( error_msg != NULL amp; *error_msg != '' ) {
fprintf( stderr, "%sn", error_msg );
}
if ( matched_msg != NULL amp;amp; *matched_msg != '' ) {
fprintf( stderr, "Part of the DN that matches an existing entry: %sn", matched_msg );
}
} else {
printf( "Search completed successfully.n"
"Entries found: %dn"
"Search references returned: %dn",
num_entries, num_refs );
}
break;
default:
break;
}
}
/* Disconnect when done. */
ldap_unbind( ld );
return( 0 );
}
Комментарии:
1. ОС этот вопрос об использовании инструмента командной строки или о C ? Сделайте это одним или другим. В первом случае вы должны указать точную версию инструмента. В последнем случае покажите код на C и точную версию библиотек, которые вы используете.
2. Если ваш вопрос касается вашего кода на C , почему вы опубликовали только ту
ldapsearch
командную строку, которая работает?3. @Tomalak Я пробовал использовать как c , так и инструмент cmd, но оба метода возвращают не все атрибуты. я использую ldap версии 3. И просто для того, чтобы уточнить, имеет ли это какое-либо отношение к типу операции привязки?
4. Это связано с тем, какие атрибуты вы запрашиваете. В
ldapsearch
случае, который вы запросили*
, это означает все нерабочие атрибуты; в случае C вы указали NULL , что означает то же самое. Если вам также нужны операционные атрибуты, вы должны указать*,
их в обоих случаях.5. @user207421 привет, я пытался использовать этот запрос, но он не перечисляет все атрибуты. ldapsearch -x -h example.net -p 389 -D «CN = Администратор, CN = Пользователи, DC = пример, DC = сеть» -W «passw» -b «CN = Компьютеры, DC = пример, DC = сеть» «(objectclass=компьютер)» «*, «. Правильный ли этот запрос?
Ответ №1:
В вашем коде вы выполняете a simple_bind_s
с NULL
параметрами, что означает, что вы выполняете анонимную привязку, и поэтому у клиента нет разрешения на чтение всех атрибутов. Если вы должны были пройти аутентификацию с тем же пользователем, что и в ldapsearch, вы, вероятно, получите тот же результат.
Комментарии:
1. да, сожалею об этом. Я забыл обновить код. я использую учетную запись администратора для привязки. Имеет ли это какое-либо отношение к типу привязки?
2. Так не должно быть. Я считаю, что обе привязки эквивалентны.
3. Мне было интересно, требуется ли для этого какое-то безопасное соединение, такое как sasl_bind
4. sasl_bind не устанавливает безопасное соединение по умолчанию. И -x в ldapsearch использует простую привязку.
Ответ №2:
ldapsearch -o ldif-wrap=no -x -h example.net -p 389 -D "CN=Administrator,CN=Users,DC=example,DC=net" -W "passw" -b "CN=Computers,DC=example,DC=net" "(objectclass=computer)" '*' ' '
-o ldif-wrap=no
// Удалить разрыв строки по умолчанию из 79 символов' '
// для возврата ТОЛЬКО рабочих атрибутов в ldapsearch'*'
// для возврата ТОЛЬКО нерабочих (пользовательских) атрибутов в ldapsearch (поведение по умолчанию)'*' ' '
// для возврата пользовательских операционных атрибутов !