~ubuntu-branches/ubuntu/oneiric/likewise-open/oneiric

« back to all changes in this revision

Viewing changes to openldap/clients/tools/ldapsearch.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Salley
  • Date: 2010-11-22 12:06:00 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122120600-8lba1fpceot71wlb
Tags: 6.0.0.53010-1
Likewise Open 6.0

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.19 2009/03/09 23:16:48 quanah Exp $ */
 
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 
4
 *
 
5
 * Copyright 1998-2009 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>              (RFC 3876 matched values filter)\n"));
 
130
        fprintf( stderr, _("             [!]pr=<size>[/prompt|noprompt] (RFC 2696 paged results/prompt)\n"));
 
131
        fprintf( stderr, _("             [!]sss=[-]<attr[:OID]>[/[-]<attr[:OID]>...]\n"));
 
132
        fprintf( stderr, _("                                         (RFC 2891 server side sorting)\n"));
 
133
        fprintf( stderr, _("             [!]subentries[=true|false]  (RFC 3672 subentries)\n"));
 
134
        fprintf( stderr, _("             [!]sync=ro[/<cookie>]       (RFC 4533 LDAP Sync refreshOnly)\n"));
 
135
        fprintf( stderr, _("                     rp[/<cookie>][/<slimit>] (refreshAndPersist)\n"));
 
136
#ifdef LDAP_CONTROL_X_DEREF
 
137
        fprintf( stderr, _("             [!]deref=derefAttr:attr[,...][;derefAttr:attr[,...][;...]]\n"));
 
138
#endif
 
139
        fprintf( stderr, _("             [!]<oid>=:<value>           (generic control; no response handling)\n"));
 
140
        fprintf( stderr, _("  -F prefix  URL prefix for files (default: %s)\n"), def_urlpre);
 
141
        fprintf( stderr, _("  -l limit   time limit (in seconds, or \"none\" or \"max\") for search\n"));
 
142
        fprintf( stderr, _("  -L         print responses in LDIFv1 format\n"));
 
143
        fprintf( stderr, _("  -LL        print responses in LDIF format without comments\n"));
 
144
        fprintf( stderr, _("  -LLL       print responses in LDIF format without comments\n"));
 
145
        fprintf( stderr, _("             and version\n"));
 
146
        fprintf( stderr, _("  -s scope   one of base, one, sub or children (search scope)\n"));
 
147
        fprintf( stderr, _("  -S attr    sort the results by attribute `attr'\n"));
 
148
        fprintf( stderr, _("  -t         write binary values to files in temporary directory\n"));
 
149
        fprintf( stderr, _("  -tt        write all values to files in temporary directory\n"));
 
150
        fprintf( stderr, _("  -T path    write files to directory specified by path (default: %s)\n"), def_tmpdir);
 
151
        fprintf( stderr, _("  -u         include User Friendly entry names in the output\n"));
 
152
        fprintf( stderr, _("  -z limit   size limit (in entries, or \"none\" or \"max\") for search\n"));
 
153
        tool_common_usage();
 
154
        exit( EXIT_FAILURE );
 
155
}
 
156
 
 
157
static void print_entry LDAP_P((
 
158
        LDAP    *ld,
 
159
        LDAPMessage     *entry,
 
160
        int             attrsonly));
 
161
 
 
162
static void print_reference(
 
163
        LDAP *ld,
 
164
        LDAPMessage *reference );
 
165
 
 
166
static void print_extended(
 
167
        LDAP *ld,
 
168
        LDAPMessage *extended );
 
169
 
 
170
static void print_partial(
 
171
        LDAP *ld,
 
172
        LDAPMessage *partial );
 
173
 
 
174
static int print_result(
 
175
        LDAP *ld,
 
176
        LDAPMessage *result,
 
177
        int search );
 
178
 
 
179
static int dosearch LDAP_P((
 
180
        LDAP    *ld,
 
181
        char    *base,
 
182
        int             scope,
 
183
        char    *filtpatt,
 
184
        char    *value,
 
185
        char    **attrs,
 
186
        int             attrsonly,
 
187
        LDAPControl **sctrls,
 
188
        LDAPControl **cctrls,
 
189
        struct timeval *timeout,
 
190
        int     sizelimit ));
 
191
 
 
192
static char *tmpdir = NULL;
 
193
static char *urlpre = NULL;
 
194
static char     *base = NULL;
 
195
static char     *sortattr = NULL;
 
196
static int  includeufn, vals2tmp = 0;
 
197
 
 
198
static int subentries = 0, valuesReturnFilter = 0;
 
199
static char     *vrFilter = NULL;
 
200
 
 
201
#ifdef LDAP_CONTROL_DONTUSECOPY
 
202
static int dontUseCopy = 0;
 
203
#endif
 
204
 
 
205
static int domainScope = 0;
 
206
 
 
207
static int sss = 0;
 
208
static LDAPSortKey **sss_keys = NULL;
 
209
 
 
210
static int ldapsync = 0;
 
211
static struct berval sync_cookie = { 0, NULL };
 
212
static int sync_slimit = -1;
 
213
 
 
214
/* cookie and morePagedResults moved to common.c */
 
215
static int pagedResults = 0;
 
216
static int pagePrompt = 1;
 
217
static ber_int_t pageSize = 0;
 
218
static ber_int_t entriesLeft = 0;
 
219
static int npagedresponses;
 
220
static int npagedentries;
 
221
static int npagedreferences;
 
222
static int npagedextended;
 
223
static int npagedpartial;
 
224
 
 
225
static LDAPControl *c = NULL;
 
226
static int nctrls = 0;
 
227
static int save_nctrls = 0;
 
228
 
 
229
#ifdef LDAP_CONTROL_X_DEREF
 
230
static int derefcrit;
 
231
static LDAPDerefSpec *ds;
 
232
static struct berval derefval;
 
233
#endif
 
234
 
 
235
static int
 
236
ctrl_add( void )
 
237
{
 
238
        LDAPControl     *tmpc;
 
239
 
 
240
        nctrls++;
 
241
        tmpc = realloc( c, sizeof( LDAPControl ) * nctrls );
 
242
        if ( tmpc == NULL ) {
 
243
                nctrls--;
 
244
                fprintf( stderr,
 
245
                        _("unable to make room for control; out of memory?\n"));
 
246
                return -1;
 
247
        }
 
248
        c = tmpc;
 
249
 
 
250
        return 0;
 
251
}
 
252
 
 
253
static void
 
254
urlize(char *url)
 
255
{
 
256
        char *p;
 
257
 
 
258
        if (*LDAP_DIRSEP != '/') {
 
259
                for (p = url; *p; p++) {
 
260
                        if (*p == *LDAP_DIRSEP)
 
261
                                *p = '/';
 
262
                }
 
263
        }
 
264
}
 
265
 
 
266
 
 
267
const char options[] = "a:Ab:cE:F:l:Ls:S:tT:uz:"
 
268
        "Cd:D:e:f:h:H:IMnNO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
 
269
 
 
270
int
 
271
handle_private_option( int i )
 
272
{
 
273
        int crit, ival;
 
274
        char *cvalue, *next;
 
275
        switch ( i ) {
 
276
        case 'a':       /* set alias deref option */
 
277
                if ( strcasecmp( optarg, "never" ) == 0 ) {
 
278
                        deref = LDAP_DEREF_NEVER;
 
279
                } else if ( strncasecmp( optarg, "search", sizeof("search")-1 ) == 0 ) {
 
280
                        deref = LDAP_DEREF_SEARCHING;
 
281
                } else if ( strncasecmp( optarg, "find", sizeof("find")-1 ) == 0 ) {
 
282
                        deref = LDAP_DEREF_FINDING;
 
283
                } else if ( strcasecmp( optarg, "always" ) == 0 ) {
 
284
                        deref = LDAP_DEREF_ALWAYS;
 
285
                } else {
 
286
                        fprintf( stderr,
 
287
                                _("alias deref should be never, search, find, or always\n") );
 
288
                        usage();
 
289
                }
 
290
                break;
 
291
        case 'A':       /* retrieve attribute names only -- no values */
 
292
                ++attrsonly;
 
293
                break;
 
294
        case 'b': /* search base */
 
295
                base = ber_strdup( optarg );
 
296
                break;
 
297
        case 'E': /* search extensions */
 
298
                if( protocol == LDAP_VERSION2 ) {
 
299
                        fprintf( stderr, _("%s: -E incompatible with LDAPv%d\n"),
 
300
                                prog, protocol );
 
301
                        exit( EXIT_FAILURE );
 
302
                }
 
303
 
 
304
                /* should be extended to support comma separated list of
 
305
                 *      [!]key[=value] parameters, e.g.  -E !foo,bar=567
 
306
                 */
 
307
 
 
308
                crit = 0;
 
309
                cvalue = NULL;
 
310
                if( optarg[0] == '!' ) {
 
311
                        crit = 1;
 
312
                        optarg++;
 
313
                }
 
314
 
 
315
                control = ber_strdup( optarg );
 
316
                if ( (cvalue = strchr( control, '=' )) != NULL ) {
 
317
                        *cvalue++ = '\0';
 
318
                }
 
319
 
 
320
                if ( strcasecmp( control, "mv" ) == 0 ) {
 
321
                        /* ValuesReturnFilter control */
 
322
                        if( valuesReturnFilter ) {
 
323
                                fprintf( stderr,
 
324
                                        _("ValuesReturnFilter previously specified\n"));
 
325
                                exit( EXIT_FAILURE );
 
326
                        }
 
327
                        valuesReturnFilter= 1 + crit;
 
328
 
 
329
                        if ( cvalue == NULL ) {
 
330
                                fprintf( stderr,
 
331
                                        _("missing filter in ValuesReturnFilter control\n"));
 
332
                                exit( EXIT_FAILURE );
 
333
                        }
 
334
 
 
335
                        vrFilter = cvalue;
 
336
                        protocol = LDAP_VERSION3;
 
337
 
 
338
                } else if ( strcasecmp( control, "pr" ) == 0 ) {
 
339
                        int num, tmp;
 
340
                        /* PagedResults control */
 
341
                        if ( pagedResults != 0 ) {
 
342
                                fprintf( stderr,
 
343
                                        _("PagedResultsControl previously specified\n") );
 
344
                                exit( EXIT_FAILURE );
 
345
                        }
 
346
 
 
347
                        if( cvalue != NULL ) {
 
348
                                char *promptp;
 
349
 
 
350
                                promptp = strchr( cvalue, '/' );
 
351
                                if ( promptp != NULL ) {
 
352
                                        *promptp++ = '\0';
 
353
                                        if ( strcasecmp( promptp, "prompt" ) == 0 ) {
 
354
                                                pagePrompt = 1;
 
355
                                        } else if ( strcasecmp( promptp, "noprompt" ) == 0) {
 
356
                                                pagePrompt = 0;
 
357
                                        } else {
 
358
                                                fprintf( stderr,
 
359
                                                        _("Invalid value for PagedResultsControl,"
 
360
                                                        " %s/%s.\n"), cvalue, promptp );
 
361
                                                exit( EXIT_FAILURE );
 
362
                                        }
 
363
                                }
 
364
                                num = sscanf( cvalue, "%d", &tmp );
 
365
                                if ( num != 1 ) {
 
366
                                        fprintf( stderr,
 
367
                                                _("Invalid value for PagedResultsControl, %s.\n"),
 
368
                                                cvalue );
 
369
                                        exit( EXIT_FAILURE );
 
370
                                }
 
371
                        } else {
 
372
                                fprintf(stderr, _("Invalid value for PagedResultsControl.\n"));
 
373
                                exit( EXIT_FAILURE );
 
374
                        }
 
375
                        pageSize = (ber_int_t) tmp;
 
376
                        pagedResults = 1 + crit;
 
377
 
 
378
#ifdef LDAP_CONTROL_DONTUSECOPY
 
379
                } else if ( strcasecmp( control, "dontUseCopy" ) == 0 ) {
 
380
                        if( dontUseCopy ) {
 
381
                                fprintf( stderr,
 
382
                                        _("dontUseCopy control previously specified\n"));
 
383
                                exit( EXIT_FAILURE );
 
384
                        }
 
385
                        if( cvalue != NULL ) {
 
386
                                fprintf( stderr,
 
387
                                 _("dontUseCopy: no control value expected\n") );
 
388
                                usage();
 
389
                        }
 
390
                        if( !crit ) {
 
391
                                fprintf( stderr,
 
392
                                 _("dontUseCopy: critical flag required\n") );
 
393
                                usage();
 
394
                        }
 
395
 
 
396
                        dontUseCopy = 1 + crit;
 
397
#endif
 
398
                } else if ( strcasecmp( control, "domainScope" ) == 0 ) {
 
399
                        if( domainScope ) {
 
400
                                fprintf( stderr,
 
401
                                        _("domainScope control previously specified\n"));
 
402
                                exit( EXIT_FAILURE );
 
403
                        }
 
404
                        if( cvalue != NULL ) {
 
405
                                fprintf( stderr,
 
406
                                 _("domainScope: no control value expected\n") );
 
407
                                usage();
 
408
                        }
 
409
 
 
410
                        domainScope = 1 + crit;
 
411
 
 
412
                } else if ( strcasecmp( control, "sss" ) == 0 ) {
 
413
                        char *keyp;
 
414
                        if( sss ) {
 
415
                                fprintf( stderr,
 
416
                                        _("server side sorting control previously specified\n"));
 
417
                                exit( EXIT_FAILURE );
 
418
                        }
 
419
                        if( cvalue == NULL ) {
 
420
                                fprintf( stderr,
 
421
                                 _("missing specification of sss control\n") );
 
422
                                exit( EXIT_FAILURE );
 
423
                        }
 
424
                        keyp = cvalue;
 
425
                        while ( ( keyp = strchr(keyp, '/') ) != NULL ) {
 
426
                                *keyp++ = ' ';
 
427
                        }
 
428
                        if ( ldap_create_sort_keylist( &sss_keys, cvalue )) {
 
429
                                fprintf( stderr,
 
430
                                        _("server side sorting control value \"%s\" invalid\n"),
 
431
                                        cvalue );
 
432
                                exit( EXIT_FAILURE );
 
433
                        }
 
434
 
 
435
                        sss = 1 + crit;
 
436
 
 
437
                } else if ( strcasecmp( control, "subentries" ) == 0 ) {
 
438
                        if( subentries ) {
 
439
                                fprintf( stderr,
 
440
                                        _("subentries control previously specified\n"));
 
441
                                exit( EXIT_FAILURE );
 
442
                        }
 
443
                        if( cvalue == NULL || strcasecmp( cvalue, "true") == 0 ) {
 
444
                                subentries = 2;
 
445
                        } else if ( strcasecmp( cvalue, "false") == 0 ) {
 
446
                                subentries = 1;
 
447
                        } else {
 
448
                                fprintf( stderr,
 
449
                                        _("subentries control value \"%s\" invalid\n"),
 
450
                                        cvalue );
 
451
                                exit( EXIT_FAILURE );
 
452
                        }
 
453
                        if( crit ) subentries *= -1;
 
454
 
 
455
                } else if ( strcasecmp( control, "sync" ) == 0 ) {
 
456
                        char *cookiep;
 
457
                        char *slimitp;
 
458
                        if ( ldapsync ) {
 
459
                                fprintf( stderr, _("sync control previously specified\n") );
 
460
                                exit( EXIT_FAILURE );
 
461
                        }
 
462
                        if ( cvalue == NULL ) {
 
463
                                fprintf( stderr, _("missing specification of sync control\n"));
 
464
                                exit( EXIT_FAILURE );
 
465
                        }
 
466
                        if ( strncasecmp( cvalue, "ro", 2 ) == 0 ) {
 
467
                                ldapsync = LDAP_SYNC_REFRESH_ONLY;
 
468
                                cookiep = strchr( cvalue, '/' );
 
469
                                if ( cookiep != NULL ) {
 
470
                                        cookiep++;
 
471
                                        if ( *cookiep != '\0' ) {
 
472
                                                ber_str2bv( cookiep, 0, 0, &sync_cookie );
 
473
                                        }
 
474
                                }
 
475
                        } else if ( strncasecmp( cvalue, "rp", 2 ) == 0 ) {
 
476
                                ldapsync = LDAP_SYNC_REFRESH_AND_PERSIST;
 
477
                                cookiep = strchr( cvalue, '/' );
 
478
                                if ( cookiep != NULL ) {
 
479
                                        *cookiep++ = '\0';      
 
480
                                        cvalue = cookiep;
 
481
                                }
 
482
                                slimitp = strchr( cvalue, '/' );
 
483
                                if ( slimitp != NULL ) {
 
484
                                        *slimitp++ = '\0';
 
485
                                }
 
486
                                if ( cookiep != NULL && *cookiep != '\0' )
 
487
                                        ber_str2bv( cookiep, 0, 0, &sync_cookie );
 
488
                                if ( slimitp != NULL && *slimitp != '\0' ) {
 
489
                                        ival = strtol( slimitp, &next, 10 );
 
490
                                        if ( next == NULL || next[0] != '\0' ) {
 
491
                                                fprintf( stderr, _("Unable to parse sync control value \"%s\"\n"), slimitp );
 
492
                                                exit( EXIT_FAILURE );
 
493
                                        }
 
494
                                        sync_slimit = ival;
 
495
                                }
 
496
                        } else {
 
497
                                fprintf( stderr, _("sync control value \"%s\" invalid\n"),
 
498
                                        cvalue );
 
499
                                exit( EXIT_FAILURE );
 
500
                        }
 
501
                        if ( crit ) ldapsync *= -1;
 
502
 
 
503
#ifdef LDAP_CONTROL_X_DEREF
 
504
                } else if ( strcasecmp( control, "deref" ) == 0 ) {
 
505
                        int ispecs;
 
506
                        char **specs;
 
507
 
 
508
                        /* cvalue is something like
 
509
                         *
 
510
                         * derefAttr:attr[,attr[...]][;derefAttr:attr[,attr[...]]]"
 
511
                         */
 
512
 
 
513
                        specs = ldap_str2charray( cvalue, ";" );
 
514
                        if ( specs == NULL ) {
 
515
                                fprintf( stderr, _("deref specs \"%s\" invalid\n"),
 
516
                                        cvalue );
 
517
                                exit( EXIT_FAILURE );
 
518
                        }
 
519
                        for ( ispecs = 0; specs[ ispecs ] != NULL; ispecs++ )
 
520
                                /* count'em */
 
521
 
 
522
                        ds = ldap_memcalloc( ispecs + 1, sizeof( LDAPDerefSpec ) );
 
523
                        if ( ds == NULL ) {
 
524
                                perror( "malloc" );
 
525
                                exit( EXIT_FAILURE );
 
526
                        }
 
527
 
 
528
                        for ( ispecs = 0; specs[ ispecs ] != NULL; ispecs++ ) {
 
529
                                char *ptr;
 
530
 
 
531
                                ptr = strchr( specs[ ispecs ], ':' );
 
532
                                if ( ptr == NULL ) {
 
533
                                        fprintf( stderr, _("deref specs \"%s\" invalid\n"),
 
534
                                                cvalue );
 
535
                                        exit( EXIT_FAILURE );
 
536
                                }
 
537
 
 
538
                                ds[ ispecs ].derefAttr = specs[ ispecs ];
 
539
                                *ptr++ = '\0';
 
540
                                ds[ ispecs ].attributes = ldap_str2charray( ptr, "," );
 
541
                        }
 
542
 
 
543
                        derefcrit = 1 + crit;
 
544
 
 
545
                        ldap_memfree( specs );
 
546
#endif /* LDAP_CONTROL_X_DEREF */
 
547
 
 
548
                } else if ( tool_is_oid( control ) ) {
 
549
                        if ( ctrl_add() ) {
 
550
                                exit( EXIT_FAILURE );
 
551
                        }
 
552
 
 
553
                        /* OID */
 
554
                        c[ nctrls - 1 ].ldctl_oid = control;
 
555
 
 
556
                        /* value */
 
557
                        if ( cvalue == NULL ) {
 
558
                                c[ nctrls - 1 ].ldctl_value.bv_val = NULL;
 
559
                                c[ nctrls - 1 ].ldctl_value.bv_len = 0;
 
560
 
 
561
                        } else if ( cvalue[ 0 ] == ':' ) {
 
562
                                struct berval   type;
 
563
                                struct berval   value;
 
564
                                int             freeval;
 
565
 
 
566
                                cvalue++;
 
567
 
 
568
                                /* dummy type "x"
 
569
                                 * to use ldif_parse_line2() */
 
570
                                cvalue[ -2 ] = 'x';
 
571
                                ldif_parse_line2( &cvalue[ -2 ], &type,
 
572
                                        &value, &freeval );
 
573
                                cvalue[ -2 ] = '\0';
 
574
 
 
575
                                if ( freeval ) {
 
576
                                        c[ nctrls - 1 ].ldctl_value = value;
 
577
 
 
578
                                } else {
 
579
                                        ber_dupbv( &c[ nctrls - 1 ].ldctl_value, &value );
 
580
                                }
 
581
                        }
 
582
 
 
583
                        /* criticality */
 
584
                        c[ nctrls - 1 ].ldctl_iscritical = crit;
 
585
 
 
586
                } else {
 
587
                        fprintf( stderr, _("Invalid search extension name: %s\n"),
 
588
                                control );
 
589
                        usage();
 
590
                }
 
591
                break;
 
592
        case 'F':       /* uri prefix */
 
593
                if( urlpre ) free( urlpre );
 
594
                urlpre = strdup( optarg );
 
595
                break;
 
596
        case 'l':       /* time limit */
 
597
                if ( strcasecmp( optarg, "none" ) == 0 ) {
 
598
                        timelimit = 0;
 
599
 
 
600
                } else if ( strcasecmp( optarg, "max" ) == 0 ) {
 
601
                        timelimit = LDAP_MAXINT;
 
602
 
 
603
                } else {
 
604
                        ival = strtol( optarg, &next, 10 );
 
605
                        if ( next == NULL || next[0] != '\0' ) {
 
606
                                fprintf( stderr,
 
607
                                        _("Unable to parse time limit \"%s\"\n"), optarg );
 
608
                                exit( EXIT_FAILURE );
 
609
                        }
 
610
                        timelimit = ival;
 
611
                }
 
612
                if( timelimit < 0 || timelimit > LDAP_MAXINT ) {
 
613
                        fprintf( stderr, _("%s: invalid timelimit (%d) specified\n"),
 
614
                                prog, timelimit );
 
615
                        exit( EXIT_FAILURE );
 
616
                }
 
617
                break;
 
618
        case 'L':       /* print entries in LDIF format */
 
619
                ++ldif;
 
620
                break;
 
621
        case 's':       /* search scope */
 
622
                if ( strncasecmp( optarg, "base", sizeof("base")-1 ) == 0 ) {
 
623
                        scope = LDAP_SCOPE_BASE;
 
624
                } else if ( strncasecmp( optarg, "one", sizeof("one")-1 ) == 0 ) {
 
625
                        scope = LDAP_SCOPE_ONELEVEL;
 
626
                } else if (( strcasecmp( optarg, "subordinate" ) == 0 )
 
627
                        || ( strcasecmp( optarg, "children" ) == 0 ))
 
628
                {
 
629
                        scope = LDAP_SCOPE_SUBORDINATE;
 
630
                } else if ( strncasecmp( optarg, "sub", sizeof("sub")-1 ) == 0 ) {
 
631
                        scope = LDAP_SCOPE_SUBTREE;
 
632
                } else {
 
633
                        fprintf( stderr, _("scope should be base, one, or sub\n") );
 
634
                        usage();
 
635
                }
 
636
                break;
 
637
        case 'S':       /* sort attribute */
 
638
                sortattr = strdup( optarg );
 
639
                break;
 
640
        case 't':       /* write attribute values to TMPDIR files */
 
641
                ++vals2tmp;
 
642
                break;
 
643
        case 'T':       /* tmpdir */
 
644
                if( tmpdir ) free( tmpdir );
 
645
                tmpdir = strdup( optarg );
 
646
                break;
 
647
        case 'u':       /* include UFN */
 
648
                ++includeufn;
 
649
                break;
 
650
        case 'z':       /* size limit */
 
651
                if ( strcasecmp( optarg, "none" ) == 0 ) {
 
652
                        sizelimit = 0;
 
653
 
 
654
                } else if ( strcasecmp( optarg, "max" ) == 0 ) {
 
655
                        sizelimit = LDAP_MAXINT;
 
656
 
 
657
                } else {
 
658
                        ival = strtol( optarg, &next, 10 );
 
659
                        if ( next == NULL || next[0] != '\0' ) {
 
660
                                fprintf( stderr,
 
661
                                        _("Unable to parse size limit \"%s\"\n"), optarg );
 
662
                                exit( EXIT_FAILURE );
 
663
                        }
 
664
                        sizelimit = ival;
 
665
                }
 
666
                if( sizelimit < 0 || sizelimit > LDAP_MAXINT ) {
 
667
                        fprintf( stderr, _("%s: invalid sizelimit (%d) specified\n"),
 
668
                                prog, sizelimit );
 
669
                        exit( EXIT_FAILURE );
 
670
                }
 
671
                break;
 
672
        default:
 
673
                return 0;
 
674
        }
 
675
        return 1;
 
676
}
 
677
 
 
678
 
 
679
static void
 
680
private_conn_setup( LDAP *ld )
 
681
{
 
682
        if (deref != -1 &&
 
683
                ldap_set_option( ld, LDAP_OPT_DEREF, (void *) &deref )
 
684
                        != LDAP_OPT_SUCCESS )
 
685
        {
 
686
                fprintf( stderr, _("Could not set LDAP_OPT_DEREF %d\n"), deref );
 
687
                exit( EXIT_FAILURE );
 
688
        }
 
689
        if (timelimit > 0 &&
 
690
                ldap_set_option( ld, LDAP_OPT_TIMELIMIT, (void *) &timelimit )
 
691
                        != LDAP_OPT_SUCCESS )
 
692
        {
 
693
                fprintf( stderr,
 
694
                        _("Could not set LDAP_OPT_TIMELIMIT %d\n"), timelimit );
 
695
                exit( EXIT_FAILURE );
 
696
        }
 
697
        if (sizelimit > 0 &&
 
698
                ldap_set_option( ld, LDAP_OPT_SIZELIMIT, (void *) &sizelimit )
 
699
                        != LDAP_OPT_SUCCESS )
 
700
        {
 
701
                fprintf( stderr,
 
702
                        _("Could not set LDAP_OPT_SIZELIMIT %d\n"), sizelimit );
 
703
                exit( EXIT_FAILURE );
 
704
        }
 
705
}
 
706
 
 
707
int
 
708
main( int argc, char **argv )
 
709
{
 
710
        char            *filtpattern, **attrs = NULL, line[BUFSIZ];
 
711
        FILE            *fp = NULL;
 
712
        int                     rc, rc1, i, first;
 
713
        LDAP            *ld = NULL;
 
714
        BerElement      *seber = NULL, *vrber = NULL;
 
715
 
 
716
        BerElement      *syncber = NULL;
 
717
        struct berval   *syncbvalp = NULL;
 
718
        int             err;
 
719
 
 
720
        tool_init( TOOL_SEARCH );
 
721
 
 
722
        npagedresponses = npagedentries = npagedreferences =
 
723
                npagedextended = npagedpartial = 0;
 
724
 
 
725
        prog = lutil_progname( "ldapsearch", argc, argv );
 
726
 
 
727
        if((def_tmpdir = getenv("TMPDIR")) == NULL &&
 
728
           (def_tmpdir = getenv("TMP")) == NULL &&
 
729
           (def_tmpdir = getenv("TEMP")) == NULL )
 
730
        {
 
731
                def_tmpdir = LDAP_TMPDIR;
 
732
        }
 
733
 
 
734
        if ( !*def_tmpdir )
 
735
                def_tmpdir = LDAP_TMPDIR;
 
736
 
 
737
        def_urlpre = malloc( sizeof("file:////") + strlen(def_tmpdir) );
 
738
 
 
739
        if( def_urlpre == NULL ) {
 
740
                perror( "malloc" );
 
741
                return EXIT_FAILURE;
 
742
        }
 
743
 
 
744
        sprintf( def_urlpre, "file:///%s/",
 
745
                def_tmpdir[0] == *LDAP_DIRSEP ? &def_tmpdir[1] : def_tmpdir );
 
746
 
 
747
        urlize( def_urlpre );
 
748
 
 
749
        tool_args( argc, argv );
 
750
 
 
751
        if (( argc - optind < 1 ) ||
 
752
                ( *argv[optind] != '(' /*')'*/ &&
 
753
                ( strchr( argv[optind], '=' ) == NULL ) ) )
 
754
        {
 
755
                filtpattern = "(objectclass=*)";
 
756
        } else {
 
757
                filtpattern = argv[optind++];
 
758
        }
 
759
 
 
760
        if ( argv[optind] != NULL ) {
 
761
                attrs = &argv[optind];
 
762
        }
 
763
 
 
764
        if ( infile != NULL ) {
 
765
                int percent = 0;
 
766
 
 
767
                if ( infile[0] == '-' && infile[1] == '\0' ) {
 
768
                        fp = stdin;
 
769
                } else if (( fp = fopen( infile, "r" )) == NULL ) {
 
770
                        perror( infile );
 
771
                        return EXIT_FAILURE;
 
772
                }
 
773
 
 
774
                for( i=0 ; filtpattern[i] ; i++ ) {
 
775
                        if( filtpattern[i] == '%' ) {
 
776
                                if( percent ) {
 
777
                                        fprintf( stderr, _("Bad filter pattern \"%s\"\n"),
 
778
                                                filtpattern );
 
779
                                        return EXIT_FAILURE;
 
780
                                }
 
781
 
 
782
                                percent++;
 
783
 
 
784
                                if( filtpattern[i+1] != 's' ) {
 
785
                                        fprintf( stderr, _("Bad filter pattern \"%s\"\n"),
 
786
                                                filtpattern );
 
787
                                        return EXIT_FAILURE;
 
788
                                }
 
789
                        }
 
790
                }
 
791
        }
 
792
 
 
793
        if ( tmpdir == NULL ) {
 
794
                tmpdir = def_tmpdir;
 
795
 
 
796
                if ( urlpre == NULL )
 
797
                        urlpre = def_urlpre;
 
798
        }
 
799
 
 
800
        if( urlpre == NULL ) {
 
801
                urlpre = malloc( sizeof("file:////") + strlen(tmpdir) );
 
802
 
 
803
                if( urlpre == NULL ) {
 
804
                        perror( "malloc" );
 
805
                        return EXIT_FAILURE;
 
806
                }
 
807
 
 
808
                sprintf( urlpre, "file:///%s/",
 
809
                        tmpdir[0] == *LDAP_DIRSEP ? &tmpdir[1] : tmpdir );
 
810
 
 
811
                urlize( urlpre );
 
812
        }
 
813
 
 
814
        if ( debug )
 
815
                ldif_debug = debug;
 
816
 
 
817
        ld = tool_conn_setup( 0, &private_conn_setup );
 
818
 
 
819
        if ( pw_file || want_bindpw ) {
 
820
                if ( pw_file ) {
 
821
                        rc = lutil_get_filed_password( pw_file, &passwd );
 
822
                        if( rc ) return EXIT_FAILURE;
 
823
                } else {
 
824
                        passwd.bv_val = getpassphrase( _("Enter LDAP Password: ") );
 
825
                        passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
 
826
                }
 
827
        }
 
828
 
 
829
        tool_bind( ld );
 
830
 
 
831
getNextPage:
 
832
        save_nctrls = nctrls;
 
833
        i = nctrls;
 
834
        if ( nctrls > 0
 
835
#ifdef LDAP_CONTROL_DONTUSECOPY
 
836
                || dontUseCopy
 
837
#endif
 
838
#ifdef LDAP_CONTROL_X_DEREF
 
839
                || derefcrit
 
840
#endif
 
841
                || domainScope
 
842
                || pagedResults
 
843
                || ldapsync
 
844
                || sss
 
845
                || subentries
 
846
                || valuesReturnFilter )
 
847
        {
 
848
 
 
849
#ifdef LDAP_CONTROL_DONTUSECOPY
 
850
                if ( dontUseCopy ) {
 
851
                        if ( ctrl_add() ) {
 
852
                                return EXIT_FAILURE;
 
853
                        }
 
854
 
 
855
                        c[i].ldctl_oid = LDAP_CONTROL_DONTUSECOPY;
 
856
                        c[i].ldctl_value.bv_val = NULL;
 
857
                        c[i].ldctl_value.bv_len = 0;
 
858
                        c[i].ldctl_iscritical = dontUseCopy > 1;
 
859
                        i++;
 
860
                }
 
861
#endif
 
862
 
 
863
                if ( domainScope ) {
 
864
                        if ( ctrl_add() ) {
 
865
                                return EXIT_FAILURE;
 
866
                        }
 
867
 
 
868
                        c[i].ldctl_oid = LDAP_CONTROL_X_DOMAIN_SCOPE;
 
869
                        c[i].ldctl_value.bv_val = NULL;
 
870
                        c[i].ldctl_value.bv_len = 0;
 
871
                        c[i].ldctl_iscritical = domainScope > 1;
 
872
                        i++;
 
873
                }
 
874
 
 
875
                if ( subentries ) {
 
876
                        if ( ctrl_add() ) {
 
877
                                return EXIT_FAILURE;
 
878
                        }
 
879
 
 
880
                        if (( seber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
 
881
                                return EXIT_FAILURE;
 
882
                        }
 
883
 
 
884
                        err = ber_printf( seber, "b", abs(subentries) == 1 ? 0 : 1 );
 
885
                        if ( err == -1 ) {
 
886
                                ber_free( seber, 1 );
 
887
                                fprintf( stderr, _("Subentries control encoding error!\n") );
 
888
                                return EXIT_FAILURE;
 
889
                        }
 
890
 
 
891
                        if ( ber_flatten2( seber, &c[i].ldctl_value, 0 ) == -1 ) {
 
892
                                return EXIT_FAILURE;
 
893
                        }
 
894
 
 
895
                        c[i].ldctl_oid = LDAP_CONTROL_SUBENTRIES;
 
896
                        c[i].ldctl_iscritical = subentries < 1;
 
897
                        i++;
 
898
                }
 
899
 
 
900
                if ( ldapsync ) {
 
901
                        if ( ctrl_add() ) {
 
902
                                return EXIT_FAILURE;
 
903
                        }
 
904
 
 
905
                        if (( syncber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
 
906
                                return EXIT_FAILURE;
 
907
                        }
 
908
 
 
909
                        if ( sync_cookie.bv_len == 0 ) {
 
910
                                err = ber_printf( syncber, "{e}", abs(ldapsync) );
 
911
                        } else {
 
912
                                err = ber_printf( syncber, "{eO}", abs(ldapsync),
 
913
                                                        &sync_cookie );
 
914
                        }
 
915
 
 
916
                        if ( err == -1 ) {
 
917
                                ber_free( syncber, 1 );
 
918
                                fprintf( stderr, _("ldap sync control encoding error!\n") );
 
919
                                return EXIT_FAILURE;
 
920
                        }
 
921
 
 
922
                        if ( ber_flatten( syncber, &syncbvalp ) == -1 ) {
 
923
                                return EXIT_FAILURE;
 
924
                        }
 
925
 
 
926
                        c[i].ldctl_oid = LDAP_CONTROL_SYNC;
 
927
                        c[i].ldctl_value = (*syncbvalp);
 
928
                        c[i].ldctl_iscritical = ldapsync < 0;
 
929
                        i++;
 
930
                }
 
931
 
 
932
                if ( valuesReturnFilter ) {
 
933
                        if ( ctrl_add() ) {
 
934
                                return EXIT_FAILURE;
 
935
                        }
 
936
 
 
937
                        if (( vrber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
 
938
                                return EXIT_FAILURE;
 
939
                        }
 
940
 
 
941
                        if ( ( err = ldap_put_vrFilter( vrber, vrFilter ) ) == -1 ) {
 
942
                                ber_free( vrber, 1 );
 
943
                                fprintf( stderr, _("Bad ValuesReturnFilter: %s\n"), vrFilter );
 
944
                                return EXIT_FAILURE;
 
945
                        }
 
946
 
 
947
                        if ( ber_flatten2( vrber, &c[i].ldctl_value, 0 ) == -1 ) {
 
948
                                return EXIT_FAILURE;
 
949
                        }
 
950
 
 
951
                        c[i].ldctl_oid = LDAP_CONTROL_VALUESRETURNFILTER;
 
952
                        c[i].ldctl_iscritical = valuesReturnFilter > 1;
 
953
                        i++;
 
954
                }
 
955
 
 
956
                if ( pagedResults ) {
 
957
                        if ( ctrl_add() ) {
 
958
                                return EXIT_FAILURE;
 
959
                        }
 
960
 
 
961
                        if ( ldap_create_page_control_value( ld,
 
962
                                pageSize, &pr_cookie, &c[i].ldctl_value ) )
 
963
                        {
 
964
                                return EXIT_FAILURE;
 
965
                        }
 
966
 
 
967
                        if ( pr_cookie.bv_val != NULL ) {
 
968
                                ber_memfree( pr_cookie.bv_val );
 
969
                                pr_cookie.bv_val = NULL;
 
970
                                pr_cookie.bv_len = 0;
 
971
                        }
 
972
                        
 
973
                        c[i].ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
 
974
                        c[i].ldctl_iscritical = pagedResults > 1;
 
975
                        i++;
 
976
                }
 
977
 
 
978
                if ( sss ) {
 
979
                        if ( ctrl_add() ) {
 
980
                                return EXIT_FAILURE;
 
981
                        }
 
982
 
 
983
                        if ( ldap_create_sort_control_value( ld,
 
984
                                sss_keys, &c[i].ldctl_value ) )
 
985
                        {
 
986
                                return EXIT_FAILURE;
 
987
                        }
 
988
 
 
989
                        c[i].ldctl_oid = LDAP_CONTROL_SORTREQUEST;
 
990
                        c[i].ldctl_iscritical = sss > 1;
 
991
                        i++;
 
992
                }
 
993
 
 
994
#ifdef LDAP_CONTROL_X_DEREF
 
995
                if ( derefcrit ) {
 
996
                        if ( derefval.bv_val == NULL ) {
 
997
                                int i;
 
998
 
 
999
                                assert( ds != NULL );
 
1000
 
 
1001
                                if ( ldap_create_deref_control_value( ld, ds, &derefval ) != LDAP_SUCCESS ) {
 
1002
                                        return EXIT_FAILURE;
 
1003
                                }
 
1004
 
 
1005
                                for ( i = 0; ds[ i ].derefAttr != NULL; i++ ) {
 
1006
                                        ldap_memfree( ds[ i ].derefAttr );
 
1007
                                        ldap_charray_free( ds[ i ].attributes );
 
1008
                                }
 
1009
                                ldap_memfree( ds );
 
1010
                                ds = NULL;
 
1011
                        }
 
1012
 
 
1013
                        if ( ctrl_add() ) {
 
1014
                                exit( EXIT_FAILURE );
 
1015
                        }
 
1016
 
 
1017
                        c[ i ].ldctl_iscritical = derefcrit > 1;
 
1018
                        c[ i ].ldctl_oid = LDAP_CONTROL_X_DEREF;
 
1019
                        c[ i ].ldctl_value = derefval;
 
1020
                        i++;
 
1021
                }
 
1022
#endif /* LDAP_CONTROL_X_DEREF */
 
1023
        }
 
1024
 
 
1025
        tool_server_controls( ld, c, i );
 
1026
 
 
1027
        if ( seber ) ber_free( seber, 1 );
 
1028
        if ( vrber ) ber_free( vrber, 1 );
 
1029
 
 
1030
        /* step back to the original number of controls, so that
 
1031
         * those set while parsing args are preserved */
 
1032
        nctrls = save_nctrls;
 
1033
 
 
1034
        if ( verbose ) {
 
1035
                fprintf( stderr, _("filter%s: %s\nrequesting: "),
 
1036
                        infile != NULL ? _(" pattern") : "",
 
1037
                        filtpattern );
 
1038
 
 
1039
                if ( attrs == NULL ) {
 
1040
                        fprintf( stderr, _("All userApplication attributes") );
 
1041
                } else {
 
1042
                        for ( i = 0; attrs[ i ] != NULL; ++i ) {
 
1043
                                fprintf( stderr, "%s ", attrs[ i ] );
 
1044
                        }
 
1045
                }
 
1046
                fprintf( stderr, "\n" );
 
1047
        }
 
1048
 
 
1049
        if ( ldif == 0 ) {
 
1050
                printf( _("# extended LDIF\n") );
 
1051
        } else if ( ldif < 3 ) {
 
1052
                printf( _("version: %d\n\n"), 1 );
 
1053
        }
 
1054
 
 
1055
        if (ldif < 2 ) {
 
1056
                char    *realbase = base;
 
1057
 
 
1058
                if ( realbase == NULL ) {
 
1059
                        ldap_get_option( ld, LDAP_OPT_DEFBASE, (void **)(char *)&realbase );
 
1060
                }
 
1061
 
 
1062
                printf( "#\n" );
 
1063
                printf(_("# LDAPv%d\n"), protocol);
 
1064
                printf(_("# base <%s>%s with scope %s\n"),
 
1065
                        realbase ? realbase : "",
 
1066
                        ( realbase == NULL || realbase != base ) ? " (default)" : "",
 
1067
                        ((scope == LDAP_SCOPE_BASE) ? "baseObject"
 
1068
                                : ((scope == LDAP_SCOPE_ONELEVEL) ? "oneLevel"
 
1069
                                : ((scope == LDAP_SCOPE_SUBORDINATE) ? "children"
 
1070
                                : "subtree" ))));
 
1071
                printf(_("# filter%s: %s\n"), infile != NULL ? _(" pattern") : "",
 
1072
                       filtpattern);
 
1073
                printf(_("# requesting: "));
 
1074
 
 
1075
                if ( attrs == NULL ) {
 
1076
                        printf( _("ALL") );
 
1077
                } else {
 
1078
                        for ( i = 0; attrs[ i ] != NULL; ++i ) {
 
1079
                                printf( "%s ", attrs[ i ] );
 
1080
                        }
 
1081
                }
 
1082
 
 
1083
                if ( manageDSAit ) {
 
1084
                        printf(_("\n# with manageDSAit %scontrol"),
 
1085
                                manageDSAit > 1 ? _("critical ") : "" );
 
1086
                }
 
1087
                if ( noop ) {
 
1088
                        printf(_("\n# with noop %scontrol"),
 
1089
                                noop > 1 ? _("critical ") : "" );
 
1090
                }
 
1091
                if ( subentries ) {
 
1092
                        printf(_("\n# with subentries %scontrol: %s"),
 
1093
                                subentries < 0 ? _("critical ") : "",
 
1094
                                abs(subentries) == 1 ? "false" : "true" );
 
1095
                }
 
1096
                if ( valuesReturnFilter ) {
 
1097
                        printf(_("\n# with valuesReturnFilter %scontrol: %s"),
 
1098
                                valuesReturnFilter > 1 ? _("critical ") : "", vrFilter );
 
1099
                }
 
1100
                if ( pagedResults ) {
 
1101
                        printf(_("\n# with pagedResults %scontrol: size=%d"),
 
1102
                                (pagedResults > 1) ? _("critical ") : "", 
 
1103
                                pageSize );
 
1104
                }
 
1105
                if ( sss ) {
 
1106
                        printf(_("\n# with server side sorting %scontrol"),
 
1107
                                sss > 1 ? _("critical ") : "" );
 
1108
                }
 
1109
#ifdef LDAP_CONTROL_X_DEREF
 
1110
                if ( sss ) {
 
1111
                        printf(_("\n# with dereference %scontrol"),
 
1112
                                sss > 1 ? _("critical ") : "" );
 
1113
                }
 
1114
#endif
 
1115
 
 
1116
                printf( _("\n#\n\n") );
 
1117
 
 
1118
                if ( realbase && realbase != base ) {
 
1119
                        ldap_memfree( realbase );
 
1120
                }
 
1121
        }
 
1122
 
 
1123
        if ( infile == NULL ) {
 
1124
                rc = dosearch( ld, base, scope, NULL, filtpattern,
 
1125
                        attrs, attrsonly, NULL, NULL, NULL, -1 );
 
1126
 
 
1127
        } else {
 
1128
                rc = 0;
 
1129
                first = 1;
 
1130
                while ( fgets( line, sizeof( line ), fp ) != NULL ) {
 
1131
                        line[ strlen( line ) - 1 ] = '\0';
 
1132
                        if ( !first ) {
 
1133
                                putchar( '\n' );
 
1134
                        } else {
 
1135
                                first = 0;
 
1136
                        }
 
1137
                        rc1 = dosearch( ld, base, scope, filtpattern, line,
 
1138
                                attrs, attrsonly, NULL, NULL, NULL, -1 );
 
1139
 
 
1140
                        if ( rc1 != 0 ) {
 
1141
                                rc = rc1;
 
1142
                                if ( !contoper )
 
1143
                                        break;
 
1144
                        }
 
1145
                }
 
1146
                if ( fp != stdin ) {
 
1147
                        fclose( fp );
 
1148
                }
 
1149
        }
 
1150
 
 
1151
        if (( rc == LDAP_SUCCESS ) && pageSize && pr_morePagedResults ) {
 
1152
                char    buf[6];
 
1153
                int     i, moreEntries, tmpSize;
 
1154
 
 
1155
                /* Loop to get the next pages when 
 
1156
                 * enter is pressed on the terminal.
 
1157
                 */
 
1158
                if ( pagePrompt != 0 ) {
 
1159
                        if ( entriesLeft > 0 ) {
 
1160
                                printf( _("Estimate entries: %d\n"), entriesLeft );
 
1161
                        }
 
1162
                        printf( _("Press [size] Enter for the next {%d|size} entries.\n"),
 
1163
                                (int)pageSize );
 
1164
                        i = 0;
 
1165
                        moreEntries = getchar();
 
1166
                        while ( moreEntries != EOF && moreEntries != '\n' ) { 
 
1167
                                if ( i < (int)sizeof(buf) - 1 ) {
 
1168
                                        buf[i] = moreEntries;
 
1169
                                        i++;
 
1170
                                }
 
1171
                                moreEntries = getchar();
 
1172
                        }
 
1173
                        buf[i] = '\0';
 
1174
 
 
1175
                        if ( i > 0 && isdigit( (unsigned char)buf[0] ) ) {
 
1176
                                int num = sscanf( buf, "%d", &tmpSize );
 
1177
                                if ( num != 1 ) {
 
1178
                                        fprintf( stderr,
 
1179
                                                _("Invalid value for PagedResultsControl, %s.\n"), buf);
 
1180
                                        return EXIT_FAILURE;
 
1181
        
 
1182
                                }
 
1183
                                pageSize = (ber_int_t)tmpSize;
 
1184
                        }
 
1185
                }
 
1186
 
 
1187
                goto getNextPage;
 
1188
        }
 
1189
 
 
1190
        tool_unbind( ld );
 
1191
        tool_destroy();
 
1192
        if ( base != NULL ) {
 
1193
                ber_memfree( base );
 
1194
        }
 
1195
        if ( control != NULL ) {
 
1196
                ber_memfree( control );
 
1197
        }
 
1198
        if ( sss_keys != NULL ) {
 
1199
                ldap_free_sort_keylist( sss_keys );
 
1200
        }
 
1201
        if ( derefval.bv_val != NULL ) {
 
1202
                ldap_memfree( derefval.bv_val );
 
1203
        }
 
1204
 
 
1205
        if ( c ) {
 
1206
                for ( ; save_nctrls-- > 0; ) {
 
1207
                        ber_memfree( c[ save_nctrls ].ldctl_value.bv_val );
 
1208
                }
 
1209
                free( c );
 
1210
                c = NULL;
 
1211
        }
 
1212
 
 
1213
        return( rc );
 
1214
}
 
1215
 
 
1216
 
 
1217
static int dosearch(
 
1218
        LDAP    *ld,
 
1219
        char    *base,
 
1220
        int             scope,
 
1221
        char    *filtpatt,
 
1222
        char    *value,
 
1223
        char    **attrs,
 
1224
        int             attrsonly,
 
1225
        LDAPControl **sctrls,
 
1226
        LDAPControl **cctrls,
 
1227
        struct timeval *timeout,
 
1228
        int sizelimit )
 
1229
{
 
1230
        char                    *filter;
 
1231
        int                     rc;
 
1232
        int                     nresponses;
 
1233
        int                     nentries;
 
1234
        int                     nreferences;
 
1235
        int                     nextended;
 
1236
        int                     npartial;
 
1237
        LDAPMessage             *res, *msg;
 
1238
        ber_int_t               msgid;
 
1239
        char                    *retoid = NULL;
 
1240
        struct berval           *retdata = NULL;
 
1241
        int                     nresponses_psearch = -1;
 
1242
        int                     cancel_msgid = -1;
 
1243
 
 
1244
        if( filtpatt != NULL ) {
 
1245
                size_t max_fsize = strlen( filtpatt ) + strlen( value ) + 1, outlen;
 
1246
                filter = malloc( max_fsize );
 
1247
                if( filter == NULL ) {
 
1248
                        perror( "malloc" );
 
1249
                        return EXIT_FAILURE;
 
1250
                }
 
1251
 
 
1252
                outlen = snprintf( filter, max_fsize, filtpatt, value );
 
1253
                if( outlen >= max_fsize ) {
 
1254
                        fprintf( stderr, "Bad filter pattern: \"%s\"\n", filtpatt );
 
1255
                        free( filter );
 
1256
                        return EXIT_FAILURE;
 
1257
                }
 
1258
 
 
1259
                if ( verbose ) {
 
1260
                        fprintf( stderr, _("filter: %s\n"), filter );
 
1261
                }
 
1262
 
 
1263
                if( ldif < 2 ) {
 
1264
                        printf( _("#\n# filter: %s\n#\n"), filter );
 
1265
                }
 
1266
 
 
1267
        } else {
 
1268
                filter = value;
 
1269
        }
 
1270
 
 
1271
        if ( dont ) {
 
1272
                if ( filtpatt != NULL ) {
 
1273
                        free( filter );
 
1274
                }
 
1275
                return LDAP_SUCCESS;
 
1276
        }
 
1277
 
 
1278
        rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
 
1279
                sctrls, cctrls, timeout, sizelimit, &msgid );
 
1280
 
 
1281
        if ( filtpatt != NULL ) {
 
1282
                free( filter );
 
1283
        }
 
1284
 
 
1285
        if( rc != LDAP_SUCCESS ) {
 
1286
                fprintf( stderr, _("%s: ldap_search_ext: %s (%d)\n"),
 
1287
                        prog, ldap_err2string( rc ), rc );
 
1288
                return( rc );
 
1289
        }
 
1290
 
 
1291
        nresponses = nentries = nreferences = nextended = npartial = 0;
 
1292
 
 
1293
        res = NULL;
 
1294
 
 
1295
        while ((rc = ldap_result( ld, LDAP_RES_ANY,
 
1296
                sortattr ? LDAP_MSG_ALL : LDAP_MSG_ONE,
 
1297
                NULL, &res )) > 0 )
 
1298
        {
 
1299
                rc = tool_check_abandon( ld, msgid );
 
1300
                if ( rc ) {
 
1301
                        return rc;
 
1302
                }
 
1303
 
 
1304
                if( sortattr ) {
 
1305
                        (void) ldap_sort_entries( ld, &res,
 
1306
                                ( *sortattr == '\0' ) ? NULL : sortattr, strcasecmp );
 
1307
                }
 
1308
 
 
1309
                for ( msg = ldap_first_message( ld, res );
 
1310
                        msg != NULL;
 
1311
                        msg = ldap_next_message( ld, msg ) )
 
1312
                {
 
1313
                        if ( nresponses++ ) putchar('\n');
 
1314
                        if ( nresponses_psearch >= 0 ) 
 
1315
                                nresponses_psearch++;
 
1316
 
 
1317
                        switch( ldap_msgtype( msg ) ) {
 
1318
                        case LDAP_RES_SEARCH_ENTRY:
 
1319
                                nentries++;
 
1320
                                print_entry( ld, msg, attrsonly );
 
1321
                                break;
 
1322
 
 
1323
                        case LDAP_RES_SEARCH_REFERENCE:
 
1324
                                nreferences++;
 
1325
                                print_reference( ld, msg );
 
1326
                                break;
 
1327
 
 
1328
                        case LDAP_RES_EXTENDED:
 
1329
                                nextended++;
 
1330
                                print_extended( ld, msg );
 
1331
 
 
1332
                                if ( ldap_msgid( msg ) == 0 ) {
 
1333
                                        /* unsolicited extended operation */
 
1334
                                        goto done;
 
1335
                                }
 
1336
 
 
1337
                                if ( cancel_msgid != -1 &&
 
1338
                                                cancel_msgid == ldap_msgid( msg ) ) {
 
1339
                                        printf(_("Cancelled \n"));
 
1340
                                        printf(_("cancel_msgid = %d\n"), cancel_msgid);
 
1341
                                        goto done;
 
1342
                                }
 
1343
                                break;
 
1344
 
 
1345
                        case LDAP_RES_SEARCH_RESULT:
 
1346
                                /* pagedResults stuff is dealt with
 
1347
                                 * in tool_print_ctrls(), called by
 
1348
                                 * print_results(). */
 
1349
                                rc = print_result( ld, msg, 1 );
 
1350
                                if ( ldapsync == LDAP_SYNC_REFRESH_AND_PERSIST ) {
 
1351
                                        break;
 
1352
                                }
 
1353
 
 
1354
                                goto done;
 
1355
 
 
1356
                        case LDAP_RES_INTERMEDIATE:
 
1357
                                npartial++;
 
1358
                                ldap_parse_intermediate( ld, msg,
 
1359
                                        &retoid, &retdata, NULL, 0 );
 
1360
 
 
1361
                                nresponses_psearch = 0;
 
1362
 
 
1363
                                if ( strcmp( retoid, LDAP_SYNC_INFO ) == 0 ) {
 
1364
                                        printf(_("SyncInfo Received\n"));
 
1365
                                        ldap_memfree( retoid );
 
1366
                                        ber_bvfree( retdata );
 
1367
                                        break;
 
1368
                                }
 
1369
 
 
1370
                                print_partial( ld, msg );
 
1371
                                ldap_memfree( retoid );
 
1372
                                ber_bvfree( retdata );
 
1373
                                goto done;
 
1374
                        }
 
1375
 
 
1376
                        if ( ldapsync && sync_slimit != -1 &&
 
1377
                                        nresponses_psearch >= sync_slimit ) {
 
1378
                                BerElement *msgidber = NULL;
 
1379
                                struct berval *msgidvalp = NULL;
 
1380
                                msgidber = ber_alloc_t(LBER_USE_DER);
 
1381
                                ber_printf(msgidber, "{i}", msgid);
 
1382
                                ber_flatten(msgidber, &msgidvalp);
 
1383
                                ldap_extended_operation(ld, LDAP_EXOP_CANCEL,
 
1384
                                        msgidvalp, NULL, NULL, &cancel_msgid);
 
1385
                                nresponses_psearch = -1;
 
1386
                        }
 
1387
                }
 
1388
 
 
1389
                ldap_msgfree( res );
 
1390
        }
 
1391
 
 
1392
done:
 
1393
        if ( rc == -1 ) {
 
1394
                tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
 
1395
                return( rc );
 
1396
        }
 
1397
 
 
1398
        ldap_msgfree( res );
 
1399
 
 
1400
        if ( pagedResults ) { 
 
1401
                npagedresponses += nresponses;
 
1402
                npagedentries += nentries;
 
1403
                npagedextended += nextended;
 
1404
                npagedpartial += npartial;
 
1405
                npagedreferences += nreferences;
 
1406
                if ( ( pr_morePagedResults == 0 ) && ( ldif < 2 ) ) {
 
1407
                        printf( _("\n# numResponses: %d\n"), npagedresponses );
 
1408
                        if( npagedentries ) {
 
1409
                                printf( _("# numEntries: %d\n"), npagedentries );
 
1410
                        }
 
1411
                        if( npagedextended ) {
 
1412
                                printf( _("# numExtended: %d\n"), npagedextended );
 
1413
                        }
 
1414
                        if( npagedpartial ) {
 
1415
                                printf( _("# numPartial: %d\n"), npagedpartial );
 
1416
                        }
 
1417
                        if( npagedreferences ) {
 
1418
                                printf( _("# numReferences: %d\n"), npagedreferences );
 
1419
                        }
 
1420
                }
 
1421
        } else if ( ldif < 2 ) {
 
1422
                printf( _("\n# numResponses: %d\n"), nresponses );
 
1423
                if( nentries ) printf( _("# numEntries: %d\n"), nentries );
 
1424
                if( nextended ) printf( _("# numExtended: %d\n"), nextended );
 
1425
                if( npartial ) printf( _("# numPartial: %d\n"), npartial );
 
1426
                if( nreferences ) printf( _("# numReferences: %d\n"), nreferences );
 
1427
        }
 
1428
 
 
1429
        return( rc );
 
1430
}
 
1431
 
 
1432
/* This is the proposed new way of doing things.
 
1433
 * It is more efficient, but the API is non-standard.
 
1434
 */
 
1435
static void
 
1436
print_entry(
 
1437
        LDAP    *ld,
 
1438
        LDAPMessage     *entry,
 
1439
        int             attrsonly)
 
1440
{
 
1441
        char            *ufn = NULL;
 
1442
        char    tmpfname[ 256 ];
 
1443
        char    url[ 256 ];
 
1444
        int                     i, rc;
 
1445
        BerElement              *ber = NULL;
 
1446
        struct berval           bv, *bvals, **bvp = &bvals;
 
1447
        LDAPControl **ctrls = NULL;
 
1448
        FILE            *tmpfp;
 
1449
 
 
1450
        rc = ldap_get_dn_ber( ld, entry, &ber, &bv );
 
1451
 
 
1452
        if ( ldif < 2 ) {
 
1453
                ufn = ldap_dn2ufn( bv.bv_val );
 
1454
                tool_write_ldif( LDIF_PUT_COMMENT, NULL, ufn, ufn ? strlen( ufn ) : 0 );
 
1455
        }
 
1456
        tool_write_ldif( LDIF_PUT_VALUE, "dn", bv.bv_val, bv.bv_len );
 
1457
 
 
1458
        rc = ldap_get_entry_controls( ld, entry, &ctrls );
 
1459
        if( rc != LDAP_SUCCESS ) {
 
1460
                fprintf(stderr, _("print_entry: %d\n"), rc );
 
1461
                tool_perror( "ldap_get_entry_controls", rc, NULL, NULL, NULL, NULL );
 
1462
                exit( EXIT_FAILURE );
 
1463
        }
 
1464
 
 
1465
        if( ctrls ) {
 
1466
                tool_print_ctrls( ld, ctrls );
 
1467
                ldap_controls_free( ctrls );
 
1468
        }
 
1469
 
 
1470
        if ( includeufn ) {
 
1471
                if( ufn == NULL ) {
 
1472
                        ufn = ldap_dn2ufn( bv.bv_val );
 
1473
                }
 
1474
                tool_write_ldif( LDIF_PUT_VALUE, "ufn", ufn, ufn ? strlen( ufn ) : 0 );
 
1475
        }
 
1476
 
 
1477
        if( ufn != NULL ) ldap_memfree( ufn );
 
1478
 
 
1479
        if ( attrsonly ) bvp = NULL;
 
1480
 
 
1481
        for ( rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp );
 
1482
                rc == LDAP_SUCCESS;
 
1483
                rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp ) )
 
1484
        {
 
1485
                if (bv.bv_val == NULL) break;
 
1486
 
 
1487
                if ( attrsonly ) {
 
1488
                        tool_write_ldif( LDIF_PUT_NOVALUE, bv.bv_val, NULL, 0 );
 
1489
 
 
1490
                } else if ( bvals ) {
 
1491
                        for ( i = 0; bvals[i].bv_val != NULL; i++ ) {
 
1492
                                if ( vals2tmp > 1 || ( vals2tmp &&
 
1493
                                        ldif_is_not_printable( bvals[i].bv_val, bvals[i].bv_len )))
 
1494
                                {
 
1495
                                        int tmpfd;
 
1496
                                        /* write value to file */
 
1497
                                        snprintf( tmpfname, sizeof tmpfname,
 
1498
                                                "%s" LDAP_DIRSEP "ldapsearch-%s-XXXXXX",
 
1499
                                                tmpdir, bv.bv_val );
 
1500
                                        tmpfp = NULL;
 
1501
 
 
1502
                                        tmpfd = mkstemp( tmpfname );
 
1503
 
 
1504
                                        if ( tmpfd < 0  ) {
 
1505
                                                perror( tmpfname );
 
1506
                                                continue;
 
1507
                                        }
 
1508
 
 
1509
                                        if (( tmpfp = fdopen( tmpfd, "w")) == NULL ) {
 
1510
                                                perror( tmpfname );
 
1511
                                                continue;
 
1512
                                        }
 
1513
 
 
1514
                                        if ( fwrite( bvals[ i ].bv_val,
 
1515
                                                bvals[ i ].bv_len, 1, tmpfp ) == 0 )
 
1516
                                        {
 
1517
                                                perror( tmpfname );
 
1518
                                                fclose( tmpfp );
 
1519
                                                continue;
 
1520
                                        }
 
1521
 
 
1522
                                        fclose( tmpfp );
 
1523
 
 
1524
                                        snprintf( url, sizeof url, "%s%s", urlpre,
 
1525
                                                &tmpfname[strlen(tmpdir) + sizeof(LDAP_DIRSEP) - 1] );
 
1526
 
 
1527
                                        urlize( url );
 
1528
                                        tool_write_ldif( LDIF_PUT_URL, bv.bv_val, url, strlen( url ));
 
1529
 
 
1530
                                } else {
 
1531
                                        tool_write_ldif( LDIF_PUT_VALUE, bv.bv_val,
 
1532
                                                bvals[ i ].bv_val, bvals[ i ].bv_len );
 
1533
                                }
 
1534
                        }
 
1535
                        ber_memfree( bvals );
 
1536
                }
 
1537
        }
 
1538
 
 
1539
        if( ber != NULL ) {
 
1540
                ber_free( ber, 0 );
 
1541
        }
 
1542
}
 
1543
 
 
1544
static void print_reference(
 
1545
        LDAP *ld,
 
1546
        LDAPMessage *reference )
 
1547
{
 
1548
        int rc;
 
1549
        char **refs = NULL;
 
1550
        LDAPControl **ctrls;
 
1551
 
 
1552
        if( ldif < 2 ) {
 
1553
                printf(_("# search reference\n"));
 
1554
        }
 
1555
 
 
1556
        rc = ldap_parse_reference( ld, reference, &refs, &ctrls, 0 );
 
1557
 
 
1558
        if( rc != LDAP_SUCCESS ) {
 
1559
                tool_perror( "ldap_parse_reference", rc, NULL, NULL, NULL, NULL );
 
1560
                exit( EXIT_FAILURE );
 
1561
        }
 
1562
 
 
1563
        if( refs ) {
 
1564
                int i;
 
1565
                for( i=0; refs[i] != NULL; i++ ) {
 
1566
                        tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
 
1567
                                "ref", refs[i], strlen(refs[i]) );
 
1568
                }
 
1569
                ber_memvfree( (void **) refs );
 
1570
        }
 
1571
 
 
1572
        if( ctrls ) {
 
1573
                tool_print_ctrls( ld, ctrls );
 
1574
                ldap_controls_free( ctrls );
 
1575
        }
 
1576
}
 
1577
 
 
1578
static void print_extended(
 
1579
        LDAP *ld,
 
1580
        LDAPMessage *extended )
 
1581
{
 
1582
        int rc;
 
1583
        char *retoid = NULL;
 
1584
        struct berval *retdata = NULL;
 
1585
 
 
1586
        if( ldif < 2 ) {
 
1587
                printf(_("# extended result response\n"));
 
1588
        }
 
1589
 
 
1590
        rc = ldap_parse_extended_result( ld, extended,
 
1591
                &retoid, &retdata, 0 );
 
1592
 
 
1593
        if( rc != LDAP_SUCCESS ) {
 
1594
                tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL );
 
1595
                exit( EXIT_FAILURE );
 
1596
        }
 
1597
 
 
1598
        if ( ldif < 2 ) {
 
1599
                tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
 
1600
                        "extended", retoid, retoid ? strlen(retoid) : 0 );
 
1601
        }
 
1602
        ber_memfree( retoid );
 
1603
 
 
1604
        if(retdata) {
 
1605
                if ( ldif < 2 ) {
 
1606
                        tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
 
1607
                                "data", retdata->bv_val, retdata->bv_len );
 
1608
                }
 
1609
                ber_bvfree( retdata );
 
1610
        }
 
1611
 
 
1612
        print_result( ld, extended, 0 );
 
1613
}
 
1614
 
 
1615
static void print_partial(
 
1616
        LDAP *ld,
 
1617
        LDAPMessage *partial )
 
1618
{
 
1619
        int rc;
 
1620
        char *retoid = NULL;
 
1621
        struct berval *retdata = NULL;
 
1622
        LDAPControl **ctrls = NULL;
 
1623
 
 
1624
        if( ldif < 2 ) {
 
1625
                printf(_("# extended partial response\n"));
 
1626
        }
 
1627
 
 
1628
        rc = ldap_parse_intermediate( ld, partial,
 
1629
                &retoid, &retdata, &ctrls, 0 );
 
1630
 
 
1631
        if( rc != LDAP_SUCCESS ) {
 
1632
                tool_perror( "ldap_parse_intermediate", rc, NULL, NULL, NULL, NULL );
 
1633
                exit( EXIT_FAILURE );
 
1634
        }
 
1635
 
 
1636
        if ( ldif < 2 ) {
 
1637
                tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
 
1638
                        "partial", retoid, retoid ? strlen(retoid) : 0 );
 
1639
        }
 
1640
 
 
1641
        ber_memfree( retoid );
 
1642
 
 
1643
        if( retdata ) {
 
1644
                if ( ldif < 2 ) {
 
1645
                        tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
 
1646
                                "data", retdata->bv_val, retdata->bv_len );
 
1647
                }
 
1648
 
 
1649
                ber_bvfree( retdata );
 
1650
        }
 
1651
 
 
1652
        if( ctrls ) {
 
1653
                tool_print_ctrls( ld, ctrls );
 
1654
                ldap_controls_free( ctrls );
 
1655
        }
 
1656
}
 
1657
 
 
1658
static int print_result(
 
1659
        LDAP *ld,
 
1660
        LDAPMessage *result, int search )
 
1661
{
 
1662
        int rc;
 
1663
        int err;
 
1664
        char *matcheddn = NULL;
 
1665
        char *text = NULL;
 
1666
        char **refs = NULL;
 
1667
        LDAPControl **ctrls = NULL;
 
1668
 
 
1669
        if( search ) {
 
1670
                if ( ldif < 2 ) {
 
1671
                        printf(_("# search result\n"));
 
1672
                }
 
1673
                if ( ldif < 1 ) {
 
1674
                        printf("%s: %d\n", _("search"), ldap_msgid(result) );
 
1675
                }
 
1676
        }
 
1677
 
 
1678
        rc = ldap_parse_result( ld, result,
 
1679
                &err, &matcheddn, &text, &refs, &ctrls, 0 );
 
1680
 
 
1681
        if( rc != LDAP_SUCCESS ) {
 
1682
                tool_perror( "ldap_parse_result", rc, NULL, NULL, NULL, NULL );
 
1683
                exit( EXIT_FAILURE );
 
1684
        }
 
1685
 
 
1686
 
 
1687
        if( !ldif ) {
 
1688
                printf( _("result: %d %s\n"), err, ldap_err2string(err) );
 
1689
 
 
1690
        } else if ( err != LDAP_SUCCESS ) {
 
1691
                fprintf( stderr, "%s (%d)\n", ldap_err2string(err), err );
 
1692
        }
 
1693
 
 
1694
        if( matcheddn ) {
 
1695
                if( *matcheddn ) {
 
1696
                if( !ldif ) {
 
1697
                        tool_write_ldif( LDIF_PUT_VALUE,
 
1698
                                "matchedDN", matcheddn, strlen(matcheddn) );
 
1699
                } else {
 
1700
                        fprintf( stderr, _("Matched DN: %s\n"), matcheddn );
 
1701
                }
 
1702
                }
 
1703
 
 
1704
                ber_memfree( matcheddn );
 
1705
        }
 
1706
 
 
1707
        if( text ) {
 
1708
                if( *text ) {
 
1709
                        if( !ldif ) {
 
1710
                                if ( err == LDAP_PARTIAL_RESULTS ) {
 
1711
                                        char    *line;
 
1712
 
 
1713
                                        for ( line = text; line != NULL; ) {
 
1714
                                                char    *next = strchr( line, '\n' );
 
1715
 
 
1716
                                                tool_write_ldif( LDIF_PUT_TEXT,
 
1717
                                                        "text", line,
 
1718
                                                        next ? (size_t) (next - line) : strlen( line ));
 
1719
 
 
1720
                                                line = next ? next + 1 : NULL;
 
1721
                                        }
 
1722
 
 
1723
                                } else {
 
1724
                                        tool_write_ldif( LDIF_PUT_TEXT, "text",
 
1725
                                                text, strlen(text) );
 
1726
                                }
 
1727
                        } else {
 
1728
                                fprintf( stderr, _("Additional information: %s\n"), text );
 
1729
                        }
 
1730
                }
 
1731
 
 
1732
                ber_memfree( text );
 
1733
        }
 
1734
 
 
1735
        if( refs ) {
 
1736
                int i;
 
1737
                for( i=0; refs[i] != NULL; i++ ) {
 
1738
                        if( !ldif ) {
 
1739
                                tool_write_ldif( LDIF_PUT_VALUE, "ref", refs[i], strlen(refs[i]) );
 
1740
                        } else {
 
1741
                                fprintf( stderr, _("Referral: %s\n"), refs[i] );
 
1742
                        }
 
1743
                }
 
1744
 
 
1745
                ber_memvfree( (void **) refs );
 
1746
        }
 
1747
 
 
1748
        pr_morePagedResults = 0;
 
1749
 
 
1750
        if( ctrls ) {
 
1751
                tool_print_ctrls( ld, ctrls );
 
1752
                ldap_controls_free( ctrls );
 
1753
        }
 
1754
 
 
1755
        return err;
 
1756
}
 
1757