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