mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-02-17 14:00:30 +08:00
Add extensible filter support to -lldap. Need to implement server
side (which most is dependent upon having matching rule support).
This commit is contained in:
parent
366e8fd5ad
commit
83abd65d49
@ -268,13 +268,13 @@ typedef struct ldapcontrol {
|
||||
#define LDAP_FILTER_LE (ber_tag_t) 0xa6U /* context specific + constructed */
|
||||
#define LDAP_FILTER_PRESENT (ber_tag_t) 0x87U /* context specific + primitive */
|
||||
#define LDAP_FILTER_APPROX (ber_tag_t) 0xa8U /* context specific + constructed */
|
||||
#define LDAP_FILTER_EXTENDED (ber_tag_t) 0xa9U /* context specific + constructed */
|
||||
#define LDAP_FILTER_EXT (ber_tag_t) 0xa9U /* context specific + constructed */
|
||||
|
||||
/* extended filter component types */
|
||||
#define LDAP_FILTER_EXTENDED_OID (ber_tag_t) 0x81U /* context specific */
|
||||
#define LDAP_FILTER_EXTENDED_TYPE (ber_tag_t) 0x82U /* context specific */
|
||||
#define LDAP_FILTER_EXTENDED_VALUE (ber_tag_t) 0x83U /* context specific */
|
||||
#define LDAP_FILTER_EXTENDED_DNATTRS (ber_tag_t) 0x84U /* context specific */
|
||||
#define LDAP_FILTER_EXT_OID (ber_tag_t) 0x81U /* context specific */
|
||||
#define LDAP_FILTER_EXT_TYPE (ber_tag_t) 0x82U /* context specific */
|
||||
#define LDAP_FILTER_EXT_VALUE (ber_tag_t) 0x83U /* context specific */
|
||||
#define LDAP_FILTER_EXT_DNATTRS (ber_tag_t) 0x84U /* context specific */
|
||||
|
||||
/* substring filter component types */
|
||||
#define LDAP_SUBSTRING_INITIAL (ber_tag_t) 0x80U /* context specific */
|
||||
|
@ -22,10 +22,10 @@
|
||||
|
||||
#include "ldap-int.h"
|
||||
|
||||
static int ldap_is_attribute LDAP_P((
|
||||
static int ldap_is_attr_oid LDAP_P((
|
||||
const char *attr ));
|
||||
|
||||
static int ldap_is_attribute_ext LDAP_P((
|
||||
static int ldap_is_attr_desc LDAP_P((
|
||||
const char *attr ));
|
||||
|
||||
static int hex2value LDAP_P((
|
||||
@ -333,33 +333,48 @@ ldap_build_search_req(
|
||||
return( ber );
|
||||
}
|
||||
|
||||
#ifndef LDAP_UNDERSCORE
|
||||
#define LDAP_UNDERSCORE ""
|
||||
#endif
|
||||
|
||||
static char *spanset =
|
||||
":-.;" LDAP_UNDERSCORE
|
||||
"ABCDEFGHIGKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789";
|
||||
|
||||
#define ATTR_SPANSET (spanset)
|
||||
#define EXT_SPANSET (&spanset[1])
|
||||
|
||||
static int ldap_is_attribute LDAP_P(( const char *attr ))
|
||||
static int ldap_is_attr_oid LDAP_P(( const char *attr ))
|
||||
{
|
||||
size_t len = strlen( attr );
|
||||
size_t span = strspn( attr, ATTR_SPANSET );
|
||||
int i, c, digit=0;
|
||||
|
||||
for( i=0 ; c = attr[i] ; i++ ) {
|
||||
if( c >= '0' && c <= '9' ) {
|
||||
digit=1;
|
||||
|
||||
} else if ( c != '.' ) {
|
||||
/* not digit nor '.' */
|
||||
return 0;
|
||||
|
||||
} else if ( !digit ) {
|
||||
/* '.' but prev not digit */
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
/* '.' */
|
||||
digit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return digit;
|
||||
|
||||
return span == len;
|
||||
}
|
||||
|
||||
static int ldap_is_attribute_ext LDAP_P(( const char *attr ))
|
||||
static int ldap_is_attr_desc LDAP_P(( const char *attr ))
|
||||
{
|
||||
size_t len = strlen( attr );
|
||||
size_t span = strspn( attr, EXT_SPANSET );
|
||||
/* cheap attribute description check */
|
||||
int i, c;
|
||||
|
||||
return span == len;
|
||||
for( i=0; c = attr[i]; i++ ) {
|
||||
if (( c >= '0' && c <= '9' )
|
||||
|| ( c >= 'A' && c <= 'Z' )
|
||||
|| ( c >= 'a' && c <= 'z' )
|
||||
|| ( c == '.' || c == '-' )
|
||||
|| ( c == ';' )) continue;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return i > 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -706,25 +721,100 @@ put_simple_filter(
|
||||
case '<':
|
||||
ftype = LDAP_FILTER_LE;
|
||||
*s = '\0';
|
||||
if(! ldap_is_attribute( str ) ) goto done;
|
||||
if(! ldap_is_attr_desc( str ) ) goto done;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
ftype = LDAP_FILTER_GE;
|
||||
*s = '\0';
|
||||
if(! ldap_is_attribute( str ) ) goto done;
|
||||
if(! ldap_is_attr_desc( str ) ) goto done;
|
||||
break;
|
||||
|
||||
case '~':
|
||||
ftype = LDAP_FILTER_APPROX;
|
||||
*s = '\0';
|
||||
if(! ldap_is_attribute( str ) ) goto done;
|
||||
if(! ldap_is_attr_desc( str ) ) goto done;
|
||||
break;
|
||||
|
||||
case ':': /* LDAPv3 extended filter */
|
||||
ftype = LDAP_FILTER_EXTENDED;
|
||||
if(! ldap_is_attribute_ext( str ) ) goto done;
|
||||
goto done; /* XXX not yet implemented */
|
||||
case ':':
|
||||
/* RFC2254 extensible filters are off the form:
|
||||
* type [:dn] [:rule] := value
|
||||
* or [:dn]:rule := value
|
||||
*/
|
||||
ftype = LDAP_FILTER_EXT;
|
||||
*s = '\0';
|
||||
|
||||
{
|
||||
char *dn = strchr( str, ':' );
|
||||
char *rule = NULL;
|
||||
|
||||
if( dn == NULL ) {
|
||||
if(! ldap_is_attr_desc( str ) ) goto done;
|
||||
break;
|
||||
}
|
||||
|
||||
*dn++ = '\0';
|
||||
rule = strchr( dn, ':' );
|
||||
|
||||
if( rule == NULL ) {
|
||||
/* one colon */
|
||||
if ( strcmp(dn, "dn") == 0 ) {
|
||||
/* must have attribute */
|
||||
if( !ldap_is_attr_desc( str ) ) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
rule = "";
|
||||
|
||||
} else {
|
||||
rule = dn;
|
||||
dn = NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* two colons */
|
||||
*rule++ = '\0';
|
||||
|
||||
if ( strcmp(dn, "dn") != 0 ) {
|
||||
/* must have "dn" */
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if ( *str == '\0' && *rule == '\0' ) {
|
||||
/* must have either type or rule */
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( *str != '\0' && !ldap_is_attr_desc( str ) ) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( *rule != '\0' && !ldap_is_attr_oid( rule ) ) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = ber_printf( ber, "t{" /*}*/, ftype );
|
||||
|
||||
if( rc != -1 && *rule != '\0' ) {
|
||||
rc = ber_printf( ber, "ts", LDAP_FILTER_EXT_OID, rule );
|
||||
}
|
||||
if( rc != -1 && *str != '\0' ) {
|
||||
rc = ber_printf( ber, "ts", LDAP_FILTER_EXT_TYPE, str );
|
||||
}
|
||||
|
||||
if( rc != -1 ) {
|
||||
ber_slen_t len = filter_value_unescape( value );
|
||||
|
||||
if( len >= 0 ) {
|
||||
rc = ber_printf( ber, "totb}",
|
||||
LDAP_FILTER_EXT_VALUE, value, len,
|
||||
LDAP_FILTER_EXT_DNATTRS, dn != NULL);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user