]> git.sur5r.net Git - openldap/blobdiff - servers/slurpd/config.c
implement add/delete granularity in write access (ITS#3631)
[openldap] / servers / slurpd / config.c
index 308a4edd42104e28eb5cf928f926cf734dec297c..71934ce59efc95a1555eb6720e3063d7254a51c9 100644 (file)
@@ -1,10 +1,20 @@
 /* $OpenLDAP$ */
-/*
- * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Portions Copyright 2003 Mark Benson.
+ * Portions Copyright 2002 John Morrissey.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
  */
-/*
- * Copyright (c) 1996 Regents of the University of Michigan.
+/* Portions Copyright (c) 1996 Regents of the University of Michigan.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
  * software without specific prior written permission. This software
  * is provided ``as is'' without express or implied warranty.
  */
+/* ACKNOWLEDGEMENTS:
+ * This work was originally developed by the University of Michigan
+ * (as part of U-MICH LDAP).  Additional signficant contributors
+ * include:
+ *    John Morrissey
+ *    Mark Benson
+ */
 
 
 /*
 #include <ac/ctype.h>
 
 #include <ldap.h>
+#include <lutil.h>
 
 #include "slurp.h"
 #include "globals.h"
 
-#define MAXARGS        100
+#define ARGS_STEP      512
 
 /* Forward declarations */
 static void    add_replica LDAP_P(( char **, int ));
 static int     parse_replica_line LDAP_P(( char **, int, Ri *));
-static void    parse_line LDAP_P(( char *, int *, char ** ));
+static void    parse_line LDAP_P(( char * ));
 static char    *getline LDAP_P(( FILE * ));
 static char    *strtok_quote LDAP_P(( char *, char * ));
 
+int    cargc = 0, cargv_size = 0;
+char   **cargv;
 /* current config file line # */
 static int     lineno;
 
-
+char *slurpd_pid_file = NULL;
+char *slurpd_args_file = NULL;
 
 /*
  * Read the slapd config file, looking only for config options we're
@@ -60,8 +81,11 @@ slurpd_read_config(
 {
     FILE       *fp;
     char       *line;
-    int                cargc;
-    char       *cargv[MAXARGS];
+
+       if ( cargv == NULL ) {
+       cargv = ch_calloc( ARGS_STEP + 1, sizeof(*cargv) );
+       cargv_size = ARGS_STEP + 1;
+       }
 
     Debug( LDAP_DEBUG_CONFIG, "Config: opening config file \"%s\"\n",
            fname, 0, 0 );
@@ -80,7 +104,7 @@ slurpd_read_config(
 
        Debug( LDAP_DEBUG_CONFIG, "Config: (%s)\n", line, 0, 0 );
 
-       parse_line( line, &cargc, cargv );
+       parse_line( line );
 
        if ( cargc < 1 ) {
            fprintf( stderr, "line %d: bad config line (ignored)\n", lineno );
@@ -107,6 +131,7 @@ slurpd_read_config(
                        lineno, cargv[1] );
                    fprintf( stderr, "line (ignored)\n" );
                }
+               LUTIL_SLASHPATH( cargv[1] );
                strcpy( sglob->slapd_replogfile, cargv[1] );
            }
        } else if ( strcasecmp( cargv[0], "replica" ) == 0 ) {
@@ -118,18 +143,13 @@ slurpd_read_config(
            int savelineno;
 
             if ( cargc < 2 ) {
-#ifdef NEW_LOGGING
-                LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
-                        "%s: line %d: missing filename in \"include "
-                        "<filename>\" line.\n", fname, lineno ));
-#else
                 Debug( LDAP_DEBUG_ANY,
         "%s: line %d: missing filename in \"include <filename>\" line\n",
                         fname, lineno, 0 );
-#endif
                
                 return( 1 );
             }
+           LUTIL_SLASHPATH( cargv[1] );
            savefname = strdup( cargv[1] );
            savelineno = lineno;
            
@@ -139,7 +159,51 @@ slurpd_read_config(
                
            free( savefname );
            lineno = savelineno - 1;
-       }
+
+       } else if ( strcasecmp( cargv[0], "replica-pidfile" ) == 0 ) {
+               if ( cargc < 2 ) {
+                       Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: missing file name in \"replica-pidfile <file>\" line\n",
+                               fname, lineno, 0 );
+
+                       return( 1 );
+               }
+
+               LUTIL_SLASHPATH( cargv[1] );
+               slurpd_pid_file = ch_strdup( cargv[1] );
+
+       } else if ( strcasecmp( cargv[0], "replica-argsfile" ) == 0 ) {
+               if ( cargc < 2 ) {
+                       Debug( LDAP_DEBUG_ANY,
+           "%s: line %d: missing file name in \"argsfile <file>\" line\n",
+                           fname, lineno, 0 );
+
+                       return( 1 );
+               }
+
+               LUTIL_SLASHPATH( cargv[1] );
+               slurpd_args_file = ch_strdup( cargv[1] );
+
+               } else if ( strcasecmp( cargv[0], "replicationinterval" ) == 0 ) {
+                       int c;
+                       if ( cargc < 2 ) {
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: missing interval in "
+                                       "\"replicationinterval <seconds>\" line\n",
+                                       fname, lineno, 0 );
+                               return( 1 );
+                       }
+
+                       c = atoi( cargv[1] );
+                       if( c < 1 ) {
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: invalid interval "
+                                       "(%d) in \"replicationinterval <seconds>\" line\n",
+                                       fname, lineno, c );
+
+                               return( 1 );
+                       }
+
+                       sglob->no_work_interval = c;
+               }
     }
     fclose( fp );
     Debug( LDAP_DEBUG_CONFIG,
@@ -156,19 +220,30 @@ slurpd_read_config(
  */
 static void
 parse_line(
-    char       *line,
-    int                *argcp,
-    char       **argv
+    char       *line
 )
 {
     char *     token;
 
-    *argcp = 0;
+    cargc = 0;
     for ( token = strtok_quote( line, " \t" ); token != NULL;
-       token = strtok_quote( NULL, " \t" ) ) {
-       argv[(*argcp)++] = token;
+       token = strtok_quote( NULL, " \t" ) )
+    {
+        if ( cargc == cargv_size - 1 ) {
+           char **tmp;
+            tmp = ch_realloc( cargv, (cargv_size + ARGS_STEP) *
+                               sizeof(*cargv) );
+           if (tmp == NULL) {
+               cargc = 0;
+               return;
+           }
+           cargv = tmp;
+            cargv_size += ARGS_STEP;
+        }
+
+       cargv[cargc++] = token;
     }
-    argv[*argcp] = NULL;
+    cargv[cargc] = NULL;
 }
 
 
@@ -259,13 +334,17 @@ getline(
     CATLINE( buf );
     while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
        if ( (p = strchr( buf, '\n' )) != NULL ) {
-           *p = '\0';
+               if( p > buf && p[-1] == '\r' ) --p;       
+               *p = '\0';
        }
        lineno++;
        if ( ! isspace( (unsigned char) buf[0] ) ) {
            return( line );
        }
 
+       /* change leading whitespace to space */
+       buf[0] = ' ';
+
        CATLINE( buf );
     }
     buf[0] = '\0';
@@ -363,10 +442,17 @@ parse_replica_line(
     int                gots = 0;
     int                i;
     char       *hp, *val;
+    LDAPURLDesc *ludp;
 
     for ( i = 1; i < cargc; i++ ) {
-       if ( !strncasecmp( cargv[ i ], HOSTSTR, strlen( HOSTSTR ))) {
-           val = cargv[ i ] + strlen( HOSTSTR ) + 1;
+       if ( !strncasecmp( cargv[ i ], HOSTSTR, sizeof( HOSTSTR ) - 1 ) ) {
+               if ( gots & GOT_HOST ) {
+                       fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
+                       fprintf( stderr, "file, too many host or uri names specified, line %d\n",
+                               lineno );
+                       return -1;
+               }       
+           val = cargv[ i ] + sizeof( HOSTSTR ); /* '\0' string terminator accounts for '=' */
            if (( hp = strchr( val, ':' )) != NULL ) {
                *hp = '\0';
                hp++;
@@ -377,62 +463,105 @@ parse_replica_line(
            }
            ri->ri_hostname = strdup( val );
            gots |= GOT_HOST;
-       } else if ( !strncasecmp( cargv[ i ], SUFFIXSTR, strlen( HOSTSTR ))) {
+       } else if ( !strncasecmp( cargv[ i ], URISTR, sizeof( URISTR ) - 1 ) ) {
+               if ( gots & GOT_HOST ) {
+                       fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
+                       fprintf( stderr, "file, too many host or uri names specified, line %d\n",
+                               lineno );
+                       return -1;
+               }               
+               if ( ldap_url_parse( cargv[ i ] + sizeof( URISTR ), &ludp ) != LDAP_SUCCESS ) {
+                       fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
+                       fprintf( stderr, "file, bad uri format specified, line %d\n",
+                               lineno );
+                       return -1;
+               }
+               if (ludp->lud_host == NULL) {
+                       fprintf( stderr, "Error: Malformed \"replica\" line in slapd config " );
+                       fprintf( stderr, "file, missing uri hostname, line %d\n",
+                               lineno );
+                       return -1;
+               }
+               ri->ri_hostname = strdup ( ludp->lud_host );
+               ri->ri_port = ludp->lud_port;
+               ri->ri_uri = strdup ( cargv[ i ] + sizeof( URISTR ) );          
+               ldap_free_urldesc( ludp );                              
+           gots |= GOT_HOST;
+       } else if ( !strncasecmp( cargv[ i ], 
+                       ATTRSTR, sizeof( ATTRSTR ) - 1 ) ) {
+           /* ignore it */ ;
+       } else if ( !strncasecmp( cargv[ i ], 
+                       SUFFIXSTR, sizeof( SUFFIXSTR ) - 1 ) ) {
            /* ignore it */ ;
-       } else if ( !strncasecmp( cargv[ i ], TLSSTR, strlen( TLSSTR ))) {
-           val = cargv[ i ] + strlen( TLSSTR ) + 1;
-               if( !strcasecmp( val, TLSCRITICALSTR ) ) {
+       } else if ( !strncasecmp( cargv[i], STARTTLSSTR, sizeof(STARTTLSSTR)-1 )) {
+           val = cargv[ i ] + sizeof( STARTTLSSTR );
+               if( !strcasecmp( val, CRITICALSTR ) ) {
+                       ri->ri_tls = TLS_CRITICAL;
+               } else {
+                       ri->ri_tls = TLS_ON;
+               }
+       } else if ( !strncasecmp( cargv[ i ], TLSSTR, sizeof( TLSSTR ) - 1 ) ) {
+           val = cargv[ i ] + sizeof( TLSSTR );
+               if( !strcasecmp( val, CRITICALSTR ) ) {
                        ri->ri_tls = TLS_CRITICAL;
                } else {
                        ri->ri_tls = TLS_ON;
                }
        } else if ( !strncasecmp( cargv[ i ],
-               BINDDNSTR, strlen( BINDDNSTR ))) { 
-           val = cargv[ i ] + strlen( BINDDNSTR ) + 1;
+                       BINDDNSTR, sizeof( BINDDNSTR ) - 1 ) ) { 
+           val = cargv[ i ] + sizeof( BINDDNSTR );
            ri->ri_bind_dn = strdup( val );
            gots |= GOT_DN;
        } else if ( !strncasecmp( cargv[ i ], BINDMETHSTR,
-               strlen( BINDMETHSTR ))) {
-           val = cargv[ i ] + strlen( BINDMETHSTR ) + 1;
+               sizeof( BINDMETHSTR ) - 1 ) ) {
+           val = cargv[ i ] + sizeof( BINDMETHSTR );
            if ( !strcasecmp( val, KERBEROSSTR )) {
            fprintf( stderr, "Error: a bind method of \"kerberos\" was\n" );
            fprintf( stderr, "specified in the slapd configuration file.\n" );
            fprintf( stderr, "slurpd no longer supports Kerberos.\n" );
            exit( EXIT_FAILURE );
            } else if ( !strcasecmp( val, SIMPLESTR )) {
-               ri->ri_bind_method = AUTH_SIMPLE;
+               ri->ri_bind_method = LDAP_AUTH_SIMPLE;
                gots |= GOT_METHOD;
            } else if ( !strcasecmp( val, SASLSTR )) {
-               ri->ri_bind_method = AUTH_SASL;
+               ri->ri_bind_method = LDAP_AUTH_SASL;
                gots |= GOT_METHOD;
            } else {
                ri->ri_bind_method = -1;
            }
-       } else if ( !strncasecmp( cargv[ i ], SASLMECHSTR, strlen( SASLMECHSTR ))) {
-           val = cargv[ i ] + strlen( SASLMECHSTR ) + 1;
+       } else if ( !strncasecmp( cargv[ i ], 
+                       SASLMECHSTR, sizeof( SASLMECHSTR ) - 1 ) ) {
+           val = cargv[ i ] + sizeof( SASLMECHSTR );
            gots |= GOT_MECH;
            ri->ri_saslmech = strdup( val );
-       } else if ( !strncasecmp( cargv[ i ], CREDSTR, strlen( CREDSTR ))) {
-           val = cargv[ i ] + strlen( CREDSTR ) + 1;
+       } else if ( !strncasecmp( cargv[ i ], 
+                       CREDSTR, sizeof( CREDSTR ) - 1 ) ) {
+           val = cargv[ i ] + sizeof( CREDSTR );
            ri->ri_password = strdup( val );
-       } else if ( !strncasecmp( cargv[ i ], SECPROPSSTR, strlen( SECPROPSSTR ))) {
-           val = cargv[ i ] + strlen( SECPROPSSTR ) + 1;
+       } else if ( !strncasecmp( cargv[ i ], 
+                       SECPROPSSTR, sizeof( SECPROPSSTR ) - 1 ) ) {
+           val = cargv[ i ] + sizeof( SECPROPSSTR );
            ri->ri_secprops = strdup( val );
-       } else if ( !strncasecmp( cargv[ i ], REALMSTR, strlen( REALMSTR ))) {
-           val = cargv[ i ] + strlen( REALMSTR ) + 1;
+       } else if ( !strncasecmp( cargv[ i ], 
+                       REALMSTR, sizeof( REALMSTR ) - 1 ) ) {
+           val = cargv[ i ] + sizeof( REALMSTR );
            ri->ri_realm = strdup( val );
-       } else if ( !strncasecmp( cargv[ i ], AUTHCSTR, strlen( AUTHCSTR ))) {
-           val = cargv[ i ] + strlen( AUTHCSTR ) + 1;
+       } else if ( !strncasecmp( cargv[ i ], 
+                       AUTHCSTR, sizeof( AUTHCSTR ) - 1 ) ) {
+           val = cargv[ i ] + sizeof( AUTHCSTR );
            ri->ri_authcId = strdup( val );
-       } else if ( !strncasecmp( cargv[ i ], OLDAUTHCSTR, strlen( OLDAUTHCSTR ))) {
+       } else if ( !strncasecmp( cargv[ i ], 
+                       OLDAUTHCSTR, sizeof( OLDAUTHCSTR ) - 1 ) ) {
            /* Old authcID is provided for some backwards compatibility */
-           val = cargv[ i ] + strlen( OLDAUTHCSTR ) + 1;
+           val = cargv[ i ] + sizeof( OLDAUTHCSTR );
            ri->ri_authcId = strdup( val );
-       } else if ( !strncasecmp( cargv[ i ], AUTHZSTR, strlen( AUTHZSTR ))) {
-           val = cargv[ i ] + strlen( AUTHZSTR ) + 1;
+       } else if ( !strncasecmp( cargv[ i ], 
+                       AUTHZSTR, sizeof( AUTHZSTR ) - 1 ) ) {
+           val = cargv[ i ] + sizeof( AUTHZSTR );
            ri->ri_authzId = strdup( val );
-       } else if ( !strncasecmp( cargv[ i ], SRVTABSTR, strlen( SRVTABSTR ))) {
-           val = cargv[ i ] + strlen( SRVTABSTR ) + 1;
+       } else if ( !strncasecmp( cargv[ i ], 
+                       SRVTABSTR, sizeof( SRVTABSTR ) - 1 ) ) {
+           val = cargv[ i ] + sizeof( SRVTABSTR );
            if ( ri->ri_srvtab != NULL ) {
                free( ri->ri_srvtab );
            }
@@ -444,14 +573,13 @@ parse_replica_line(
        }
     }
     
-       if ( ri->ri_bind_method == AUTH_SASL) {
+       if ( ri->ri_bind_method == LDAP_AUTH_SASL) {
                if ((gots & GOT_MECH) == 0) {
                        fprintf( stderr, "Error: \"replica\" line needs SASLmech flag in " );
                        fprintf( stderr, "slapd config file, line %d\n", lineno );
                        return -1;
                }
-       }
-       else if ( gots != GOT_ALL ) {
+       } else if ( gots != GOT_ALL ) {
                fprintf( stderr, "Error: Malformed \"replica\" line in slapd " );
                fprintf( stderr, "config file, line %d\n", lineno );
                return -1;