X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Frwmconf.c;h=532b17fcc607a0221680c161880cf2e555e66069;hb=c4f99a5ddcd06ea4daaaa41ef3bcd5919c1e0549;hp=c0a498f2b6152429b7f37eefdf6c61163b1af96a;hpb=b5bba83a31e8f5c1cf82214ab88c294fe8cf3fd9;p=openldap diff --git a/servers/slapd/overlays/rwmconf.c b/servers/slapd/overlays/rwmconf.c index c0a498f2b6..532b17fcc6 100644 --- a/servers/slapd/overlays/rwmconf.c +++ b/servers/slapd/overlays/rwmconf.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1999-2003 The OpenLDAP Foundation. + * Copyright 1999-2011 The OpenLDAP Foundation. * Portions Copyright 1999-2003 Howard Chu. * Portions Copyright 2000-2003 Pierangelo Masarati. * All rights reserved. @@ -47,11 +47,12 @@ rwm_map_config( struct ldapmapping *mapping; char *src, *dst; int is_oc = 0; + int rc = 0; if ( argc < 3 || argc > 4 ) { - fprintf( stderr, + Debug( LDAP_DEBUG_ANY, "%s: line %d: syntax is \"map {objectclass | attribute} [ | *] { | *}\"\n", - fname, lineno ); + fname, lineno, 0 ); return 1; } @@ -63,17 +64,24 @@ rwm_map_config( map = at_map; } else { - fprintf( stderr, "%s: line %d: syntax is " + Debug( LDAP_DEBUG_ANY, "%s: line %d: syntax is " "\"map {objectclass | attribute} [ | *] " "{ | *}\"\n", - fname, lineno ); + fname, lineno, 0 ); return 1; } + if ( !is_oc && map->map == NULL ) { + /* only init if required */ + if ( rwm_map_init( map, &mapping ) != LDAP_SUCCESS ) { + return 1; + } + } + if ( strcmp( argv[2], "*" ) == 0 ) { if ( argc < 4 || strcmp( argv[3], "*" ) == 0 ) { map->drop_missing = ( argc < 4 ); - return 0; + goto success_return; } src = dst = argv[3]; @@ -90,31 +98,36 @@ rwm_map_config( && ( strcasecmp( src, "objectclass" ) == 0 || strcasecmp( dst, "objectclass" ) == 0 ) ) { - fprintf( stderr, + Debug( LDAP_DEBUG_ANY, "%s: line %d: objectclass attribute cannot be mapped\n", - fname, lineno ); + fname, lineno, 0 ); + return 1; } mapping = (struct ldapmapping *)ch_calloc( 2, sizeof(struct ldapmapping) ); if ( mapping == NULL ) { - fprintf( stderr, + Debug( LDAP_DEBUG_ANY, "%s: line %d: out of memory\n", - fname, lineno ); + fname, lineno, 0 ); 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 ) { - fprintf( stderr, + mapping[0].m_src_oc = oc_bvfind( &mapping[0].m_src ); + if ( mapping[0].m_src_oc == NULL ) { + Debug( LDAP_DEBUG_ANY, "%s: line %d: warning, source objectClass '%s' " "should be defined in schema\n", fname, lineno, src ); @@ -122,90 +135,141 @@ 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 ) { - fprintf( stderr, + mapping[0].m_dst_oc = oc_bvfind( &mapping[0].m_dst ); + if ( mapping[0].m_dst_oc == NULL ) { + Debug( LDAP_DEBUG_ANY, "%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 ) { + Debug( LDAP_DEBUG_ANY, "%s: line %d: unable to mimic destination objectClass '%s'\n", + fname, lineno, dst ); + goto error_return; + } } + 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, + Debug( LDAP_DEBUG_ANY, "%s: line %d: warning, source attributeType '%s' " "should be defined in schema\n", 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 ) { + char prefix[1024]; + snprintf( prefix, sizeof(prefix), + "%s: line %d: source attributeType '%s': %d", + fname, lineno, src, rc ); + Debug( LDAP_DEBUG_ANY, "%s (%s)\n", + prefix, text ? text : "null", 0 ); + 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, + Debug( LDAP_DEBUG_ANY, "%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 ) { + char prefix[1024]; + snprintf( prefix, sizeof(prefix), + "%s: line %d: destination attributeType '%s': %d", + fname, lineno, dst, rc ); + Debug( LDAP_DEBUG_ANY, "%s (%s)\n", + prefix, text ? text : "null", 0 ); + 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", - fname, lineno ); + Debug( LDAP_DEBUG_ANY, + "%s: line %d: duplicate mapping found.\n", + fname, lineno, 0 ); /* 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; +success_return:; + return rc; 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; } -#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++ ) { @@ -216,32 +280,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( s ); + len = strlen( p ); - res = ch_calloc( sizeof( char ), len + sizeof( "%1" ) ); + if ( s[ 0 ] == '\0' ) { + len++; + } + + 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, @@ -263,44 +337,81 @@ suffix_massage_config( rewrite_parse( info, "", ++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, "", ++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, "", ++line, 4, rargv ); + } + rargv[ 0 ] = "rewriteContext"; - rargv[ 1 ] = "searchResultDN"; + rargv[ 1 ] = "searchEntryDN"; rargv[ 2 ] = NULL; rewrite_parse( info, "", ++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, "", ++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, "", ++line, 4, rargv ); + } + rargv[ 0 ] = "rewriteContext"; rargv[ 1 ] = "matchedDN"; rargv[ 2 ] = "alias"; - rargv[ 3 ] = "searchResultDN"; + rargv[ 3 ] = "searchEntryDN"; + rargv[ 4 ] = NULL; + rewrite_parse( info, "", ++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, "", ++line, 4, rargv ); +#else /* ! RWM_REFERRAL_REWRITE */ + rargv[ 0 ] = "rewriteContext"; + rargv[ 1 ] = "referralAttrDN"; + rargv[ 2 ] = NULL; + rewrite_parse( info, "", ++line, 2, rargv ); + + rargv[ 0 ] = "rewriteContext"; + rargv[ 1 ] = "referralDN"; + rargv[ 2 ] = NULL; + rewrite_parse( info, "", ++line, 2, rargv ); +#endif /* ! RWM_REFERRAL_REWRITE */ rargv[ 0 ] = "rewriteContext"; rargv[ 1 ] = "searchAttrDN"; rargv[ 2 ] = "alias"; - rargv[ 3 ] = "searchResultDN"; + rargv[ 3 ] = "searchEntryDN"; rargv[ 4 ] = NULL; rewrite_parse( info, "", ++line, 4, rargv ); return 0; } -#endif /* ENABLE_REWRITE */ #endif /* SLAPD_OVER_RWM */