honor T-F filters (ITS#3706) and some cleanup

This commit is contained in:
Pierangelo Masarati 2005-05-05 00:07:17 +00:00
parent 4d9750afb5
commit c80eb34888
4 changed files with 178 additions and 46 deletions

View File

@ -93,14 +93,20 @@ struct ldapinfo {
#define LDAP_BACK_F_USE_TLS 0x02U
#define LDAP_BACK_F_PROPAGATE_TLS 0x04U
#define LDAP_BACK_F_TLS_CRITICAL 0x08U
#define LDAP_BACK_F_TLS_MASK (LDAP_BACK_F_USE_TLS|LDAP_BACK_F_PROPAGATE_TLS|LDAP_BACK_F_TLS_CRITICAL)
#define LDAP_BACK_F_CHASE_REFERRALS 0x10U
#define LDAP_BACK_F_SUPPORT_T_F 0x80U
#define LDAP_BACK_F_SUPPORT_T_F_DISCOVER 0x40U
#define LDAP_BACK_SAVECRED(li) ( (li)->flags & LDAP_BACK_F_SAVECRED )
#define LDAP_BACK_USE_TLS(li) ( (li)->flags & LDAP_BACK_F_USE_TLS )
#define LDAP_BACK_PROPAGATE_TLS(li) ( (li)->flags & LDAP_BACK_F_PROPAGATE_TLS )
#define LDAP_BACK_TLS_CRITICAL(li) ( (li)->flags & LDAP_BACK_F_TLS_CRITICAL )
#define LDAP_BACK_CHASE_REFERRALS(li) ( (li)->flags & LDAP_BACK_F_CHASE_REFERRALS )
int version;
Avlnode *conntree;
int rwm_started;

View File

@ -217,49 +217,37 @@ ldap_back_db_config(
li->url = ch_strdup( argv[ 1 ] );
#endif
} else if ( strncasecmp( argv[0], "tls-", STRLENOF( "tls-" ) ) == 0 ) {
} else if ( strcasecmp( argv[0], "tls" ) == 0 ) {
if ( argc != 2 ) {
fprintf( stderr,
"%s: line %d: \"tls <what>\" needs 1 argument.\n",
fname, lineno );
return( 1 );
}
/* start tls */
if ( strcasecmp( argv[0], "tls-start" ) == 0 ) {
if ( argc != 1 ) {
fprintf( stderr,
"%s: line %d: tls-start takes no arguments\n",
fname, lineno );
return( 1 );
}
/* start */
if ( strcasecmp( argv[1], "start" ) == 0 ) {
li->flags |= ( LDAP_BACK_F_USE_TLS | LDAP_BACK_F_TLS_CRITICAL );
/* try start tls */
} else if ( strcasecmp( argv[0], "tls-try-start" ) == 0 ) {
if ( argc != 1 ) {
fprintf( stderr,
"%s: line %d: tls-try-start takes no arguments\n",
fname, lineno );
return( 1 );
}
} else if ( strcasecmp( argv[1], "try-start" ) == 0 ) {
li->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
li->flags |= LDAP_BACK_F_USE_TLS;
/* propagate start tls */
} else if ( strcasecmp( argv[0], "tls-propagate" ) == 0 ) {
if ( argc != 1 ) {
fprintf( stderr,
"%s: line %d: tls-propagate takes no arguments\n",
fname, lineno );
return( 1 );
}
} else if ( strcasecmp( argv[1], "propagate" ) == 0 ) {
li->flags |= ( LDAP_BACK_F_PROPAGATE_TLS | LDAP_BACK_F_TLS_CRITICAL );
/* try start tls */
} else if ( strcasecmp( argv[0], "tls-try-propagate" ) == 0 ) {
if ( argc != 1 ) {
fprintf( stderr,
"%s: line %d: tls-try-propagate takes no arguments\n",
fname, lineno );
return( 1 );
}
} else if ( strcasecmp( argv[1], "try-propagate" ) == 0 ) {
li->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
li->flags |= LDAP_BACK_F_PROPAGATE_TLS;
} else {
fprintf( stderr,
"%s: line %d: \"tls <what>\": unknown argument \"%s\".\n",
fname, lineno, argv[1] );
return( 1 );
}
/* remote ACL stuff... */
@ -291,24 +279,50 @@ ldap_back_db_config(
li->flags |= LDAP_BACK_F_SAVECRED;
} else if ( strcasecmp( argv[0], "chase-referrals" ) == 0 ) {
if ( argc != 1 ) {
if ( argc != 2 ) {
fprintf( stderr,
"%s: line %d: \"chase-referrals\" takes no arguments\n",
"%s: line %d: \"chase-referrals\" needs 1 argument.\n",
fname, lineno );
return( 1 );
}
li->flags |= LDAP_BACK_F_CHASE_REFERRALS;
/* this is the default; we add it because the default might change... */
if ( strcasecmp( argv[1], "yes" ) == 0 ) {
li->flags |= LDAP_BACK_F_CHASE_REFERRALS;
} else if ( strcasecmp( argv[0], "dont-chase-referrals" ) == 0 ) {
if ( argc != 1 ) {
} else if ( strcasecmp( argv[1], "no" ) == 0 ) {
li->flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
} else {
fprintf( stderr,
"%s: line %d: \"dont-chase-referrals\" takes no arguments\n",
"%s: line %d: \"chase-referrals {yes|no}\": unknown argument \"%s\".\n",
fname, lineno, argv[1] );
return( 1 );
}
} else if ( strcasecmp( argv[ 0 ], "t-f-support" ) == 0 ) {
if ( argc != 2 ) {
fprintf( stderr,
"%s: line %d: \"t-f-support {no|yes|discover}\" needs 1 argument.\n",
fname, lineno );
return( 1 );
}
li->flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
li->flags &= ~(LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER);
} else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
li->flags |= LDAP_BACK_F_SUPPORT_T_F;
} else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) {
li->flags |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
} else {
fprintf( stderr,
"%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n",
fname, lineno, argv[ 1 ] );
return 1;
}
/* intercept exop_who_am_i? */
} else if ( strcasecmp( argv[0], "proxy-whoami" ) == 0 ) {
@ -352,6 +366,7 @@ ldap_back_db_config(
"triggered by \"%s\" directive.\n",
fname, lineno, argv[ 0 ] );
/* this is the default; we add it because the default might change... */
li->rwm_started = 1;
return ( *be->bd_info->bi_db_config )( be, fname, lineno, argc, argv );
@ -606,6 +621,8 @@ parse_idassert(
ber_bvarray_add( &li->idassert_authz, &rule );
} else if ( strcasecmp( argv[0], "idassert-method" ) == 0 ) {
char *argv1;
if ( argc < 2 ) {
fprintf( stderr,
"%s: line %d: missing method in \"%s <method>\" line\n",
@ -613,7 +630,12 @@ parse_idassert(
return( 1 );
}
if ( strcasecmp( argv[1], "none" ) == 0 ) {
argv1 = argv[1];
if ( strncasecmp( argv1, "bindmethod=", STRLENOF( "bindmethod=" ) ) == 0 ) {
argv1 += STRLENOF( "bindmethod=" );
}
if ( strcasecmp( argv1, "none" ) == 0 ) {
/* FIXME: is this at all useful? */
li->idassert_authmethod = LDAP_AUTH_NONE;
@ -623,7 +645,7 @@ parse_idassert(
fname, lineno, argv[0], argv[1] );
}
} else if ( strcasecmp( argv[1], "simple" ) == 0 ) {
} else if ( strcasecmp( argv1, "simple" ) == 0 ) {
li->idassert_authmethod = LDAP_AUTH_SIMPLE;
if ( argc != 2 ) {
@ -632,7 +654,7 @@ parse_idassert(
fname, lineno, argv[0], argv[1] );
}
} else if ( strcasecmp( argv[1], "sasl" ) == 0 ) {
} else if ( strcasecmp( argv1, "sasl" ) == 0 ) {
#ifdef HAVE_CYRUS_SASL
int arg;
@ -823,6 +845,8 @@ parse_acl_auth(
ber_str2bv( argv[1], 0, 1, &li->acl_passwd );
} else if ( strcasecmp( argv[0], "acl-method" ) == 0 ) {
char *argv1;
if ( argc < 2 ) {
fprintf( stderr,
"%s: line %d: missing method in \"%s <method>\" line\n",
@ -830,7 +854,12 @@ parse_acl_auth(
return( 1 );
}
if ( strcasecmp( argv[1], "none" ) == 0 ) {
argv1 = argv[1];
if ( strncasecmp( argv1, "bindmethod=", STRLENOF( "bindmethod=" ) ) == 0 ) {
argv1 += STRLENOF( "bindmethod=" );
}
if ( strcasecmp( argv1, "none" ) == 0 ) {
/* FIXME: is this at all useful? */
li->acl_authmethod = LDAP_AUTH_NONE;
@ -840,7 +869,7 @@ parse_acl_auth(
fname, lineno, argv[0], argv[1] );
}
} else if ( strcasecmp( argv[1], "simple" ) == 0 ) {
} else if ( strcasecmp( argv1, "simple" ) == 0 ) {
li->acl_authmethod = LDAP_AUTH_SIMPLE;
if ( argc != 2 ) {
@ -849,7 +878,7 @@ parse_acl_auth(
fname, lineno, argv[0], argv[1] );
}
} else if ( strcasecmp( argv[1], "sasl" ) == 0 ) {
} else if ( strcasecmp( argv1, "sasl" ) == 0 ) {
#ifdef HAVE_CYRUS_SASL
int arg;

View File

@ -113,6 +113,9 @@ ldap_back_db_init( Backend *be )
/* initialize flags */
li->flags = LDAP_BACK_F_CHASE_REFERRALS;
/* initialize version */
li->version = LDAP_VERSION3;
ldap_pvt_thread_mutex_init( &li->conn_mutex );
be->be_private = li;
@ -121,6 +124,73 @@ ldap_back_db_init( Backend *be )
return 0;
}
int
ldap_back_discover_t_f_support( const char *uri, int version )
{
LDAP *ld;
LDAPMessage *res = NULL, *entry;
int rc, i;
struct berval cred = BER_BVC( "" ),
absoluteFilters = BER_BVC( LDAP_FEATURE_ABSOLUTE_FILTERS ),
**values = NULL;
char *attrs[ 2 ] = { "supportedFeatures", NULL };
rc = ldap_initialize( &ld, uri );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
rc = ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
if ( rc != LDAP_SUCCESS ) {
goto done;
}
rc = ldap_sasl_bind_s( ld, "", LDAP_SASL_SIMPLE,
&cred, NULL, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
goto done;
}
rc = ldap_search_ext_s( ld, "", LDAP_SCOPE_BASE, "(objectClass=*)",
attrs, 0, NULL, NULL, NULL, 0, &res );
if ( rc != LDAP_SUCCESS ) {
goto done;
}
entry = ldap_first_entry( ld, res );
if ( entry == NULL ) {
goto done;
}
values = ldap_get_values_len( ld, entry, attrs[ 0 ] );
if ( values == NULL ) {
rc = LDAP_NO_SUCH_ATTRIBUTE;
goto done;
}
for ( i = 0; values[ i ] != NULL; i++ ) {
if ( bvmatch( &absoluteFilters, values[ i ] ) ) {
rc = LDAP_COMPARE_TRUE;
goto done;
}
}
rc = LDAP_COMPARE_FALSE;
done:;
if ( values != NULL ) {
ldap_value_free_len( values );
}
if ( res != NULL ) {
ldap_msgfree( res );
}
ldap_unbind_ext( ld, NULL, NULL );
return rc;
}
int
ldap_back_db_open( BackendDB *be )
{
@ -175,6 +245,17 @@ ldap_back_db_open( BackendDB *be )
}
#endif /* SLAPD_MONITOR */
if ( li->flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER ) {
int rc;
li->flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
rc = ldap_back_discover_t_f_support( li->url, li->version );
if ( rc == LDAP_COMPARE_TRUE ) {
li->flags |= LDAP_BACK_F_SUPPORT_T_F;
}
}
return 0;
}

View File

@ -46,6 +46,8 @@ ldap_back_search(
Operation *op,
SlapReply *rs )
{
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
struct ldapconn *lc;
struct timeval tv;
LDAPMessage *res,
@ -54,7 +56,11 @@ ldap_back_search(
msgid;
struct berval match = BER_BVNULL;
int i;
char **attrs = NULL;
char **attrs = NULL,
*filter = NULL;
static struct berval
bv_true = BER_BVC( "(?=true)" ),
bv_false = BER_BVC( "(?=false)" );
int dontfreetext = 0;
int do_retry = 1;
LDAPControl **ctrls = NULL;
@ -109,10 +115,20 @@ ldap_back_search(
dontfreetext = 1;
goto finish;
}
/* deal with <draft-zeilenga-ldap-t-f> filters */
filter = op->ors_filterstr.bv_val;
if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) {
if ( bvmatch( &op->ors_filterstr, &bv_true ) ) {
filter = "(&)";
} else if ( bvmatch( &op->ors_filterstr, &bv_false ) ) {
filter = "(|)";
}
}
retry:
rs->sr_err = ldap_search_ext( lc->lc_ld, op->o_req_ndn.bv_val,
op->ors_scope, op->ors_filterstr.bv_val,
op->ors_scope, filter,
attrs, op->ors_attrsonly, ctrls, NULL,
tv.tv_sec ? &tv : NULL,
op->ors_slimit, &msgid );