]> git.sur5r.net Git - openldap/blob - clients/tools/ldapsearch.c
Use LDAP_VERSION3 instead of 3
[openldap] / clients / tools / ldapsearch.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/stdlib.h>
12
13 #include <ac/ctype.h>
14 #include <ac/signal.h>
15 #include <ac/string.h>
16 #include <ac/unistd.h>
17 #include <ac/errno.h>
18 #include <sys/stat.h>
19
20 #ifdef HAVE_FCNTL_H
21 #include <fcntl.h>
22 #endif
23 #ifdef HAVE_SYS_TYPES_H
24 #include <sys/types.h>
25 #endif
26 #ifdef HAVE_IO_H
27 #include <io.h>
28 #endif
29
30 #include <ldap.h>
31
32 #include "ldif.h"
33 #include "lutil.h"
34 #include "lutil_ldap.h"
35 #include "ldap_defaults.h"
36
37 static void
38 usage( const char *s )
39 {
40         fprintf( stderr,
41 "usage: %s [options] [filter [attributes...]]\nwhere:\n"
42 "  filter\tRFC-2254 compliant LDAP search filter\n"
43 "  attributes\twhitespace-separated list of attribute descriptions\n"
44 "    which may include:\n"
45 "      1.1   no attributes\n"
46 "      *     all user attributes\n"
47 "      +     all operational attributes\n"
48
49 "Search options:\n"
50 "  -a deref   one of never (default), always, search, or find\n"
51 "  -A         retrieve attribute names only (no values)\n"
52 "  -b basedn  base dn for search\n"
53 "  -l limit   time limit (in seconds) for search\n"
54 "  -L         print responses in LDIFv1 format\n"
55 "  -LL        print responses in LDIF format without comments\n"
56 "  -LLL       print responses in LDIF format without comments\n"
57 "             and version\n"
58 "  -s scope   one of base, one, or sub (search scope)\n"
59 "  -S attr    sort the results by attribute `attr'\n"
60 "  -t         write binary values to files in temporary directory\n"
61 "  -tt        write all values to files in temporary directory\n"
62 "  -T path    write files to directory specified by path (default:\n"
63 "             " LDAP_TMPDIR ")\n"
64 "  -u         include User Friendly entry names in the output\n"
65 "  -V prefix  URL prefix for files (default: \"" LDAP_FILE_URI_PREFIX ")\n"
66 "  -z limit   size limit (in entries) for search\n"
67
68 "Common options:\n"
69 "  -d level   set LDAP debugging level to `level'\n"
70 "  -D binddn  bind DN\n"
71 "  -f file    read operations from `file'\n"
72 "  -h host    LDAP server\n"
73 "  -H URI     LDAP Uniform Resource Indentifier(s)\n"
74 "  -I         use SASL Interactive mode\n"
75 "  -k         use Kerberos authentication\n"
76 "  -K         like -k, but do only step 1 of the Kerberos bind\n"
77 "  -M         enable Manage DSA IT control (-MM to make critical)\n"
78 "  -n         show what would be done but don't actually search\n"
79 "  -O props   SASL security properties\n"
80 "  -p port    port on LDAP server\n"
81 "  -P version procotol version (default: 3)\n"
82 "  -Q         use SASL Quiet mode\n"
83 "  -R realm   SASL realm\n"
84 "  -U user    SASL authentication identity (username)\n"
85 "  -v         run in verbose mode (diagnostics to standard output)\n"
86 "  -w passwd  bind passwd (for simple authentication)\n"
87 "  -W         prompt for bind passwd\n"
88 "  -x         Simple authentication\n"
89 "  -X id      SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
90 "  -Y mech    SASL mechanism\n"
91 "  -Z         Start TLS request (-ZZ to require successful response)\n"
92 , s );
93
94         exit( EXIT_FAILURE );
95 }
96
97 static void print_entry LDAP_P((
98         LDAP    *ld,
99         LDAPMessage     *entry,
100         int             attrsonly));
101
102 static void print_reference(
103         LDAP *ld,
104         LDAPMessage *reference );
105
106 static void print_extended(
107         LDAP *ld,
108         LDAPMessage *extended );
109
110 static void print_partial(
111         LDAP *ld,
112         LDAPMessage *partial );
113
114 static int print_result(
115         LDAP *ld,
116         LDAPMessage *result,
117         int search );
118
119 static void print_ctrls(
120         LDAPControl **ctrls );
121
122 static int write_ldif LDAP_P((
123         int type,
124         char *name,
125         char *value,
126         ber_len_t vallen ));
127
128 static int dosearch LDAP_P((
129         LDAP    *ld,
130         char    *base,
131         int             scope,
132         char    *filtpatt,
133         char    *value,
134         char    **attrs,
135         int             attrsonly,
136         LDAPControl **sctrls,
137         LDAPControl **cctrls,
138         struct timeval *timelimit,
139         int     sizelimit ));
140
141 static char *tmpdir = NULL;
142 static char *urlpre = NULL;
143
144 static char *prog = NULL;
145 static char     *binddn = NULL;
146 static struct berval passwd = { 0, NULL };
147 static char     *base = NULL;
148 static char     *ldaphost = NULL;
149 static char *ldapuri = NULL;
150 static int      ldapport = 0;
151 #ifdef HAVE_CYRUS_SASL
152 static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
153 static char     *sasl_realm = NULL;
154 static char     *sasl_authc_id = NULL;
155 static char     *sasl_authz_id = NULL;
156 static char     *sasl_mech = NULL;
157 static char     *sasl_secprops = NULL;
158 #endif
159 static int      use_tls = 0;
160 static char     *sortattr = NULL;
161 static int      verbose, not, includeufn, vals2tmp, ldif;
162
163 int
164 main( int argc, char **argv )
165 {
166         char            *infile, *filtpattern, **attrs = NULL, line[BUFSIZ];
167         FILE            *fp = NULL;
168         FILE            *log = NULL;
169         int                     rc, i, first, scope, deref, attrsonly, manageDSAit;
170         int                     referrals, timelimit, sizelimit, debug;
171         int             authmethod, version, want_bindpw;
172         LDAP            *ld = NULL;
173
174         infile = NULL;
175         debug = verbose = not = vals2tmp = referrals =
176                 attrsonly = manageDSAit = ldif = want_bindpw = 0;
177
178         lutil_log_initialize(argc, argv);
179         lutil_set_debug_level( "LIBLBER", 8 );
180         /* log = fopen( "ldapsearch.log", "w" ); */
181         /* ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, log ); */
182
183         deref = sizelimit = timelimit = version = -1;
184
185         scope = LDAP_SCOPE_SUBTREE;
186         authmethod = -1;
187
188     prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : prog + 1;
189
190         while (( i = getopt( argc, argv, "Aa:b:f:Ll:S:s:T:tuV:z:"
191                 "Cd:D:h:H:IkKMnO:p:P:QR:U:vw:WxX:Y:Z")) != EOF )
192         {
193         switch( i ) {
194         /* Search Options */
195         case 'a':       /* set alias deref option */
196                 if ( strcasecmp( optarg, "never" ) == 0 ) {
197                 deref = LDAP_DEREF_NEVER;
198                 } else if ( strncasecmp( optarg, "search", sizeof("search")-1 ) == 0 ) {
199                 deref = LDAP_DEREF_SEARCHING;
200                 } else if ( strncasecmp( optarg, "find", sizeof("find")-1 ) == 0 ) {
201                 deref = LDAP_DEREF_FINDING;
202                 } else if ( strcasecmp( optarg, "always" ) == 0 ) {
203                 deref = LDAP_DEREF_ALWAYS;
204                 } else {
205                 fprintf( stderr, "alias deref should be never, search, find, or always\n" );
206                 usage( argv[ 0 ] );
207                 }
208                 break;
209         case 'A':       /* retrieve attribute names only -- no values */
210                 ++attrsonly;
211                 break;
212         case 'b': /* search base */
213                 base = strdup( optarg );
214                 break;
215         case 'f':       /* input file */
216                 if( infile != NULL ) {
217                         fprintf( stderr, "%s: -f previously specified\n", prog );
218                         return EXIT_FAILURE;
219                 }
220                 infile = strdup( optarg );
221                 break;
222         case 'l':       /* time limit */
223                 timelimit = atoi( optarg );
224                 break;
225         case 'L':       /* print entries in LDIF format */
226                 ++ldif;
227                 break;
228         case 's':       /* search scope */
229                 if ( strcasecmp( optarg, "base" ) == 0 ) {
230                 scope = LDAP_SCOPE_BASE;
231                 } else if ( strncasecmp( optarg, "one", sizeof("one")-1 ) == 0 ) {
232                 scope = LDAP_SCOPE_ONELEVEL;
233                 } else if ( strncasecmp( optarg, "sub", sizeof("sub")-1 ) == 0 ) {
234                 scope = LDAP_SCOPE_SUBTREE;
235                 } else {
236                 fprintf( stderr, "scope should be base, one, or sub\n" );
237                 usage( argv[ 0 ] );
238                 }
239                 break;
240         case 'S':       /* sort attribute */
241                 sortattr = strdup( optarg );
242                 break;
243         case 'u':       /* include UFN */
244                 ++includeufn;
245                 break;
246         case 't':       /* write attribute values to TMPDIR files */
247                 ++vals2tmp;
248                 break;
249         case 'T':       /* tmpdir */
250                 if( tmpdir ) free( tmpdir );
251                 tmpdir = strdup( optarg );
252                 break;
253         case 'V':       /* uri prefix */
254                 if( urlpre ) free( urlpre );
255                 urlpre = strdup( optarg );
256                 break;
257         case 'z':       /* size limit */
258                 sizelimit = atoi( optarg );
259                 break;
260
261         /* Common Options */
262         case 'C':
263                 referrals++;
264                 break;
265         case 'd':
266             debug |= atoi( optarg );
267             break;
268         case 'D':       /* bind DN */
269                 if( binddn != NULL ) {
270                         fprintf( stderr, "%s: -D previously specified\n", prog );
271                         return EXIT_FAILURE;
272                 }
273             binddn = strdup( optarg );
274             break;
275         case 'h':       /* ldap host */
276                 if( ldapuri != NULL ) {
277                         fprintf( stderr, "%s: -h incompatible with -H\n", prog );
278                         return EXIT_FAILURE;
279                 }
280                 if( ldaphost != NULL ) {
281                         fprintf( stderr, "%s: -h previously specified\n", prog );
282                         return EXIT_FAILURE;
283                 }
284             ldaphost = strdup( optarg );
285             break;
286         case 'H':       /* ldap URI */
287                 if( ldaphost != NULL ) {
288                         fprintf( stderr, "%s: -H incompatible with -h\n", prog );
289                         return EXIT_FAILURE;
290                 }
291                 if( ldapport ) {
292                         fprintf( stderr, "%s: -H incompatible with -p\n", prog );
293                         return EXIT_FAILURE;
294                 }
295                 if( ldapuri != NULL ) {
296                         fprintf( stderr, "%s: -H previously specified\n", prog );
297                         return EXIT_FAILURE;
298                 }
299             ldapuri = strdup( optarg );
300             break;
301         case 'I':
302 #ifdef HAVE_CYRUS_SASL
303                 if( version == LDAP_VERSION2 ) {
304                         fprintf( stderr, "%s: -I incompatible with version %d\n",
305                                 prog, version );
306                         return EXIT_FAILURE;
307                 }
308                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
309                         fprintf( stderr, "%s: incompatible previous "
310                                 "authentication choice\n",
311                                 prog );
312                         return EXIT_FAILURE;
313                 }
314                 authmethod = LDAP_AUTH_SASL;
315                 version = LDAP_VERSION3;
316                 sasl_flags = LDAP_SASL_INTERACTIVE;
317                 break;
318 #else
319                 fprintf( stderr, "%s: was not compiled with SASL support\n",
320                         prog );
321                 return( EXIT_FAILURE );
322 #endif
323         case 'k':       /* kerberos bind */
324 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
325                 if( version > LDAP_VERSION2 ) {
326                         fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
327                                 prog, version );
328                         return EXIT_FAILURE;
329                 }
330
331                 if( authmethod != -1 ) {
332                         fprintf( stderr, "%s: -k incompatible with previous "
333                                 "authentication choice\n", prog );
334                         return EXIT_FAILURE;
335                 }
336                         
337                 authmethod = LDAP_AUTH_KRBV4;
338 #else
339                 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
340                 return EXIT_FAILURE;
341 #endif
342             break;
343         case 'K':       /* kerberos bind, part one only */
344 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
345                 if( version > LDAP_VERSION2 ) {
346                         fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
347                                 prog, version );
348                         return EXIT_FAILURE;
349                 }
350                 if( authmethod != -1 ) {
351                         fprintf( stderr, "%s: incompatible with previous "
352                                 "authentication choice\n", prog );
353                         return EXIT_FAILURE;
354                 }
355
356                 authmethod = LDAP_AUTH_KRBV41;
357 #else
358                 fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
359                 return( EXIT_FAILURE );
360 #endif
361             break;
362         case 'M':
363                 /* enable Manage DSA IT */
364                 if( version == LDAP_VERSION2 ) {
365                         fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
366                                 prog, version );
367                         return EXIT_FAILURE;
368                 }
369                 manageDSAit++;
370                 version = LDAP_VERSION3;
371                 break;
372         case 'n':       /* print deletes, don't actually do them */
373             ++not;
374             break;
375         case 'O':
376 #ifdef HAVE_CYRUS_SASL
377                 if( sasl_secprops != NULL ) {
378                         fprintf( stderr, "%s: -O previously specified\n", prog );
379                         return EXIT_FAILURE;
380                 }
381                 if( version == LDAP_VERSION2 ) {
382                         fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
383                                 prog, version );
384                         return EXIT_FAILURE;
385                 }
386                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
387                         fprintf( stderr, "%s: incompatible previous "
388                                 "authentication choice\n", prog );
389                         return EXIT_FAILURE;
390                 }
391                 authmethod = LDAP_AUTH_SASL;
392                 version = LDAP_VERSION3;
393                 sasl_secprops = strdup( optarg );
394 #else
395                 fprintf( stderr, "%s: not compiled with SASL support\n",
396                         prog );
397                 return( EXIT_FAILURE );
398 #endif
399                 break;
400         case 'p':
401                 if( ldapport ) {
402                         fprintf( stderr, "%s: -p previously specified\n", prog );
403                         return EXIT_FAILURE;
404                 }
405             ldapport = atoi( optarg );
406             break;
407         case 'P':
408                 switch( atoi(optarg) ) {
409                 case 2:
410                         if( version == LDAP_VERSION3 ) {
411                                 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
412                                         prog, version );
413                                 return EXIT_FAILURE;
414                         }
415                         version = LDAP_VERSION2;
416                         break;
417                 case 3:
418                         if( version == LDAP_VERSION2 ) {
419                                 fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
420                                         prog, version );
421                                 return EXIT_FAILURE;
422                         }
423                         version = LDAP_VERSION3;
424                         break;
425                 default:
426                         fprintf( stderr, "%s: protocol version should be 2 or 3\n",
427                                 prog );
428                         usage( prog );
429                         return( EXIT_FAILURE );
430                 } break;
431         case 'Q':
432 #ifdef HAVE_CYRUS_SASL
433                 if( version == LDAP_VERSION2 ) {
434                         fprintf( stderr, "%s: -Q incompatible with version %d\n",
435                                 prog, version );
436                         return EXIT_FAILURE;
437                 }
438                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
439                         fprintf( stderr, "%s: incompatible previous "
440                                 "authentication choice\n",
441                                 prog );
442                         return EXIT_FAILURE;
443                 }
444                 authmethod = LDAP_AUTH_SASL;
445                 version = LDAP_VERSION3;
446                 sasl_flags = LDAP_SASL_QUIET;
447                 break;
448 #else
449                 fprintf( stderr, "%s: not compiled with SASL support\n",
450                         prog );
451                 return( EXIT_FAILURE );
452 #endif
453         case 'R':
454 #ifdef HAVE_CYRUS_SASL
455                 if( sasl_realm != NULL ) {
456                         fprintf( stderr, "%s: -R previously specified\n", prog );
457                         return EXIT_FAILURE;
458                 }
459                 if( version == LDAP_VERSION2 ) {
460                         fprintf( stderr, "%s: -R incompatible with version %d\n",
461                                 prog, version );
462                         return EXIT_FAILURE;
463                 }
464                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
465                         fprintf( stderr, "%s: incompatible previous "
466                                 "authentication choice\n",
467                                 prog );
468                         return EXIT_FAILURE;
469                 }
470                 authmethod = LDAP_AUTH_SASL;
471                 version = LDAP_VERSION3;
472                 sasl_realm = strdup( optarg );
473 #else
474                 fprintf( stderr, "%s: not compiled with SASL support\n",
475                         prog );
476                 return( EXIT_FAILURE );
477 #endif
478                 break;
479         case 'U':
480 #ifdef HAVE_CYRUS_SASL
481                 if( sasl_authc_id != NULL ) {
482                         fprintf( stderr, "%s: -U previously specified\n", prog );
483                         return EXIT_FAILURE;
484                 }
485                 if( version == LDAP_VERSION2 ) {
486                         fprintf( stderr, "%s: -U incompatible with version %d\n",
487                                 prog, version );
488                         return EXIT_FAILURE;
489                 }
490                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
491                         fprintf( stderr, "%s: incompatible previous "
492                                 "authentication choice\n",
493                                 prog );
494                         return EXIT_FAILURE;
495                 }
496                 authmethod = LDAP_AUTH_SASL;
497                 version = LDAP_VERSION3;
498                 sasl_authc_id = strdup( optarg );
499 #else
500                 fprintf( stderr, "%s: not compiled with SASL support\n",
501                         prog );
502                 return( EXIT_FAILURE );
503 #endif
504                 break;
505         case 'v':       /* verbose mode */
506             verbose++;
507             break;
508         case 'w':       /* password */
509             passwd.bv_val = strdup( optarg );
510                 {
511                         char* p;
512
513                         for( p = optarg; *p == '\0'; p++ ) {
514                                 *p = '\0';
515                         }
516                 }
517                 passwd.bv_len = strlen( passwd.bv_val );
518             break;
519         case 'W':
520                 want_bindpw++;
521                 break;
522         case 'Y':
523 #ifdef HAVE_CYRUS_SASL
524                 if( sasl_mech != NULL ) {
525                         fprintf( stderr, "%s: -Y previously specified\n", prog );
526                         return EXIT_FAILURE;
527                 }
528                 if( version == LDAP_VERSION2 ) {
529                         fprintf( stderr, "%s: -Y incompatible with version %d\n",
530                                 prog, version );
531                         return EXIT_FAILURE;
532                 }
533                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
534                         fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
535                         return EXIT_FAILURE;
536                 }
537                 authmethod = LDAP_AUTH_SASL;
538                 version = LDAP_VERSION3;
539                 sasl_mech = strdup( optarg );
540 #else
541                 fprintf( stderr, "%s: not compiled with SASL support\n",
542                         prog );
543                 return( EXIT_FAILURE );
544 #endif
545                 break;
546         case 'x':
547                 if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
548                         fprintf( stderr, "%s: incompatible with previous "
549                                 "authentication choice\n", prog );
550                         return EXIT_FAILURE;
551                 }
552                 authmethod = LDAP_AUTH_SIMPLE;
553                 break;
554         case 'X':
555 #ifdef HAVE_CYRUS_SASL
556                 if( sasl_authz_id != NULL ) {
557                         fprintf( stderr, "%s: -X previously specified\n", prog );
558                         return EXIT_FAILURE;
559                 }
560                 if( version == LDAP_VERSION2 ) {
561                         fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
562                                 prog, version );
563                         return EXIT_FAILURE;
564                 }
565                 if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
566                         fprintf( stderr, "%s: -X incompatible with "
567                                 "authentication choice\n", prog );
568                         return EXIT_FAILURE;
569                 }
570                 authmethod = LDAP_AUTH_SASL;
571                 version = LDAP_VERSION3;
572                 sasl_authz_id = strdup( optarg );
573 #else
574                 fprintf( stderr, "%s: not compiled with SASL support\n",
575                         prog );
576                 return( EXIT_FAILURE );
577 #endif
578                 break;
579         case 'Z':
580 #ifdef HAVE_TLS
581                 if( version == LDAP_VERSION2 ) {
582                         fprintf( stderr, "%s: -Z incompatible with version %d\n",
583                                 prog, version );
584                         return EXIT_FAILURE;
585                 }
586                 version = LDAP_VERSION3;
587                 use_tls++;
588 #else
589                 fprintf( stderr, "%s: not compiled with TLS support\n",
590                         prog );
591                 return( EXIT_FAILURE );
592 #endif
593                 break;
594         default:
595                 fprintf( stderr, "%s: unrecognized option -%c\n",
596                         prog, optopt );
597                 usage( argv[0] );
598         }
599         }
600
601         if (version == -1) {
602                 version = LDAP_VERSION3;
603         }
604         if (authmethod == -1 && version > LDAP_VERSION2) {
605 #ifdef HAVE_CYRUS_SASL
606                 authmethod = LDAP_AUTH_SASL;
607 #else
608                 authmethod = LDAP_AUTH_SIMPLE;
609 #endif
610         }
611
612         if (( argc - optind < 1 ) ||
613                 ( *argv[optind] != '(' /*')'*/ &&
614                 ( strchr( argv[optind], '=' ) == NULL ) ) )
615         {
616                 filtpattern = "(objectclass=*)";
617         } else {
618                 filtpattern = strdup( argv[optind++] );
619         }
620
621         if ( (argv[optind] != NULL) && (sortattr == NULL || *sortattr == '\0') ) {
622                 attrs = &argv[optind];
623         }
624
625         if ( infile != NULL ) {
626                 if ( infile[0] == '-' && infile[1] == '\0' ) {
627                         fp = stdin;
628                 } else if (( fp = fopen( infile, "r" )) == NULL ) {
629                         perror( infile );
630                         return EXIT_FAILURE;
631                 }
632         }
633
634         if( tmpdir == NULL
635                 && (tmpdir = getenv("TMPDIR")) == NULL
636                 && (tmpdir = getenv("TMP")) == NULL
637                 && (tmpdir = getenv("TEMP")) == NULL )
638         {
639                 tmpdir = LDAP_TMPDIR;
640         }
641
642         if( urlpre == NULL ) {
643                 urlpre = malloc( sizeof("file:////") + strlen(tmpdir) );
644
645                 if( urlpre == NULL ) {
646                         perror( "malloc" );
647                         return EXIT_FAILURE;
648                 }
649
650                 sprintf( urlpre, "file:///%s/",
651                         tmpdir[0] == '/' ? &tmpdir[1] : tmpdir );
652
653                 /* urlpre should be URLized.... */
654         }
655
656         if ( debug ) {
657                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
658                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
659                 }
660                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
661                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
662                 }
663                 ldif_debug = debug;
664         }
665
666 #ifdef SIGPIPE
667         (void) SIGNAL( SIGPIPE, SIG_IGN );
668 #endif
669
670         if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
671                 if ( verbose ) {
672                         fprintf( stderr, "ldap_init( %s, %d )\n",
673                                 ldaphost != NULL ? ldaphost : "<DEFAULT>",
674                                 ldapport );
675                 }
676
677                 ld = ldap_init( ldaphost, ldapport );
678                 if( ld == NULL ) {
679                         perror("ldapsearch: ldap_init");
680                         return EXIT_FAILURE;
681                 }
682
683         } else {
684                 if ( verbose ) {
685                         fprintf( stderr, "ldap_initialize( %s )\n",
686                                 ldapuri != NULL ? ldapuri : "<DEFAULT>" );
687                 }
688
689                 rc = ldap_initialize( &ld, ldapuri );
690                 if( rc != LDAP_SUCCESS ) {
691                         fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
692                                 rc, ldap_err2string(rc) );
693                         return EXIT_FAILURE;
694                 }
695         }
696
697         if (deref != -1 &&
698                 ldap_set_option( ld, LDAP_OPT_DEREF, (void *) &deref ) != LDAP_OPT_SUCCESS )
699         {
700                 fprintf( stderr, "Could not set LDAP_OPT_DEREF %d\n", deref );
701                 return EXIT_FAILURE;
702         }
703         if (timelimit != -1 &&
704                 ldap_set_option( ld, LDAP_OPT_TIMELIMIT, (void *) &timelimit ) != LDAP_OPT_SUCCESS )
705         {
706                 fprintf( stderr, "Could not set LDAP_OPT_TIMELIMIT %d\n", timelimit );
707                 return EXIT_FAILURE;
708         }
709         if (sizelimit != -1 &&
710                 ldap_set_option( ld, LDAP_OPT_SIZELIMIT, (void *) &sizelimit ) != LDAP_OPT_SUCCESS )
711         {
712                 fprintf( stderr, "Could not set LDAP_OPT_SIZELIMIT %d\n", sizelimit );
713                 return EXIT_FAILURE;
714         }
715
716         /* referrals */
717         if (ldap_set_option( ld, LDAP_OPT_REFERRALS,
718                 referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
719         {
720                 fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
721                         referrals ? "on" : "off" );
722                 return EXIT_FAILURE;
723         }
724
725         if (version == -1 ) {
726                 version = LDAP_VERSION3;
727         }
728
729         if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
730                 != LDAP_OPT_SUCCESS )
731         {
732                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
733                         version );
734                 return EXIT_FAILURE;
735         }
736
737
738         if ( use_tls && ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
739                 if ( use_tls > 1 ) {
740                         ldap_perror( ld, "ldap_start_tls" );
741                         return EXIT_FAILURE;
742                 }
743                 fprintf( stderr, "WARNING: could not start TLS\n" );
744         }
745
746         if (want_bindpw) {
747                 passwd.bv_val = getpassphrase("Enter LDAP Password: ");
748                 passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
749         }
750
751         if ( authmethod == LDAP_AUTH_SASL ) {
752 #ifdef HAVE_CYRUS_SASL
753                 void *defaults;
754
755                 if( sasl_secprops != NULL ) {
756                         rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
757                                 (void *) sasl_secprops );
758                         
759                         if( rc != LDAP_OPT_SUCCESS ) {
760                                 fprintf( stderr,
761                                         "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
762                                         sasl_secprops );
763                                 return( EXIT_FAILURE );
764                         }
765                 }
766                 
767                 defaults = lutil_sasl_defaults( ld,
768                         sasl_mech,
769                         sasl_realm,
770                         sasl_authc_id,
771                         passwd.bv_val,
772                         sasl_authz_id );
773
774                 rc = ldap_sasl_interactive_bind_s( ld, binddn,
775                         sasl_mech, NULL, NULL,
776                         sasl_flags, lutil_sasl_interact, defaults );
777
778                 if( rc != LDAP_SUCCESS ) {
779                         ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
780                         return( EXIT_FAILURE );
781                 }
782 #else
783                 fprintf( stderr, "%s: not compiled with SASL support\n",
784                         prog, argv[0] );
785                 return( EXIT_FAILURE );
786 #endif
787         } else {
788                 if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
789                                 != LDAP_SUCCESS ) {
790                         ldap_perror( ld, "ldap_bind" );
791                         return( EXIT_FAILURE );
792                 }
793         }
794
795         if ( manageDSAit ) {
796                 int err;
797                 LDAPControl c;
798                 LDAPControl *ctrls[2];
799                 ctrls[0] = &c;
800                 ctrls[1] = NULL;
801
802                 c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
803                 c.ldctl_value.bv_val = NULL;
804                 c.ldctl_value.bv_len = 0;
805                 c.ldctl_iscritical = manageDSAit > 1;
806
807                 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
808
809                 if( err != LDAP_OPT_SUCCESS ) {
810                         fprintf( stderr, "Could not set ManageDSAit %scontrol\n",
811                                 c.ldctl_iscritical ? "critical " : "" );
812                         if( c.ldctl_iscritical ) {
813                                 exit( EXIT_FAILURE );
814                         }
815                 }
816         }
817
818         if ( verbose ) {
819                 fprintf( stderr, "filter%s: %s\nrequesting: ",
820                         infile != NULL ? " pattern" : "",
821                         filtpattern );
822
823                 if ( attrs == NULL ) {
824                         fprintf( stderr, "ALL" );
825                 } else {
826                         for ( i = 0; attrs[ i ] != NULL; ++i ) {
827                                 fprintf( stderr, "%s ", attrs[ i ] );
828                         }
829                 }
830                 fprintf( stderr, "\n" );
831         }
832
833         if (ldif < 3 ) {
834                 printf( "version: %d\n\n", ldif ? 1 : 2 );
835         }
836
837         if (ldif < 2 ) {
838                 printf( "#\n# filter%s: %s\n# requesting: ",
839                         infile != NULL ? " pattern" : "",
840                         filtpattern );
841
842                 if ( attrs == NULL ) {
843                         printf( "ALL" );
844                 } else {
845                         for ( i = 0; attrs[ i ] != NULL; ++i ) {
846                                 printf( "%s ", attrs[ i ] );
847                         }
848                 }
849
850                 if ( manageDSAit ) {
851                         printf("\n# with manageDSAit %scontrol",
852                                 manageDSAit > 1 ? "critical " : "" );
853                 }
854
855                 printf( "\n#\n\n" );
856         }
857
858         if ( infile == NULL ) {
859                 rc = dosearch( ld, base, scope, NULL, filtpattern,
860                         attrs, attrsonly, NULL, NULL, NULL, -1 );
861
862         } else {
863                 rc = 0;
864                 first = 1;
865                 while ( rc == 0 && fgets( line, sizeof( line ), fp ) != NULL ) { 
866                         line[ strlen( line ) - 1 ] = '\0';
867                         if ( !first ) {
868                                 putchar( '\n' );
869                         } else {
870                                 first = 0;
871                         }
872                         rc = dosearch( ld, base, scope, filtpattern, line,
873                                 attrs, attrsonly, NULL, NULL, NULL, -1 );
874                 }
875                 if ( fp != stdin ) {
876                         fclose( fp );
877                 }
878         }
879
880         ldap_unbind( ld );
881         return( rc );
882 }
883
884
885 static int dosearch(
886         LDAP    *ld,
887         char    *base,
888         int             scope,
889         char    *filtpatt,
890         char    *value,
891         char    **attrs,
892         int             attrsonly,
893         LDAPControl **sctrls,
894         LDAPControl **cctrls,
895         struct timeval *timelimit,
896         int sizelimit )
897 {
898         char            filter[ BUFSIZ ];
899         int                     rc;
900         int                     nresponses;
901         int                     nentries;
902         int                     nreferences;
903         int                     nextended;
904         int                     npartial;
905         LDAPMessage             *res, *msg;
906         ber_int_t       msgid;
907
908         if( filtpatt != NULL ) {
909                 sprintf( filter, filtpatt, value );
910
911                 if ( verbose ) {
912                         fprintf( stderr, "filter is: (%s)\n", filter );
913                 }
914
915                 if( ldif < 2 ) {
916                         printf( "#\n# filter: %s\n#\n", filter );
917                 }
918
919         } else {
920                 sprintf( filter, "%s", value );
921         }
922
923         if ( not ) {
924                 return LDAP_SUCCESS;
925         }
926
927         rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
928                 sctrls, cctrls, timelimit, sizelimit, &msgid );
929
930         if( rc != LDAP_SUCCESS ) {
931                 fprintf( stderr, "%s: ldap_search_ext: %s (%d)\n",
932                         prog, ldap_err2string( rc ), rc );
933                 return( rc );
934         }
935
936         nresponses = nentries = nreferences = nextended = npartial = 0;
937
938         res = NULL;
939
940         while ((rc = ldap_result( ld, LDAP_RES_ANY,
941                 sortattr ? LDAP_MSG_ALL : LDAP_MSG_ONE,
942                 NULL, &res )) > 0 )
943         {
944                 if( sortattr ) {
945                         (void) ldap_sort_entries( ld, &res,
946                                 ( *sortattr == '\0' ) ? NULL : sortattr, strcasecmp );
947                 }
948
949                 for ( msg = ldap_first_message( ld, res );
950                         msg != NULL;
951                         msg = ldap_next_message( ld, msg ) )
952                 {
953                         if( nresponses++ ) putchar('\n');
954
955                         switch( ldap_msgtype( msg ) ) {
956                         case LDAP_RES_SEARCH_ENTRY:
957                                 nentries++;
958                                 print_entry( ld, msg, attrsonly );
959                                 break;
960
961                         case LDAP_RES_SEARCH_REFERENCE:
962                                 nreferences++;
963                                 print_reference( ld, msg );
964                                 break;
965
966                         case LDAP_RES_EXTENDED:
967                                 nextended++;
968                                 print_extended( ld, msg );
969
970                                 if( ldap_msgid( msg ) == 0 ) {
971                                         /* unsolicited extended operation */
972                                         goto done;
973                                 }
974                                 break;
975
976                         case LDAP_RES_EXTENDED_PARTIAL:
977                                 npartial++;
978                                 print_partial( ld, msg );
979                                 break;
980
981                         case LDAP_RES_SEARCH_RESULT:
982                                 rc = print_result( ld, msg, 1 );
983                                 goto done;
984                         }
985                 }
986
987                 ldap_msgfree( res );
988         }
989
990         if ( rc == -1 ) {
991                 ldap_perror( ld, "ldap_result" );
992                 return( rc );
993         }
994
995 done:
996         if ( ldif < 2 ) {
997                 printf( "\n# numResponses: %d\n", nresponses );
998                 if( nentries ) printf( "# numEntries: %d\n", nentries );
999                 if( nextended ) printf( "# numExtended: %d\n", nextended );
1000                 if( npartial ) printf( "# numPartial: %d\n", npartial );
1001                 if( nreferences ) printf( "# numReferences: %d\n", nreferences );
1002         }
1003
1004         return( rc );
1005 }
1006
1007 static void
1008 print_entry(
1009         LDAP    *ld,
1010         LDAPMessage     *entry,
1011         int             attrsonly)
1012 {
1013         char            *a, *dn, *ufn;
1014         char    tmpfname[ 256 ];
1015         char    url[ 256 ];
1016         int                     i, rc;
1017         BerElement              *ber = NULL;
1018         struct berval   **bvals;
1019         LDAPControl **ctrls = NULL;
1020         FILE            *tmpfp;
1021
1022         dn = ldap_get_dn( ld, entry );
1023         ufn = NULL;
1024
1025         if ( ldif < 2 ) {
1026                 ufn = ldap_dn2ufn( dn );
1027                 write_ldif( LDIF_PUT_COMMENT, NULL, ufn, ufn ? strlen( ufn ) : 0 );
1028         }
1029         write_ldif( LDIF_PUT_VALUE, "dn", dn, dn ? strlen( dn ) : 0);
1030
1031         rc = ldap_get_entry_controls( ld, entry, &ctrls );
1032
1033         if( rc != LDAP_SUCCESS ) {
1034                 fprintf(stderr, "print_entry: %d\n", rc );
1035                 ldap_perror( ld, "ldap_get_entry_controls" );
1036                 exit( EXIT_FAILURE );
1037         }
1038
1039         if( ctrls ) {
1040                 print_ctrls( ctrls );
1041                 ldap_controls_free( ctrls );
1042         }
1043
1044         if ( includeufn ) {
1045                 if( ufn == NULL ) {
1046                         ufn = ldap_dn2ufn( dn );
1047                 }
1048                 write_ldif( LDIF_PUT_VALUE, "ufn", ufn, ufn ? strlen( ufn ) : 0 );
1049         }
1050
1051         if( ufn != NULL ) ldap_memfree( ufn );
1052         ldap_memfree( dn );
1053
1054         for ( a = ldap_first_attribute( ld, entry, &ber ); a != NULL;
1055                 a = ldap_next_attribute( ld, entry, ber ) )
1056         {
1057                 if ( attrsonly ) {
1058                         write_ldif( LDIF_PUT_NOVALUE, a, NULL, 0 );
1059
1060                 } else if (( bvals = ldap_get_values_len( ld, entry, a )) != NULL ) {
1061                         for ( i = 0; bvals[i] != NULL; i++ ) {
1062                                 if ( vals2tmp > 1 || ( vals2tmp
1063                                         && ldif_is_not_printable( bvals[i]->bv_val, bvals[i]->bv_len ) ))
1064                                 {
1065                                         int tmpfd;
1066                                         /* write value to file */
1067                                         sprintf( tmpfname, "%s" LDAP_DIRSEP "ldapsearch-%s-XXXXXX",
1068                                                 tmpdir, a );
1069                                         tmpfp = NULL;
1070
1071                                         if ( mktemp( tmpfname ) == NULL ) {
1072                                                 perror( tmpfname );
1073                                                 continue;
1074                                         }
1075
1076                                         if (( tmpfd = open( tmpfname, O_WRONLY|O_CREAT|O_EXCL, 0600 )) == -1 ) {
1077                                                 perror( tmpfname );
1078                                                 continue;
1079                                         }
1080
1081                                         if (( tmpfp = fdopen( tmpfd, "w")) == NULL ) {
1082                                                 perror( tmpfname );
1083                                                 continue;
1084                                         }
1085
1086                                         if ( fwrite( bvals[ i ]->bv_val,
1087                                                 bvals[ i ]->bv_len, 1, tmpfp ) == 0 )
1088                                         {
1089                                                 perror( tmpfname );
1090                                                 fclose( tmpfp );
1091                                                 continue;
1092                                         }
1093
1094                                         fclose( tmpfp );
1095
1096                                         sprintf( url, "%s%s", urlpre,
1097                                                 &tmpfname[strlen(tmpdir) + sizeof(LDAP_DIRSEP) - 1] );
1098
1099                                         write_ldif( LDIF_PUT_URL, a, url, strlen( url ));
1100
1101                                 } else {
1102                                         write_ldif( LDIF_PUT_VALUE, a,
1103                                                 bvals[ i ]->bv_val, bvals[ i ]->bv_len );
1104                                 }
1105                         }
1106                         ber_bvecfree( bvals );
1107                 }
1108         }
1109
1110         if( ber != NULL ) {
1111                 ber_free( ber, 0 );
1112         }
1113 }
1114
1115 static void print_reference(
1116         LDAP *ld,
1117         LDAPMessage *reference )
1118 {
1119         int rc;
1120         char **refs = NULL;
1121         LDAPControl **ctrls;
1122
1123         if( ldif < 2 ) {
1124                 printf("# search reference\n");
1125         }
1126
1127         rc = ldap_parse_reference( ld, reference, &refs, &ctrls, 0 );
1128
1129         if( rc != LDAP_SUCCESS ) {
1130                 ldap_perror(ld, "ldap_parse_reference");
1131                 exit( EXIT_FAILURE );
1132         }
1133
1134         if( refs ) {
1135                 int i;
1136                 for( i=0; refs[i] != NULL; i++ ) {
1137                         write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
1138                                 "ref", refs[i], strlen(refs[i]) );
1139                 }
1140                 ber_memvfree( (void **) refs );
1141         }
1142
1143         if( ctrls ) {
1144                 print_ctrls( ctrls );
1145                 ldap_controls_free( ctrls );
1146         }
1147 }
1148
1149 static void print_extended(
1150         LDAP *ld,
1151         LDAPMessage *extended )
1152 {
1153         int rc;
1154         char *retoid = NULL;
1155         struct berval *retdata = NULL;
1156
1157         if( ldif < 2 ) {
1158                 printf("# extended result response\n");
1159         }
1160
1161         rc = ldap_parse_extended_result( ld, extended,
1162                 &retoid, &retdata, 0 );
1163
1164         if( rc != LDAP_SUCCESS ) {
1165                 ldap_perror(ld, "ldap_parse_extended_result");
1166                 exit( EXIT_FAILURE );
1167         }
1168
1169         write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
1170                 "extended", retoid, retoid ? strlen(retoid) : 0 );
1171         ber_memfree( retoid );
1172
1173         if(retdata) {
1174                 write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
1175                         "data", retdata->bv_val, retdata->bv_len );
1176                 ber_bvfree( retdata );
1177         }
1178
1179         print_result( ld, extended, 0 );
1180 }
1181
1182 static void print_partial(
1183         LDAP *ld,
1184         LDAPMessage *partial )
1185 {
1186         int rc;
1187         char *retoid = NULL;
1188         struct berval *retdata = NULL;
1189         LDAPControl **ctrls = NULL;
1190
1191         if( ldif < 2 ) {
1192                 printf("# extended partial response\n");
1193         }
1194
1195         rc = ldap_parse_extended_partial( ld, partial,
1196                 &retoid, &retdata, &ctrls, 0 );
1197
1198         if( rc != LDAP_SUCCESS ) {
1199                 ldap_perror(ld, "ldap_parse_extended_partial");
1200                 exit( EXIT_FAILURE );
1201         }
1202
1203         write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
1204                 "partial", retoid, retoid ? strlen(retoid) : 0 );
1205
1206         ber_memfree( retoid );
1207
1208         if( retdata ) {
1209                 write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
1210                         "data", 
1211                         retdata->bv_val, retdata->bv_len );
1212
1213                 ber_bvfree( retdata );
1214         }
1215
1216         if( ctrls ) {
1217                 print_ctrls( ctrls );
1218                 ldap_controls_free( ctrls );
1219         }
1220 }
1221
1222 static int print_result(
1223         LDAP *ld,
1224         LDAPMessage *result, int search )
1225 {
1226         int rc;
1227         int err;
1228         char *matcheddn = NULL;
1229         char *text = NULL;
1230         char **refs = NULL;
1231         LDAPControl **ctrls = NULL;
1232
1233         if( search ) {
1234                 if ( ldif < 2 ) {
1235                         printf("# search result\n");
1236                 }
1237                 if ( ldif < 1 ) {
1238                         printf("%s: %d\n", "search", ldap_msgid(result) );
1239                 }
1240         }
1241
1242         rc = ldap_parse_result( ld, result,
1243                 &err, &matcheddn, &text, &refs, &ctrls, 0 );
1244
1245         if( rc != LDAP_SUCCESS ) {
1246                 ldap_perror(ld, "ldap_parse_result");
1247                 exit( EXIT_FAILURE );
1248         }
1249
1250
1251         if( !ldif ) {
1252                 printf( "result: %d %s\n", err, ldap_err2string(err) );
1253
1254         } else if ( err != LDAP_SUCCESS ) {
1255                 fprintf( stderr, "%s (%d)\n", ldap_err2string(err), err );
1256         }
1257
1258         if( matcheddn && *matcheddn ) {
1259                 if( !ldif ) {
1260                         write_ldif( LDIF_PUT_VALUE,
1261                                 "matchedDN", matcheddn, strlen(matcheddn) );
1262                 } else {
1263                         fprintf( stderr, "Matched DN: %s\n", matcheddn );
1264                 }
1265
1266                 ber_memfree( matcheddn );
1267         }
1268
1269         if( text && *text ) {
1270                 if( !ldif ) {
1271                         write_ldif( LDIF_PUT_TEXT, "text",
1272                                 text, strlen(text) );
1273                 } else {
1274                         fprintf( stderr, "Additional information: %s\n", text );
1275                 }
1276
1277                 ber_memfree( text );
1278         }
1279
1280         if( refs ) {
1281                 int i;
1282                 for( i=0; refs[i] != NULL; i++ ) {
1283                         if( !ldif ) {
1284                                 write_ldif( LDIF_PUT_VALUE, "ref", refs[i], strlen(refs[i]) );
1285                         } else {
1286                                 fprintf( stderr, "Referral: %s\n", refs[i] );
1287                         }
1288                 }
1289
1290                 ber_memvfree( (void **) refs );
1291         }
1292
1293         if( ctrls ) {
1294                 print_ctrls( ctrls );
1295                 ldap_controls_free( ctrls );
1296         }
1297
1298         return err;
1299 }
1300
1301 static void print_ctrls(
1302         LDAPControl **ctrls )
1303 {
1304         int i;
1305         for(i=0; ctrls[i] != NULL; i++ ) {
1306                 /* control: OID criticality base64value */
1307                 struct berval *b64 = NULL;
1308                 ber_len_t len;
1309                 char *str;
1310                         
1311                 len = strlen( ctrls[i]->ldctl_oid );
1312
1313                 /* add enough for space after OID and the critical value itself */
1314                 len += ctrls[i]->ldctl_iscritical
1315                         ? sizeof("true") : sizeof("false");
1316
1317                 /* convert to base64 */
1318                 if( ctrls[i]->ldctl_value.bv_len ) {
1319                         b64 = ber_memalloc( sizeof(struct berval) );
1320                         
1321                         b64->bv_len = LUTIL_BASE64_ENCODE_LEN(
1322                                 ctrls[i]->ldctl_value.bv_len ) + 1;
1323                         b64->bv_val = ber_memalloc( b64->bv_len + 1 );
1324
1325                         b64->bv_len = lutil_b64_ntop(
1326                                 ctrls[i]->ldctl_value.bv_val, ctrls[i]->ldctl_value.bv_len,
1327                                 b64->bv_val, b64->bv_len );
1328                 }
1329
1330                 if( b64 ) {
1331                         len += 1 + b64->bv_len;
1332                 }
1333
1334                 str = malloc( len + 1 );
1335                 strcpy( str, ctrls[i]->ldctl_oid );
1336                 strcat( str, ctrls[i]->ldctl_iscritical
1337                         ? " true" : " false" );
1338
1339                 if( b64 ) {
1340                         strcat(str, " ");
1341                         strcat(str, b64->bv_val );
1342                 }
1343
1344                 write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
1345                         "control", str, len );
1346
1347                 free( str );
1348                 ber_bvfree( b64 );
1349         }
1350 }
1351
1352 static int
1353 write_ldif( int type, char *name, char *value, ber_len_t vallen )
1354 {
1355         char    *ldif;
1356
1357         if (( ldif = ldif_put( type, name, value, vallen )) == NULL ) {
1358                 return( -1 );
1359         }
1360
1361         fputs( ldif, stdout );
1362         ber_memfree( ldif );
1363
1364         return( 0 );
1365 }