]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/add.c
cleanup bind
[openldap] / servers / slapd / add.c
index 952c6b4610d2ed8fe2774daaa754a8ab14c6e262..49f7b3440c7e21ebff7d4ff3dd86d4343a3424f2 100644 (file)
 
 #include "ldap_pvt.h"
 #include "slap.h"
+
+#ifdef LDAP_SLAPI
 #include "slapi.h"
+static Slapi_PBlock *initAddPlugin( Backend *be, Connection *conn, Operation *op,
+       struct berval *dn, Entry *e, int manageDSAit );
+static int doPreAddPluginFNs( Backend *be, Slapi_PBlock *pb );
+static void doPostAddPluginFNs( Backend *be, Slapi_PBlock *pb );
+#endif /* LDAP_SLAPI */
 
 int
 do_add( Connection *conn, Operation *op )
@@ -40,12 +47,11 @@ do_add( Connection *conn, Operation *op )
        Modifications   **modtail = &modlist;
        Modifications   tmp;
        const char *text;
-       LDAPRDN         *rdn = NULL;
-       int             a_cnt;
        int                     rc = LDAP_SUCCESS;
        int     manageDSAit;
-
-       Slapi_PBlock *pb = op->o_pb;
+#ifdef LDAP_SLAPI
+       Slapi_PBlock    *pb = NULL;
+#endif /* LDAP_SLAPI */
 
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_add: conn %d enter\n", conn->c_connid,0,0 );
@@ -107,7 +113,11 @@ do_add( Connection *conn, Operation *op )
                Modifications *mod;
                ber_tag_t rtag;
 
-               rtag = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_bvalues );
+#ifdef SLAP_NVALUES
+               tmp.sml_nvalues = NULL;
+#endif
+
+               rtag = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_values );
 
                if ( rtag == LBER_ERROR ) {
 #ifdef NEW_LOGGING
@@ -122,7 +132,7 @@ do_add( Connection *conn, Operation *op )
                        goto done;
                }
 
-               if ( tmp.sml_bvalues == NULL ) {
+               if ( tmp.sml_values == NULL ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG( OPERATION, INFO, 
                                "do_add: conn %d         no values for type %s\n",
@@ -135,13 +145,16 @@ do_add( Connection *conn, Operation *op )
                                NULL, "no values for attribute type", NULL, NULL );
                        goto done;
                }
+
                mod  = (Modifications *) ch_malloc( sizeof(Modifications) );
-               
                mod->sml_op = LDAP_MOD_ADD;
                mod->sml_next = NULL;
                mod->sml_desc = NULL;
                mod->sml_type = tmp.sml_type;
-               mod->sml_bvalues = tmp.sml_bvalues;
+               mod->sml_values = tmp.sml_values;
+#ifdef SLAP_NVALUES
+               mod->sml_nvalues = NULL;
+#endif
 
                *modtail = mod;
                modtail = &mod->sml_next;
@@ -193,131 +206,6 @@ do_add( Connection *conn, Operation *op )
                goto done;
        }
 
-       /*
-        * Get attribute type(s) and attribute value(s) of our rdn,
-        */
-       if ( ldap_bv2rdn( &e->e_name, &rdn, (char **)&text,
-               LDAP_DN_FORMAT_LDAP ) )
-       {
-               send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX,
-                       NULL, "unknown type(s) used in RDN",
-                       NULL, NULL );
-               goto done;
-       }
-
-       /* Check for RDN attrs in entry */
-       for ( a_cnt = 0; rdn[ 0 ][ a_cnt ]; a_cnt++ ) {
-               AttributeDescription    *desc = NULL;
-               Modifications           *mod;
-               MatchingRule            *mr;
-               int                     i;
-
-               rc = slap_bv2ad( &rdn[ 0 ][ a_cnt ]->la_attr, 
-                               &desc, &text );
-
-               if ( rc != LDAP_SUCCESS ) {
-                       send_ldap_result( conn, op, rc,
-                                       NULL, text, NULL, NULL );
-                       goto done;
-               }
-
-               for (mod = modlist; mod; mod = mod->sml_next) {
-                       AttributeDescription    *mod_desc = NULL;
-
-                       rc = slap_bv2ad( &mod->sml_type, 
-                                       &mod_desc, &text );
-                       if ( rc != LDAP_SUCCESS ) {
-                               send_ldap_result( conn, op, rc,
-                                               NULL, text, NULL, NULL );
-                               goto done;
-                       }
-
-                       if (mod_desc == desc) {
-                               break;
-                       }
-               }
-
-               if (mod == NULL) {
-#define BAILOUT
-#ifdef BAILOUT
-                       /* bail out */
-                       send_ldap_result( conn, op, 
-                                       rc = LDAP_NO_SUCH_ATTRIBUTE,
-                                       NULL,
-                                       "attribute in RDN not listed in entry", 
-                                       NULL, NULL );
-                       goto done;
-
-#else /* ! BAILOUT */
-                       struct berval   bv;
-
-                       /* add attribute type and value to modlist */
-                       mod  = (Modifications *) ch_malloc( sizeof(Modifications) );
-               
-                       mod->sml_op = LDAP_MOD_ADD;
-                       mod->sml_next = NULL;
-                       mod->sml_desc = NULL;
-
-                       ber_dupbv( &mod->sml_type,
-                                       &rdn[ 0 ][ a_cnt ]->la_attr );
-
-                       mod->sml_bvalues = NULL;
-                       ber_dupbv( &bv, &rdn[ 0 ][ a_cnt ]->la_value );
-                       ber_bvarray_add( &mod->sml_bvalues, &bv );
-
-                       *modtail = mod;
-                       modtail = &mod->sml_next;
-                       continue;
-#endif /* ! BAILOUT */
-               }
-
-               mr = desc->ad_type->sat_equality;
-               if (mr == NULL || !mr->smr_match ) {
-                       /* brrrr ... */
-                       continue;
-               }
-
-               for (i = 0; mod->sml_bvalues[ i ].bv_val; i++) {
-                       int             match = 0;
-                       
-                       rc = value_match(&match, desc, mr,
-                                       SLAP_MR_VALUE_SYNTAX_MATCH,
-                                       &mod->sml_bvalues[ i ],
-                                       &rdn[ 0 ][ a_cnt ]->la_value, &text);
-
-                       if ( rc != LDAP_SUCCESS ) {
-                               send_ldap_result( conn, op, rc,
-                                               NULL, text, NULL, NULL);
-                               goto done;
-                       }
-
-                       if (match == 0) {
-                               break;
-                       }
-               }
-
-               /* not found? */
-               if (mod->sml_bvalues[ i ].bv_val == NULL) {
-#ifdef BAILOUT
-                       /* bailout */
-                       send_ldap_result( conn, op, 
-                                       rc = LDAP_NO_SUCH_ATTRIBUTE,
-                                       NULL,
-                                       "value in RDN not listed in entry", 
-                                       NULL, NULL );
-                       goto done;
-
-#else /* ! BAILOUT */
-                       struct berval   bv;
-
-                       /* add attribute type and value to modlist */
-                       ber_dupbv( &bv, &rdn[ 0 ][ a_cnt ]->la_value );
-                       ber_bvarray_add( &mod->sml_bvalues, &bv );
-                       continue;
-#endif /* ! BAILOUT */
-               }
-       }
-
        manageDSAit = get_manageDSAit( op );
 
        /*
@@ -351,32 +239,9 @@ do_add( Connection *conn, Operation *op )
                goto done;
        }
 
-#if defined( LDAP_SLAPI )
-       slapi_x_backend_set_pb( pb, be );
-       slapi_x_connection_set_pb( pb, conn );
-       slapi_x_operation_set_pb( pb, op );
-       slapi_pblock_set( pb, SLAPI_ADD_ENTRY, (void *)e );
-       slapi_pblock_set( pb, SLAPI_ADD_TARGET, (void *)dn.bv_val );
-       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
-
-       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_ADD_FN, pb );
-       if ( rc != 0 ) {
-               /*
-                * A preoperation plugin failure will abort the
-                * entire operation.
-                */
-#ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, INFO, "do_add: add preoperation plugin failed\n",
-                               0, 0, 0);
-#else
-               Debug(LDAP_DEBUG_TRACE, "do_add: add preoperation plugin failed.\n",
-                               0, 0, 0);
-               if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0 )
-                       rc = LDAP_OTHER;
-               goto done;
-#endif
-       }
-#endif /* defined( LDAP_SLAPI ) */
+#ifdef LDAP_SLAPI
+       pb = initAddPlugin( be, conn, op, &dn, e, manageDSAit );
+#endif /* LDAP_SLAPI */
 
        /*
         * do the add if 1 && (2 || 3)
@@ -429,6 +294,18 @@ do_add( Connection *conn, Operation *op )
                                goto done;
                        }
 
+#ifdef LDAP_SLAPI
+                       /*
+                        * Call the preoperation plugin here, because the entry
+                        * will actually contain something.
+                        */
+                       rc = doPreAddPluginFNs( be, pb );
+                       if ( rc != LDAP_SUCCESS ) {
+                               /* plugin will have sent result */
+                               goto done;
+                       }
+#endif /* LDAP_SLAPI */
+
                        if ( (*be->be_add)( be, conn, op, e ) == 0 ) {
 #ifdef SLAPD_MULTIMASTER
                                if ( !repl_user )
@@ -442,18 +319,39 @@ do_add( Connection *conn, Operation *op )
 
 #ifndef SLAPD_MULTIMASTER
                } else {
-                       BerVarray defref = be->be_update_refs
+                       BerVarray defref;
+                       BerVarray ref;
+#ifdef LDAP_SLAPI
+                       /*
+                        * SLAPI_ADD_ENTRY will be empty, but this may be acceptable
+                        * on replicas (for now, it involves the minimum code intrusion).
+                        */
+                       rc = doPreAddPluginFNs( be, pb );
+                       if ( rc != LDAP_SUCCESS ) {
+                               /* plugin will have sent result */
+                               goto done;
+                       }
+#endif /* LDAP_SLAPI */
+
+                       defref = be->be_update_refs
                                ? be->be_update_refs : default_referral;
-                       BerVarray ref = referral_rewrite( defref,
+                       ref = referral_rewrite( defref,
                                NULL, &e->e_name, LDAP_SCOPE_DEFAULT );
 
                        send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL,
                                ref ? ref : defref, NULL );
 
                        if ( ref ) ber_bvarray_free( ref );
-#endif
+#endif /* SLAPD_MULTIMASTER */
                }
        } else {
+#ifdef LDAP_SLAPI
+           rc = doPreAddPluginFNs( be, pb );
+           if ( rc != LDAP_SUCCESS ) {
+               /* plugin will have sent result */
+               goto done;
+           }
+#endif
 #ifdef NEW_LOGGING
            LDAP_LOG( OPERATION, INFO, 
                       "do_add: conn %d  no backend support\n", conn->c_connid, 0, 0 );
@@ -464,21 +362,9 @@ do_add( Connection *conn, Operation *op )
                              NULL, "operation not supported within namingContext", NULL, NULL );
        }
 
-#if defined( LDAP_SLAPI )
-       /*
-        * Postoperation errors are silently ignored; the work has
-        * been done.
-        */
-       if ( doPluginFNs( be, SLAPI_PLUGIN_POST_ADD_FN, pb ) != 0) {
-#ifdef NEW_LOGGING
-               LDAP_LOG( OPERATION, INFO, "do_add: Add postoperation plugins failed\n",
-                               0, 0, 0);
-#else
-               Debug(LDAP_DEBUG_TRACE, "do_add: Add postoperation plugins failed.\n",
-                               0, 0, 0);
-#endif
-       }
-#endif /* defined( LDAP_SLAPI ) */
+#ifdef LDAP_SLAPI
+       doPostAddPluginFNs( be, pb );
+#endif /* LDAP_SLAPI */
 
 done:
        if( modlist != NULL ) {
@@ -527,7 +413,7 @@ slap_mods2entry(
                        for( i=0; attr->a_vals[i].bv_val; i++ ) {
                                /* count them */
                        }
-                       for( j=0; mods->sml_bvalues[j].bv_val; j++ ) {
+                       for( j=0; mods->sml_values[j].bv_val; j++ ) {
                                /* count them */
                        }
                        j++;    /* NULL */
@@ -537,12 +423,26 @@ slap_mods2entry(
 
                        /* should check for duplicates */
 
-                       AC_MEMCPY( &attr->a_vals[i], mods->sml_bvalues,
+                       AC_MEMCPY( &attr->a_vals[i], mods->sml_values,
                                sizeof( struct berval ) * j );
 
                        /* trim the mods array */
-                       ch_free( mods->sml_bvalues );
-                       mods->sml_bvalues = NULL;
+                       ch_free( mods->sml_values );
+                       mods->sml_values = NULL;
+
+#ifdef SLAP_NVALUES
+                       if( attr->a_nvals ) {
+                               attr->a_nvals = ch_realloc( attr->a_nvals,
+                                       sizeof( struct berval ) * (i+j) );
+
+                               AC_MEMCPY( &attr->a_nvals[i], mods->sml_nvalues,
+                                       sizeof( struct berval ) * j );
+
+                               /* trim the mods array */
+                               ch_free( mods->sml_nvalues );
+                               mods->sml_nvalues = NULL;
+                       }
+#endif
 
                        continue;
 #else
@@ -553,7 +453,7 @@ slap_mods2entry(
 #endif
                }
 
-               if( mods->sml_bvalues[1].bv_val != NULL ) {
+               if( mods->sml_values[1].bv_val != NULL ) {
                        /* check for duplicates */
                        int             i, j;
                        MatchingRule *mr = mods->sml_desc->ad_type->sat_equality;
@@ -597,8 +497,13 @@ slap_mods2entry(
 
                /* move values to attr structure */
                /*      should check for duplicates */
-               attr->a_vals = mods->sml_bvalues;
-               mods->sml_bvalues = NULL;
+               attr->a_vals = mods->sml_values;
+               mods->sml_values = NULL;
+
+#ifdef SLAP_NVALUES
+               attr->a_nvals = mods->sml_nvalues;
+               mods->sml_nvalues = NULL;
+#endif
 
                *tail = attr;
                tail = &attr->a_next;
@@ -606,3 +511,65 @@ slap_mods2entry(
 
        return LDAP_SUCCESS;
 }
+
+#ifdef LDAP_SLAPI
+static Slapi_PBlock *initAddPlugin( Backend *be, Connection *conn, Operation *op,
+       struct berval *dn, Entry *e, int manageDSAit )
+{
+       Slapi_PBlock *pb;
+
+       pb = op->o_pb;
+
+       slapi_x_backend_set_pb( pb, be );
+       slapi_x_connection_set_pb( pb, conn );
+       slapi_x_operation_set_pb( pb, op );
+
+       slapi_pblock_set( pb, SLAPI_ADD_TARGET, (void *)dn->bv_val );
+       slapi_pblock_set( pb, SLAPI_ADD_ENTRY, (void *)e );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+
+       return pb;
+}
+
+static int doPreAddPluginFNs( Backend *be, Slapi_PBlock *pb )
+{
+       int rc;
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_ADD_FN, pb );
+       if ( rc != 0 ) {
+               /*
+                * A preoperation plugin failure will abort the
+                * entire operation.
+                */
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_add: add preoperation plugin failed\n",
+                               0, 0, 0);
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_add: add preoperation plugin failed.\n",
+                               0, 0, 0);
+               if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0 )
+                       rc = LDAP_OTHER;
+#endif
+       } else {
+               rc = LDAP_SUCCESS;
+       }
+
+       return rc;
+}
+
+static void doPostAddPluginFNs( Backend *be, Slapi_PBlock *pb )
+{
+       int rc;
+
+       rc = doPluginFNs( be, SLAPI_PLUGIN_POST_ADD_FN, pb );
+       if ( rc != 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, INFO, "do_add: add postoperation plugin failed\n",
+                               0, 0, 0);
+#else
+               Debug(LDAP_DEBUG_TRACE, "do_add: add preoperation plugin failed.\n",
+                               0, 0, 0);
+#endif
+       }
+}
+#endif /* LDAP_SLAPI */