1 1.3 christos /* $NetBSD: ldapsearch.c,v 1.4 2025/09/05 21:16:13 christos Exp $ */ 2 1.2 christos 3 1.1 lukem /* ldapsearch -- a tool for searching LDAP directories */ 4 1.2 christos /* $OpenLDAP$ */ 5 1.1 lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 1.1 lukem * 7 1.4 christos * Copyright 1998-2024 The OpenLDAP Foundation. 8 1.1 lukem * Portions Copyright 1998-2003 Kurt D. Zeilenga. 9 1.1 lukem * Portions Copyright 1998-2001 Net Boolean Incorporated. 10 1.1 lukem * Portions Copyright 2001-2003 IBM Corporation. 11 1.1 lukem * All rights reserved. 12 1.1 lukem * 13 1.1 lukem * Redistribution and use in source and binary forms, with or without 14 1.1 lukem * modification, are permitted only as authorized by the OpenLDAP 15 1.1 lukem * Public License. 16 1.1 lukem * 17 1.1 lukem * A copy of this license is available in the file LICENSE in the 18 1.1 lukem * top-level directory of the distribution or, alternatively, at 19 1.1 lukem * <http://www.OpenLDAP.org/license.html>. 20 1.1 lukem */ 21 1.1 lukem /* Portions Copyright (c) 1992-1996 Regents of the University of Michigan. 22 1.1 lukem * All rights reserved. 23 1.1 lukem * 24 1.1 lukem * Redistribution and use in source and binary forms are permitted 25 1.1 lukem * provided that this notice is preserved and that due credit is given 26 1.1 lukem * to the University of Michigan at Ann Arbor. The name of the 27 1.1 lukem * University may not be used to endorse or promote products derived 28 1.1 lukem * from this software without specific prior written permission. This 29 1.1 lukem * software is provided ``as is'' without express or implied warranty. 30 1.1 lukem */ 31 1.1 lukem /* ACKNOWLEDGEMENTS: 32 1.1 lukem * This work was originally developed by the University of Michigan 33 1.1 lukem * (as part of U-MICH LDAP). Additional significant contributors 34 1.1 lukem * include: 35 1.1 lukem * Jong Hyuk Choi 36 1.1 lukem * Lynn Moss 37 1.1 lukem * Mikhail Sahalaev 38 1.1 lukem * Kurt D. Zeilenga 39 1.1 lukem */ 40 1.1 lukem 41 1.2 christos #include <sys/cdefs.h> 42 1.3 christos __RCSID("$NetBSD: ldapsearch.c,v 1.4 2025/09/05 21:16:13 christos Exp $"); 43 1.2 christos 44 1.1 lukem #include "portable.h" 45 1.1 lukem 46 1.1 lukem #include <stdio.h> 47 1.1 lukem 48 1.1 lukem #include <ac/stdlib.h> 49 1.1 lukem #include <ac/ctype.h> 50 1.1 lukem #include <ac/string.h> 51 1.1 lukem #include <ac/unistd.h> 52 1.1 lukem #include <ac/errno.h> 53 1.2 christos #include <ac/time.h> 54 1.2 christos 55 1.1 lukem #include <sys/stat.h> 56 1.1 lukem 57 1.1 lukem #include <ac/signal.h> 58 1.1 lukem 59 1.1 lukem #ifdef HAVE_FCNTL_H 60 1.1 lukem #include <fcntl.h> 61 1.1 lukem #endif 62 1.1 lukem #ifdef HAVE_SYS_TYPES_H 63 1.1 lukem #include <sys/types.h> 64 1.1 lukem #endif 65 1.1 lukem #ifdef HAVE_IO_H 66 1.1 lukem #include <io.h> 67 1.1 lukem #endif 68 1.1 lukem 69 1.1 lukem #include <ldap.h> 70 1.1 lukem 71 1.1 lukem #include "ldif.h" 72 1.1 lukem #include "lutil.h" 73 1.1 lukem #include "lutil_ldap.h" 74 1.1 lukem #include "ldap_defaults.h" 75 1.1 lukem #include "ldap_pvt.h" 76 1.1 lukem 77 1.1 lukem #include "common.h" 78 1.1 lukem 79 1.1 lukem #if !LDAP_DEPRECATED 80 1.1 lukem /* 81 1.1 lukem * NOTE: we use this deprecated function only because 82 1.1 lukem * we want ldapsearch to provide some client-side sorting 83 1.1 lukem * capability. 84 1.1 lukem */ 85 1.1 lukem /* from ldap.h */ 86 1.1 lukem typedef int (LDAP_SORT_AD_CMP_PROC) LDAP_P(( /* deprecated */ 87 1.1 lukem LDAP_CONST char *left, 88 1.1 lukem LDAP_CONST char *right )); 89 1.1 lukem 90 1.1 lukem LDAP_F( int ) /* deprecated */ 91 1.1 lukem ldap_sort_entries LDAP_P(( LDAP *ld, 92 1.1 lukem LDAPMessage **chain, 93 1.1 lukem LDAP_CONST char *attr, 94 1.1 lukem LDAP_SORT_AD_CMP_PROC *cmp )); 95 1.1 lukem #endif 96 1.1 lukem 97 1.1 lukem static int scope = LDAP_SCOPE_SUBTREE; 98 1.1 lukem static int deref = -1; 99 1.1 lukem static int attrsonly; 100 1.1 lukem static int timelimit = -1; 101 1.1 lukem static int sizelimit = -1; 102 1.1 lukem 103 1.1 lukem static char *control; 104 1.1 lukem 105 1.1 lukem static char *def_tmpdir; 106 1.1 lukem static char *def_urlpre; 107 1.1 lukem 108 1.1 lukem #if defined(__CYGWIN__) || defined(__MINGW32__) 109 1.1 lukem /* Turn off commandline globbing, otherwise you cannot search for 110 1.1 lukem * attribute '*' 111 1.1 lukem */ 112 1.1 lukem int _CRT_glob = 0; 113 1.1 lukem #endif 114 1.1 lukem 115 1.1 lukem void 116 1.1 lukem usage( void ) 117 1.1 lukem { 118 1.1 lukem fprintf( stderr, _("usage: %s [options] [filter [attributes...]]\nwhere:\n"), prog); 119 1.1 lukem fprintf( stderr, _(" filter\tRFC 4515 compliant LDAP search filter\n")); 120 1.1 lukem fprintf( stderr, _(" attributes\twhitespace-separated list of attribute descriptions\n")); 121 1.1 lukem fprintf( stderr, _(" which may include:\n")); 122 1.1 lukem fprintf( stderr, _(" 1.1 no attributes\n")); 123 1.1 lukem fprintf( stderr, _(" * all user attributes\n")); 124 1.1 lukem fprintf( stderr, _(" + all operational attributes\n")); 125 1.1 lukem 126 1.1 lukem 127 1.1 lukem fprintf( stderr, _("Search options:\n")); 128 1.1 lukem fprintf( stderr, _(" -a deref one of never (default), always, search, or find\n")); 129 1.1 lukem fprintf( stderr, _(" -A retrieve attribute names only (no values)\n")); 130 1.1 lukem fprintf( stderr, _(" -b basedn base dn for search\n")); 131 1.2 christos fprintf( stderr, _(" -c continuous operation mode (do not stop on errors)\n")); 132 1.1 lukem fprintf( stderr, _(" -E [!]<ext>[=<extparam>] search extensions (! indicates criticality)\n")); 133 1.3 christos #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY 134 1.3 christos fprintf( stderr, _(" [!]accountUsability (NetScape Account usability)\n")); 135 1.3 christos #endif 136 1.1 lukem fprintf( stderr, _(" [!]domainScope (domain scope)\n")); 137 1.1 lukem fprintf( stderr, _(" !dontUseCopy (Don't Use Copy)\n")); 138 1.2 christos fprintf( stderr, _(" [!]mv=<filter> (RFC 3876 matched values filter)\n")); 139 1.2 christos fprintf( stderr, _(" [!]pr=<size>[/prompt|noprompt] (RFC 2696 paged results/prompt)\n")); 140 1.3 christos fprintf( stderr, _(" [!]ps=<changetypes>/<changesonly>/<echg> (draft persistent search)\n")); 141 1.2 christos fprintf( stderr, _(" [!]sss=[-]<attr[:OID]>[/[-]<attr[:OID]>...]\n")); 142 1.2 christos fprintf( stderr, _(" (RFC 2891 server side sorting)\n")); 143 1.2 christos fprintf( stderr, _(" [!]subentries[=true|false] (RFC 3672 subentries)\n")); 144 1.2 christos fprintf( stderr, _(" [!]sync=ro[/<cookie>] (RFC 4533 LDAP Sync refreshOnly)\n")); 145 1.2 christos fprintf( stderr, _(" rp[/<cookie>][/<slimit>] (refreshAndPersist)\n")); 146 1.2 christos fprintf( stderr, _(" [!]vlv=<before>/<after>(/<offset>/<count>|:<value>)\n")); 147 1.2 christos fprintf( stderr, _(" (ldapv3-vlv-09 virtual list views)\n")); 148 1.2 christos #ifdef LDAP_CONTROL_X_DEREF 149 1.2 christos fprintf( stderr, _(" [!]deref=derefAttr:attr[,...][;derefAttr:attr[,...][;...]]\n")); 150 1.2 christos #endif 151 1.3 christos #ifdef LDAP_CONTROL_X_DIRSYNC 152 1.3 christos fprintf( stderr, _(" !dirSync=<flags>/<maxAttrCount>[/<cookie>]\n")); 153 1.3 christos fprintf( stderr, _(" (MS AD DirSync)\n")); 154 1.3 christos #endif 155 1.3 christos #ifdef LDAP_CONTROL_X_EXTENDED_DN 156 1.3 christos fprintf( stderr, _(" [!]extendedDn=<flag> (MS AD Extended DN\n")); 157 1.3 christos #endif 158 1.3 christos #ifdef LDAP_CONTROL_X_SHOW_DELETED 159 1.3 christos fprintf( stderr, _(" [!]showDeleted (MS AD Show Deleted)\n")); 160 1.3 christos #endif 161 1.3 christos #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION 162 1.3 christos fprintf( stderr, _(" [!]serverNotif (MS AD Server Notification)\n")); 163 1.3 christos #endif 164 1.3 christos fprintf( stderr, _(" [!]<oid>[=:<value>|::<b64value>] (generic control; no response handling)\n")); 165 1.2 christos fprintf( stderr, _(" -f file read operations from `file'\n")); 166 1.1 lukem fprintf( stderr, _(" -F prefix URL prefix for files (default: %s)\n"), def_urlpre); 167 1.1 lukem fprintf( stderr, _(" -l limit time limit (in seconds, or \"none\" or \"max\") for search\n")); 168 1.1 lukem fprintf( stderr, _(" -L print responses in LDIFv1 format\n")); 169 1.1 lukem fprintf( stderr, _(" -LL print responses in LDIF format without comments\n")); 170 1.1 lukem fprintf( stderr, _(" -LLL print responses in LDIF format without comments\n")); 171 1.1 lukem fprintf( stderr, _(" and version\n")); 172 1.2 christos fprintf( stderr, _(" -M enable Manage DSA IT control (-MM to make critical)\n")); 173 1.2 christos fprintf( stderr, _(" -P version protocol version (default: 3)\n")); 174 1.1 lukem fprintf( stderr, _(" -s scope one of base, one, sub or children (search scope)\n")); 175 1.1 lukem fprintf( stderr, _(" -S attr sort the results by attribute `attr'\n")); 176 1.1 lukem fprintf( stderr, _(" -t write binary values to files in temporary directory\n")); 177 1.1 lukem fprintf( stderr, _(" -tt write all values to files in temporary directory\n")); 178 1.1 lukem fprintf( stderr, _(" -T path write files to directory specified by path (default: %s)\n"), def_tmpdir); 179 1.1 lukem fprintf( stderr, _(" -u include User Friendly entry names in the output\n")); 180 1.1 lukem fprintf( stderr, _(" -z limit size limit (in entries, or \"none\" or \"max\") for search\n")); 181 1.1 lukem tool_common_usage(); 182 1.1 lukem exit( EXIT_FAILURE ); 183 1.1 lukem } 184 1.1 lukem 185 1.1 lukem static void print_entry LDAP_P(( 186 1.1 lukem LDAP *ld, 187 1.1 lukem LDAPMessage *entry, 188 1.1 lukem int attrsonly)); 189 1.1 lukem 190 1.1 lukem static void print_reference( 191 1.1 lukem LDAP *ld, 192 1.1 lukem LDAPMessage *reference ); 193 1.1 lukem 194 1.1 lukem static void print_extended( 195 1.1 lukem LDAP *ld, 196 1.1 lukem LDAPMessage *extended ); 197 1.1 lukem 198 1.3 christos static void print_syncinfo( 199 1.3 christos BerValue *info ); 200 1.3 christos 201 1.1 lukem static void print_partial( 202 1.1 lukem LDAP *ld, 203 1.1 lukem LDAPMessage *partial ); 204 1.1 lukem 205 1.1 lukem static int print_result( 206 1.1 lukem LDAP *ld, 207 1.1 lukem LDAPMessage *result, 208 1.1 lukem int search ); 209 1.1 lukem 210 1.1 lukem static int dosearch LDAP_P(( 211 1.1 lukem LDAP *ld, 212 1.1 lukem char *base, 213 1.1 lukem int scope, 214 1.1 lukem char *filtpatt, 215 1.1 lukem char *value, 216 1.1 lukem char **attrs, 217 1.1 lukem int attrsonly, 218 1.1 lukem LDAPControl **sctrls, 219 1.1 lukem LDAPControl **cctrls, 220 1.1 lukem struct timeval *timeout, 221 1.1 lukem int sizelimit )); 222 1.1 lukem 223 1.1 lukem static char *tmpdir = NULL; 224 1.1 lukem static char *urlpre = NULL; 225 1.1 lukem static char *base = NULL; 226 1.1 lukem static char *sortattr = NULL; 227 1.1 lukem static int includeufn, vals2tmp = 0; 228 1.1 lukem 229 1.1 lukem static int subentries = 0, valuesReturnFilter = 0; 230 1.1 lukem static char *vrFilter = NULL; 231 1.1 lukem 232 1.3 christos #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY 233 1.3 christos static int accountUsability = 0; 234 1.3 christos #endif 235 1.3 christos 236 1.1 lukem #ifdef LDAP_CONTROL_DONTUSECOPY 237 1.1 lukem static int dontUseCopy = 0; 238 1.1 lukem #endif 239 1.1 lukem 240 1.1 lukem static int domainScope = 0; 241 1.1 lukem 242 1.2 christos static int sss = 0; 243 1.2 christos static LDAPSortKey **sss_keys = NULL; 244 1.2 christos 245 1.2 christos static int vlv = 0; 246 1.2 christos static LDAPVLVInfo vlvInfo; 247 1.2 christos static struct berval vlvValue; 248 1.2 christos 249 1.1 lukem static int ldapsync = 0; 250 1.1 lukem static struct berval sync_cookie = { 0, NULL }; 251 1.1 lukem static int sync_slimit = -1; 252 1.1 lukem 253 1.3 christos static int psearch = 0; 254 1.3 christos static int ps_chgtypes, ps_chgsonly, ps_echg_ctrls; 255 1.3 christos 256 1.1 lukem /* cookie and morePagedResults moved to common.c */ 257 1.1 lukem static int pagedResults = 0; 258 1.1 lukem static int pagePrompt = 1; 259 1.1 lukem static ber_int_t pageSize = 0; 260 1.1 lukem static ber_int_t entriesLeft = 0; 261 1.1 lukem static int npagedresponses; 262 1.1 lukem static int npagedentries; 263 1.1 lukem static int npagedreferences; 264 1.1 lukem static int npagedextended; 265 1.1 lukem static int npagedpartial; 266 1.1 lukem 267 1.1 lukem static LDAPControl *c = NULL; 268 1.1 lukem static int nctrls = 0; 269 1.1 lukem static int save_nctrls = 0; 270 1.1 lukem 271 1.2 christos #ifdef LDAP_CONTROL_X_DEREF 272 1.2 christos static int derefcrit; 273 1.2 christos static LDAPDerefSpec *ds; 274 1.2 christos static struct berval derefval; 275 1.2 christos #endif 276 1.2 christos 277 1.3 christos #ifdef LDAP_CONTROL_X_DIRSYNC 278 1.3 christos static int dirSync; 279 1.3 christos static int dirSyncFlags; 280 1.3 christos static int dirSyncMaxAttrCount; 281 1.3 christos static struct berval dirSyncCookie; 282 1.3 christos #endif 283 1.3 christos 284 1.3 christos #ifdef LDAP_CONTROL_X_EXTENDED_DN 285 1.3 christos static int extendedDn; 286 1.3 christos static int extendedDnFlag; 287 1.3 christos #endif 288 1.3 christos 289 1.3 christos #ifdef LDAP_CONTROL_X_SHOW_DELETED 290 1.3 christos static int showDeleted; 291 1.3 christos #endif 292 1.3 christos 293 1.3 christos #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION 294 1.3 christos static int serverNotif; 295 1.3 christos #endif 296 1.3 christos 297 1.1 lukem static int 298 1.1 lukem ctrl_add( void ) 299 1.1 lukem { 300 1.1 lukem LDAPControl *tmpc; 301 1.1 lukem 302 1.1 lukem nctrls++; 303 1.1 lukem tmpc = realloc( c, sizeof( LDAPControl ) * nctrls ); 304 1.1 lukem if ( tmpc == NULL ) { 305 1.1 lukem nctrls--; 306 1.1 lukem fprintf( stderr, 307 1.1 lukem _("unable to make room for control; out of memory?\n")); 308 1.1 lukem return -1; 309 1.1 lukem } 310 1.1 lukem c = tmpc; 311 1.1 lukem 312 1.1 lukem return 0; 313 1.1 lukem } 314 1.1 lukem 315 1.1 lukem static void 316 1.1 lukem urlize(char *url) 317 1.1 lukem { 318 1.1 lukem char *p; 319 1.1 lukem 320 1.1 lukem if (*LDAP_DIRSEP != '/') { 321 1.1 lukem for (p = url; *p; p++) { 322 1.1 lukem if (*p == *LDAP_DIRSEP) 323 1.1 lukem *p = '/'; 324 1.1 lukem } 325 1.1 lukem } 326 1.1 lukem } 327 1.1 lukem 328 1.2 christos static int 329 1.2 christos parse_vlv(char *cvalue) 330 1.2 christos { 331 1.2 christos char *keyp, *key2; 332 1.2 christos int num1, num2; 333 1.2 christos 334 1.2 christos keyp = cvalue; 335 1.2 christos if ( sscanf( keyp, "%d/%d", &num1, &num2 ) != 2 ) { 336 1.2 christos fprintf( stderr, 337 1.2 christos _("VLV control value \"%s\" invalid\n"), 338 1.2 christos cvalue ); 339 1.2 christos return -1; 340 1.2 christos } 341 1.2 christos vlvInfo.ldvlv_before_count = num1; 342 1.2 christos vlvInfo.ldvlv_after_count = num2; 343 1.2 christos keyp = strchr( keyp, '/' ) + 1; 344 1.2 christos key2 = strchr( keyp, '/' ); 345 1.2 christos if ( key2 ) { 346 1.2 christos keyp = key2 + 1; 347 1.2 christos if ( sscanf( keyp, "%d/%d", &num1, &num2 ) != 2 ) { 348 1.2 christos fprintf( stderr, 349 1.2 christos _("VLV control value \"%s\" invalid\n"), 350 1.2 christos cvalue ); 351 1.2 christos return -1; 352 1.2 christos } 353 1.2 christos vlvInfo.ldvlv_offset = num1; 354 1.2 christos vlvInfo.ldvlv_count = num2; 355 1.2 christos vlvInfo.ldvlv_attrvalue = NULL; 356 1.2 christos } else { 357 1.2 christos key2 = strchr( keyp, ':' ); 358 1.2 christos if ( !key2 ) { 359 1.2 christos fprintf( stderr, 360 1.2 christos _("VLV control value \"%s\" invalid\n"), 361 1.2 christos cvalue ); 362 1.2 christos return -1; 363 1.2 christos } 364 1.2 christos ber_str2bv( key2+1, 0, 0, &vlvValue ); 365 1.2 christos vlvInfo.ldvlv_attrvalue = &vlvValue; 366 1.2 christos } 367 1.2 christos return 0; 368 1.2 christos } 369 1.1 lukem 370 1.1 lukem const char options[] = "a:Ab:cE:F:l:Ls:S:tT:uz:" 371 1.4 christos "Cd:D:e:f:H:IMnNO:o:P:QR:U:vVw:WxX:y:Y:Z"; 372 1.1 lukem 373 1.1 lukem int 374 1.1 lukem handle_private_option( int i ) 375 1.1 lukem { 376 1.1 lukem int crit, ival; 377 1.1 lukem char *cvalue, *next; 378 1.1 lukem switch ( i ) { 379 1.1 lukem case 'a': /* set alias deref option */ 380 1.1 lukem if ( strcasecmp( optarg, "never" ) == 0 ) { 381 1.1 lukem deref = LDAP_DEREF_NEVER; 382 1.1 lukem } else if ( strncasecmp( optarg, "search", sizeof("search")-1 ) == 0 ) { 383 1.1 lukem deref = LDAP_DEREF_SEARCHING; 384 1.1 lukem } else if ( strncasecmp( optarg, "find", sizeof("find")-1 ) == 0 ) { 385 1.1 lukem deref = LDAP_DEREF_FINDING; 386 1.1 lukem } else if ( strcasecmp( optarg, "always" ) == 0 ) { 387 1.1 lukem deref = LDAP_DEREF_ALWAYS; 388 1.1 lukem } else { 389 1.1 lukem fprintf( stderr, 390 1.1 lukem _("alias deref should be never, search, find, or always\n") ); 391 1.1 lukem usage(); 392 1.1 lukem } 393 1.1 lukem break; 394 1.1 lukem case 'A': /* retrieve attribute names only -- no values */ 395 1.1 lukem ++attrsonly; 396 1.1 lukem break; 397 1.1 lukem case 'b': /* search base */ 398 1.3 christos base = optarg; 399 1.1 lukem break; 400 1.1 lukem case 'E': /* search extensions */ 401 1.1 lukem if( protocol == LDAP_VERSION2 ) { 402 1.1 lukem fprintf( stderr, _("%s: -E incompatible with LDAPv%d\n"), 403 1.1 lukem prog, protocol ); 404 1.1 lukem exit( EXIT_FAILURE ); 405 1.1 lukem } 406 1.1 lukem 407 1.1 lukem /* should be extended to support comma separated list of 408 1.1 lukem * [!]key[=value] parameters, e.g. -E !foo,bar=567 409 1.1 lukem */ 410 1.1 lukem 411 1.1 lukem crit = 0; 412 1.1 lukem cvalue = NULL; 413 1.3 christos while ( optarg[0] == '!' ) { 414 1.3 christos crit++; 415 1.1 lukem optarg++; 416 1.1 lukem } 417 1.1 lukem 418 1.3 christos control = optarg; 419 1.1 lukem if ( (cvalue = strchr( control, '=' )) != NULL ) { 420 1.1 lukem *cvalue++ = '\0'; 421 1.1 lukem } 422 1.1 lukem 423 1.1 lukem if ( strcasecmp( control, "mv" ) == 0 ) { 424 1.1 lukem /* ValuesReturnFilter control */ 425 1.1 lukem if( valuesReturnFilter ) { 426 1.1 lukem fprintf( stderr, 427 1.1 lukem _("ValuesReturnFilter previously specified\n")); 428 1.1 lukem exit( EXIT_FAILURE ); 429 1.1 lukem } 430 1.1 lukem valuesReturnFilter= 1 + crit; 431 1.1 lukem 432 1.1 lukem if ( cvalue == NULL ) { 433 1.1 lukem fprintf( stderr, 434 1.1 lukem _("missing filter in ValuesReturnFilter control\n")); 435 1.1 lukem exit( EXIT_FAILURE ); 436 1.1 lukem } 437 1.1 lukem 438 1.1 lukem vrFilter = cvalue; 439 1.1 lukem protocol = LDAP_VERSION3; 440 1.1 lukem 441 1.1 lukem } else if ( strcasecmp( control, "pr" ) == 0 ) { 442 1.1 lukem int num, tmp; 443 1.1 lukem /* PagedResults control */ 444 1.1 lukem if ( pagedResults != 0 ) { 445 1.1 lukem fprintf( stderr, 446 1.1 lukem _("PagedResultsControl previously specified\n") ); 447 1.1 lukem exit( EXIT_FAILURE ); 448 1.1 lukem } 449 1.2 christos if ( vlv != 0 ) { 450 1.2 christos fprintf( stderr, 451 1.2 christos _("PagedResultsControl incompatible with VLV\n") ); 452 1.2 christos exit( EXIT_FAILURE ); 453 1.2 christos } 454 1.1 lukem 455 1.1 lukem if( cvalue != NULL ) { 456 1.1 lukem char *promptp; 457 1.1 lukem 458 1.1 lukem promptp = strchr( cvalue, '/' ); 459 1.1 lukem if ( promptp != NULL ) { 460 1.1 lukem *promptp++ = '\0'; 461 1.1 lukem if ( strcasecmp( promptp, "prompt" ) == 0 ) { 462 1.1 lukem pagePrompt = 1; 463 1.1 lukem } else if ( strcasecmp( promptp, "noprompt" ) == 0) { 464 1.1 lukem pagePrompt = 0; 465 1.1 lukem } else { 466 1.1 lukem fprintf( stderr, 467 1.1 lukem _("Invalid value for PagedResultsControl," 468 1.1 lukem " %s/%s.\n"), cvalue, promptp ); 469 1.1 lukem exit( EXIT_FAILURE ); 470 1.1 lukem } 471 1.1 lukem } 472 1.1 lukem num = sscanf( cvalue, "%d", &tmp ); 473 1.1 lukem if ( num != 1 ) { 474 1.1 lukem fprintf( stderr, 475 1.1 lukem _("Invalid value for PagedResultsControl, %s.\n"), 476 1.1 lukem cvalue ); 477 1.1 lukem exit( EXIT_FAILURE ); 478 1.1 lukem } 479 1.1 lukem } else { 480 1.1 lukem fprintf(stderr, _("Invalid value for PagedResultsControl.\n")); 481 1.1 lukem exit( EXIT_FAILURE ); 482 1.1 lukem } 483 1.1 lukem pageSize = (ber_int_t) tmp; 484 1.1 lukem pagedResults = 1 + crit; 485 1.1 lukem 486 1.3 christos } else if ( strcasecmp( control, "ps" ) == 0 ) { 487 1.3 christos int num; 488 1.3 christos /* PersistentSearch control */ 489 1.3 christos if ( psearch != 0 ) { 490 1.3 christos fprintf( stderr, 491 1.3 christos _("PersistentSearch previously specified\n") ); 492 1.3 christos exit( EXIT_FAILURE ); 493 1.3 christos } 494 1.3 christos if( cvalue != NULL ) { 495 1.3 christos num = sscanf( cvalue, "%i/%d/%d", &ps_chgtypes, &ps_chgsonly, &ps_echg_ctrls ); 496 1.3 christos if ( num != 3 ) { 497 1.3 christos fprintf( stderr, 498 1.3 christos _("Invalid value for PersistentSearch, %s.\n"), 499 1.3 christos cvalue ); 500 1.3 christos exit( EXIT_FAILURE ); 501 1.3 christos } 502 1.3 christos } else { 503 1.3 christos fprintf(stderr, _("Invalid value for PersistentSearch.\n")); 504 1.3 christos exit( EXIT_FAILURE ); 505 1.3 christos } 506 1.3 christos psearch = 1 + crit; 507 1.3 christos 508 1.1 lukem #ifdef LDAP_CONTROL_DONTUSECOPY 509 1.1 lukem } else if ( strcasecmp( control, "dontUseCopy" ) == 0 ) { 510 1.1 lukem if( dontUseCopy ) { 511 1.1 lukem fprintf( stderr, 512 1.1 lukem _("dontUseCopy control previously specified\n")); 513 1.1 lukem exit( EXIT_FAILURE ); 514 1.1 lukem } 515 1.1 lukem if( cvalue != NULL ) { 516 1.1 lukem fprintf( stderr, 517 1.1 lukem _("dontUseCopy: no control value expected\n") ); 518 1.1 lukem usage(); 519 1.1 lukem } 520 1.1 lukem if( !crit ) { 521 1.1 lukem fprintf( stderr, 522 1.1 lukem _("dontUseCopy: critical flag required\n") ); 523 1.1 lukem usage(); 524 1.1 lukem } 525 1.1 lukem 526 1.1 lukem dontUseCopy = 1 + crit; 527 1.1 lukem #endif 528 1.1 lukem } else if ( strcasecmp( control, "domainScope" ) == 0 ) { 529 1.1 lukem if( domainScope ) { 530 1.1 lukem fprintf( stderr, 531 1.1 lukem _("domainScope control previously specified\n")); 532 1.1 lukem exit( EXIT_FAILURE ); 533 1.1 lukem } 534 1.1 lukem if( cvalue != NULL ) { 535 1.1 lukem fprintf( stderr, 536 1.1 lukem _("domainScope: no control value expected\n") ); 537 1.1 lukem usage(); 538 1.1 lukem } 539 1.1 lukem 540 1.1 lukem domainScope = 1 + crit; 541 1.1 lukem 542 1.2 christos } else if ( strcasecmp( control, "sss" ) == 0 ) { 543 1.2 christos char *keyp; 544 1.2 christos if( sss ) { 545 1.2 christos fprintf( stderr, 546 1.2 christos _("server side sorting control previously specified\n")); 547 1.2 christos exit( EXIT_FAILURE ); 548 1.2 christos } 549 1.2 christos if( cvalue == NULL ) { 550 1.2 christos fprintf( stderr, 551 1.2 christos _("missing specification of sss control\n") ); 552 1.2 christos exit( EXIT_FAILURE ); 553 1.2 christos } 554 1.2 christos keyp = cvalue; 555 1.2 christos while ( ( keyp = strchr(keyp, '/') ) != NULL ) { 556 1.2 christos *keyp++ = ' '; 557 1.2 christos } 558 1.2 christos if ( ldap_create_sort_keylist( &sss_keys, cvalue )) { 559 1.2 christos fprintf( stderr, 560 1.2 christos _("server side sorting control value \"%s\" invalid\n"), 561 1.2 christos cvalue ); 562 1.2 christos exit( EXIT_FAILURE ); 563 1.2 christos } 564 1.2 christos 565 1.2 christos sss = 1 + crit; 566 1.2 christos 567 1.1 lukem } else if ( strcasecmp( control, "subentries" ) == 0 ) { 568 1.1 lukem if( subentries ) { 569 1.1 lukem fprintf( stderr, 570 1.1 lukem _("subentries control previously specified\n")); 571 1.1 lukem exit( EXIT_FAILURE ); 572 1.1 lukem } 573 1.1 lukem if( cvalue == NULL || strcasecmp( cvalue, "true") == 0 ) { 574 1.1 lukem subentries = 2; 575 1.1 lukem } else if ( strcasecmp( cvalue, "false") == 0 ) { 576 1.1 lukem subentries = 1; 577 1.1 lukem } else { 578 1.1 lukem fprintf( stderr, 579 1.1 lukem _("subentries control value \"%s\" invalid\n"), 580 1.1 lukem cvalue ); 581 1.1 lukem exit( EXIT_FAILURE ); 582 1.1 lukem } 583 1.1 lukem if( crit ) subentries *= -1; 584 1.1 lukem 585 1.1 lukem } else if ( strcasecmp( control, "sync" ) == 0 ) { 586 1.1 lukem char *cookiep; 587 1.1 lukem char *slimitp; 588 1.1 lukem if ( ldapsync ) { 589 1.1 lukem fprintf( stderr, _("sync control previously specified\n") ); 590 1.1 lukem exit( EXIT_FAILURE ); 591 1.1 lukem } 592 1.1 lukem if ( cvalue == NULL ) { 593 1.1 lukem fprintf( stderr, _("missing specification of sync control\n")); 594 1.1 lukem exit( EXIT_FAILURE ); 595 1.1 lukem } 596 1.1 lukem if ( strncasecmp( cvalue, "ro", 2 ) == 0 ) { 597 1.1 lukem ldapsync = LDAP_SYNC_REFRESH_ONLY; 598 1.1 lukem cookiep = strchr( cvalue, '/' ); 599 1.1 lukem if ( cookiep != NULL ) { 600 1.1 lukem cookiep++; 601 1.1 lukem if ( *cookiep != '\0' ) { 602 1.1 lukem ber_str2bv( cookiep, 0, 0, &sync_cookie ); 603 1.1 lukem } 604 1.1 lukem } 605 1.1 lukem } else if ( strncasecmp( cvalue, "rp", 2 ) == 0 ) { 606 1.1 lukem ldapsync = LDAP_SYNC_REFRESH_AND_PERSIST; 607 1.1 lukem cookiep = strchr( cvalue, '/' ); 608 1.1 lukem if ( cookiep != NULL ) { 609 1.1 lukem *cookiep++ = '\0'; 610 1.1 lukem cvalue = cookiep; 611 1.1 lukem } 612 1.1 lukem slimitp = strchr( cvalue, '/' ); 613 1.1 lukem if ( slimitp != NULL ) { 614 1.1 lukem *slimitp++ = '\0'; 615 1.1 lukem } 616 1.1 lukem if ( cookiep != NULL && *cookiep != '\0' ) 617 1.1 lukem ber_str2bv( cookiep, 0, 0, &sync_cookie ); 618 1.1 lukem if ( slimitp != NULL && *slimitp != '\0' ) { 619 1.1 lukem ival = strtol( slimitp, &next, 10 ); 620 1.1 lukem if ( next == NULL || next[0] != '\0' ) { 621 1.1 lukem fprintf( stderr, _("Unable to parse sync control value \"%s\"\n"), slimitp ); 622 1.1 lukem exit( EXIT_FAILURE ); 623 1.1 lukem } 624 1.1 lukem sync_slimit = ival; 625 1.1 lukem } 626 1.1 lukem } else { 627 1.1 lukem fprintf( stderr, _("sync control value \"%s\" invalid\n"), 628 1.1 lukem cvalue ); 629 1.1 lukem exit( EXIT_FAILURE ); 630 1.1 lukem } 631 1.1 lukem if ( crit ) ldapsync *= -1; 632 1.1 lukem 633 1.2 christos } else if ( strcasecmp( control, "vlv" ) == 0 ) { 634 1.2 christos if( vlv ) { 635 1.2 christos fprintf( stderr, 636 1.2 christos _("virtual list view control previously specified\n")); 637 1.2 christos exit( EXIT_FAILURE ); 638 1.2 christos } 639 1.2 christos if ( pagedResults != 0 ) { 640 1.2 christos fprintf( stderr, 641 1.2 christos _("PagedResultsControl incompatible with VLV\n") ); 642 1.2 christos exit( EXIT_FAILURE ); 643 1.2 christos } 644 1.2 christos if( cvalue == NULL ) { 645 1.2 christos fprintf( stderr, 646 1.2 christos _("missing specification of vlv control\n") ); 647 1.2 christos exit( EXIT_FAILURE ); 648 1.2 christos } 649 1.2 christos if ( parse_vlv( cvalue )) 650 1.2 christos exit( EXIT_FAILURE ); 651 1.2 christos 652 1.2 christos vlv = 1 + crit; 653 1.2 christos 654 1.2 christos #ifdef LDAP_CONTROL_X_DEREF 655 1.2 christos } else if ( strcasecmp( control, "deref" ) == 0 ) { 656 1.2 christos int ispecs; 657 1.2 christos char **specs; 658 1.2 christos 659 1.2 christos /* cvalue is something like 660 1.2 christos * 661 1.2 christos * derefAttr:attr[,attr[...]][;derefAttr:attr[,attr[...]]]" 662 1.2 christos */ 663 1.2 christos 664 1.2 christos specs = ldap_str2charray( cvalue, ";" ); 665 1.2 christos if ( specs == NULL ) { 666 1.2 christos fprintf( stderr, _("deref specs \"%s\" invalid\n"), 667 1.2 christos cvalue ); 668 1.2 christos exit( EXIT_FAILURE ); 669 1.2 christos } 670 1.2 christos for ( ispecs = 0; specs[ ispecs ] != NULL; ispecs++ ) 671 1.2 christos /* count'em */ ; 672 1.2 christos 673 1.2 christos ds = ldap_memcalloc( ispecs + 1, sizeof( LDAPDerefSpec ) ); 674 1.2 christos if ( ds == NULL ) { 675 1.2 christos perror( "malloc" ); 676 1.2 christos exit( EXIT_FAILURE ); 677 1.2 christos } 678 1.2 christos 679 1.2 christos for ( ispecs = 0; specs[ ispecs ] != NULL; ispecs++ ) { 680 1.2 christos char *ptr; 681 1.2 christos 682 1.2 christos ptr = strchr( specs[ ispecs ], ':' ); 683 1.2 christos if ( ptr == NULL ) { 684 1.2 christos fprintf( stderr, _("deref specs \"%s\" invalid\n"), 685 1.2 christos cvalue ); 686 1.2 christos exit( EXIT_FAILURE ); 687 1.2 christos } 688 1.2 christos 689 1.2 christos ds[ ispecs ].derefAttr = specs[ ispecs ]; 690 1.2 christos *ptr++ = '\0'; 691 1.2 christos ds[ ispecs ].attributes = ldap_str2charray( ptr, "," ); 692 1.2 christos } 693 1.2 christos 694 1.2 christos derefcrit = 1 + crit; 695 1.2 christos 696 1.2 christos ldap_memfree( specs ); 697 1.2 christos #endif /* LDAP_CONTROL_X_DEREF */ 698 1.2 christos 699 1.3 christos #ifdef LDAP_CONTROL_X_DIRSYNC 700 1.3 christos } else if ( strcasecmp( control, "dirSync" ) == 0 ) { 701 1.3 christos char *maxattrp; 702 1.3 christos char *cookiep; 703 1.3 christos int num, tmp; 704 1.3 christos if( dirSync ) { 705 1.3 christos fprintf( stderr, 706 1.3 christos _("dirSync control previously specified\n")); 707 1.3 christos exit( EXIT_FAILURE ); 708 1.3 christos } 709 1.3 christos if ( cvalue == NULL ) { 710 1.3 christos fprintf( stderr, _("missing specification of dirSync control\n")); 711 1.3 christos exit( EXIT_FAILURE ); 712 1.3 christos } 713 1.3 christos if( !crit ) { 714 1.3 christos fprintf( stderr, 715 1.3 christos _("dirSync: critical flag required\n") ); 716 1.3 christos usage(); 717 1.3 christos } 718 1.3 christos maxattrp = strchr( cvalue, '/' ); 719 1.3 christos if ( maxattrp == NULL ) { 720 1.3 christos fprintf( stderr, _("dirSync control value \"%s\" invalid\n"), 721 1.3 christos cvalue ); 722 1.3 christos exit( EXIT_FAILURE ); 723 1.3 christos } 724 1.3 christos *maxattrp++ = '\0'; 725 1.3 christos cookiep = strchr( maxattrp, '/' ); 726 1.3 christos if ( cookiep != NULL ) { 727 1.3 christos if ( cookiep[1] != '\0' ) { 728 1.3 christos struct berval type; 729 1.3 christos int freeval; 730 1.3 christos char save1, save2; 731 1.3 christos 732 1.3 christos /* dummy type "x" 733 1.3 christos * to use ldif_parse_line2() */ 734 1.3 christos save1 = cookiep[ -1 ]; 735 1.3 christos save2 = cookiep[ -2 ]; 736 1.3 christos cookiep[ -2 ] = 'x'; 737 1.3 christos cookiep[ -1 ] = ':'; 738 1.3 christos cookiep[ 0 ] = ':'; 739 1.3 christos ldif_parse_line2( &cookiep[ -2 ], &type, 740 1.3 christos &dirSyncCookie, &freeval ); 741 1.3 christos cookiep[ -1 ] = save1; 742 1.3 christos cookiep[ -2 ] = save2; 743 1.3 christos } 744 1.3 christos *cookiep = '\0'; 745 1.3 christos } 746 1.3 christos num = sscanf( cvalue, "%i", &tmp ); 747 1.3 christos if ( num != 1 ) { 748 1.3 christos fprintf( stderr, 749 1.3 christos _("Invalid value for dirSync, %s.\n"), 750 1.3 christos cvalue ); 751 1.3 christos exit( EXIT_FAILURE ); 752 1.3 christos } 753 1.3 christos dirSyncFlags = tmp; 754 1.3 christos 755 1.3 christos num = sscanf( maxattrp, "%d", &tmp ); 756 1.3 christos if ( num != 1 ) { 757 1.3 christos fprintf( stderr, 758 1.3 christos _("Invalid value for dirSync, %s.\n"), 759 1.3 christos maxattrp ); 760 1.3 christos exit( EXIT_FAILURE ); 761 1.3 christos } 762 1.3 christos dirSyncMaxAttrCount = tmp; 763 1.3 christos 764 1.3 christos dirSync = 1 + crit; 765 1.3 christos #endif /* LDAP_CONTROL_X_DIRSYNC */ 766 1.3 christos 767 1.3 christos #ifdef LDAP_CONTROL_X_EXTENDED_DN 768 1.3 christos } else if ( strcasecmp( control, "extendedDn" ) == 0 ) { 769 1.3 christos int num, tmp; 770 1.3 christos if( extendedDn ) { 771 1.3 christos fprintf( stderr, 772 1.3 christos _("extendedDn control previously specified\n")); 773 1.3 christos exit( EXIT_FAILURE ); 774 1.3 christos } 775 1.3 christos if ( cvalue == NULL ) { 776 1.3 christos fprintf( stderr, _("missing specification of extendedDn control\n")); 777 1.3 christos exit( EXIT_FAILURE ); 778 1.3 christos } 779 1.3 christos num = sscanf( cvalue, "%d", &tmp ); 780 1.3 christos if ( num != 1 ) { 781 1.3 christos fprintf( stderr, 782 1.3 christos _("Invalid value for extendedDn, %s.\n"), 783 1.3 christos cvalue ); 784 1.3 christos exit( EXIT_FAILURE ); 785 1.3 christos } 786 1.3 christos 787 1.3 christos extendedDnFlag = tmp; 788 1.3 christos extendedDn = 1 + crit; 789 1.3 christos #endif /* LDAP_CONTROL_X_EXTENDED_DN */ 790 1.3 christos 791 1.3 christos #ifdef LDAP_CONTROL_X_SHOW_DELETED 792 1.3 christos } else if ( strcasecmp( control, "showDeleted" ) == 0 ) { 793 1.3 christos if( showDeleted ) { 794 1.3 christos fprintf( stderr, 795 1.3 christos _("showDeleted control previously specified\n")); 796 1.3 christos exit( EXIT_FAILURE ); 797 1.3 christos } 798 1.3 christos if ( cvalue != NULL ) { 799 1.3 christos fprintf( stderr, 800 1.3 christos _("showDeleted: no control value expected\n") ); 801 1.3 christos usage(); 802 1.3 christos } 803 1.3 christos 804 1.3 christos showDeleted = 1 + crit; 805 1.3 christos #endif /* LDAP_CONTROL_X_SHOW_DELETED */ 806 1.3 christos 807 1.3 christos #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION 808 1.3 christos } else if ( strcasecmp( control, "serverNotif" ) == 0 ) { 809 1.3 christos if( serverNotif ) { 810 1.3 christos fprintf( stderr, 811 1.3 christos _("serverNotif control previously specified\n")); 812 1.3 christos exit( EXIT_FAILURE ); 813 1.3 christos } 814 1.3 christos if ( cvalue != NULL ) { 815 1.3 christos fprintf( stderr, 816 1.3 christos _("serverNotif: no control value expected\n") ); 817 1.3 christos usage(); 818 1.3 christos } 819 1.3 christos 820 1.3 christos serverNotif = 1 + crit; 821 1.3 christos #endif /* LDAP_CONTROL_X_SERVER_NOTIFICATION */ 822 1.3 christos 823 1.3 christos #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY 824 1.3 christos } else if ( strcasecmp( control, "accountUsability" ) == 0 ) { 825 1.3 christos if( accountUsability ) { 826 1.3 christos fprintf( stderr, 827 1.3 christos _("accountUsability control previously specified\n")); 828 1.3 christos exit( EXIT_FAILURE ); 829 1.3 christos } 830 1.3 christos if( cvalue != NULL ) { 831 1.3 christos fprintf( stderr, 832 1.3 christos _("accountUsability: no control value expected\n") ); 833 1.3 christos usage(); 834 1.3 christos } 835 1.3 christos 836 1.3 christos accountUsability = 1 + crit; 837 1.3 christos #endif /* LDAP_CONTROL_X_ACCOUNT_USABILITY */ 838 1.3 christos 839 1.1 lukem } else if ( tool_is_oid( control ) ) { 840 1.3 christos if ( c != NULL ) { 841 1.3 christos int i; 842 1.3 christos for ( i = 0; i < nctrls; i++ ) { 843 1.3 christos if ( strcmp( control, c[ i ].ldctl_oid ) == 0 ) { 844 1.3 christos fprintf( stderr, "%s control previously specified\n", control ); 845 1.3 christos exit( EXIT_FAILURE ); 846 1.3 christos } 847 1.3 christos } 848 1.3 christos } 849 1.3 christos 850 1.1 lukem if ( ctrl_add() ) { 851 1.1 lukem exit( EXIT_FAILURE ); 852 1.1 lukem } 853 1.1 lukem 854 1.1 lukem /* OID */ 855 1.1 lukem c[ nctrls - 1 ].ldctl_oid = control; 856 1.1 lukem 857 1.1 lukem /* value */ 858 1.1 lukem if ( cvalue == NULL ) { 859 1.1 lukem c[ nctrls - 1 ].ldctl_value.bv_val = NULL; 860 1.1 lukem c[ nctrls - 1 ].ldctl_value.bv_len = 0; 861 1.1 lukem 862 1.1 lukem } else if ( cvalue[ 0 ] == ':' ) { 863 1.2 christos struct berval type; 864 1.2 christos struct berval value; 865 1.2 christos int freeval; 866 1.2 christos char save_c; 867 1.1 lukem 868 1.1 lukem cvalue++; 869 1.1 lukem 870 1.1 lukem /* dummy type "x" 871 1.1 lukem * to use ldif_parse_line2() */ 872 1.2 christos save_c = cvalue[ -2 ]; 873 1.1 lukem cvalue[ -2 ] = 'x'; 874 1.1 lukem ldif_parse_line2( &cvalue[ -2 ], &type, 875 1.1 lukem &value, &freeval ); 876 1.2 christos cvalue[ -2 ] = save_c; 877 1.1 lukem 878 1.1 lukem if ( freeval ) { 879 1.1 lukem c[ nctrls - 1 ].ldctl_value = value; 880 1.1 lukem 881 1.1 lukem } else { 882 1.1 lukem ber_dupbv( &c[ nctrls - 1 ].ldctl_value, &value ); 883 1.1 lukem } 884 1.2 christos 885 1.2 christos } else { 886 1.2 christos fprintf( stderr, "unable to parse %s control value\n", control ); 887 1.2 christos exit( EXIT_FAILURE ); 888 1.2 christos 889 1.1 lukem } 890 1.1 lukem 891 1.1 lukem /* criticality */ 892 1.1 lukem c[ nctrls - 1 ].ldctl_iscritical = crit; 893 1.1 lukem 894 1.1 lukem } else { 895 1.1 lukem fprintf( stderr, _("Invalid search extension name: %s\n"), 896 1.1 lukem control ); 897 1.1 lukem usage(); 898 1.1 lukem } 899 1.1 lukem break; 900 1.1 lukem case 'F': /* uri prefix */ 901 1.1 lukem if( urlpre ) free( urlpre ); 902 1.4 christos urlpre = strdup( optarg ); 903 1.1 lukem break; 904 1.1 lukem case 'l': /* time limit */ 905 1.1 lukem if ( strcasecmp( optarg, "none" ) == 0 ) { 906 1.1 lukem timelimit = 0; 907 1.1 lukem 908 1.1 lukem } else if ( strcasecmp( optarg, "max" ) == 0 ) { 909 1.1 lukem timelimit = LDAP_MAXINT; 910 1.1 lukem 911 1.1 lukem } else { 912 1.1 lukem ival = strtol( optarg, &next, 10 ); 913 1.1 lukem if ( next == NULL || next[0] != '\0' ) { 914 1.1 lukem fprintf( stderr, 915 1.1 lukem _("Unable to parse time limit \"%s\"\n"), optarg ); 916 1.1 lukem exit( EXIT_FAILURE ); 917 1.1 lukem } 918 1.1 lukem timelimit = ival; 919 1.1 lukem } 920 1.1 lukem if( timelimit < 0 || timelimit > LDAP_MAXINT ) { 921 1.1 lukem fprintf( stderr, _("%s: invalid timelimit (%d) specified\n"), 922 1.1 lukem prog, timelimit ); 923 1.1 lukem exit( EXIT_FAILURE ); 924 1.1 lukem } 925 1.1 lukem break; 926 1.1 lukem case 'L': /* print entries in LDIF format */ 927 1.1 lukem ++ldif; 928 1.1 lukem break; 929 1.1 lukem case 's': /* search scope */ 930 1.1 lukem if ( strncasecmp( optarg, "base", sizeof("base")-1 ) == 0 ) { 931 1.1 lukem scope = LDAP_SCOPE_BASE; 932 1.1 lukem } else if ( strncasecmp( optarg, "one", sizeof("one")-1 ) == 0 ) { 933 1.1 lukem scope = LDAP_SCOPE_ONELEVEL; 934 1.1 lukem } else if (( strcasecmp( optarg, "subordinate" ) == 0 ) 935 1.1 lukem || ( strcasecmp( optarg, "children" ) == 0 )) 936 1.1 lukem { 937 1.1 lukem scope = LDAP_SCOPE_SUBORDINATE; 938 1.1 lukem } else if ( strncasecmp( optarg, "sub", sizeof("sub")-1 ) == 0 ) { 939 1.1 lukem scope = LDAP_SCOPE_SUBTREE; 940 1.1 lukem } else { 941 1.1 lukem fprintf( stderr, _("scope should be base, one, or sub\n") ); 942 1.1 lukem usage(); 943 1.1 lukem } 944 1.1 lukem break; 945 1.1 lukem case 'S': /* sort attribute */ 946 1.3 christos sortattr = optarg; 947 1.1 lukem break; 948 1.1 lukem case 't': /* write attribute values to TMPDIR files */ 949 1.1 lukem ++vals2tmp; 950 1.1 lukem break; 951 1.1 lukem case 'T': /* tmpdir */ 952 1.1 lukem if( tmpdir ) free( tmpdir ); 953 1.4 christos tmpdir = strdup( optarg ); 954 1.1 lukem break; 955 1.1 lukem case 'u': /* include UFN */ 956 1.1 lukem ++includeufn; 957 1.1 lukem break; 958 1.1 lukem case 'z': /* size limit */ 959 1.1 lukem if ( strcasecmp( optarg, "none" ) == 0 ) { 960 1.1 lukem sizelimit = 0; 961 1.1 lukem 962 1.1 lukem } else if ( strcasecmp( optarg, "max" ) == 0 ) { 963 1.1 lukem sizelimit = LDAP_MAXINT; 964 1.1 lukem 965 1.1 lukem } else { 966 1.1 lukem ival = strtol( optarg, &next, 10 ); 967 1.1 lukem if ( next == NULL || next[0] != '\0' ) { 968 1.1 lukem fprintf( stderr, 969 1.1 lukem _("Unable to parse size limit \"%s\"\n"), optarg ); 970 1.1 lukem exit( EXIT_FAILURE ); 971 1.1 lukem } 972 1.1 lukem sizelimit = ival; 973 1.1 lukem } 974 1.1 lukem if( sizelimit < 0 || sizelimit > LDAP_MAXINT ) { 975 1.1 lukem fprintf( stderr, _("%s: invalid sizelimit (%d) specified\n"), 976 1.1 lukem prog, sizelimit ); 977 1.1 lukem exit( EXIT_FAILURE ); 978 1.1 lukem } 979 1.1 lukem break; 980 1.1 lukem default: 981 1.1 lukem return 0; 982 1.1 lukem } 983 1.1 lukem return 1; 984 1.1 lukem } 985 1.1 lukem 986 1.1 lukem 987 1.1 lukem static void 988 1.1 lukem private_conn_setup( LDAP *ld ) 989 1.1 lukem { 990 1.1 lukem if (deref != -1 && 991 1.1 lukem ldap_set_option( ld, LDAP_OPT_DEREF, (void *) &deref ) 992 1.1 lukem != LDAP_OPT_SUCCESS ) 993 1.1 lukem { 994 1.1 lukem fprintf( stderr, _("Could not set LDAP_OPT_DEREF %d\n"), deref ); 995 1.2 christos tool_exit( ld, EXIT_FAILURE ); 996 1.1 lukem } 997 1.1 lukem } 998 1.1 lukem 999 1.1 lukem int 1000 1.1 lukem main( int argc, char **argv ) 1001 1.1 lukem { 1002 1.1 lukem char *filtpattern, **attrs = NULL, line[BUFSIZ]; 1003 1.1 lukem FILE *fp = NULL; 1004 1.1 lukem int rc, rc1, i, first; 1005 1.1 lukem LDAP *ld = NULL; 1006 1.4 christos BerElement *ber = NULL; 1007 1.1 lukem int err; 1008 1.1 lukem 1009 1.1 lukem tool_init( TOOL_SEARCH ); 1010 1.1 lukem 1011 1.1 lukem npagedresponses = npagedentries = npagedreferences = 1012 1.1 lukem npagedextended = npagedpartial = 0; 1013 1.1 lukem 1014 1.1 lukem prog = lutil_progname( "ldapsearch", argc, argv ); 1015 1.1 lukem 1016 1.1 lukem if((def_tmpdir = getenv("TMPDIR")) == NULL && 1017 1.1 lukem (def_tmpdir = getenv("TMP")) == NULL && 1018 1.1 lukem (def_tmpdir = getenv("TEMP")) == NULL ) 1019 1.1 lukem { 1020 1.1 lukem def_tmpdir = LDAP_TMPDIR; 1021 1.1 lukem } 1022 1.1 lukem 1023 1.1 lukem if ( !*def_tmpdir ) 1024 1.1 lukem def_tmpdir = LDAP_TMPDIR; 1025 1.1 lukem 1026 1.1 lukem def_urlpre = malloc( sizeof("file:////") + strlen(def_tmpdir) ); 1027 1.1 lukem 1028 1.1 lukem if( def_urlpre == NULL ) { 1029 1.1 lukem perror( "malloc" ); 1030 1.1 lukem return EXIT_FAILURE; 1031 1.1 lukem } 1032 1.1 lukem 1033 1.1 lukem sprintf( def_urlpre, "file:///%s/", 1034 1.1 lukem def_tmpdir[0] == *LDAP_DIRSEP ? &def_tmpdir[1] : def_tmpdir ); 1035 1.1 lukem 1036 1.1 lukem urlize( def_urlpre ); 1037 1.1 lukem 1038 1.1 lukem tool_args( argc, argv ); 1039 1.1 lukem 1040 1.2 christos if ( vlv && !sss ) { 1041 1.2 christos fprintf( stderr, 1042 1.2 christos _("VLV control requires server side sort control\n" )); 1043 1.2 christos return EXIT_FAILURE; 1044 1.2 christos } 1045 1.2 christos 1046 1.1 lukem if (( argc - optind < 1 ) || 1047 1.1 lukem ( *argv[optind] != '(' /*')'*/ && 1048 1.1 lukem ( strchr( argv[optind], '=' ) == NULL ) ) ) 1049 1.1 lukem { 1050 1.1 lukem filtpattern = "(objectclass=*)"; 1051 1.1 lukem } else { 1052 1.1 lukem filtpattern = argv[optind++]; 1053 1.1 lukem } 1054 1.1 lukem 1055 1.1 lukem if ( argv[optind] != NULL ) { 1056 1.1 lukem attrs = &argv[optind]; 1057 1.1 lukem } 1058 1.1 lukem 1059 1.1 lukem if ( infile != NULL ) { 1060 1.1 lukem int percent = 0; 1061 1.1 lukem 1062 1.1 lukem if ( infile[0] == '-' && infile[1] == '\0' ) { 1063 1.1 lukem fp = stdin; 1064 1.1 lukem } else if (( fp = fopen( infile, "r" )) == NULL ) { 1065 1.1 lukem perror( infile ); 1066 1.1 lukem return EXIT_FAILURE; 1067 1.1 lukem } 1068 1.1 lukem 1069 1.1 lukem for( i=0 ; filtpattern[i] ; i++ ) { 1070 1.1 lukem if( filtpattern[i] == '%' ) { 1071 1.1 lukem if( percent ) { 1072 1.1 lukem fprintf( stderr, _("Bad filter pattern \"%s\"\n"), 1073 1.1 lukem filtpattern ); 1074 1.1 lukem return EXIT_FAILURE; 1075 1.1 lukem } 1076 1.1 lukem 1077 1.1 lukem percent++; 1078 1.1 lukem 1079 1.1 lukem if( filtpattern[i+1] != 's' ) { 1080 1.1 lukem fprintf( stderr, _("Bad filter pattern \"%s\"\n"), 1081 1.1 lukem filtpattern ); 1082 1.1 lukem return EXIT_FAILURE; 1083 1.1 lukem } 1084 1.1 lukem } 1085 1.1 lukem } 1086 1.1 lukem } 1087 1.1 lukem 1088 1.1 lukem if ( tmpdir == NULL ) { 1089 1.1 lukem tmpdir = def_tmpdir; 1090 1.1 lukem 1091 1.1 lukem if ( urlpre == NULL ) 1092 1.1 lukem urlpre = def_urlpre; 1093 1.1 lukem } 1094 1.1 lukem 1095 1.1 lukem if( urlpre == NULL ) { 1096 1.1 lukem urlpre = malloc( sizeof("file:////") + strlen(tmpdir) ); 1097 1.1 lukem 1098 1.1 lukem if( urlpre == NULL ) { 1099 1.1 lukem perror( "malloc" ); 1100 1.1 lukem return EXIT_FAILURE; 1101 1.1 lukem } 1102 1.1 lukem 1103 1.1 lukem sprintf( urlpre, "file:///%s/", 1104 1.1 lukem tmpdir[0] == *LDAP_DIRSEP ? &tmpdir[1] : tmpdir ); 1105 1.1 lukem 1106 1.1 lukem urlize( urlpre ); 1107 1.1 lukem } 1108 1.1 lukem 1109 1.1 lukem if ( debug ) 1110 1.1 lukem ldif_debug = debug; 1111 1.1 lukem 1112 1.1 lukem ld = tool_conn_setup( 0, &private_conn_setup ); 1113 1.1 lukem 1114 1.1 lukem tool_bind( ld ); 1115 1.1 lukem 1116 1.1 lukem getNextPage: 1117 1.2 christos /* fp may have been closed, need to reopen if code jumps 1118 1.2 christos * back here to getNextPage. 1119 1.2 christos */ 1120 1.2 christos if ( !fp && infile ) { 1121 1.2 christos if (( fp = fopen( infile, "r" )) == NULL ) { 1122 1.2 christos perror( infile ); 1123 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1124 1.2 christos } 1125 1.2 christos } 1126 1.1 lukem save_nctrls = nctrls; 1127 1.1 lukem i = nctrls; 1128 1.1 lukem if ( nctrls > 0 1129 1.3 christos #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY 1130 1.3 christos || accountUsability 1131 1.3 christos #endif 1132 1.1 lukem #ifdef LDAP_CONTROL_DONTUSECOPY 1133 1.1 lukem || dontUseCopy 1134 1.1 lukem #endif 1135 1.2 christos #ifdef LDAP_CONTROL_X_DEREF 1136 1.2 christos || derefcrit 1137 1.2 christos #endif 1138 1.3 christos #ifdef LDAP_CONTROL_X_DIRSYNC 1139 1.3 christos || dirSync 1140 1.3 christos #endif 1141 1.3 christos #ifdef LDAP_CONTROL_X_EXTENDED_DN 1142 1.3 christos || extendedDn 1143 1.3 christos #endif 1144 1.3 christos #ifdef LDAP_CONTROL_X_SHOW_DELETED 1145 1.3 christos || showDeleted 1146 1.3 christos #endif 1147 1.3 christos #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION 1148 1.3 christos || serverNotif 1149 1.3 christos #endif 1150 1.1 lukem || domainScope 1151 1.1 lukem || pagedResults 1152 1.3 christos || psearch 1153 1.1 lukem || ldapsync 1154 1.2 christos || sss 1155 1.1 lukem || subentries 1156 1.2 christos || valuesReturnFilter 1157 1.2 christos || vlv ) 1158 1.1 lukem { 1159 1.1 lukem 1160 1.3 christos #ifdef LDAP_CONTROL_X_ACCOUNT_USABILITY 1161 1.3 christos if ( accountUsability ) { 1162 1.3 christos if ( ctrl_add() ) { 1163 1.3 christos tool_exit( ld, EXIT_FAILURE ); 1164 1.3 christos } 1165 1.3 christos 1166 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_X_ACCOUNT_USABILITY; 1167 1.3 christos c[i].ldctl_value.bv_val = NULL; 1168 1.3 christos c[i].ldctl_value.bv_len = 0; 1169 1.3 christos c[i].ldctl_iscritical = accountUsability == 2; 1170 1.3 christos i++; 1171 1.3 christos } 1172 1.3 christos #endif 1173 1.3 christos 1174 1.1 lukem #ifdef LDAP_CONTROL_DONTUSECOPY 1175 1.1 lukem if ( dontUseCopy ) { 1176 1.1 lukem if ( ctrl_add() ) { 1177 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1178 1.1 lukem } 1179 1.1 lukem 1180 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_DONTUSECOPY; 1181 1.1 lukem c[i].ldctl_value.bv_val = NULL; 1182 1.1 lukem c[i].ldctl_value.bv_len = 0; 1183 1.3 christos c[i].ldctl_iscritical = dontUseCopy == 2; 1184 1.1 lukem i++; 1185 1.1 lukem } 1186 1.1 lukem #endif 1187 1.1 lukem 1188 1.1 lukem if ( domainScope ) { 1189 1.1 lukem if ( ctrl_add() ) { 1190 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1191 1.1 lukem } 1192 1.1 lukem 1193 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_X_DOMAIN_SCOPE; 1194 1.1 lukem c[i].ldctl_value.bv_val = NULL; 1195 1.1 lukem c[i].ldctl_value.bv_len = 0; 1196 1.1 lukem c[i].ldctl_iscritical = domainScope > 1; 1197 1.1 lukem i++; 1198 1.1 lukem } 1199 1.1 lukem 1200 1.1 lukem if ( subentries ) { 1201 1.1 lukem if ( ctrl_add() ) { 1202 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1203 1.1 lukem } 1204 1.1 lukem 1205 1.4 christos if (( ber = ber_alloc_t(LBER_USE_DER)) == NULL ) { 1206 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1207 1.1 lukem } 1208 1.1 lukem 1209 1.4 christos err = ber_printf( ber, "b", abs(subentries) == 1 ? 0 : 1 ); 1210 1.1 lukem if ( err == -1 ) { 1211 1.4 christos ber_free( ber, 1 ); 1212 1.1 lukem fprintf( stderr, _("Subentries control encoding error!\n") ); 1213 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1214 1.1 lukem } 1215 1.1 lukem 1216 1.4 christos err = ber_flatten2( ber, &c[i].ldctl_value, 1 ); 1217 1.4 christos ber_free( ber, 1 ); 1218 1.4 christos if ( err == -1 ) 1219 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1220 1.1 lukem 1221 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_SUBENTRIES; 1222 1.1 lukem c[i].ldctl_iscritical = subentries < 1; 1223 1.1 lukem i++; 1224 1.1 lukem } 1225 1.1 lukem 1226 1.1 lukem if ( ldapsync ) { 1227 1.1 lukem if ( ctrl_add() ) { 1228 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1229 1.1 lukem } 1230 1.1 lukem 1231 1.4 christos if (( ber = ber_alloc_t(LBER_USE_DER)) == NULL ) { 1232 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1233 1.1 lukem } 1234 1.1 lukem 1235 1.1 lukem if ( sync_cookie.bv_len == 0 ) { 1236 1.4 christos err = ber_printf( ber, "{e}", abs(ldapsync) ); 1237 1.1 lukem } else { 1238 1.4 christos err = ber_printf( ber, "{eO}", abs(ldapsync), 1239 1.1 lukem &sync_cookie ); 1240 1.1 lukem } 1241 1.1 lukem 1242 1.2 christos if ( err == -1 ) { 1243 1.4 christos ber_free( ber, 1 ); 1244 1.1 lukem fprintf( stderr, _("ldap sync control encoding error!\n") ); 1245 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1246 1.1 lukem } 1247 1.1 lukem 1248 1.4 christos err = ber_flatten2( ber, &c[i].ldctl_value, 1 ); 1249 1.4 christos ber_free( ber, 1 ); 1250 1.4 christos if ( err == -1 ) 1251 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1252 1.1 lukem 1253 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_SYNC; 1254 1.1 lukem c[i].ldctl_iscritical = ldapsync < 0; 1255 1.1 lukem i++; 1256 1.1 lukem } 1257 1.1 lukem 1258 1.1 lukem if ( valuesReturnFilter ) { 1259 1.1 lukem if ( ctrl_add() ) { 1260 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1261 1.1 lukem } 1262 1.1 lukem 1263 1.4 christos if (( ber = ber_alloc_t(LBER_USE_DER)) == NULL ) { 1264 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1265 1.1 lukem } 1266 1.1 lukem 1267 1.4 christos if ( ( err = ldap_put_vrFilter( ber, vrFilter ) ) == -1 ) { 1268 1.4 christos ber_free( ber, 1 ); 1269 1.1 lukem fprintf( stderr, _("Bad ValuesReturnFilter: %s\n"), vrFilter ); 1270 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1271 1.1 lukem } 1272 1.1 lukem 1273 1.4 christos err = ber_flatten2( ber, &c[i].ldctl_value, 1 ); 1274 1.4 christos ber_free( ber, 1 ); 1275 1.4 christos if ( err == -1 ) 1276 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1277 1.1 lukem 1278 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_VALUESRETURNFILTER; 1279 1.1 lukem c[i].ldctl_iscritical = valuesReturnFilter > 1; 1280 1.1 lukem i++; 1281 1.1 lukem } 1282 1.1 lukem 1283 1.1 lukem if ( pagedResults ) { 1284 1.1 lukem if ( ctrl_add() ) { 1285 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1286 1.1 lukem } 1287 1.1 lukem 1288 1.1 lukem if ( ldap_create_page_control_value( ld, 1289 1.1 lukem pageSize, &pr_cookie, &c[i].ldctl_value ) ) 1290 1.1 lukem { 1291 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1292 1.1 lukem } 1293 1.1 lukem 1294 1.1 lukem if ( pr_cookie.bv_val != NULL ) { 1295 1.1 lukem ber_memfree( pr_cookie.bv_val ); 1296 1.1 lukem pr_cookie.bv_val = NULL; 1297 1.1 lukem pr_cookie.bv_len = 0; 1298 1.1 lukem } 1299 1.1 lukem 1300 1.1 lukem c[i].ldctl_oid = LDAP_CONTROL_PAGEDRESULTS; 1301 1.1 lukem c[i].ldctl_iscritical = pagedResults > 1; 1302 1.1 lukem i++; 1303 1.1 lukem } 1304 1.2 christos 1305 1.3 christos if ( psearch ) { 1306 1.3 christos if ( ctrl_add() ) { 1307 1.3 christos tool_exit( ld, EXIT_FAILURE ); 1308 1.3 christos } 1309 1.3 christos 1310 1.3 christos if ( ldap_create_persistentsearch_control_value( ld, 1311 1.3 christos ps_chgtypes, ps_chgsonly, ps_echg_ctrls, &c[i].ldctl_value ) ) 1312 1.3 christos { 1313 1.3 christos tool_exit( ld, EXIT_FAILURE ); 1314 1.3 christos } 1315 1.3 christos 1316 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_PERSIST_REQUEST; 1317 1.3 christos c[i].ldctl_iscritical = psearch > 1; 1318 1.3 christos i++; 1319 1.3 christos } 1320 1.3 christos 1321 1.2 christos if ( sss ) { 1322 1.2 christos if ( ctrl_add() ) { 1323 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1324 1.2 christos } 1325 1.2 christos 1326 1.2 christos if ( ldap_create_sort_control_value( ld, 1327 1.2 christos sss_keys, &c[i].ldctl_value ) ) 1328 1.2 christos { 1329 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1330 1.2 christos } 1331 1.2 christos 1332 1.2 christos c[i].ldctl_oid = LDAP_CONTROL_SORTREQUEST; 1333 1.2 christos c[i].ldctl_iscritical = sss > 1; 1334 1.2 christos i++; 1335 1.2 christos } 1336 1.2 christos 1337 1.2 christos if ( vlv ) { 1338 1.2 christos if ( ctrl_add() ) { 1339 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1340 1.2 christos } 1341 1.2 christos 1342 1.2 christos if ( ldap_create_vlv_control_value( ld, 1343 1.2 christos &vlvInfo, &c[i].ldctl_value ) ) 1344 1.2 christos { 1345 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1346 1.2 christos } 1347 1.2 christos 1348 1.2 christos c[i].ldctl_oid = LDAP_CONTROL_VLVREQUEST; 1349 1.3 christos c[i].ldctl_iscritical = vlv > 1; 1350 1.2 christos i++; 1351 1.2 christos } 1352 1.2 christos #ifdef LDAP_CONTROL_X_DEREF 1353 1.2 christos if ( derefcrit ) { 1354 1.2 christos if ( derefval.bv_val == NULL ) { 1355 1.2 christos int i; 1356 1.2 christos 1357 1.2 christos assert( ds != NULL ); 1358 1.2 christos 1359 1.2 christos if ( ldap_create_deref_control_value( ld, ds, &derefval ) != LDAP_SUCCESS ) { 1360 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1361 1.2 christos } 1362 1.2 christos 1363 1.2 christos for ( i = 0; ds[ i ].derefAttr != NULL; i++ ) { 1364 1.2 christos ldap_memfree( ds[ i ].derefAttr ); 1365 1.2 christos ldap_charray_free( ds[ i ].attributes ); 1366 1.2 christos } 1367 1.2 christos ldap_memfree( ds ); 1368 1.2 christos ds = NULL; 1369 1.2 christos } 1370 1.2 christos 1371 1.2 christos if ( ctrl_add() ) { 1372 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1373 1.2 christos } 1374 1.2 christos 1375 1.2 christos c[ i ].ldctl_iscritical = derefcrit > 1; 1376 1.2 christos c[ i ].ldctl_oid = LDAP_CONTROL_X_DEREF; 1377 1.2 christos c[ i ].ldctl_value = derefval; 1378 1.2 christos i++; 1379 1.2 christos } 1380 1.2 christos #endif /* LDAP_CONTROL_X_DEREF */ 1381 1.3 christos #ifdef LDAP_CONTROL_X_DIRSYNC 1382 1.3 christos if ( dirSync ) { 1383 1.3 christos if ( ctrl_add() ) { 1384 1.3 christos tool_exit( ld, EXIT_FAILURE ); 1385 1.3 christos } 1386 1.3 christos 1387 1.3 christos if ( ldap_create_dirsync_value( ld, 1388 1.3 christos dirSyncFlags, dirSyncMaxAttrCount, &dirSyncCookie, 1389 1.3 christos &c[i].ldctl_value ) ) 1390 1.3 christos { 1391 1.3 christos tool_exit( ld, EXIT_FAILURE ); 1392 1.3 christos } 1393 1.3 christos 1394 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_X_DIRSYNC; 1395 1.3 christos c[i].ldctl_iscritical = dirSync > 1; 1396 1.3 christos i++; 1397 1.3 christos } 1398 1.3 christos #endif 1399 1.3 christos #ifdef LDAP_CONTROL_X_EXTENDED_DN 1400 1.3 christos if ( extendedDn ) { 1401 1.3 christos if ( ctrl_add() ) { 1402 1.3 christos tool_exit( ld, EXIT_FAILURE ); 1403 1.3 christos } 1404 1.3 christos 1405 1.3 christos if ( ldap_create_extended_dn_value( ld, 1406 1.3 christos extendedDnFlag, &c[i].ldctl_value ) ) 1407 1.3 christos { 1408 1.3 christos tool_exit( ld, EXIT_FAILURE ); 1409 1.3 christos } 1410 1.3 christos 1411 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_X_EXTENDED_DN; 1412 1.3 christos c[i].ldctl_iscritical = extendedDn > 1; 1413 1.3 christos i++; 1414 1.3 christos } 1415 1.3 christos #endif 1416 1.3 christos #ifdef LDAP_CONTROL_X_SHOW_DELETED 1417 1.3 christos if ( showDeleted ) { 1418 1.3 christos if ( ctrl_add() ) { 1419 1.3 christos tool_exit( ld, EXIT_FAILURE ); 1420 1.3 christos } 1421 1.3 christos 1422 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_X_SHOW_DELETED; 1423 1.3 christos c[i].ldctl_value.bv_val = NULL; 1424 1.3 christos c[i].ldctl_value.bv_len = 0; 1425 1.3 christos c[i].ldctl_iscritical = showDeleted > 1; 1426 1.3 christos i++; 1427 1.3 christos } 1428 1.3 christos #endif 1429 1.3 christos #ifdef LDAP_CONTROL_X_SERVER_NOTIFICATION 1430 1.3 christos if ( serverNotif ) { 1431 1.3 christos if ( ctrl_add() ) { 1432 1.3 christos tool_exit( ld, EXIT_FAILURE ); 1433 1.3 christos } 1434 1.3 christos 1435 1.3 christos c[i].ldctl_oid = LDAP_CONTROL_X_SERVER_NOTIFICATION; 1436 1.3 christos c[i].ldctl_value.bv_val = NULL; 1437 1.3 christos c[i].ldctl_value.bv_len = 0; 1438 1.3 christos c[i].ldctl_iscritical = serverNotif > 1; 1439 1.3 christos i++; 1440 1.3 christos } 1441 1.3 christos #endif 1442 1.1 lukem } 1443 1.1 lukem 1444 1.1 lukem tool_server_controls( ld, c, i ); 1445 1.1 lukem 1446 1.4 christos /* free any controls we added */ 1447 1.4 christos for ( ; nctrls-- > save_nctrls; ) { 1448 1.4 christos if ( c[nctrls].ldctl_value.bv_val != derefval.bv_val ) 1449 1.4 christos ber_memfree( c[nctrls].ldctl_value.bv_val ); 1450 1.4 christos } 1451 1.1 lukem 1452 1.1 lukem /* step back to the original number of controls, so that 1453 1.1 lukem * those set while parsing args are preserved */ 1454 1.1 lukem nctrls = save_nctrls; 1455 1.1 lukem 1456 1.1 lukem if ( verbose ) { 1457 1.1 lukem fprintf( stderr, _("filter%s: %s\nrequesting: "), 1458 1.1 lukem infile != NULL ? _(" pattern") : "", 1459 1.1 lukem filtpattern ); 1460 1.1 lukem 1461 1.1 lukem if ( attrs == NULL ) { 1462 1.1 lukem fprintf( stderr, _("All userApplication attributes") ); 1463 1.1 lukem } else { 1464 1.1 lukem for ( i = 0; attrs[ i ] != NULL; ++i ) { 1465 1.1 lukem fprintf( stderr, "%s ", attrs[ i ] ); 1466 1.1 lukem } 1467 1.1 lukem } 1468 1.1 lukem fprintf( stderr, "\n" ); 1469 1.1 lukem } 1470 1.1 lukem 1471 1.1 lukem if ( ldif == 0 ) { 1472 1.1 lukem printf( _("# extended LDIF\n") ); 1473 1.1 lukem } else if ( ldif < 3 ) { 1474 1.1 lukem printf( _("version: %d\n\n"), 1 ); 1475 1.1 lukem } 1476 1.1 lukem 1477 1.1 lukem if (ldif < 2 ) { 1478 1.1 lukem char *realbase = base; 1479 1.1 lukem 1480 1.1 lukem if ( realbase == NULL ) { 1481 1.1 lukem ldap_get_option( ld, LDAP_OPT_DEFBASE, (void **)(char *)&realbase ); 1482 1.1 lukem } 1483 1.1 lukem 1484 1.1 lukem printf( "#\n" ); 1485 1.1 lukem printf(_("# LDAPv%d\n"), protocol); 1486 1.1 lukem printf(_("# base <%s>%s with scope %s\n"), 1487 1.1 lukem realbase ? realbase : "", 1488 1.1 lukem ( realbase == NULL || realbase != base ) ? " (default)" : "", 1489 1.1 lukem ((scope == LDAP_SCOPE_BASE) ? "baseObject" 1490 1.1 lukem : ((scope == LDAP_SCOPE_ONELEVEL) ? "oneLevel" 1491 1.1 lukem : ((scope == LDAP_SCOPE_SUBORDINATE) ? "children" 1492 1.1 lukem : "subtree" )))); 1493 1.1 lukem printf(_("# filter%s: %s\n"), infile != NULL ? _(" pattern") : "", 1494 1.1 lukem filtpattern); 1495 1.1 lukem printf(_("# requesting: ")); 1496 1.1 lukem 1497 1.1 lukem if ( attrs == NULL ) { 1498 1.1 lukem printf( _("ALL") ); 1499 1.1 lukem } else { 1500 1.1 lukem for ( i = 0; attrs[ i ] != NULL; ++i ) { 1501 1.1 lukem printf( "%s ", attrs[ i ] ); 1502 1.1 lukem } 1503 1.1 lukem } 1504 1.1 lukem 1505 1.1 lukem if ( manageDSAit ) { 1506 1.1 lukem printf(_("\n# with manageDSAit %scontrol"), 1507 1.1 lukem manageDSAit > 1 ? _("critical ") : "" ); 1508 1.1 lukem } 1509 1.1 lukem if ( noop ) { 1510 1.1 lukem printf(_("\n# with noop %scontrol"), 1511 1.1 lukem noop > 1 ? _("critical ") : "" ); 1512 1.1 lukem } 1513 1.1 lukem if ( subentries ) { 1514 1.1 lukem printf(_("\n# with subentries %scontrol: %s"), 1515 1.1 lukem subentries < 0 ? _("critical ") : "", 1516 1.1 lukem abs(subentries) == 1 ? "false" : "true" ); 1517 1.1 lukem } 1518 1.1 lukem if ( valuesReturnFilter ) { 1519 1.1 lukem printf(_("\n# with valuesReturnFilter %scontrol: %s"), 1520 1.1 lukem valuesReturnFilter > 1 ? _("critical ") : "", vrFilter ); 1521 1.1 lukem } 1522 1.1 lukem if ( pagedResults ) { 1523 1.1 lukem printf(_("\n# with pagedResults %scontrol: size=%d"), 1524 1.1 lukem (pagedResults > 1) ? _("critical ") : "", 1525 1.1 lukem pageSize ); 1526 1.1 lukem } 1527 1.2 christos if ( sss ) { 1528 1.2 christos printf(_("\n# with server side sorting %scontrol"), 1529 1.2 christos sss > 1 ? _("critical ") : "" ); 1530 1.2 christos } 1531 1.2 christos if ( vlv ) { 1532 1.2 christos printf(_("\n# with virtual list view %scontrol: %d/%d"), 1533 1.2 christos vlv > 1 ? _("critical ") : "", 1534 1.2 christos vlvInfo.ldvlv_before_count, vlvInfo.ldvlv_after_count); 1535 1.2 christos if ( vlvInfo.ldvlv_attrvalue ) 1536 1.2 christos printf(":%s", vlvInfo.ldvlv_attrvalue->bv_val ); 1537 1.2 christos else 1538 1.2 christos printf("/%d/%d", vlvInfo.ldvlv_offset, vlvInfo.ldvlv_count ); 1539 1.2 christos } 1540 1.2 christos #ifdef LDAP_CONTROL_X_DEREF 1541 1.2 christos if ( derefcrit ) { 1542 1.2 christos printf(_("\n# with dereference %scontrol"), 1543 1.2 christos derefcrit > 1 ? _("critical ") : "" ); 1544 1.2 christos } 1545 1.2 christos #endif 1546 1.1 lukem 1547 1.1 lukem printf( _("\n#\n\n") ); 1548 1.1 lukem 1549 1.1 lukem if ( realbase && realbase != base ) { 1550 1.1 lukem ldap_memfree( realbase ); 1551 1.1 lukem } 1552 1.1 lukem } 1553 1.1 lukem 1554 1.1 lukem if ( infile == NULL ) { 1555 1.1 lukem rc = dosearch( ld, base, scope, NULL, filtpattern, 1556 1.2 christos attrs, attrsonly, NULL, NULL, NULL, sizelimit ); 1557 1.1 lukem 1558 1.1 lukem } else { 1559 1.1 lukem rc = 0; 1560 1.1 lukem first = 1; 1561 1.1 lukem while ( fgets( line, sizeof( line ), fp ) != NULL ) { 1562 1.1 lukem line[ strlen( line ) - 1 ] = '\0'; 1563 1.1 lukem if ( !first ) { 1564 1.1 lukem putchar( '\n' ); 1565 1.1 lukem } else { 1566 1.1 lukem first = 0; 1567 1.1 lukem } 1568 1.1 lukem rc1 = dosearch( ld, base, scope, filtpattern, line, 1569 1.2 christos attrs, attrsonly, NULL, NULL, NULL, sizelimit ); 1570 1.1 lukem 1571 1.1 lukem if ( rc1 != 0 ) { 1572 1.1 lukem rc = rc1; 1573 1.1 lukem if ( !contoper ) 1574 1.1 lukem break; 1575 1.1 lukem } 1576 1.1 lukem } 1577 1.1 lukem if ( fp != stdin ) { 1578 1.1 lukem fclose( fp ); 1579 1.2 christos fp = NULL; 1580 1.1 lukem } 1581 1.1 lukem } 1582 1.1 lukem 1583 1.1 lukem if (( rc == LDAP_SUCCESS ) && pageSize && pr_morePagedResults ) { 1584 1.2 christos char buf[12]; 1585 1.1 lukem int i, moreEntries, tmpSize; 1586 1.1 lukem 1587 1.1 lukem /* Loop to get the next pages when 1588 1.1 lukem * enter is pressed on the terminal. 1589 1.1 lukem */ 1590 1.1 lukem if ( pagePrompt != 0 ) { 1591 1.1 lukem if ( entriesLeft > 0 ) { 1592 1.1 lukem printf( _("Estimate entries: %d\n"), entriesLeft ); 1593 1.1 lukem } 1594 1.1 lukem printf( _("Press [size] Enter for the next {%d|size} entries.\n"), 1595 1.1 lukem (int)pageSize ); 1596 1.1 lukem i = 0; 1597 1.1 lukem moreEntries = getchar(); 1598 1.1 lukem while ( moreEntries != EOF && moreEntries != '\n' ) { 1599 1.1 lukem if ( i < (int)sizeof(buf) - 1 ) { 1600 1.1 lukem buf[i] = moreEntries; 1601 1.1 lukem i++; 1602 1.1 lukem } 1603 1.1 lukem moreEntries = getchar(); 1604 1.1 lukem } 1605 1.1 lukem buf[i] = '\0'; 1606 1.1 lukem 1607 1.1 lukem if ( i > 0 && isdigit( (unsigned char)buf[0] ) ) { 1608 1.1 lukem int num = sscanf( buf, "%d", &tmpSize ); 1609 1.1 lukem if ( num != 1 ) { 1610 1.1 lukem fprintf( stderr, 1611 1.1 lukem _("Invalid value for PagedResultsControl, %s.\n"), buf); 1612 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1613 1.1 lukem 1614 1.1 lukem } 1615 1.1 lukem pageSize = (ber_int_t)tmpSize; 1616 1.1 lukem } 1617 1.1 lukem } 1618 1.1 lukem 1619 1.1 lukem goto getNextPage; 1620 1.1 lukem } 1621 1.1 lukem 1622 1.2 christos if (( rc == LDAP_SUCCESS ) && vlv ) { 1623 1.2 christos char buf[BUFSIZ]; 1624 1.2 christos int i, moreEntries; 1625 1.2 christos 1626 1.2 christos /* Loop to get the next window when 1627 1.2 christos * enter is pressed on the terminal. 1628 1.2 christos */ 1629 1.2 christos printf( _("Press [before/after(/offset/count|:value)] Enter for the next window.\n")); 1630 1.2 christos i = 0; 1631 1.2 christos moreEntries = getchar(); 1632 1.2 christos while ( moreEntries != EOF && moreEntries != '\n' ) { 1633 1.2 christos if ( i < (int)sizeof(buf) - 1 ) { 1634 1.2 christos buf[i] = moreEntries; 1635 1.2 christos i++; 1636 1.2 christos } 1637 1.2 christos moreEntries = getchar(); 1638 1.2 christos } 1639 1.2 christos buf[i] = '\0'; 1640 1.2 christos if ( buf[0] ) { 1641 1.2 christos i = parse_vlv( strdup( buf )); 1642 1.2 christos if ( i ) 1643 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1644 1.2 christos } else { 1645 1.2 christos vlvInfo.ldvlv_attrvalue = NULL; 1646 1.2 christos vlvInfo.ldvlv_count = vlvCount; 1647 1.2 christos vlvInfo.ldvlv_offset += vlvInfo.ldvlv_after_count; 1648 1.2 christos } 1649 1.2 christos 1650 1.2 christos if ( vlvInfo.ldvlv_context ) 1651 1.2 christos ber_bvfree( vlvInfo.ldvlv_context ); 1652 1.2 christos vlvInfo.ldvlv_context = vlvContext; 1653 1.2 christos 1654 1.2 christos goto getNextPage; 1655 1.2 christos } 1656 1.2 christos 1657 1.2 christos if ( sss_keys != NULL ) { 1658 1.2 christos ldap_free_sort_keylist( sss_keys ); 1659 1.2 christos } 1660 1.2 christos if ( derefval.bv_val != NULL ) { 1661 1.2 christos ldap_memfree( derefval.bv_val ); 1662 1.2 christos } 1663 1.2 christos if ( urlpre != NULL ) { 1664 1.2 christos if ( def_urlpre != urlpre ) 1665 1.2 christos free( def_urlpre ); 1666 1.2 christos free( urlpre ); 1667 1.2 christos } 1668 1.4 christos if ( tmpdir && tmpdir != def_tmpdir ) { 1669 1.4 christos free( tmpdir ); 1670 1.4 christos } 1671 1.1 lukem 1672 1.1 lukem if ( c ) { 1673 1.1 lukem for ( ; save_nctrls-- > 0; ) { 1674 1.1 lukem ber_memfree( c[ save_nctrls ].ldctl_value.bv_val ); 1675 1.1 lukem } 1676 1.1 lukem free( c ); 1677 1.1 lukem c = NULL; 1678 1.1 lukem } 1679 1.1 lukem 1680 1.2 christos tool_exit( ld, rc ); 1681 1.1 lukem } 1682 1.1 lukem 1683 1.1 lukem 1684 1.1 lukem static int dosearch( 1685 1.1 lukem LDAP *ld, 1686 1.1 lukem char *base, 1687 1.1 lukem int scope, 1688 1.1 lukem char *filtpatt, 1689 1.1 lukem char *value, 1690 1.1 lukem char **attrs, 1691 1.1 lukem int attrsonly, 1692 1.1 lukem LDAPControl **sctrls, 1693 1.1 lukem LDAPControl **cctrls, 1694 1.1 lukem struct timeval *timeout, 1695 1.1 lukem int sizelimit ) 1696 1.1 lukem { 1697 1.1 lukem char *filter; 1698 1.2 christos int rc, rc2 = LDAP_OTHER; 1699 1.1 lukem int nresponses; 1700 1.1 lukem int nentries; 1701 1.1 lukem int nreferences; 1702 1.1 lukem int nextended; 1703 1.1 lukem int npartial; 1704 1.1 lukem LDAPMessage *res, *msg; 1705 1.1 lukem ber_int_t msgid; 1706 1.1 lukem char *retoid = NULL; 1707 1.1 lukem struct berval *retdata = NULL; 1708 1.1 lukem int nresponses_psearch = -1; 1709 1.1 lukem int cancel_msgid = -1; 1710 1.2 christos struct timeval tv, *tvp = NULL; 1711 1.2 christos struct timeval tv_timelimit, *tv_timelimitp = NULL; 1712 1.1 lukem 1713 1.1 lukem if( filtpatt != NULL ) { 1714 1.2 christos size_t max_fsize = strlen( filtpatt ) + strlen( value ) + 1, outlen; 1715 1.1 lukem filter = malloc( max_fsize ); 1716 1.1 lukem if( filter == NULL ) { 1717 1.1 lukem perror( "malloc" ); 1718 1.1 lukem return EXIT_FAILURE; 1719 1.1 lukem } 1720 1.1 lukem 1721 1.2 christos outlen = snprintf( filter, max_fsize, filtpatt, value ); 1722 1.2 christos if( outlen >= max_fsize ) { 1723 1.1 lukem fprintf( stderr, "Bad filter pattern: \"%s\"\n", filtpatt ); 1724 1.1 lukem free( filter ); 1725 1.1 lukem return EXIT_FAILURE; 1726 1.1 lukem } 1727 1.1 lukem 1728 1.1 lukem if ( verbose ) { 1729 1.1 lukem fprintf( stderr, _("filter: %s\n"), filter ); 1730 1.1 lukem } 1731 1.1 lukem 1732 1.1 lukem if( ldif < 2 ) { 1733 1.1 lukem printf( _("#\n# filter: %s\n#\n"), filter ); 1734 1.1 lukem } 1735 1.1 lukem 1736 1.1 lukem } else { 1737 1.1 lukem filter = value; 1738 1.1 lukem } 1739 1.1 lukem 1740 1.1 lukem if ( dont ) { 1741 1.1 lukem if ( filtpatt != NULL ) { 1742 1.1 lukem free( filter ); 1743 1.1 lukem } 1744 1.1 lukem return LDAP_SUCCESS; 1745 1.1 lukem } 1746 1.1 lukem 1747 1.2 christos if ( timelimit > 0 ) { 1748 1.2 christos tv_timelimit.tv_sec = timelimit; 1749 1.2 christos tv_timelimit.tv_usec = 0; 1750 1.2 christos tv_timelimitp = &tv_timelimit; 1751 1.2 christos } 1752 1.2 christos 1753 1.3 christos again: 1754 1.1 lukem rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly, 1755 1.2 christos sctrls, cctrls, tv_timelimitp, sizelimit, &msgid ); 1756 1.1 lukem 1757 1.1 lukem if ( filtpatt != NULL ) { 1758 1.1 lukem free( filter ); 1759 1.1 lukem } 1760 1.1 lukem 1761 1.1 lukem if( rc != LDAP_SUCCESS ) { 1762 1.2 christos tool_perror( "ldap_search_ext", rc, NULL, NULL, NULL, NULL ); 1763 1.1 lukem return( rc ); 1764 1.1 lukem } 1765 1.1 lukem 1766 1.1 lukem nresponses = nentries = nreferences = nextended = npartial = 0; 1767 1.1 lukem 1768 1.1 lukem res = NULL; 1769 1.1 lukem 1770 1.2 christos if ( timelimit > 0 ) { 1771 1.2 christos /* disable timeout */ 1772 1.2 christos tv.tv_sec = -1; 1773 1.2 christos tv.tv_usec = 0; 1774 1.2 christos tvp = &tv; 1775 1.2 christos } 1776 1.2 christos 1777 1.3 christos if ( backlog == 1 ) { 1778 1.3 christos printf( _("\nWaiting for responses to accumulate, press Enter to continue: ")); 1779 1.3 christos fflush( stdout ); 1780 1.3 christos getchar(); 1781 1.3 christos printf( _("Abandoning msgid %d\n"), msgid ); 1782 1.3 christos ldap_abandon_ext( ld, msgid, NULL, NULL ); 1783 1.3 christos /* turn off syncrepl control */ 1784 1.3 christos ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, NULL ); 1785 1.3 christos backlog = 2; 1786 1.3 christos scope = LDAP_SCOPE_BASE; 1787 1.3 christos goto again; 1788 1.3 christos } else if ( backlog == 2 ) { 1789 1.3 christos tv.tv_sec = timelimit; 1790 1.3 christos } 1791 1.3 christos 1792 1.1 lukem while ((rc = ldap_result( ld, LDAP_RES_ANY, 1793 1.1 lukem sortattr ? LDAP_MSG_ALL : LDAP_MSG_ONE, 1794 1.2 christos tvp, &res )) > 0 ) 1795 1.1 lukem { 1796 1.2 christos if ( tool_check_abandon( ld, msgid ) ) { 1797 1.2 christos return -1; 1798 1.1 lukem } 1799 1.1 lukem 1800 1.1 lukem if( sortattr ) { 1801 1.1 lukem (void) ldap_sort_entries( ld, &res, 1802 1.1 lukem ( *sortattr == '\0' ) ? NULL : sortattr, strcasecmp ); 1803 1.1 lukem } 1804 1.1 lukem 1805 1.1 lukem for ( msg = ldap_first_message( ld, res ); 1806 1.1 lukem msg != NULL; 1807 1.1 lukem msg = ldap_next_message( ld, msg ) ) 1808 1.1 lukem { 1809 1.1 lukem if ( nresponses++ ) putchar('\n'); 1810 1.1 lukem if ( nresponses_psearch >= 0 ) 1811 1.1 lukem nresponses_psearch++; 1812 1.1 lukem 1813 1.1 lukem switch( ldap_msgtype( msg ) ) { 1814 1.1 lukem case LDAP_RES_SEARCH_ENTRY: 1815 1.1 lukem nentries++; 1816 1.1 lukem print_entry( ld, msg, attrsonly ); 1817 1.1 lukem break; 1818 1.1 lukem 1819 1.1 lukem case LDAP_RES_SEARCH_REFERENCE: 1820 1.1 lukem nreferences++; 1821 1.1 lukem print_reference( ld, msg ); 1822 1.1 lukem break; 1823 1.1 lukem 1824 1.1 lukem case LDAP_RES_EXTENDED: 1825 1.1 lukem nextended++; 1826 1.1 lukem print_extended( ld, msg ); 1827 1.1 lukem 1828 1.1 lukem if ( ldap_msgid( msg ) == 0 ) { 1829 1.1 lukem /* unsolicited extended operation */ 1830 1.1 lukem goto done; 1831 1.1 lukem } 1832 1.1 lukem 1833 1.1 lukem if ( cancel_msgid != -1 && 1834 1.1 lukem cancel_msgid == ldap_msgid( msg ) ) { 1835 1.1 lukem printf(_("Cancelled \n")); 1836 1.1 lukem printf(_("cancel_msgid = %d\n"), cancel_msgid); 1837 1.1 lukem goto done; 1838 1.1 lukem } 1839 1.1 lukem break; 1840 1.1 lukem 1841 1.1 lukem case LDAP_RES_SEARCH_RESULT: 1842 1.1 lukem /* pagedResults stuff is dealt with 1843 1.1 lukem * in tool_print_ctrls(), called by 1844 1.1 lukem * print_results(). */ 1845 1.2 christos rc2 = print_result( ld, msg, 1 ); 1846 1.1 lukem if ( ldapsync == LDAP_SYNC_REFRESH_AND_PERSIST ) { 1847 1.1 lukem break; 1848 1.1 lukem } 1849 1.1 lukem 1850 1.1 lukem goto done; 1851 1.1 lukem 1852 1.1 lukem case LDAP_RES_INTERMEDIATE: 1853 1.1 lukem npartial++; 1854 1.1 lukem ldap_parse_intermediate( ld, msg, 1855 1.1 lukem &retoid, &retdata, NULL, 0 ); 1856 1.1 lukem 1857 1.1 lukem nresponses_psearch = 0; 1858 1.1 lukem 1859 1.1 lukem if ( strcmp( retoid, LDAP_SYNC_INFO ) == 0 ) { 1860 1.3 christos if ( ldif < 1 ) { 1861 1.3 christos print_syncinfo( retdata ); 1862 1.3 christos } else if ( ldif < 2 ) { 1863 1.3 christos printf(_("# SyncInfo Received\n")); 1864 1.3 christos } 1865 1.1 lukem ldap_memfree( retoid ); 1866 1.1 lukem ber_bvfree( retdata ); 1867 1.1 lukem break; 1868 1.1 lukem } 1869 1.1 lukem 1870 1.1 lukem print_partial( ld, msg ); 1871 1.1 lukem ldap_memfree( retoid ); 1872 1.1 lukem ber_bvfree( retdata ); 1873 1.1 lukem goto done; 1874 1.1 lukem } 1875 1.1 lukem 1876 1.1 lukem if ( ldapsync && sync_slimit != -1 && 1877 1.1 lukem nresponses_psearch >= sync_slimit ) { 1878 1.1 lukem BerElement *msgidber = NULL; 1879 1.4 christos struct berval msgidval; 1880 1.1 lukem msgidber = ber_alloc_t(LBER_USE_DER); 1881 1.1 lukem ber_printf(msgidber, "{i}", msgid); 1882 1.4 christos ber_flatten2( msgidber, &msgidval, 0 ); 1883 1.1 lukem ldap_extended_operation(ld, LDAP_EXOP_CANCEL, 1884 1.4 christos &msgidval, NULL, NULL, &cancel_msgid); 1885 1.4 christos ber_free( msgidber, 1 ); 1886 1.1 lukem nresponses_psearch = -1; 1887 1.1 lukem } 1888 1.1 lukem } 1889 1.1 lukem 1890 1.1 lukem ldap_msgfree( res ); 1891 1.2 christos fflush( stdout ); 1892 1.1 lukem } 1893 1.1 lukem 1894 1.1 lukem done: 1895 1.2 christos if ( tvp == NULL && rc != LDAP_RES_SEARCH_RESULT ) { 1896 1.2 christos ldap_get_option( ld, LDAP_OPT_RESULT_CODE, (void *)&rc2 ); 1897 1.1 lukem } 1898 1.1 lukem 1899 1.1 lukem ldap_msgfree( res ); 1900 1.1 lukem 1901 1.1 lukem if ( pagedResults ) { 1902 1.1 lukem npagedresponses += nresponses; 1903 1.1 lukem npagedentries += nentries; 1904 1.1 lukem npagedextended += nextended; 1905 1.1 lukem npagedpartial += npartial; 1906 1.1 lukem npagedreferences += nreferences; 1907 1.1 lukem if ( ( pr_morePagedResults == 0 ) && ( ldif < 2 ) ) { 1908 1.1 lukem printf( _("\n# numResponses: %d\n"), npagedresponses ); 1909 1.1 lukem if( npagedentries ) { 1910 1.1 lukem printf( _("# numEntries: %d\n"), npagedentries ); 1911 1.1 lukem } 1912 1.1 lukem if( npagedextended ) { 1913 1.1 lukem printf( _("# numExtended: %d\n"), npagedextended ); 1914 1.1 lukem } 1915 1.1 lukem if( npagedpartial ) { 1916 1.1 lukem printf( _("# numPartial: %d\n"), npagedpartial ); 1917 1.1 lukem } 1918 1.1 lukem if( npagedreferences ) { 1919 1.1 lukem printf( _("# numReferences: %d\n"), npagedreferences ); 1920 1.1 lukem } 1921 1.1 lukem } 1922 1.1 lukem } else if ( ldif < 2 ) { 1923 1.1 lukem printf( _("\n# numResponses: %d\n"), nresponses ); 1924 1.1 lukem if( nentries ) printf( _("# numEntries: %d\n"), nentries ); 1925 1.1 lukem if( nextended ) printf( _("# numExtended: %d\n"), nextended ); 1926 1.1 lukem if( npartial ) printf( _("# numPartial: %d\n"), npartial ); 1927 1.1 lukem if( nreferences ) printf( _("# numReferences: %d\n"), nreferences ); 1928 1.1 lukem } 1929 1.1 lukem 1930 1.2 christos if ( rc != LDAP_RES_SEARCH_RESULT ) { 1931 1.2 christos tool_perror( "ldap_result", rc2, NULL, NULL, NULL, NULL ); 1932 1.2 christos } 1933 1.2 christos 1934 1.2 christos return( rc2 ); 1935 1.1 lukem } 1936 1.1 lukem 1937 1.1 lukem /* This is the proposed new way of doing things. 1938 1.1 lukem * It is more efficient, but the API is non-standard. 1939 1.1 lukem */ 1940 1.1 lukem static void 1941 1.1 lukem print_entry( 1942 1.1 lukem LDAP *ld, 1943 1.1 lukem LDAPMessage *entry, 1944 1.1 lukem int attrsonly) 1945 1.1 lukem { 1946 1.1 lukem char *ufn = NULL; 1947 1.1 lukem char tmpfname[ 256 ]; 1948 1.1 lukem char url[ 256 ]; 1949 1.1 lukem int i, rc; 1950 1.1 lukem BerElement *ber = NULL; 1951 1.1 lukem struct berval bv, *bvals, **bvp = &bvals; 1952 1.1 lukem LDAPControl **ctrls = NULL; 1953 1.1 lukem FILE *tmpfp; 1954 1.1 lukem 1955 1.1 lukem rc = ldap_get_dn_ber( ld, entry, &ber, &bv ); 1956 1.1 lukem 1957 1.1 lukem if ( ldif < 2 ) { 1958 1.1 lukem ufn = ldap_dn2ufn( bv.bv_val ); 1959 1.1 lukem tool_write_ldif( LDIF_PUT_COMMENT, NULL, ufn, ufn ? strlen( ufn ) : 0 ); 1960 1.1 lukem } 1961 1.1 lukem tool_write_ldif( LDIF_PUT_VALUE, "dn", bv.bv_val, bv.bv_len ); 1962 1.1 lukem 1963 1.1 lukem rc = ldap_get_entry_controls( ld, entry, &ctrls ); 1964 1.1 lukem if( rc != LDAP_SUCCESS ) { 1965 1.1 lukem fprintf(stderr, _("print_entry: %d\n"), rc ); 1966 1.1 lukem tool_perror( "ldap_get_entry_controls", rc, NULL, NULL, NULL, NULL ); 1967 1.2 christos tool_exit( ld, EXIT_FAILURE ); 1968 1.1 lukem } 1969 1.1 lukem 1970 1.1 lukem if( ctrls ) { 1971 1.1 lukem tool_print_ctrls( ld, ctrls ); 1972 1.1 lukem ldap_controls_free( ctrls ); 1973 1.1 lukem } 1974 1.1 lukem 1975 1.1 lukem if ( includeufn ) { 1976 1.1 lukem if( ufn == NULL ) { 1977 1.1 lukem ufn = ldap_dn2ufn( bv.bv_val ); 1978 1.1 lukem } 1979 1.1 lukem tool_write_ldif( LDIF_PUT_VALUE, "ufn", ufn, ufn ? strlen( ufn ) : 0 ); 1980 1.1 lukem } 1981 1.1 lukem 1982 1.1 lukem if( ufn != NULL ) ldap_memfree( ufn ); 1983 1.1 lukem 1984 1.1 lukem if ( attrsonly ) bvp = NULL; 1985 1.1 lukem 1986 1.1 lukem for ( rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp ); 1987 1.1 lukem rc == LDAP_SUCCESS; 1988 1.1 lukem rc = ldap_get_attribute_ber( ld, entry, ber, &bv, bvp ) ) 1989 1.1 lukem { 1990 1.1 lukem if (bv.bv_val == NULL) break; 1991 1.1 lukem 1992 1.1 lukem if ( attrsonly ) { 1993 1.1 lukem tool_write_ldif( LDIF_PUT_NOVALUE, bv.bv_val, NULL, 0 ); 1994 1.1 lukem 1995 1.1 lukem } else if ( bvals ) { 1996 1.1 lukem for ( i = 0; bvals[i].bv_val != NULL; i++ ) { 1997 1.1 lukem if ( vals2tmp > 1 || ( vals2tmp && 1998 1.1 lukem ldif_is_not_printable( bvals[i].bv_val, bvals[i].bv_len ))) 1999 1.1 lukem { 2000 1.1 lukem int tmpfd; 2001 1.1 lukem /* write value to file */ 2002 1.1 lukem snprintf( tmpfname, sizeof tmpfname, 2003 1.1 lukem "%s" LDAP_DIRSEP "ldapsearch-%s-XXXXXX", 2004 1.1 lukem tmpdir, bv.bv_val ); 2005 1.1 lukem tmpfp = NULL; 2006 1.1 lukem 2007 1.1 lukem tmpfd = mkstemp( tmpfname ); 2008 1.1 lukem 2009 1.1 lukem if ( tmpfd < 0 ) { 2010 1.1 lukem perror( tmpfname ); 2011 1.1 lukem continue; 2012 1.1 lukem } 2013 1.1 lukem 2014 1.1 lukem if (( tmpfp = fdopen( tmpfd, "w")) == NULL ) { 2015 1.1 lukem perror( tmpfname ); 2016 1.1 lukem continue; 2017 1.1 lukem } 2018 1.1 lukem 2019 1.1 lukem if ( fwrite( bvals[ i ].bv_val, 2020 1.1 lukem bvals[ i ].bv_len, 1, tmpfp ) == 0 ) 2021 1.1 lukem { 2022 1.1 lukem perror( tmpfname ); 2023 1.1 lukem fclose( tmpfp ); 2024 1.1 lukem continue; 2025 1.1 lukem } 2026 1.1 lukem 2027 1.1 lukem fclose( tmpfp ); 2028 1.1 lukem 2029 1.1 lukem snprintf( url, sizeof url, "%s%s", urlpre, 2030 1.1 lukem &tmpfname[strlen(tmpdir) + sizeof(LDAP_DIRSEP) - 1] ); 2031 1.1 lukem 2032 1.1 lukem urlize( url ); 2033 1.1 lukem tool_write_ldif( LDIF_PUT_URL, bv.bv_val, url, strlen( url )); 2034 1.1 lukem 2035 1.1 lukem } else { 2036 1.1 lukem tool_write_ldif( LDIF_PUT_VALUE, bv.bv_val, 2037 1.1 lukem bvals[ i ].bv_val, bvals[ i ].bv_len ); 2038 1.1 lukem } 2039 1.1 lukem } 2040 1.1 lukem ber_memfree( bvals ); 2041 1.1 lukem } 2042 1.1 lukem } 2043 1.1 lukem 2044 1.1 lukem if( ber != NULL ) { 2045 1.1 lukem ber_free( ber, 0 ); 2046 1.1 lukem } 2047 1.1 lukem } 2048 1.1 lukem 2049 1.1 lukem static void print_reference( 2050 1.1 lukem LDAP *ld, 2051 1.1 lukem LDAPMessage *reference ) 2052 1.1 lukem { 2053 1.1 lukem int rc; 2054 1.1 lukem char **refs = NULL; 2055 1.1 lukem LDAPControl **ctrls; 2056 1.1 lukem 2057 1.1 lukem if( ldif < 2 ) { 2058 1.1 lukem printf(_("# search reference\n")); 2059 1.1 lukem } 2060 1.1 lukem 2061 1.1 lukem rc = ldap_parse_reference( ld, reference, &refs, &ctrls, 0 ); 2062 1.1 lukem 2063 1.1 lukem if( rc != LDAP_SUCCESS ) { 2064 1.1 lukem tool_perror( "ldap_parse_reference", rc, NULL, NULL, NULL, NULL ); 2065 1.2 christos tool_exit( ld, EXIT_FAILURE ); 2066 1.1 lukem } 2067 1.1 lukem 2068 1.1 lukem if( refs ) { 2069 1.1 lukem int i; 2070 1.1 lukem for( i=0; refs[i] != NULL; i++ ) { 2071 1.1 lukem tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE, 2072 1.1 lukem "ref", refs[i], strlen(refs[i]) ); 2073 1.1 lukem } 2074 1.1 lukem ber_memvfree( (void **) refs ); 2075 1.1 lukem } 2076 1.1 lukem 2077 1.1 lukem if( ctrls ) { 2078 1.1 lukem tool_print_ctrls( ld, ctrls ); 2079 1.1 lukem ldap_controls_free( ctrls ); 2080 1.1 lukem } 2081 1.1 lukem } 2082 1.1 lukem 2083 1.1 lukem static void print_extended( 2084 1.1 lukem LDAP *ld, 2085 1.1 lukem LDAPMessage *extended ) 2086 1.1 lukem { 2087 1.1 lukem int rc; 2088 1.1 lukem char *retoid = NULL; 2089 1.1 lukem struct berval *retdata = NULL; 2090 1.1 lukem 2091 1.1 lukem if( ldif < 2 ) { 2092 1.1 lukem printf(_("# extended result response\n")); 2093 1.1 lukem } 2094 1.1 lukem 2095 1.1 lukem rc = ldap_parse_extended_result( ld, extended, 2096 1.1 lukem &retoid, &retdata, 0 ); 2097 1.1 lukem 2098 1.1 lukem if( rc != LDAP_SUCCESS ) { 2099 1.1 lukem tool_perror( "ldap_parse_extended_result", rc, NULL, NULL, NULL, NULL ); 2100 1.2 christos tool_exit( ld, EXIT_FAILURE ); 2101 1.1 lukem } 2102 1.1 lukem 2103 1.1 lukem if ( ldif < 2 ) { 2104 1.1 lukem tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE, 2105 1.1 lukem "extended", retoid, retoid ? strlen(retoid) : 0 ); 2106 1.1 lukem } 2107 1.1 lukem ber_memfree( retoid ); 2108 1.1 lukem 2109 1.1 lukem if(retdata) { 2110 1.1 lukem if ( ldif < 2 ) { 2111 1.1 lukem tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY, 2112 1.1 lukem "data", retdata->bv_val, retdata->bv_len ); 2113 1.1 lukem } 2114 1.1 lukem ber_bvfree( retdata ); 2115 1.1 lukem } 2116 1.1 lukem 2117 1.1 lukem print_result( ld, extended, 0 ); 2118 1.1 lukem } 2119 1.1 lukem 2120 1.3 christos static void print_syncinfo( 2121 1.3 christos BerValue *data ) 2122 1.3 christos { 2123 1.3 christos BerElement *syncinfo; 2124 1.3 christos struct berval bv, cookie; 2125 1.3 christos ber_tag_t tag; 2126 1.3 christos ber_len_t len; 2127 1.3 christos 2128 1.3 christos if ( (syncinfo = ber_alloc()) == NULL ) { 2129 1.3 christos return; 2130 1.3 christos } 2131 1.3 christos ber_init2( syncinfo, data, 0 ); 2132 1.3 christos 2133 1.3 christos printf(_("# SyncInfo Received: ")); 2134 1.3 christos tag = ber_peek_tag( syncinfo, &len ); 2135 1.3 christos switch (tag) { 2136 1.3 christos case LDAP_TAG_SYNC_NEW_COOKIE: { 2137 1.3 christos printf(_("new cookie\n")); 2138 1.3 christos ber_scanf( syncinfo, "m", &cookie ); 2139 1.3 christos 2140 1.3 christos if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) { 2141 1.3 christos bv.bv_len = LUTIL_BASE64_ENCODE_LEN( 2142 1.3 christos cookie.bv_len ) + 1; 2143 1.3 christos bv.bv_val = ber_memalloc( bv.bv_len + 1 ); 2144 1.3 christos 2145 1.3 christos bv.bv_len = lutil_b64_ntop( 2146 1.3 christos (unsigned char *) cookie.bv_val, 2147 1.3 christos cookie.bv_len, 2148 1.3 christos bv.bv_val, bv.bv_len ); 2149 1.3 christos 2150 1.3 christos printf(_("# cookie:: %s\n"), bv.bv_val ); 2151 1.3 christos ber_memfree( bv.bv_val ); 2152 1.3 christos } else { 2153 1.3 christos printf(_("# cookie: %s\n"), cookie.bv_val ); 2154 1.3 christos } 2155 1.3 christos } break; 2156 1.3 christos case LDAP_TAG_SYNC_REFRESH_DELETE: { 2157 1.3 christos ber_int_t done = 1; 2158 1.3 christos 2159 1.3 christos printf(_("refresh delete\n")); 2160 1.3 christos /* Skip sequence tag first */ 2161 1.3 christos ber_skip_tag( syncinfo, &len ); 2162 1.3 christos 2163 1.3 christos tag = ber_peek_tag( syncinfo, &len ); 2164 1.3 christos if ( tag == LDAP_TAG_SYNC_COOKIE ) { 2165 1.3 christos ber_scanf( syncinfo, "m", &cookie ); 2166 1.3 christos 2167 1.3 christos if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) { 2168 1.3 christos bv.bv_len = LUTIL_BASE64_ENCODE_LEN( 2169 1.3 christos cookie.bv_len ) + 1; 2170 1.3 christos bv.bv_val = ber_memalloc( bv.bv_len + 1 ); 2171 1.3 christos 2172 1.3 christos bv.bv_len = lutil_b64_ntop( 2173 1.3 christos (unsigned char *) cookie.bv_val, 2174 1.3 christos cookie.bv_len, 2175 1.3 christos bv.bv_val, bv.bv_len ); 2176 1.3 christos 2177 1.3 christos printf(_("# cookie:: %s\n"), bv.bv_val ); 2178 1.3 christos ber_memfree( bv.bv_val ); 2179 1.3 christos } else { 2180 1.3 christos printf(_("# cookie: %s\n"), cookie.bv_val ); 2181 1.3 christos } 2182 1.3 christos 2183 1.3 christos tag = ber_peek_tag( syncinfo, &len ); 2184 1.3 christos } 2185 1.3 christos if ( tag == LDAP_TAG_REFRESHDONE ) { 2186 1.3 christos ber_get_boolean( syncinfo, &done ); 2187 1.3 christos } 2188 1.3 christos if ( done ) 2189 1.3 christos printf(_("# refresh done, switching to persist stage\n")); 2190 1.3 christos } break; 2191 1.3 christos case LDAP_TAG_SYNC_REFRESH_PRESENT: { 2192 1.3 christos ber_int_t done = 1; 2193 1.3 christos 2194 1.3 christos printf(_("refresh present\n")); 2195 1.3 christos /* Skip sequence tag first */ 2196 1.3 christos ber_skip_tag( syncinfo, &len ); 2197 1.3 christos 2198 1.3 christos tag = ber_peek_tag( syncinfo, &len ); 2199 1.3 christos if ( tag == LDAP_TAG_SYNC_COOKIE ) { 2200 1.3 christos ber_scanf( syncinfo, "m", &cookie ); 2201 1.3 christos 2202 1.3 christos if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) { 2203 1.3 christos bv.bv_len = LUTIL_BASE64_ENCODE_LEN( 2204 1.3 christos cookie.bv_len ) + 1; 2205 1.3 christos bv.bv_val = ber_memalloc( bv.bv_len + 1 ); 2206 1.3 christos 2207 1.3 christos bv.bv_len = lutil_b64_ntop( 2208 1.3 christos (unsigned char *) cookie.bv_val, 2209 1.3 christos cookie.bv_len, 2210 1.3 christos bv.bv_val, bv.bv_len ); 2211 1.3 christos 2212 1.3 christos printf(_("# cookie:: %s\n"), bv.bv_val ); 2213 1.3 christos ber_memfree( bv.bv_val ); 2214 1.3 christos } else { 2215 1.3 christos printf(_("# cookie: %s\n"), cookie.bv_val ); 2216 1.3 christos } 2217 1.3 christos 2218 1.3 christos tag = ber_peek_tag( syncinfo, &len ); 2219 1.3 christos } 2220 1.3 christos if ( tag == LDAP_TAG_REFRESHDONE ) { 2221 1.3 christos ber_get_boolean( syncinfo, &done ); 2222 1.3 christos } 2223 1.3 christos if ( done ) 2224 1.3 christos printf(_("# refresh done, switching to persist stage\n")); 2225 1.3 christos } break; 2226 1.3 christos case LDAP_TAG_SYNC_ID_SET: { 2227 1.3 christos ber_int_t refreshDeletes = 0; 2228 1.3 christos BerVarray uuids; 2229 1.3 christos 2230 1.3 christos printf(_("ID Set\n")); 2231 1.3 christos /* Skip sequence tag first */ 2232 1.3 christos ber_skip_tag( syncinfo, &len ); 2233 1.3 christos 2234 1.3 christos tag = ber_peek_tag( syncinfo, &len ); 2235 1.3 christos if ( tag == LDAP_TAG_SYNC_COOKIE ) { 2236 1.3 christos ber_scanf( syncinfo, "m", &cookie ); 2237 1.3 christos 2238 1.3 christos if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) { 2239 1.3 christos bv.bv_len = LUTIL_BASE64_ENCODE_LEN( 2240 1.3 christos cookie.bv_len ) + 1; 2241 1.3 christos bv.bv_val = ber_memalloc( bv.bv_len + 1 ); 2242 1.3 christos 2243 1.3 christos bv.bv_len = lutil_b64_ntop( 2244 1.3 christos (unsigned char *) cookie.bv_val, 2245 1.3 christos cookie.bv_len, 2246 1.3 christos bv.bv_val, bv.bv_len ); 2247 1.3 christos 2248 1.3 christos printf(_("# cookie:: %s\n"), bv.bv_val ); 2249 1.3 christos ber_memfree( bv.bv_val ); 2250 1.3 christos } else { 2251 1.3 christos printf(_("# cookie: %s\n"), cookie.bv_val ); 2252 1.3 christos } 2253 1.3 christos 2254 1.3 christos tag = ber_peek_tag( syncinfo, &len ); 2255 1.3 christos } 2256 1.3 christos if ( tag == LDAP_TAG_REFRESHDELETES ) { 2257 1.3 christos ber_get_boolean( syncinfo, &refreshDeletes ); 2258 1.3 christos tag = ber_peek_tag( syncinfo, &len ); 2259 1.3 christos } 2260 1.3 christos if ( refreshDeletes ) { 2261 1.3 christos printf(_("# following UUIDs no longer match the search\n")); 2262 1.3 christos } 2263 1.3 christos 2264 1.3 christos printf(_("# syncUUIDs:\n")); 2265 1.3 christos ber_scanf( syncinfo, "[W]", &uuids ); 2266 1.3 christos if ( uuids ) { 2267 1.3 christos char buf[LDAP_LUTIL_UUIDSTR_BUFSIZE]; 2268 1.3 christos int i; 2269 1.3 christos 2270 1.3 christos for ( i=0; !BER_BVISNULL( &uuids[i] ); i++ ) { 2271 1.3 christos int rc = lutil_uuidstr_from_normalized( 2272 1.3 christos uuids[i].bv_val, uuids[i].bv_len, 2273 1.3 christos buf, LDAP_LUTIL_UUIDSTR_BUFSIZE ); 2274 1.3 christos if ( rc <= 0 || rc >= LDAP_LUTIL_UUIDSTR_BUFSIZE ) { 2275 1.3 christos printf(_("#\t(UUID malformed)\n")); 2276 1.3 christos } else { 2277 1.3 christos printf(_("#\t%s\n"), buf); 2278 1.3 christos } 2279 1.3 christos } 2280 1.3 christos ber_bvarray_free( uuids ); 2281 1.3 christos } 2282 1.3 christos } break; 2283 1.3 christos case LBER_DEFAULT: 2284 1.3 christos printf(_("empty SyncInfoValue\n")); 2285 1.3 christos default: 2286 1.3 christos printf(_("SyncInfoValue unknown\n")); 2287 1.3 christos break; 2288 1.3 christos } 2289 1.3 christos ber_free( syncinfo, 0 ); 2290 1.3 christos } 2291 1.3 christos 2292 1.1 lukem static void print_partial( 2293 1.1 lukem LDAP *ld, 2294 1.1 lukem LDAPMessage *partial ) 2295 1.1 lukem { 2296 1.1 lukem int rc; 2297 1.1 lukem char *retoid = NULL; 2298 1.1 lukem struct berval *retdata = NULL; 2299 1.1 lukem LDAPControl **ctrls = NULL; 2300 1.1 lukem 2301 1.1 lukem if( ldif < 2 ) { 2302 1.1 lukem printf(_("# extended partial response\n")); 2303 1.1 lukem } 2304 1.1 lukem 2305 1.1 lukem rc = ldap_parse_intermediate( ld, partial, 2306 1.1 lukem &retoid, &retdata, &ctrls, 0 ); 2307 1.1 lukem 2308 1.1 lukem if( rc != LDAP_SUCCESS ) { 2309 1.1 lukem tool_perror( "ldap_parse_intermediate", rc, NULL, NULL, NULL, NULL ); 2310 1.2 christos tool_exit( ld, EXIT_FAILURE ); 2311 1.1 lukem } 2312 1.1 lukem 2313 1.1 lukem if ( ldif < 2 ) { 2314 1.1 lukem tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE, 2315 1.1 lukem "partial", retoid, retoid ? strlen(retoid) : 0 ); 2316 1.1 lukem } 2317 1.1 lukem 2318 1.1 lukem ber_memfree( retoid ); 2319 1.1 lukem 2320 1.1 lukem if( retdata ) { 2321 1.1 lukem if ( ldif < 2 ) { 2322 1.1 lukem tool_write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY, 2323 1.1 lukem "data", retdata->bv_val, retdata->bv_len ); 2324 1.1 lukem } 2325 1.1 lukem 2326 1.1 lukem ber_bvfree( retdata ); 2327 1.1 lukem } 2328 1.1 lukem 2329 1.1 lukem if( ctrls ) { 2330 1.1 lukem tool_print_ctrls( ld, ctrls ); 2331 1.1 lukem ldap_controls_free( ctrls ); 2332 1.1 lukem } 2333 1.1 lukem } 2334 1.1 lukem 2335 1.1 lukem static int print_result( 2336 1.1 lukem LDAP *ld, 2337 1.1 lukem LDAPMessage *result, int search ) 2338 1.1 lukem { 2339 1.1 lukem int rc; 2340 1.1 lukem int err; 2341 1.1 lukem char *matcheddn = NULL; 2342 1.1 lukem char *text = NULL; 2343 1.1 lukem char **refs = NULL; 2344 1.1 lukem LDAPControl **ctrls = NULL; 2345 1.1 lukem 2346 1.1 lukem if( search ) { 2347 1.1 lukem if ( ldif < 2 ) { 2348 1.1 lukem printf(_("# search result\n")); 2349 1.1 lukem } 2350 1.1 lukem if ( ldif < 1 ) { 2351 1.1 lukem printf("%s: %d\n", _("search"), ldap_msgid(result) ); 2352 1.1 lukem } 2353 1.1 lukem } 2354 1.1 lukem 2355 1.1 lukem rc = ldap_parse_result( ld, result, 2356 1.1 lukem &err, &matcheddn, &text, &refs, &ctrls, 0 ); 2357 1.1 lukem 2358 1.1 lukem if( rc != LDAP_SUCCESS ) { 2359 1.1 lukem tool_perror( "ldap_parse_result", rc, NULL, NULL, NULL, NULL ); 2360 1.2 christos tool_exit( ld, EXIT_FAILURE ); 2361 1.1 lukem } 2362 1.1 lukem 2363 1.1 lukem 2364 1.1 lukem if( !ldif ) { 2365 1.1 lukem printf( _("result: %d %s\n"), err, ldap_err2string(err) ); 2366 1.1 lukem 2367 1.1 lukem } else if ( err != LDAP_SUCCESS ) { 2368 1.1 lukem fprintf( stderr, "%s (%d)\n", ldap_err2string(err), err ); 2369 1.1 lukem } 2370 1.1 lukem 2371 1.1 lukem if( matcheddn ) { 2372 1.1 lukem if( *matcheddn ) { 2373 1.1 lukem if( !ldif ) { 2374 1.1 lukem tool_write_ldif( LDIF_PUT_VALUE, 2375 1.1 lukem "matchedDN", matcheddn, strlen(matcheddn) ); 2376 1.1 lukem } else { 2377 1.1 lukem fprintf( stderr, _("Matched DN: %s\n"), matcheddn ); 2378 1.1 lukem } 2379 1.1 lukem } 2380 1.1 lukem 2381 1.1 lukem ber_memfree( matcheddn ); 2382 1.1 lukem } 2383 1.1 lukem 2384 1.1 lukem if( text ) { 2385 1.1 lukem if( *text ) { 2386 1.1 lukem if( !ldif ) { 2387 1.1 lukem if ( err == LDAP_PARTIAL_RESULTS ) { 2388 1.1 lukem char *line; 2389 1.1 lukem 2390 1.1 lukem for ( line = text; line != NULL; ) { 2391 1.1 lukem char *next = strchr( line, '\n' ); 2392 1.1 lukem 2393 1.1 lukem tool_write_ldif( LDIF_PUT_TEXT, 2394 1.1 lukem "text", line, 2395 1.2 christos next ? (size_t) (next - line) : strlen( line )); 2396 1.1 lukem 2397 1.1 lukem line = next ? next + 1 : NULL; 2398 1.1 lukem } 2399 1.1 lukem 2400 1.1 lukem } else { 2401 1.1 lukem tool_write_ldif( LDIF_PUT_TEXT, "text", 2402 1.1 lukem text, strlen(text) ); 2403 1.1 lukem } 2404 1.1 lukem } else { 2405 1.1 lukem fprintf( stderr, _("Additional information: %s\n"), text ); 2406 1.1 lukem } 2407 1.1 lukem } 2408 1.1 lukem 2409 1.1 lukem ber_memfree( text ); 2410 1.1 lukem } 2411 1.1 lukem 2412 1.1 lukem if( refs ) { 2413 1.1 lukem int i; 2414 1.1 lukem for( i=0; refs[i] != NULL; i++ ) { 2415 1.1 lukem if( !ldif ) { 2416 1.1 lukem tool_write_ldif( LDIF_PUT_VALUE, "ref", refs[i], strlen(refs[i]) ); 2417 1.1 lukem } else { 2418 1.1 lukem fprintf( stderr, _("Referral: %s\n"), refs[i] ); 2419 1.1 lukem } 2420 1.1 lukem } 2421 1.1 lukem 2422 1.1 lukem ber_memvfree( (void **) refs ); 2423 1.1 lukem } 2424 1.1 lukem 2425 1.1 lukem pr_morePagedResults = 0; 2426 1.1 lukem 2427 1.1 lukem if( ctrls ) { 2428 1.1 lukem tool_print_ctrls( ld, ctrls ); 2429 1.1 lukem ldap_controls_free( ctrls ); 2430 1.1 lukem } 2431 1.1 lukem 2432 1.1 lukem return err; 2433 1.1 lukem } 2434