diff options
Diffstat (limited to 'servers/slapd/shell-backends/shellutil.c')
-rw-r--r-- | servers/slapd/shell-backends/shellutil.c | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/servers/slapd/shell-backends/shellutil.c b/servers/slapd/shell-backends/shellutil.c new file mode 100644 index 0000000..c3935ce --- /dev/null +++ b/servers/slapd/shell-backends/shellutil.c @@ -0,0 +1,396 @@ +/* shellutil.c - common routines useful when building shell-based backends */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software <http://www.openldap.org/>. + * + * Copyright 1998-2018 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * <http://www.OpenLDAP.org/license.html>. + */ +/* Portions Copyright (c) 1995 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + */ +/* ACKNOWLEDGEMENTS: + * This work was originally developed by the University of Michigan + * (as part of U-MICH LDAP). + */ + + +#include "portable.h" + +#include <stdio.h> + +#include <ac/stdlib.h> +#include <ac/stdarg.h> + +#include <pwd.h> + +#include <ac/ctype.h> +#include <ac/string.h> + +#include <lber.h> +#include <ldap.h> +#include "shellutil.h" + + +int debugflg; +char *progname; + +static struct inputparams ips[] = { + IP_TYPE_SUFFIX, "suffix", + IP_TYPE_BASE, "base", + IP_TYPE_SCOPE, "scope", + IP_TYPE_ALIASDEREF, "deref", + IP_TYPE_SIZELIMIT, "sizelimit", + IP_TYPE_TIMELIMIT, "timelimit", + IP_TYPE_FILTER, "filter", + IP_TYPE_ATTRS, "attrs", + IP_TYPE_ATTRSONLY, "attrsonly", + 0, NULL +}; + + +void +write_result( FILE *fp, int code, char *matched, char *info ) +{ + fprintf( fp, "RESULT\ncode: %d\n", code ); + debug_printf( ">> RESULT\n" ); + debug_printf( ">> code: %d\n", code ); + + if ( matched != NULL ) { + fprintf( fp, "matched: %s\n", matched ); + debug_printf( ">> matched: %s\n", matched ); + } + + if ( info != NULL ) { + fprintf( fp, "info: %s\n", info ); + debug_printf( ">> info: %s\n", info ); + } +} + + +void +write_entry( struct ldop *op, struct ldentry *entry, FILE *ofp ) +{ + struct ldattr **app; + char **valp; + + fprintf( ofp, "dn: %s\n", entry->lde_dn ); + for ( app = entry->lde_attrs; *app != NULL; ++app ) { + if ( attr_requested( (*app)->lda_name, op )) { + for ( valp = (*app)->lda_values; *valp != NULL; ++valp ) { + fprintf( ofp, "%s: %s\n", (*app)->lda_name, *valp ); + } + } + } + fputc( '\n', ofp ); +} + + +int +test_filter( struct ldop *op, struct ldentry *entry ) +{ + return ((random() & 0x07 ) == 0x07) /* XXX random for now */ + ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE; +} + + +int +attr_requested( char *name, struct ldop *op ) +{ + char **ap; + + if ( op->ldop_srch.ldsp_attrs == NULL ) { /* special case */ + return( 1 ); + } + + for ( ap = op->ldop_srch.ldsp_attrs; *ap != NULL; ++ap ) { + if ( strcasecmp( name, *ap ) == 0 ) { + return( 1 ); + } + } + + return( 0 ); +} + + +void +free_entry( struct ldentry *entry ) +{ + struct ldattr **app; + char **valp; + + free( entry->lde_dn ); + + for ( app = entry->lde_attrs; *app != NULL; ++app ) { + for ( valp = (*app)->lda_values; *valp != NULL; ++valp ) { + free( *valp ); + } + free( (*app)->lda_values ); + free( (*app)->lda_name ); + } + + free( entry->lde_attrs ); + free( entry ); +} + + +int +parse_input( FILE *ifp, FILE *ofp, struct ldop *op ) +{ + char *p, *args, line[ MAXLINELEN + 1 ]; + struct inputparams *ip; + + if ( fgets( line, MAXLINELEN, ifp ) == NULL ) { + write_result( ofp, LDAP_OTHER, NULL, "Empty Input" ); + } + line[ strlen( line ) - 1 ] = '\0'; + if ( strncasecmp( line, STR_OP_SEARCH, sizeof( STR_OP_SEARCH ) - 1 ) + != 0 ) { + write_result( ofp, LDAP_UNWILLING_TO_PERFORM, NULL, + "Operation Not Supported" ); + return( -1 ); + } + + op->ldop_op = LDOP_SEARCH; + + while ( fgets( line, MAXLINELEN, ifp ) != NULL ) { + line[ strlen( line ) - 1 ] = '\0'; + debug_printf( "<< %s\n", line ); + + args = line; + if (( ip = find_input_tag( &args )) == NULL ) { + debug_printf( "ignoring %s\n", line ); + continue; + } + + switch( ip->ip_type ) { + case IP_TYPE_SUFFIX: + add_strval( &op->ldop_suffixes, args ); + break; + case IP_TYPE_BASE: + op->ldop_dn = estrdup( args ); + break; + case IP_TYPE_SCOPE: + if ( lutil_atoi( &op->ldop_srch.ldsp_scope, args ) != 0 || + ( op->ldop_srch.ldsp_scope != LDAP_SCOPE_BASE && + op->ldop_srch.ldsp_scope != LDAP_SCOPE_ONELEVEL && + op->ldop_srch.ldsp_scope != LDAP_SCOPE_SUBTREE ) ) + { + write_result( ofp, LDAP_OTHER, NULL, "Bad scope" ); + return( -1 ); + } + break; + case IP_TYPE_ALIASDEREF: + if ( lutil_atoi( &op->ldop_srch.ldsp_aliasderef, args ) != 0 ) { + write_result( ofp, LDAP_OTHER, NULL, "Bad alias deref" ); + return( -1 ); + } + break; + case IP_TYPE_SIZELIMIT: + if ( lutil_atoi( &op->ldop_srch.ldsp_sizelimit, args ) != 0 ) { + write_result( ofp, LDAP_OTHER, NULL, "Bad size limit" ); + return( -1 ); + } + break; + case IP_TYPE_TIMELIMIT: + if ( lutil_atoi( &op->ldop_srch.ldsp_timelimit, args ) != 0 ) { + write_result( ofp, LDAP_OTHER, NULL, "Bad time limit" ); + return( -1 ); + } + break; + case IP_TYPE_FILTER: + op->ldop_srch.ldsp_filter = estrdup( args ); + break; + case IP_TYPE_ATTRSONLY: + op->ldop_srch.ldsp_attrsonly = ( *args != '0' ); + break; + case IP_TYPE_ATTRS: + if ( strcmp( args, "all" ) == 0 ) { + op->ldop_srch.ldsp_attrs = NULL; + } else { + while ( args != NULL ) { + if (( p = strchr( args, ' ' )) != NULL ) { + *p++ = '\0'; + while ( isspace( (unsigned char) *p )) { + ++p; + } + } + add_strval( &op->ldop_srch.ldsp_attrs, args ); + args = p; + } + } + break; + } + } + + if ( op->ldop_suffixes == NULL || op->ldop_dn == NULL || + op->ldop_srch.ldsp_filter == NULL ) { + write_result( ofp, LDAP_OTHER, NULL, + "Required suffix:, base:, or filter: missing" ); + return( -1 ); + } + + return( 0 ); +} + + +struct inputparams * +find_input_tag( char **linep ) /* linep is set to start of args */ +{ + int i; + char *p; + + if (( p = strchr( *linep, ':' )) == NULL || p == *linep ) { + return( NULL ); + } + + for ( i = 0; ips[ i ].ip_type != 0; ++i ) { + if ( strncasecmp( *linep, ips[ i ].ip_tag, p - *linep ) == 0 ) { + while ( isspace( (unsigned char) *(++p) )) { + ; + } + *linep = p; + return( &ips[ i ] ); + } + } + + return( NULL ); +} + + +void +add_strval( char ***sp, char *val ) +{ + int i; + char **vallist; + + vallist = *sp; + + if ( vallist == NULL ) { + i = 0; + } else { + for ( i = 0; vallist[ i ] != NULL; ++i ) { + ; + } + } + + vallist = (char **)erealloc( vallist, ( i + 2 ) * sizeof( char * )); + vallist[ i ] = estrdup( val ); + vallist[ ++i ] = NULL; + *sp = vallist; +} + + +char * +estrdup( char *s ) +{ + char *p; + + if (( p = strdup( s )) == NULL ) { + debug_printf( "strdup failed\n" ); + exit( EXIT_FAILURE ); + } + + return( p ); +} + + +void * +erealloc( void *s, unsigned size ) +{ + char *p; + + if ( s == NULL ) { + p = malloc( size ); + } else { + p = realloc( s, size ); + } + + if ( p == NULL ) { + debug_printf( "realloc( p, %d ) failed\n", size ); + exit( EXIT_FAILURE ); + } + + return( p ); +} + + +char * +ecalloc( unsigned nelem, unsigned elsize ) +{ + char *p; + + if (( p = calloc( nelem, elsize )) == NULL ) { + debug_printf( "calloc( %d, %d ) failed\n", nelem, elsize ); + exit( EXIT_FAILURE ); + } + + return( p ); +} + + +#ifdef LDAP_DEBUG + +/* VARARGS */ +void +debug_printf( const char *fmt, ... ) +{ + va_list ap; + + if ( debugflg ) { + va_start( ap, fmt ); + fprintf( stderr, "%s: ", progname ); + vfprintf( stderr, fmt, ap ); + va_end( ap ); + } +} + + +void +dump_ldop( struct ldop *op ) +{ + if ( !debugflg ) { + return; + } + + debug_printf( "SEARCH operation\n" ); + if ( op->ldop_suffixes == NULL ) { + debug_printf( " suffix: NONE\n" ); + } else { + int i; + for ( i = 0; op->ldop_suffixes[ i ] != NULL; ++i ) { + debug_printf( " suffix: <%s>\n", op->ldop_suffixes[ i ] ); + } + } + debug_printf( " dn: <%s>\n", op->ldop_dn ); + debug_printf( " scope: <%d>\n", op->ldop_srch.ldsp_scope ); + debug_printf( " filter: <%s>\n", op->ldop_srch.ldsp_filter ); + debug_printf( "aliasderef: <%d>\n", op->ldop_srch.ldsp_aliasderef ); + debug_printf( " sizelimit: <%d>\n", op->ldop_srch.ldsp_sizelimit ); + debug_printf( " timelimit: <%d>\n", op->ldop_srch.ldsp_timelimit ); + debug_printf( " attrsonly: <%d>\n", op->ldop_srch.ldsp_attrsonly ); + if ( op->ldop_srch.ldsp_attrs == NULL ) { + debug_printf( " attrs: ALL\n" ); + } else { + int i; + + for ( i = 0; op->ldop_srch.ldsp_attrs[ i ] != NULL; ++i ) { + debug_printf( " attrs: <%s>\n", op->ldop_srch.ldsp_attrs[ i ] ); + } + } +} +#endif /* LDAP_DEBUG */ |