~ttx/openldap/lucid-gssapi-495418

« back to all changes in this revision

Viewing changes to clients/tools/ldapsearch.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2008-07-10 14:45:49 UTC
  • Revision ID: james.westby@ubuntu.com-20080710144549-wck73med0e72gfyo
Tags: upstream-2.4.10
ImportĀ upstreamĀ versionĀ 2.4.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/>.
 
4
 *
 
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.
 
9
 * All rights reserved.
 
10
 *
 
11
 * Redistribution and use in source and binary forms, with or without
 
12
 * modification, are permitted only as authorized by the OpenLDAP
 
13
 * Public License.
 
14
 *
 
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>.
 
18
 */
 
19
/* Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
 
20
 * All rights reserved.
 
21
 *
 
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.
 
28
 */
 
29
/* ACKNOWLEDGEMENTS:
 
30
 * This work was originally developed by the University of Michigan
 
31
 * (as part of U-MICH LDAP).  Additional significant contributors
 
32
 * include:
 
33
 *   Jong Hyuk Choi
 
34
 *   Lynn Moss
 
35
 *   Mikhail Sahalaev
 
36
 *   Kurt D. Zeilenga
 
37
 */
 
38
 
 
39
#include "portable.h"
 
40
 
 
41
#include <stdio.h>
 
42
 
 
43
#include <ac/stdlib.h>
 
44
 
 
45
#include <ac/ctype.h>
 
46
#include <ac/string.h>
 
47
#include <ac/unistd.h>
 
48
#include <ac/errno.h>
 
49
#include <sys/stat.h>
 
50
 
 
51
#include <ac/signal.h>
 
52
 
 
53
#ifdef HAVE_FCNTL_H
 
54
#include <fcntl.h>
 
55
#endif
 
56
#ifdef HAVE_SYS_TYPES_H
 
57
#include <sys/types.h>
 
58
#endif
 
59
#ifdef HAVE_IO_H
 
60
#include <io.h>
 
61
#endif
 
62
 
 
63
#include <ldap.h>
 
64
 
 
65
#include "ldif.h"
 
66
#include "lutil.h"
 
67
#include "lutil_ldap.h"
 
68
#include "ldap_defaults.h"
 
69
#include "ldap_log.h"
 
70
#include "ldap_pvt.h"
 
71
 
 
72
#include "common.h"
 
73
 
 
74
#if !LDAP_DEPRECATED
 
75
/*
 
76
 * NOTE: we use this deprecated function only because
 
77
 * we want ldapsearch to provide some client-side sorting 
 
78
 * capability.
 
79
 */
 
80
/* from ldap.h */
 
81
typedef int (LDAP_SORT_AD_CMP_PROC) LDAP_P(( /* deprecated */
 
82
        LDAP_CONST char *left,
 
83
        LDAP_CONST char *right ));
 
84
 
 
85
LDAP_F( int )   /* deprecated */
 
86
ldap_sort_entries LDAP_P(( LDAP *ld,
 
87
        LDAPMessage **chain,
 
88
        LDAP_CONST char *attr,
 
89
        LDAP_SORT_AD_CMP_PROC *cmp ));
 
90
#endif
 
91
 
 
92
static int scope = LDAP_SCOPE_SUBTREE;
 
93
static int deref = -1;
 
94
static int attrsonly;
 
95
static int timelimit = -1;
 
96
static int sizelimit = -1;
 
97
 
 
98
static char *control;
 
99
 
 
100
static char *def_tmpdir;
 
101
static char *def_urlpre;
 
102
 
 
103
#if defined(__CYGWIN__) || defined(__MINGW32__)
 
104
/* Turn off commandline globbing, otherwise you cannot search for
 
105
 * attribute '*'
 
106
 */
 
107
int _CRT_glob = 0;
 
108
#endif
 
109
 
 
110
void
 
111
usage( void )
 
112
{
 
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"));
 
120
 
 
121
 
 
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"));
 
148
        tool_common_usage();
 
149
        exit( EXIT_FAILURE );
 
150
}
 
151
 
 
152
static void print_entry LDAP_P((
 
153
        LDAP    *ld,
 
154
        LDAPMessage     *entry,
 
155
        int             attrsonly));
 
156
 
 
157
static void print_reference(
 
158
        LDAP *ld,
 
159
        LDAPMessage *reference );
 
160
 
 
161
static void print_extended(
 
162
        LDAP *ld,
 
163
        LDAPMessage *extended );
 
164
 
 
165
static void print_partial(
 
166
        LDAP *ld,
 
167
        LDAPMessage *partial );
 
168
 
 
169
static int print_result(
 
170
        LDAP *ld,
 
171
        LDAPMessage *result,
 
172
        int search );
 
173
 
 
174
static int dosearch LDAP_P((
 
175
        LDAP    *ld,
 
176
        char    *base,
 
177
        int             scope,
 
178
        char    *filtpatt,
 
179
        char    *value,
 
180
        char    **attrs,
 
181
        int             attrsonly,
 
182
        LDAPControl **sctrls,
 
183
        LDAPControl **cctrls,
 
184
        struct timeval *timeout,
 
185
        int     sizelimit ));
 
186
 
 
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;
 
192
 
 
193
static int subentries = 0, valuesReturnFilter = 0;
 
194
static char     *vrFilter = NULL;
 
195
 
 
196
#ifdef LDAP_CONTROL_DONTUSECOPY
 
197
static int dontUseCopy = 0;
 
198
#endif
 
199
 
 
200
static int domainScope = 0;
 
201
 
 
202
static int ldapsync = 0;
 
203
static struct berval sync_cookie = { 0, NULL };
 
204
static int sync_slimit = -1;
 
205
 
 
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;
 
216
 
 
217
static LDAPControl *c = NULL;
 
218
static int nctrls = 0;
 
219
static int save_nctrls = 0;
 
220
 
 
221
static int
 
222
ctrl_add( void )
 
223
{
 
224
        LDAPControl     *tmpc;
 
225
 
 
226
        nctrls++;
 
227
        tmpc = realloc( c, sizeof( LDAPControl ) * nctrls );
 
228
        if ( tmpc == NULL ) {
 
229
                nctrls--;
 
230
                fprintf( stderr,
 
231
                        _("unable to make room for control; out of memory?\n"));
 
232
                return -1;
 
233
        }
 
234
        c = tmpc;
 
235
 
 
236
        return 0;
 
237
}
 
238
 
 
239
static void
 
240
urlize(char *url)
 
241
{
 
242
        char *p;
 
243
 
 
244
        if (*LDAP_DIRSEP != '/') {
 
245
                for (p = url; *p; p++) {
 
246
                        if (*p == *LDAP_DIRSEP)
 
247
                                *p = '/';
 
248
                }
 
249
        }
 
250
}
 
251
 
 
252
 
 
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";
 
255
 
 
256
int
 
257
handle_private_option( int i )
 
258
{
 
259
        int crit, ival;
 
260
        char *cvalue, *next;
 
261
        switch ( 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;
 
271
                } else {
 
272
                        fprintf( stderr,
 
273
                                _("alias deref should be never, search, find, or always\n") );
 
274
                        usage();
 
275
                }
 
276
                break;
 
277
        case 'A':       /* retrieve attribute names only -- no values */
 
278
                ++attrsonly;
 
279
                break;
 
280
        case 'b': /* search base */
 
281
                base = ber_strdup( optarg );
 
282
                break;
 
283
        case 'E': /* search extensions */
 
284
                if( protocol == LDAP_VERSION2 ) {
 
285
                        fprintf( stderr, _("%s: -E incompatible with LDAPv%d\n"),
 
286
                                prog, protocol );
 
287
                        exit( EXIT_FAILURE );
 
288
                }
 
289
 
 
290
                /* should be extended to support comma separated list of
 
291
                 *      [!]key[=value] parameters, e.g.  -E !foo,bar=567
 
292
                 */
 
293
 
 
294
                crit = 0;
 
295
                cvalue = NULL;
 
296
                if( optarg[0] == '!' ) {
 
297
                        crit = 1;
 
298
                        optarg++;
 
299
                }
 
300
 
 
301
                control = ber_strdup( optarg );
 
302
                if ( (cvalue = strchr( control, '=' )) != NULL ) {
 
303
                        *cvalue++ = '\0';
 
304
                }
 
305
 
 
306
                if ( strcasecmp( control, "mv" ) == 0 ) {
 
307
                        /* ValuesReturnFilter control */
 
308
                        if( valuesReturnFilter ) {
 
309
                                fprintf( stderr,
 
310
                                        _("ValuesReturnFilter previously specified\n"));
 
311
                                exit( EXIT_FAILURE );
 
312
                        }
 
313
                        valuesReturnFilter= 1 + crit;
 
314
 
 
315
                        if ( cvalue == NULL ) {
 
316
                                fprintf( stderr,
 
317
                                        _("missing filter in ValuesReturnFilter control\n"));
 
318
                                exit( EXIT_FAILURE );
 
319
                        }
 
320
 
 
321
                        vrFilter = cvalue;
 
322
                        protocol = LDAP_VERSION3;
 
323
 
 
324
                } else if ( strcasecmp( control, "pr" ) == 0 ) {
 
325
                        int num, tmp;
 
326
                        /* PagedResults control */
 
327
                        if ( pagedResults != 0 ) {
 
328
                                fprintf( stderr,
 
329
                                        _("PagedResultsControl previously specified\n") );
 
330
                                exit( EXIT_FAILURE );
 
331
                        }
 
332
 
 
333
                        if( cvalue != NULL ) {
 
334
                                char *promptp;
 
335
 
 
336
                                promptp = strchr( cvalue, '/' );
 
337
                                if ( promptp != NULL ) {
 
338
                                        *promptp++ = '\0';
 
339
                                        if ( strcasecmp( promptp, "prompt" ) == 0 ) {
 
340
                                                pagePrompt = 1;
 
341
                                        } else if ( strcasecmp( promptp, "noprompt" ) == 0) {
 
342
                                                pagePrompt = 0;
 
343
                                        } else {
 
344
                                                fprintf( stderr,
 
345
                                                        _("Invalid value for PagedResultsControl,"
 
346
                                                        " %s/%s.\n"), cvalue, promptp );
 
347
                                                exit( EXIT_FAILURE );
 
348
                                        }
 
349
                                }
 
350
                                num = sscanf( cvalue, "%d", &tmp );
 
351
                                if ( num != 1 ) {
 
352
                                        fprintf( stderr,
 
353
                                                _("Invalid value for PagedResultsControl, %s.\n"),
 
354
                                                cvalue );
 
355
                                        exit( EXIT_FAILURE );
 
356
                                }
 
357
                        } else {
 
358
                                fprintf(stderr, _("Invalid value for PagedResultsControl.\n"));
 
359
                                exit( EXIT_FAILURE );
 
360
                        }
 
361
                        pageSize = (ber_int_t) tmp;
 
362
                        pagedResults = 1 + crit;
 
363
 
 
364
#ifdef LDAP_CONTROL_DONTUSECOPY
 
365
                } else if ( strcasecmp( control, "dontUseCopy" ) == 0 ) {
 
366
                        if( dontUseCopy ) {
 
367
                                fprintf( stderr,
 
368
                                        _("dontUseCopy control previously specified\n"));
 
369
                                exit( EXIT_FAILURE );
 
370
                        }
 
371
                        if( cvalue != NULL ) {
 
372
                                fprintf( stderr,
 
373
                                 _("dontUseCopy: no control value expected\n") );
 
374
                                usage();
 
375
                        }
 
376
                        if( !crit ) {
 
377
                                fprintf( stderr,
 
378
                                 _("dontUseCopy: critical flag required\n") );
 
379
                                usage();
 
380
                        }
 
381
 
 
382
                        dontUseCopy = 1 + crit;
 
383
#endif
 
384
                } else if ( strcasecmp( control, "domainScope" ) == 0 ) {
 
385
                        if( domainScope ) {
 
386
                                fprintf( stderr,
 
387
                                        _("domainScope control previously specified\n"));
 
388
                                exit( EXIT_FAILURE );
 
389
                        }
 
390
                        if( cvalue != NULL ) {
 
391
                                fprintf( stderr,
 
392
                                 _("domainScope: no control value expected\n") );
 
393
                                usage();
 
394
                        }
 
395
 
 
396
                        domainScope = 1 + crit;
 
397
 
 
398
                } else if ( strcasecmp( control, "subentries" ) == 0 ) {
 
399
                        if( subentries ) {
 
400
                                fprintf( stderr,
 
401
                                        _("subentries control previously specified\n"));
 
402
                                exit( EXIT_FAILURE );
 
403
                        }
 
404
                        if( cvalue == NULL || strcasecmp( cvalue, "true") == 0 ) {
 
405
                                subentries = 2;
 
406
                        } else if ( strcasecmp( cvalue, "false") == 0 ) {
 
407
                                subentries = 1;
 
408
                        } else {
 
409
                                fprintf( stderr,
 
410
                                        _("subentries control value \"%s\" invalid\n"),
 
411
                                        cvalue );
 
412
                                exit( EXIT_FAILURE );
 
413
                        }
 
414
                        if( crit ) subentries *= -1;
 
415
 
 
416
                } else if ( strcasecmp( control, "sync" ) == 0 ) {
 
417
                        char *cookiep;
 
418
                        char *slimitp;
 
419
                        if ( ldapsync ) {
 
420
                                fprintf( stderr, _("sync control previously specified\n") );
 
421
                                exit( EXIT_FAILURE );
 
422
                        }
 
423
                        if ( cvalue == NULL ) {
 
424
                                fprintf( stderr, _("missing specification of sync control\n"));
 
425
                                exit( EXIT_FAILURE );
 
426
                        }
 
427
                        if ( strncasecmp( cvalue, "ro", 2 ) == 0 ) {
 
428
                                ldapsync = LDAP_SYNC_REFRESH_ONLY;
 
429
                                cookiep = strchr( cvalue, '/' );
 
430
                                if ( cookiep != NULL ) {
 
431
                                        cookiep++;
 
432
                                        if ( *cookiep != '\0' ) {
 
433
                                                ber_str2bv( cookiep, 0, 0, &sync_cookie );
 
434
                                        }
 
435
                                }
 
436
                        } else if ( strncasecmp( cvalue, "rp", 2 ) == 0 ) {
 
437
                                ldapsync = LDAP_SYNC_REFRESH_AND_PERSIST;
 
438
                                cookiep = strchr( cvalue, '/' );
 
439
                                if ( cookiep != NULL ) {
 
440
                                        *cookiep++ = '\0';      
 
441
                                        cvalue = cookiep;
 
442
                                }
 
443
                                slimitp = strchr( cvalue, '/' );
 
444
                                if ( slimitp != NULL ) {
 
445
                                        *slimitp++ = '\0';
 
446
                                }
 
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 );
 
454
                                        }
 
455
                                        sync_slimit = ival;
 
456
                                }
 
457
                        } else {
 
458
                                fprintf( stderr, _("sync control value \"%s\" invalid\n"),
 
459
                                        cvalue );
 
460
                                exit( EXIT_FAILURE );
 
461
                        }
 
462
                        if ( crit ) ldapsync *= -1;
 
463
 
 
464
                } else if ( tool_is_oid( control ) ) {
 
465
                        if ( ctrl_add() ) {
 
466
                                exit( EXIT_FAILURE );
 
467
                        }
 
468
 
 
469
                        /* OID */
 
470
                        c[ nctrls - 1 ].ldctl_oid = control;
 
471
 
 
472
                        /* value */
 
473
                        if ( cvalue == NULL ) {
 
474
                                c[ nctrls - 1 ].ldctl_value.bv_val = NULL;
 
475
                                c[ nctrls - 1 ].ldctl_value.bv_len = 0;
 
476
 
 
477
                        } else if ( cvalue[ 0 ] == ':' ) {
 
478
                                struct berval   type;
 
479
                                struct berval   value;
 
480
                                int             freeval;
 
481
 
 
482
                                cvalue++;
 
483
 
 
484
                                /* dummy type "x"
 
485
                                 * to use ldif_parse_line2() */
 
486
                                cvalue[ -2 ] = 'x';
 
487
                                ldif_parse_line2( &cvalue[ -2 ], &type,
 
488
                                        &value, &freeval );
 
489
                                cvalue[ -2 ] = '\0';
 
490
 
 
491
                                if ( freeval ) {
 
492
                                        c[ nctrls - 1 ].ldctl_value = value;
 
493
 
 
494
                                } else {
 
495
                                        ber_dupbv( &c[ nctrls - 1 ].ldctl_value, &value );
 
496
                                }
 
497
                        }
 
498
 
 
499
                        /* criticality */
 
500
                        c[ nctrls - 1 ].ldctl_iscritical = crit;
 
501
 
 
502
                } else {
 
503
                        fprintf( stderr, _("Invalid search extension name: %s\n"),
 
504
                                control );
 
505
                        usage();
 
506
                }
 
507
                break;
 
508
        case 'F':       /* uri prefix */
 
509
                if( urlpre ) free( urlpre );
 
510
                urlpre = strdup( optarg );
 
511
                break;
 
512
        case 'l':       /* time limit */
 
513
                if ( strcasecmp( optarg, "none" ) == 0 ) {
 
514
                        timelimit = 0;
 
515
 
 
516
                } else if ( strcasecmp( optarg, "max" ) == 0 ) {
 
517
                        timelimit = LDAP_MAXINT;
 
518
 
 
519
                } else {
 
520
                        ival = strtol( optarg, &next, 10 );
 
521
                        if ( next == NULL || next[0] != '\0' ) {
 
522
                                fprintf( stderr,
 
523
                                        _("Unable to parse time limit \"%s\"\n"), optarg );
 
524
                                exit( EXIT_FAILURE );
 
525
                        }
 
526
                        timelimit = ival;
 
527
                }
 
528
                if( timelimit < 0 || timelimit > LDAP_MAXINT ) {
 
529
                        fprintf( stderr, _("%s: invalid timelimit (%d) specified\n"),
 
530
                                prog, timelimit );
 
531
                        exit( EXIT_FAILURE );
 
532
                }
 
533
                break;
 
534
        case 'L':       /* print entries in LDIF format */
 
535
                ++ldif;
 
536
                break;
 
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 ))
 
544
                {
 
545
                        scope = LDAP_SCOPE_SUBORDINATE;
 
546
                } else if ( strncasecmp( optarg, "sub", sizeof("sub")-1 ) == 0 ) {
 
547
                        scope = LDAP_SCOPE_SUBTREE;
 
548
                } else {
 
549
                        fprintf( stderr, _("scope should be base, one, or sub\n") );
 
550
                        usage();
 
551
                }
 
552
                break;
 
553
        case 'S':       /* sort attribute */
 
554
                sortattr = strdup( optarg );
 
555
                break;
 
556
        case 't':       /* write attribute values to TMPDIR files */
 
557
                ++vals2tmp;
 
558
                break;
 
559
        case 'T':       /* tmpdir */
 
560
                if( tmpdir ) free( tmpdir );
 
561
                tmpdir = strdup( optarg );
 
562
                break;
 
563
        case 'u':       /* include UFN */
 
564
                ++includeufn;
 
565
                break;
 
566
        case 'z':       /* size limit */
 
567
                if ( strcasecmp( optarg, "none" ) == 0 ) {
 
568
                        sizelimit = 0;
 
569
 
 
570
                } else if ( strcasecmp( optarg, "max" ) == 0 ) {
 
571
                        sizelimit = LDAP_MAXINT;
 
572
 
 
573
                } else {
 
574
                        ival = strtol( optarg, &next, 10 );
 
575
                        if ( next == NULL || next[0] != '\0' ) {
 
576
                                fprintf( stderr,
 
577
                                        _("Unable to parse size limit \"%s\"\n"), optarg );
 
578
                                exit( EXIT_FAILURE );
 
579
                        }
 
580
                        sizelimit = ival;
 
581
                }
 
582
                if( sizelimit < 0 || sizelimit > LDAP_MAXINT ) {
 
583
                        fprintf( stderr, _("%s: invalid sizelimit (%d) specified\n"),
 
584
                                prog, sizelimit );
 
585
                        exit( EXIT_FAILURE );
 
586
                }
 
587
                break;
 
588
        default:
 
589
                return 0;
 
590
        }
 
591
        return 1;
 
592
}
 
593
 
 
594
 
 
595
static void
 
596
private_conn_setup( LDAP *ld )
 
597
{
 
598
        if (deref != -1 &&
 
599
                ldap_set_option( ld, LDAP_OPT_DEREF, (void *) &deref )
 
600
                        != LDAP_OPT_SUCCESS )
 
601
        {
 
602
                fprintf( stderr, _("Could not set LDAP_OPT_DEREF %d\n"), deref );
 
603
                exit( EXIT_FAILURE );
 
604
        }
 
605
        if (timelimit > 0 &&
 
606
                ldap_set_option( ld, LDAP_OPT_TIMELIMIT, (void *) &timelimit )
 
607
                        != LDAP_OPT_SUCCESS )
 
608
        {
 
609
                fprintf( stderr,
 
610
                        _("Could not set LDAP_OPT_TIMELIMIT %d\n"), timelimit );
 
611
                exit( EXIT_FAILURE );
 
612
        }
 
613
        if (sizelimit > 0 &&
 
614
                ldap_set_option( ld, LDAP_OPT_SIZELIMIT, (void *) &sizelimit )
 
615
                        != LDAP_OPT_SUCCESS )
 
616
        {
 
617
                fprintf( stderr,
 
618
                        _("Could not set LDAP_OPT_SIZELIMIT %d\n"), sizelimit );
 
619
                exit( EXIT_FAILURE );
 
620
        }
 
621
}
 
622
 
 
623
int
 
624
main( int argc, char **argv )
 
625
{
 
626
        char            *filtpattern, **attrs = NULL, line[BUFSIZ];
 
627
        FILE            *fp = NULL;
 
628
        int                     rc, rc1, i, first;
 
629
        LDAP            *ld = NULL;
 
630
        BerElement      *seber = NULL, *vrber = NULL;
 
631
 
 
632
        BerElement      *syncber = NULL;
 
633
        struct berval   *syncbvalp = NULL;
 
634
        int             err;
 
635
 
 
636
        tool_init( TOOL_SEARCH );
 
637
 
 
638
        npagedresponses = npagedentries = npagedreferences =
 
639
                npagedextended = npagedpartial = 0;
 
640
 
 
641
        prog = lutil_progname( "ldapsearch", argc, argv );
 
642
 
 
643
        if((def_tmpdir = getenv("TMPDIR")) == NULL &&
 
644
           (def_tmpdir = getenv("TMP")) == NULL &&
 
645
           (def_tmpdir = getenv("TEMP")) == NULL )
 
646
        {
 
647
                def_tmpdir = LDAP_TMPDIR;
 
648
        }
 
649
 
 
650
        if ( !*def_tmpdir )
 
651
                def_tmpdir = LDAP_TMPDIR;
 
652
 
 
653
        def_urlpre = malloc( sizeof("file:////") + strlen(def_tmpdir) );
 
654
 
 
655
        if( def_urlpre == NULL ) {
 
656
                perror( "malloc" );
 
657
                return EXIT_FAILURE;
 
658
        }
 
659
 
 
660
        sprintf( def_urlpre, "file:///%s/",
 
661
                def_tmpdir[0] == *LDAP_DIRSEP ? &def_tmpdir[1] : def_tmpdir );
 
662
 
 
663
        urlize( def_urlpre );
 
664
 
 
665
        tool_args( argc, argv );
 
666
 
 
667
        if (( argc - optind < 1 ) ||
 
668
                ( *argv[optind] != '(' /*')'*/ &&
 
669
                ( strchr( argv[optind], '=' ) == NULL ) ) )
 
670
        {
 
671
                filtpattern = "(objectclass=*)";
 
672
        } else {
 
673
                filtpattern = argv[optind++];
 
674
        }
 
675
 
 
676
        if ( argv[optind] != NULL ) {
 
677
                attrs = &argv[optind];
 
678
        }
 
679
 
 
680
        if ( infile != NULL ) {
 
681
                int percent = 0;
 
682
        
 
683
                if ( infile[0] == '-' && infile[1] == '\0' ) {
 
684
                        fp = stdin;
 
685
                } else if (( fp = fopen( infile, "r" )) == NULL ) {
 
686
                        perror( infile );
 
687
                        return EXIT_FAILURE;
 
688
                }
 
689
 
 
690
                for( i=0 ; filtpattern[i] ; i++ ) {
 
691
                        if( filtpattern[i] == '%' ) {
 
692
                                if( percent ) {
 
693
                                        fprintf( stderr, _("Bad filter pattern \"%s\"\n"),
 
694
                                                filtpattern );
 
695
                                        return EXIT_FAILURE;
 
696
                                }
 
697
 
 
698
                                percent++;
 
699
 
 
700
                                if( filtpattern[i+1] != 's' ) {
 
701
                                        fprintf( stderr, _("Bad filter pattern \"%s\"\n"),
 
702
                                                filtpattern );
 
703
                                        return EXIT_FAILURE;
 
704
                                }
 
705
                        }
 
706
                }
 
707
        }
 
708
 
 
709
        if ( tmpdir == NULL ) {
 
710
                tmpdir = def_tmpdir;
 
711
 
 
712
                if ( urlpre == NULL )
 
713
                        urlpre = def_urlpre;
 
714
        }
 
715
 
 
716
        if( urlpre == NULL ) {
 
717
                urlpre = malloc( sizeof("file:////") + strlen(tmpdir) );
 
718
 
 
719
                if( urlpre == NULL ) {
 
720
                        perror( "malloc" );
 
721
                        return EXIT_FAILURE;
 
722
                }
 
723
 
 
724
                sprintf( urlpre, "file:///%s/",
 
725
                        tmpdir[0] == *LDAP_DIRSEP ? &tmpdir[1] : tmpdir );
 
726
 
 
727
                urlize( urlpre );
 
728
        }
 
729
 
 
730
        if ( debug )
 
731
                ldif_debug = debug;
 
732
 
 
733
        ld = tool_conn_setup( 0, &private_conn_setup );
 
734
 
 
735
        if ( pw_file || want_bindpw ) {
 
736
                if ( pw_file ) {
 
737
                        rc = lutil_get_filed_password( pw_file, &passwd );
 
738
                        if( rc ) return EXIT_FAILURE;
 
739
                } else {
 
740
                        passwd.bv_val = getpassphrase( _("Enter LDAP Password: ") );
 
741
                        passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
 
742
                }
 
743
        }
 
744
 
 
745
        tool_bind( ld );
 
746
 
 
747
getNextPage:
 
748
        save_nctrls = nctrls;
 
749
        i = nctrls;
 
750
        if ( nctrls > 0
 
751
#ifdef LDAP_CONTROL_DONTUSECOPY
 
752
                || dontUseCopy
 
753
#endif
 
754
                || domainScope
 
755
                || pagedResults
 
756
                || ldapsync
 
757
                || subentries
 
758
                || valuesReturnFilter )
 
759
        {
 
760
 
 
761
#ifdef LDAP_CONTROL_DONTUSECOPY
 
762
                if ( dontUseCopy ) {
 
763
                        if ( ctrl_add() ) {
 
764
                                return EXIT_FAILURE;
 
765
                        }
 
766
 
 
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;
 
771
                        i++;
 
772
                }
 
773
#endif
 
774
 
 
775
                if ( domainScope ) {
 
776
                        if ( ctrl_add() ) {
 
777
                                return EXIT_FAILURE;
 
778
                        }
 
779
 
 
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;
 
784
                        i++;
 
785
                }
 
786
 
 
787
                if ( subentries ) {
 
788
                        if ( ctrl_add() ) {
 
789
                                return EXIT_FAILURE;
 
790
                        }
 
791
 
 
792
                        if (( seber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
 
793
                                return EXIT_FAILURE;
 
794
                        }
 
795
 
 
796
                        err = ber_printf( seber, "b", abs(subentries) == 1 ? 0 : 1 );
 
797
                        if ( err == -1 ) {
 
798
                                ber_free( seber, 1 );
 
799
                                fprintf( stderr, _("Subentries control encoding error!\n") );
 
800
                                return EXIT_FAILURE;
 
801
                        }
 
802
 
 
803
                        if ( ber_flatten2( seber, &c[i].ldctl_value, 0 ) == -1 ) {
 
804
                                return EXIT_FAILURE;
 
805
                        }
 
806
 
 
807
                        c[i].ldctl_oid = LDAP_CONTROL_SUBENTRIES;
 
808
                        c[i].ldctl_iscritical = subentries < 1;
 
809
                        i++;
 
810
                }
 
811
 
 
812
                if ( ldapsync ) {
 
813
                        if ( ctrl_add() ) {
 
814
                                return EXIT_FAILURE;
 
815
                        }
 
816
 
 
817
                        if (( syncber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
 
818
                                return EXIT_FAILURE;
 
819
                        }
 
820
 
 
821
                        if ( sync_cookie.bv_len == 0 ) {
 
822
                                err = ber_printf( syncber, "{e}", abs(ldapsync) );
 
823
                        } else {
 
824
                                err = ber_printf( syncber, "{eO}", abs(ldapsync),
 
825
                                                        &sync_cookie );
 
826
                        }
 
827
 
 
828
                        if ( err == LBER_ERROR ) {
 
829
                                ber_free( syncber, 1 );
 
830
                                fprintf( stderr, _("ldap sync control encoding error!\n") );
 
831
                                return EXIT_FAILURE;
 
832
                        }
 
833
 
 
834
                        if ( ber_flatten( syncber, &syncbvalp ) == LBER_ERROR ) {
 
835
                                return EXIT_FAILURE;
 
836
                        }
 
837
 
 
838
                        c[i].ldctl_oid = LDAP_CONTROL_SYNC;
 
839
                        c[i].ldctl_value = (*syncbvalp);
 
840
                        c[i].ldctl_iscritical = ldapsync < 0;
 
841
                        i++;
 
842
                }
 
843
 
 
844
                if ( valuesReturnFilter ) {
 
845
                        if ( ctrl_add() ) {
 
846
                                return EXIT_FAILURE;
 
847
                        }
 
848
 
 
849
                        if (( vrber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
 
850
                                return EXIT_FAILURE;
 
851
                        }
 
852
 
 
853
                        if ( ( err = ldap_put_vrFilter( vrber, vrFilter ) ) == -1 ) {
 
854
                                ber_free( vrber, 1 );
 
855
                                fprintf( stderr, _("Bad ValuesReturnFilter: %s\n"), vrFilter );
 
856
                                return EXIT_FAILURE;
 
857
                        }
 
858
 
 
859
                        if ( ber_flatten2( vrber, &c[i].ldctl_value, 0 ) == -1 ) {
 
860
                                return EXIT_FAILURE;
 
861
                        }
 
862
 
 
863
                        c[i].ldctl_oid = LDAP_CONTROL_VALUESRETURNFILTER;
 
864
                        c[i].ldctl_iscritical = valuesReturnFilter > 1;
 
865
                        i++;
 
866
                }
 
867
 
 
868
                if ( pagedResults ) {
 
869
                        if ( ctrl_add() ) {
 
870
                                return EXIT_FAILURE;
 
871
                        }
 
872
 
 
873
                        if ( ldap_create_page_control_value( ld,
 
874
                                pageSize, &pr_cookie, &c[i].ldctl_value ) )
 
875
                        {
 
876
                                return EXIT_FAILURE;
 
877
                        }
 
878
 
 
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;
 
883
                        }
 
884
                        
 
885
                        c[i].ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
 
886
                        c[i].ldctl_iscritical = pagedResults > 1;
 
887
                        i++;
 
888
                }
 
889
        }
 
890
 
 
891
        tool_server_controls( ld, c, i );
 
892
 
 
893
        ber_free( seber, 1 );
 
894
        ber_free( vrber, 1 );
 
895
 
 
896
        /* step back to the original number of controls, so that 
 
897
         * those set while parsing args are preserved */
 
898
        nctrls = save_nctrls;
 
899
 
 
900
        if ( verbose ) {
 
901
                fprintf( stderr, _("filter%s: %s\nrequesting: "),
 
902
                        infile != NULL ? _(" pattern") : "",
 
903
                        filtpattern );
 
904
 
 
905
                if ( attrs == NULL ) {
 
906
                        fprintf( stderr, _("All userApplication attributes") );
 
907
                } else {
 
908
                        for ( i = 0; attrs[ i ] != NULL; ++i ) {
 
909
                                fprintf( stderr, "%s ", attrs[ i ] );
 
910
                        }
 
911
                }
 
912
                fprintf( stderr, "\n" );
 
913
        }
 
914
 
 
915
        if ( ldif == 0 ) {
 
916
                printf( _("# extended LDIF\n") );
 
917
        } else if ( ldif < 3 ) {
 
918
                printf( _("version: %d\n\n"), 1 );
 
919
        }
 
920
 
 
921
        if (ldif < 2 ) {
 
922
                char    *realbase = base;
 
923
 
 
924
                if ( realbase == NULL ) {
 
925
                        ldap_get_option( ld, LDAP_OPT_DEFBASE, (void **)(char *)&realbase );
 
926
                }
 
927
                
 
928
                printf( "#\n" );
 
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"
 
936
                                : "subtree" ))));
 
937
                printf(_("# filter%s: %s\n"), infile != NULL ? _(" pattern") : "",
 
938
                       filtpattern);
 
939
                printf(_("# requesting: "));
 
940
 
 
941
                if ( attrs == NULL ) {
 
942
                        printf( _("ALL") );
 
943
                } else {
 
944
                        for ( i = 0; attrs[ i ] != NULL; ++i ) {
 
945
                                printf( "%s ", attrs[ i ] );
 
946
                        }
 
947
                }
 
948
 
 
949
                if ( manageDSAit ) {
 
950
                        printf(_("\n# with manageDSAit %scontrol"),
 
951
                                manageDSAit > 1 ? _("critical ") : "" );
 
952
                }
 
953
                if ( noop ) {
 
954
                        printf(_("\n# with noop %scontrol"),
 
955
                                noop > 1 ? _("critical ") : "" );
 
956
                }
 
957
                if ( subentries ) {
 
958
                        printf(_("\n# with subentries %scontrol: %s"),
 
959
                                subentries < 0 ? _("critical ") : "",
 
960
                                abs(subentries) == 1 ? "false" : "true" );
 
961
                }
 
962
                if ( valuesReturnFilter ) {
 
963
                        printf(_("\n# with valuesReturnFilter %scontrol: %s"),
 
964
                                valuesReturnFilter > 1 ? _("critical ") : "", vrFilter );
 
965
                }
 
966
                if ( pagedResults ) {
 
967
                        printf(_("\n# with pagedResults %scontrol: size=%d"),
 
968
                                (pagedResults > 1) ? _("critical ") : "", 
 
969
                                pageSize );
 
970
                }
 
971
 
 
972
                printf( _("\n#\n\n") );
 
973
 
 
974
                if ( realbase && realbase != base ) {
 
975
                        ldap_memfree( realbase );
 
976
                }
 
977
        }
 
978
 
 
979
        if ( infile == NULL ) {
 
980
                rc = dosearch( ld, base, scope, NULL, filtpattern,
 
981
                        attrs, attrsonly, NULL, NULL, NULL, -1 );
 
982
 
 
983
        } else {
 
984
                rc = 0;
 
985
                first = 1;
 
986
                while ( fgets( line, sizeof( line ), fp ) != NULL ) { 
 
987
                        line[ strlen( line ) - 1 ] = '\0';
 
988
                        if ( !first ) {
 
989
                                putchar( '\n' );
 
990
                        } else {
 
991
                                first = 0;
 
992
                        }
 
993
                        rc1 = dosearch( ld, base, scope, filtpattern, line,
 
994
                                attrs, attrsonly, NULL, NULL, NULL, -1 );
 
995
 
 
996
                        if ( rc1 != 0 ) {
 
997
                                rc = rc1;
 
998
                                if ( !contoper )
 
999
                                        break;
 
1000
                        }
 
1001
                }
 
1002
                if ( fp != stdin ) {
 
1003
                        fclose( fp );
 
1004
                }
 
1005
        }
 
1006
 
 
1007
        if (( rc == LDAP_SUCCESS ) && pageSize && pr_morePagedResults ) {
 
1008
                char    buf[6];
 
1009
                int     i, moreEntries, tmpSize;
 
1010
 
 
1011
                /* Loop to get the next pages when 
 
1012
                 * enter is pressed on the terminal.
 
1013
                 */
 
1014
                if ( pagePrompt != 0 ) {
 
1015
                        if ( entriesLeft > 0 ) {
 
1016
                                printf( _("Estimate entries: %d\n"), entriesLeft );
 
1017
                        }
 
1018
                        printf( _("Press [size] Enter for the next {%d|size} entries.\n"),
 
1019
                                (int)pageSize );
 
1020
                        i = 0;
 
1021
                        moreEntries = getchar();
 
1022
                        while ( moreEntries != EOF && moreEntries != '\n' ) { 
 
1023
                                if ( i < (int)sizeof(buf) - 1 ) {
 
1024
                                        buf[i] = moreEntries;
 
1025
                                        i++;
 
1026
                                }
 
1027
                                moreEntries = getchar();
 
1028
                        }
 
1029
                        buf[i] = '\0';
 
1030
 
 
1031
                        if ( i > 0 && isdigit( (unsigned char)buf[0] ) ) {
 
1032
                                int num = sscanf( buf, "%d", &tmpSize );
 
1033
                                if ( num != 1 ) {
 
1034
                                        fprintf( stderr,
 
1035
                                                _("Invalid value for PagedResultsControl, %s.\n"), buf);
 
1036
                                        return EXIT_FAILURE;
 
1037
        
 
1038
                                }
 
1039
                                pageSize = (ber_int_t)tmpSize;
 
1040
                        }
 
1041
                }
 
1042
 
 
1043
                goto getNextPage;
 
1044
        }
 
1045
 
 
1046
        tool_unbind( ld );
 
1047
        tool_destroy();
 
1048
        if ( base != NULL ) {
 
1049
                ber_memfree( base );
 
1050
        }
 
1051
        if ( control != NULL ) {
 
1052
                ber_memfree( control );
 
1053
        }
 
1054
 
 
1055
        if ( c ) {
 
1056
                for ( ; save_nctrls-- > 0; ) {
 
1057
                        ber_memfree( c[ save_nctrls ].ldctl_value.bv_val );
 
1058
                }
 
1059
                free( c );
 
1060
                c = NULL;
 
1061
        }
 
1062
 
 
1063
        return( rc );
 
1064
}
 
1065
 
 
1066
 
 
1067
static int dosearch(
 
1068
        LDAP    *ld,
 
1069
        char    *base,
 
1070
        int             scope,
 
1071
        char    *filtpatt,
 
1072
        char    *value,
 
1073
        char    **attrs,
 
1074
        int             attrsonly,
 
1075
        LDAPControl **sctrls,
 
1076
        LDAPControl **cctrls,
 
1077
        struct timeval *timeout,
 
1078
        int sizelimit )
 
1079
{
 
1080
        char                    *filter;
 
1081
        int                     rc;
 
1082
        int                     nresponses;
 
1083
        int                     nentries;
 
1084
        int                     nreferences;
 
1085
        int                     nextended;
 
1086
        int                     npartial;
 
1087
        LDAPMessage             *res, *msg;
 
1088
        ber_int_t               msgid;
 
1089
        char                    *retoid = NULL;
 
1090
        struct berval           *retdata = NULL;
 
1091
        int                     nresponses_psearch = -1;
 
1092
        int                     cancel_msgid = -1;
 
1093
 
 
1094
        if( filtpatt != NULL ) {
 
1095
                size_t max_fsize = strlen( filtpatt ) + strlen( value ) + 1;
 
1096
                filter = malloc( max_fsize );
 
1097
                if( filter == NULL ) {
 
1098
                        perror( "malloc" );
 
1099
                        return EXIT_FAILURE;
 
1100
                }
 
1101
 
 
1102
                if( snprintf( filter, max_fsize, filtpatt, value ) >= max_fsize ) {
 
1103
                        fprintf( stderr, "Bad filter pattern: \"%s\"\n", filtpatt );
 
1104
                        free( filter );
 
1105
                        return EXIT_FAILURE;
 
1106
                }
 
1107
 
 
1108
                if ( verbose ) {
 
1109
                        fprintf( stderr, _("filter: %s\n"), filter );
 
1110
                }
 
1111
 
 
1112
                if( ldif < 2 ) {
 
1113
                        printf( _("#\n# filter: %s\n#\n"), filter );
 
1114
                }
 
1115
 
 
1116
        } else {
 
1117
                filter = value;
 
1118
        }
 
1119
 
 
1120
        if ( dont ) {
 
1121
                if ( filtpatt != NULL ) {
 
1122
                        free( filter );
 
1123
                }
 
1124
                return LDAP_SUCCESS;
 
1125
        }
 
1126
 
 
1127
        rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
 
1128
                sctrls, cctrls, timeout, sizelimit, &msgid );
 
1129
 
 
1130
        if ( filtpatt != NULL ) {
 
1131
                free( filter );
 
1132
        }
 
1133
 
 
1134
        if( rc != LDAP_SUCCESS ) {
 
1135
                fprintf( stderr, _("%s: ldap_search_ext: %s (%d)\n"),
 
1136
                        prog, ldap_err2string( rc ), rc );
 
1137
                return( rc );
 
1138
        }
 
1139
 
 
1140
        nresponses = nentries = nreferences = nextended = npartial = 0;
 
1141
 
 
1142
        res = NULL;
 
1143
 
 
1144
        while ((rc = ldap_result( ld, LDAP_RES_ANY,
 
1145
                sortattr ? LDAP_MSG_ALL : LDAP_MSG_ONE,
 
1146
                NULL, &res )) > 0 )
 
1147
        {
 
1148
                rc = tool_check_abandon( ld, msgid );
 
1149
                if ( rc ) {
 
1150
                        return rc;
 
1151
                }
 
1152
 
 
1153
                if( sortattr ) {
 
1154
                        (void) ldap_sort_entries( ld, &res,
 
1155
                                ( *sortattr == '\0' ) ? NULL : sortattr, strcasecmp );
 
1156
                }
 
1157
 
 
1158
                for ( msg = ldap_first_message( ld, res );
 
1159
                        msg != NULL;
 
1160
                        msg = ldap_next_message( ld, msg ) )
 
1161
                {
 
1162
                        if ( nresponses++ ) putchar('\n');
 
1163
                        if ( nresponses_psearch >= 0 ) 
 
1164
                                nresponses_psearch++;
 
1165
 
 
1166
                        switch( ldap_msgtype( msg ) ) {
 
1167
                        case LDAP_RES_SEARCH_ENTRY:
 
1168
                                nentries++;
 
1169
                                print_entry( ld, msg, attrsonly );
 
1170
                                break;
 
1171
 
 
1172
                        case LDAP_RES_SEARCH_REFERENCE:
 
1173
                                nreferences++;
 
1174
                                print_reference( ld, msg );
 
1175
                                break;
 
1176
 
 
1177
                        case LDAP_RES_EXTENDED:
 
1178
                                nextended++;
 
1179
                                print_extended( ld, msg );
 
1180
 
 
1181
                                if ( ldap_msgid( msg ) == 0 ) {
 
1182
                                        /* unsolicited extended operation */
 
1183
                                        goto done;
 
1184
                                }
 
1185
 
 
1186
                                if ( cancel_msgid != -1 &&
 
1187
                                                cancel_msgid == ldap_msgid( msg ) ) {
 
1188
                                        printf(_("Cancelled \n"));
 
1189
                                        printf(_("cancel_msgid = %d\n"), cancel_msgid);
 
1190
                                        goto done;
 
1191
                                }
 
1192
                                break;
 
1193
 
 
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 ) {
 
1200
                                        break;
 
1201
                                }
 
1202
 
 
1203
                                goto done;
 
1204
 
 
1205
                        case LDAP_RES_INTERMEDIATE:
 
1206
                                npartial++;
 
1207
                                ldap_parse_intermediate( ld, msg,
 
1208
                                        &retoid, &retdata, NULL, 0 );
 
1209
 
 
1210
                                nresponses_psearch = 0;
 
1211
 
 
1212
                                if ( strcmp( retoid, LDAP_SYNC_INFO ) == 0 ) {
 
1213
                                        printf(_("SyncInfo Received\n"));
 
1214
                                        ldap_memfree( retoid );
 
1215
                                        ber_bvfree( retdata );
 
1216
                                        break;
 
1217
                                }
 
1218
 
 
1219
                                print_partial( ld, msg );
 
1220
                                ldap_memfree( retoid );
 
1221
                                ber_bvfree( retdata );
 
1222
                                goto done;
 
1223
                        }
 
1224
 
 
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;
 
1235
                        }
 
1236
                }
 
1237
 
 
1238
                ldap_msgfree( res );
 
1239
        }
 
1240
 
 
1241
done:
 
1242
        if ( rc == -1 ) {
 
1243
                tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
 
1244
                return( rc );
 
1245
        }
 
1246
 
 
1247
        ldap_msgfree( res );
 
1248
 
 
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 );
 
1259
                        }
 
1260
                        if( npagedextended ) {
 
1261
                                printf( _("# numExtended: %d\n"), npagedextended );
 
1262
                        }
 
1263
                        if( npagedpartial ) {
 
1264
                                printf( _("# numPartial: %d\n"), npagedpartial );
 
1265
                        }
 
1266
                        if( npagedreferences ) {
 
1267
                                printf( _("# numReferences: %d\n"), npagedreferences );
 
1268
                        }
 
1269
                }
 
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 );
 
1276
        }
 
1277
 
 
1278
        return( rc );
 
1279
}
 
1280
 
 
1281
/* This is the proposed new way of doing things.
 
1282
 * It is more efficient, but the API is non-standard.
 
1283
 */
 
1284
static void
 
1285
print_entry(
 
1286
        LDAP    *ld,
 
1287
        LDAPMessage     *entry,
 
1288
        int             attrsonly)
 
1289
{
 
1290
        char            *ufn = NULL;
 
1291
        char    tmpfname[ 256 ];
 
1292
        char    url[ 256 ];
 
1293
        int                     i, rc;
 
1294
        BerElement              *ber = NULL;
 
1295
        struct berval           bv, *bvals, **bvp = &bvals;
 
1296
        LDAPControl **ctrls = NULL;
 
1297
        FILE            *tmpfp;
 
1298
 
 
1299
        rc = ldap_get_dn_ber( ld, entry, &ber, &bv );
 
1300
 
 
1301
        if ( ldif < 2 ) {
 
1302
                ufn = ldap_dn2ufn( bv.bv_val );
 
1303
                tool_write_ldif( LDIF_PUT_COMMENT, NULL, ufn, ufn ? strlen( ufn ) : 0 );
 
1304
        }
 
1305
        tool_write_ldif( LDIF_PUT_VALUE, "dn", bv.bv_val, bv.bv_len );
 
1306
 
 
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 );
 
1312
        }
 
1313
 
 
1314
        if( ctrls ) {
 
1315
                tool_print_ctrls( ld, ctrls );
 
1316
                ldap_controls_free( ctrls );
 
1317
        }
 
1318
 
 
1319
        if ( includeufn ) {
 
1320
                if( ufn == NULL ) {
 
1321
                        ufn = ldap_dn2ufn( bv.bv_val );
 
1322
                }
 
1323
                tool_write_ldif( LDIF_PUT_VALUE, "ufn", ufn, ufn ? strlen( ufn ) : 0 );
 
1324
        }
 
1325
 
 
1326
        if( ufn != NULL ) ldap_memfree( ufn );
 
1327
 
 
1328
        if ( attrsonly ) bvp = NULL;
 
1329
 
 
1330
        for ( rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp );
 
1331
                rc == LDAP_SUCCESS;
 
1332
                rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp ) )
 
1333
        {
 
1334
                if (bv.bv_val == NULL) break;
 
1335
 
 
1336
                if ( attrsonly ) {
 
1337
                        tool_write_ldif( LDIF_PUT_NOVALUE, bv.bv_val, NULL, 0 );
 
1338
 
 
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 )))
 
1343
                                {
 
1344
                                        int tmpfd;
 
1345
                                        /* write value to file */
 
1346
                                        snprintf( tmpfname, sizeof tmpfname,
 
1347
                                                "%s" LDAP_DIRSEP "ldapsearch-%s-XXXXXX",
 
1348
                                                tmpdir, bv.bv_val );
 
1349
                                        tmpfp = NULL;
 
1350
 
 
1351
                                        tmpfd = mkstemp( tmpfname );
 
1352
 
 
1353
                                        if ( tmpfd < 0  ) {
 
1354
                                                perror( tmpfname );
 
1355
                                                continue;
 
1356
                                        }
 
1357
 
 
1358
                                        if (( tmpfp = fdopen( tmpfd, "w")) == NULL ) {
 
1359
                                                perror( tmpfname );
 
1360
                                                continue;
 
1361
                                        }
 
1362
 
 
1363
                                        if ( fwrite( bvals[ i ].bv_val,
 
1364
                                                bvals[ i ].bv_len, 1, tmpfp ) == 0 )
 
1365
                                        {
 
1366
                                                perror( tmpfname );
 
1367
                                                fclose( tmpfp );
 
1368
                                                continue;
 
1369
                                        }
 
1370
 
 
1371
                                        fclose( tmpfp );
 
1372
 
 
1373
                                        snprintf( url, sizeof url, "%s%s", urlpre,
 
1374
                                                &tmpfname[strlen(tmpdir) + sizeof(LDAP_DIRSEP) - 1] );
 
1375
 
 
1376
                                        urlize( url );
 
1377
                                        tool_write_ldif( LDIF_PUT_URL, bv.bv_val, url, strlen( url ));
 
1378
 
 
1379
                                } else {
 
1380
                                        tool_write_ldif( LDIF_PUT_VALUE, bv.bv_val,
 
1381
                                                bvals[ i ].bv_val, bvals[ i ].bv_len );
 
1382
                                }
 
1383
                        }
 
1384
                        ber_memfree( bvals );
 
1385
                }
 
1386
        }
 
1387
 
 
1388
        if( ber != NULL ) {
 
1389
                ber_free( ber, 0 );
 
1390
        }
 
1391
}
 
1392
 
 
1393
static void print_reference(
 
1394
        LDAP *ld,
 
1395
        LDAPMessage *reference )
 
1396
{
 
1397
        int rc;
 
1398
        char **refs = NULL;
 
1399
        LDAPControl **ctrls;
 
1400
 
 
1401
        if( ldif < 2 ) {
 
1402
                printf(_("# search reference\n"));
 
1403
        }
 
1404
 
 
1405
        rc = ldap_parse_reference( ld, reference, &refs, &ctrls, 0 );
 
1406
 
 
1407
        if( rc != LDAP_SUCCESS ) {
 
1408
                tool_perror( "ldap_parse_reference", rc, NULL, NULL, NULL, NULL );
 
1409
                exit( EXIT_FAILURE );
 
1410
        }
 
1411
 
 
1412
        if( refs ) {
 
1413
                int i;
 
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]) );
 
1417
                }
 
1418
                ber_memvfree( (void **) refs );
 
1419
        }
 
1420
 
 
1421
        if( ctrls ) {
 
1422
                tool_print_ctrls( ld, ctrls );
 
1423
                ldap_controls_free( ctrls );
 
1424
        }
 
1425
}
 
1426
 
 
1427
static void print_extended(
 
1428
        LDAP *ld,
 
1429
        LDAPMessage *extended )
 
1430
{
 
1431
        int rc;
 
1432
        char *retoid = NULL;
 
1433
        struct berval *retdata = NULL;
 
1434
 
 
1435
        if( ldif < 2 ) {
 
1436
                printf(_("# extended result response\n"));
 
1437
        }
 
1438
 
 
1439
        rc = ldap_parse_extended_result( ld, extended,
 
1440
                &retoid, &retdata, 0 );
 
1441
 
 
1442
        if( rc != LDAP_SUCCESS ) {
 
1443
                tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
 
1444
                exit( EXIT_FAILURE );
 
1445
        }
 
1446
 
 
1447
        if ( ldif < 2 ) {
 
1448
                tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
 
1449
                        "extended", retoid, retoid ? strlen(retoid) : 0 );
 
1450
        }
 
1451
        ber_memfree( retoid );
 
1452
 
 
1453
        if(retdata) {
 
1454
                if ( ldif < 2 ) {
 
1455
                        tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
 
1456
                                "data", retdata->bv_val, retdata->bv_len );
 
1457
                }
 
1458
                ber_bvfree( retdata );
 
1459
        }
 
1460
 
 
1461
        print_result( ld, extended, 0 );
 
1462
}
 
1463
 
 
1464
static void print_partial(
 
1465
        LDAP *ld,
 
1466
        LDAPMessage *partial )
 
1467
{
 
1468
        int rc;
 
1469
        char *retoid = NULL;
 
1470
        struct berval *retdata = NULL;
 
1471
        LDAPControl **ctrls = NULL;
 
1472
 
 
1473
        if( ldif < 2 ) {
 
1474
                printf(_("# extended partial response\n"));
 
1475
        }
 
1476
 
 
1477
        rc = ldap_parse_intermediate( ld, partial,
 
1478
                &retoid, &retdata, &ctrls, 0 );
 
1479
 
 
1480
        if( rc != LDAP_SUCCESS ) {
 
1481
                tool_perror( "ldap_parse_intermediate", rc, NULL, NULL, NULL, NULL );
 
1482
                exit( EXIT_FAILURE );
 
1483
        }
 
1484
 
 
1485
        if ( ldif < 2 ) {
 
1486
                tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
 
1487
                        "partial", retoid, retoid ? strlen(retoid) : 0 );
 
1488
        }
 
1489
 
 
1490
        ber_memfree( retoid );
 
1491
 
 
1492
        if( retdata ) {
 
1493
                if ( ldif < 2 ) {
 
1494
                        tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
 
1495
                                "data", retdata->bv_val, retdata->bv_len );
 
1496
                }
 
1497
 
 
1498
                ber_bvfree( retdata );
 
1499
        }
 
1500
 
 
1501
        if( ctrls ) {
 
1502
                tool_print_ctrls( ld, ctrls );
 
1503
                ldap_controls_free( ctrls );
 
1504
        }
 
1505
}
 
1506
 
 
1507
static int print_result(
 
1508
        LDAP *ld,
 
1509
        LDAPMessage *result, int search )
 
1510
{
 
1511
        int rc;
 
1512
        int err;
 
1513
        char *matcheddn = NULL;
 
1514
        char *text = NULL;
 
1515
        char **refs = NULL;
 
1516
        LDAPControl **ctrls = NULL;
 
1517
 
 
1518
        if( search ) {
 
1519
                if ( ldif < 2 ) {
 
1520
                        printf(_("# search result\n"));
 
1521
                }
 
1522
                if ( ldif < 1 ) {
 
1523
                        printf("%s: %d\n", _("search"), ldap_msgid(result) );
 
1524
                }
 
1525
        }
 
1526
 
 
1527
        rc = ldap_parse_result( ld, result,
 
1528
                &err, &matcheddn, &text, &refs, &ctrls, 0 );
 
1529
 
 
1530
        if( rc != LDAP_SUCCESS ) {
 
1531
                tool_perror( "ldap_parse_result", rc, NULL, NULL, NULL, NULL );
 
1532
                exit( EXIT_FAILURE );
 
1533
        }
 
1534
 
 
1535
 
 
1536
        if( !ldif ) {
 
1537
                printf( _("result: %d %s\n"), err, ldap_err2string(err) );
 
1538
 
 
1539
        } else if ( err != LDAP_SUCCESS ) {
 
1540
                fprintf( stderr, "%s (%d)\n", ldap_err2string(err), err );
 
1541
        }
 
1542
 
 
1543
        if( matcheddn ) {
 
1544
                if( *matcheddn ) {
 
1545
                if( !ldif ) {
 
1546
                        tool_write_ldif( LDIF_PUT_VALUE,
 
1547
                                "matchedDN", matcheddn, strlen(matcheddn) );
 
1548
                } else {
 
1549
                        fprintf( stderr, _("Matched DN: %s\n"), matcheddn );
 
1550
                }
 
1551
                }
 
1552
 
 
1553
                ber_memfree( matcheddn );
 
1554
        }
 
1555
 
 
1556
        if( text ) {
 
1557
                if( *text ) {
 
1558
                        if( !ldif ) {
 
1559
                                if ( err == LDAP_PARTIAL_RESULTS ) {
 
1560
                                        char    *line;
 
1561
 
 
1562
                                        for ( line = text; line != NULL; ) {
 
1563
                                                char    *next = strchr( line, '\n' );
 
1564
 
 
1565
                                                tool_write_ldif( LDIF_PUT_TEXT,
 
1566
                                                        "text", line,
 
1567
                                                        next ? next - line : strlen( line ) );
 
1568
 
 
1569
                                                line = next ? next + 1 : NULL;
 
1570
                                        }
 
1571
 
 
1572
                                } else {
 
1573
                                        tool_write_ldif( LDIF_PUT_TEXT, "text",
 
1574
                                                text, strlen(text) );
 
1575
                                }
 
1576
                        } else {
 
1577
                                fprintf( stderr, _("Additional information: %s\n"), text );
 
1578
                        }
 
1579
                }
 
1580
 
 
1581
                ber_memfree( text );
 
1582
        }
 
1583
 
 
1584
        if( refs ) {
 
1585
                int i;
 
1586
                for( i=0; refs[i] != NULL; i++ ) {
 
1587
                        if( !ldif ) {
 
1588
                                tool_write_ldif( LDIF_PUT_VALUE, "ref", refs[i], strlen(refs[i]) );
 
1589
                        } else {
 
1590
                                fprintf( stderr, _("Referral: %s\n"), refs[i] );
 
1591
                        }
 
1592
                }
 
1593
 
 
1594
                ber_memvfree( (void **) refs );
 
1595
        }
 
1596
 
 
1597
        pr_morePagedResults = 0;
 
1598
 
 
1599
        if( ctrls ) {
 
1600
                tool_print_ctrls( ld, ctrls );
 
1601
                ldap_controls_free( ctrls );
 
1602
        }
 
1603
 
 
1604
        return err;
 
1605
}
 
1606