]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/config.c
ITS#8845 Recognise control-exop compatibility
[openldap] / servers / slapd / config.c
index cdc17d9e77900dffb4d0237986ab75a6650948dc..67ad0243664b1001decb44e7b1bb2bd18c8b3723 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2014 The OpenLDAP Foundation.
+ * Copyright 1998-2018 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -94,7 +94,7 @@ int slapi_plugins_used = 0;
 static int fp_getline(FILE *fp, ConfigArgs *c);
 static void fp_getline_init(ConfigArgs *c);
 
-static char    *strtok_quote(char *line, char *sep, char **quote_ptr);
+static char    *strtok_quote(char *line, char *sep, char **quote_ptr, int *inquote);
 static char *strtok_quote_ldif(char **line);
 
 ConfigArgs *
@@ -126,6 +126,19 @@ ConfigTable *config_find_keyword(ConfigTable *Conf, ConfigArgs *c) {
                if( (Conf[i].length && (!strncasecmp(c->argv[0], Conf[i].name, Conf[i].length))) ||
                        (!strcasecmp(c->argv[0], Conf[i].name)) ) break;
        if ( !Conf[i].name ) return NULL;
+       if (( Conf[i].arg_type & ARGS_TYPES ) == ARG_BINARY ) {
+               size_t decode_len = LUTIL_BASE64_DECODE_LEN(c->linelen);
+               ch_free( c->tline );
+               c->tline = ch_malloc( decode_len+1 );
+               c->linelen = lutil_b64_pton( c->line, c->tline, decode_len );
+               if ( c->linelen < 0 )
+               {
+                       ch_free( c->tline );
+                       c->tline = NULL;
+                       return NULL;
+               }
+               c->line = c->tline;
+       }
        return Conf+i;
 }
 
@@ -210,6 +223,13 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) {
                assert( c->argc == 2 );
                if ( !check_only )
                        ber_str2bv( c->argv[1], 0, 1, &c->value_bv );
+       } else if(arg_type == ARG_BINARY) {
+               assert( c->argc == 2 );
+               if ( !check_only ) {
+                       c->value_bv.bv_len = c->linelen;
+                       c->value_bv.bv_val = ch_malloc( c->linelen );
+                       AC_MEMCPY( c->value_bv.bv_val, c->line, c->linelen );
+               }
        } else if(arg_type == ARG_DN) {
                struct berval bv;
                assert( c->argc == 2 );
@@ -403,6 +423,7 @@ int config_set_vals(ConfigTable *Conf, ConfigArgs *c) {
                                break;
                                }
                        case ARG_BERVAL:
+                       case ARG_BINARY:
                                *(struct berval *)ptr = c->value_bv;
                                break;
                        case ARG_ATDESC:
@@ -551,6 +572,10 @@ init_config_attrs(ConfigTable *ct) {
                        fprintf( stderr, "init_config_attrs: register_at failed\n" );
                        return code;
                }
+               if (( ct[i].arg_type & ARGS_TYPES ) == ARG_BINARY ) {
+                       ldif_must_b64_encode_register( ct[i].ad->ad_cname.bv_val,
+                               ct[i].ad->ad_type->sat_oid );
+               }
        }
 
        return 0;
@@ -628,7 +653,7 @@ strtok_quote_ldif( char **line )
        return beg;
 }
 
-static void
+void
 config_parse_ldif( ConfigArgs *c )
 {
        char *next;
@@ -651,13 +676,15 @@ int
 config_parse_vals(ConfigTable *ct, ConfigArgs *c, int valx)
 {
        int     rc = 0;
+       int arg_type = ct->arg_type & ARGS_TYPES;
 
        snprintf( c->log, sizeof( c->log ), "%s: value #%d",
                ct->ad->ad_cname.bv_val, valx );
        c->argc = 1;
        c->argv[0] = ct->ad->ad_cname.bv_val;
 
-       if ( ( ct->arg_type & ARG_QUOTE ) && c->line[ 0 ] != '"' ) {
+       if ( (( ct->arg_type & ARG_QUOTE ) && c->line[ 0 ] != '"' ) ||
+               (arg_type == ARG_BERVAL || arg_type == ARG_BINARY)) {
                c->argv[c->argc] = c->line;
                c->argc++;
                c->argv[c->argc] = NULL;
@@ -679,13 +706,15 @@ int
 config_parse_add(ConfigTable *ct, ConfigArgs *c, int valx)
 {
        int     rc = 0;
+       int arg_type = ct->arg_type & ARGS_TYPES;
 
        snprintf( c->log, sizeof( c->log ), "%s: value #%d",
                ct->ad->ad_cname.bv_val, valx );
        c->argc = 1;
        c->argv[0] = ct->ad->ad_cname.bv_val;
 
-       if ( ( ct->arg_type & ARG_QUOTE ) && c->line[ 0 ] != '"' ) {
+       if ( (( ct->arg_type & ARG_QUOTE ) && c->line[ 0 ] != '"' ) ||
+               (arg_type == ARG_BERVAL || arg_type == ARG_BINARY)) {
                c->argv[c->argc] = c->line;
                c->argc++;
                c->argv[c->argc] = NULL;
@@ -731,6 +760,7 @@ read_config_file(const char *fname, int depth, ConfigArgs *cf, ConfigTable *cft)
                Debug(LDAP_DEBUG_ANY,
                    "could not stat config file \"%s\": %s (%d)\n",
                    fname, strerror(errno), errno);
+               ch_free( c->argv );
                ch_free( c );
                return(1);
        }
@@ -740,6 +770,7 @@ read_config_file(const char *fname, int depth, ConfigArgs *cf, ConfigTable *cft)
                Debug(LDAP_DEBUG_ANY,
                    "regular file expected, got \"%s\"\n",
                    fname, 0, 0 );
+               ch_free( c->argv );
                ch_free( c );
                return(1);
        }
@@ -750,6 +781,7 @@ read_config_file(const char *fname, int depth, ConfigArgs *cf, ConfigTable *cft)
                Debug(LDAP_DEBUG_ANY,
                    "could not open config file \"%s\": %s (%d)\n",
                    fname, strerror(errno), errno);
+               ch_free( c->argv );
                ch_free( c );
                return(1);
        }
@@ -1353,9 +1385,8 @@ slap_keepalive_parse(
                        s = ++next;
                }
 
-               if ( s == '\0' ) {
+               if ( *s == '\0' ) {
                        sk2.sk_interval = 0;
-                       s++;
 
                } else {
                        sk2.sk_interval = strtol( s, &next, 10 );
@@ -2011,7 +2042,7 @@ slap_client_connect( LDAP **ldp, slap_bindconf *sb )
                        "slap_client_connect: "
                        "URI=%s TLS context initialization failed (%d)\n",
                        sb->sb_uri.bv_val, rc, 0 );
-               return rc;
+               goto done;
        }
 #endif
 
@@ -2131,7 +2162,7 @@ done:;
 
 
 static char *
-strtok_quote( char *line, char *sep, char **quote_ptr )
+strtok_quote( char *line, char *sep, char **quote_ptr, int *iqp )
 {
        int             inquote;
        char            *tmp;
@@ -2181,6 +2212,7 @@ strtok_quote( char *line, char *sep, char **quote_ptr )
                        break;
                }
        }
+       *iqp = inquote;
 
        return( tmp );
 }
@@ -2266,24 +2298,28 @@ config_fp_parse_line(ConfigArgs *c)
                "dbpasswd",  /* in back-sql */
                NULL
        };
+       static char *const raw[] = {
+               "attributetype", "objectclass", "ditcontentrule", "ldapsyntax", NULL };
        char *quote_ptr;
        int i = (int)(sizeof(hide)/sizeof(hide[0])) - 1;
+       int inquote = 0;
 
        c->tline = ch_strdup(c->line);
-       token = strtok_quote(c->tline, " \t", &quote_ptr);
+       c->linelen = strlen(c->line);
+       token = strtok_quote(c->tline, " \t", &quote_ptr, &inquote);
 
        if(token) for(i = 0; hide[i]; i++) if(!strcasecmp(token, hide[i])) break;
        if(quote_ptr) *quote_ptr = ' ';
-       Debug(LDAP_DEBUG_CONFIG, "line %d (%s%s)\n", c->lineno,
+       Debug(LDAP_DEBUG_CONFIG, "%s (%s%s)\n", c->log,
                hide[i] ? hide[i] : c->line, hide[i] ? " ***" : "");
        if(quote_ptr) *quote_ptr = '\0';
 
-       for(;; token = strtok_quote(NULL, " \t", &quote_ptr)) {
+       for(;; token = strtok_quote(NULL, " \t", &quote_ptr, &inquote)) {
                if(c->argc >= c->argv_size) {
                        char **tmp;
                        tmp = ch_realloc(c->argv, (c->argv_size + ARGS_STEP) * sizeof(*c->argv));
                        if(!tmp) {
-                               Debug(LDAP_DEBUG_ANY, "line %d: out of memory\n", c->lineno, 0, 0);
+                               Debug(LDAP_DEBUG_ANY, "%s: out of memory\n", c->log, 0, 0);
                                return -1;
                        }
                        c->argv = tmp;
@@ -2294,6 +2330,13 @@ config_fp_parse_line(ConfigArgs *c)
                c->argv[c->argc++] = token;
        }
        c->argv[c->argc] = NULL;
+       if (inquote) {
+               /* these directives parse c->line independently of argv tokenizing */
+               for(i = 0; raw[i]; i++) if (!strcasecmp(c->argv[0], raw[i])) return 0;
+
+               Debug(LDAP_DEBUG_ANY, "%s: unterminated quoted string \"%s\"\n", c->log, c->argv[c->argc-1], 0);
+               return -1;
+       }
        return(0);
 }