]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-meta/config.c
better fix: in case of error during bind, just bail out (very conservative, though)
[openldap] / servers / slapd / back-meta / config.c
index d4167bd0948e08ce4ac7ffc8a8970fc88b2d862e..18f3a772d96646dbb84d57fd57efcff6d0be0849 100644 (file)
@@ -69,6 +69,21 @@ new_target(
        return 0;
 }
 
+static int
+check_true_false( char *str )
+{
+       if ( strcasecmp( str, "true" ) == 0 || strcasecmp( str, "yes" ) == 0 ) {
+               return 1;
+       }
+
+       if ( strcasecmp( str, "false" ) == 0 || strcasecmp( str, "no" ) == 0 ) {
+               return 0;
+       }
+
+       return -1;
+}
+
+
 int
 meta_back_db_config(
                BackendDB       *be,
@@ -98,10 +113,28 @@ meta_back_db_config(
                int             rc;
                int             c;
                
-               if ( argc != 2 ) {
+               switch ( argc ) {
+               case 1:
                        fprintf( stderr,
-       "%s: line %d: missing address"
-       " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
+       "%s: line %d: missing URI "
+       "in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
+                               fname, lineno );
+                       return 1;
+
+               case 2:
+                       break;
+
+               default:
+                       fprintf( stderr,
+       "%s: line %d: too many args "
+       "in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
+                               fname, lineno );
+                       return 1;
+               }
+
+               if ( be->be_nsuffix == NULL ) {
+                       fprintf( stderr,
+       "%s: line %d: the suffix must be defined before any target.\n",
                                fname, lineno );
                        return 1;
                }
@@ -148,20 +181,35 @@ meta_back_db_config(
                /*
                 * uri MUST have the <dn> part!
                 */
-               if ( ludp->lud_dn == NULL || ludp->lud_dn[ 0 ] == '\0' ) {
+               if ( ludp->lud_dn == NULL ) {
                        fprintf( stderr,
        "%s: line %d: missing <naming context> "
        " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
                                fname, lineno );
                        return 1;
+
+               } else if ( ludp->lud_dn[ 0 ] == '\0' ) {
+                       int     j = -1;
+
+                       for ( j = 0; !BER_BVISNULL( &be->be_nsuffix[ j ] ); j++ ) {
+                               if ( BER_BVISEMPTY( &be->be_nsuffix[ j ] ) ) {
+                                       break;
+                               }
+                       }
+
+                       if ( BER_BVISNULL( &be->be_nsuffix[ j ] ) ) {
+                               fprintf( stderr,
+               "%s: line %d: missing <naming context> "
+               " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
+                                       fname, lineno );
+                               return 1;
+                       }
                }
 
                /*
                 * copies and stores uri and suffix
                 */
-               dn.bv_val = ludp->lud_dn;
-               dn.bv_len = strlen( ludp->lud_dn );
-
+               ber_str2bv( ludp->lud_dn, 0, 0, &dn );
                rc = dnPrettyNormal( NULL, &dn, &mi->mi_targets[ i ].mt_psuffix,
                        &mi->mi_targets[ i ].mt_nsuffix, NULL );
                if( rc != LDAP_SUCCESS ) {
@@ -173,6 +221,25 @@ meta_back_db_config(
 
                ludp->lud_dn[ 0 ] = '\0';
 
+               switch ( ludp->lud_scope ) {
+               case LDAP_SCOPE_DEFAULT:
+                       mi->mi_targets[ i ].mt_scope = LDAP_SCOPE_SUBTREE;
+                       break;
+
+               case LDAP_SCOPE_SUBTREE:
+#ifdef LDAP_SCOPE_SUBORDINATE
+               case LDAP_SCOPE_SUBORDINATE:
+#endif /* LDAP_SCOPE_SUBORDINATE */
+                       mi->mi_targets[ i ].mt_scope = ludp->lud_scope;
+                       break;
+
+               default:
+                       fprintf( stderr, "%s: line %d: "
+                                       "invalid scope for target '%s'\n",
+                                       fname, lineno, argv[ 1 ] );
+                       return( 1 );
+               }
+
                /* check all, to apply the scope check on the first one */
                for ( tmpludp = ludp; tmpludp; tmpludp = tmpludp->lud_next ) {
                        if ( tmpludp->lud_dn != NULL && tmpludp->lud_dn[ 0 ] != '\0' ) {
@@ -183,10 +250,6 @@ meta_back_db_config(
                                return( 1 );
 
                        }
-
-                       if ( tmpludp->lud_scope == LDAP_SCOPE_BASE ) {
-                               tmpludp->lud_scope = LDAP_SCOPE_DEFAULT;
-                       }
                }
 
                mi->mi_targets[ i ].mt_uri = ldap_url_list2urls( ludp );
@@ -365,20 +428,23 @@ meta_back_db_config(
 
                if ( argc == 1 ) {
                        fprintf( stderr,
-       "%s: line %d: deprecated use of \"rebind-as-user {NO|yes}\" with no arguments.\n",
+       "%s: line %d: deprecated use of \"rebind-as-user {FALSE|true}\" with no arguments.\n",
                            fname, lineno );
                        mi->flags |= LDAP_BACK_F_SAVECRED;
 
                } else {
-                       if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
+                       switch ( check_true_false( argv[ 1 ] ) ) {
+                       case 0:
                                mi->flags &= ~LDAP_BACK_F_SAVECRED;
+                               break;
 
-                       } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
+                       case 1:
                                mi->flags |= LDAP_BACK_F_SAVECRED;
+                               break;
 
-                       } else {
+                       default:
                                fprintf( stderr,
-       "%s: line %d: \"rebind-as-user {NO|yes}\" unknown argument \"%s\".\n",
+       "%s: line %d: \"rebind-as-user {FALSE|true}\" unknown argument \"%s\".\n",
                                    fname, lineno, argv[ 1 ] );
                                return 1;
                        }
@@ -391,21 +457,24 @@ meta_back_db_config(
 
                if ( argc != 2 ) {
                        fprintf( stderr,
-       "%s: line %d: \"chase-referrals\" needs 1 argument.\n",
+       "%s: line %d: \"chase-referrals {TRUE|false}\" needs 1 argument.\n",
                                        fname, lineno );
                        return( 1 );
                }
 
                /* this is the default; we add it because the default might change... */
-               if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
+               switch ( check_true_false( argv[ 1 ] ) ) {
+               case 1:
                        *flagsp |= LDAP_BACK_F_CHASE_REFERRALS;
+                       break;
 
-               } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
+               case 0:
                        *flagsp &= ~LDAP_BACK_F_CHASE_REFERRALS;
+                       break;
 
-               } else {
+               default:
                        fprintf( stderr,
-               "%s: line %d: \"chase-referrals {YES|no}\": unknown argument \"%s\".\n",
+               "%s: line %d: \"chase-referrals {TRUE|false}\": unknown argument \"%s\".\n",
                                        fname, lineno, argv[ 1 ] );
                        return( 1 );
                }
@@ -454,25 +523,31 @@ meta_back_db_config(
 
                if ( argc != 2 ) {
                        fprintf( stderr,
-               "%s: line %d: \"t-f-support {NO|yes|discover}\" needs 1 argument.\n",
+               "%s: line %d: \"t-f-support {FALSE|true|discover}\" needs 1 argument.\n",
                                        fname, lineno );
                        return( 1 );
                }
 
-               if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
+               switch ( check_true_false( argv[ 1 ] ) ) {
+               case 0:
                        *flagsp &= ~(LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER);
+                       break;
 
-               } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
+               case 1:
                        *flagsp |= LDAP_BACK_F_SUPPORT_T_F;
+                       break;
 
-               } else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
-                       *flagsp |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
+               default:
+                       if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
+                               *flagsp |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
 
-               } else {
-                       fprintf( stderr,
+                       } else {
+                               fprintf( stderr,
        "%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n",
-                               fname, lineno, argv[ 1 ] );
-                       return 1;
+                                       fname, lineno, argv[ 1 ] );
+                               return 1;
+                       }
+                       break;
                }
 
        /* onerr? */
@@ -497,11 +572,36 @@ meta_back_db_config(
                        return 1;
                }
 
+       /* bind-defer? */
+       } else if ( strcasecmp( argv[ 0 ], "pseudoroot-bind-defer" ) == 0 ) {
+               if ( argc != 2 ) {
+                       fprintf( stderr,
+       "%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\" takes 1 argument\n",
+                           fname, lineno );
+                       return( 1 );
+               }
+
+               switch ( check_true_false( argv[ 1 ] ) ) {
+               case 0:
+                       mi->flags &= ~META_BACK_F_DEFER_ROOTDN_BIND;
+                       break;
+
+               case 1:
+                       mi->flags |= META_BACK_F_DEFER_ROOTDN_BIND;
+                       break;
+
+               default:
+                       fprintf( stderr,
+       "%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\": invalid arg \"%s\".\n",
+                               fname, lineno, argv[ 1 ] );
+                       return 1;
+               }
+
        } else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) {
                char    *sep, *next;
                time_t  *tv = mi->mi_ntargets ?
-                               &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_timeout
-                               : &mi->mi_timeout;
+                               mi->mi_targets[ mi->mi_ntargets - 1 ].mt_timeout
+                               : mi->mi_timeout;
                int     c;
 
                if ( argc < 2 ) {
@@ -610,7 +710,7 @@ meta_back_db_config(
        /* dn massaging */
        } else if ( strcasecmp( argv[ 0 ], "suffixmassage" ) == 0 ) {
                BackendDB       *tmp_be;
-               int             i = mi->mi_ntargets - 1;
+               int             i = mi->mi_ntargets - 1, rc;
                struct berval   dn, nvnc, pvnc, nrnc, prnc;
 
                if ( i < 0 ) {
@@ -638,8 +738,7 @@ meta_back_db_config(
                        return 1;
                }
 
-               dn.bv_val = argv[ 1 ];
-               dn.bv_len = strlen( argv[ 1 ] );
+               ber_str2bv( argv[ 1 ], 0, 0, &dn );
                if ( dnPrettyNormal( NULL, &dn, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
                        fprintf( stderr, "%s: line %d: "
                                        "suffix '%s' is invalid\n",
@@ -658,8 +757,7 @@ meta_back_db_config(
                        return 1;                                               
                }
 
-               dn.bv_val = argv[ 2 ];
-               dn.bv_len = strlen( argv[ 2 ] );
+               ber_str2bv( argv[ 2 ], 0, 0, &dn );
                if ( dnPrettyNormal( NULL, &dn, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
                        fprintf( stderr, "%s: line %d: "
                                        "massaged suffix '%s' is invalid\n",
@@ -690,8 +788,15 @@ meta_back_db_config(
                 * FIXME: no extra rewrite capabilities should be added
                 * to the database
                 */
-               return suffix_massage_config( mi->mi_targets[ i ].mt_rwmap.rwm_rw,
+               rc = suffix_massage_config( mi->mi_targets[ i ].mt_rwmap.rwm_rw,
                                &pvnc, &nvnc, &prnc, &nrnc );
+
+               free( pvnc.bv_val );
+               free( nvnc.bv_val );
+               free( prnc.bv_val );
+               free( nrnc.bv_val );
+
+               return rc;
                
        /* rewrite stuff ... */
        } else if ( strncasecmp( argv[ 0 ], "rewrite", 7 ) == 0 ) {
@@ -879,7 +984,20 @@ ldap_back_map_config(
                                /*
                                 * FIXME: this should become an err
                                 */
-                               goto error_return;
+                               /*
+                                * we create a fake "proxied" ad 
+                                * and add it here.
+                                */
+
+                               rc = slap_bv2undef_ad( &mapping->src,
+                                               &ad, &text, SLAP_AD_PROXIED );
+                               if ( rc != LDAP_SUCCESS ) {
+                                       fprintf( stderr,
+       "%s: line %d: source attributeType '%s': %d (%s)\n",
+                                               fname, lineno, src,
+                                               rc, text ? text : "" );
+                                       goto error_return;
+                               }
                        }
 
                        ad = NULL;
@@ -891,6 +1009,21 @@ ldap_back_map_config(
        "%s: line %d: warning, destination attributeType '%s' "
        "is not defined in schema\n",
                                fname, lineno, dst );
+
+                       /*
+                        * we create a fake "proxied" ad 
+                        * and add it here.
+                        */
+
+                       rc = slap_bv2undef_ad( &mapping->dst,
+                                       &ad, &text, SLAP_AD_PROXIED );
+                       if ( rc != LDAP_SUCCESS ) {
+                               fprintf( stderr,
+       "%s: line %d: source attributeType '%s': %d (%s)\n",
+                                       fname, lineno, dst,
+                                       rc, text ? text : "" );
+                               return 1;
+                       }
                }
        }
 
@@ -931,6 +1064,10 @@ suffix_massage_regexize( const char *s )
        const char *p, *r;
        int i;
 
+       if ( s[ 0 ] == '\0' ) {
+               return ch_strdup( "^(.+)$" );
+       }
+
        for ( i = 0, p = s; 
                        ( r = strchr( p, ',' ) ) != NULL; 
                        p = r + 1, i++ )
@@ -938,10 +1075,11 @@ suffix_massage_regexize( const char *s )
 
        res = ch_calloc( sizeof( char ),
                        strlen( s )
-                       + STRLENOF( "(.+,)?" )
-                       + STRLENOF( "[ ]?" ) * i + 1 );
+                       + STRLENOF( "((.+),)?" )
+                       + STRLENOF( "[ ]?" ) * i
+                       + STRLENOF( "$" ) + 1 );
 
-       ptr = lutil_strcopy( res, "(.+,)?" );
+       ptr = lutil_strcopy( res, "((.+),)?" );
        for ( i = 0, p = s;
                        ( r = strchr( p, ',' ) ) != NULL;
                        p = r + 1 , i++ ) {
@@ -952,26 +1090,37 @@ suffix_massage_regexize( const char *s )
                        r++;
                }
        }
-       lutil_strcopy( ptr, p );
+       ptr = lutil_strcopy( ptr, p );
+       ptr[ 0 ] = '$';
+       ptr++;
+       ptr[ 0 ] = '\0';
 
        return res;
 }
 
 static char *
-suffix_massage_patternize( const char *s )
+suffix_massage_patternize( const char *s, const char *p )
 {
        ber_len_t       len;
-       char            *res;
+       char            *res, *ptr;
 
-       len = strlen( s );
+       len = strlen( p );
+
+       if ( s[ 0 ] == '\0' ) {
+               len++;
+       }
 
        res = ch_calloc( sizeof( char ), len + STRLENOF( "%1" ) + 1 );
        if ( res == NULL ) {
                return NULL;
        }
 
-       strcpy( res, "%1" );
-       strcpy( &res[ STRLENOF( "%1" ) ], s );
+       ptr = lutil_strcopy( res, ( p[ 0 ] == '\0' ? "%2" : "%1" ) );
+       if ( s[ 0 ] == '\0' ) {
+               ptr[ 0 ] = ',';
+               ptr++;
+       }
+       lutil_strcopy( ptr, p );
 
        return res;
 }
@@ -1000,12 +1149,21 @@ suffix_massage_config(
 
        rargv[ 0 ] = "rewriteRule";
        rargv[ 1 ] = suffix_massage_regexize( pvnc->bv_val );
-       rargv[ 2 ] = suffix_massage_patternize( prnc->bv_val );
+       rargv[ 2 ] = suffix_massage_patternize( pvnc->bv_val, prnc->bv_val );
        rargv[ 3 ] = ":";
        rargv[ 4 ] = NULL;
        rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
        ch_free( rargv[ 1 ] );
        ch_free( rargv[ 2 ] );
+
+       if ( BER_BVISEMPTY( pvnc ) ) {
+               rargv[ 0 ] = "rewriteRule";
+               rargv[ 1 ] = "^$";
+               rargv[ 2 ] = prnc->bv_val;
+               rargv[ 3 ] = ":";
+               rargv[ 4 ] = NULL;
+               rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
+       }
        
        rargv[ 0 ] = "rewriteContext";
        rargv[ 1 ] = "searchEntryDN";
@@ -1014,13 +1172,22 @@ suffix_massage_config(
 
        rargv[ 0 ] = "rewriteRule";
        rargv[ 1 ] = suffix_massage_regexize( prnc->bv_val );
-       rargv[ 2 ] = suffix_massage_patternize( pvnc->bv_val );
+       rargv[ 2 ] = suffix_massage_patternize( prnc->bv_val, pvnc->bv_val );
        rargv[ 3 ] = ":";
        rargv[ 4 ] = NULL;
        rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
        ch_free( rargv[ 1 ] );
        ch_free( rargv[ 2 ] );
 
+       if ( BER_BVISEMPTY( prnc ) ) {
+               rargv[ 0 ] = "rewriteRule";
+               rargv[ 1 ] = "^$";
+               rargv[ 2 ] = pvnc->bv_val;
+               rargv[ 3 ] = ":";
+               rargv[ 4 ] = NULL;
+               rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
+       }
+       
        /* backward compatibility */
        rargv[ 0 ] = "rewriteContext";
        rargv[ 1 ] = "searchResult";