Oracle Internet Directory Application Developer's Guide Release 2.1.1 Part Number A86082-01 |
|
This chapter introduces the Oracle Internet Directory C API and provides examples of how to use it. It contains these topics:
The Oracle Internet Directory SDK C API Release 2.1.1 is based on:
Oracle Internet Directory SDK C API Release 2.1.1 supports the following modes:
To use the SSL mode, you must use the Oracle SSL call interface. You determine which mode you are using by the presence or absence of the SSL calls in the API usage. You can easily switch between SSL and non-SSL modes.
This section contains these topics:
Oracle SSL extensions to the LDAP API are based on standard SSL protocol. The SSL extensions provide encryption and decryption of data over the wire, and authentication.
There are three modes of authentication:
The type of authentication is indicated by a parameter in the SSL interface call.
There is only one call required to enable SSL:
int ldap_init_SSL(Sockbuf *sb, text *sslwallet, text *sslwalletpasswd, int sslauthmode)
The ldap_init_SSL call performs the necessary handshake between client and server using the standard SSL protocol. If the call is successful, all subsequent communication happens over a secure connection.
To use the SSL feature, both the server and the client may require wallets, depending on which authentication mode is being used. Release 2.1.1 of the API supports only Oracle Wallet. You can create wallets using Oracle Wallet Manager.
This section lists all the calls available in the LDAP C API found in RFC 1823.
This section contains these topics:
ldap_open() |
Open a connection to an LDAP server |
ldap_unbind() |
End an LDAP session |
ldap_bind_s() |
General authentication to an LDAP server |
ldap_simple_bind_s() |
Simple authentication to an LDAP server |
ldap_get_dn() |
Get the distinguished name for an entry |
ldap_explode_dn() |
Split up a distinguished name into its components |
ldap_dn2ufn() |
Converts the name into a more user friendly format |
ldap_result2error() |
Returns the error code from result message. |
ldap_err2string() |
Get the error message for a specific error code |
ldap_perror |
Prints the message supplied in message. |
The following examples show how to use the API both with and without SSL. More complete examples are given in RFC 1823. The sample code for the command line tool to perform LDAP search also demonstrates usage of the API in two modes.
This section contains these topics:
#include <stdio.h> #include <string.h> #include <ctype.h> #include <netdb.h> #include <gsle.h> #include <gslc.h> #include <gsld.h> #include "gslcc.h" main() {LDAP *ld; int ret = 0; .... /* open a connection */ if ( (ld = ldap_open( "MyHost", 636 )) == NULL ) exit( 1 ); /* SSL initialization */ ret = ldap_init_SSL(&ld->ld_sb, "file:/sslwallet", "welcome", GSLC_SSL_ONEWAY_AUTH ); if(ret != 0) {printf(" %s \n", ldap_err2string(ret)); exit(1);} /* authenticate as nobody */ if ( ldap_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_bind_s" ); exit( 1 ); }..... .....}
Because the user is making the ldap_init_SSL
call, the client-to-sever communication in the above example is secured by using SSL.
#include <stdio.h> #include <string.h> #include <ctype.h> #include <netdb.h> #include <gsle.h> #include <gslc.h> #include <gsld.h> #include "gslcc.h" main() {LDAP *ld; int ret = 0; .... /* open a connection */ if ( (ld = ldap_open( "MyHost", LDAP_PORT )) == NULL ) exit( 1 ); /* authenticate as nobody */ if ( ldap_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_bind_s" ); exit( 1 ); } ..... .....}
In the previous example, the user is not making the ldap_init_SSL
call, and the client-to-server communication is therefore not secure.
This section contains these topics:
To build applications with the C API, you need:
The Oracle Internet Directory SDK Release 2.1.1 provides a sample command line tool, samplesearch, for demonstrating how to use the C API to build applications. You can use samplesearch to perform LDAP searches in either SSL or non-SSL mode.
You can find the source file (samplesearch.c
) and the make file (demo_ldap.mk
) in the following directory: ORACLE_HOME/ldap/demo
.
To build the sample search tool, enter the following command:
make -f demo_ldap.mk build EXE=samplesearch OBJS=samplesearch.o
The sample code for ldapsearch is:
/* NAME s0gsldsearch.c - <one-line expansion of the name> DESCRIPTION <short description of component this file declares/defines> PUBLIC FUNCTION(S) <list of external functions declared/defined - with one-line descriptions> PRIVATE FUNCTION(S) <list of static functions defined in .c file - with one-line descriptions> RETURNS <function return values, for .c file with single function> NOTES <other useful comments, qualifications, etc.> */ #include <stdio.h> #include <string.h> #include <ctype.h> #include <netdb.h> #include "ldap.h" #define DEFSEP "=" #define LDAPSEARCH_BINDDN NULL #define LDAPSEARCH_BASE DEFAULT_BASE #define DEFAULT_BASE "o=oracle, c=US" #ifdef LDAP_DEBUG extern int ldap_debug, lber_debug; #endif /* LDAP_DEBUG */ usage( s ) char *s; { fprintf( stderr, "usage: %s [options] filter [attributes...]\nwhere:\n", s ); fprintf( stderr, " filter\tRFC-1558 compliant LDAP search filter\n" ); fprintf( stderr, " attributes\twhitespace-separated list of attributes to retrieve\n" ); fprintf( stderr, "\t\t(if no attribute list is given, all are retrieved)\n" ); fprintf( stderr, "options:\n" ); fprintf( stderr, " -n\t\tshow what would be done but don't actually search\n" ); fprintf( stderr, " -v\t\trun in verbose mode (diagnostics to standard output)\n" ); fprintf( stderr, " -t\t\twrite values to files in /tmp\n" ); fprintf( stderr, " -u\t\tinclude User Friendly entry names in the output\n" ); fprintf( stderr, " -A\t\tretrieve attribute names only (no values)\n" ); fprintf( stderr, " -B\t\tdo not suppress printing of non-ASCII values\n" ); fprintf( stderr, " -L\t\tprint entries in LDIF format (-B is implied)\n" ); #ifdef LDAP_REFERRALS fprintf( stderr, " -R\t\tdo not automatically follow referrals\n" ); #endif /* LDAP_REFERRALS */ fprintf( stderr, " -d level\tset LDAP debugging level to `level'\n" ); fprintf( stderr, " -F sep\tprint `sep' instead of `=' between attribute names and values\n" ); fprintf( stderr, " -S attr\tsort the results by attribute `attr'\n" ); fprintf( stderr, " -f file\tperform sequence of searches listed in `file'\n" ); fprintf( stderr, " -b basedn\tbase dn for search\n" ); fprintf( stderr, " -s scope\tone of base, one, or sub (search scope)\n" ); fprintf( stderr, " -a deref\tone of never, always, search, or find (alias dereferencing)\n" ); fprintf( stderr, " -l time lim\ttime limit (in seconds) for search\n" ); fprintf( stderr, " -z size lim\tsize limit (in entries) for search\n" ); fprintf( stderr, " -D binddn\tbind dn\n" ); fprintf( stderr, " -w passwd\tbind passwd (for simple authentication)\n" ); #ifdef KERBEROS fprintf( stderr, " -k\t\tuse Kerberos instead of Simple Password authentication\n" ); #endif fprintf( stderr, " -h host\tldap server\n" ); fprintf( stderr, " -p port\tport on ldap server\n" ); fprintf( stderr, " -W Wallet\tWallet location\n" ); fprintf( stderr, " -P Wpasswd\tWallet Password\n" ); fprintf( stderr, " -U SSLAuth\tSSL Authentication Mode\n" ); return; } static char *binddn = LDAPSEARCH_BINDDN; static char *passwd = NULL; static char *base = LDAPSEARCH_BASE; static char *ldaphost = NULL; static int ldapport = LDAP_PORT; static char *sep = DEFSEP; static char *sortattr = NULL; static int skipsortattr = 0; static int verbose, not, includeufn, allow_binary, vals2tmp, ldif; /* TEMP */ main( argc, argv ) int argc; char **argv; { char *infile, *filtpattern, **attrs, line[ BUFSIZ ]; FILE *fp; int rc, i, first, scope, kerberos, deref, attrsonly; int ldap_options, timelimit, sizelimit, authmethod; LDAP *ld; extern char *optarg; extern int optind; char localHostName[MAXHOSTNAMELEN + 1]; char *sslwrl = NULL; char *sslpasswd = NULL; int sslauth=0,err=0; infile = NULL; deref = verbose = allow_binary = not = kerberos = vals2tmp = attrsonly = ldif = 0; #ifdef LDAP_REFERRALS ldap_options = LDAP_OPT_REFERRALS; #else /* LDAP_REFERRALS */ ldap_options = 0; #endif /* LDAP_REFERRALS */ sizelimit = timelimit = 0; scope = LDAP_SCOPE_SUBTREE; while (( i = getopt( argc, argv, #ifdef KERBEROS "KknuvtRABLD:s:f:h:b:d:p:F:a:w:l:z:S:" #else "nuvtRABLD:s:f:h:b:d:p:F:a:w:l:z:S:W:P:U:" #endif )) != EOF ) { switch( i ) { case 'n': /* do Not do any searches */ ++not; break; case 'v': /* verbose mode */ ++verbose; break; case 'd': #ifdef LDAP_DEBUG ldap_debug = lber_debug = atoi( optarg ); /* */ #else /* LDAP_DEBUG */ fprintf( stderr, "compile with -DLDAP_DEBUG for debugging\n" ); #endif /* LDAP_DEBUG */ break; #ifdef KERBEROS case 'k': /* use kerberos bind */ kerberos = 2; break; case 'K': /* use kerberos bind, 1st part only */ kerberos = 1; break; #endif case 'u': /* include UFN */ ++includeufn; break; case 't': /* write attribute values to /tmp files */ ++vals2tmp; break; case 'R': /* don't automatically chase referrals */ #ifdef LDAP_REFERRALS ldap_options &= ~LDAP_OPT_REFERRALS; #else /* LDAP_REFERRALS */ fprintf( stderr, "compile with -DLDAP_REFERRALS for referral support\n" ); #endif /* LDAP_REFERRALS */ break; case 'A': /* retrieve attribute names only -- no values */ ++attrsonly; break; case 'L': /* print entries in LDIF format */ ++ldif; /* fall through -- always allow binary when outputting LDIF */ case 'B': /* allow binary values to be printed */ ++allow_binary; break; case 's': /* search scope */ if ( strncasecmp( optarg, "base", 4 ) == 0 ) { scope = LDAP_SCOPE_BASE; } else if ( strncasecmp( optarg, "one", 3 ) == 0 ) { scope = LDAP_SCOPE_ONELEVEL; } else if ( strncasecmp( optarg, "sub", 3 ) == 0 ) { scope = LDAP_SCOPE_SUBTREE; } else { fprintf( stderr, "scope should be base, one, or sub\n" ); usage( argv[ 0 ] ); exit(1); } break; case 'a': /* set alias deref option */ if ( strncasecmp( optarg, "never", 5 ) == 0 ) { deref = LDAP_DEREF_NEVER; } else if ( strncasecmp( optarg, "search", 5 ) == 0 ) { deref = LDAP_DEREF_SEARCHING; } else if ( strncasecmp( optarg, "find", 4 ) == 0 ) { deref = LDAP_DEREF_FINDING; } else if ( strncasecmp( optarg, "always", 6 ) == 0 ) { deref = LDAP_DEREF_ALWAYS; } else { fprintf( stderr, "alias deref should be never, search, find, or always\n" ); usage( argv[ 0 ] ); exit(1); } break; case 'F': /* field separator */ sep = (char *)strdup( optarg ); break; case 'f': /* input file */ infile = (char *)strdup( optarg ); break; case 'h': /* ldap host */ ldaphost = (char *)strdup( optarg ); break; case 'b': /* searchbase */ base = (char *)strdup( optarg ); break; case 'D': /* bind DN */ binddn = (char *)strdup( optarg ); break; case 'p': /* ldap port */ ldapport = atoi( optarg ); break; case 'w': /* bind password */ passwd = (char *)strdup( optarg ); break; case 'l': /* time limit */ timelimit = atoi( optarg ); break; case 'z': /* size limit */ sizelimit = atoi( optarg ); break; case 'S': /* sort attribute */ sortattr = (char *)strdup( optarg ); break; case 'W': /* Wallet URL */ sslwrl = (char *)strdup( optarg ); break; case 'P': /* Wallet password */ sslpasswd = (char *)strdup( optarg ); break; case 'U': /* SSL Authentication Mode */ sslauth = atoi( optarg ); break; default: usage( argv[0] ); exit(1); break; } } if ( argc - optind < 1 ) { usage( argv[ 0 ] ); exit(1); } filtpattern = (char *)strdup( argv[ optind ] ); if ( argv[ optind + 1 ] == NULL ) { attrs = NULL; } else if ( sortattr == NULL || *sortattr == '\0' ) { attrs = &argv[ optind + 1 ]; } else { for ( i = optind + 1; i < argc; i++ ) { if ( strcasecmp( argv[ i ], sortattr ) == 0 ) { break; } } if ( i == argc ) { skipsortattr = 1; argv[ optind ] = sortattr; } else { optind++; } attrs = &argv[ optind ]; } if ( infile != NULL ) { if ( infile[0] == '-' && infile[1] == '\0' ) { fp = stdin; } else if (( fp = fopen( infile, "r" )) == NULL ) { perror( infile ); exit( 1 ); } } if (ldaphost == NULL) { if (gethostname(localHostName, MAXHOSTNAMELEN) != 0) { perror("gethostname"); exit(1); } ldaphost = localHostName; } if ( verbose ) { printf( "ldap_open( %s, %d )\n", ldaphost, ldapport ); } if (( ld = ldap_open( ldaphost, ldapport )) == NULL ) { perror( ldaphost ); exit( 1 ); } if (sslauth > 1) { if (!sslwrl || !sslpasswd) { printf ("Null Wallet or password given\n"); exit (0); } } if (sslauth > 0) { if (sslauth == 1) sslauth = GSLC_SSL_NO_AUTH; else if (sslauth == 2) sslauth = GSLC_SSL_ONEWAY_AUTH; else if (sslauth == 3) sslauth = GSLC_SSL_TWOWAY_AUTH; else { printf(" Wrong SSL Authenication Mode Value\n"); exit(0); } err = ldap_init_SSL(&ld->ld_sb,sslwrl,sslpasswd,sslauth); if(err != 0) { printf(" %s\n", ldap_err2string(err)); exit(0); } } ld->ld_deref = deref; ld->ld_timelimit = timelimit; ld->ld_sizelimit = sizelimit; ld->ld_options = ldap_options; if ( !kerberos ) { authmethod = LDAP_AUTH_SIMPLE; } else if ( kerberos == 1 ) { authmethod = LDAP_AUTH_KRBV41; } else { authmethod = LDAP_AUTH_KRBV4; } if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_bind" ); exit( 1 ); } if ( verbose ) { printf( "filter pattern: %s\nreturning: ", filtpattern ); if ( attrs == NULL ) { printf( "ALL" ); } else { for ( i = 0; attrs[ i ] != NULL; ++i ) { printf( "%s ", attrs[ i ] ); } } putchar( '\n' ); } if ( infile == NULL ) { rc = dosearch( ld, base, scope, attrs, attrsonly, filtpattern, "" ); } else { rc = 0; first = 1; while ( rc == 0 && fgets( line, sizeof( line ), fp ) != NULL ) { line[ strlen( line ) - 1 ] = '\0'; if ( !first ) { putchar( '\n' ); } else { first = 0; } rc = dosearch( ld, base, scope, attrs, attrsonly, filtpattern, line ); } if ( fp != stdin ) { fclose( fp ); } } ldap_unbind( ld ); exit( rc ); } dosearch( ld, base, scope, attrs, attrsonly, filtpatt, value ) LDAP *ld; char *base; int scope; char **attrs; int attrsonly; char *filtpatt; char *value; { char filter[ BUFSIZ ], **val; int rc, first, matches; LDAPMessage *res, *e; sprintf( filter, filtpatt, value ); if ( verbose ) { printf( "filter is: (%s)\n", filter ); } if ( not ) { return( LDAP_SUCCESS ); } if ( ldap_search( ld, base, scope, filter, attrs, attrsonly ) == -1 ) { ldap_perror( ld, "ldap_search" ); return( ld->ld_errno ); } matches = 0; first = 1; while ( (rc = ldap_result( ld, LDAP_RES_ANY, sortattr ? 1 : 0, NULL, &res )) == LDAP_RES_SEARCH_ENTRY ) { matches++; e = ldap_first_entry( ld, res ); if ( !first ) { putchar( '\n' ); } else { first = 0; } print_entry( ld, e, attrsonly ); ldap_msgfree( res ); } if ( rc == -1 ) { ldap_perror( ld, "ldap_result" ); return( rc ); } if (( rc = ldap_result2error( ld, res, 0 )) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_search" ); } if ( sortattr != NULL ) { extern int strcasecmp(); (void) ldap_sort_entries( ld, &res, ( *sortattr == '\0' ) ? NULL : sortattr, strcasecmp ); matches = 0; first = 1; for ( e = ldap_first_entry( ld, res ); e != NULLMSG; e = ldap_next_entry( ld, e ) ) { matches++; if ( !first ) { putchar( '\n' ); } else { first = 0; } print_entry( ld, e, attrsonly ); } } if ( verbose ) { printf( "%d matches\n", matches ); } ldap_msgfree( res ); return( rc ); } print_entry( ld, entry, attrsonly ) LDAP *ld; LDAPMessage *entry; int attrsonly; { char *a, *dn, *ufn, tmpfname[ 64 ]; int i, j, notascii; BerElement *ber; struct berval **bvals; FILE *tmpfp; extern char *mktemp(); dn = ldap_get_dn( ld, entry ); if ( ldif ) { write_ldif_value( "dn", dn, strlen( dn )); } else { printf( "%s\n", dn ); } if ( includeufn ) { ufn = ldap_dn2ufn( dn ); if ( ldif ) { write_ldif_value( "ufn", ufn, strlen( ufn )); } else { printf( "%s\n", ufn ); } free( ufn ); } free( dn ); for ( a = ldap_first_attribute( ld, entry, &ber ); a != NULL; a = ldap_next_attribute( ld, entry, ber ) ) { if ( skipsortattr && strcasecmp( a, sortattr ) == 0 ) { continue; } if ( attrsonly ) { if ( ldif ) { write_ldif_value( a, "", 0 ); } else { printf( "%s\n", a ); } } else if (( bvals = ldap_get_values_len( ld, entry, a )) != NULL ) { for ( i = 0; bvals[i] != NULL; i++ ) { if ( vals2tmp ) { sprintf( tmpfname, "/tmp/ldapsearch-%s-XXXXXX", a ); tmpfp = NULL; if ( mktemp( tmpfname ) == NULL ) { perror( tmpfname ); } else if (( tmpfp = fopen( tmpfname, "w")) == NULL ) { perror( tmpfname ); } else if ( fwrite( bvals[ i ]->bv_val, bvals[ i ]->bv_len, 1, tmpfp ) == 0 ) { perror( tmpfname ); } else if ( ldif ) { write_ldif_value( a, tmpfname, strlen( tmpfname )); } else { printf( "%s%s%s\n", a, sep, tmpfname ); } if ( tmpfp != NULL ) { fclose( tmpfp ); } } else { notascii = 0; if ( !allow_binary ) { for ( j = 0; j < bvals[ i ]->bv_len; ++j ) { if ( !isascii( bvals[ i ]->bv_val[ j ] )) { notascii = 1; break; } } } if ( ldif ) { write_ldif_value( a, bvals[ i ]->bv_val, bvals[ i ]->bv_len ); } else { printf( "%s%s%s\n", a, sep, notascii ? "NOT ASCII" : (char *)bvals[ i ]->bv_val ); } } } gsledePBerBvecfree( bvals ); } } } int write_ldif_value( char *type, char *value, unsigned long vallen ) { char *ldif; if (( ldif = gsldlDLdifTypeAndValue( type, value, (int)vallen )) == NULL ) { return( -1 ); } fputs( ldif, stdout ); free( ldif ); return( 0 ); }
This API can work against any release of Oracle Internet Directory server or a third party LDAP server.
To use the different authentication modes in SSL, the directory server requires corresponding configuration settings.
Oracle Wallet Manager is required for creating wallets if you are using the C API in SSL mode.
TCP/IP Socket Library is required.
The following Oracle libraries are required:
Sample libraries are included in the release for the sample command line tool. You should replace these libraries with your own versions of the libraries.
The product supports only those authentication mechanisms described in LDAP SDK specifications (RFC 1823).
|
![]() Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
|