LDAP_CALL ldap_dn2ufn( const char *dn ) { char *p, *ufn, *r; size_t plen; int state; LDAPDebug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 ); if ( dn == NULL ) { dn = ""; } if ( ldap_is_dns_dn( dn ) || ( p = strchr( dn, '=' )) == NULL ) return( nsldapi_strdup( (char *)dn )); ufn = nsldapi_strdup( ++p ); #define INQUOTE 1 #define OUTQUOTE 2 state = OUTQUOTE; for ( p = ufn, r = ufn; *p; p += plen ) { plen = 1; switch ( *p ) { case '\\': if ( *++p == '\0' ) plen=0; else { *r++ = '\\'; r += (plen = LDAP_UTF8COPY(r,p)); } break; case '"': if ( state == INQUOTE ) state = OUTQUOTE; else state = INQUOTE; *r++ = *p; break; case ';': case ',': if ( state == OUTQUOTE ) *r++ = ','; else *r++ = *p; break; case '=': if ( state == INQUOTE ) *r++ = *p; else { char *rsave = r; LDAP_UTF8DEC(r); *rsave = '\0'; while ( !ldap_utf8isspace( r ) && *r != ';' && *r != ',' && r > ufn ) LDAP_UTF8DEC(r); LDAP_UTF8INC(r); if ( strcasecmp( r, "c" ) && strcasecmp( r, "o" ) && strcasecmp( r, "ou" ) && strcasecmp( r, "st" ) && strcasecmp( r, "l" ) && strcasecmp( r, "dc" ) && strcasecmp( r, "uid" ) && strcasecmp( r, "cn" ) ) { r = rsave; *r++ = '='; } } break; default: r += (plen = LDAP_UTF8COPY(r,p)); break; } } *r = '\0'; return( ufn ); }
static int ss_filter_match (or_filter_t* or, struct berval** vals) /* returns: 0 filter matched * -1 filter did not match * >0 an LDAP error code */ { auto int rc = -1; /* no match */ auto indexer_t* ix = or->or_indexer; if (vals != NULL) for (; *vals; ++vals) { auto struct berval v; auto struct berval** k = or->or_match_keys; if (k == NULL || *k == NULL) { rc = 0; /* present */ break; } v.bv_len = (*vals)->bv_len; v.bv_val = (*vals)->bv_val; if ((*k)->bv_len > 0 && ss_match (&v, *k, ix) != 0) { break; /* initial failed */ } rc = 0; /* so far, so good */ while (*++k) { if ((*k)->bv_len <= 0) { rc = 0; } else if (k[1]) { /* middle */ do { rc = ss_match (&v, *k, ix); } while (rc > 0); if (rc < 0) { break; } } else { /* final */ auto size_t attempts = MAX_CHAR_COMBINING; auto char* limit = v.bv_val; auto struct berval** vkeys; auto struct berval* vals[2]; auto struct berval key; rc = -1; vals[0] = &v; vals[1] = NULL; key.bv_val = (*k)->bv_val; key.bv_len = (*k)->bv_len - 1; v.bv_val = (*vals)->bv_val + (*vals)->bv_len; while(1) { v.bv_len = (*vals)->bv_len - (v.bv_val - (*vals)->bv_val); vkeys = ix->ix_index (ix, vals, NULL); if (vkeys && vkeys[0]) { auto const struct berval* vkey = vkeys[0]; if (vkey->bv_len > key.bv_len) { if (--attempts <= 0) { break; } /* else Try looking at another character; it may combine, and produce a shorter key. */ } else if (SLAPI_BERVAL_EQ (vkey, &key)) { rc = 0; break; } } if (v.bv_val <= limit) break; LDAP_UTF8DEC (v.bv_val); } break; } } if (rc != -1) break; } return rc; }