]> git.sur5r.net Git - openldap/blob - servers/slapd/shell-backends/shellutil.c
Added bdb_attribute and bdb_group ACL support routines
[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                 ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
94 }
95
96
97 int
98 attr_requested( char *name, struct ldop *op )
99 {
100     char        **ap;
101
102     if ( op->ldop_srch.ldsp_attrs == NULL ) {   /* special case */
103         return( 1 );
104     }
105
106     for ( ap = op->ldop_srch.ldsp_attrs; *ap != NULL; ++ap ) {
107         if ( strcasecmp( name, *ap ) == 0 ) {
108             return( 1 );
109         }
110     }
111
112     return( 0 );
113 }
114
115
116 void
117 free_entry( struct ldentry *entry )
118 {
119     struct ldattr       **app;
120     char                **valp;
121
122     free( entry->lde_dn );
123
124     for ( app = entry->lde_attrs; *app != NULL; ++app ) {
125         for ( valp = (*app)->lda_values; *valp != NULL; ++valp ) {
126             free( *valp );
127         }
128         free( (*app)->lda_values );
129         free( (*app)->lda_name );
130     }
131
132     free( entry->lde_attrs );
133     free( entry );
134 }
135
136
137 int
138 parse_input( FILE *ifp, FILE *ofp, struct ldop *op )
139 {
140     char                *p, *args, line[ MAXLINELEN + 1 ];
141     struct inputparams  *ip;
142
143     if ( fgets( line, MAXLINELEN, ifp ) == NULL ) {
144         write_result( ofp, LDAP_OPERATIONS_ERROR, NULL, "Empty Input" );
145     }
146     line[ strlen( line ) - 1 ] = '\0';
147     if ( strncasecmp( line, STR_OP_SEARCH, sizeof( STR_OP_SEARCH ) - 1 )
148             != 0 ) {
149         write_result( ofp, LDAP_UNWILLING_TO_PERFORM, NULL,
150                 "Operation Not Supported" );
151         return( -1 );
152     }
153
154     op->ldop_op = LDOP_SEARCH;
155
156     while ( fgets( line, MAXLINELEN, ifp ) != NULL ) {
157         line[ strlen( line ) - 1 ] = '\0';
158         debug_printf( "<< %s\n", line );
159
160         args = line;
161         if (( ip = find_input_tag( &args )) == NULL ) {
162             debug_printf( "ignoring %s\n", line );
163             continue;
164         }
165
166         switch( ip->ip_type ) {
167         case IP_TYPE_SUFFIX:
168             add_strval( &op->ldop_suffixes, args );
169             break;
170         case IP_TYPE_BASE:
171             op->ldop_dn = estrdup( args );
172             break;
173         case IP_TYPE_SCOPE:
174             if (( op->ldop_srch.ldsp_scope = atoi( args )) != LDAP_SCOPE_BASE &&
175                     op->ldop_srch.ldsp_scope != LDAP_SCOPE_ONELEVEL &&
176                     op->ldop_srch.ldsp_scope != LDAP_SCOPE_SUBTREE ) {
177                 write_result( ofp, LDAP_OPERATIONS_ERROR, NULL, "Bad scope" );
178                 return( -1 );
179             }
180             break;
181         case IP_TYPE_ALIASDEREF:
182             op->ldop_srch.ldsp_aliasderef = atoi( args );
183             break;
184         case IP_TYPE_SIZELIMIT:
185             op->ldop_srch.ldsp_sizelimit = atoi( args );
186             break;
187         case IP_TYPE_TIMELIMIT:
188             op->ldop_srch.ldsp_timelimit = atoi( args );
189             break;
190         case IP_TYPE_FILTER:
191             op->ldop_srch.ldsp_filter = estrdup( args );
192             break;
193         case IP_TYPE_ATTRSONLY:
194             op->ldop_srch.ldsp_attrsonly = ( *args != '0' );
195             break;
196         case IP_TYPE_ATTRS:
197             if ( strcmp( args, "all" ) == 0 ) {
198                 op->ldop_srch.ldsp_attrs = NULL;
199             } else {
200                 while ( args != NULL ) {
201                     if (( p = strchr( args, ' ' )) != NULL ) {
202                         *p++ = '\0';
203                         while ( isspace( (unsigned char) *p )) {
204                             ++p;
205                         }
206                     }
207                     add_strval( &op->ldop_srch.ldsp_attrs, args );
208                     args = p;
209                 }
210             }
211             break;
212         }
213     }
214
215     if ( op->ldop_suffixes == NULL || op->ldop_dn == NULL ||
216                 op->ldop_srch.ldsp_filter == NULL ) {
217         write_result( ofp, LDAP_OPERATIONS_ERROR, NULL,
218                 "Required suffix:, base:, or filter: missing" );
219         return( -1 );
220     }
221
222     return( 0 );
223 }
224
225
226 struct inputparams *
227 find_input_tag( char **linep )  /* linep is set to start of args */
228 {
229     int         i;
230     char        *p;
231
232     if (( p = strchr( *linep, ':' )) == NULL || p == *linep ) {
233         return( NULL );
234     }
235
236     for ( i = 0; ips[ i ].ip_type != 0; ++i ) {
237         if ( strncasecmp( *linep, ips[ i ].ip_tag, p - *linep ) == 0 ) {
238             while ( isspace( (unsigned char) *(++p) )) {
239                 ;
240             }
241             *linep = p;
242             return( &ips[ i ] );
243         }
244     }
245
246     return( NULL );
247 }
248
249
250 void
251 add_strval( char ***sp, char *val )
252 {
253     int         i;
254     char        **vallist;
255
256     vallist = *sp;
257
258     if ( vallist == NULL ) {
259         i = 0;
260     } else {
261         for ( i = 0; vallist[ i ] != NULL; ++i ) {
262             ;
263         }
264     }
265
266     vallist = (char **)erealloc( vallist, ( i + 2 ) * sizeof( char * ));
267     vallist[ i ] = estrdup( val );
268     vallist[ ++i ] = NULL;
269     *sp = vallist;
270 }
271
272
273 char *
274 estrdup( char *s )
275 {
276     char        *p;
277
278     if (( p = strdup( s )) == NULL ) {
279         debug_printf( "strdup failed\n" );
280         exit( EXIT_FAILURE );
281     }
282
283     return( p );
284 }
285
286
287 void *
288 erealloc( void *s, unsigned size )
289 {
290     char        *p;
291
292     if ( s == NULL ) {
293         p = malloc( size );
294     } else {
295         p = realloc( s, size );
296     }
297
298     if ( p == NULL ) {
299         debug_printf( "realloc( p, %d ) failed\n", size );
300         exit( EXIT_FAILURE );
301     }
302
303     return( p );
304 }
305
306
307 char *
308 ecalloc( unsigned nelem, unsigned elsize )
309 {
310     char        *p;
311
312     if (( p = calloc( nelem, elsize )) == NULL ) {
313         debug_printf( "calloc( %d, %d ) failed\n", nelem, elsize );
314         exit( EXIT_FAILURE );
315     }
316
317     return( p );
318 }
319
320
321 #ifdef LDAP_DEBUG
322
323 /* VARARGS */
324 void
325 debug_printf( const char *fmt, ... )
326 {
327     va_list     ap;
328
329         if ( debugflg ) {
330                 va_start( ap, fmt );
331                 fprintf( stderr, "%s: ", progname );
332                 vfprintf( stderr, fmt, ap );
333                 va_end( ap );
334         }
335 }
336
337
338 void
339 dump_ldop( struct ldop *op )
340 {
341     if ( !debugflg ) {
342         return;
343     }
344
345     debug_printf( "SEARCH operation\n" );
346     if ( op->ldop_suffixes == NULL ) {
347         debug_printf( "    suffix: NONE\n" );
348     } else {
349         int     i;
350         for ( i = 0; op->ldop_suffixes[ i ] != NULL; ++i ) {
351             debug_printf( "    suffix: <%s>\n", op->ldop_suffixes[ i ] );
352         }
353     }
354     debug_printf( "        dn: <%s>\n", op->ldop_dn );
355     debug_printf( "     scope: <%d>\n", op->ldop_srch.ldsp_scope );
356     debug_printf( "    filter: <%s>\n", op->ldop_srch.ldsp_filter );
357     debug_printf( "aliasderef: <%d>\n", op->ldop_srch.ldsp_aliasderef );
358     debug_printf( " sizelimit: <%d>\n", op->ldop_srch.ldsp_sizelimit );
359     debug_printf( " timelimit: <%d>\n", op->ldop_srch.ldsp_timelimit );
360     debug_printf( " attrsonly: <%d>\n", op->ldop_srch.ldsp_attrsonly );
361     if ( op->ldop_srch.ldsp_attrs == NULL ) {
362         debug_printf( "     attrs: ALL\n" );
363     } else {
364         int     i;
365
366         for ( i = 0; op->ldop_srch.ldsp_attrs[ i ] != NULL; ++i ) {
367             debug_printf( "  attrs: <%s>\n", op->ldop_srch.ldsp_attrs[ i ] );
368         }
369     }
370 }
371 #endif /* LDAP_DEBUG */