break;
}
- if ( strcasecmp( argv[i], "*" ) == 0 ) {
+ if ( strcmp( argv[i], "*" ) == 0 ) {
int e;
if ((e = regcomp( &a->acl_dnre, ".*",
REG_EXTENDED|REG_ICASE)))
acl_usage();
} else {
+ /* ### Should be normalized, but how? */
a->acl_dnpat = dn_upcase(ch_strdup( right ));
}
} else if ( strncasecmp( left, "attr", 4 )
/* get <who> */
split( argv[i], '=', &left, &right );
- if ( strcasecmp( argv[i], "*" ) == 0 ) {
+ if ( strcmp( argv[i], "*" ) == 0 ) {
b->a_dnpat = ch_strdup( ".*" );
} else if ( strcasecmp( argv[i], "self" ) == 0 ) {
b->a_dnpat = ch_strdup( "self" );
} else if ( strcasecmp( left, "dn" ) == 0 ) {
regtest(fname, lineno, right);
+ /* ### Should be normalized, but how? */
b->a_dnpat = dn_upcase( ch_strdup( right ) );
} else if ( strcasecmp( left, "dnattr" ) == 0 ) {
b->a_dnattr = ch_strdup( right );
*name++ = '\0';
}
+ /* ### Should it be normalized? */
b->a_group = dn_upcase(ch_strdup( right ));
if (value && *value) {
strcasecmp( argv[lasti], "tel" ) == 0 ) {
a->asi_syntax = (SYNTAX_CIS | SYNTAX_TEL);
} else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) {
- a->asi_syntax = (SYNTAX_CIS | SYNTAX_DN);
+ a->asi_syntax = SYNTAX_DN;
} else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 ||
strcasecmp( argv[lasti], "ces" ) == 0 ) {
a->asi_syntax = SYNTAX_CES;
Debug( LDAP_DEBUG_TRACE, "<= l&g we have %s vs %s \n", matched, eNew->e_dn, 0 );
- i = strcasecmp (matched, eNew->e_dn);
+ i = dn_casecmp (matched, eNew->e_dn);
/* free reader lock */
bdb2i_cache_return_entry_r(&li->li_cache, eNew);
/*
* no krbName values present: check against DN
*/
+ /*###??? Should this be some variant of dn_casecmp? */
if ( strcasecmp( dn, krbname ) == 0 ) {
rc = 0; /* XXX wild ass guess */
break;
"<= bdb2i_back_group: failed to find %s in objectClass\n",
objectclassValue, 0, 0 );
}
- else if (value_find(member->a_vals, &bvMembers, SYNTAX_CIS, 1) != 0) {
+ else if (value_find(member->a_vals, &bvMembers, member->a_syntax, 1) != 0) {
Debug( LDAP_DEBUG_ACL,
"<= bdb2i_back_group: \"%s\" not in \"%s\": %s\n",
op_ndn, gr_ndn, groupattrName );
f->f_and->f_sub_initial = NULL;
f->f_and->f_sub_any = NULL;
f->f_and->f_sub_final = ch_strdup( base );
- value_normalize( f->f_and->f_sub_final, SYNTAX_CIS );
+ value_normalize( f->f_and->f_sub_final, SYNTAX_DN );
f->f_and->f_next = filter;
filter = f;
}
Debug( LDAP_DEBUG_TRACE, "<= l&g we have %s vs %s \n", matched, eNew->e_dn, 0 );
- i = strcasecmp (matched, eNew->e_dn);
+ i = dn_casecmp (matched, eNew->e_dn);
/* free reader lock */
cache_return_entry_r(&li->li_cache, eNew);
/*
* no krbName values present: check against DN
*/
+ /*###??? Should this be some variant of dn_casecmp? */
if ( strcasecmp( dn, krbname ) == 0 ) {
rc = 0; /* XXX wild ass guess */
break;
"<= ldbm_back_group: failed to find %s in objectClass\n",
objectclassValue, 0, 0 );
}
- else if (value_find(member->a_vals, &bvMembers, SYNTAX_CIS, 1) != 0) {
+ else if (value_find(member->a_vals, &bvMembers, member->a_syntax, 1) != 0) {
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: \"%s\" not in \"%s\": %s\n",
op_ndn, gr_ndn, groupattrName );
f->f_and->f_sub_initial = NULL;
f->f_and->f_sub_any = NULL;
f->f_and->f_sub_final = ch_strdup( base );
- value_normalize( f->f_and->f_sub_final, SYNTAX_CIS );
+ value_normalize( f->f_and->f_sub_final, SYNTAX_DN );
f->f_and->f_next = filter;
filter = f;
}
char *alias, *aliased_dn;
alias = ch_strdup( cargv[1] );
- (void) dn_normalize( alias );
+ (void) dn_normalize_case( alias );
aliased_dn = ch_strdup( cargv[2] );
- (void) dn_normalize( aliased_dn );
+ (void) dn_normalize_case( aliased_dn );
- if ( strcasecmp( alias, aliased_dn) == 0 ) {
+ if ( strcmp( alias, aliased_dn) == 0 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: suffixAlias %s is not different from aliased dn (ignored)\n",
fname, lineno, alias );
} else {
- (void) dn_normalize_case( alias );
- (void) dn_normalize_case( aliased_dn );
charray_add( &be->be_suffixAlias, alias );
charray_add( &be->be_suffixAlias, aliased_dn );
}
#include "slap.h"
-#define B4TYPE 0
-#define INTYPE 1
-#define B4EQUAL 2
-#define B4VALUE 3
-#define INVALUE 4
-#define INQUOTEDVALUE 5
-#define B4SEPARATOR 6
+typedef enum DnState {
+ B4TYPE, /* before attribute type */
+ INTYPE, /* in attribute type */
+ B4EQUAL, /* before '=' */
+ B4VALUE, /* before attribute value */
+ INVALUE, /* in attribute value */
+ INQUOTEDVALUE, /* in "" in attribute value */
+ B4SEPARATOR, /* before separator ('+', ',' or ';') */
+} DnState;
/*
- * dn_normalize - put dn into a canonical format. the dn is
- * normalized in place, as well as returned.
+ * dn_normalize_internal - put dn into a canonical form suitable for storing
+ * in a hash database. If correct_case == 1, this involves normalizing the case
+ * as well as the format. The dn is normalized in place as well as returned.
+ *
+ * The dn_normalize() and dn_normalize_case() macros use this function.
*/
char *
-dn_normalize( char *dn )
+dn_normalize_internal( char *dn, int correct_case )
{
- char *d, *s;
- int state, gotesc;
+ char *s, *d; /* source and destination pointers */
+ char *type; /* start of attr.type when state==INTYPE */
+ int gotesc; /* last char was '\\' */
+ int ic; /* ignore case */
+ DnState state;
/* Debug( LDAP_DEBUG_TRACE, "=> dn_normalize \"%s\"\n", dn, 0, 0 ); */
case B4TYPE:
if ( ! SPACE( *s ) ) {
state = INTYPE;
- *d++ = *s;
+ ic = 1;
+ type = d;
+ *d++ = TOUPPER( (unsigned char) *s );
}
break;
case INTYPE:
if ( *s == '=' ) {
state = B4VALUE;
- *d++ = *s;
} else if ( SPACE( *s ) ) {
state = B4EQUAL;
} else {
- *d++ = *s;
+ *d++ = TOUPPER( (unsigned char) *s );
+ break;
+ }
+ /* Check if case is ignored in this type */
+ if ( correct_case ) {
+ *d = '\0';
+ if ( ! (attr_syntax( type ) | SYNTAX_CIS) )
+ ic = 0;
}
+ if (state == B4VALUE)
+ *d++ = '=';
break;
case B4EQUAL:
if ( *s == '=' ) {
*d++ = *s;
} else if ( ! SPACE( *s ) ) {
/* not a valid dn - but what can we do here? */
- *d++ = *s;
+ *d++ = TOUPPER( (unsigned char) *s );
}
break;
case B4VALUE:
*d++ = *s;
} else if ( ! SPACE( *s ) ) {
state = INVALUE;
- *d++ = *s;
+ *d++ = (ic ? TOUPPER((unsigned char) *s) : *s);
}
break;
case INVALUE:
}
} else if ( gotesc && !NEEDSESCAPE( *s ) &&
!SEPARATOR( *s ) ) {
- *--d = *s;
+ *--d = (ic ? TOUPPER((unsigned char) *s) : *s);
d++;
} else {
- *d++ = *s;
+ *d++ = (ic ? TOUPPER((unsigned char) *s) : *s);
}
break;
case INQUOTEDVALUE:
state = B4SEPARATOR;
*d++ = *s;
} else if ( gotesc && !NEEDSESCAPE( *s ) ) {
- *--d = *s;
+ *--d = (ic ? TOUPPER((unsigned char) *s) : *s);
d++;
} else {
- *d++ = *s;
+ *d++ = (ic ? TOUPPER((unsigned char) *s) : *s);
}
break;
case B4SEPARATOR:
return( dn );
}
+
/*
- * dn_normalize_case - put dn into a canonical form suitable for storing
- * in a hash database. this involves normalizing the case as well as
- * the format. the dn is normalized in place as well as returned.
+ * dn_casecmp - compare two DNs after normalizing (private copies of) them
*/
-char *
-dn_normalize_case( char *dn )
+int
+dn_casecmp( const char *dn1, const char *dn2 )
{
- char *s;
-
- /* normalize format */
- dn_normalize( dn );
-
- /* normalize case */
- for ( s = dn; *s; s++ ) {
- *s = TOUPPER( (unsigned char) *s );
- }
-
- return( dn );
+ char *ndn1 = dn_normalize_case( ch_strdup( dn1 ) );
+ char *ndn2 = dn_normalize_case( ch_strdup( dn2 ) );
+ int i = strcmp( ndn1, ndn2 );
+ free( ndn1 );
+ free( ndn2 );
+ return i;
}
+
/*
* dn_parent - return a copy of the dn of dn's parent
*/
wait4child( int sig )
{
int save_errno = errno;
+
+#ifdef WNOHANG
errno = 0;
- /*
- * ### The wait3 vs. waitpid choice needs improvement.
- * ### There are apparently systems where waitpid(-1, ...) fails, and
- * ### others where waitpid should preferred over wait3 for some reason.
- * ### Now wait3 is only here for reference, configure does not detect it.
- */
-#if defined(HAVE_WAITPID) && defined(WNOHANG)
+#ifdef HAVE_WAITPID
while ( waitpid( (pid_t)-1, NULL, WNOHANG ) >= 0 || errno == EINTR )
; /* NULL */
-#elif defined(HAVE_WAIT3) && defined(WNOHANG)
+#else
while ( wait3( NULL, WNOHANG, NULL ) >= 0 || errno == EINTR )
; /* NULL */
-#else
+#endif
(void) wait( NULL );
#endif
- (void) signal( sig, wait4child );
+ (void) SIGNAL( sig, wait4child );
errno = save_errno;
}
* dn.c
*/
-char * dn_normalize LDAP_P(( char *dn ));
-char * dn_normalize_case LDAP_P(( char *dn ));
+char * dn_normalize_internal LDAP_P(( char *dn, int correct_case ));
+int dn_casecmp LDAP_P(( const char *dn1, const char *dn2 ));
char * dn_parent LDAP_P(( Backend *be, char *dn ));
char * dn_rdn LDAP_P(( Backend *be, char *dn ));
int dn_issuffix LDAP_P(( char *dn, char *suffix ));
! acl_access_allowed( acl, be, conn, e, a->a_vals[i], op,
ACL_READ, edn, matches) )
{
+ /* ### What the hell? Attributes with DN-syntax
+ * ### are only returned if we have access to
+ * ### the entry with that DN? Or...?
+ */
continue;
}
for ( pw = getpwent(); pw != NULL; pw = getpwent()) {
if (( entry = pw2entry( op, pw )) != NULL ) {
if ( oneentry ) {
- if ( strcasecmp( op->ldop_dn, entry->lde_dn ) == 0 ) {
+ if ( dn_casecmp( op->ldop_dn, entry->lde_dn ) == 0 ) {
write_entry( op, entry, ofp );
break;
}
#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 )
#endif
+#define dn_normalize(dn) dn_normalize_internal( dn, 0 )
+#define dn_normalize_case(dn) dn_normalize_internal( dn, 1 )
+
#include "proto-slap.h"
LDAP_END_DECL
/* normalize the value */
for ( s = val[j]; *s; s++ ) {
+ /* May need other normalization here,
+ * unless that breaks compatibility
+ * with other centipedes
+ */
*s = TOLOWER( (unsigned char) *s );
last = *s;
}
int syntax
)
{
- char *d, *save;
-
- if ( ! (syntax & SYNTAX_CIS) ) {
- return;
- }
+ char *d;
if ( syntax & SYNTAX_DN ) {
(void) dn_normalize_case( s );
return;
}
+ if ( ! (syntax & SYNTAX_CIS) ) {
+ return;
+ }
- save = s;
for ( d = s; *s; s++ ) {
if ( (syntax & SYNTAX_TEL) && (*s == ' ' || *s == '-') ) {
continue;
)
{
int rc;
+ unsigned char *s1, *s2;
+
+ if ( syntax & SYNTAX_DN ) /* #### TEST ### */
+ normalize = 3;
+ if ( normalize ) {
+ if ( ! (syntax & ~(SYNTAX_CIS | SYNTAX_CES | SYNTAX_BIN)) )
+ /* Normalization not needed,
+ * in SYNTAX_CIS's case because it's handled by strcascmp */
+ normalize = 0;
if ( normalize & 1 ) {
v1 = ber_bvdup( v1 );
value_normalize( v1->bv_val, syntax );
v2 = ber_bvdup( v2 );
value_normalize( v2->bv_val, syntax );
}
+ }
switch ( syntax ) {
case SYNTAX_CIS:
case (SYNTAX_CIS | SYNTAX_TEL):
- case (SYNTAX_CIS | SYNTAX_DN):
rc = strcasecmp( v1->bv_val, v2->bv_val );
break;
+ case SYNTAX_DN:
case SYNTAX_CES:
rc = strcmp( v1->bv_val, v2->bv_val );
break;
+ default:
+ Debug( LDAP_DEBUG_ANY, "value_cmp: unknown syntax %d.\n", syntax, 0, 0);
+ /* Fall through */
case SYNTAX_BIN:
rc = (v1->bv_len == v2->bv_len
? memcmp( v1->bv_val, v2->bv_val, v1->bv_len )