]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/rwmconf.c
ITS#4238 don't hide syncrepl control from rootDSE
[openldap] / servers / slapd / overlays / rwmconf.c
index 4e20ed2506eef585c6c35b14138e6d86c7e4efab..71a77924c903cbc9a41d93583bbf87173feaaefe 100644 (file)
@@ -2,7 +2,9 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2003 The OpenLDAP Foundation.
+ * Copyright 1999-2005 The OpenLDAP Foundation.
+ * Portions Copyright 1999-2003 Howard Chu.
+ * Portions Copyright 2000-2003 Pierangelo Masarati.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * in OpenLDAP Software and subsequently enhanced by Pierangelo
  * Masarati.
  */
-/* This is an altered version */
-/*
- * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
- * 
- * Permission is granted to anyone to use this software for any purpose
- * on any computer system, and to alter it and redistribute it, subject
- * to the following restrictions:
- * 
- * 1. The author is not responsible for the consequences of use of this
- *    software, no matter how awful, even if they arise from flaws in it.
- * 
- * 2. The origin of this software must not be misrepresented, either by
- *    explicit claim or by omission.  Since few users ever read sources,
- *    credits should appear in the documentation.
- * 
- * 3. Altered versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.  Since few users
- *    ever read sources, credits should appear in the documentation.
- * 
- * 4. This notice may not be removed or altered.
- *
- *
- *
- * Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
- * 
- * This software is being modified by Pierangelo Masarati.
- * The previously reported conditions apply to the modified code as well.
- * Changes in the original code are highlighted where required.
- * Credits for the original code go to the author, Howard Chu.
- */
 
 #include "portable.h"
 
+#ifdef SLAPD_OVER_RWM
+
 #include <stdio.h>
 
 #include <ac/string.h>
@@ -119,6 +93,7 @@ rwm_map_config(
                fprintf( stderr,
                        "%s: line %d: objectclass attribute cannot be mapped\n",
                        fname, lineno );
+               return 1;
        }
 
        mapping = (struct ldapmapping *)ch_calloc( 2,
@@ -129,17 +104,21 @@ rwm_map_config(
                        fname, lineno );
                return 1;
        }
-       ber_str2bv( src, 0, 1, &mapping->src );
-       ber_str2bv( dst, 0, 1, &mapping->dst );
-       mapping[1].src = mapping->dst;
-       mapping[1].dst = mapping->src;
+       ber_str2bv( src, 0, 1, &mapping[0].m_src );
+       ber_str2bv( dst, 0, 1, &mapping[0].m_dst );
+       mapping[1].m_src = mapping[0].m_dst;
+       mapping[1].m_dst = mapping[0].m_src;
+
+       mapping[0].m_flags = RWMMAP_F_NONE;
+       mapping[1].m_flags = RWMMAP_F_NONE;
 
        /*
         * schema check
         */
        if ( is_oc ) {
                if ( src[0] != '\0' ) {
-                       if ( oc_bvfind( &mapping->src ) == NULL ) {
+                       mapping[0].m_src_oc = oc_bvfind( &mapping[0].m_src );
+                       if ( mapping[0].m_src_oc == NULL ) {
                                fprintf( stderr,
        "%s: line %d: warning, source objectClass '%s' "
        "should be defined in schema\n",
@@ -148,22 +127,47 @@ rwm_map_config(
                                /*
                                 * FIXME: this should become an err
                                 */
+                               mapping[0].m_src_oc = ch_malloc( sizeof( ObjectClass ) );
+                               memset( mapping[0].m_src_oc, 0, sizeof( ObjectClass ) );
+                               mapping[0].m_src_oc->soc_cname = mapping[0].m_src;
+                               mapping[0].m_flags |= RWMMAP_F_FREE_SRC;
                        }
+                       mapping[1].m_dst_oc = mapping[0].m_src_oc;
                }
 
-               if ( oc_bvfind( &mapping->dst ) == NULL ) {
+               mapping[0].m_dst_oc = oc_bvfind( &mapping[0].m_dst );
+               if ( mapping[0].m_dst_oc == NULL ) {
                        fprintf( stderr,
        "%s: line %d: warning, destination objectClass '%s' "
        "is not defined in schema\n",
                                fname, lineno, dst );
+
+                       mapping[0].m_dst_oc = oc_bvfind_undef( &mapping[0].m_dst );
+                       if ( mapping[0].m_dst_oc == NULL ) {
+                               fprintf( stderr, "%s: line %d: unable to mimic destination objectClass '%s'\n",
+                                       fname, lineno, dst );
+                               goto error_return;
+                       }
+
+#if 0
+                       mapping[0].m_dst_oc = ch_malloc( sizeof( ObjectClass ) );
+                       memset( mapping[0].m_dst_oc, 0, sizeof( ObjectClass ) );
+                       mapping[0].m_dst_oc->soc_cname = mapping[0].m_dst;
+                       mapping[0].m_flags |= RWMMAP_F_FREE_DST;
+#endif
                }
+               mapping[1].m_src_oc = mapping[0].m_dst_oc;
+
+               mapping[0].m_flags |= RWMMAP_F_IS_OC;
+               mapping[1].m_flags |= RWMMAP_F_IS_OC;
+
        } else {
                int                     rc;
                const char              *text = NULL;
-               AttributeDescription    *ad = NULL;
 
                if ( src[0] != '\0' ) {
-                       rc = slap_bv2ad( &mapping->src, &ad, &text );
+                       rc = slap_bv2ad( &mapping[0].m_src,
+                                       &mapping[0].m_src_ad, &text );
                        if ( rc != LDAP_SUCCESS ) {
                                fprintf( stderr,
        "%s: line %d: warning, source attributeType '%s' "
@@ -171,46 +175,66 @@ rwm_map_config(
                                        fname, lineno, src );
 
                                /*
-                                * FIXME: this should become an err
+                                * we create a fake "proxied" ad 
+                                * and add it here.
                                 */
-                       }
 
-                       ad = NULL;
+                               rc = slap_bv2undef_ad( &mapping[0].m_src,
+                                               &mapping[0].m_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 : "null" );
+                                       goto error_return;
+                               }
+
+                       }
+                       mapping[1].m_dst_ad = mapping[0].m_src_ad;
                }
 
-               rc = slap_bv2ad( &mapping->dst, &ad, &text );
+               rc = slap_bv2ad( &mapping[0].m_dst, &mapping[0].m_dst_ad, &text );
                if ( rc != LDAP_SUCCESS ) {
                        fprintf( stderr,
        "%s: line %d: warning, destination attributeType '%s' "
        "is not defined in schema\n",
                                fname, lineno, dst );
+
+                       rc = slap_bv2undef_ad( &mapping[0].m_dst,
+                                       &mapping[0].m_dst_ad, &text,
+                                       SLAP_AD_PROXIED );
+                       if ( rc != LDAP_SUCCESS ) {
+                               fprintf( stderr,
+       "%s: line %d: destination attributeType '%s': %d (%s)\n",
+                                       fname, lineno, dst, rc, text ? text : "null" );
+                               goto error_return;
+                       }
                }
+               mapping[1].m_src_ad = mapping[0].m_dst_ad;
        }
 
-       if ( (src[0] != '\0' && avl_find( map->map, (caddr_t)mapping, mapping_cmp ) != NULL)
-                       || avl_find( map->remap, (caddr_t)&mapping[1], mapping_cmp ) != NULL)
+       if ( ( src[0] != '\0' && avl_find( map->map, (caddr_t)mapping, rwm_mapping_cmp ) != NULL)
+                       || avl_find( map->remap, (caddr_t)&mapping[1], rwm_mapping_cmp ) != NULL)
        {
                fprintf( stderr,
-                       "%s: line %d: duplicate mapping found (ignored)\n",
+                       "%s: line %d: duplicate mapping found" SLAPD_CONF_UNKNOWN_IGNORED ".\n",
                        fname, lineno );
                /* FIXME: free stuff */
                goto error_return;
        }
 
        if ( src[0] != '\0' ) {
-               avl_insert( &map->map, (caddr_t)mapping,
-                                       mapping_cmp, mapping_dup );
+               avl_insert( &map->map, (caddr_t)&mapping[0],
+                                       rwm_mapping_cmp, rwm_mapping_dup );
        }
        avl_insert( &map->remap, (caddr_t)&mapping[1],
-                               mapping_cmp, mapping_dup );
+                               rwm_mapping_cmp, rwm_mapping_dup );
 
        return 0;
 
 error_return:;
        if ( mapping ) {
-               ch_free( mapping->src.bv_val );
-               ch_free( mapping->dst.bv_val );
-               ch_free( mapping );
+               rwm_mapping_free( mapping );
        }
 
        return 1;
@@ -218,20 +242,27 @@ error_return:;
 
 #ifdef ENABLE_REWRITE
 static char *
-suffix_massage_regexize( const char *s )
+rwm_suffix_massage_regexize( const char *s )
 {
        char *res, *ptr;
        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++ )
                ;
 
-       res = ch_calloc( sizeof( char ), strlen( s ) + 4 + 4*i + 1 );
+       res = ch_calloc( sizeof( char ), strlen( s )
+                       + 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++ ) {
@@ -242,32 +273,42 @@ suffix_massage_regexize( const char *s )
                        r++;
                }
        }
-       lutil_strcopy( ptr, p );
+       ptr = lutil_strcopy( ptr, p );
+       ptr[0] = '$';
+       ptr[1] = '\0';
 
        return res;
 }
 
 static char *
-suffix_massage_patternize( const char *s )
+rwm_suffix_massage_patternize( const char *s, const char *p )
 {
        ber_len_t       len;
-       char            *res;
+       char            *res, *ptr;
+
+       len = strlen( p );
 
-       len = strlen( s );
+       if ( s[ 0 ] == '\0' ) {
+               len++;
+       }
 
-       res = ch_calloc( sizeof( char ), len + sizeof( "%1" ) );
+       res = ch_calloc( sizeof( char ), len + STRLENOF( "%1" ) + 1 );
        if ( res == NULL ) {
                return NULL;
        }
 
-       strcpy( res, "%1" );
-       strcpy( res + sizeof( "%1" ) - 1, s );
+       ptr = lutil_strcopy( res, ( p[0] == '\0' ? "%2" : "%1" ) );
+       if ( s[ 0 ] == '\0' ) {
+               ptr[ 0 ] = ',';
+               ptr++;
+       }
+       lutil_strcopy( ptr, p );
 
        return res;
 }
 
 int
-suffix_massage_config( 
+rwm_suffix_massage_config( 
                struct rewrite_info *info,
                struct berval *pvnc,
                struct berval *nvnc,
@@ -289,42 +330,82 @@ suffix_massage_config(
        rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
 
        rargv[ 0 ] = "rewriteRule";
-       rargv[ 1 ] = suffix_massage_regexize( pvnc->bv_val );
-       rargv[ 2 ] = suffix_massage_patternize( prnc->bv_val );
+       rargv[ 1 ] = rwm_suffix_massage_regexize( pvnc->bv_val );
+       rargv[ 2 ] = rwm_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 ] = "searchResult";
+       rargv[ 1 ] = "searchEntryDN";
        rargv[ 2 ] = NULL;
        rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
        
        rargv[ 0 ] = "rewriteRule";
-       rargv[ 1 ] = suffix_massage_regexize( prnc->bv_val );
-       rargv[ 2 ] = suffix_massage_patternize( pvnc->bv_val );
+       rargv[ 1 ] = rwm_suffix_massage_regexize( prnc->bv_val );
+       rargv[ 2 ] = rwm_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 );
+       }
+
        rargv[ 0 ] = "rewriteContext";
        rargv[ 1 ] = "matchedDN";
        rargv[ 2 ] = "alias";
-       rargv[ 3 ] = "searchResult";
+       rargv[ 3 ] = "searchEntryDN";
+       rargv[ 4 ] = NULL;
+       rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
+
+#ifdef RWM_REFERRAL_REWRITE
+       /* FIXME: we don't want this on by default, do we? */
+       rargv[ 0 ] = "rewriteContext";
+       rargv[ 1 ] = "referralDN";
+       rargv[ 2 ] = "alias";
+       rargv[ 3 ] = "searchEntryDN";
        rargv[ 4 ] = NULL;
        rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
+#else /* ! RWM_REFERRAL_REWRITE */
+       rargv[ 0 ] = "rewriteContext";
+       rargv[ 1 ] = "referralAttrDN";
+       rargv[ 2 ] = NULL;
+       rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
+
+       rargv[ 0 ] = "rewriteContext";
+       rargv[ 1 ] = "referralDN";
+       rargv[ 2 ] = NULL;
+       rewrite_parse( info, "<suffix massage>", ++line, 2, rargv );
+#endif /* ! RWM_REFERRAL_REWRITE */
 
        rargv[ 0 ] = "rewriteContext";
        rargv[ 1 ] = "searchAttrDN";
        rargv[ 2 ] = "alias";
-       rargv[ 3 ] = "searchResult";
+       rargv[ 3 ] = "searchEntryDN";
        rargv[ 4 ] = NULL;
        rewrite_parse( info, "<suffix massage>", ++line, 4, rargv );
 
        return 0;
 }
 #endif /* ENABLE_REWRITE */
+
+#endif /* SLAPD_OVER_RWM */