From 45118be88ed82e2bb660d5d4343fbafe3e9fad67 Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Fri, 2 Apr 1999 03:23:20 +0000 Subject: [PATCH] Fix wait4child change: Prefer wait3 over wait. Use SIGNAL instead of signal. --- servers/slapd/aclparse.c | 7 +- servers/slapd/attr.c | 2 +- servers/slapd/back-bdb2/alias.c | 2 +- servers/slapd/back-bdb2/bind.c | 1 + servers/slapd/back-bdb2/group.c | 2 +- servers/slapd/back-bdb2/search.c | 2 +- servers/slapd/back-ldbm/alias.c | 2 +- servers/slapd/back-ldbm/bind.c | 1 + servers/slapd/back-ldbm/group.c | 2 +- servers/slapd/back-ldbm/search.c | 2 +- servers/slapd/config.c | 8 +- servers/slapd/dn.c | 87 ++++++++++++--------- servers/slapd/main.c | 16 ++-- servers/slapd/proto-slap.h | 4 +- servers/slapd/result.c | 4 + servers/slapd/shell-backends/passwd-shell.c | 2 +- servers/slapd/slap.h | 3 + servers/slapd/tools/centipede.c | 4 + servers/slapd/value.c | 25 ++++-- 19 files changed, 105 insertions(+), 71 deletions(-) diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c index b7b0d9507a..61a31f1c57 100644 --- a/servers/slapd/aclparse.c +++ b/servers/slapd/aclparse.c @@ -108,7 +108,7 @@ parse_acl( break; } - if ( strcasecmp( argv[i], "*" ) == 0 ) { + if ( strcmp( argv[i], "*" ) == 0 ) { int e; if ((e = regcomp( &a->acl_dnre, ".*", REG_EXTENDED|REG_ICASE))) @@ -152,6 +152,7 @@ parse_acl( acl_usage(); } else { + /* ### Should be normalized, but how? */ a->acl_dnpat = dn_upcase(ch_strdup( right )); } } else if ( strncasecmp( left, "attr", 4 ) @@ -192,12 +193,13 @@ parse_acl( /* get */ 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 ); @@ -216,6 +218,7 @@ parse_acl( *name++ = '\0'; } + /* ### Should it be normalized? */ b->a_group = dn_upcase(ch_strdup( right )); if (value && *value) { diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c index c1178c94e9..581f4570e7 100644 --- a/servers/slapd/attr.c +++ b/servers/slapd/attr.c @@ -279,7 +279,7 @@ attr_syntax_config( 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; diff --git a/servers/slapd/back-bdb2/alias.c b/servers/slapd/back-bdb2/alias.c index 5b3588f7ee..4bec355fa6 100644 --- a/servers/slapd/back-bdb2/alias.c +++ b/servers/slapd/back-bdb2/alias.c @@ -222,7 +222,7 @@ char *bdb2i_derefDN ( BackendDB *be, 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); diff --git a/servers/slapd/back-bdb2/bind.c b/servers/slapd/back-bdb2/bind.c index b51d9ea136..29e5304a64 100644 --- a/servers/slapd/back-bdb2/bind.c +++ b/servers/slapd/back-bdb2/bind.c @@ -163,6 +163,7 @@ bdb2i_back_bind_internal( /* * 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; diff --git a/servers/slapd/back-bdb2/group.c b/servers/slapd/back-bdb2/group.c index 4634107ba4..6865cf2ac2 100644 --- a/servers/slapd/back-bdb2/group.c +++ b/servers/slapd/back-bdb2/group.c @@ -101,7 +101,7 @@ bdb2i_back_group_internal( "<= 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 ); diff --git a/servers/slapd/back-bdb2/search.c b/servers/slapd/back-bdb2/search.c index 5080a5faad..8e6b7950d9 100644 --- a/servers/slapd/back-bdb2/search.c +++ b/servers/slapd/back-bdb2/search.c @@ -525,7 +525,7 @@ subtree_candidates( 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; } diff --git a/servers/slapd/back-ldbm/alias.c b/servers/slapd/back-ldbm/alias.c index 9c4f1adeac..5224839c5b 100644 --- a/servers/slapd/back-ldbm/alias.c +++ b/servers/slapd/back-ldbm/alias.c @@ -221,7 +221,7 @@ char *derefDN ( Backend *be, 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); diff --git a/servers/slapd/back-ldbm/bind.c b/servers/slapd/back-ldbm/bind.c index 70d3d06d4a..8c4fb3fcc0 100644 --- a/servers/slapd/back-ldbm/bind.c +++ b/servers/slapd/back-ldbm/bind.c @@ -164,6 +164,7 @@ ldbm_back_bind( /* * 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; diff --git a/servers/slapd/back-ldbm/group.c b/servers/slapd/back-ldbm/group.c index eb35dc3d7e..beecb2d1fa 100644 --- a/servers/slapd/back-ldbm/group.c +++ b/servers/slapd/back-ldbm/group.c @@ -101,7 +101,7 @@ ldbm_back_group( "<= 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 ); diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c index 04e0593193..5434966e5d 100644 --- a/servers/slapd/back-ldbm/search.c +++ b/servers/slapd/back-ldbm/search.c @@ -483,7 +483,7 @@ subtree_candidates( 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; } diff --git a/servers/slapd/config.c b/servers/slapd/config.c index b02313b5ce..94ff13b468 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -208,19 +208,17 @@ read_config( char *fname ) 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 ); } diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c index e7bb61d584..38c4bdab89 100644 --- a/servers/slapd/dn.c +++ b/servers/slapd/dn.c @@ -11,24 +11,32 @@ #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 ); */ @@ -39,18 +47,28 @@ dn_normalize( char *dn ) 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 == '=' ) { @@ -58,7 +76,7 @@ dn_normalize( char *dn ) *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: @@ -67,7 +85,7 @@ dn_normalize( char *dn ) *d++ = *s; } else if ( ! SPACE( *s ) ) { state = INVALUE; - *d++ = *s; + *d++ = (ic ? TOUPPER((unsigned char) *s) : *s); } break; case INVALUE: @@ -82,10 +100,10 @@ dn_normalize( char *dn ) } } 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: @@ -93,10 +111,10 @@ dn_normalize( char *dn ) 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: @@ -122,28 +140,23 @@ dn_normalize( char *dn ) 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 */ diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 6c06c02799..c37b0031b7 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -312,23 +312,19 @@ static RETSIGTYPE 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; } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 7907d6a623..108ca114b0 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -130,8 +130,8 @@ void connection_done LDAP_P((Connection *)); * 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 )); diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 17f454ac83..f03423a0b6 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -273,6 +273,10 @@ send_search_entry( ! 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; } diff --git a/servers/slapd/shell-backends/passwd-shell.c b/servers/slapd/shell-backends/passwd-shell.c index 89d2fd73d6..f546d2de5b 100644 --- a/servers/slapd/shell-backends/passwd-shell.c +++ b/servers/slapd/shell-backends/passwd-shell.c @@ -106,7 +106,7 @@ pwdfile_search( struct ldop *op, FILE *ofp ) 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; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index a7d99114dd..0f86b9001e 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -460,6 +460,9 @@ typedef struct slap_conn { #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 diff --git a/servers/slapd/tools/centipede.c b/servers/slapd/tools/centipede.c index 536417b43f..f01b44a72f 100644 --- a/servers/slapd/tools/centipede.c +++ b/servers/slapd/tools/centipede.c @@ -502,6 +502,10 @@ generate_new_centroids( /* 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; } diff --git a/servers/slapd/value.c b/servers/slapd/value.c index ccabdf06a4..97fd1f4a39 100644 --- a/servers/slapd/value.c +++ b/servers/slapd/value.c @@ -82,18 +82,16 @@ value_normalize( 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; @@ -112,7 +110,16 @@ value_cmp( ) { 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 ); @@ -121,18 +128,22 @@ value_cmp( 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 ) -- 2.39.5