/* Copyright (c) 2003 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants * permission under its copyrights to use, copy, modify, and distribute this * Software with or without fee, provided that the above copyright notice and * all paragraphs of this notice appear in all copies, and that the name of IBM * not be used in connection with the marketing of any product incorporating * the Software or modifications thereof, without specific, written prior * permission. * * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "portable.h" #include #include #include #include #include "slap.h" #include "../back-ldap/back-ldap.h" #include "back-meta.h" #include "ldap_pvt.h" #undef ldap_debug /* silence a warning in ldap-int.h */ #include "ldap_log.h" #include "../../../libraries/libldap/ldap-int.h" #include "slap.h" #include "back-meta.h" #ifdef LDAP_CACHING static char* invert_string(char* string); static struct berval* merge_init_final(struct berval*, struct berval*, struct berval*); static int strings_containment(struct berval* stored, struct berval* incoming); /* find and remove string2 from string1 * from start if position = 1, * from end if position = 3, * from anywhere if position = 2 */ int find_and_remove(struct berval* ber1, struct berval* ber2, int position) { char* temp; int len; int ret=0; char* arg1, *arg2; char* string1=ber1->bv_val; char* string2=ber2->bv_val; if (string2 == NULL) return 1; if (string1 == NULL) return 0; if (position == 3) { arg1 = invert_string(string1); arg2 = invert_string(string2); } else { arg1 = string1; arg2 = string2; } temp = strstr(arg1, arg2); len = strlen(arg2); if (!temp) return 0; switch (position) { case 1: if (temp == arg1) { string1 += len; ret = 1; } else { ret = 0; } break; case 2: string1 = temp+len; ret = 1; break; case 3: temp = strstr(arg1, arg2); len = strlen(arg2); if (temp == arg1) { /*arg1 += len;*/ string1 = invert_string(arg1+len); free(arg1); free(arg2); ret = 1; } else { free(arg1); free(arg2); ret = 0; } break; } temp = (char*) malloc( strlen( string1 ) + 1 ); strcpy( temp, string1 ); free( ber1->bv_val ); ber1->bv_val = temp; return ret; } char* invert_string( char* string ) { int len = strlen(string); int i; char* inverted = (char*)(malloc(len+1)); for (i=0; ibv_val) count++; if (final->bv_val) count++; merged = (struct berval*)(malloc((count+1)*sizeof(struct berval))); temp = merged; if (init->bv_val) { ber_dupbv(temp, init); temp++; } for (i=0; ibv_val){ ber_dupbv(temp, final); temp++; } temp->bv_val = NULL; temp->bv_len = 0; return merged; } int strings_containment(struct berval* stored, struct berval* incoming) { struct berval* element; int k=0; int j, rc = 0; for ( element=stored; element->bv_val != NULL; element++ ) { for (j = k; incoming[j].bv_val != NULL; j++) { if (find_and_remove(&(incoming[j]), element, 2)) { k = j; rc = 1; break; } rc = 0; } if ( rc ) { continue; } else { return 0; } } return 1; } int substr_containment_substr(Filter* stored, Filter* incoming) { int i; int k=0; int rc; int any_count = 0; struct berval* init_incoming = (struct berval*)(malloc(sizeof(struct berval))); struct berval* final_incoming = (struct berval*)(malloc(sizeof(struct berval))); struct berval* any_incoming = NULL; struct berval* remaining_incoming; struct berval* any_element; if ((!(incoming->f_sub_initial.bv_val) && (stored->f_sub_initial.bv_val)) || (!(incoming->f_sub_final.bv_val) && (stored->f_sub_final.bv_val))) return 0; ber_dupbv(init_incoming, &(incoming->f_sub_initial)); ber_dupbv(final_incoming, &(incoming->f_sub_final)); if (incoming->f_sub_any) { for ( any_count=0; incoming->f_sub_any[any_count].bv_val != NULL; any_count++ ) ; any_incoming = (struct berval*)malloc((any_count+1) * sizeof(struct berval)); for (i=0; if_sub_any[i])); } any_incoming[any_count].bv_val = NULL; any_incoming[any_count].bv_len = 0; } if (find_and_remove(init_incoming, &(stored->f_sub_initial), 1) && find_and_remove(final_incoming, &(stored->f_sub_final), 3)) { if (stored->f_sub_any == NULL) { rc = 1; goto final; } remaining_incoming = merge_init_final(init_incoming, any_incoming, final_incoming); rc = strings_containment(stored->f_sub_any, remaining_incoming); goto final; } rc = 0; final: /* ber_bvfree(init_incoming); ber_bvfree(final_incoming); if (any_incoming) { for (i=0; i < any_count; i++) free(any_incoming[i].bv_val); free(any_incoming); } */ return rc; } int substr_containment_equality(Filter* stored, Filter* incoming) { struct berval* incoming_val = (struct berval*)(malloc(2*sizeof(struct berval))); int rc; ber_dupbv(incoming_val, &(incoming->f_av_value)); incoming_val[1].bv_val = NULL; incoming_val[1].bv_len = 0; if (find_and_remove(incoming_val, &(stored->f_sub_initial), 1) && find_and_remove(incoming_val, &(stored->f_sub_final), 3)) { if (stored->f_sub_any == NULL){ rc = 1; goto final; } rc = strings_containment(stored->f_sub_any, incoming_val); goto final; } rc=0; final: /* if(incoming_val[0].bv_val) free(incoming_val[0].bv_val); free(incoming_val); */ return rc; } #endif