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