]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/at.c
Merge remote branch 'origin/mdb.master'
[openldap] / servers / slapd / at.c
index 04c0d0168e3412564cf47ee0a0ae1ab6279feba1..e4d95541e23965c159c671f411107ebf13c38144 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2008 The OpenLDAP Foundation.
+ * Copyright 1998-2012 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -288,6 +288,10 @@ at_clean( AttributeType *a )
                ldap_memfree( a->sat_oidmacro );
                a->sat_oidmacro = NULL;
        }
+       if ( a->sat_soidmacro ) {
+               ldap_memfree( a->sat_soidmacro );
+               a->sat_soidmacro = NULL;
+       }
        if ( a->sat_subtypes ) {
                ldap_memfree( a->sat_subtypes );
                a->sat_subtypes = NULL;
@@ -590,6 +594,7 @@ at_add(
        int             code = LDAP_SUCCESS;
        char            *cname = NULL;
        char            *oidm = NULL;
+       char            *soidm = NULL;
 
        if ( !at->at_oid ) {
                *err = "";
@@ -622,7 +627,7 @@ at_add(
                        goto error_return;
                }
                if ( oid != at->at_syntax_oid ) {
-                       ldap_memfree( at->at_syntax_oid );
+                       soidm = at->at_syntax_oid;
                        at->at_syntax_oid = oid;
                }
        }
@@ -673,6 +678,7 @@ at_add(
        sat->sat_cname.bv_val = cname;
        sat->sat_cname.bv_len = strlen( cname );
        sat->sat_oidmacro = oidm;
+       sat->sat_soidmacro = soidm;
        ldap_pvt_thread_mutex_init(&sat->sat_ad_mutex);
 
        if ( at->at_sup_oid ) {
@@ -716,8 +722,22 @@ at_add(
         * its own superiorss
         */
        if ( sat->sat_sup ) {
-               sat->sat_syntax = sat->sat_sup->sat_syntax;
-               sat->sat_equality = sat->sat_sup->sat_equality;
+               Syntax *syn = syn_find(sat->sat_sup->sat_syntax->ssyn_oid);
+               if ( syn != sat->sat_sup->sat_syntax ) {
+                       sat->sat_syntax = ch_malloc( sizeof( Syntax ));
+                       *sat->sat_syntax = *sat->sat_sup->sat_syntax;
+               } else {
+                       sat->sat_syntax = sat->sat_sup->sat_syntax;
+               }
+               if ( sat->sat_sup->sat_equality ) {
+                       MatchingRule *mr = mr_find( sat->sat_sup->sat_equality->smr_oid );
+                       if ( mr != sat->sat_sup->sat_equality ) {
+                               sat->sat_equality = ch_malloc( sizeof( MatchingRule ));
+                               *sat->sat_equality = *sat->sat_sup->sat_equality;
+                       } else {
+                               sat->sat_equality = sat->sat_sup->sat_equality;
+                       }
+               }
                sat->sat_approx = sat->sat_sup->sat_approx;
                sat->sat_ordering = sat->sat_sup->sat_ordering;
                sat->sat_substr = sat->sat_sup->sat_substr;
@@ -919,6 +939,11 @@ error_return:;
                        at->at_oid = oidm;
                }
 
+               if ( soidm ) {
+                       SLAP_FREE( at->at_syntax_oid );
+                       at->at_syntax_oid = soidm;
+               }
+
        } else if ( rsat ) {
                *rsat = sat;
        }
@@ -979,9 +1004,12 @@ at_unparse( BerVarray *res, AttributeType *start, AttributeType *end, int sys )
        for ( at=start; at; at=LDAP_STAILQ_NEXT(at, sat_next)) {
                LDAPAttributeType lat, *latp;
                if ( sys && !(at->sat_flags & SLAP_AT_HARDCODE)) break;
-               if ( at->sat_oidmacro ) {
+               if ( at->sat_oidmacro || at->sat_soidmacro ) {
                        lat = at->sat_atype;
-                       lat.at_oid = at->sat_oidmacro;
+                       if ( at->sat_oidmacro )
+                               lat.at_oid = at->sat_oidmacro;
+                       if ( at->sat_soidmacro )
+                               lat.at_syntax_oid = at->sat_soidmacro;
                        latp = &lat;
                } else {
                        latp = &at->sat_atype;
@@ -1052,10 +1080,10 @@ register_at( const char *def, AttributeDescription **rad, int dupok )
                        freeit = 1;
 
                } else {
-                       ldap_attributetype_free( at );
                        Debug( LDAP_DEBUG_ANY,
                                "register_at: AttributeType \"%s\": %s, %s\n",
                                def, scherr2str(code), err );
+                       ldap_attributetype_free( at );
                        return code;
                }
        }