Back to index

openldap  2.4.31
shellutil.c
Go to the documentation of this file.
00001 /* shellutil.c - common routines useful when building shell-based backends */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 1998-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
00017  * All rights reserved.
00018  *
00019  * Redistribution and use in source and binary forms are permitted
00020  * provided that this notice is preserved and that due credit is given
00021  * to the University of Michigan at Ann Arbor. The name of the University
00022  * may not be used to endorse or promote products derived from this
00023  * software without specific prior written permission. This software
00024  * is provided ``as is'' without express or implied warranty.
00025  */
00026 /* ACKNOWLEDGEMENTS:
00027  * This work was originally developed by the University of Michigan
00028  * (as part of U-MICH LDAP).
00029  */
00030 
00031 
00032 #include "portable.h"
00033 
00034 #include <stdio.h>
00035 
00036 #include <ac/stdlib.h>
00037 #include <ac/stdarg.h>
00038 
00039 #include <pwd.h>
00040 
00041 #include <ac/ctype.h>
00042 #include <ac/string.h>
00043 
00044 #include <lber.h>
00045 #include <ldap.h>
00046 #include "shellutil.h"
00047 
00048 
00049 int    debugflg;
00050 char   *progname;
00051 
00052 static struct inputparams   ips[] = {
00053     IP_TYPE_SUFFIX,  "suffix",
00054     IP_TYPE_BASE,    "base",
00055     IP_TYPE_SCOPE,   "scope",
00056     IP_TYPE_ALIASDEREF,     "deref",
00057     IP_TYPE_SIZELIMIT,      "sizelimit",
00058     IP_TYPE_TIMELIMIT,      "timelimit",
00059     IP_TYPE_FILTER,  "filter",
00060     IP_TYPE_ATTRS,   "attrs",
00061     IP_TYPE_ATTRSONLY,      "attrsonly",
00062     0,               NULL
00063 };
00064 
00065 
00066 void
00067 write_result( FILE *fp, int code, char *matched, char *info )
00068 {
00069     fprintf( fp, "RESULT\ncode: %d\n", code );
00070     debug_printf( ">> RESULT\n" );
00071     debug_printf( ">> code: %d\n", code );
00072 
00073     if ( matched != NULL ) {
00074        fprintf( fp, "matched: %s\n", matched );
00075        debug_printf( ">> matched: %s\n", matched );
00076     }
00077 
00078     if ( info != NULL ) {
00079        fprintf( fp, "info: %s\n", info );
00080        debug_printf( ">> info: %s\n", info );
00081     }
00082 }
00083 
00084 
00085 void
00086 write_entry( struct ldop *op, struct ldentry *entry, FILE *ofp )
00087 {
00088     struct ldattr    **app;
00089     char             **valp;
00090 
00091     fprintf( ofp, "dn: %s\n", entry->lde_dn );
00092     for ( app = entry->lde_attrs; *app != NULL; ++app ) {
00093        if ( attr_requested( (*app)->lda_name, op )) {
00094            for ( valp = (*app)->lda_values; *valp != NULL; ++valp ) {
00095               fprintf( ofp, "%s: %s\n", (*app)->lda_name, *valp );
00096            }
00097        }
00098     }
00099     fputc( '\n', ofp );
00100 }
00101 
00102 
00103 int
00104 test_filter( struct ldop *op, struct ldentry *entry )
00105 {
00106     return ((random() & 0x07 ) == 0x07) /* XXX random for now */
00107               ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
00108 }
00109 
00110 
00111 int
00112 attr_requested( char *name, struct ldop *op )
00113 {
00114     char      **ap;
00115 
00116     if ( op->ldop_srch.ldsp_attrs == NULL ) {    /* special case */
00117        return( 1 );
00118     }
00119 
00120     for ( ap = op->ldop_srch.ldsp_attrs; *ap != NULL; ++ap ) {
00121        if ( strcasecmp( name, *ap ) == 0 ) {
00122            return( 1 );
00123        }
00124     }
00125 
00126     return( 0 );
00127 }
00128 
00129 
00130 void
00131 free_entry( struct ldentry *entry )
00132 {
00133     struct ldattr    **app;
00134     char             **valp;
00135 
00136     free( entry->lde_dn );
00137 
00138     for ( app = entry->lde_attrs; *app != NULL; ++app ) {
00139        for ( valp = (*app)->lda_values; *valp != NULL; ++valp ) {
00140            free( *valp );
00141        }
00142        free( (*app)->lda_values );
00143        free( (*app)->lda_name );
00144     }
00145 
00146     free( entry->lde_attrs );
00147     free( entry );
00148 }
00149 
00150 
00151 int
00152 parse_input( FILE *ifp, FILE *ofp, struct ldop *op )
00153 {
00154     char             *p, *args, line[ MAXLINELEN + 1 ];
00155     struct inputparams      *ip;
00156 
00157     if ( fgets( line, MAXLINELEN, ifp ) == NULL ) {
00158        write_result( ofp, LDAP_OTHER, NULL, "Empty Input" );
00159     }
00160     line[ strlen( line ) - 1 ] = '\0';
00161     if ( strncasecmp( line, STR_OP_SEARCH, sizeof( STR_OP_SEARCH ) - 1 )
00162            != 0 ) {
00163        write_result( ofp, LDAP_UNWILLING_TO_PERFORM, NULL,
00164               "Operation Not Supported" );
00165        return( -1 );
00166     }
00167 
00168     op->ldop_op = LDOP_SEARCH;
00169 
00170     while ( fgets( line, MAXLINELEN, ifp ) != NULL ) {
00171        line[ strlen( line ) - 1 ] = '\0';
00172        debug_printf( "<< %s\n", line );
00173 
00174        args = line;
00175        if (( ip = find_input_tag( &args )) == NULL ) {
00176            debug_printf( "ignoring %s\n", line );
00177            continue;
00178        }
00179 
00180        switch( ip->ip_type ) {
00181        case IP_TYPE_SUFFIX:
00182            add_strval( &op->ldop_suffixes, args );
00183            break;
00184        case IP_TYPE_BASE:
00185            op->ldop_dn = estrdup( args );
00186            break;
00187        case IP_TYPE_SCOPE:
00188            if ( lutil_atoi( &op->ldop_srch.ldsp_scope, args ) != 0 ||
00189               ( op->ldop_srch.ldsp_scope != LDAP_SCOPE_BASE &&
00190                   op->ldop_srch.ldsp_scope != LDAP_SCOPE_ONELEVEL &&
00191                   op->ldop_srch.ldsp_scope != LDAP_SCOPE_SUBTREE ) )
00192            {
00193               write_result( ofp, LDAP_OTHER, NULL, "Bad scope" );
00194               return( -1 );
00195            }
00196            break;
00197        case IP_TYPE_ALIASDEREF:
00198            if ( lutil_atoi( &op->ldop_srch.ldsp_aliasderef, args ) != 0 ) {
00199               write_result( ofp, LDAP_OTHER, NULL, "Bad alias deref" );
00200               return( -1 );
00201            }
00202            break;
00203        case IP_TYPE_SIZELIMIT:
00204            if ( lutil_atoi( &op->ldop_srch.ldsp_sizelimit, args ) != 0 ) {
00205               write_result( ofp, LDAP_OTHER, NULL, "Bad size limit" );
00206               return( -1 );
00207            }
00208            break;
00209        case IP_TYPE_TIMELIMIT:
00210            if ( lutil_atoi( &op->ldop_srch.ldsp_timelimit, args ) != 0 ) {
00211               write_result( ofp, LDAP_OTHER, NULL, "Bad time limit" );
00212               return( -1 );
00213            }
00214            break;
00215        case IP_TYPE_FILTER:
00216            op->ldop_srch.ldsp_filter = estrdup( args );
00217            break;
00218        case IP_TYPE_ATTRSONLY:
00219            op->ldop_srch.ldsp_attrsonly = ( *args != '0' );
00220            break;
00221        case IP_TYPE_ATTRS:
00222            if ( strcmp( args, "all" ) == 0 ) {
00223               op->ldop_srch.ldsp_attrs = NULL;
00224            } else {
00225               while ( args != NULL ) {
00226                   if (( p = strchr( args, ' ' )) != NULL ) {
00227                      *p++ = '\0';
00228                      while ( isspace( (unsigned char) *p )) {
00229                          ++p;
00230                      }
00231                   }
00232                   add_strval( &op->ldop_srch.ldsp_attrs, args );
00233                   args = p;
00234               }
00235            }
00236            break;
00237        }
00238     }
00239 
00240     if ( op->ldop_suffixes == NULL || op->ldop_dn == NULL ||
00241               op->ldop_srch.ldsp_filter == NULL ) {
00242        write_result( ofp, LDAP_OTHER, NULL,
00243               "Required suffix:, base:, or filter: missing" );
00244        return( -1 );
00245     }
00246 
00247     return( 0 );
00248 }
00249 
00250 
00251 struct inputparams *
00252 find_input_tag( char **linep )     /* linep is set to start of args */
00253 {
00254     int              i;
00255     char      *p;
00256 
00257     if (( p = strchr( *linep, ':' )) == NULL || p == *linep ) {
00258        return( NULL );
00259     }
00260 
00261     for ( i = 0; ips[ i ].ip_type != 0; ++i ) {
00262        if ( strncasecmp( *linep, ips[ i ].ip_tag, p - *linep ) == 0 ) {
00263            while ( isspace( (unsigned char) *(++p) )) {
00264               ;
00265            }
00266            *linep = p;
00267            return( &ips[ i ] );
00268        }
00269     }
00270 
00271     return( NULL );
00272 }
00273 
00274 
00275 void
00276 add_strval( char ***sp, char *val )
00277 {
00278     int              i;
00279     char      **vallist;
00280 
00281     vallist = *sp;
00282 
00283     if ( vallist == NULL ) {
00284        i = 0;
00285     } else {
00286        for ( i = 0; vallist[ i ] != NULL; ++i ) {
00287            ;
00288        }
00289     }
00290 
00291     vallist = (char **)erealloc( vallist, ( i + 2 ) * sizeof( char * ));
00292     vallist[ i ] = estrdup( val );
00293     vallist[ ++i ] = NULL;
00294     *sp = vallist;
00295 }
00296 
00297 
00298 char *
00299 estrdup( char *s )
00300 {
00301     char      *p;
00302 
00303     if (( p = strdup( s )) == NULL ) {
00304        debug_printf( "strdup failed\n" );
00305        exit( EXIT_FAILURE );
00306     }
00307 
00308     return( p );
00309 }
00310 
00311 
00312 void *
00313 erealloc( void *s, unsigned size )
00314 {
00315     char      *p;
00316 
00317     if ( s == NULL ) {
00318        p = malloc( size );
00319     } else {
00320        p = realloc( s, size );
00321     }
00322 
00323     if ( p == NULL ) {
00324        debug_printf( "realloc( p, %d ) failed\n", size );
00325        exit( EXIT_FAILURE );
00326     }
00327 
00328     return( p );
00329 }
00330 
00331 
00332 char *
00333 ecalloc( unsigned nelem, unsigned elsize )
00334 {
00335     char      *p;
00336 
00337     if (( p = calloc( nelem, elsize )) == NULL ) {
00338        debug_printf( "calloc( %d, %d ) failed\n", nelem, elsize );
00339        exit( EXIT_FAILURE );
00340     }
00341 
00342     return( p );
00343 }
00344 
00345 
00346 #ifdef LDAP_DEBUG
00347 
00348 /* VARARGS */
00349 void
00350 debug_printf( const char *fmt, ... )
00351 {
00352     va_list   ap;
00353 
00354        if ( debugflg ) {
00355               va_start( ap, fmt );
00356               fprintf( stderr, "%s: ", progname );
00357               vfprintf( stderr, fmt, ap );
00358               va_end( ap );
00359        }
00360 }
00361 
00362 
00363 void
00364 dump_ldop( struct ldop *op )
00365 {
00366     if ( !debugflg ) {
00367        return;
00368     }
00369 
00370     debug_printf( "SEARCH operation\n" );
00371     if ( op->ldop_suffixes == NULL ) {
00372        debug_printf( "    suffix: NONE\n" );
00373     } else {
00374        int    i;
00375        for ( i = 0; op->ldop_suffixes[ i ] != NULL; ++i ) {
00376            debug_printf( "    suffix: <%s>\n", op->ldop_suffixes[ i ] );
00377        }
00378     }
00379     debug_printf( "        dn: <%s>\n", op->ldop_dn );
00380     debug_printf( "     scope: <%d>\n", op->ldop_srch.ldsp_scope );
00381     debug_printf( "    filter: <%s>\n", op->ldop_srch.ldsp_filter );
00382     debug_printf( "aliasderef: <%d>\n", op->ldop_srch.ldsp_aliasderef );
00383     debug_printf( " sizelimit: <%d>\n", op->ldop_srch.ldsp_sizelimit );
00384     debug_printf( " timelimit: <%d>\n", op->ldop_srch.ldsp_timelimit );
00385     debug_printf( " attrsonly: <%d>\n", op->ldop_srch.ldsp_attrsonly );
00386     if ( op->ldop_srch.ldsp_attrs == NULL ) {
00387        debug_printf( "     attrs: ALL\n" );
00388     } else {
00389        int    i;
00390 
00391        for ( i = 0; op->ldop_srch.ldsp_attrs[ i ] != NULL; ++i ) {
00392            debug_printf( "  attrs: <%s>\n", op->ldop_srch.ldsp_attrs[ i ] );
00393        }
00394     }
00395 }
00396 #endif /* LDAP_DEBUG */