diff options
Diffstat (limited to 'ldap/servers/plugins/syntaxes')
-rw-r--r-- | ldap/servers/plugins/syntaxes/string.c | 166 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/syntax.h | 1 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/validate.c | 12 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/value.c | 90 |
4 files changed, 209 insertions, 60 deletions
diff --git a/ldap/servers/plugins/syntaxes/string.c b/ldap/servers/plugins/syntaxes/string.c index 9b338335..21ff5d1b 100644 --- a/ldap/servers/plugins/syntaxes/string.c +++ b/ldap/servers/plugins/syntaxes/string.c @@ -63,6 +63,7 @@ string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax, { int i, rc; struct berval bvfilter_norm; + char *alt = NULL; if(retVal) { *retVal = NULL; @@ -74,7 +75,12 @@ string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax, bvfilter_norm.bv_val = slapi_ch_malloc( bvfilter->bv_len + 1 ); SAFEMEMCPY( bvfilter_norm.bv_val, bvfilter->bv_val, bvfilter->bv_len ); bvfilter_norm.bv_val[bvfilter->bv_len] = '\0'; - value_normalize( bvfilter_norm.bv_val, syntax, 1 /* trim leading blanks */ ); + /* 3rd arg: 1 - trim leading blanks */ + value_normalize_ext( bvfilter_norm.bv_val, syntax, 1, &alt ); + if (alt) { + slapi_ch_free_string(&bvfilter_norm.bv_val); + bvfilter_norm.bv_val = alt; + } bvfilter_norm.bv_len = strlen(bvfilter_norm.bv_val); for ( i = 0; (bvals != NULL) && (bvals[i] != NULL); i++ ) { @@ -211,6 +217,7 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final, Operation *op = NULL; Slapi_Regex *re = NULL; const char *re_result = NULL; + char *alt = NULL; LDAPDebug( LDAP_DEBUG_FILTER, "=> string_filter_sub\n", 0, 0, 0 ); @@ -260,27 +267,45 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final, } if ( initial != NULL ) { - value_normalize( initial, syntax, 1 /* trim leading blanks */ ); + /* 3rd arg: 1 - trim leading blanks */ + value_normalize_ext( initial, syntax, 1, &alt ); *p++ = '^'; - filter_strcpy_special_ext( p, initial, FILTER_STRCPY_ESCAPE_RECHARS ); + if (alt) { + filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS ); + slapi_ch_free_string(&alt); + } else { + filter_strcpy_special_ext( p, initial, FILTER_STRCPY_ESCAPE_RECHARS ); + } p = strchr( p, '\0' ); } if ( any != NULL ) { for ( i = 0; any[i] != NULL; i++ ) { - value_normalize( any[i], syntax, 0 /* DO NOT trim leading blanks */ ); + /* 3rd arg: 0 - DO NOT trim leading blanks */ + value_normalize_ext( any[i], syntax, 0, &alt ); /* ".*" + value */ *p++ = '.'; *p++ = '*'; - filter_strcpy_special_ext( p, any[i], FILTER_STRCPY_ESCAPE_RECHARS ); + if (alt) { + filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS ); + slapi_ch_free_string(&alt); + } else { + filter_strcpy_special_ext( p, any[i], FILTER_STRCPY_ESCAPE_RECHARS ); + } p = strchr( p, '\0' ); } } if ( final != NULL ) { - value_normalize( final, syntax, 0 /* DO NOT trim leading blanks */ ); + /* 3rd arg: 0 - DO NOT trim leading blanks */ + value_normalize_ext( final, syntax, 0, &alt ); /* ".*" + value */ *p++ = '.'; *p++ = '*'; - filter_strcpy_special_ext( p, final, FILTER_STRCPY_ESCAPE_RECHARS ); + if (alt) { + filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS ); + slapi_ch_free_string(&alt); + } else { + filter_strcpy_special_ext( p, final, FILTER_STRCPY_ESCAPE_RECHARS ); + } strcat( p, "$" ); } @@ -327,9 +352,15 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final, strcpy( tmpbuf, bvp->bv_val ); realval = tmpbuf; } - value_normalize( realval, syntax, 1 /* trim leading blanks */ ); + /* 3rd arg: 1 - trim leading blanks */ + value_normalize_ext( realval, syntax, 1, &alt ); - tmprc = slapi_re_exec( re, realval, time_up ); + if (alt) { + tmprc = slapi_re_exec( re, alt, time_up ); + slapi_ch_free_string(&alt); + } else { + tmprc = slapi_re_exec( re, realval, time_up ); + } LDAPDebug( LDAP_DEBUG_TRACE, "re_exec (%s) %i\n", escape_string( realval, ebuf ), tmprc, 0 ); @@ -359,6 +390,7 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals, Slapi_Value **nbvals, **nbvlp; Slapi_Value **bvlp; char *w, *c, *p; + char *alt = NULL; if (NULL == ivals) { return 1; @@ -380,9 +412,16 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals, { c = slapi_ch_strdup(slapi_value_get_string(*bvlp)); /* if the NORMALIZED flag is set, skip normalizing */ - if (!(slapi_value_get_flags(*bvlp) & SLAPI_ATTR_FLAG_NORMALIZED)) - value_normalize( c, syntax, 1 /* trim leading blanks */ ); - *nbvlp = slapi_value_new_string_passin(c); + if (!(slapi_value_get_flags(*bvlp) & SLAPI_ATTR_FLAG_NORMALIZED)) { + /* 3rd arg: 1 - trim leading blanks */ + value_normalize_ext( c, syntax, 1, &alt ); + } + if (alt) { + slapi_ch_free_string(&c); + *nbvlp = slapi_value_new_string_passin(alt); + } else { + *nbvlp = slapi_value_new_string_passin(c); + } } *ivals = nbvals; break; @@ -470,14 +509,16 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals, for ( bvlp = bvals; bvlp && *bvlp; bvlp++ ) { /* * Note: this calculation may err on the high side, - * because value_normalize(), which is called below + * because value_normalize_ext(), which is called below * before we actually create the substring keys, may - * reduce the length of the value in some cases. For - * example, spaces are removed when space insensitive - * strings are normalized. But it's okay for nsubs to - * be too big. Since the ivals array is NULL terminated, - * the only downside is that we allocate more space than - * we really need. + * reduce the length of the value in some cases or + * increase the length in other cases. For example, + * spaces are removed when space insensitive strings + * are normalized. Or if the value includes '\"' (2 bytes), + * it's normalized to '\22' (3 bytes). But it's okay + * for nsubs to be too big. Since the ivals array is + * NULL terminated, the only downside is that we + * allocate more space than we really need. */ nsubs += slapi_value_get_length(*bvlp) - substrlens[INDEX_SUBSTRMIDDLE] + 3; } @@ -489,8 +530,14 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals, bvdup= slapi_value_new(); for ( bvlp = bvals; bvlp && *bvlp; bvlp++ ) { c = slapi_ch_strdup(slapi_value_get_string(*bvlp)); - value_normalize( c, syntax, 1 /* trim leading blanks */ ); - slapi_value_set_string_passin(bvdup, c); + /* 3rd arg: 1 - trim leading blanks */ + value_normalize_ext( c, syntax, 1, &alt ); + if (alt) { + slapi_ch_free_string(&c); + slapi_value_set_string_passin(bvdup, alt); + } else { + slapi_value_set_string_passin(bvdup, c); + } bvp = slapi_value_get_berval(bvdup); @@ -554,6 +601,7 @@ string_assertion2keys_ava( size_t len; char *w, *c; Slapi_Value *tmpval=NULL; + char *alt = NULL; switch ( ftype ) { case LDAP_FILTER_EQUALITY_FAST: @@ -565,13 +613,23 @@ string_assertion2keys_ava( } memcpy(tmpval->bv.bv_val,slapi_value_get_string(val),len); tmpval->bv.bv_val[len]='\0'; - value_normalize(tmpval->bv.bv_val, syntax, 1 /* trim leading blanks */ ); + /* 3rd arg: 1 - trim leading blanks */ + value_normalize_ext(tmpval->bv.bv_val, syntax, 1, &alt ); + if (alt) { + slapi_ch_free_string(&tmpval->bv.bv_val); + tmpval->bv.bv_val = alt; + } tmpval->bv.bv_len=strlen(tmpval->bv.bv_val); break; case LDAP_FILTER_EQUALITY: (*ivals) = (Slapi_Value **) slapi_ch_malloc( 2 * sizeof(Slapi_Value *) ); (*ivals)[0] = slapi_value_dup( val ); - value_normalize( (*ivals)[0]->bv.bv_val, syntax, 1 /* trim leading blanks */ ); + /* 3rd arg: 1 - trim leading blanks */ + value_normalize_ext( (*ivals)[0]->bv.bv_val, syntax, 1, &alt ); + if (alt) { + slapi_ch_free_string(&(*ivals)[0]->bv.bv_val); + (*ivals)[0]->bv.bv_val = alt; + } (*ivals)[0]->bv.bv_len = strlen( (*ivals)[0]->bv.bv_val ); (*ivals)[1] = NULL; break; @@ -628,6 +686,10 @@ string_assertion2keys_sub( int localsublens[3] = {SUBBEGIN, SUBMIDDLE, SUBEND};/* default values */ int maxsublen; char *comp_buf = NULL; + char *altinit = NULL; + char **altany = NULL; + char *altfinal = NULL; + int anysize = 0; slapi_pblock_get(pb, SLAPI_SYNTAX_SUBSTRLENS, &substrlens); @@ -650,13 +712,17 @@ string_assertion2keys_sub( * First figure out how many keys we will return. The answer is based * on the length of each assertion value. Since normalization may * reduce the length (such as when spaces are removed from space - * insensitive strings), we call value_normalize() before checking + * insensitive strings), we call value_normalize_ext() before checking * the length. */ nsubs = 0; if ( initial != NULL ) { - value_normalize( initial, syntax, 0 /* do not trim leading blanks */ ); - initiallen = strlen( initial ); + /* 3rd arg: 0 - DO NOT trim leading blanks */ + value_normalize_ext( initial, syntax, 0, &altinit ); + if (NULL == altinit) { + altinit = initial; + } + initiallen = strlen( altinit ); if ( initiallen > substrlens[INDEX_SUBSTRBEGIN] - 2 ) { nsubs += 1; /* for the initial begin string key */ /* the rest of the sub keys are "any" keys for this case */ @@ -664,19 +730,31 @@ string_assertion2keys_sub( nsubs += initiallen - substrlens[INDEX_SUBSTRMIDDLE] + 1; } } else { - initial = NULL; /* save some work later */ + altinit = NULL; /* save some work later */ } } for ( i = 0; any != NULL && any[i] != NULL; i++ ) { - value_normalize( any[i], syntax, 0 /* do not trim leading blanks */ ); - len = strlen( any[i] ); + anysize++; + } + altany = (char **)slapi_ch_calloc(anysize + 1, sizeof(char *)); + for ( i = 0; any != NULL && any[i] != NULL; i++ ) { + /* 3rd arg: 0 - DO NOT trim leading blanks */ + value_normalize_ext( any[i], syntax, 0, &altany[i] ); + if (NULL == altany[i]) { + altany[i] = any[i]; + } + len = strlen( altany[i] ); if ( len >= substrlens[INDEX_SUBSTRMIDDLE] ) { nsubs += len - substrlens[INDEX_SUBSTRMIDDLE] + 1; } } if ( final != NULL ) { - value_normalize( final, syntax, 0 /* do not trim leading blanks */ ); - finallen = strlen( final ); + /* 3rd arg: 0 - DO NOT trim leading blanks */ + value_normalize_ext( final, syntax, 0, &altfinal ); + if (NULL == altfinal) { + altfinal = final; + } + finallen = strlen( altfinal ); if ( finallen > substrlens[INDEX_SUBSTREND] - 2 ) { nsubs += 1; /* for the final end string key */ /* the rest of the sub keys are "any" keys for this case */ @@ -684,7 +762,7 @@ string_assertion2keys_sub( nsubs += finallen - substrlens[INDEX_SUBSTRMIDDLE] + 1; } } else { - final = NULL; /* save some work later */ + altfinal = NULL; /* save some work later */ } } if ( nsubs == 0 ) { /* no keys to return */ @@ -703,21 +781,31 @@ string_assertion2keys_sub( nsubs = 0; comp_buf = (char *)slapi_ch_malloc(maxsublen + 1); - if ( initial != NULL ) { - substring_comp_keys( ivals, &nsubs, initial, initiallen, '^', syntax, + if ( altinit != NULL ) { + substring_comp_keys( ivals, &nsubs, altinit, initiallen, '^', syntax, comp_buf, substrlens ); + if (altinit != initial) { + slapi_ch_free_string(&altinit); + } } - for ( i = 0; any != NULL && any[i] != NULL; i++ ) { - len = strlen( any[i] ); + for ( i = 0; altany != NULL && altany[i] != NULL; i++ ) { + len = strlen( altany[i] ); if ( len < substrlens[INDEX_SUBSTRMIDDLE] ) { continue; } - substring_comp_keys( ivals, &nsubs, any[i], len, 0, syntax, + substring_comp_keys( ivals, &nsubs, altany[i], len, 0, syntax, comp_buf, substrlens ); + if (altany[i] != any[i]) { + slapi_ch_free_string(&altany[i]); + } } - if ( final != NULL ) { - substring_comp_keys( ivals, &nsubs, final, finallen, '$', syntax, + slapi_ch_free((void **)&altany); + if ( altfinal != NULL ) { + substring_comp_keys( ivals, &nsubs, altfinal, finallen, '$', syntax, comp_buf, substrlens ); + if (altfinal != final) { + slapi_ch_free_string(&final); + } } (*ivals)[nsubs] = NULL; slapi_ch_free_string(&comp_buf); diff --git a/ldap/servers/plugins/syntaxes/syntax.h b/ldap/servers/plugins/syntaxes/syntax.h index ec3d5f03..64942ec7 100644 --- a/ldap/servers/plugins/syntaxes/syntax.h +++ b/ldap/servers/plugins/syntaxes/syntax.h @@ -113,6 +113,7 @@ int string_assertion2keys_ava(Slapi_PBlock *pb,Slapi_Value *val,Slapi_Value ***i int string_assertion2keys_sub(Slapi_PBlock *pb,char *initial,char **any,char *final,Slapi_Value ***ivals,int syntax); int value_cmp(struct berval *v1,struct berval *v2,int syntax,int normalize); void value_normalize(char *s,int syntax,int trim_leading_blanks); +void value_normalize_ext(char *s,int syntax,int trim_leading_blanks, char **alt); char *first_word( char *s ); char *next_word( char *s ); diff --git a/ldap/servers/plugins/syntaxes/validate.c b/ldap/servers/plugins/syntaxes/validate.c index aab6d9c2..989137b5 100644 --- a/ldap/servers/plugins/syntaxes/validate.c +++ b/ldap/servers/plugins/syntaxes/validate.c @@ -362,7 +362,6 @@ int distinguishedname_validate( { int rc = 0; /* Assume value is valid */ char *val_copy = NULL; - int strict = 0; const char *p = begin; const char *last = NULL; @@ -377,17 +376,6 @@ int distinguishedname_validate( * attributeValue = string / hexstring */ - /* Check if we should be performing strict validation. */ - strict = config_get_dn_validate_strict(); - if (!strict) { - /* Create a normalized copy of the value to use - * for validation. The original value will be - * stored in the backend unmodified. */ - val_copy = PL_strndup(begin, end - begin + 1); - p = val_copy; - end = slapi_dn_normalize_to_end(val_copy, NULL) - 1; - } - /* Validate one RDN at a time in a loop. */ while (p <= end) { if ((rc = rdn_validate(p, end, &last)) != 0) { diff --git a/ldap/servers/plugins/syntaxes/value.c b/ldap/servers/plugins/syntaxes/value.c index f127b6b6..9b048f30 100644 --- a/ldap/servers/plugins/syntaxes/value.c +++ b/ldap/servers/plugins/syntaxes/value.c @@ -86,23 +86,40 @@ utf8isspace_fast( char* s ) ** Also note that this deviates from rfc 4517 INTEGER syntax, but we must ** support legacy clients for the time being */ +/* + * alt stores the normalized value in case the normalized value is longer + * than the original value. It may happen the value is DN. + */ void -value_normalize( +value_normalize_ext( char *s, int syntax, - int trim_spaces + int trim_spaces, + char **alt ) { char *head = s; char *d; int prevspace, curspace; + if (NULL == alt) { + return; + } + *alt = NULL; + if ( ! (syntax & SYNTAX_CIS) && ! (syntax & SYNTAX_CES) ) { return; } if ( syntax & SYNTAX_DN ) { - (void) slapi_dn_normalize_case( s ); + char *dest = NULL; + size_t dlen = 0; + int rc = slapi_dn_normalize_case_ext(s, 0, &dest, &dlen); + if (rc > 0) { + *alt = dest; + } else if (rc == 0) { /* normalized in line; not terminated */ + *(dest + dlen) = '\0'; + } return; } @@ -203,6 +220,16 @@ value_normalize( } } +void +value_normalize( + char *s, + int syntax, + int trim_spaces +) +{ + /* deprecated */ +} + int value_cmp( struct berval *v1, @@ -220,6 +247,7 @@ value_cmp( int free_v1 = 0; int free_v2 = 0; int v1sign = 1, v2sign = 1; /* default to positive */ + char *alt = NULL; /* This code used to call malloc up to four times in the copying * of attributes to be normalized. Now we attempt to keep everything @@ -233,13 +261,35 @@ value_cmp( bvcopy1.bv_val = &little_buffer[buffer_offset]; bvcopy1.bv_val[v1->bv_len] = '\0'; v1 = &bvcopy1; - buffer_space-= v1->bv_len+1; - buffer_offset+= v1->bv_len+1; } else { v1 = ber_bvdup( v1 ); free_v1 = 1; } - value_normalize( v1->bv_val, syntax, 1 /* trim leading blanks */ ); + value_normalize_ext( v1->bv_val, syntax, + 1 /* trim leading blanks */, &alt ); + if (alt) { + if (free_v1) { + slapi_ch_free_string(&v1->bv_val); + v1->bv_val = alt; + v1->bv_len = strlen(alt); + } else { + if (strlen(alt) < buffer_space) { + v1->bv_len = strlen(alt); + /* Copying to little_buffer */ + SAFEMEMCPY(v1->bv_val, alt, v1->bv_len); + *(v1->bv_val + v1->bv_len) = '\0'; + } else { + free_v1 = 1; + v1 = (struct berval *)slapi_ch_malloc(sizeof(struct berval)); + v1->bv_val = alt; + v1->bv_len = strlen(alt); + } + } + } + if (!free_v1) { + buffer_space -= v1->bv_len + 1; + buffer_offset += v1->bv_len + 1; + } } if ( normalize & 2 ) { /* Do we have space in the little buffer ? */ @@ -249,13 +299,35 @@ value_cmp( bvcopy2.bv_val = &little_buffer[buffer_offset]; bvcopy2.bv_val[v2->bv_len] = '\0'; v2 = &bvcopy2; - buffer_space-= v2->bv_len+1; - buffer_offset+= v2->bv_len+1; } else { v2 = ber_bvdup( v2 ); free_v2 = 1; } - value_normalize( v2->bv_val, syntax, 1 /* trim leading blanks */ ); + value_normalize_ext( v2->bv_val, syntax, + 1 /* trim leading blanks */, &alt ); + if (alt) { + if (free_v2) { + slapi_ch_free_string(&v2->bv_val); + v2->bv_val = alt; + v2->bv_len = strlen(alt); + } else { + if (strlen(alt) < buffer_space) { + v2->bv_len = strlen(alt); + /* Copying to little_buffer */ + SAFEMEMCPY(v2->bv_val, alt, v2->bv_len); + *(v2->bv_val + v2->bv_len) = '\0'; + } else { + free_v2 = 1; + v2 = (struct berval *)slapi_ch_malloc(sizeof(struct berval)); + v2->bv_val = alt; + v2->bv_len = strlen(alt); + } + } + } + if (!free_v2) { + buffer_space -= v2->bv_len + 1; + buffer_offset += v2->bv_len + 1; + } } if (syntax & SYNTAX_INT) { |