]> git.sur5r.net Git - openldap/blob - clients/tools/ldapcompare.c
3b731f9346cc5e7aaf23a2ad2c0ec7321d582daf
[openldap] / clients / tools / ldapcompare.c
1 /*
2  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5
6 #include "portable.h"
7
8 #include <stdio.h>
9
10 #include <ac/stdlib.h>
11
12 #include <ac/ctype.h>
13 #include <ac/signal.h>
14 #include <ac/string.h>
15 #include <ac/unistd.h>
16 #include <ac/errno.h>
17 #include <sys/stat.h>
18
19 #ifdef HAVE_FCNTL_H
20 #include <fcntl.h>
21 #endif
22 #ifdef HAVE_SYS_TYPES_H
23 #include <sys/types.h>
24 #endif
25 #ifdef HAVE_IO_H
26 #include <io.h>
27 #endif
28
29 #include <ldap.h>
30
31 #include "ldif.h"
32 #include "lutil.h"
33 #include "lutil_ldap.h"
34 #include "ldap_defaults.h"
35
36 static void
37 usage( const char *s )
38 {
39         fprintf( stderr,
40 "usage: %s [options] DN <attr:value|attr::b64value>\n"
41 "where:\n"
42 "  DN\tDistinguished Name\n"
43 "  attr\tassertion attribute\n"
44 "  value\tassertion value\n"
45 "  b64value\tbase64 encoding of assertion value\n"
46
47 "Common options:\n"
48 "  -d level   set LDAP debugging level to `level'\n"
49 "  -D binddn  bind DN\n"
50 "  -h host    LDAP server\n"
51 "  -H URI     LDAP Uniform Resource Indentifier(s)\n"
52 "  -I         use SASL Interactive mode\n"
53 "  -k         use Kerberos authentication\n"
54 "  -K         like -k, but do only step 1 of the Kerberos bind\n"
55 "  -M         enable Manage DSA IT control (-MM to make critical)\n"
56 "  -n         show what would be done but don't actually compare\n"
57 "  -O props   SASL security properties\n"
58 "  -p port    port on LDAP server\n"
59 "  -P version procotol version (default: 3)\n"
60 "  -z         Quiet mode, don't print anything, use return values\n"
61 "  -Q         use SASL Quiet mode\n"
62 "  -R realm   SASL realm\n"
63 "  -U authcid SASL authentication identity\n"
64 "  -v         run in verbose mode (diagnostics to standard output)\n"
65 "  -w passwd  bind passwd (for simple authentication)\n"
66 "  -W         prompt for bind passwd\n"
67 "  -x         Simple authentication\n"
68 "  -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
69 "  -Y mech    SASL mechanism\n"
70 "  -Z         Start TLS request (-ZZ to require successful response)\n"
71 , s );
72
73         exit( EXIT_FAILURE );
74 }
75
76 static int docompare LDAP_P((
77         LDAP *ld,
78         char *dn,
79         char *attr,
80         struct berval *bvalue,
81         int quiet,
82         LDAPControl **sctrls,
83         LDAPControl **cctrls));
84
85 static char *prog = NULL;
86 static char     *binddn = NULL;
87 static struct berval passwd = { 0, NULL };
88 static char     *ldaphost = NULL;
89 static char *ldapuri = NULL;
90 static int      ldapport = 0;
91 #ifdef HAVE_CYRUS_SASL
92 static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
93 static char     *sasl_realm = NULL;
94 static char     *sasl_authc_id = NULL;
95 static char     *sasl_authz_id = NULL;
96 static char     *sasl_mech = NULL;
97 static char     *sasl_secprops = NULL;
98 #endif
99 static int      use_tls = 0;
100 static int      verbose, not;
101
102 int
103 main( int argc, char **argv )
104 {
105         char    *compdn = NULL, *attrs = NULL;
106         char    *sep;
107         int             rc, i, manageDSAit, quiet;
108         int             referrals, debug;
109         int             authmethod, version, want_bindpw;
110         LDAP    *ld = NULL;
111         struct berval bvalue = { 0, NULL };
112
113         debug = verbose = not = referrals =
114                 manageDSAit = want_bindpw = quiet = 0;
115
116         version = -1;
117
118         authmethod = -1;
119
120         prog = lutil_progname( "ldapcompare", argc, argv );
121
122         while (( i = getopt( argc, argv,
123                 "Cd:D:h:H:IkKMnO:p:P:qQR:U:vw:WxX:Y:zZ")) != EOF )
124         {
125                 switch( i ) {
126
127                 /* Common Options */
128                 case 'C':
129                         referrals++;
130                         break;
131                 case 'd':
132                         debug |= atoi( optarg );
133                         break;
134                 case 'D':       /* bind DN */
135                         if( binddn != NULL ) {
136                                 fprintf( stderr, "%s: -D previously specified\n", prog );
137                                 return EXIT_FAILURE;
138                         }
139                         binddn = strdup( optarg );
140                         break;
141                 case 'h':       /* ldap host */
142                         if( ldapuri != NULL ) {
143                                 fprintf( stderr, "%s: -h incompatible with -H\n", prog );
144                                 return EXIT_FAILURE;
145                         }
146                         if( ldaphost != NULL ) {
147                                 fprintf( stderr, "%s: -h previously specified\n", prog );
148                                 return EXIT_FAILURE;
149                         }
150                         ldaphost = strdup( optarg );
151                         break;
152                 case 'H':       /* ldap URI */
153                         if( ldaphost != NULL ) {
154                                 fprintf( stderr, "%s: -H incompatible with -h\n", prog );
155                                 return EXIT_FAILURE;
156                         }
157                         if( ldapport ) {
158                                 fprintf( stderr, "%s: -H incompatible with -p\n", prog );
159                                 return EXIT_FAILURE;
160                         }
161                         if( ldapuri != NULL ) {
162                                 fprintf( stderr, "%s: -H previously specified\n", prog );
163                                 return EXIT_FAILURE;
164                         }
165                         ldapuri = strdup( optarg );
166                         break;
167                 case 'I':
168 #ifdef HAVE_CYRUS_SASL
169                         if( version == LDAP_VERSION2 ) {
170                                 fprintf( stderr, "%s: -I incompatible with version %d\n",
171                                         prog, version );
172                                 return EXIT_FAILURE;
173                         }
174                         if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
175                                 fprintf( stderr, "%s: incompatible previous "
176                                         "authentication choice\n",
177                                         prog );
178                                 return EXIT_FAILURE;
179                         }
180                         authmethod = LDAP_AUTH_SASL;
181                         version = LDAP_VERSION3;
182                         sasl_flags = LDAP_SASL_INTERACTIVE;
183                         break;
184 #else
185                         fprintf( stderr, "%s: was not compiled with SASL support\n",
186                                 prog );
187                         return( EXIT_FAILURE );
188 #endif
189                 case 'k':       /* kerberos bind */
190 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
191                         if( version > LDAP_VERSION2 ) {
192                                 fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
193                                         prog, version );
194                                 return EXIT_FAILURE;
195                         }
196
197                         if( authmethod != -1 ) {
198                                 fprintf( stderr, "%s: -k incompatible with previous "
199                                         "authentication choice\n", prog );
200                                 return EXIT_FAILURE;
201                         }
202
203                         authmethod = LDAP_AUTH_KRBV4;
204 #else
205                         fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
206                         return EXIT_FAILURE;
207 #endif
208                         break;
209                 case 'K':       /* kerberos bind, part one only */
210 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
211                         if( version > LDAP_VERSION2 ) {
212                                 fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
213                                         prog, version );
214                                 return EXIT_FAILURE;
215                         }
216                         if( authmethod != -1 ) {
217                                 fprintf( stderr, "%s: incompatible with previous "
218                                         "authentication choice\n", prog );
219                                 return EXIT_FAILURE;
220                         }
221
222                         authmethod = LDAP_AUTH_KRBV41;
223 #else
224                         fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
225                         return( EXIT_FAILURE );
226 #endif
227                         break;
228                 case 'M':
229                         /* enable Manage DSA IT */
230                         if( version == LDAP_VERSION2 ) {
231                                 fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
232                                         prog, version );
233                                 return EXIT_FAILURE;
234                         }
235                         manageDSAit++;
236                         version = LDAP_VERSION3;
237                         break;
238                 case 'n':       /* print compares, don't actually do them */
239                         ++not;
240                         break;
241                 case 'O':
242 #ifdef HAVE_CYRUS_SASL
243                         if( sasl_secprops != NULL ) {
244                                 fprintf( stderr, "%s: -O previously specified\n", prog );
245                                 return EXIT_FAILURE;
246                         }
247                         if( version == LDAP_VERSION2 ) {
248                                 fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
249                                         prog, version );
250                                 return EXIT_FAILURE;
251                         }
252                         if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
253                                 fprintf( stderr, "%s: incompatible previous "
254                                         "authentication choice\n", prog );
255                                 return EXIT_FAILURE;
256                         }
257                         authmethod = LDAP_AUTH_SASL;
258                         version = LDAP_VERSION3;
259                         sasl_secprops = strdup( optarg );
260 #else
261                         fprintf( stderr, "%s: not compiled with SASL support\n",
262                                 prog );
263                         return( EXIT_FAILURE );
264 #endif
265                         break;
266                 case 'p':
267                         if( ldapport ) {
268                                 fprintf( stderr, "%s: -p previously specified\n", prog );
269                                 return EXIT_FAILURE;
270                         }
271                         ldapport = atoi( optarg );
272                         break;
273                 case 'P':
274                         switch( atoi(optarg) ) {
275                         case 2:
276                                 if( version == LDAP_VERSION3 ) {
277                                         fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
278                                                 prog, version );
279                                         return EXIT_FAILURE;
280                                 }
281                                 version = LDAP_VERSION2;
282                                 break;
283                         case 3:
284                                 if( version == LDAP_VERSION2 ) {
285                                         fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
286                                                 prog, version );
287                                         return EXIT_FAILURE;
288                                 }
289                                 version = LDAP_VERSION3;
290                                 break;
291                         default:
292                                 fprintf( stderr, "%s: protocol version should be 2 or 3\n",
293                                         prog );
294                                 usage( prog );
295                                 return( EXIT_FAILURE );
296                         } break;
297                 case 'Q':
298 #ifdef HAVE_CYRUS_SASL
299                         if( version == LDAP_VERSION2 ) {
300                                 fprintf( stderr, "%s: -Q incompatible with version %d\n",
301                                         prog, version );
302                                 return EXIT_FAILURE;
303                         }
304                         if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
305                                 fprintf( stderr, "%s: incompatible previous "
306                                         "authentication choice\n",
307                                         prog );
308                                 return EXIT_FAILURE;
309                         }
310                         authmethod = LDAP_AUTH_SASL;
311                         version = LDAP_VERSION3;
312                         sasl_flags = LDAP_SASL_QUIET;
313                         break;
314 #else
315                         fprintf( stderr, "%s: not compiled with SASL support\n",
316                                 prog );
317                         return( EXIT_FAILURE );
318 #endif
319                 case 'R':
320 #ifdef HAVE_CYRUS_SASL
321                         if( sasl_realm != NULL ) {
322                                 fprintf( stderr, "%s: -R previously specified\n", prog );
323                                 return EXIT_FAILURE;
324                         }
325                         if( version == LDAP_VERSION2 ) {
326                                 fprintf( stderr, "%s: -R incompatible with version %d\n",
327                                         prog, version );
328                                 return EXIT_FAILURE;
329                         }
330                         if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
331                                 fprintf( stderr, "%s: incompatible previous "
332                                         "authentication choice\n",
333                                         prog );
334                                 return EXIT_FAILURE;
335                         }
336                         authmethod = LDAP_AUTH_SASL;
337                         version = LDAP_VERSION3;
338                         sasl_realm = strdup( optarg );
339 #else
340                         fprintf( stderr, "%s: not compiled with SASL support\n",
341                                 prog );
342                         return( EXIT_FAILURE );
343 #endif
344                         break;
345         case 'U':
346 #ifdef HAVE_CYRUS_SASL
347                         if( sasl_authc_id != NULL ) {
348                                 fprintf( stderr, "%s: -U previously specified\n", prog );
349                                 return EXIT_FAILURE;
350                         }
351                         if( version == LDAP_VERSION2 ) {
352                                 fprintf( stderr, "%s: -U incompatible with version %d\n",
353                                         prog, version );
354                                 return EXIT_FAILURE;
355                         }
356                         if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
357                                 fprintf( stderr, "%s: incompatible previous "
358                                         "authentication choice\n",
359                                         prog );
360                                 return EXIT_FAILURE;
361                         }
362                         authmethod = LDAP_AUTH_SASL;
363                         version = LDAP_VERSION3;
364                         sasl_authc_id = strdup( optarg );
365 #else
366                         fprintf( stderr, "%s: not compiled with SASL support\n",
367                                 prog );
368                         return( EXIT_FAILURE );
369 #endif
370                         break;
371                 case 'v':       /* verbose mode */
372                         verbose++;
373                         break;
374                 case 'w':       /* password */
375                         passwd.bv_val = strdup( optarg );
376                         {
377                                 char* p;
378
379                                 for( p = optarg; *p != '\0'; p++ ) {
380                                         *p = '\0';
381                                 }
382                         }
383                         passwd.bv_len = strlen( passwd.bv_val );
384                         break;
385                 case 'W':
386                         want_bindpw++;
387                         break;
388                 case 'Y':
389 #ifdef HAVE_CYRUS_SASL
390                         if( sasl_mech != NULL ) {
391                                 fprintf( stderr, "%s: -Y previously specified\n", prog );
392                                 return EXIT_FAILURE;
393                         }
394                         if( version == LDAP_VERSION2 ) {
395                                 fprintf( stderr, "%s: -Y incompatible with version %d\n",
396                                         prog, version );
397                                 return EXIT_FAILURE;
398                         }
399                         if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
400                                 fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
401                                 return EXIT_FAILURE;
402                         }
403                         authmethod = LDAP_AUTH_SASL;
404                         version = LDAP_VERSION3;
405                         sasl_mech = strdup( optarg );
406 #else
407                         fprintf( stderr, "%s: not compiled with SASL support\n",
408                                 prog );
409                         return( EXIT_FAILURE );
410 #endif
411                         break;
412                 case 'x':
413                         if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
414                                 fprintf( stderr, "%s: incompatible with previous "
415                                         "authentication choice\n", prog );
416                                 return EXIT_FAILURE;
417                         }
418                         authmethod = LDAP_AUTH_SIMPLE;
419                         break;
420                 case 'X':
421 #ifdef HAVE_CYRUS_SASL
422                         if( sasl_authz_id != NULL ) {
423                                 fprintf( stderr, "%s: -X previously specified\n", prog );
424                                 return EXIT_FAILURE;
425                         }
426                         if( version == LDAP_VERSION2 ) {
427                                 fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
428                                         prog, version );
429                                 return EXIT_FAILURE;
430                         }
431                         if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
432                                 fprintf( stderr, "%s: -X incompatible with "
433                                         "authentication choice\n", prog );
434                                 return EXIT_FAILURE;
435                         }
436                         authmethod = LDAP_AUTH_SASL;
437                         version = LDAP_VERSION3;
438                         sasl_authz_id = strdup( optarg );
439 #else
440                         fprintf( stderr, "%s: not compiled with SASL support\n",
441                                 prog );
442                         return( EXIT_FAILURE );
443 #endif
444                         break;
445                 case 'z':
446                         quiet++;
447                         break;
448                 case 'Z':
449 #ifdef HAVE_TLS
450                         if( version == LDAP_VERSION2 ) {
451                                 fprintf( stderr, "%s: -Z incompatible with version %d\n",
452                                         prog, version );
453                                 return EXIT_FAILURE;
454                         }
455                         version = LDAP_VERSION3;
456                         use_tls++;
457 #else
458                         fprintf( stderr, "%s: not compiled with TLS support\n",
459                                 prog );
460                         return( EXIT_FAILURE );
461 #endif
462                         break;
463                 default:
464                         fprintf( stderr, "%s: unrecognized option -%c\n",
465                                 prog, optopt );
466                         usage( argv[0] );
467                 }
468         }
469
470         if (version == -1) {
471                 version = LDAP_VERSION3;
472         }
473         if (authmethod == -1 && version > LDAP_VERSION2) {
474 #ifdef HAVE_CYRUS_SASL
475                 authmethod = LDAP_AUTH_SASL;
476 #else
477                 authmethod = LDAP_AUTH_SIMPLE;
478 #endif
479         }
480
481         if ( argc - optind != 2 ) {
482                 usage( argv[ 0 ] );
483         }
484
485         compdn = argv[optind++];
486         attrs = argv[optind++];
487
488         /* user passed in only 2 args, the last one better be in
489          * the form attr:value or attr::b64value
490          */
491         sep = strchr(attrs, ':');
492         if (!sep) {
493                 usage( argv[ 0 ] );
494         }
495
496         *sep++='\0';
497         if ( *sep != ':' ) {
498                 bvalue.bv_val = strdup( sep );
499                 bvalue.bv_len = strlen( bvalue.bv_val );
500
501         } else {
502                 /* it's base64 encoded. */
503                 bvalue.bv_val = malloc( strlen( &sep[1] ));
504                 bvalue.bv_len = lutil_b64_pton( &sep[1],
505                         bvalue.bv_val, strlen( &sep[1] ));
506
507                 if (bvalue.bv_len == -1) {
508                         fprintf(stderr, "base64 decode error\n");
509                         exit(-1);
510                 }
511         }
512
513         if ( debug ) {
514                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug )
515                         != LBER_OPT_SUCCESS )
516                 {
517                         fprintf( stderr,
518                                 "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
519                 }
520                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug )
521                         != LDAP_OPT_SUCCESS )
522                 {
523                         fprintf( stderr,
524                                 "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
525                 }
526                 ldif_debug = debug;
527         }
528
529 #ifdef SIGPIPE
530         (void) SIGNAL( SIGPIPE, SIG_IGN );
531 #endif
532
533         if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
534                 if ( verbose ) {
535                         fprintf( stderr, "ldap_init( %s, %d )\n",
536                                 ldaphost != NULL ? ldaphost : "<DEFAULT>",
537                                 ldapport );
538                 }
539
540                 ld = ldap_init( ldaphost, ldapport );
541                 if( ld == NULL ) {
542                         perror("ldapcompare: ldap_init");
543                         return EXIT_FAILURE;
544                 }
545
546         } else {
547                 if ( verbose ) {
548                         fprintf( stderr, "ldap_initialize( %s )\n",
549                                 ldapuri != NULL ? ldapuri : "<DEFAULT>" );
550                 }
551
552                 rc = ldap_initialize( &ld, ldapuri );
553                 if( rc != LDAP_SUCCESS ) {
554                         fprintf( stderr,
555                                 "Could not create LDAP session handle (%d): %s\n",
556                                 rc, ldap_err2string(rc) );
557                         return EXIT_FAILURE;
558                 }
559         }
560
561
562         /* referrals */
563         if (ldap_set_option( ld, LDAP_OPT_REFERRALS,
564                 referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
565         {
566                 fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
567                         referrals ? "on" : "off" );
568                 return EXIT_FAILURE;
569         }
570
571         if (version == -1 ) {
572                 version = LDAP_VERSION3;
573         }
574
575         if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
576                 != LDAP_OPT_SUCCESS )
577         {
578                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
579                         version );
580                 return EXIT_FAILURE;
581         }
582
583         if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
584                 ldap_perror( ld, "ldap_start_tls" );
585                 if ( use_tls > 1 ) {
586                         return EXIT_FAILURE;
587                 }
588         }
589
590         if (want_bindpw) {
591                 passwd.bv_val = getpassphrase("Enter LDAP Password: ");
592                 passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
593         }
594
595         if ( authmethod == LDAP_AUTH_SASL ) {
596 #ifdef HAVE_CYRUS_SASL
597                 void *defaults;
598
599                 if( sasl_secprops != NULL ) {
600                         rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
601                                 (void *) sasl_secprops );
602
603                         if( rc != LDAP_OPT_SUCCESS ) {
604                                 fprintf( stderr,
605                                         "Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
606                                         sasl_secprops );
607                                 return EXIT_FAILURE;
608                         }
609                 }
610
611                 defaults = lutil_sasl_defaults( ld,
612                         sasl_mech,
613                         sasl_realm,
614                         sasl_authc_id,
615                         passwd.bv_val,
616                         sasl_authz_id );
617
618                 rc = ldap_sasl_interactive_bind_s( ld, binddn,
619                         sasl_mech, NULL, NULL,
620                         sasl_flags, lutil_sasl_interact, defaults );
621
622                 if( rc != LDAP_SUCCESS ) {
623                         ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
624                         return EXIT_FAILURE;
625                 }
626 #else
627                 fprintf( stderr, "%s: not compiled with SASL support\n",
628                         prog, argv[0] );
629                 return EXIT_FAILURE;
630 #endif
631         } else {
632                 if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
633                                 != LDAP_SUCCESS ) {
634                         ldap_perror( ld, "ldap_bind" );
635                         return EXIT_FAILURE;
636                 }
637         }
638
639         if ( manageDSAit ) {
640                 int err;
641                 LDAPControl c;
642                 LDAPControl *ctrls[2];
643                 ctrls[0] = &c;
644                 ctrls[1] = NULL;
645
646                 c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
647                 c.ldctl_value.bv_val = NULL;
648                 c.ldctl_value.bv_len = 0;
649                 c.ldctl_iscritical = manageDSAit > 1;
650
651                 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
652
653                 if( err != LDAP_OPT_SUCCESS ) {
654                         fprintf( stderr, "Could not set ManageDSAit %scontrol\n",
655                                 c.ldctl_iscritical ? "critical " : "" );
656                         if( c.ldctl_iscritical ) {
657                                 return EXIT_FAILURE;
658                         }
659                 }
660         }
661
662         if ( verbose ) {
663                 fprintf( stderr, "DN:%s, attr:%s, value:%s\n",
664                         compdn, attrs, sep );
665         }
666
667         rc = docompare( ld, compdn, attrs, &bvalue, quiet, NULL, NULL );
668
669         free( bvalue.bv_val );
670
671         ldap_unbind( ld );
672
673         return rc;
674 }
675
676
677 static int docompare(
678         LDAP *ld,
679         char *dn,
680         char *attr,
681         struct berval *bvalue,
682         int quiet,
683         LDAPControl **sctrls,
684         LDAPControl **cctrls )
685 {
686         int                     rc;
687
688         if ( not ) {
689                 return LDAP_SUCCESS;
690         }
691
692         rc = ldap_compare_ext_s( ld, dn, attr, bvalue,
693                 sctrls, cctrls );
694
695         if ( rc == -1 ) {
696                 ldap_perror( ld, "ldap_result" );
697                 return( rc );
698         }
699
700         /* if we were told to be quiet, use the return value. */
701         if ( !quiet ) {
702                 if ( rc == LDAP_COMPARE_TRUE ) {
703                         rc = 0;
704                         printf("TRUE\n");
705                 } else if ( rc == LDAP_COMPARE_FALSE ) {
706                         rc = 0;
707                         printf("FALSE\n");
708                 } else {
709                         ldap_perror( ld, "ldap_compare" );
710                 }
711         }
712
713         return( rc );
714 }
715