]> git.sur5r.net Git - openldap/blob - servers/slapd/shell-backends/shellutil.c
4f7b4690433b21c92f4518ed1ddaeb245754204c
[openldap] / servers / slapd / shell-backends / shellutil.c
1 /*
2  shellutil.c - common routines useful when building shell-based backends
3                  for the standalone ldap server
4
5  Copyright (c) 1995 Regents of the University of Michigan.
6  All rights reserved.
7
8  Redistribution and use in source and binary forms are permitted
9  provided that this notice is preserved and that due credit is given
10  to the University of Michigan at Ann Arbor. The name of the University
11  may not be used to endorse or promote products derived from this
12  software without specific prior written permission. This software
13  is provided ``as is'' without express or implied warranty.
14 */
15
16
17 #include "portable.h"
18
19 #include <stdio.h>
20
21 #ifdef STDC_HEADERS
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #else
25 #include <varargs.h>
26 #endif
27
28 #include <pwd.h>
29
30 #include <ac/string.h>
31
32 #include <lber.h>
33 #include <ldap.h>
34 #include "shellutil.h"
35
36
37 int     debugflg;
38 char    *progname;
39
40 static struct inputparams       ips[] = {
41     IP_TYPE_SUFFIX,     "suffix",
42     IP_TYPE_BASE,       "base",
43     IP_TYPE_SCOPE,      "scope",
44     IP_TYPE_ALIASDEREF, "deref",
45     IP_TYPE_SIZELIMIT,  "sizelimit",
46     IP_TYPE_TIMELIMIT,  "timelimit",
47     IP_TYPE_FILTER,     "filter",
48     IP_TYPE_ATTRS,      "attrs",
49     IP_TYPE_ATTRSONLY,  "attrsonly",
50     0,                  NULL
51 };
52
53
54 void
55 write_result( FILE *fp, int code, char *matched, char *info )
56 {
57     fprintf( fp, "RESULT\ncode: %d\n", code );
58     debug_printf( ">> RESULT\n" );
59     debug_printf( ">> code: %d\n", code );
60
61     if ( matched != NULL ) {
62         fprintf( fp, "matched: %s\n", matched );
63         debug_printf( ">> matched: %s\n", matched );
64     }
65
66     if ( info != NULL ) {
67         fprintf( fp, "info: %s\n", info );
68         debug_printf( ">> info: %s\n", info );
69     }
70 }
71
72
73 void
74 write_entry( struct ldop *op, struct ldentry *entry, FILE *ofp )
75 {
76     struct ldattr       **app;
77     char                **valp;
78
79     fprintf( ofp, "dn: %s\n", entry->lde_dn );
80     for ( app = entry->lde_attrs; *app != NULL; ++app ) {
81         if ( attr_requested( (*app)->lda_name, op )) {
82             for ( valp = (*app)->lda_values; *valp != NULL; ++valp ) {
83                 fprintf( ofp, "%s: %s\n", (*app)->lda_name, *valp );
84             }
85         }
86     }
87     fputc( '\n', ofp );
88 }
89
90
91 int
92 test_filter( struct ldop *op, struct ldentry *entry )
93 {
94     return (( random() & 0x07 ) == 0x07 );      /* XXX random for now */
95 }
96
97
98 int
99 attr_requested( char *name, struct ldop *op )
100 {
101     char        **ap;
102
103     if ( op->ldop_srch.ldsp_attrs == NULL ) {   /* special case */
104         return( 1 );
105     }
106
107     for ( ap = op->ldop_srch.ldsp_attrs; *ap != NULL; ++ap ) {
108         if ( strcasecmp( name, *ap ) == 0 ) {
109             return( 1 );
110         }
111     }
112
113     return( 0 );
114 }
115
116
117 void
118 free_entry( struct ldentry *entry )
119 {
120     struct ldattr       **app;
121     char                **valp;
122
123     free( entry->lde_dn );
124
125     for ( app = entry->lde_attrs; *app != NULL; ++app ) {
126         for ( valp = (*app)->lda_values; *valp != NULL; ++valp ) {
127             free( *valp );
128         }
129         free( (*app)->lda_values );
130         free( (*app)->lda_name );
131     }
132
133     free( entry->lde_attrs );
134     free( entry );
135 }
136
137
138 int
139 parse_input( FILE *ifp, FILE *ofp, struct ldop *op )
140 {
141     char                *p, *args, line[ MAXLINELEN + 1 ];
142     struct inputparams  *ip;
143
144     if ( fgets( line, MAXLINELEN, ifp ) == NULL ) {
145         write_result( ofp, LDAP_OPERATIONS_ERROR, NULL, "Empty Input" );
146     }
147     line[ strlen( line ) - 1 ] = '\0';
148     if ( strncasecmp( line, STR_OP_SEARCH, sizeof( STR_OP_SEARCH ) - 1 )
149             != 0 ) {
150         write_result( ofp, LDAP_UNWILLING_TO_PERFORM, NULL,
151                 "Operation Not Supported" );
152         return( -1 );
153     }
154
155     op->ldop_op = LDOP_SEARCH;
156
157     while ( fgets( line, MAXLINELEN, ifp ) != NULL ) {
158         line[ strlen( line ) - 1 ] = '\0';
159         debug_printf( "<< %s\n", line );
160
161         args = line;
162         if (( ip = find_input_tag( &args )) == NULL ) {
163             debug_printf( "ignoring %s\n", line );
164             continue;
165         }
166
167         switch( ip->ip_type ) {
168         case IP_TYPE_SUFFIX:
169             add_strval( &op->ldop_suffixes, args );
170             break;
171         case IP_TYPE_BASE:
172             op->ldop_dn = estrdup( args );
173             break;
174         case IP_TYPE_SCOPE:
175             if (( op->ldop_srch.ldsp_scope = atoi( args )) != LDAP_SCOPE_BASE &&
176                     op->ldop_srch.ldsp_scope != LDAP_SCOPE_ONELEVEL &&
177                     op->ldop_srch.ldsp_scope != LDAP_SCOPE_SUBTREE ) {
178                 write_result( ofp, LDAP_OPERATIONS_ERROR, NULL, "Bad scope" );
179                 return( -1 );
180             }
181             break;
182         case IP_TYPE_ALIASDEREF:
183             op->ldop_srch.ldsp_aliasderef = atoi( args );
184             break;
185         case IP_TYPE_SIZELIMIT:
186             op->ldop_srch.ldsp_sizelimit = atoi( args );
187             break;
188         case IP_TYPE_TIMELIMIT:
189             op->ldop_srch.ldsp_timelimit = atoi( args );
190             break;
191         case IP_TYPE_FILTER:
192             op->ldop_srch.ldsp_filter = estrdup( args );
193             break;
194         case IP_TYPE_ATTRSONLY:
195             op->ldop_srch.ldsp_attrsonly = ( *args != '0' );
196             break;
197         case IP_TYPE_ATTRS:
198             if ( strcmp( args, "all" ) == 0 ) {
199                 op->ldop_srch.ldsp_attrs = NULL;
200             } else {
201                 while ( args != NULL ) {
202                     if (( p = strchr( args, ' ' )) != NULL ) {
203                         *p++ = '\0';
204                         while ( isspace( *p )) {
205                             ++p;
206                         }
207                     }
208                     add_strval( &op->ldop_srch.ldsp_attrs, args );
209                     args = p;
210                 }
211             }
212             break;
213         }
214     }
215
216     if ( op->ldop_suffixes == NULL || op->ldop_dn == NULL ||
217                 op->ldop_srch.ldsp_filter == NULL ) {
218         write_result( ofp, LDAP_OPERATIONS_ERROR, NULL,
219                 "Required suffix:, base:, or filter: missing" );
220         return( -1 );
221     }
222
223     return( 0 );
224 }
225
226
227 struct inputparams *
228 find_input_tag( char **linep )  /* linep is set to start of args */
229 {
230     int         i;
231     char        *p;
232
233     if (( p = strchr( *linep, ':' )) == NULL || p == *linep ) {
234         return( NULL );
235     }
236
237     for ( i = 0; ips[ i ].ip_type != 0; ++i ) {
238         if ( strncasecmp( *linep, ips[ i ].ip_tag, p - *linep ) == 0 ) {
239             while ( isspace( *(++p) )) {
240                 ;
241             }
242             *linep = p;
243             return( &ips[ i ] );
244         }
245     }
246
247     return( NULL );
248 }
249
250
251 void
252 add_strval( char ***sp, char *val )
253 {
254     int         i;
255     char        **vallist;
256
257     vallist = *sp;
258
259     if ( vallist == NULL ) {
260         i = 0;
261     } else {
262         for ( i = 0; vallist[ i ] != NULL; ++i ) {
263             ;
264         }
265     }
266
267     vallist = (char **)erealloc( vallist, ( i + 2 ) * sizeof( char * ));
268     vallist[ i ] = estrdup( val );
269     vallist[ ++i ] = NULL;
270     *sp = vallist;
271 }
272
273
274 char *
275 estrdup( char *s )
276 {
277     char        *p;
278
279     if (( p = strdup( s )) == NULL ) {
280         debug_printf( "strdup failed\n" );
281         exit( 1 );
282     }
283
284     return( p );
285 }
286
287
288 void *
289 erealloc( void *s, unsigned size )
290 {
291     char        *p;
292
293     if ( s == NULL ) {
294         p = malloc( size );
295     } else {
296         p = realloc( s, size );
297     }
298
299     if ( p == NULL ) {
300         debug_printf( "realloc( p, %d ) failed\n", size );
301         exit( 1 );
302     }
303
304     return( p );
305 }
306
307
308 char *
309 ecalloc( unsigned nelem, unsigned elsize )
310 {
311     char        *p;
312
313     if (( p = calloc( nelem, elsize )) == NULL ) {
314         debug_printf( "calloc( %d, %d ) failed\n", nelem, elsize );
315         exit( 1 );
316     }
317
318     return( p );
319 }
320
321
322 #ifdef LDAP_DEBUG
323
324 /* VARARGS */
325 void
326 debug_printf
327 #ifdef STDC_HEADERS
328         ( char *fmt, ... )
329 #else
330         ( va_alist )
331     va_dcl
332 #endif
333 {
334     va_list     ap;
335 #ifndef STDC_HEADERS
336     char        *fmt;
337 #endif
338
339         if ( debugflg ) {
340 #ifdef STDC_HEADERS
341                 va_start( ap, fmt );
342 #else
343                 va_start( ap );
344                 fmt = va_arg( ap, char * );
345 #endif
346                 fprintf( stderr, "%s: ", progname );
347                 vfprintf( stderr, fmt, ap );
348                 va_end( ap );
349         }
350 }
351
352
353 void
354 dump_ldop( struct ldop *op )
355 {
356     if ( !debugflg ) {
357         return;
358     }
359
360     debug_printf( "SEARCH operation\n" );
361     if ( op->ldop_suffixes == NULL ) {
362         debug_printf( "    suffix: NONE\n" );
363     } else {
364         int     i;
365         for ( i = 0; op->ldop_suffixes[ i ] != NULL; ++i ) {
366             debug_printf( "    suffix: <%s>\n", op->ldop_suffixes[ i ] );
367         }
368     }
369     debug_printf( "        dn: <%s>\n", op->ldop_dn );
370     debug_printf( "     scope: <%d>\n", op->ldop_srch.ldsp_scope );
371     debug_printf( "    filter: <%s>\n", op->ldop_srch.ldsp_filter );
372     debug_printf( "aliasderef: <%d>\n", op->ldop_srch.ldsp_aliasderef );
373     debug_printf( " sizelimit: <%d>\n", op->ldop_srch.ldsp_sizelimit );
374     debug_printf( " timelimit: <%d>\n", op->ldop_srch.ldsp_timelimit );
375     debug_printf( " attrsonly: <%d>\n", op->ldop_srch.ldsp_attrsonly );
376     if ( op->ldop_srch.ldsp_attrs == NULL ) {
377         debug_printf( "     attrs: ALL\n" );
378     } else {
379         int     i;
380
381         for ( i = 0; op->ldop_srch.ldsp_attrs[ i ] != NULL; ++i ) {
382             debug_printf( "  attrs: <%s>\n", op->ldop_srch.ldsp_attrs[ i ] );
383         }
384     }
385 }
386 #endif /* LDAP_DEBUG */