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