/* Netprog 2000 */ /* Sample LDAP client based on the code in RFC 1823 - LDAP API This example uses asynchronous calls, see client for an example that uses synchronous LDAP requests */ #include #include /* the encoding library */ #include /* the LDAP library */ #include #include /* for sleep() */ /* The name of the server is hard-coded here! In general we would want this to be specified on the command line, or in a config file somewhere! */ char *serverhost = "monte.cs.rpi.edu"; int main(void) { LDAP *ld; /* ldap connection handle */ LDAPMessage *res, *e; /* point to LDAP messages */ int i; char *a, *dn; void *ptr; char **vals; int msgid; /* used to hold the message ID (query ID) */ int status; /* used when calling ldap_result */ /* open a connection to the LDAP server running on the default LDAP port on the machine serverhost */ if ( (ld = ldap_open( serverhost, LDAP_PORT )) == NULL ) { printf("Problem opening LDAP connection to %s\n",serverhost); exit( 1 ); } /* authenticate as nobody and do so synchronously */ if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) { /* ldap_perror is like perror, but uses the ldap_errno */ ldap_perror( ld, "ldap_simple_bind_s" ); exit( 1 ); } /* search for all records that have the substring "ho" as part of the cn attribute (cn is "common name" - used to hold a person's name) parameters are: ld - the ldap connection handle the base is hard-coded to "course=Network Programming, school=RPI" this works only with the demo server running for netpworg 2000! the scope is LDAP_SCOPE_SUBTREE - means the server should search everything below the base of the search the search filter is "(cn=*ho*)" attrs is NULL - this means we are not specifying what attributes we want to get - so we get them all. We could include a null terminated array of char * pointing to attribute names, and only get those attributes returned by the server. attrsonly flag is set to 0, this means we get both the attribute names and values from the server (if set to 1 we only get the attribute names). This will be an asynchronous search, and we will establish some limits before starting the search. We set a time limit and a maximum number of records limit by altering the ldap connection handle structure built by ldap_bind */ ld->ld_sizelimit = 10; /* limit result to first 10 records found */ ld->ld_timelimit = 1; /* limit the search to 1 second */ if ( (msgid = ldap_search( ld, "course=Network Programming, school=RPI", LDAP_SCOPE_SUBTREE, "(cn=*ho*)", NULL, 0 )) == -1) { ldap_perror( ld, "ldap_search" ); exit( 1 ); } /* The query is now running on the server - we hang out a while and then go try to retrieve it (presumably we would have something better to do here in a real application!) */ printf("Query sent - message id is %d\n",msgid); sleep(2); /* OK - now go see if our request is done */ /* parameter are: ld - ldap connection handle msgid - ldap message id associated with our search 1 - all flag that says don't give us partial results - wait until all results are ready (all matching records). NULL is the timeout - NULL means block until the result is ready &res - the address of a pointer in which the result should be placed */ status = ldap_result(ld,msgid,1,NULL,&res) ; /* make sure we got the result of our search */ if (status != LDAP_RES_SEARCH_RESULT) { printf("Got unexpected status back from ldap_result: %d\n",status); exit(1); } /* The search has worked - now we go through the result and print out the stuff returned in res. /* step through each entry returned */ for ( e = ldap_first_entry( ld, res ); e != NULL; e = ldap_next_entry( ld, e ) ) { /* e is a pointer to an ldap message that holds one record that matched our search filter */ /* print the distinguished name associated with the record */ dn = ldap_get_dn( ld, e ); printf( "dn: %s\n", dn ); /* ldap_get_dn creates a copy for us - we need to free it */ free( dn ); /* Print the name each attribute in this record */ /* Some implementations want the third parameter to be of type **BerElement instead of **void -so the compiler may complain here. You can ignore the warning... */ for ( a = ldap_first_attribute( ld, e, &ptr ); a != NULL; a = ldap_next_attribute( ld, e, ptr ) ) { printf( " attribute: %s: ", a ); /* and print all the values (there can be multiple values for each attribute ) */ vals = ldap_get_values( ld, e, a ); for ( i = 0; vals[i] != NULL; i++ ) { printf( "%s ", vals[i] ); } printf("\n"); /* vals was a copy of the values - must free it! */ ldap_value_free( vals ); } printf("\n\n"); } /* free the search results */ ldap_msgfree( res ); /* close and free connection resources */ ldap_unbind( ld ); return(0); }