1 /* ldapsearch -- a tool for searching LDAP directories */
2 /* $OpenLDAP: pkg/ldap/clients/tools/ldapsearch.c,v 1.234.2.9 2008/02/12 19:59:52 quanah Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2008 The OpenLDAP Foundation.
6 * Portions Copyright 1998-2003 Kurt D. Zeilenga.
7 * Portions Copyright 1998-2001 Net Boolean Incorporated.
8 * Portions Copyright 2001-2003 IBM Corporation.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted only as authorized by the OpenLDAP
15 * A copy of this license is available in the file LICENSE in the
16 * top-level directory of the distribution or, alternatively, at
17 * <http://www.OpenLDAP.org/license.html>.
19 /* Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
20 * All rights reserved.
22 * Redistribution and use in source and binary forms are permitted
23 * provided that this notice is preserved and that due credit is given
24 * to the University of Michigan at Ann Arbor. The name of the
25 * University may not be used to endorse or promote products derived
26 * from this software without specific prior written permission. This
27 * software is provided ``as is'' without express or implied warranty.
30 * This work was originally developed by the University of Michigan
31 * (as part of U-MICH LDAP). Additional significant contributors
43 #include <ac/stdlib.h>
46 #include <ac/string.h>
47 #include <ac/unistd.h>
51 #include <ac/signal.h>
56 #ifdef HAVE_SYS_TYPES_H
57 #include <sys/types.h>
67 #include "lutil_ldap.h"
68 #include "ldap_defaults.h"
76 * NOTE: we use this deprecated function only because
77 * we want ldapsearch to provide some client-side sorting
81 typedef int (LDAP_SORT_AD_CMP_PROC
) LDAP_P(( /* deprecated */
82 LDAP_CONST
char *left
,
83 LDAP_CONST
char *right
));
85 LDAP_F( int ) /* deprecated */
86 ldap_sort_entries
LDAP_P(( LDAP
*ld
,
88 LDAP_CONST
char *attr
,
89 LDAP_SORT_AD_CMP_PROC
*cmp
));
92 static int scope
= LDAP_SCOPE_SUBTREE
;
93 static int deref
= -1;
95 static int timelimit
= -1;
96 static int sizelimit
= -1;
100 static char *def_tmpdir
;
101 static char *def_urlpre
;
103 #if defined(__CYGWIN__) || defined(__MINGW32__)
104 /* Turn off commandline globbing, otherwise you cannot search for
113 fprintf( stderr
, _("usage: %s [options] [filter [attributes...]]\nwhere:\n"), prog
);
114 fprintf( stderr
, _(" filter\tRFC 4515 compliant LDAP search filter\n"));
115 fprintf( stderr
, _(" attributes\twhitespace-separated list of attribute descriptions\n"));
116 fprintf( stderr
, _(" which may include:\n"));
117 fprintf( stderr
, _(" 1.1 no attributes\n"));
118 fprintf( stderr
, _(" * all user attributes\n"));
119 fprintf( stderr
, _(" + all operational attributes\n"));
122 fprintf( stderr
, _("Search options:\n"));
123 fprintf( stderr
, _(" -a deref one of never (default), always, search, or find\n"));
124 fprintf( stderr
, _(" -A retrieve attribute names only (no values)\n"));
125 fprintf( stderr
, _(" -b basedn base dn for search\n"));
126 fprintf( stderr
, _(" -E [!]<ext>[=<extparam>] search extensions (! indicates criticality)\n"));
127 fprintf( stderr
, _(" [!]domainScope (domain scope)\n"));
128 fprintf( stderr
, _(" !dontUseCopy (Don't Use Copy)\n"));
129 fprintf( stderr
, _(" [!]mv=<filter> (matched values filter)\n"));
130 fprintf( stderr
, _(" [!]pr=<size>[/prompt|noprompt] (paged results/prompt)\n"));
131 fprintf( stderr
, _(" [!]subentries[=true|false] (subentries)\n"));
132 fprintf( stderr
, _(" [!]sync=ro[/<cookie>] (LDAP Sync refreshOnly)\n"));
133 fprintf( stderr
, _(" rp[/<cookie>][/<slimit>] (LDAP Sync refreshAndPersist)\n"));
134 fprintf( stderr
, _(" [!]<oid>=:<value> (generic control; no response handling)\n"));
135 fprintf( stderr
, _(" -F prefix URL prefix for files (default: %s)\n"), def_urlpre
);
136 fprintf( stderr
, _(" -l limit time limit (in seconds, or \"none\" or \"max\") for search\n"));
137 fprintf( stderr
, _(" -L print responses in LDIFv1 format\n"));
138 fprintf( stderr
, _(" -LL print responses in LDIF format without comments\n"));
139 fprintf( stderr
, _(" -LLL print responses in LDIF format without comments\n"));
140 fprintf( stderr
, _(" and version\n"));
141 fprintf( stderr
, _(" -s scope one of base, one, sub or children (search scope)\n"));
142 fprintf( stderr
, _(" -S attr sort the results by attribute `attr'\n"));
143 fprintf( stderr
, _(" -t write binary values to files in temporary directory\n"));
144 fprintf( stderr
, _(" -tt write all values to files in temporary directory\n"));
145 fprintf( stderr
, _(" -T path write files to directory specified by path (default: %s)\n"), def_tmpdir
);
146 fprintf( stderr
, _(" -u include User Friendly entry names in the output\n"));
147 fprintf( stderr
, _(" -z limit size limit (in entries, or \"none\" or \"max\") for search\n"));
149 exit( EXIT_FAILURE
);
152 static void print_entry
LDAP_P((
157 static void print_reference(
159 LDAPMessage
*reference
);
161 static void print_extended(
163 LDAPMessage
*extended
);
165 static void print_partial(
167 LDAPMessage
*partial
);
169 static int print_result(
174 static int dosearch
LDAP_P((
182 LDAPControl
**sctrls
,
183 LDAPControl
**cctrls
,
184 struct timeval
*timeout
,
187 static char *tmpdir
= NULL
;
188 static char *urlpre
= NULL
;
189 static char *base
= NULL
;
190 static char *sortattr
= NULL
;
191 static int includeufn
, vals2tmp
= 0;
193 static int subentries
= 0, valuesReturnFilter
= 0;
194 static char *vrFilter
= NULL
;
196 #ifdef LDAP_CONTROL_DONTUSECOPY
197 static int dontUseCopy
= 0;
200 static int domainScope
= 0;
202 static int ldapsync
= 0;
203 static struct berval sync_cookie
= { 0, NULL
};
204 static int sync_slimit
= -1;
206 /* cookie and morePagedResults moved to common.c */
207 static int pagedResults
= 0;
208 static int pagePrompt
= 1;
209 static ber_int_t pageSize
= 0;
210 static ber_int_t entriesLeft
= 0;
211 static int npagedresponses
;
212 static int npagedentries
;
213 static int npagedreferences
;
214 static int npagedextended
;
215 static int npagedpartial
;
217 static LDAPControl
*c
= NULL
;
218 static int nctrls
= 0;
219 static int save_nctrls
= 0;
227 tmpc
= realloc( c
, sizeof( LDAPControl
) * nctrls
);
228 if ( tmpc
== NULL
) {
231 _("unable to make room for control; out of memory?\n"));
244 if (*LDAP_DIRSEP
!= '/') {
245 for (p
= url
; *p
; p
++) {
246 if (*p
== *LDAP_DIRSEP
)
253 const char options
[] = "a:Ab:cE:F:l:Ls:S:tT:uz:"
254 "Cd:D:e:f:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
257 handle_private_option( int i
)
262 case 'a': /* set alias deref option */
263 if ( strcasecmp( optarg
, "never" ) == 0 ) {
264 deref
= LDAP_DEREF_NEVER
;
265 } else if ( strncasecmp( optarg
, "search", sizeof("search")-1 ) == 0 ) {
266 deref
= LDAP_DEREF_SEARCHING
;
267 } else if ( strncasecmp( optarg
, "find", sizeof("find")-1 ) == 0 ) {
268 deref
= LDAP_DEREF_FINDING
;
269 } else if ( strcasecmp( optarg
, "always" ) == 0 ) {
270 deref
= LDAP_DEREF_ALWAYS
;
273 _("alias deref should be never, search, find, or always\n") );
277 case 'A': /* retrieve attribute names only -- no values */
280 case 'b': /* search base */
281 base
= ber_strdup( optarg
);
283 case 'E': /* search extensions */
284 if( protocol
== LDAP_VERSION2
) {
285 fprintf( stderr
, _("%s: -E incompatible with LDAPv%d\n"),
287 exit( EXIT_FAILURE
);
290 /* should be extended to support comma separated list of
291 * [!]key[=value] parameters, e.g. -E !foo,bar=567
296 if( optarg
[0] == '!' ) {
301 control
= ber_strdup( optarg
);
302 if ( (cvalue
= strchr( control
, '=' )) != NULL
) {
306 if ( strcasecmp( control
, "mv" ) == 0 ) {
307 /* ValuesReturnFilter control */
308 if( valuesReturnFilter
) {
310 _("ValuesReturnFilter previously specified\n"));
311 exit( EXIT_FAILURE
);
313 valuesReturnFilter
= 1 + crit
;
315 if ( cvalue
== NULL
) {
317 _("missing filter in ValuesReturnFilter control\n"));
318 exit( EXIT_FAILURE
);
322 protocol
= LDAP_VERSION3
;
324 } else if ( strcasecmp( control
, "pr" ) == 0 ) {
326 /* PagedResults control */
327 if ( pagedResults
!= 0 ) {
329 _("PagedResultsControl previously specified\n") );
330 exit( EXIT_FAILURE
);
333 if( cvalue
!= NULL
) {
336 promptp
= strchr( cvalue
, '/' );
337 if ( promptp
!= NULL
) {
339 if ( strcasecmp( promptp
, "prompt" ) == 0 ) {
341 } else if ( strcasecmp( promptp
, "noprompt" ) == 0) {
345 _("Invalid value for PagedResultsControl,"
346 " %s/%s.\n"), cvalue
, promptp
);
347 exit( EXIT_FAILURE
);
350 num
= sscanf( cvalue
, "%d", &tmp
);
353 _("Invalid value for PagedResultsControl, %s.\n"),
355 exit( EXIT_FAILURE
);
358 fprintf(stderr
, _("Invalid value for PagedResultsControl.\n"));
359 exit( EXIT_FAILURE
);
361 pageSize
= (ber_int_t
) tmp
;
362 pagedResults
= 1 + crit
;
364 #ifdef LDAP_CONTROL_DONTUSECOPY
365 } else if ( strcasecmp( control
, "dontUseCopy" ) == 0 ) {
368 _("dontUseCopy control previously specified\n"));
369 exit( EXIT_FAILURE
);
371 if( cvalue
!= NULL
) {
373 _("dontUseCopy: no control value expected\n") );
378 _("dontUseCopy: critical flag required\n") );
382 dontUseCopy
= 1 + crit
;
384 } else if ( strcasecmp( control
, "domainScope" ) == 0 ) {
387 _("domainScope control previously specified\n"));
388 exit( EXIT_FAILURE
);
390 if( cvalue
!= NULL
) {
392 _("domainScope: no control value expected\n") );
396 domainScope
= 1 + crit
;
398 } else if ( strcasecmp( control
, "subentries" ) == 0 ) {
401 _("subentries control previously specified\n"));
402 exit( EXIT_FAILURE
);
404 if( cvalue
== NULL
|| strcasecmp( cvalue
, "true") == 0 ) {
406 } else if ( strcasecmp( cvalue
, "false") == 0 ) {
410 _("subentries control value \"%s\" invalid\n"),
412 exit( EXIT_FAILURE
);
414 if( crit
) subentries
*= -1;
416 } else if ( strcasecmp( control
, "sync" ) == 0 ) {
420 fprintf( stderr
, _("sync control previously specified\n") );
421 exit( EXIT_FAILURE
);
423 if ( cvalue
== NULL
) {
424 fprintf( stderr
, _("missing specification of sync control\n"));
425 exit( EXIT_FAILURE
);
427 if ( strncasecmp( cvalue
, "ro", 2 ) == 0 ) {
428 ldapsync
= LDAP_SYNC_REFRESH_ONLY
;
429 cookiep
= strchr( cvalue
, '/' );
430 if ( cookiep
!= NULL
) {
432 if ( *cookiep
!= '\0' ) {
433 ber_str2bv( cookiep
, 0, 0, &sync_cookie
);
436 } else if ( strncasecmp( cvalue
, "rp", 2 ) == 0 ) {
437 ldapsync
= LDAP_SYNC_REFRESH_AND_PERSIST
;
438 cookiep
= strchr( cvalue
, '/' );
439 if ( cookiep
!= NULL
) {
443 slimitp
= strchr( cvalue
, '/' );
444 if ( slimitp
!= NULL
) {
447 if ( cookiep
!= NULL
&& *cookiep
!= '\0' )
448 ber_str2bv( cookiep
, 0, 0, &sync_cookie
);
449 if ( slimitp
!= NULL
&& *slimitp
!= '\0' ) {
450 ival
= strtol( slimitp
, &next
, 10 );
451 if ( next
== NULL
|| next
[0] != '\0' ) {
452 fprintf( stderr
, _("Unable to parse sync control value \"%s\"\n"), slimitp
);
453 exit( EXIT_FAILURE
);
458 fprintf( stderr
, _("sync control value \"%s\" invalid\n"),
460 exit( EXIT_FAILURE
);
462 if ( crit
) ldapsync
*= -1;
464 } else if ( tool_is_oid( control
) ) {
466 exit( EXIT_FAILURE
);
470 c
[ nctrls
- 1 ].ldctl_oid
= control
;
473 if ( cvalue
== NULL
) {
474 c
[ nctrls
- 1 ].ldctl_value
.bv_val
= NULL
;
475 c
[ nctrls
- 1 ].ldctl_value
.bv_len
= 0;
477 } else if ( cvalue
[ 0 ] == ':' ) {
485 * to use ldif_parse_line2() */
487 ldif_parse_line2( &cvalue
[ -2 ], &type
,
492 c
[ nctrls
- 1 ].ldctl_value
= value
;
495 ber_dupbv( &c
[ nctrls
- 1 ].ldctl_value
, &value
);
500 c
[ nctrls
- 1 ].ldctl_iscritical
= crit
;
503 fprintf( stderr
, _("Invalid search extension name: %s\n"),
508 case 'F': /* uri prefix */
509 if( urlpre
) free( urlpre
);
510 urlpre
= strdup( optarg
);
512 case 'l': /* time limit */
513 if ( strcasecmp( optarg
, "none" ) == 0 ) {
516 } else if ( strcasecmp( optarg
, "max" ) == 0 ) {
517 timelimit
= LDAP_MAXINT
;
520 ival
= strtol( optarg
, &next
, 10 );
521 if ( next
== NULL
|| next
[0] != '\0' ) {
523 _("Unable to parse time limit \"%s\"\n"), optarg
);
524 exit( EXIT_FAILURE
);
528 if( timelimit
< 0 || timelimit
> LDAP_MAXINT
) {
529 fprintf( stderr
, _("%s: invalid timelimit (%d) specified\n"),
531 exit( EXIT_FAILURE
);
534 case 'L': /* print entries in LDIF format */
537 case 's': /* search scope */
538 if ( strncasecmp( optarg
, "base", sizeof("base")-1 ) == 0 ) {
539 scope
= LDAP_SCOPE_BASE
;
540 } else if ( strncasecmp( optarg
, "one", sizeof("one")-1 ) == 0 ) {
541 scope
= LDAP_SCOPE_ONELEVEL
;
542 } else if (( strcasecmp( optarg
, "subordinate" ) == 0 )
543 || ( strcasecmp( optarg
, "children" ) == 0 ))
545 scope
= LDAP_SCOPE_SUBORDINATE
;
546 } else if ( strncasecmp( optarg
, "sub", sizeof("sub")-1 ) == 0 ) {
547 scope
= LDAP_SCOPE_SUBTREE
;
549 fprintf( stderr
, _("scope should be base, one, or sub\n") );
553 case 'S': /* sort attribute */
554 sortattr
= strdup( optarg
);
556 case 't': /* write attribute values to TMPDIR files */
559 case 'T': /* tmpdir */
560 if( tmpdir
) free( tmpdir
);
561 tmpdir
= strdup( optarg
);
563 case 'u': /* include UFN */
566 case 'z': /* size limit */
567 if ( strcasecmp( optarg
, "none" ) == 0 ) {
570 } else if ( strcasecmp( optarg
, "max" ) == 0 ) {
571 sizelimit
= LDAP_MAXINT
;
574 ival
= strtol( optarg
, &next
, 10 );
575 if ( next
== NULL
|| next
[0] != '\0' ) {
577 _("Unable to parse size limit \"%s\"\n"), optarg
);
578 exit( EXIT_FAILURE
);
582 if( sizelimit
< 0 || sizelimit
> LDAP_MAXINT
) {
583 fprintf( stderr
, _("%s: invalid sizelimit (%d) specified\n"),
585 exit( EXIT_FAILURE
);
596 private_conn_setup( LDAP
*ld
)
599 ldap_set_option( ld
, LDAP_OPT_DEREF
, (void *) &deref
)
600 != LDAP_OPT_SUCCESS
)
602 fprintf( stderr
, _("Could not set LDAP_OPT_DEREF %d\n"), deref
);
603 exit( EXIT_FAILURE
);
606 ldap_set_option( ld
, LDAP_OPT_TIMELIMIT
, (void *) &timelimit
)
607 != LDAP_OPT_SUCCESS
)
610 _("Could not set LDAP_OPT_TIMELIMIT %d\n"), timelimit
);
611 exit( EXIT_FAILURE
);
614 ldap_set_option( ld
, LDAP_OPT_SIZELIMIT
, (void *) &sizelimit
)
615 != LDAP_OPT_SUCCESS
)
618 _("Could not set LDAP_OPT_SIZELIMIT %d\n"), sizelimit
);
619 exit( EXIT_FAILURE
);
624 main( int argc
, char **argv
)
626 char *filtpattern
, **attrs
= NULL
, line
[BUFSIZ
];
628 int rc
, rc1
, i
, first
;
630 BerElement
*seber
= NULL
, *vrber
= NULL
;
632 BerElement
*syncber
= NULL
;
633 struct berval
*syncbvalp
= NULL
;
636 tool_init( TOOL_SEARCH
);
638 npagedresponses
= npagedentries
= npagedreferences
=
639 npagedextended
= npagedpartial
= 0;
641 prog
= lutil_progname( "ldapsearch", argc
, argv
);
643 if((def_tmpdir
= getenv("TMPDIR")) == NULL
&&
644 (def_tmpdir
= getenv("TMP")) == NULL
&&
645 (def_tmpdir
= getenv("TEMP")) == NULL
)
647 def_tmpdir
= LDAP_TMPDIR
;
651 def_tmpdir
= LDAP_TMPDIR
;
653 def_urlpre
= malloc( sizeof("file:////") + strlen(def_tmpdir
) );
655 if( def_urlpre
== NULL
) {
660 sprintf( def_urlpre
, "file:///%s/",
661 def_tmpdir
[0] == *LDAP_DIRSEP
? &def_tmpdir
[1] : def_tmpdir
);
663 urlize( def_urlpre
);
665 tool_args( argc
, argv
);
667 if (( argc
- optind
< 1 ) ||
668 ( *argv
[optind
] != '(' /*')'*/ &&
669 ( strchr( argv
[optind
], '=' ) == NULL
) ) )
671 filtpattern
= "(objectclass=*)";
673 filtpattern
= argv
[optind
++];
676 if ( argv
[optind
] != NULL
) {
677 attrs
= &argv
[optind
];
680 if ( infile
!= NULL
) {
683 if ( infile
[0] == '-' && infile
[1] == '\0' ) {
685 } else if (( fp
= fopen( infile
, "r" )) == NULL
) {
690 for( i
=0 ; filtpattern
[i
] ; i
++ ) {
691 if( filtpattern
[i
] == '%' ) {
693 fprintf( stderr
, _("Bad filter pattern \"%s\"\n"),
700 if( filtpattern
[i
+1] != 's' ) {
701 fprintf( stderr
, _("Bad filter pattern \"%s\"\n"),
709 if ( tmpdir
== NULL
) {
712 if ( urlpre
== NULL
)
716 if( urlpre
== NULL
) {
717 urlpre
= malloc( sizeof("file:////") + strlen(tmpdir
) );
719 if( urlpre
== NULL
) {
724 sprintf( urlpre
, "file:///%s/",
725 tmpdir
[0] == *LDAP_DIRSEP
? &tmpdir
[1] : tmpdir
);
733 ld
= tool_conn_setup( 0, &private_conn_setup
);
735 if ( pw_file
|| want_bindpw
) {
737 rc
= lutil_get_filed_password( pw_file
, &passwd
);
738 if( rc
) return EXIT_FAILURE
;
740 passwd
.bv_val
= getpassphrase( _("Enter LDAP Password: ") );
741 passwd
.bv_len
= passwd
.bv_val
? strlen( passwd
.bv_val
) : 0;
748 save_nctrls
= nctrls
;
751 #ifdef LDAP_CONTROL_DONTUSECOPY
758 || valuesReturnFilter
)
761 #ifdef LDAP_CONTROL_DONTUSECOPY
767 c
[i
].ldctl_oid
= LDAP_CONTROL_DONTUSECOPY
;
768 c
[i
].ldctl_value
.bv_val
= NULL
;
769 c
[i
].ldctl_value
.bv_len
= 0;
770 c
[i
].ldctl_iscritical
= dontUseCopy
> 1;
780 c
[i
].ldctl_oid
= LDAP_CONTROL_X_DOMAIN_SCOPE
;
781 c
[i
].ldctl_value
.bv_val
= NULL
;
782 c
[i
].ldctl_value
.bv_len
= 0;
783 c
[i
].ldctl_iscritical
= domainScope
> 1;
792 if (( seber
= ber_alloc_t(LBER_USE_DER
)) == NULL
) {
796 err
= ber_printf( seber
, "b", abs(subentries
) == 1 ? 0 : 1 );
798 ber_free( seber
, 1 );
799 fprintf( stderr
, _("Subentries control encoding error!\n") );
803 if ( ber_flatten2( seber
, &c
[i
].ldctl_value
, 0 ) == -1 ) {
807 c
[i
].ldctl_oid
= LDAP_CONTROL_SUBENTRIES
;
808 c
[i
].ldctl_iscritical
= subentries
< 1;
817 if (( syncber
= ber_alloc_t(LBER_USE_DER
)) == NULL
) {
821 if ( sync_cookie
.bv_len
== 0 ) {
822 err
= ber_printf( syncber
, "{e}", abs(ldapsync
) );
824 err
= ber_printf( syncber
, "{eO}", abs(ldapsync
),
828 if ( err
== LBER_ERROR
) {
829 ber_free( syncber
, 1 );
830 fprintf( stderr
, _("ldap sync control encoding error!\n") );
834 if ( ber_flatten( syncber
, &syncbvalp
) == LBER_ERROR
) {
838 c
[i
].ldctl_oid
= LDAP_CONTROL_SYNC
;
839 c
[i
].ldctl_value
= (*syncbvalp
);
840 c
[i
].ldctl_iscritical
= ldapsync
< 0;
844 if ( valuesReturnFilter
) {
849 if (( vrber
= ber_alloc_t(LBER_USE_DER
)) == NULL
) {
853 if ( ( err
= ldap_put_vrFilter( vrber
, vrFilter
) ) == -1 ) {
854 ber_free( vrber
, 1 );
855 fprintf( stderr
, _("Bad ValuesReturnFilter: %s\n"), vrFilter
);
859 if ( ber_flatten2( vrber
, &c
[i
].ldctl_value
, 0 ) == -1 ) {
863 c
[i
].ldctl_oid
= LDAP_CONTROL_VALUESRETURNFILTER
;
864 c
[i
].ldctl_iscritical
= valuesReturnFilter
> 1;
868 if ( pagedResults
) {
873 if ( ldap_create_page_control_value( ld
,
874 pageSize
, &pr_cookie
, &c
[i
].ldctl_value
) )
879 if ( pr_cookie
.bv_val
!= NULL
) {
880 ber_memfree( pr_cookie
.bv_val
);
881 pr_cookie
.bv_val
= NULL
;
882 pr_cookie
.bv_len
= 0;
885 c
[i
].ldctl_oid
= LDAP_CONTROL_PAGEDRESULTS
;
886 c
[i
].ldctl_iscritical
= pagedResults
> 1;
891 tool_server_controls( ld
, c
, i
);
893 ber_free( seber
, 1 );
894 ber_free( vrber
, 1 );
896 /* step back to the original number of controls, so that
897 * those set while parsing args are preserved */
898 nctrls
= save_nctrls
;
901 fprintf( stderr
, _("filter%s: %s\nrequesting: "),
902 infile
!= NULL
? _(" pattern") : "",
905 if ( attrs
== NULL
) {
906 fprintf( stderr
, _("All userApplication attributes") );
908 for ( i
= 0; attrs
[ i
] != NULL
; ++i
) {
909 fprintf( stderr
, "%s ", attrs
[ i
] );
912 fprintf( stderr
, "\n" );
916 printf( _("# extended LDIF\n") );
917 } else if ( ldif
< 3 ) {
918 printf( _("version: %d\n\n"), 1 );
922 char *realbase
= base
;
924 if ( realbase
== NULL
) {
925 ldap_get_option( ld
, LDAP_OPT_DEFBASE
, (void **)(char *)&realbase
);
929 printf(_("# LDAPv%d\n"), protocol
);
930 printf(_("# base <%s>%s with scope %s\n"),
931 realbase
? realbase
: "",
932 ( realbase
== NULL
|| realbase
!= base
) ? " (default)" : "",
933 ((scope
== LDAP_SCOPE_BASE
) ? "baseObject"
934 : ((scope
== LDAP_SCOPE_ONELEVEL
) ? "oneLevel"
935 : ((scope
== LDAP_SCOPE_SUBORDINATE
) ? "children"
937 printf(_("# filter%s: %s\n"), infile
!= NULL
? _(" pattern") : "",
939 printf(_("# requesting: "));
941 if ( attrs
== NULL
) {
944 for ( i
= 0; attrs
[ i
] != NULL
; ++i
) {
945 printf( "%s ", attrs
[ i
] );
950 printf(_("\n# with manageDSAit %scontrol"),
951 manageDSAit
> 1 ? _("critical ") : "" );
954 printf(_("\n# with noop %scontrol"),
955 noop
> 1 ? _("critical ") : "" );
958 printf(_("\n# with subentries %scontrol: %s"),
959 subentries
< 0 ? _("critical ") : "",
960 abs(subentries
) == 1 ? "false" : "true" );
962 if ( valuesReturnFilter
) {
963 printf(_("\n# with valuesReturnFilter %scontrol: %s"),
964 valuesReturnFilter
> 1 ? _("critical ") : "", vrFilter
);
966 if ( pagedResults
) {
967 printf(_("\n# with pagedResults %scontrol: size=%d"),
968 (pagedResults
> 1) ? _("critical ") : "",
972 printf( _("\n#\n\n") );
974 if ( realbase
&& realbase
!= base
) {
975 ldap_memfree( realbase
);
979 if ( infile
== NULL
) {
980 rc
= dosearch( ld
, base
, scope
, NULL
, filtpattern
,
981 attrs
, attrsonly
, NULL
, NULL
, NULL
, -1 );
986 while ( fgets( line
, sizeof( line
), fp
) != NULL
) {
987 line
[ strlen( line
) - 1 ] = '\0';
993 rc1
= dosearch( ld
, base
, scope
, filtpattern
, line
,
994 attrs
, attrsonly
, NULL
, NULL
, NULL
, -1 );
1002 if ( fp
!= stdin
) {
1007 if (( rc
== LDAP_SUCCESS
) && pageSize
&& pr_morePagedResults
) {
1009 int i
, moreEntries
, tmpSize
;
1011 /* Loop to get the next pages when
1012 * enter is pressed on the terminal.
1014 if ( pagePrompt
!= 0 ) {
1015 if ( entriesLeft
> 0 ) {
1016 printf( _("Estimate entries: %d\n"), entriesLeft
);
1018 printf( _("Press [size] Enter for the next {%d|size} entries.\n"),
1021 moreEntries
= getchar();
1022 while ( moreEntries
!= EOF
&& moreEntries
!= '\n' ) {
1023 if ( i
< (int)sizeof(buf
) - 1 ) {
1024 buf
[i
] = moreEntries
;
1027 moreEntries
= getchar();
1031 if ( i
> 0 && isdigit( (unsigned char)buf
[0] ) ) {
1032 int num
= sscanf( buf
, "%d", &tmpSize
);
1035 _("Invalid value for PagedResultsControl, %s.\n"), buf
);
1036 return EXIT_FAILURE
;
1039 pageSize
= (ber_int_t
)tmpSize
;
1048 if ( base
!= NULL
) {
1049 ber_memfree( base
);
1051 if ( control
!= NULL
) {
1052 ber_memfree( control
);
1056 for ( ; save_nctrls
-- > 0; ) {
1057 ber_memfree( c
[ save_nctrls
].ldctl_value
.bv_val
);
1067 static int dosearch(
1075 LDAPControl
**sctrls
,
1076 LDAPControl
**cctrls
,
1077 struct timeval
*timeout
,
1087 LDAPMessage
*res
, *msg
;
1089 char *retoid
= NULL
;
1090 struct berval
*retdata
= NULL
;
1091 int nresponses_psearch
= -1;
1092 int cancel_msgid
= -1;
1094 if( filtpatt
!= NULL
) {
1095 size_t max_fsize
= strlen( filtpatt
) + strlen( value
) + 1;
1096 filter
= malloc( max_fsize
);
1097 if( filter
== NULL
) {
1099 return EXIT_FAILURE
;
1102 if( snprintf( filter
, max_fsize
, filtpatt
, value
) >= max_fsize
) {
1103 fprintf( stderr
, "Bad filter pattern: \"%s\"\n", filtpatt
);
1105 return EXIT_FAILURE
;
1109 fprintf( stderr
, _("filter: %s\n"), filter
);
1113 printf( _("#\n# filter: %s\n#\n"), filter
);
1121 if ( filtpatt
!= NULL
) {
1124 return LDAP_SUCCESS
;
1127 rc
= ldap_search_ext( ld
, base
, scope
, filter
, attrs
, attrsonly
,
1128 sctrls
, cctrls
, timeout
, sizelimit
, &msgid
);
1130 if ( filtpatt
!= NULL
) {
1134 if( rc
!= LDAP_SUCCESS
) {
1135 fprintf( stderr
, _("%s: ldap_search_ext: %s (%d)\n"),
1136 prog
, ldap_err2string( rc
), rc
);
1140 nresponses
= nentries
= nreferences
= nextended
= npartial
= 0;
1144 while ((rc
= ldap_result( ld
, LDAP_RES_ANY
,
1145 sortattr
? LDAP_MSG_ALL
: LDAP_MSG_ONE
,
1148 rc
= tool_check_abandon( ld
, msgid
);
1154 (void) ldap_sort_entries( ld
, &res
,
1155 ( *sortattr
== '\0' ) ? NULL
: sortattr
, strcasecmp
);
1158 for ( msg
= ldap_first_message( ld
, res
);
1160 msg
= ldap_next_message( ld
, msg
) )
1162 if ( nresponses
++ ) putchar('\n');
1163 if ( nresponses_psearch
>= 0 )
1164 nresponses_psearch
++;
1166 switch( ldap_msgtype( msg
) ) {
1167 case LDAP_RES_SEARCH_ENTRY
:
1169 print_entry( ld
, msg
, attrsonly
);
1172 case LDAP_RES_SEARCH_REFERENCE
:
1174 print_reference( ld
, msg
);
1177 case LDAP_RES_EXTENDED
:
1179 print_extended( ld
, msg
);
1181 if ( ldap_msgid( msg
) == 0 ) {
1182 /* unsolicited extended operation */
1186 if ( cancel_msgid
!= -1 &&
1187 cancel_msgid
== ldap_msgid( msg
) ) {
1188 printf(_("Cancelled \n"));
1189 printf(_("cancel_msgid = %d\n"), cancel_msgid
);
1194 case LDAP_RES_SEARCH_RESULT
:
1195 /* pagedResults stuff is dealt with
1196 * in tool_print_ctrls(), called by
1197 * print_results(). */
1198 rc
= print_result( ld
, msg
, 1 );
1199 if ( ldapsync
== LDAP_SYNC_REFRESH_AND_PERSIST
) {
1205 case LDAP_RES_INTERMEDIATE
:
1207 ldap_parse_intermediate( ld
, msg
,
1208 &retoid
, &retdata
, NULL
, 0 );
1210 nresponses_psearch
= 0;
1212 if ( strcmp( retoid
, LDAP_SYNC_INFO
) == 0 ) {
1213 printf(_("SyncInfo Received\n"));
1214 ldap_memfree( retoid
);
1215 ber_bvfree( retdata
);
1219 print_partial( ld
, msg
);
1220 ldap_memfree( retoid
);
1221 ber_bvfree( retdata
);
1225 if ( ldapsync
&& sync_slimit
!= -1 &&
1226 nresponses_psearch
>= sync_slimit
) {
1227 BerElement
*msgidber
= NULL
;
1228 struct berval
*msgidvalp
= NULL
;
1229 msgidber
= ber_alloc_t(LBER_USE_DER
);
1230 ber_printf(msgidber
, "{i}", msgid
);
1231 ber_flatten(msgidber
, &msgidvalp
);
1232 ldap_extended_operation(ld
, LDAP_EXOP_CANCEL
,
1233 msgidvalp
, NULL
, NULL
, &cancel_msgid
);
1234 nresponses_psearch
= -1;
1238 ldap_msgfree( res
);
1243 tool_perror( "ldap_result", rc
, NULL
, NULL
, NULL
, NULL
);
1247 ldap_msgfree( res
);
1249 if ( pagedResults
) {
1250 npagedresponses
+= nresponses
;
1251 npagedentries
+= nentries
;
1252 npagedextended
+= nextended
;
1253 npagedpartial
+= npartial
;
1254 npagedreferences
+= nreferences
;
1255 if ( ( pr_morePagedResults
== 0 ) && ( ldif
< 2 ) ) {
1256 printf( _("\n# numResponses: %d\n"), npagedresponses
);
1257 if( npagedentries
) {
1258 printf( _("# numEntries: %d\n"), npagedentries
);
1260 if( npagedextended
) {
1261 printf( _("# numExtended: %d\n"), npagedextended
);
1263 if( npagedpartial
) {
1264 printf( _("# numPartial: %d\n"), npagedpartial
);
1266 if( npagedreferences
) {
1267 printf( _("# numReferences: %d\n"), npagedreferences
);
1270 } else if ( ldif
< 2 ) {
1271 printf( _("\n# numResponses: %d\n"), nresponses
);
1272 if( nentries
) printf( _("# numEntries: %d\n"), nentries
);
1273 if( nextended
) printf( _("# numExtended: %d\n"), nextended
);
1274 if( npartial
) printf( _("# numPartial: %d\n"), npartial
);
1275 if( nreferences
) printf( _("# numReferences: %d\n"), nreferences
);
1281 /* This is the proposed new way of doing things.
1282 * It is more efficient, but the API is non-standard.
1291 char tmpfname
[ 256 ];
1294 BerElement
*ber
= NULL
;
1295 struct berval bv
, *bvals
, **bvp
= &bvals
;
1296 LDAPControl
**ctrls
= NULL
;
1299 rc
= ldap_get_dn_ber( ld
, entry
, &ber
, &bv
);
1302 ufn
= ldap_dn2ufn( bv
.bv_val
);
1303 tool_write_ldif( LDIF_PUT_COMMENT
, NULL
, ufn
, ufn
? strlen( ufn
) : 0 );
1305 tool_write_ldif( LDIF_PUT_VALUE
, "dn", bv
.bv_val
, bv
.bv_len
);
1307 rc
= ldap_get_entry_controls( ld
, entry
, &ctrls
);
1308 if( rc
!= LDAP_SUCCESS
) {
1309 fprintf(stderr
, _("print_entry: %d\n"), rc
);
1310 tool_perror( "ldap_get_entry_controls", rc
, NULL
, NULL
, NULL
, NULL
);
1311 exit( EXIT_FAILURE
);
1315 tool_print_ctrls( ld
, ctrls
);
1316 ldap_controls_free( ctrls
);
1321 ufn
= ldap_dn2ufn( bv
.bv_val
);
1323 tool_write_ldif( LDIF_PUT_VALUE
, "ufn", ufn
, ufn
? strlen( ufn
) : 0 );
1326 if( ufn
!= NULL
) ldap_memfree( ufn
);
1328 if ( attrsonly
) bvp
= NULL
;
1330 for ( rc
= ldap_get_attribute_ber( ld
, entry
, ber
, &bv
, bvp
);
1332 rc
= ldap_get_attribute_ber( ld
, entry
, ber
, &bv
, bvp
) )
1334 if (bv
.bv_val
== NULL
) break;
1337 tool_write_ldif( LDIF_PUT_NOVALUE
, bv
.bv_val
, NULL
, 0 );
1339 } else if ( bvals
) {
1340 for ( i
= 0; bvals
[i
].bv_val
!= NULL
; i
++ ) {
1341 if ( vals2tmp
> 1 || ( vals2tmp
&&
1342 ldif_is_not_printable( bvals
[i
].bv_val
, bvals
[i
].bv_len
)))
1345 /* write value to file */
1346 snprintf( tmpfname
, sizeof tmpfname
,
1347 "%s" LDAP_DIRSEP
"ldapsearch-%s-XXXXXX",
1348 tmpdir
, bv
.bv_val
);
1351 tmpfd
= mkstemp( tmpfname
);
1358 if (( tmpfp
= fdopen( tmpfd
, "w")) == NULL
) {
1363 if ( fwrite( bvals
[ i
].bv_val
,
1364 bvals
[ i
].bv_len
, 1, tmpfp
) == 0 )
1373 snprintf( url
, sizeof url
, "%s%s", urlpre
,
1374 &tmpfname
[strlen(tmpdir
) + sizeof(LDAP_DIRSEP
) - 1] );
1377 tool_write_ldif( LDIF_PUT_URL
, bv
.bv_val
, url
, strlen( url
));
1380 tool_write_ldif( LDIF_PUT_VALUE
, bv
.bv_val
,
1381 bvals
[ i
].bv_val
, bvals
[ i
].bv_len
);
1384 ber_memfree( bvals
);
1393 static void print_reference(
1395 LDAPMessage
*reference
)
1399 LDAPControl
**ctrls
;
1402 printf(_("# search reference\n"));
1405 rc
= ldap_parse_reference( ld
, reference
, &refs
, &ctrls
, 0 );
1407 if( rc
!= LDAP_SUCCESS
) {
1408 tool_perror( "ldap_parse_reference", rc
, NULL
, NULL
, NULL
, NULL
);
1409 exit( EXIT_FAILURE
);
1414 for( i
=0; refs
[i
] != NULL
; i
++ ) {
1415 tool_write_ldif( ldif
? LDIF_PUT_COMMENT
: LDIF_PUT_VALUE
,
1416 "ref", refs
[i
], strlen(refs
[i
]) );
1418 ber_memvfree( (void **) refs
);
1422 tool_print_ctrls( ld
, ctrls
);
1423 ldap_controls_free( ctrls
);
1427 static void print_extended(
1429 LDAPMessage
*extended
)
1432 char *retoid
= NULL
;
1433 struct berval
*retdata
= NULL
;
1436 printf(_("# extended result response\n"));
1439 rc
= ldap_parse_extended_result( ld
, extended
,
1440 &retoid
, &retdata
, 0 );
1442 if( rc
!= LDAP_SUCCESS
) {
1443 tool_perror( "ldap_parse_extended_result", rc
, NULL
, NULL
, NULL
, NULL
);
1444 exit( EXIT_FAILURE
);
1448 tool_write_ldif( ldif
? LDIF_PUT_COMMENT
: LDIF_PUT_VALUE
,
1449 "extended", retoid
, retoid
? strlen(retoid
) : 0 );
1451 ber_memfree( retoid
);
1455 tool_write_ldif( ldif
? LDIF_PUT_COMMENT
: LDIF_PUT_BINARY
,
1456 "data", retdata
->bv_val
, retdata
->bv_len
);
1458 ber_bvfree( retdata
);
1461 print_result( ld
, extended
, 0 );
1464 static void print_partial(
1466 LDAPMessage
*partial
)
1469 char *retoid
= NULL
;
1470 struct berval
*retdata
= NULL
;
1471 LDAPControl
**ctrls
= NULL
;
1474 printf(_("# extended partial response\n"));
1477 rc
= ldap_parse_intermediate( ld
, partial
,
1478 &retoid
, &retdata
, &ctrls
, 0 );
1480 if( rc
!= LDAP_SUCCESS
) {
1481 tool_perror( "ldap_parse_intermediate", rc
, NULL
, NULL
, NULL
, NULL
);
1482 exit( EXIT_FAILURE
);
1486 tool_write_ldif( ldif
? LDIF_PUT_COMMENT
: LDIF_PUT_VALUE
,
1487 "partial", retoid
, retoid
? strlen(retoid
) : 0 );
1490 ber_memfree( retoid
);
1494 tool_write_ldif( ldif
? LDIF_PUT_COMMENT
: LDIF_PUT_BINARY
,
1495 "data", retdata
->bv_val
, retdata
->bv_len
);
1498 ber_bvfree( retdata
);
1502 tool_print_ctrls( ld
, ctrls
);
1503 ldap_controls_free( ctrls
);
1507 static int print_result(
1509 LDAPMessage
*result
, int search
)
1513 char *matcheddn
= NULL
;
1516 LDAPControl
**ctrls
= NULL
;
1520 printf(_("# search result\n"));
1523 printf("%s: %d\n", _("search"), ldap_msgid(result
) );
1527 rc
= ldap_parse_result( ld
, result
,
1528 &err
, &matcheddn
, &text
, &refs
, &ctrls
, 0 );
1530 if( rc
!= LDAP_SUCCESS
) {
1531 tool_perror( "ldap_parse_result", rc
, NULL
, NULL
, NULL
, NULL
);
1532 exit( EXIT_FAILURE
);
1537 printf( _("result: %d %s\n"), err
, ldap_err2string(err
) );
1539 } else if ( err
!= LDAP_SUCCESS
) {
1540 fprintf( stderr
, "%s (%d)\n", ldap_err2string(err
), err
);
1546 tool_write_ldif( LDIF_PUT_VALUE
,
1547 "matchedDN", matcheddn
, strlen(matcheddn
) );
1549 fprintf( stderr
, _("Matched DN: %s\n"), matcheddn
);
1553 ber_memfree( matcheddn
);
1559 if ( err
== LDAP_PARTIAL_RESULTS
) {
1562 for ( line
= text
; line
!= NULL
; ) {
1563 char *next
= strchr( line
, '\n' );
1565 tool_write_ldif( LDIF_PUT_TEXT
,
1567 next
? next
- line
: strlen( line
) );
1569 line
= next
? next
+ 1 : NULL
;
1573 tool_write_ldif( LDIF_PUT_TEXT
, "text",
1574 text
, strlen(text
) );
1577 fprintf( stderr
, _("Additional information: %s\n"), text
);
1581 ber_memfree( text
);
1586 for( i
=0; refs
[i
] != NULL
; i
++ ) {
1588 tool_write_ldif( LDIF_PUT_VALUE
, "ref", refs
[i
], strlen(refs
[i
]) );
1590 fprintf( stderr
, _("Referral: %s\n"), refs
[i
] );
1594 ber_memvfree( (void **) refs
);
1597 pr_morePagedResults
= 0;
1600 tool_print_ctrls( ld
, ctrls
);
1601 ldap_controls_free( ctrls
);