#include <stdio.h>
#include <stdlib.h>
#include <ldap.h>
#include <string.h>
#if defined(N_PLAT_NLM) && defined(LIBC)
#include <screen.h>
#endif
int isVLVSupported(LDAP *ld);
static char usage[] =
"\n Usage: vlvcntl <host name> <port number> <login dn> <password>"
"\n <search base>\n"
"\n Example: vlvcntl acme.com 389 cn=admin,o=acme secret ou=sales,o=acme\n";
int main( int argc, char **argv)
{
int ldapPort;
char *ldapHost, *loginDN, *password, *searchBase;
struct timeval timeOut = {10,0};
LDAP *ld;
int rc;
int version=3;
int err;
unsigned long err1;
char *dn = NULL;
char **values = NULL;
LDAPSortKey **sortkeylist = NULL;
LDAPMessage *searchResult = NULL;
LDAPMessage *entry = NULL;
LDAPControl *serverctrls[3] = {NULL, NULL, NULL};
LDAPControl **resultControls = NULL;
LDAPVLVInfo vlvInfo;
char *sortAttr = "sn";
char *attrs[] = {"givenname","sn", NULL };
int attrsonly = 0;
int isCritical = 1;
char *searchFilter = "(sn=*)";
unsigned long target = 3;
unsigned long before_count = 1;
unsigned long after_count = 2;
unsigned long total_count = 0;
struct berval *pContext = NULL;
#if defined(N_PLAT_NLM) && defined(LIBC)
setscreenmode(SCR_NO_MODE);
#endif
if (argc != 6)
{
printf("%s", usage);
return ( 1 );
}
ldapHost = argv[1];
ldapPort = atoi(argv[2]);
loginDN = argv[3];
password = argv[4];
searchBase = argv[5];
ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version);
ldap_set_option( NULL, LDAP_OPT_NETWORK_TIMEOUT, &timeOut);
ld = ldap_init( ldapHost, ldapPort );
if (NULL == ld)
{
printf( "\n\tLDAP session initialization failed\n");
return ( 1 );
}
if (!isVLVSupported(ld))
{
printf("\nVirtual List View Control is not supported by the LDAP Server.\n");
ldap_unbind_s(ld);
return ( 1 );
}
printf("\nSort key: %s\n", sortAttr);
printf("Target index: %d\nBefore count: %d\nAfter count: %d\n",
target, before_count, after_count);
printf("Client's total_count estimate: %d\n", total_count);
printf("\nVirtual List View Control is supported by the LDAP Server ... \n");
rc = ldap_simple_bind_s( ld, loginDN, password );
if (LDAP_SUCCESS != rc)
{
printf("\n\tldap_simple_bind_s: %s\n", ldap_err2string(rc));
return ( rc );
}
rc = ldap_create_sort_keylist(&sortkeylist, sortAttr);
if (LDAP_SUCCESS != rc)
{
printf("\n\tldap_create_sort_keylist: %s\n", ldap_err2string(rc));
goto cleanup;
}
rc = ldap_create_sort_control(
ld,
sortkeylist,
isCritical,
&serverctrls[0]);
if (LDAP_SUCCESS != rc)
{
printf("\n\tldap_create_sort_control: %s\n",ldap_err2string(rc));
goto cleanup;
}
vlvInfo.ldvlv_version = 1;
vlvInfo.ldvlv_attrvalue = NULL;
vlvInfo.ldvlv_offset = target;
vlvInfo.ldvlv_before_count = before_count;
vlvInfo.ldvlv_after_count = after_count;
vlvInfo.ldvlv_count = total_count;
vlvInfo.ldvlv_context = pContext;
vlvInfo.ldvlv_extradata = NULL;
rc = ldap_create_vlv_control(
ld,
&vlvInfo,
&serverctrls[1]);
if (LDAP_SUCCESS != rc)
{
printf("\n\tldap_create_vlv_control: %s\n",ldap_err2string(rc));
goto cleanup;
}
printf("\nPerforming search with sort and VLV controls...\n");
rc = ldap_search_ext_s(
ld,
searchBase,
LDAP_SCOPE_ONELEVEL,
searchFilter,
attrs,
attrsonly,
serverctrls,
NULL,
&timeOut,
LDAP_NO_LIMIT,
&searchResult);
if (LDAP_SUCCESS != rc)
{
printf("\n\tldap_search_ext_s: %s\n", ldap_err2string(rc));
goto cleanup;
}
rc = ldap_parse_result(
ld,
searchResult,
&err,
NULL,
NULL,
NULL,
&resultControls,
0);
if (LDAP_SUCCESS != rc)
{
printf("\n\tldap_parse_result: %s\n", ldap_err2string(rc));
goto cleanup;
}
rc = ldap_parse_sort_control(
ld,
resultControls,
&err1,
NULL);
if (LDAP_SUCCESS != rc)
{
printf("\n\tldap_parse_sort_control: %s\n", ldap_err2string(rc));
goto cleanup;
}
if (err)
printf("*** Sort control error: %s\n\n", ldap_err2string((int)err1));
rc = ldap_parse_vlv_control(
ld,
resultControls,
&target,
&total_count,
&pContext,
&err);
if (LDAP_SUCCESS != rc)
{
printf("\n\tldap_parse_vlv_control: %s\n", ldap_err2string(rc));
goto cleanup;
}
if (err)
printf("*** VLV control error: %s\n\n", ldap_err2string(err));
else
{
printf("\nParse VLV control results:\n");
printf(" Server's target index: %d\n", target);
printf(" Server's total count: %d\n\n", total_count);
}
printf("Entry <dn>: <sn>, <given name>\n\n");
for ( entry = ldap_first_entry( ld, searchResult );
entry != NULL;
entry = ldap_next_entry( ld, entry ) )
{
dn = ldap_get_dn( ld, entry );
if (dn)
{
printf("Object %s:\t",dn);
ldap_memfree(dn);
}
if ((values = ldap_get_values( ld, entry, "sn")) != NULL )
{
if ( values[0] != NULL )
printf("%s, ", values[0] );
ldap_value_free( values );
}
if ((values = ldap_get_values( ld, entry, "givenname")) != NULL )
{
if ( values[0] != NULL )
printf("%s", values[0] );
ldap_value_free( values );
}
printf("\n" );
}
cleanup:
ber_bvfree( pContext );
ldap_msgfree( searchResult );
ldap_control_free( serverctrls[0] );
ldap_control_free( serverctrls[1] );
ldap_controls_free( resultControls );
ldap_free_sort_keylist( sortkeylist );
ldap_unbind_s( ld );
return( rc );
}
int isVLVSupported(LDAP *ld)
{
int i, rc = LDAP_SUCCESS;
char *attribute = NULL;
char **values = NULL;
BerElement *ber = NULL;
LDAPMessage *searchResult = NULL;
LDAPMessage *entry = NULL;
char *attribs[] = {"supportedControl",NULL};
rc = ldap_search_ext_s(ld, "" , LDAP_SCOPE_BASE, "(objectClass=*)",
attribs, 0, NULL, NULL, NULL,
LDAP_NO_LIMIT, &searchResult);
if( LDAP_SUCCESS != rc)
{
printf("ldap_search_ext_s: %s\n", ldap_err2string( rc ));
ldap_msgfree( searchResult );
ldap_unbind_s( ld );
return ( 0 );
}
entry = ldap_first_entry( ld, searchResult );
attribute = ldap_first_attribute( ld, entry, &ber );
if (attribute == NULL)
{
printf("ldap_first_attribute returned no results.\n");
ldap_msgfree( searchResult );
ldap_unbind_s( ld );
return ( 0 );
}
if (( values = ldap_get_values( ld, entry, attribute)) != NULL )
{
for ( i = 0; values[i] != NULL; i++ )
if (strcmp(values[i], "2.16.840.1.113730.3.4.9") == 0)
{
rc = 1;
break;
}
ldap_value_free( values );
}
ldap_memfree( attribute );
ldap_msgfree( searchResult );
ber_free(ber, 0);
return rc;
}