#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ldap.h>
#if defined(N_PLAT_NLM) && defined(LIBC)
#include <screen.h>
#endif
static char *
getChangeTypeString(
int changeType);
static char usage[] =
"\n Usage: searchPersist <host name> <port number> <login dn> <password>"
"\n <search base>\n"
"\n Example: searchPersist Acme.com 389 cn=admin,o=Acme secret"
"\n ou=Sales,o=Acme\n";
#define EXECUTE_TIME 300
int main( int argc, char **argv )
{
int version, ldapPort, rc;
int msgid;
char *ldapHost, *loginDN, *password, *searchBase;
char *dn ;
LDAP *ld;
struct timeval timeOut = {10,0};
LDAPMessage *result, *entry;
LDAPControl *controls[2], *psControl, **ecControls;
int finished, errorCode;
time_t startTime;
char *attrs[2];
char *errorMsg;
#if defined(N_PLAT_NLM) && defined(LIBC)
setscreenmode(SCR_NO_MODE);
#endif
startTime = time(NULL);
if (argc != 6)
{
printf("%s", usage);
return (1);
}
ldapHost = argv[1];
ldapPort = atoi(argv[2]);
loginDN = argv[3];
password = argv[4];
searchBase = argv[5];
version = LDAP_VERSION3;
ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version);
ldap_set_option( NULL, LDAP_OPT_NETWORK_TIMEOUT, &timeOut);
if (( ld = ldap_init( ldapHost, ldapPort )) == NULL)
{
printf ( "\n LDAP session initialization failed\n");
return( 1 );
}
printf ( "\n LDAP session initialized\n");
rc = ldap_simple_bind_s( ld, loginDN, password );
if (rc != LDAP_SUCCESS )
{
printf("ldap_simple_bind_s: %s\n", ldap_err2string( rc ));
ldap_unbind( ld );
return( 1 );
}
printf("\n Bind successful\n");
rc = ldap_create_persistentsearch_control(
ld,
LDAP_CHANGETYPE_ANY,
1,
1,
1,
&psControl );
if (rc != LDAP_SUCCESS)
{
printf("ldap_create_persistentsearch_control: %s\n",
ldap_err2string( rc ));
ldap_unbind( ld );
return( 1 );
}
controls[0] = psControl;
controls[1] = NULL;
attrs[0] = LDAP_NO_ATTRS;
attrs[1] = NULL;
rc = ldap_search_ext(
ld,
searchBase,
LDAP_SCOPE_SUBTREE,
"(objectclass=*)",
attrs,
0,
controls,
NULL,
NULL,
LDAP_NO_LIMIT,
&msgid );
ldap_control_free( psControl );
if ( rc != LDAP_SUCCESS )
{
printf("ldap_search_ext: %s\n", ldap_err2string( rc ));
ldap_unbind_s( ld );
return ( 1 );
}
timeOut.tv_sec = 0L;
timeOut.tv_usec = 0L;
printf("Monitoring directory changes for %d minutes.\n", EXECUTE_TIME/60);
finished = 0;
while ( 0 == finished )
{
result = NULL;
rc = ldap_result( ld, msgid, LDAP_MSG_ONE, &timeOut, &result );
switch ( rc )
{
case -1:
ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &errorCode);
printf("ldap_result: %s\n", ldap_err2string( errorCode ));
if ( result != NULL )
ldap_msgfree( result );
finished = 1;
break;
case 0:
if ( result != NULL )
ldap_msgfree( result );
break;
case LDAP_RES_SEARCH_ENTRY:
if (( entry = ldap_first_entry( ld, result )) == NULL )
{
if ( result != NULL )
ldap_msgfree( result );
continue;
}
printf( "\n" );
if (( dn = ldap_get_dn( ld, entry )) != NULL )
{
printf("dn: %s\n", dn );
ldap_memfree( dn );
}
if ( LDAP_SUCCESS ==
ldap_get_entry_controls( ld, entry, &ecControls ))
{
int chgtype, chgnumpresent;
long chgnum;
char *prevdn;
if ( LDAP_SUCCESS == ldap_parse_entrychange_control( ld,
ecControls, &chgtype, &prevdn, &chgnumpresent, &chgnum ))
{
printf("changeType: %s\n",
getChangeTypeString( chgtype ));
if ( prevdn != NULL )
{
printf("previousDN: %s\n", prevdn );
ldap_memfree( prevdn );
}
if ( chgnumpresent )
{
printf("changeNumber: %d\n", chgnum );
}
ldap_controls_free( ecControls );
}
}
if (NULL != result)
ldap_msgfree( result );
break;
case LDAP_RES_SEARCH_RESULT:
errorMsg = NULL;
rc = ldap_parse_result(ld,
result,
&errorCode,
NULL,
&errorMsg,
NULL,
NULL,
1);
if (rc != LDAP_SUCCESS)
{
printf("Error parsing result: %d\n", rc);
}
else if (errorCode != LDAP_SUCCESS)
{
printf("Search result error: %d\n", errorCode);
if (NULL != errorMsg)
{
ldap_memfree( errorMsg );
printf("Server Message: %s\n", errorMsg);
}
finished = 1;
}
break;
default:
break;
}
if ( (time(NULL) - startTime) > EXECUTE_TIME )
{
finished = 1;
rc = ldap_abandon(ld, msgid);
if (LDAP_SUCCESS == rc)
printf("\nSearch operation successfully abandoned.\n");
else
printf("\nldap_abandon: %s\n", ldap_err2string(rc));
}
}
ldap_unbind( ld );
return( 0 );
}
static char *
getChangeTypeString(
int changeType)
{
static char buffer[30];
if (LDAP_CHANGETYPE_ADD == changeType)
sprintf( buffer, "%s", "Entry Added" );
else if (LDAP_CHANGETYPE_DELETE == changeType)
sprintf( buffer, "%s", "Entry Deleted" );
else if (LDAP_CHANGETYPE_MODIFY == changeType)
sprintf( buffer, "%s", "Attribute Modified" );
else if (LDAP_CHANGETYPE_MODDN == changeType)
sprintf( buffer, "%s", "DN Changed" );
else
sprintf( buffer, "Change type '%d' unknown.", changeType );
return buffer;
}