]> git.sur5r.net Git - openldap/commitdiff
fix ITS#3499
authorPierangelo Masarati <ando@openldap.org>
Thu, 20 Jan 2005 19:28:01 +0000 (19:28 +0000)
committerPierangelo Masarati <ando@openldap.org>
Thu, 20 Jan 2005 19:28:01 +0000 (19:28 +0000)
servers/slapd/back-meta/add.c
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/map.c
servers/slapd/back-meta/modify.c

index 6f352696e030968441c5a5e46ccc721f7bc75bff..571b57b75f2ed4cccf7b3c87a1c92871d5cbb390 100644 (file)
@@ -54,13 +54,14 @@ meta_back_add( Operation *op, SlapReply *rs )
                        &op->o_req_ndn, &candidate );
        if ( !lc ) {
                send_ldap_result( op, rs );
+               return rs->sr_err;
        }
 
        if ( !meta_back_dobind( lc, op )
                        || !meta_back_is_valid( lc, candidate ) ) {
                rs->sr_err = LDAP_UNAVAILABLE;
                send_ldap_result( op, rs );
-               return -1;
+               return rs->sr_err;
        }
 
        /*
@@ -73,7 +74,7 @@ meta_back_add( Operation *op, SlapReply *rs )
 
        if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
                send_ldap_result( op, rs );
-               return -1;
+               return rs->sr_err;
        }
 
        /* Count number of attributes in entry */
@@ -84,16 +85,24 @@ meta_back_add( Operation *op, SlapReply *rs )
 
        isupdate = be_shadow_update( op );
        for ( i = 0, a = op->ora_e->e_attrs; a; a = a->a_next ) {
-               int j;
+               int     j, is_oc = 0;
 
                if ( !isupdate && a->a_desc->ad_type->sat_no_user_mod  ) {
                        continue;
                }
 
-               ldap_back_map( &li->targets[ candidate ]->mt_rwmap.rwm_at,
-                               &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
-               if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
-                       continue;
+               if ( a->a_desc == slap_schema.si_ad_objectClass 
+                               || a->a_desc == slap_schema.si_ad_structuralObjectClass )
+               {
+                       is_oc = 1;
+                       mapped = a->a_desc->ad_cname;
+
+               } else {
+                       ldap_back_map( &li->targets[ candidate ]->mt_rwmap.rwm_at,
+                                       &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
+                       if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
+                               continue;
+                       }
                }
 
                attrs[ i ] = ch_malloc( sizeof( LDAPMod ) );
@@ -103,28 +112,60 @@ meta_back_add( Operation *op, SlapReply *rs )
                attrs[ i ]->mod_op = LDAP_MOD_BVALUES;
                attrs[ i ]->mod_type = mapped.bv_val;
 
-               /*
-                * FIXME: dn-valued attrs should be rewritten
-                * to allow their use in ACLs at the back-ldap
-                * level.
-                */
-               if ( a->a_desc->ad_type->sat_syntax ==
+               if ( is_oc ) {
+                       for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ )
+                               ;
+
+                       attrs[ i ]->mod_bvalues =
+                               (struct berval **)ch_malloc( ( j + 1 ) *
+                               sizeof( struct berval * ) );
+
+                       for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); ) {
+                               struct ldapmapping      *mapping;
+
+                               ldap_back_mapping( &li->targets[ candidate ]->mt_rwmap.rwm_oc,
+                                               &a->a_vals[ j ], &mapping, BACKLDAP_MAP );
+
+                               if ( mapping == NULL ) {
+                                       if ( li->targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
+                                               continue;
+                                       }
+                                       attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ];
+
+                               } else {
+                                       attrs[ i ]->mod_bvalues[ j ] = &mapping->dst;
+                               }
+                               j++;
+                       }
+                       attrs[ i ]->mod_bvalues[ j ] = NULL;
+
+               } else {
+                       /*
+                        * FIXME: dn-valued attrs should be rewritten
+                        * to allow their use in ACLs at the back-ldap
+                        * level.
+                        */
+                       if ( a->a_desc->ad_type->sat_syntax ==
                                slap_schema.si_syn_distinguishedName )
-               {
-                       (void)ldap_dnattr_rewrite( &dc, a->a_vals );
-               }
-
-               for ( j = 0; a->a_vals[ j ].bv_val; j++ );
-               attrs[ i ]->mod_vals.modv_bvals = ch_malloc((j+1)*sizeof(struct berval *));
-               for ( j = 0; a->a_vals[ j ].bv_val; j++ ) {
-                       attrs[ i ]->mod_vals.modv_bvals[ j ] = &a->a_vals[ j ];
+                       {
+                               (void)ldap_dnattr_rewrite( &dc, a->a_vals );
+                               if ( a->a_vals == NULL ) {
+                                       continue;
+                               }
+                       }
+
+                       for ( j = 0; a->a_vals[ j ].bv_val; j++ );
+                       attrs[ i ]->mod_vals.modv_bvals = ch_malloc((j+1)*sizeof(struct berval *));
+                       for ( j = 0; a->a_vals[ j ].bv_val; j++ ) {
+                               attrs[ i ]->mod_vals.modv_bvals[ j ] = &a->a_vals[ j ];
+                       }
+                       attrs[ i ]->mod_vals.modv_bvals[ j ] = NULL;
                }
-               attrs[ i ]->mod_vals.modv_bvals[ j ] = NULL;
                i++;
        }
        attrs[ i ] = NULL;
 
-       (void)ldap_add_ext_s( lc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
+       rs->sr_err = ldap_add_ext_s( lc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
                              attrs, NULL, NULL );
        for ( --i; i >= 0; --i ) {
                free( attrs[ i ]->mod_vals.modv_bvals );
index cd82865fb9e23a52f94f5bde3d0ca9151545403a..50dd8e584b69db06a09d7a17558d74539a4e9030 100644 (file)
@@ -106,6 +106,8 @@ int mapping_cmp (const void *, const void *);
 int mapping_dup (void *, void *);
 
 void ldap_back_map_init ( struct ldapmap *lm, struct ldapmapping ** );
+int ldap_back_mapping ( struct ldapmap *map, struct berval *s,
+       struct ldapmapping **m, int remap );
 void ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *m,
        int remap );
 #define BACKLDAP_MAP   0
index a607369b7edbd2c5db1ad829f2dcb95fb3285e91..5021fc5c59f3da827b5b38e9e980811d4d4695d3 100644 (file)
@@ -109,12 +109,14 @@ ldap_back_map_init ( struct ldapmap *lm, struct ldapmapping **m )
        *m = mapping;
 }
 
-void
-ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
+int
+ldap_back_mapping ( struct ldapmap *map, struct berval *s, struct ldapmapping **m,
        int remap )
 {
        Avlnode *tree;
-       struct ldapmapping *mapping, fmapping;
+       struct ldapmapping fmapping;
+
+       assert( m );
 
        if ( remap == BACKLDAP_REMAP ) {
                tree = map->remap;
@@ -122,9 +124,23 @@ ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
                tree = map->map;
        }
 
-       BER_BVZERO( bv );
        fmapping.src = *s;
-       mapping = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping, mapping_cmp );
+       *m = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping, mapping_cmp );
+       if ( *m == NULL ) {
+               return map->drop_missing;
+       }
+
+       return 0;
+}
+
+void
+ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
+       int remap )
+{
+       struct ldapmapping *mapping;
+
+       BER_BVZERO( bv );
+       ( void )ldap_back_mapping( map, s, &mapping, remap );
        if ( mapping != NULL ) {
                if ( !BER_BVISNULL( &mapping->dst ) ) {
                        *bv = mapping->dst;
@@ -135,8 +151,6 @@ ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
        if ( !map->drop_missing ) {
                *bv = *s;
        }
-
-       return;
 }
 
 int
index 77e92da1455e791ed06a2c48168e3c4c19a2dc12..40709354a4dafc2f5c3de380e12d6132f4a6c29e 100644 (file)
@@ -134,15 +134,22 @@ meta_back_modify( Operation *op, SlapReply *rs )
                                mods[ i ].mod_bvalues =
                                        (struct berval **)ch_malloc( ( j + 1 ) *
                                        sizeof( struct berval * ) );
-                               for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); j++ ) {
-                                       ldap_back_map( &li->targets[ candidate ]->mt_rwmap.rwm_oc,
-                                                       &ml->sml_values[ j ],
-                                                       &mapped, BACKLDAP_MAP );
-                                       if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) )
-                                       {
-                                               continue;
+                               for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); ) {
+                                       struct ldapmapping      *mapping;
+
+                                       ldap_back_mapping( &li->targets[ candidate ]->mt_rwmap.rwm_oc,
+                                                       &ml->sml_values[ j ], &mapping, BACKLDAP_MAP );
+
+                                       if ( mapping == NULL ) {
+                                               if ( li->targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
+                                                       continue;
+                                               }
+                                               mods[ i ].mod_bvalues[ j ] = &ml->sml_values[ j ];
+
+                                       } else {
+                                               mods[ i ].mod_bvalues[ j ] = &mapping->dst;
                                        }
-                                       mods[ i ].mod_bvalues[ j ] = &mapped;
+                                       j++;
                                }
                                mods[ i ].mod_bvalues[ j ] = NULL;