X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fentry.c;h=bf59a51f1e4e37efa99fea69ea589dcb5f768e13;hb=0445405299ebc97d0f11585031fb1abef031caf9;hp=115daa3eea959587b2609f511c39931cfb8814b8;hpb=693fb9424a17799192116e8ce007c4070798cdeb;p=openldap diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index 115daa3eea..bf59a51f1e 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -16,9 +16,9 @@ #include "slap.h" -static unsigned char *ebuf; /* buf returned by entry2str */ +static unsigned char *ebuf; /* buf returned by entry2str */ static unsigned char *ecur; /* pointer to end of currently used ebuf */ -static int emaxsize;/* max size of ebuf */ +static int emaxsize;/* max size of ebuf */ int entry_destroy(void) { @@ -58,16 +58,26 @@ str2entry( char *s ) * or newline. */ +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1, + "str2entry: \"%s\"\n", s ? s : "NULL" )); +#else Debug( LDAP_DEBUG_TRACE, "=> str2entry\n", s ? s : "NULL", 0, 0 ); +#endif /* initialize reader/writer lock */ e = (Entry *) ch_malloc( sizeof(Entry) ); if( e == NULL ) { - Debug( LDAP_DEBUG_TRACE, +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_ERR, + "str2entry: entry allocation failed.\n" )); +#else + Debug( LDAP_DEBUG_ANY, "<= str2entry NULL (entry allocation failed)\n", 0, 0, 0 ); +#endif return( NULL ); } @@ -89,8 +99,13 @@ str2entry( char *s ) } if ( ldif_parse_line( s, &type, &value.bv_val, &value.bv_len ) != 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1, + "str2entry: NULL (parse_line)\n" )); +#else Debug( LDAP_DEBUG_TRACE, "<= str2entry NULL (parse_line)\n", 0, 0, 0 ); +#endif continue; } @@ -98,10 +113,16 @@ str2entry( char *s ) free( type ); if ( e->e_dn != NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1, + "str2entry: entry %ld has multiple dns \"%s\" and \"%s\" (second ignored)\n", + e->e_id, e->e_dn, value.bv_val != NULL ? value.bv_val : "" )); +#else Debug( LDAP_DEBUG_ANY, "str2entry: entry %ld has multiple dns \"%s\" and \"%s\" (second ignored)\n", e->e_id, e->e_dn, value.bv_val != NULL ? value.bv_val : "" ); +#endif if( value.bv_val != NULL ) free( value.bv_val ); continue; } @@ -114,12 +135,79 @@ str2entry( char *s ) rc = slap_str2ad( type, &ad, &text ); if( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, - "<= str2entry NULL (str2ad=%s)\n", text, 0, 0 ); - entry_free( e ); - free( value.bv_val ); - free( type ); - return( NULL ); +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1, + "str2entry: str2ad(%s): %s\n", type, text )); +#else + Debug( slapMode & SLAP_TOOL_MODE + ? LDAP_DEBUG_ANY : LDAP_DEBUG_TRACE, + "<= str2entry: str2ad(%s): %s\n", type, text, 0 ); +#endif + if( slapMode & SLAP_TOOL_MODE ) { + entry_free( e ); + free( value.bv_val ); + free( type ); + return NULL; + } + + rc = slap_str2undef_ad( type, &ad, &text ); + + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1, + "str2entry: str2undef_ad(%s): %s\n", type, text )); +#else + Debug( LDAP_DEBUG_ANY, + "<= str2entry: str2undef_ad(%s): %s\n", + type, text, 0 ); +#endif + entry_free( e ); + free( value.bv_val ); + free( type ); + return NULL; + } + } + + if( slapMode & SLAP_TOOL_MODE ) { + slap_syntax_validate_func *validate = + ad->ad_type->sat_syntax->ssyn_validate; + + if( !validate ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_INFO, + "str2entry: no validator for syntax %s\n", + ad->ad_type->sat_syntax->ssyn_oid )); +#else + Debug( LDAP_DEBUG_ANY, + "str2entry: no validator for syntax %s\n", + ad->ad_type->sat_syntax->ssyn_oid, 0, 0 ); +#endif + entry_free( e ); + free( value.bv_val ); + free( type ); + return NULL; + } + + /* + * validate value per syntax + */ + rc = validate( ad->ad_type->sat_syntax, &value ); + + if( rc != 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_ERR, + "str2entry: invalid value for syntax %s\n", + ad->ad_type->sat_syntax->ssyn_oid )); +#else + Debug( LDAP_DEBUG_ANY, + "str2entry: invalid value for syntax %s\n", + ad->ad_type->sat_syntax->ssyn_oid, 0, 0 ); +#endif + entry_free( e ); + free( value.bv_val ); + free( type ); + return NULL; + } } rc = attr_merge( e, ad, vals ); @@ -127,8 +215,13 @@ str2entry( char *s ) ad_free( ad, 1 ); if( rc != 0 ) { - Debug( LDAP_DEBUG_TRACE, +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1, + "str2entry: NULL (attr_merge)\n" )); +#else + Debug( LDAP_DEBUG_ANY, "<= str2entry NULL (attr_merge)\n", 0, 0, 0 ); +#endif entry_free( e ); free( value.bv_val ); free( type ); @@ -141,8 +234,13 @@ str2entry( char *s ) /* check to make sure there was a dn: line */ if ( e->e_dn == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_INFO, + "str2entry: entry %ld has no dn.\n", e->e_id )); +#else Debug( LDAP_DEBUG_ANY, "str2entry: entry %ld has no dn\n", e->e_id, 0, 0 ); +#endif entry_free( e ); return( NULL ); } @@ -151,9 +249,13 @@ str2entry( char *s ) e->e_ndn = ch_strdup( e->e_dn ); (void) dn_normalize( e->e_ndn ); - Debug(LDAP_DEBUG_TRACE, "<= str2entry(%s) -> %ld (0x%lx)\n", - e->e_dn, e->e_id, (unsigned long)e ); - +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL2, + "str2entry(%s) -> 0x%lx\n", e->e_dn, (unsigned long)e )); +#else + Debug(LDAP_DEBUG_TRACE, "<= str2entry(%s) -> 0x%lx\n", + e->e_dn, (unsigned long) e, 0 ); +#endif return( e ); } @@ -218,8 +320,14 @@ entry2str( void entry_free( Entry *e ) { - Attribute *a, *next; + /* free an entry structure */ + assert( e != NULL ); + + /* e_private must be freed by the caller */ + assert( e->e_private == NULL ); + e->e_private = NULL; + /* free DNs */ if ( e->e_dn != NULL ) { free( e->e_dn ); e->e_dn = NULL; @@ -228,12 +336,11 @@ entry_free( Entry *e ) free( e->e_ndn ); e->e_ndn = NULL; } - for ( a = e->e_attrs; a != NULL; a = next ) { - next = a->a_next; - attr_free( a ); - } + + /* free attributes */ + attrs_free( e->e_attrs ); e->e_attrs = NULL; - e->e_private = NULL; + free( e ); } @@ -242,7 +349,7 @@ entry_free( Entry *e ) * * the Entry has three entry points (ways to find things): * - * by entry e.g., if you already have an entry from the cache + * by entry e.g., if you already have an entry from the cache * and want to delete it. (really by entry ptr) * by dn e.g., when looking for the base object of a search * by id e.g., for search candidates @@ -269,3 +376,238 @@ entry_id_cmp( Entry *e1, Entry *e2 ) return( e1->e_id < e2->e_id ? -1 : (e1->e_id > e2->e_id ? 1 : 0) ); } +#define SLAPD_SLEEPY 1 +#ifdef SLAPD_SLEEPY + +/* a DER encoded entry looks like: + * + * entry :== SEQUENCE { + * dn DistinguishedName, + * ndn NormalizedDistinguishedName, + * attrs SEQUENCE OF SEQUENCE { + * type AttributeType, + * values SET OF AttributeValue + * } + * } + * + * Encoding/Decoding of DER should be much faster than LDIF + */ + +int entry_decode( struct berval *bv, Entry **entry ) +{ + int rc; + BerElement *ber; + Entry *e; + ber_tag_t tag; + ber_len_t len; + char *last; + + ber = ber_init( bv ); + if( ber == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_ERR, + "entry_decode: ber_init failed\n" )); +#else + Debug( LDAP_DEBUG_ANY, + "<= entry_decode: ber_init failed\n", + 0, 0, 0 ); +#endif + return LDAP_LOCAL_ERROR; + } + + /* initialize reader/writer lock */ + e = (Entry *) ch_malloc( sizeof(Entry) ); + + if( e == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_ERR, + "entry_decode: entry allocation failed.\n" )); +#else + Debug( LDAP_DEBUG_ANY, + "<= entry_decode: entry allocation failed\n", + 0, 0, 0 ); +#endif + return LDAP_LOCAL_ERROR; + } + + /* initialize entry */ + e->e_id = NOID; + e->e_dn = NULL; + e->e_ndn = NULL; + e->e_attrs = NULL; + e->e_private = NULL; + + tag = ber_scanf( ber, "{aa" /*"}"*/, &e->e_dn, &e->e_ndn ); + if( tag == LBER_ERROR ) { + free( e ); + return LDAP_PROTOCOL_ERROR; + } + +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL2, + "entry_decode: \"%s\"\n", e->e_dn )); +#else + Debug( LDAP_DEBUG_TRACE, + "entry_decode: \"%s\"\n", + e->e_dn, 0, 0 ); +#endif + /* get the attrs */ + for ( tag = ber_first_element( ber, &len, &last ); + tag != LBER_DEFAULT; + tag = ber_next_element( ber, &len, last ) ) + { + struct berval *type; + struct berval **vals; + AttributeDescription *ad; + const char *text; + + tag = ber_scanf( ber, "{O{V}}", &type, &vals ); + + if ( tag == LBER_ERROR ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_ERR, + "entry_decode: decoding error (%s)\n", e->e_dn )); +#else + Debug( LDAP_DEBUG_ANY, "entry_decode: decoding error\n", 0, 0, 0 ); +#endif + entry_free( e ); + return LDAP_PROTOCOL_ERROR; + } + + if ( vals == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_ERR, + "entry_decode: no values for type %s\n", type )); +#else + Debug( LDAP_DEBUG_ANY, "entry_decode: no values for type %s\n", + type, 0, 0 ); +#endif + ber_bvfree( type ); + entry_free( e ); + return LDAP_PROTOCOL_ERROR; + } + + ad = NULL; + rc = slap_bv2ad( type, &ad, &text ); + + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_INFO, + "entry_decode: str2ad(%s): %s\n", type, text )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= entry_decode: str2ad(%s): %s\n", type, text, 0 ); +#endif + rc = slap_bv2undef_ad( type, &ad, &text ); + + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_INFO, + "entry_decode: str2undef_ad(%s): %s\n", type, text)); +#else + Debug( LDAP_DEBUG_ANY, + "<= entry_decode: str2undef_ad(%s): %s\n", + type, text, 0 ); +#endif + ber_bvfree( type ); + ber_bvecfree( vals ); + entry_free( e ); + return rc; + } + } + + rc = attr_merge( e, ad, vals ); + ad_free( ad, 1 ); + + if( rc != 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_INFO, + "entry_decode: attr_merge failed\n")); +#else + Debug( LDAP_DEBUG_ANY, + "<= entry_decode: attr_merge failed\n", 0, 0, 0 ); +#endif + ber_bvfree( type ); + ber_bvecfree( vals ); + entry_free( e ); + return LDAP_LOCAL_ERROR; + } + + free( type ); + ber_bvecfree( vals ); + } + + rc = ber_scanf( ber, /*"{"*/ "}" ); + if( rc < 0 ) { + entry_free( e ); + return LDAP_PROTOCOL_ERROR; + } + +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1, + "entry_decode: %s\n", e->e_dn )); +#else + Debug(LDAP_DEBUG_TRACE, "<= entry_decode(%s)\n", + e->e_dn, 0, 0 ); +#endif + + *entry = e; + return LDAP_SUCCESS; +} + +int entry_encode( + Entry *e, + struct berval **bv ) +{ + int rc = -1; + Attribute *a; + BerElement *ber; + +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_DETAIL1, + "entry_encode: id: 0x%08lx \"%s\"\n", + e->e_id, e->e_dn )); +#else + Debug( LDAP_DEBUG_TRACE, "=> entry_encode(0x%08lx): %s\n", + e->e_id, e->e_dn, 0 ); +#endif + ber = ber_alloc_t( LBER_USE_DER ); + if( ber == NULL ) { + goto done; + } + + rc = ber_printf( ber, "{ss{" /*"}}"*/, e->e_dn, e->e_ndn ); + if( rc < 0 ) { + goto done; + } + + for ( a = e->e_attrs; a != NULL; a = a->a_next ) { + rc = ber_printf( ber, "{O{V}}", + a->a_desc->ad_cname, + a->a_vals ); + if( rc < 0 ) { + goto done; + } + } + + rc = ber_printf( ber, /*"{{"*/ "}}" ); + if( rc < 0 ) { + goto done; + } + + rc = ber_flatten( ber, bv ); + +done: + ber_free( ber, 1 ); + if( rc ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "operation", LDAP_LEVEL_INFO, + "entry_encode: id=0x%08lx failed (%d)\n", e->e_id, rc )); +#else + Debug( LDAP_DEBUG_ANY, "=> entry_encode(0x%08lx): failed (%d)\n", + e->e_id, rc, 0 ); +#endif + } + return rc; +} +#endif