X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=clients%2Ftools%2Fldapsearch.c;h=b1d5879a448f4d5d1e96ed0674be8e15413455d1;hb=49f414738569096eae2c94a4f05f0f3f2636b8b7;hp=d28c9a3b2de5cab7d01b62f6c39e7c6b1cdec66a;hpb=6b4aac2678ec5998e6d6ba0d44fc09ed595763d6;p=openldap diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c index d28c9a3b2d..b1d5879a44 100644 --- a/clients/tools/ldapsearch.c +++ b/clients/tools/ldapsearch.c @@ -1,8 +1,9 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ + #include "portable.h" #include @@ -13,7 +14,15 @@ #include #include #include +#include +#include +#ifdef HAVE_FCNTL_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif #ifdef HAVE_IO_H #include #endif @@ -23,8 +32,6 @@ #include "ldif.h" #include "ldap_defaults.h" -#define DEFSEP "=" - static void usage( const char *s ) { @@ -37,43 +44,62 @@ usage( const char *s ) "\t\t+ -- all operational attributes\n" "\t\tempty list -- all non-operational attributes\n" "options:\n" -" -n\t\tshow what would be done but don't actually search\n" -" -v\t\trun in verbose mode (diagnostics to standard output)\n" -" -t\t\twrite binary values to files in TMPDIR\n" -" -tt\t\twrite all values to files in TMPDIR\n" -" -T path\twrite files to directory specified by path (default: \"/tmp\")\n" -" -V prefix\tURL prefix for files (default: \"file://tmp/\"\n" -" -u\t\tinclude User Friendly entry names in the output\n" +" -a deref\tone of `never', `always', `search', or `find' (alias\n" +" \tdereferencing)\n" " -A\t\tretrieve attribute names only (no values)\n" -" -B\t\tdo not suppress printing of binary values\n" -" -F sep\tprint `sep' instead of `=' between attribute names and values\n" -" -L\t\tprint entries in LDIF format (implies -B)\n" +" -b basedn\tbase dn for search\n" +" -d level\tset LDAP debugging level to `level'\n" +" -D binddn\tbind DN\n" +" -E\t\trequest SASL privacy (-EE to make it critical)\n" +" -f file\t\tperform sequence of searches listed in `file'\n" +" -h host\t\tLDAP server\n" +" -I\t\trequest SASL integrity checking (-II to make it\n" +" \tcritical)\n" +" -k\t\tuse Kerberos authentication\n" +" -K\t\tlike -k, but do only step 1 of the Kerberos bind\n" +" -l limit\ttime limit (in seconds) for search\n" +" -L\t\tprint entries in LDIF format (default)\n" " -LL\t\tprint entries in LDIF format without comments\n" -" -LLL\t\tprint entries in LDIF format without comments and version\n" +" -LLL\t\tprint entries in LDIF format without comments and\n" +" \tversion\n" " -M\t\tenable Manage DSA IT control (-MM to make critical)\n" +" -n\t\tshow what would be done but don't actually search\n" +" -p port\t\tport on LDAP server\n" +" -P version\tprocotol version (2 or 3)\n" " -R\t\tdo not automatically follow referrals\n" -" -S attr\tsort the results by attribute `attr'\n" -" -d level\tset LDAP debugging level to `level'\n" -" -f file\tperform sequence of searches listed in `file'\n" -" -b basedn\tbase dn for search\n" " -s scope\tone of base, one, or sub (search scope)\n" -" -a deref\tone of never, always, search, or find (alias dereferencing)\n" -" -l limit\ttime limit (in seconds) for search\n" -" -z limit\tsize limit (in entries) for search\n" -" -D binddn\tbind dn\n" +" -S attr\t\tsort the results by attribute `attr'\n" +" -t\t\twrite binary values to files in TMPDIR\n" +" -tt\t\twrite all values to files in TMPDIR\n" +" -T path\t\twrite files to directory specified by path (default:\n" +" \t\"/tmp\")\n" +" -u\t\tinclude User Friendly entry names in the output\n" +" -U user\t\tSASL authentication identity (username)\n" +" -v\t\trun in verbose mode (diagnostics to standard output)\n" +" -V prefix\tURL prefix for files (default: \"file://tmp/\")\n" " -w passwd\tbind passwd (for simple authentication)\n" " -W\t\tprompt for bind passwd\n" -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND -" -k\t\tuse Kerberos instead of Simple Password authentication\n" -#endif -" -h host\tldap server\n" -" -p port\tport on ldap server\n" -" -P version\tprocotol version (2 or 3)\n" +" -X id\t\tSASL authorization identity (\"dn:\" or \"u:\")\n" +" -Y mech\t\tSASL mechanism\n" +" -z limit\tsize limit (in entries) for search\n" +" -Z\t\tissue Start TLS request (-ZZ to require successful response)\n" , s ); exit( EXIT_FAILURE ); } +static void print_extended( + LDAP *ld, + LDAPMessage *extended ); + +static void print_partial( + LDAP *ld, + LDAPMessage *partial ); + +static void print_reference( + LDAP *ld, + LDAPMessage *reference ); + static void print_entry LDAP_P(( LDAP *ld, LDAPMessage *entry, @@ -101,39 +127,49 @@ static char *tmpdir = NULL; static char *urlpre = NULL; static char *binddn = NULL; -static char *passwd = NULL; +static struct berval passwd = { 0, NULL }; static char *base = NULL; static char *ldaphost = NULL; static int ldapport = 0; -static char *sep = DEFSEP; +#ifdef HAVE_CYRUS_SASL +static char *sasl_authc_id = NULL; +static char *sasl_authz_id = NULL; +static char *sasl_mech = NULL; +static int sasl_integrity = 0; +static int sasl_privacy = 0; +#endif +static int use_tls = 0; static char *sortattr = NULL; static int skipsortattr = 0; -static int verbose, not, includeufn, binary, vals2tmp, ldif; +static int verbose, not, includeufn, vals2tmp, ldif; int main( int argc, char **argv ) { char *infile, *filtpattern, **attrs, line[ BUFSIZ ]; - FILE *fp; + FILE *fp = NULL; int rc, i, first, scope, deref, attrsonly, manageDSAit; int referrals, timelimit, sizelimit, debug; int authmethod, version, want_bindpw; LDAP *ld; infile = NULL; - debug = verbose = binary = not = vals2tmp = + debug = verbose = not = vals2tmp = attrsonly = manageDSAit = ldif = want_bindpw = 0; - deref = referrals = sizelimit = timelimit = version = -1; + deref = sizelimit = timelimit = version = -1; + + /* default should be off */ + referrals = 1; scope = LDAP_SCOPE_SUBTREE; authmethod = LDAP_AUTH_SIMPLE; while (( i = getopt( argc, argv, - "WKknuvtMRABLD:s:f:h:b:d:P:p:F:a:w:l:z:S:T:V:")) != EOF ) + "Aa:b:D:d:Ef:h:IKkLl:MnP:p:RS:s:T:tU:uV:vWw:X:Y:Zz:")) != EOF ) { switch( i ) { - case 'n': /* do Not do any searches */ + case 'n': /* do nothing */ ++not; break; case 'v': /* verbose mode */ @@ -146,16 +182,19 @@ main( int argc, char **argv ) #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND authmethod = LDAP_AUTH_KRBV4; #else - fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]); + fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] ); + return( EXIT_FAILURE ); #endif break; case 'K': /* use kerberos bind, 1st part only */ #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND authmethod = LDAP_AUTH_KRBV41; #else - fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]); + fprintf( stderr, "%s was not compiled with Kerberos support\n", argv[0] ); + return( EXIT_FAILURE ); #endif break; + break; case 'u': /* include UFN */ ++includeufn; break; @@ -167,23 +206,21 @@ main( int argc, char **argv ) manageDSAit++; break; case 'R': /* don't automatically chase referrals */ - referrals = (int) LDAP_OPT_OFF; + referrals = 0; 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 */ - ++binary; break; + case 's': /* search scope */ if ( strcasecmp( optarg, "base" ) == 0 ) { scope = LDAP_SCOPE_BASE; - } else if ( strcasecmp( optarg, "one" ) == 0 ) { + } else if ( strncasecmp( optarg, "one", sizeof("one")-1 ) == 0 ) { scope = LDAP_SCOPE_ONELEVEL; - } else if ( strcasecmp( optarg, "sub" ) == 0 ) { + } else if ( strncasecmp( optarg, "sub", sizeof("sub")-1 ) == 0 ) { scope = LDAP_SCOPE_SUBTREE; } else { fprintf( stderr, "scope should be base, one, or sub\n" ); @@ -194,9 +231,9 @@ main( int argc, char **argv ) case 'a': /* set alias deref option */ if ( strcasecmp( optarg, "never" ) == 0 ) { deref = LDAP_DEREF_NEVER; - } else if ( strcasecmp( optarg, "search" ) == 0 ) { + } else if ( strncasecmp( optarg, "search", sizeof("search")-1 ) == 0 ) { deref = LDAP_DEREF_SEARCHING; - } else if ( strcasecmp( optarg, "find" ) == 0 ) { + } else if ( strncasecmp( optarg, "find", sizeof("find")-1 ) == 0 ) { deref = LDAP_DEREF_FINDING; } else if ( strcasecmp( optarg, "always" ) == 0 ) { deref = LDAP_DEREF_ALWAYS; @@ -214,9 +251,6 @@ main( int argc, char **argv ) if( urlpre ) free( urlpre ); urlpre = strdup( optarg ); break; - case 'F': /* field separator */ - sep = strdup( optarg ); - break; case 'f': /* input file */ infile = strdup( optarg ); break; @@ -233,7 +267,7 @@ main( int argc, char **argv ) ldapport = atoi( optarg ); break; case 'w': /* bind password */ - passwd = strdup( optarg ); + passwd.bv_val = strdup( optarg ); { char* p; @@ -241,6 +275,7 @@ main( int argc, char **argv ) *p = '*'; } } + passwd.bv_len = strlen( passwd.bv_val ); break; case 'l': /* time limit */ timelimit = atoi( optarg ); @@ -268,32 +303,107 @@ main( int argc, char **argv ) usage( argv[0] ); } break; + case 'I': +#ifdef HAVE_CYRUS_SASL + sasl_integrity++; + authmethod = LDAP_AUTH_SASL; +#else + fprintf( stderr, "%s was not compiled with SASL support\n", + argv[0] ); + return( EXIT_FAILURE ); +#endif + break; + case 'E': +#ifdef HAVE_CYRUS_SASL + sasl_privacy++; + authmethod = LDAP_AUTH_SASL; +#else + fprintf( stderr, "%s was not compiled with SASL support\n", + argv[0] ); + return( EXIT_FAILURE ); +#endif + break; + case 'Y': +#ifdef HAVE_CYRUS_SASL + if ( strcasecmp( optarg, "any" ) && strcmp( optarg, "*" ) ) { + sasl_mech = strdup( optarg ); + } + authmethod = LDAP_AUTH_SASL; +#else + fprintf( stderr, "%s was not compiled with SASL support\n", + argv[0] ); + return( EXIT_FAILURE ); +#endif + break; + case 'U': +#ifdef HAVE_CYRUS_SASL + sasl_authc_id = strdup( optarg ); + authmethod = LDAP_AUTH_SASL; +#else + fprintf( stderr, "%s was not compiled with SASL support\n", + argv[0] ); + return( EXIT_FAILURE ); +#endif + break; + case 'X': +#ifdef HAVE_CYRUS_SASL + sasl_authz_id = strdup( optarg ); + authmethod = LDAP_AUTH_SASL; +#else + fprintf( stderr, "%s was not compiled with SASL support\n", + argv[0] ); + return( EXIT_FAILURE ); +#endif + break; + case 'Z': +#ifdef HAVE_TLS + use_tls++; +#else + fprintf( stderr, "%s was not compiled with TLS support\n", + argv[0] ); + return( EXIT_FAILURE ); +#endif + break; default: usage( argv[0] ); } } -#ifdef LDAP_LDIF /* no alternative format */ - if( ldif < 1 ) ldif = 1; -#endif + if( ldif == 0 ) ldif = 1; - if( authmethod != LDAP_AUTH_SIMPLE ) { - if( version == LDAP_VERSION3 ) { - fprintf(stderr, "Kerberos requires LDAPv2\n"); - return EXIT_FAILURE; + if ( ( authmethod == LDAP_AUTH_KRBV4 ) || ( authmethod == + LDAP_AUTH_KRBV41 ) ) { + if( version > LDAP_VERSION2 ) { + fprintf( stderr, "Kerberos requires LDAPv2\n" ); + return( EXIT_FAILURE ); } version = LDAP_VERSION2; } + else if ( authmethod == LDAP_AUTH_SASL ) { + if( version != -1 && version != LDAP_VERSION3 ) { + fprintf( stderr, "SASL requires LDAPv3\n" ); + return( EXIT_FAILURE ); + } + version = LDAP_VERSION3; + } if( manageDSAit ) { - if( version == LDAP_VERSION2 ) { + if( version != -1 && version != LDAP_VERSION3 ) { fprintf(stderr, "manage DSA control requires LDAPv3\n"); return EXIT_FAILURE; } version = LDAP_VERSION3; } + if( use_tls ) { + if( version != -1 && version != LDAP_VERSION3 ) { + fprintf(stderr, "Start TLS requires LDAPv3\n"); + return EXIT_FAILURE; + } + version = LDAP_VERSION3; + } + if ( argc - optind < 1 ) { usage( argv[ 0 ] ); } @@ -337,7 +447,7 @@ main( int argc, char **argv ) } if( urlpre == NULL ) { - urlpre = malloc( sizeof("file:///") + strlen(tmpdir) ); + urlpre = malloc( sizeof("file:////") + strlen(tmpdir) ); if( urlpre == NULL ) { perror( "malloc" ); @@ -399,19 +509,75 @@ main( int argc, char **argv ) referrals ? "on" : "off" ); } - if (version != -1 && - ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS ) + if (version == -1 ) { + version = 3; + } + + if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) + != LDAP_OPT_SUCCESS ) { - fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version ); + fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", + version ); } - if (want_bindpw) { - passwd = getpass("Enter LDAP Password: "); + if ( use_tls && ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ) { + if ( use_tls > 1 ) { + ldap_perror( ld, "ldap_start_tls" ); + return( EXIT_FAILURE ); + } } - if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) { - ldap_perror( ld, "ldap_bind" ); + if (want_bindpw) { + passwd.bv_val = getpassphrase("Enter LDAP Password: "); + passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0; + } + + if ( authmethod == LDAP_AUTH_SASL ) { +#ifdef HAVE_CYRUS_SASL + int minssf = 0, maxssf = 0; + + if ( sasl_integrity > 0 ) + maxssf = 1; + if ( sasl_integrity > 1 ) + minssf = 1; + if ( sasl_privacy > 0 ) + maxssf = 100000; /* Something big value */ + if ( sasl_privacy > 1 ) + minssf = 56; + + if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MINSSF, + (void *)&minssf ) != LDAP_OPT_SUCCESS ) { + fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MINSSF" + "%d\n", minssf); + return( EXIT_FAILURE ); + } + if ( ldap_set_option( ld, LDAP_OPT_X_SASL_MAXSSF, + (void *)&maxssf ) != LDAP_OPT_SUCCESS ) { + fprintf( stderr, "Could not set LDAP_OPT_X_SASL_MAXSSF" + "%d\n", maxssf); + return( EXIT_FAILURE ); + } + + rc = ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id, + sasl_authz_id, sasl_mech, + passwd.bv_len ? &passwd : NULL, + NULL, NULL ); + + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_negotiated_sasl_bind_s" ); + return( EXIT_FAILURE ); + } +#else + fprintf( stderr, "%s was not compiled with SASL support\n", + argv[0] ); return( EXIT_FAILURE ); +#endif + } else { + if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod ) + != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_bind" ); + return( EXIT_FAILURE ); + } } if ( manageDSAit ) { @@ -451,25 +617,23 @@ main( int argc, char **argv ) fprintf( stderr, "\n" ); } - if ( ldif ) { - if (ldif < 3 ) { - printf( "version: 1\n\n"); - } + if (ldif < 3 ) { + printf( "version: 2\n\n"); + } - if (ldif < 2 ) { - printf( "#\n# filter%s: %s\n# returning: ", - infile != NULL ? " pattern" : "", - filtpattern ); + if (ldif < 2 ) { + printf( "#\n# filter%s: %s\n# returning: ", + infile != NULL ? " pattern" : "", + filtpattern ); - if ( attrs == NULL ) { - printf( "ALL" ); - } else { - for ( i = 0; attrs[ i ] != NULL; ++i ) { - printf( "%s ", attrs[ i ] ); - } + if ( attrs == NULL ) { + printf( "ALL" ); + } else { + for ( i = 0; attrs[ i ] != NULL; ++i ) { + printf( "%s ", attrs[ i ] ); } - printf( "\n#\n\n" ); } + printf( "\n#\n\n" ); } if ( infile == NULL ) { @@ -508,8 +672,14 @@ static int dosearch( char *value) { char filter[ BUFSIZ ]; - int rc, first, matches; - LDAPMessage *res, *e; + int rc, first; + int nresponses; + int nentries; + int nreferences; + int nextended; + int npartial; + LDAPMessage *res, *msg; + ber_int_t msgid; if( filtpatt != NULL ) { sprintf( filter, filtpatt, value ); @@ -530,62 +700,184 @@ static int dosearch( return( LDAP_SUCCESS ); } - if ( ldap_search( ld, base, scope, filter, attrs, attrsonly ) == -1 ) { + msgid = ldap_search( ld, base, scope, filter, attrs, attrsonly ); + if( msgid == -1 ) { int ld_errno; ldap_perror( ld, "ldap_search" ); - ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno); return( ld_errno ); } - matches = 0; - first = 1; - res = NULL; - 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 ); + nresponses = nentries = nreferences = nextended = npartial = 0; + res = NULL; + while ((rc = ldap_result( ld, LDAP_RES_ANY, + sortattr ? 1 : 0, NULL, &res )) > 0 ) + { + if( sortattr ) { + (void) ldap_sort_entries( ld, &res, + ( *sortattr == '\0' ) ? NULL : sortattr, strcasecmp ); + } + + for ( msg = ldap_first_message( ld, res ); + msg != NULL; + msg = ldap_next_message( ld, msg ) ) + { + nresponses++; + + switch( ldap_msgtype( msg ) ) { + case LDAP_RES_SEARCH_ENTRY: + if( nresponses > 1 ) putchar('\n'); + nentries++; + print_entry( ld, msg, attrsonly ); + break; + + case LDAP_RES_SEARCH_REFERENCE: + if( nresponses > 1 ) putchar('\n'); + nreferences++; + print_reference( ld, msg ); + break; + + case LDAP_RES_EXTENDED: + if( nresponses > 1 ) putchar('\n'); + nextended++; + print_extended( ld, msg ); + + rc = ldap_result2error( ld, msg, 0 ); + + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_search" ); + } + + if( ldap_msgid( msg ) == 0 ) { + /* unsolicited extended operation */ + goto done; + } + + break; + + case LDAP_RES_EXTENDED_PARTIAL: + if( nresponses > 1 ) putchar('\n'); + npartial++; + print_partial( ld, msg ); + break; + + case LDAP_RES_SEARCH_RESULT: + /* if( nresponses > 1 ) putchar('\n'); */ + rc = ldap_result2error( ld, msg, 0 ); + + if( rc != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_search" ); + } + + goto done; + + } + } + + ldap_msgfree( res ); } + if ( rc == -1 ) { - ldap_perror( ld, "ldap_result" ); + ldap_perror( ld, "ldap_result" ); + return( rc ); + } + +done: + if ( verbose ) { + printf( "%d responses\n", nresponses ); + } + return( rc ); +} + + +static void print_reference( + LDAP *ld, + LDAPMessage *reference ) +{ + int rc, i; + char **refs = NULL; + + if( ldif == 1 ) { + printf("# search reference\n"); } - if (( rc = ldap_result2error( ld, res, 0 )) != LDAP_SUCCESS ) { - ldap_perror( ld, "ldap_search" ); + + rc = ldap_parse_reference( ld, reference, &refs, NULL, 0 ); + + for( i=0; refs[i] != NULL; i++ ) { + write_ldif( LDIF_PUT_VALUE, "ref", refs[i], strlen(refs[i]) ); } - if ( sortattr != NULL ) { - (void) ldap_sort_entries( ld, &res, - ( *sortattr == '\0' ) ? NULL : sortattr, strcasecmp ); - matches = 0; - first = 1; - for ( e = ldap_first_entry( ld, res ); e != NULL; - e = ldap_next_entry( ld, e ) ) { - matches++; - if ( !first ) { - putchar( '\n' ); - } else { - first = 0; - } - print_entry( ld, e, attrsonly ); - } + + ber_memvfree( (void **) refs ); + + if( rc != LDAP_SUCCESS ) { + ldap_perror(ld, "ldap_parse_reference"); + exit( EXIT_FAILURE ); } +} - if ( verbose ) { - printf( "%d matches\n", matches ); +static void print_extended( + LDAP *ld, + LDAPMessage *extended ) +{ + char rst[16]; + int rc; + char *retoid = NULL; + struct berval *retdata = NULL; + + if( ldif == 1 ) { + printf("# extended result response\n"); } - ldap_msgfree( res ); - return( rc ); + rc = ldap_parse_extended_result( ld, extended, + &retoid, &retdata, 0 ); + + write_ldif( LDIF_PUT_VALUE, "extended", + retoid, retoid ? strlen(retoid) : 0 ); + + if(retdata) { + write_ldif( LDIF_PUT_BINARY, "data", + retdata->bv_val, retdata->bv_len ); + } + + sprintf( rst, "%ld", (long) rst ); + write_ldif( LDIF_PUT_VALUE, "result", rst, strlen(rst)); + + if( rc != LDAP_SUCCESS ) { + ldap_perror(ld, "ldap_parse_extended_result"); + exit( EXIT_FAILURE ); + } } +static void print_partial( + LDAP *ld, + LDAPMessage *partial ) +{ + int rc; + char *retoid = NULL; + struct berval *retdata = NULL; + + if( ldif == 1 ) { + printf("# extended partial response\n"); + } + + rc = ldap_parse_extended_partial( ld, partial, + &retoid, &retdata, NULL, 0 ); + + write_ldif( LDIF_PUT_VALUE, "partial", + retoid, retoid ? strlen(retoid) : 0 ); + + if(retdata) { + write_ldif( LDIF_PUT_BINARY, "data", + retdata->bv_val, retdata->bv_len ); + } + + if( rc != LDAP_SUCCESS ) { + ldap_perror(ld, "ldap_parse_extended_partial"); + exit( EXIT_FAILURE ); + } +} static void print_entry( @@ -606,10 +898,10 @@ print_entry( if ( ldif == 1 ) { ufn = ldap_dn2ufn( dn ); - write_ldif( LDIF_PUT_COMMENT, NULL, ufn, strlen( ufn )); + write_ldif( LDIF_PUT_COMMENT, NULL, ufn, ufn ? strlen( ufn ) : 0 ); } if ( ldif ) { - write_ldif( LDIF_PUT_VALUE, "dn", dn, strlen( dn )); + write_ldif( LDIF_PUT_VALUE, "dn", dn, dn ? strlen( dn ) : 0); } else { printf( "%s\n", dn ); } @@ -619,7 +911,7 @@ print_entry( ufn = ldap_dn2ufn( dn ); } if ( ldif ) { - write_ldif( LDIF_PUT_VALUE, "ufn", ufn, strlen( ufn )); + write_ldif( LDIF_PUT_VALUE, "ufn", ufn, ufn ? strlen( ufn ) : 0 ); } else { printf( "%s\n", ufn ); } @@ -647,6 +939,7 @@ print_entry( if ( vals2tmp > 1 || ( vals2tmp && ldif_is_not_printable( bvals[i]->bv_val, bvals[i]->bv_len ) )) { + int tmpfd; /* write value to file */ sprintf( tmpfname, "%s" LDAP_DIRSEP "ldapsearch-%s-XXXXXX", tmpdir, a ); @@ -657,7 +950,12 @@ print_entry( continue; } - if (( tmpfp = fopen( tmpfname, "w")) == NULL ) { + if (( tmpfd = open( tmpfname, O_WRONLY|O_CREAT|O_EXCL, 0600 )) == -1 ) { + perror( tmpfname ); + continue; + } + + if (( tmpfp = fdopen( tmpfd, "w")) == NULL ) { perror( tmpfname ); continue; } @@ -675,25 +973,11 @@ print_entry( sprintf( url, "%s%s", urlpre, &tmpfname[strlen(tmpdir) + sizeof(LDAP_DIRSEP) - 1] ); - if ( ldif ) { - write_ldif( LDIF_PUT_URL, a, url, strlen( url )); - } else { - printf( "%s%s%s\n", a, sep, url ); - } - + write_ldif( LDIF_PUT_URL, a, url, strlen( url )); } else { - if ( ldif ) { - write_ldif( LDIF_PUT_VALUE, a, - bvals[ i ]->bv_val, bvals[ i ]->bv_len ); - - } else { - int notprint = !binary && !vals2tmp - && ldif_is_not_printable( bvals[i]->bv_val, - bvals[i]->bv_len ); - printf( "%s%s", a, sep ); - puts( notprint ? "NOT PRINTABLE" : bvals[ i ]->bv_val ); - } + write_ldif( LDIF_PUT_VALUE, a, + bvals[ i ]->bv_val, bvals[ i ]->bv_len ); } } ber_bvecfree( bvals );