/*
*/
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* ldapsearch.c - generic program to search LDAP */
#include "ldaptool.h"
#include "fileurl.h"
#ifdef SOLARIS_LDAP_CMD
#include <locale.h>
#include "solaris-int.h"
#endif /* SOLARIS_LDAP_CMD */
#ifndef SOLARIS_LDAP_CMD
#define gettext(s) s
#endif
static void usage( void );
unsigned long opts );
unsigned long ldifoptions );
static char *sortresult2string(unsigned long result);
static char *changetype_num2string( int chgtype );
static char *msgtype2str( int msgtype );
static char **get_effectiverights_attrlist(char * optarg);
#ifdef SOLARIS_LDAP_CMD
static void fill_ldapsearch_msgtypes( void );
#endif /* SOLARIS_LDAP_CMD */
/*
* Prefix used in names of pseudo attributes added to the entry LDIF
* output if we receive an entryChangeNotification control with an entry
* (requested using persistent search).
*/
static void
usage( void )
{
fprintf( stderr, gettext("usage: %s -b basedn [options] filter [attributes...]\n"), ldaptool_progname );
fprintf( stderr, gettext(" %s -b basedn [options] -f file [attributes...]\nwhere:\n"), ldaptool_progname );
ldaptool_common_usage( 0 );
#if defined( XP_WIN32 )
#else
#endif
#ifndef HAVE_SASL_OPTIONS
#endif
fprintf( stderr, gettext(" -1\t\tomit leading \"version: %d\" line in LDIF output\n"), LDIF_VERSION_ONE );
fprintf( stderr, gettext(" -B\t\tprint non-ASCII values and use old output format (attr=value)\n") );
#ifdef SOLARIS_LDAP_CMD
#endif /* SOLARIS_LDAP_CMD */
fprintf( stderr, gettext(" -F sep\tprint `sep' instead of `%s' between attribute names\n"), LDAPTOOL_DEFSEP );
fprintf( stderr, gettext(" -l timelim\ttime limit (in seconds) for search (default is no limit)\n") );
fprintf( stderr, gettext(" -z sizelim\tsize limit (in entries) for search (default is no limit)\n") );
fprintf( stderr, gettext(" -G before%cafter%cindex%ccount | before%cafter%cvalue where 'before' and\n"), VLV_PARAM_SEP, VLV_PARAM_SEP, VLV_PARAM_SEP, VLV_PARAM_SEP, VLV_PARAM_SEP );
#ifndef SOLARIS_LDAP_CMD
fprintf( stderr, gettext("\t\t A value of \"\" means \"the authorization id for the operation\".\n"));
fprintf( stderr, gettext(" -X attrlist\tspecifies the getEffectiveRights control specific attribute list.\n"));
#endif /* SOLARIS_LDAP_CMD */
exit( LDAP_PARAM_ERROR );
}
static int sortsize = 0;
static int use_psearch=0;
#ifndef SOLARIS_LDAP_CMD
static int do_effective_rights_control = 0;
#endif /* SOLARIS_LDAP_CMD */
/* Persistent search variables */
int
{
#ifdef SOLARIS_LDAP_CMD
#endif /* SOLARIS_LDAP_CMD */
free_filtpattern = 0;
minimize_base64 = produce_file_urls = 0;
ldif = 1;
fold = 1;
server_sort = 0;
#ifdef notdef
#ifdef HPUX11
#ifndef __LP64__
#endif /* __LP64_ */
#endif /* HPUX11 */
#endif
#ifdef HAVE_SASL_OPTIONS
#ifdef SOLARIS_LDAP_CMD
0, options_callback );
#else
0, options_callback );
#endif /* SOLARIS_LDAP_CMD */
#else
0, options_callback );
#endif /* HAVE_SASL_OPTIONS */
if ( optind == -1 ) {
usage();
}
usage();
}
}
if ( sortattr ) {
; /* NULL */
}
sortsize++; /* add in the final NULL field */
if ( skipsortattr == NULL ) {
exit( LDAP_NO_MEMORY );
}
} else if ( server_sort ) {
server_sort = 0; /* ignore this option if no sortattrs were given */
}
if ( ldaptool_fp == NULL ) {
usage();
}
filtpattern = "%s";
} else { /* there are additional args (filter + attrs) */
/* since local2UTF8 always allocates something, we should free it */
free_filtpattern = 1;
++optind;
} else {
filtpattern = "%s";
}
} else {
exit( LDAP_NO_MEMORY );
}
for ( i = 0; i < (sortsize - 1); i++ ) {
exit( LDAP_NO_MEMORY );
}
/*
* attribute in the search list only for the purpose of
* sorting
*/
skipsortattr[i] = 1;
}
}
}
}
ld = ldaptool_ldap_init( 0 );
if ( !ldaptool_not ) {
}
ldaptool_bind( ld );
if ( ldaptool_verbose ) {
} else {
}
}
putchar( '\n' );
}
if ( ldaptool_fp == NULL ) {
char *conv;
} else {
int done = 0;
rc = LDAP_SUCCESS;
first = 1;
int increment = 0;
int c, index;
/* allocate initial block of memory */
exit( LDAP_NO_MEMORY );
}
increment++;
index = 0;
/* check if we will overflow the buffer */
/* if we did, add another BUFSIZ worth of bytes */
if ((linep = (char *)
exit( LDAP_NO_MEMORY );
}
increment++;
}
}
if (c == EOF) {
done = 1;
break;
}
if ( !first ) {
putchar( '\n' );
} else {
first = 0;
}
linep );
}
}
ldaptool_cleanup( ld );
free (filtpattern);
}
/* check for and report output error */
gettext("output error (output might be incomplete)") );
return( rc );
}
static void
{
switch( option ) {
case 'u': /* include UFN */
++includeufn;
break;
case 't': /* write attribute values to /tmp files */
++vals2tmp;
break;
case 'U': /* produce file URLs in conjunction with -t */
break;
case 'e': /* minimize base-64 encoding of values */
break;
case 'A': /* retrieve attribute names only -- no values */
++attrsonly;
break;
case 'L': /* print entries in LDIF format -- now the default */
break;
#ifdef SOLARIS_LDAP_CMD
case 'r': /* print entries in the old format */
ldif = 0;
break;
#endif /* SOLARIS_LDAP_CMD */
#ifdef HAVE_SASL_OPTIONS
#ifdef HAVE_SASL_OPTIONS_2
case 'o': /* print entries using old ldapsearch format */
ldif = 0;
break;
#endif
#else
case 'o': /* print entries using old ldapsearch format */
ldif = 0;
break;
#endif
case 'B': /* allow binary values to be printed, use old format */
++allow_binary;
ldif = 0;
break;
case '1': /* omit leading "version: #" line from LDIF output */
write_ldif_version = 0;
break;
case 's': /* search scope */
} else {
usage();
}
break;
case 'a': /* set alias deref option */
} else {
usage();
}
break;
case 'F': /* field separator */
ldif = 0;
break;
#ifndef SOLARIS_LDAP_CMD
case 'c':
/* -c ""
means "This user"
*/
"\"dn:\" means anonymous user."));
usage();
} else {
}
break;
case 'X':
break;
#endif /* SOLARIS_LDAP_CMD */
case 'b': /* searchbase */
break;
case 'l': /* time limit */
break;
case 'x': /* server sorting requested */
server_sort = 1;
break;
case 'z': /* size limit */
break;
case 'S': /* sort attribute */
break;
case 'T': /* don't fold lines */
fold = 0;
break;
case 'G': /* do the virtual list setup */
use_vlv++;
if (s != NULL)
{
s++;
s = strchr(s, VLV_PARAM_SEP );
if (s != NULL)
{
s++;
/* below is a small set of logic to implement the following cases
* -G23:23:wilber
* -G23:23:"wilber:wright"
* -G23:23:'wilber'
* -G23:23:wilber wright
* all of the above are before, after, value - NOTE: a colon not in a quoted
* string will break the parser!!!!
* -G23:23:45:600
* above is index, count encoding
*/
if (*s == '\'' || *s == '"')
{
}
else
{
if (strchr( s, VLV_PARAM_SEP ))
{
/* we have an index + count option */
}
else
{
/* we don't have a quote surrounding the assertion value
* do we need to???
*/
}
}
}
else
{
exit( LDAP_PARAM_ERROR );
}
}
else
{
exit( LDAP_PARAM_ERROR );
}
break;
case 'C':
use_psearch++;
perror ("strdup");
}
usage();
}
perror ("strdup");
}
} else {
usage();
}
usage();
}
}
usage();
}
}
/* Now parse the temp_arg and build chgtype as
* the changetypes are encountered */
usage();
} else {
while ( ps_ptr ) {
else {
usage();
}
}
}
break;
default:
usage();
break;
}
}
static int
char *base;
int scope;
char **attrs;
int attrsonly;
char *filtpatt;
char *value;
{
int msgid = 0;
int length = 0;
int mallocd_filter = 0;
} else {
if ((filterp = (char *)
}
mallocd_filter = 1;
} else {
}
#ifdef HAVE_SNPRINTF
exit( LDAP_PARAM_ERROR );
}
#else
#endif
}
if (mallocd_filter) {
mallocd_filter = 0;
}
filterp = "(objectclass=*)";
}
if ( ldaptool_verbose ) {
/*
* Display the filter that will be used. Add surrounding parens.
* if they are missing.
*/
if ( '(' == *filterp ) {
} else {
}
}
if ( ldaptool_not ) {
return( LDAP_SUCCESS );
}
}
}
#ifndef SOLARIS_LDAP_CMD
if ( do_effective_rights_control ) {
(const char**) get_effectiverights_control_attrlist)) !=NULL) {
}
}
#endif /* SOLARIS_LDAP_CMD */
if (use_psearch) {
{
return (1);
}
}
if (server_sort) {
/* First make a sort key list from the attribute list we have */
int i = 0;
char *s = NULL;
int string_length = 0;
/* Count the sort strings */
for (i = 0; i < sortsize - 1 ; i++) {
}
exit( LDAP_NO_MEMORY );
}
s = sortattrs;
for (i = 0; i < sortsize - 1 ; i++) {
*s++ = ' ';
}
/* Then make a control for the sort attributes we have */
if ( rc != LDAP_SUCCESS ) {
}
}
/* remember server side sorting must be available for vlv!!!! */
if (use_vlv)
{
if ( ldaptool_verbose ) {
);
}
if (vlv_value)
{
vlv_data.ldvlist_size = 0;
vlv_data.ldvlist_index = 0;
if ( ldaptool_verbose ) {
}
}
else
{
if ( ldaptool_verbose ) {
}
}
if ( rc != LDAP_SUCCESS ) {
}
{
return( ldaptool_print_lderror( ld,
"ldap_create_virtuallist_control",
}
}
!= LDAP_SUCCESS ) {
}
matches = 0;
first = 1;
if ( sortattr && !server_sort ) {
} else {
if ( rc != LDAP_RES_SEARCH_ENTRY ) {
if ( rc == LDAP_RES_SEARCH_REFERENCE ) {
} else if ( rc == LDAP_RES_EXTENDED
gettext("Unsolicited response") );
} else {
" type 0x%x (%s)\n"),
}
ldap_msgfree( res );
continue;
}
matches++;
if ( !first ) {
putchar( '\n' );
} else {
first = 0;
}
ldap_msgfree( res );
}
}
if ( rc == -1 ) {
}
&ctrl_response_array, 0 ) != LDAP_SUCCESS ) {
} else if ( rc != LDAP_SUCCESS ) {
}
/* Parse the returned sort control */
if (server_sort) {
unsigned long result = 0;
char *attribute;
}
if (0 == result) {
if ( ldaptool_verbose ) {
}
} else {
printf(gettext("Server reported sorting error %ld: %s, attribute in error\"%s\"\n"),result,sortresult2string(result),attribute);
} else {
}
}
}
if (use_vlv)
{
int vresult;
if ( LDAP_SUCCESS != ldap_parse_virtuallist_control(ld,ctrl_response_array,&vpos, &vcount,&vresult) ) {
}
if (0 == vresult) {
if ( ldaptool_verbose ) {
}
} else {
}
}
(LDAP_CMP_CALLBACK *)strcasecmp );
matches = 0;
first = 1;
e = ldap_next_entry( ld, e ) ) {
matches++;
if ( !first ) {
putchar( '\n' );
} else {
first = 0;
}
}
}
if ( ldaptool_verbose ) {
}
ldap_value_free( refs );
}
ldap_msgfree( res );
return( rc );
}
static void
int attrsonly;
{
int i, notascii;
#if defined( XP_WIN32 )
#else
#endif
if ( includeufn ) {
}
ldap_memfree( dn );
if ( use_psearch ) {
#ifdef SOLARIS_LDAP_CMD
#else
long chgnum;
#endif /* SOLARIS_LDAP_CMD */
LDAPTOOL_PSEARCH_ATTR_PREFIX "changeType",
changetype_num2string( chgtype ), 0 );
if ( chgnumpresent ) {
LDAPTOOL_PSEARCH_ATTR_PREFIX "changeNumber",
longbuf, 0 );
}
LDAPTOOL_PSEARCH_ATTR_PREFIX "previousDN",
prevdn, 0 );
ldap_memfree( prevdn );
}
}
}
}
continue; /* so skip it! */
}
if ( attrsonly ) {
if ( ldif ) {
write_ldif_value( a, "", 0, 0 );
} else {
printf( "%s\n", a );
}
if ( vals2tmp ) {
#ifdef HAVE_SNPRINTF
"%s/ldapsearch-%s-XXXXXX",
ldaptool_get_tmp_dir(), a ) < 0 ) {
exit( LDAP_PARAM_ERROR );
}
#else
ldaptool_get_tmp_dir(), a );
#endif
} else if ( ldif ) {
if ( produce_file_urls ) {
char *url;
perror( "ldaptool_path2fileurl" );
} else {
}
} else {
0 );
}
} else {
}
}
} else {
notascii = 0;
if ( !ldif && !allow_binary ) {
}
if ( ldif ) {
} else {
}
}
}
ber_bvecfree( bvals );
}
ldap_memfree( a );
}
}
}
}
static void
{
strval = "";
}
if ( ldif ) {
} else if ( 0 != ( opts & LDAPTOOL_WRITEVALOPT_SUPPRESS_NAME )) {
} else {
}
}
static int
unsigned long ldifoptions )
{
char *ldif;
static int wrote_version = 0;
if ( write_ldif_version && !wrote_version ) {
wrote_version = 1;
}
if ( !fold ) {
}
if ( minimize_base64 ) {
}
ldifoptions )) == NULL ) {
return( -1 );
}
return( 0 );
}
static char *
{
/*
success (0), -- results are sorted
operationsError (1), -- server internal failure
timeLimitExceeded (3), -- timelimit reached before
-- sorting was completed
strongAuthRequired (8), -- refused to return sorted
-- results via insecure
-- protocol
adminLimitExceeded (11), -- too many matching entries
-- for the server to sort
noSuchAttribute (16), -- unrecognized attribute
-- type in sort key
inappropriateMatching (18), -- unrecognized or inappro-
-- priate matching rule in
-- sort key
insufficientAccessRights (50), -- refused to return sorted
-- results to this client
busy (51), -- too busy to process
unwillingToPerform (53), -- unable to sort
other (80)
*/
switch (result) {
case 0: return (gettext("success"));
case 80:
default: return (gettext("Er...Other ?"));
}
}
static void
{
int i;
char **refs;
}
ldap_value_free( refs );
}
}
/*possible operations a client can invoke -- copied from ldaprot.h */
#ifndef LDAP_REQ_BIND
#endif /* LDAP_REQ_BIND */
struct ldapsearch_type2str {
};
#ifdef SOLARIS_LDAP_CMD
/* results: */
{ LDAP_RES_BIND, NULL },
{ LDAP_RES_SEARCH_ENTRY, NULL },
{ LDAP_RES_SEARCH_RESULT, NULL },
{ LDAP_RES_MODIFY, NULL },
{ LDAP_RES_ADD, NULL },
{ LDAP_RES_DELETE, NULL },
{ LDAP_RES_MODDN, NULL },
{ LDAP_RES_COMPARE, NULL },
{ LDAP_RES_EXTENDED, NULL },
/* requests: */
{ LDAP_REQ_BIND, NULL },
{ LDAP_REQ_UNBIND, NULL },
{ LDAP_REQ_SEARCH, NULL },
{ LDAP_REQ_MODIFY, NULL },
{ LDAP_REQ_ADD, NULL },
{ LDAP_REQ_DELETE, NULL },
{ LDAP_REQ_RENAME, NULL },
{ LDAP_REQ_COMPARE, NULL },
{ LDAP_REQ_ABANDON, NULL },
{ LDAP_REQ_EXTENDED, NULL },
};
#else
/* results: */
{ LDAP_RES_BIND, "bind result" },
{ LDAP_RES_SEARCH_REFERENCE, "continuation reference" },
{ LDAP_RES_SEARCH_ENTRY, "entry" },
{ LDAP_RES_SEARCH_RESULT, "search result" },
{ LDAP_RES_MODIFY, "modify result" },
{ LDAP_RES_ADD, "add result" },
{ LDAP_RES_DELETE, "delete result" },
{ LDAP_RES_MODDN, "rename result" },
{ LDAP_RES_COMPARE, "compare result" },
{ LDAP_RES_EXTENDED, "extended operation result" },
/* requests: */
{ LDAP_REQ_BIND, "bind request" },
{ LDAP_REQ_UNBIND, "unbind request" },
{ LDAP_REQ_SEARCH, "search request" },
{ LDAP_REQ_MODIFY, "modify request" },
{ LDAP_REQ_ADD, "add request" },
{ LDAP_REQ_DELETE, "delete request" },
{ LDAP_REQ_RENAME, "rename request" },
{ LDAP_REQ_COMPARE, "compare request" },
{ LDAP_REQ_ABANDON, "abandon request" },
{ LDAP_REQ_EXTENDED, "extended request" },
};
#endif /* SOLARIS_LDAP_CMD */
/ sizeof(struct ldapsearch_type2str))
#ifdef SOLARIS_LDAP_CMD
static void
fill_ldapsearch_msgtypes( void )
{
int i = 0;
!= NULL)
return;
/* results: */
"bind result");
"continuation reference");
"entry");
"search result");
"modify result");
"add result");
"delete result");
"rename result");
"compare result");
"extended operation result");
/* requests: */
"bind request");
"unbind request");
"search request");
"modify request");
"add request");
"delete request");
"rename request");
"compare request");
"abandon request");
"extended request");
}
#endif /* SOLARIS_LDAP_CMD */
/*
* Return a descriptive string given an LDAP result message type (tag).
*/
static char *
{
char *s = gettext("unknown");
int i;
#ifdef SOLARIS_LDAP_CMD
/* Make sure ldapsearch_msgtypes is initialized */
== NULL)
(void) fill_ldapsearch_msgtypes();
#endif /* SOLARIS_LDAP_CMD */
for ( i = 0; i < LDAPSEARCHTOOL_NUMTYPES; ++i ) {
s = ldapsearch_msgtypes[ i ].ldst2s_string;
}
}
return( s );
}
/*
* Return a descriptive string given a Persistent Search change type
*/
static char *
{
char *s = gettext("unknown");
switch( chgtype ) {
case LDAP_CHANGETYPE_ADD:
s = gettext("add");
break;
case LDAP_CHANGETYPE_DELETE:
s = gettext("delete");
break;
case LDAP_CHANGETYPE_MODIFY:
s = gettext("modify");
break;
case LDAP_CHANGETYPE_MODDN:
s = gettext("moddn");
break;
}
return( s );
}
/* returns a null teminated charrary */
int i = 0;
/* Oops - somebody left this debug message in for the
getEffectiveRights control
fprintf(stderr, "attrlist: "); */
i = 0;
i++;
}
return(retArray);
}