" -a deref one of never (default), always, search, or find\n"
" -A retrieve attribute names only (no values)\n"
" -b basedn base dn for search\n"
+" -E [!]<ctrl>[=<ctrlparam>] search controls (! indicates criticality)\n"
+" [!]mv=<filter> (matched values filter)\n"
" -F prefix URL prefix for files (default: %s)\n"
" -l limit time limit (in seconds) for search\n"
" -L print responses in LDIFv1 format\n"
"Common options:\n"
" -d level set LDAP debugging level to `level'\n"
" -D binddn bind DN\n"
+" -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n"
+" [!]manageDSAit (alternate form, see -M)\n"
+" [!]noop\n"
" -f file read operations from `file'\n"
" -h host LDAP server\n"
" -H URI LDAP Uniform Resource Indentifier(s)\n"
" -W prompt for bind passwd\n"
" -x Simple authentication\n"
" -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
+" -y file Read passwd from file\n"
" -Y mech SASL mechanism\n"
" -Z Start TLS request (-ZZ to require successful response)\n"
, s, def_urlpre, def_tmpdir );
{
char *p;
- if (*LDAP_DIRSEP != '/')
- {
- for (p = url; *p; p++)
- {
+ if (*LDAP_DIRSEP != '/') {
+ for (p = url; *p; p++) {
if (*p == *LDAP_DIRSEP)
*p = '/';
}
{
char *infile, *filtpattern, **attrs = NULL, line[BUFSIZ];
FILE *fp = NULL;
- int rc, i, first, scope, deref, attrsonly, manageDSAit;
+ int rc, i, first, scope, deref, attrsonly, manageDSAit, noop, crit;
int referrals, timelimit, sizelimit, debug;
int authmethod, version, want_bindpw;
LDAP *ld = NULL;
+ int valuesReturnFilter;
+ BerElement *ber = NULL;
+ struct berval *bvalp = NULL;
+ char *vrFilter = NULL, *control = NULL, *cvalue;
+ char *pw_file = NULL;
+
infile = NULL;
- debug = verbose = not = vals2tmp = referrals =
- attrsonly = manageDSAit = ldif = want_bindpw = 0;
+ debug = verbose = not = vals2tmp = referrals = valuesReturnFilter =
+ attrsonly = manageDSAit = noop = ldif = want_bindpw = 0;
+
+ prog = lutil_progname( "ldapsearch", argc, argv );
lutil_log_initialize(argc, argv);
urlize( def_urlpre );
- prog = (prog = strrchr(argv[0], *LDAP_DIRSEP)) == NULL ? argv[0] : prog + 1;
-
- while (( i = getopt( argc, argv, "Aa:b:F:f:Ll:S:s:T:tuz:"
- "Cd:D:h:H:IkKMnO:p:P:QR:U:vw:WxX:Y:Z")) != EOF )
+ while (( i = getopt( argc, argv, "Aa:b:E:F:f:Ll:S:s:T:tuz:"
+ "Cd:e:D:h:H:IkKMnO:p:P:QR:U:vw:WxX:y:Y:Z")) != EOF )
{
switch( i ) {
/* Search Options */
case 'b': /* search base */
base = strdup( optarg );
break;
+ case 'E': /* search controls */
+ if( version == LDAP_VERSION2 ) {
+ fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
+ prog, version );
+ return EXIT_FAILURE;
+ }
+
+ /* should be extended to support comma separated list of
+ * [!]key[=value] parameters, e.g. -E !foo,bar=567
+ */
+
+ crit = 0;
+ cvalue = NULL;
+ if( optarg[0] == '!' ) {
+ crit = 1;
+ optarg++;
+ }
+
+ control = strdup( optarg );
+ if ( (cvalue = strchr( control, '=' )) != NULL ) {
+ *cvalue++ = '\0';
+ }
+
+ if ( strcasecmp( control, "mv" ) == 0 ) {
+ /* ValuesReturnFilter control */
+ if (valuesReturnFilter!=0) {
+ fprintf( stderr, "ValuesReturnFilter previously specified");
+ return EXIT_FAILURE;
+ }
+ valuesReturnFilter= 1 + crit;
+
+ if ( cvalue == NULL ) {
+ fprintf( stderr,
+ "missing filter in ValuesReturnFilter control\n");
+ return EXIT_FAILURE;
+ }
+
+ vrFilter = cvalue;
+ version = LDAP_VERSION3;
+ break;
+
+ } else {
+ fprintf( stderr, "Invalid control name: %s\n", control );
+ usage(prog);
+ return EXIT_FAILURE;
+ }
case 'f': /* input file */
if( infile != NULL ) {
fprintf( stderr, "%s: -f previously specified\n", prog );
}
binddn = strdup( optarg );
break;
+ case 'e': /* general controls */
+ if( version == LDAP_VERSION2 ) {
+ fprintf( stderr, "%s: -e incompatible with LDAPv%d\n",
+ prog, version );
+ return EXIT_FAILURE;
+ }
+
+ /* should be extended to support comma separated list of
+ * [!]key[=value] parameters, e.g. -e !foo,bar=567
+ */
+
+ crit = 0;
+ cvalue = NULL;
+ if( optarg[0] == '!' ) {
+ crit = 1;
+ optarg++;
+ }
+
+ control = strdup( optarg );
+ if ( (cvalue = strchr( control, '=' )) != NULL ) {
+ *cvalue++ = '\0';
+ }
+
+ if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
+ if( cvalue != NULL ) {
+ fprintf( stderr, "manageDSAit: no control value expected" );
+ usage(prog);
+ return EXIT_FAILURE;
+ }
+
+ manageDSAit = 1 + crit;
+ free( control );
+ break;
+
+ } else if ( strcasecmp( control, "noop" ) == 0 ) {
+ if( cvalue != NULL ) {
+ fprintf( stderr, "noop: no control value expected" );
+ usage(prog);
+ return EXIT_FAILURE;
+ }
+
+ noop = 1 + crit;
+ free( control );
+ break;
+
+ } else {
+ fprintf( stderr, "Invalid general control name: %s\n", control );
+ usage(prog);
+ return EXIT_FAILURE;
+ }
case 'h': /* ldap host */
if( ldapuri != NULL ) {
fprintf( stderr, "%s: -h incompatible with -H\n", prog );
case 'W':
want_bindpw++;
break;
+ case 'y':
+ pw_file = optarg;
+ break;
case 'Y':
#ifdef HAVE_CYRUS_SASL
if( sasl_mech != NULL ) {
}
}
- if (want_bindpw) {
- passwd.bv_val = getpassphrase("Enter LDAP Password: ");
- passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
+ if ( pw_file || want_bindpw ) {
+ if ( pw_file ) {
+ rc = lutil_get_filed_password( pw_file, &passwd );
+ if( rc ) return EXIT_FAILURE;
+ } else {
+ passwd.bv_val = getpassphrase( "Enter LDAP Password: " );
+ passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
+ }
}
if ( authmethod == LDAP_AUTH_SASL ) {
}
}
- if ( manageDSAit ) {
+ if ( manageDSAit || valuesReturnFilter ) {
int err;
- LDAPControl c;
- LDAPControl *ctrls[2];
- ctrls[0] = &c;
- ctrls[1] = NULL;
+ int i=0;
+ LDAPControl c1,c2;
+ LDAPControl *ctrls[3];
+
+ if ( manageDSAit ) {
+ ctrls[i++]=&c1;
+ ctrls[i] = NULL;
+
+ c1.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
+ c1.ldctl_value.bv_val = NULL;
+ c1.ldctl_value.bv_len = 0;
+ c1.ldctl_iscritical = manageDSAit > 1;
+ }
- c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
- c.ldctl_value.bv_val = NULL;
- c.ldctl_value.bv_len = 0;
- c.ldctl_iscritical = manageDSAit > 1;
+ if ( valuesReturnFilter ) {
+ ctrls[i++]=&c2;
+ ctrls[i] = NULL;
+
+ c2.ldctl_oid = LDAP_CONTROL_VALUESRETURNFILTER;
+ c2.ldctl_iscritical = valuesReturnFilter > 1;
+
+ if (( ber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
+ return EXIT_FAILURE;
+ }
+
+ if ( ( err = ldap_put_vrFilter( ber, vrFilter ) ) == -1 ) {
+ ber_free( ber, 1 );
+ fprintf( stderr, "Bad ValuesReturnFilter: %s\n", vrFilter );
+ return EXIT_FAILURE;
+ }
+
+ if ( ber_flatten( ber, &bvalp ) == LBER_ERROR ) {
+ return EXIT_FAILURE;
+ }
+
+ c2.ldctl_value=(*bvalp);
+ }
err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
+ ber_bvfree(bvalp);
+ ber_free( ber, 1 );
+
if( err != LDAP_OPT_SUCCESS ) {
- fprintf( stderr, "Could not set ManageDSAit %scontrol\n",
- c.ldctl_iscritical ? "critical " : "" );
- if( c.ldctl_iscritical ) {
- exit( EXIT_FAILURE );
+ fprintf( stderr, "Could not set %scontrols\n",
+ (c1.ldctl_iscritical || c2.ldctl_iscritical)
+ ? "critical " : "" );
+ if( c1.ldctl_iscritical && c2.ldctl_iscritical ) {
+ return EXIT_FAILURE;
}
}
}
struct timeval *timeout,
int sizelimit )
{
- char filter[ BUFSIZ ];
+ char *filter;
int rc;
int nresponses;
int nentries;
ber_int_t msgid;
if( filtpatt != NULL ) {
+ filter = malloc( strlen( filtpatt ) + strlen( value ) );
+ if( filter == NULL ) {
+ perror( "malloc" );
+ return EXIT_FAILURE;
+ }
+
sprintf( filter, filtpatt, value );
if ( verbose ) {
}
} else {
- sprintf( filter, "%s", value );
+ filter = value;
}
if ( not ) {
rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
sctrls, cctrls, timeout, sizelimit, &msgid );
+ if ( filtpatt != NULL ) {
+ free( filter );
+ }
+
if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s: ldap_search_ext: %s (%d)\n",
prog, ldap_err2string( rc ), rc );
{
int tmpfd;
/* write value to file */
- sprintf( tmpfname, "%s" LDAP_DIRSEP "ldapsearch-%s-XXXXXX",
+ snprintf( tmpfname, sizeof tmpfname,
+ "%s" LDAP_DIRSEP "ldapsearch-%s-XXXXXX",
tmpdir, a );
tmpfp = NULL;
fclose( tmpfp );
- sprintf( url, "%s%s", urlpre,
+ snprintf( url, sizeof url, "%s%s", urlpre,
&tmpfname[strlen(tmpdir) + sizeof(LDAP_DIRSEP) - 1] );
urlize( url );