/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2003-2004 The OpenLDAP Foundation.
+ * Copyright 2003-2005 The OpenLDAP Foundation.
* Portions Copyright 1999-2003 Howard Chu.
* Portions Copyright 2000-2003 Pierangelo Masarati.
* All rights reserved.
#include "slap.h"
#include "back-ldap.h"
#include "lutil.h"
+#undef ldap_debug
+/* for advanced URL parsing */
+#include "../../../libraries/libldap/ldap-int.h"
static SLAP_EXTOP_MAIN_FN ldap_back_exop_whoami;
/* URI of server to query (preferred over "server" directive) */
} else if ( strcasecmp( argv[0], "uri" ) == 0 ) {
- LDAPURLDesc tmplud;
+ LDAPURLDesc *tmpludp;
+ int urlrc, i;
if (argc != 2) {
fprintf( stderr, "%s: line %d: "
ldap_free_urldesc( li->lud );
}
- if ( ldap_url_parse( argv[ 1 ], &li->lud ) != LDAP_URL_SUCCESS ) {
+ urlrc = ldap_url_parselist( &li->lud, argv[ 1 ] );
+ if ( urlrc != LDAP_URL_SUCCESS ) {
+ char *why;
+
+ switch ( urlrc ) {
+ case LDAP_URL_ERR_MEM:
+ why = "no memory";
+ break;
+ case LDAP_URL_ERR_PARAM:
+ why = "parameter is bad";
+ break;
+ case LDAP_URL_ERR_BADSCHEME:
+ why = "URL doesn't begin with \"[c]ldap[si]://\"";
+ break;
+ case LDAP_URL_ERR_BADENCLOSURE:
+ why = "URL is missing trailing \">\"";
+ break;
+ case LDAP_URL_ERR_BADURL:
+ why = "URL is bad";
+ case LDAP_URL_ERR_BADHOST:
+ why = "host/port is bad";
+ break;
+ case LDAP_URL_ERR_BADATTRS:
+ why = "bad (or missing) attributes";
+ break;
+ case LDAP_URL_ERR_BADSCOPE:
+ why = "scope string is invalid (or missing)";
+ break;
+ case LDAP_URL_ERR_BADFILTER:
+ why = "bad or missing filter";
+ break;
+ case LDAP_URL_ERR_BADEXTS:
+ why = "bad or missing extensions";
+ break;
+ default:
+ why = "unknown reason";
+ break;
+ }
fprintf( stderr, "%s: line %d: "
- "unable to parse uri \"%s\" "
- "in \"uri <uri>\" line\n",
- fname, lineno, argv[ 1 ] );
+ "unable to parse uri \"%s\" "
+ "in \"uri <uri>\" line: %s\n",
+ fname, lineno, argv[ 1 ], why );
return 1;
}
- if ( ( li->lud->lud_dn != NULL && li->lud->lud_dn[0] != '\0' )
- || li->lud->lud_attrs != NULL
- || li->lud->lud_filter != NULL
- || li->lud->lud_exts != NULL )
+ for ( i = 0, tmpludp = li->lud;
+ tmpludp;
+ i++, tmpludp = tmpludp->lud_next )
{
- fprintf( stderr, "%s: line %d: "
- "warning, only protocol, "
- "host and port allowed "
- "in \"uri <uri>\" line\n",
- fname, lineno );
+ if ( ( tmpludp->lud_dn != NULL
+ && tmpludp->lud_dn[0] != '\0' )
+ || tmpludp->lud_attrs != NULL
+ || tmpludp->lud_filter != NULL
+ || tmpludp->lud_exts != NULL )
+ {
+ fprintf( stderr, "%s: line %d: "
+ "warning, only protocol, "
+ "host and port allowed "
+ "in \"uri <uri>\" statement "
+ "for uri #%d of \"%s\"\n",
+ fname, lineno, i, argv[1] );
+ }
}
-#if 0
- tmplud = *lud;
- tmplud.lud_dn = "";
- tmplud.lud_attrs = NULL;
- tmplud.lud_filter = NULL;
- if ( !ldap_is_ldapi_url( argv[ 1 ] ) ) {
- tmplud.lud_exts = NULL;
- tmplud.lud_crit_exts = 0;
- }
-
- li->url = ldap_url_desc2str( &tmplud );
- if ( li->url == NULL ) {
- fprintf( stderr, "%s: line %d: "
- "unable to rebuild uri \"%s\" "
- "in \"uri <uri>\" line\n",
- fname, lineno, argv[ 1 ] );
- return 1;
- }
-#else
li->url = ch_strdup( argv[ 1 ] );
-#endif
/* name to use for ldap_back_group */
} else if ( strcasecmp( argv[0], "binddn" ) == 0 ) {
LDAPMessage *res;
Operation op2 = *op;
ber_int_t msgid;
+ int do_retry = 1;
ctrls[0] = &c;
op2.o_ndn = op->o_conn->c_ndn;
strcpy(c.ldctl_value.bv_val, "dn:");
strcpy(c.ldctl_value.bv_val+3, op->o_ndn.bv_val);
+retry:
rs->sr_err = ldap_whoami(lc->ld, ctrls, NULL, &msgid);
if (rs->sr_err == LDAP_SUCCESS) {
if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) {
ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER,
&rs->sr_err);
+ if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
+ do_retry = 0;
+ if ( ldap_back_retry( lc, op, rs ))
+ goto retry;
+ }
+ ldap_back_freeconn( op, lc );
+ lc = NULL;
+
} else {
rs->sr_err = ldap_parse_whoami(lc->ld, res, &bv);
ldap_msgfree(res);
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++ ) {
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( p );
- len = strlen( s );
+ if ( s[ 0 ] == '\0' ) {
+ len++;
+ }
res = ch_calloc( sizeof( char ), len + sizeof( "%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++;
+ }
+ ptr = lutil_strcopy( ptr, p );
return res;
}
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 ] = "searchResult";
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 );
+ }
+
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "matchedDN";
rargv[ 2 ] = "alias";