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