]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/slapi/slapi_utils.c
Don't return frontend as SLAPI_BACKEND, return actual backend instead
[openldap] / servers / slapd / slapi / slapi_utils.c
index 95c9bbda6ad432e132b7c789de9bfcbe979ab0aa..f2ac0cf24b3db170e46e1939af21af88caf0610c 100644 (file)
@@ -148,6 +148,27 @@ slapi_x_entry_get_id( Slapi_Entry *e )
        return e->e_id;
 }
 
+static int
+slapi_int_dn_pretty( struct berval *in, struct berval *out )
+{
+       Syntax          *syntax = slap_schema.si_syn_distinguishedName;
+
+       assert( syntax != NULL );
+
+       return (syntax->ssyn_pretty)( syntax, in, out, NULL );
+}
+
+static int
+slapi_int_dn_normalize( struct berval *in, struct berval *out )
+{
+       MatchingRule    *mr = slap_schema.si_mr_distinguishedNameMatch;
+       Syntax          *syntax = slap_schema.si_syn_distinguishedName;
+
+       assert( mr != NULL );
+
+       return (mr->smr_normalize)( 0, syntax, mr, in, out, NULL );
+}
+
 void 
 slapi_entry_set_dn(
        Slapi_Entry     *e, 
@@ -158,7 +179,8 @@ slapi_entry_set_dn(
        dn.bv_val = ldn;
        dn.bv_len = strlen( ldn );
 
-       dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname, NULL );
+       slapi_int_dn_pretty( &dn, &e->e_name );
+       slapi_int_dn_normalize( &dn, &e->e_nname );
 }
 
 Slapi_Entry *
@@ -770,7 +792,7 @@ slapi_dn_normalize( char *dn )
        bdn.bv_val = dn;
        bdn.bv_len = strlen( dn );
 
-       if ( dnPretty( NULL, &bdn, &pdn, NULL ) != LDAP_SUCCESS ) {
+       if ( slapi_int_dn_pretty( &bdn, &pdn ) != LDAP_SUCCESS ) {
                return NULL;
        }
 
@@ -788,7 +810,7 @@ slapi_dn_normalize_case( char *dn )
        bdn.bv_val = dn;
        bdn.bv_len = strlen( dn );
 
-       if ( dnNormalize( 0, NULL, NULL, &bdn, &ndn, NULL ) != LDAP_SUCCESS ) {
+       if ( slapi_int_dn_normalize( &bdn, &ndn ) != LDAP_SUCCESS ) {
                return NULL;
        }
 
@@ -914,45 +936,69 @@ slapi_dn_parent( const char *_dn )
        return slapi_ch_strdup( parentDN.bv_val );
 }
 
+int slapi_dn_isbesuffix( Slapi_PBlock *pb, char *ldn )
+{
+       struct berval   ndn;
+       Backend         *be;
+
+       if ( slapi_is_rootdse( ldn ) ) {
+               return 0;
+       }
+
+       /* according to spec should already be normalized */
+       ndn.bv_len = strlen( ldn );
+       ndn.bv_val = ldn;
+
+       be = select_backend( &pb->pb_op->o_req_ndn, 0, 0 );
+       if ( be == NULL ) {
+               return 0;
+       }
+
+       return be_issuffix( be, &ndn );
+}
+
 /*
  * Returns DN of the parent entry; or NULL if the DN is
  * an empty string, if the DN has no parent, or if the
  * DN is the suffix of the backend database
  */
-char *slapi_dn_beparent( Slapi_PBlock *pb, const char *_dn )
+char *slapi_dn_beparent( Slapi_PBlock *pb, const char *ldn )
 {
        Backend         *be;
        struct berval   dn, prettyDN;
        struct berval   normalizedDN, parentDN;
+       char            *parent = NULL;
 
-       if ( pb == NULL || pb->pb_op == NULL )
+       if ( pb == NULL ) {
                return NULL;
+       }
 
-       be = pb->pb_op->o_bd;
-
-       dn.bv_val = (char *)_dn;
-       dn.bv_len = strlen( _dn );
+       PBLOCK_ASSERT_OP( pb, 0 );
 
-       if ( dnPrettyNormal( NULL, &dn, &prettyDN, &normalizedDN, NULL ) != LDAP_SUCCESS ) {
+       if ( slapi_is_rootdse( ldn ) ) {
                return NULL;
        }
 
-       if ( be != NULL && be_issuffix( be, &normalizedDN ) ) {
-               slapi_ch_free( (void **)&prettyDN.bv_val );
-               slapi_ch_free( (void **)&normalizedDN.bv_val );
+       dn.bv_val = (char *)ldn;
+       dn.bv_len = strlen( ldn );
+
+       if ( dnPrettyNormal( NULL, &dn, &prettyDN, &normalizedDN, NULL ) != LDAP_SUCCESS ) {
                return NULL;
        }
 
-       dnParent( &prettyDN, &parentDN );
+       be = select_backend( &pb->pb_op->o_req_ndn, 0, 0 );
 
-       slapi_ch_free( (void **)&prettyDN.bv_val );
-       slapi_ch_free( (void **)&normalizedDN.bv_val );
+       if ( be == NULL || be_issuffix( be, &normalizedDN ) == 0 ) {
+               dnParent( &prettyDN, &parentDN );
 
-       if ( parentDN.bv_len == 0 ) {
-               return NULL;
+               if ( parentDN.bv_len != 0 )
+                       parent = slapi_ch_strdup( parentDN.bv_val );
        }
 
-       return slapi_ch_strdup( parentDN.bv_val );
+       slapi_ch_free_string( &prettyDN.bv_val );
+       slapi_ch_free_string( &normalizedDN.bv_val );
+
+       return parent;
 }
 
 char *
@@ -2635,7 +2681,7 @@ int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char
        if ( pb == NULL || pb->pb_op == NULL )
                return LDAP_PARAM_ERROR;
 
-       ml = slapi_int_ldapmods2modifications( mods, NULL );
+       ml = slapi_int_ldapmods2modifications( mods );
        if ( ml == NULL ) {
                return LDAP_OTHER;
        }
@@ -2644,8 +2690,7 @@ int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char
                rc = acl_check_modlist( pb->pb_op, e, ml ) ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
        }
 
-       /* Careful when freeing the modlist because it has pointers into the mods array. */
-       slapi_int_mods_free( ml );
+       slap_mods_free( ml, 1 );
 
        return rc;
 }
@@ -2658,10 +2703,7 @@ int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char
  * 
  * This function must also be called before slap_mods_check().
  */
-LDAPMod **slapi_int_modifications2ldapmods(
-       Modifications **pmodlist,
-       void *memctx
-)
+LDAPMod **slapi_int_modifications2ldapmods( Modifications **pmodlist )
 {
        Modifications *ml, *modlist;
        LDAPMod **mods, *modp;
@@ -2672,10 +2714,10 @@ LDAPMod **slapi_int_modifications2ldapmods(
        for( i = 0, ml = modlist; ml != NULL; i++, ml = ml->sml_next )
                ;
 
-       mods = (LDAPMod **)slap_sl_malloc( (i + 1) * sizeof(LDAPMod *), memctx );
+       mods = (LDAPMod **)slapi_ch_malloc( (i + 1) * sizeof(LDAPMod *) );
 
        for( i = 0, ml = modlist; ml != NULL; ml = ml->sml_next ) {
-               mods[i] = (LDAPMod *)slap_sl_malloc( sizeof(LDAPMod), memctx );
+               mods[i] = (LDAPMod *)slapi_ch_malloc( sizeof(LDAPMod) );
                modp = mods[i];
                modp->mod_op = ml->sml_op | LDAP_MOD_BVALUES;
                modp->mod_type = slapi_ch_strdup( ml->sml_type.bv_val );
@@ -2684,12 +2726,12 @@ LDAPMod **slapi_int_modifications2ldapmods(
                if ( ml->sml_values != NULL ) {
                        for( j = 0; ml->sml_values[j].bv_val != NULL; j++ )
                                ;
-                       modp->mod_bvalues = (struct berval **)slap_sl_malloc( (j + 1) *
-                               sizeof(struct berval *), memctx );
+                       modp->mod_bvalues = (struct berval **)slapi_ch_malloc( (j + 1) *
+                               sizeof(struct berval *) );
                        for( j = 0; ml->sml_values[j].bv_val != NULL; j++ ) {
+                               modp->mod_bvalues[j] = (struct berval *)slapi_ch_malloc(
+                                               sizeof(struct berval) );
                                /* Take ownership of original values. */
-                               modp->mod_bvalues[j] = (struct berval *)slap_sl_malloc(
-                                               sizeof(struct berval), memctx );
                                modp->mod_bvalues[j]->bv_len = ml->sml_values[j].bv_len;
                                modp->mod_bvalues[j]->bv_val = ml->sml_values[j].bv_val;
                                ml->sml_values[j].bv_len = 0;
@@ -2705,7 +2747,7 @@ LDAPMod **slapi_int_modifications2ldapmods(
 
        mods[i] = NULL;
 
-       slap_mods_free( modlist );
+       slap_mods_free( modlist, 1 );
        *pmodlist = NULL;
 
        return mods;
@@ -2713,16 +2755,17 @@ LDAPMod **slapi_int_modifications2ldapmods(
 
 /*
  * Convert a potentially modified array of LDAPMods back to a
- * Modification list. 
- * 
- * The returned Modification list contains pointers into the
- * LDAPMods array; the latter MUST be freed with
- * slapi_int_free_ldapmods() (see below).
+ * Modification list. Unfortunately the values need to be
+ * duplicated because slap_mods_check() will try to free them
+ * before prettying (and we can't easily get out of calling
+ * slap_mods_check() because we need normalized values).
  */
-Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods, void *memctx )
+Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods )
 {
        Modifications *modlist = NULL, **modtail;
        LDAPMod **modp;
+       char textbuf[SLAP_TEXT_BUFLEN];
+       const char *text;
 
        if ( mods == NULL ) {
                return NULL;
@@ -2741,39 +2784,39 @@ Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods, void *memctx )
                        continue;
                }
 
-               mod = (Modifications *) slap_sl_malloc( sizeof(Modifications), memctx );
+               mod = (Modifications *) slapi_ch_malloc( sizeof(Modifications) );
                mod->sml_op = lmod->mod_op & ~(LDAP_MOD_BVALUES);
                mod->sml_flags = 0;
                mod->sml_type = ad->ad_cname;
                mod->sml_desc = ad;
                mod->sml_next = NULL;
 
+               i = 0;
                if ( lmod->mod_op & LDAP_MOD_BVALUES ) {
                        if ( lmod->mod_bvalues != NULL ) {
-                               for ( i = 0; lmod->mod_bvalues[i] != NULL; i++ )
-                                       ;
+                               while ( lmod->mod_bvalues[i] != NULL )
+                                       i++;
                        }
                } else {
-                       if ( (*modp)->mod_values != NULL ) {
-                               for ( i = 0; lmod->mod_values[i] != NULL; i++ )
-                                       ;
+                       if ( lmod->mod_values != NULL ) {
+                               while ( lmod->mod_values[i] != NULL )
+                                       i++;
                        }
                }
 
                if ( i == 0 ) {
                        mod->sml_values = NULL;
                } else {
-                       mod->sml_values = (BerVarray) slap_sl_malloc( (i + 1) * sizeof(struct berval), memctx );
+                       mod->sml_values = (BerVarray) slapi_ch_malloc( (i + 1) * sizeof(struct berval) );
 
                        /* NB: This implicitly trusts a plugin to return valid modifications. */
                        if ( lmod->mod_op & LDAP_MOD_BVALUES ) {
                                for ( i = 0; lmod->mod_bvalues[i] != NULL; i++ ) {
-                                       mod->sml_values[i].bv_val = lmod->mod_bvalues[i]->bv_val;
-                                       mod->sml_values[i].bv_len = lmod->mod_bvalues[i]->bv_len;
+                                       ber_dupbv( &mod->sml_values[i], lmod->mod_bvalues[i] );
                                }
                        } else {
                                for ( i = 0; lmod->mod_values[i] != NULL; i++ ) {
-                                       mod->sml_values[i].bv_val = lmod->mod_values[i];
+                                       mod->sml_values[i].bv_val = slapi_ch_strdup( lmod->mod_values[i] );
                                        mod->sml_values[i].bv_len = strlen( lmod->mod_values[i] );
                                }
                        }
@@ -2785,63 +2828,13 @@ Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods, void *memctx )
                *modtail = mod;
                modtail = &mod->sml_next;
        }
-       
-       return modlist;
-}
 
-/*
- * For an internal operation, the unnormalized values are
- * owned by the caller (ie. the plugin making the internal
- * operation).
- */
-void
-slapi_int_mods_free( Modifications *ml )
-{
-       Modifications           *next;
-
-       for ( ; ml != NULL; ml = next ) {
-               next = ml->sml_next;
-
-               if ( ml->sml_nvalues != NULL ) {
-                       ber_bvarray_free( ml->sml_nvalues );
-                       ml->sml_nvalues = NULL;
-               }
-               slapi_ch_free( (void **)&ml->sml_values );
-               slapi_ch_free( (void **)&ml );
+       if ( slap_mods_check( modlist, &text, textbuf, sizeof( textbuf ), NULL ) != LDAP_SUCCESS ) {
+               slap_mods_free( modlist, 1 );
+               modlist = NULL;
        }
-}
 
-/*
- * This function only frees the parts of the mods array that
- * are not shared with the Modification list that was created
- * by slapi_int_ldapmods2modifications(). 
- */
-void
-slapi_int_free_ldapmods ( LDAPMod **mods )
-{
-       int i, j;
-
-       if ( mods == NULL )
-               return;
-
-       for ( i = 0; mods[i] != NULL; i++ ) {
-               /*
-                * Don't free values themselves; they're owned by the
-                * Modification list. Do free the containing array.
-                */
-               if ( mods[i]->mod_op & LDAP_MOD_BVALUES ) {
-                       if ( mods[i]->mod_bvalues != NULL ) {
-                               for ( j = 0; mods[i]->mod_bvalues[j] != NULL; j++ )
-                                       slapi_ch_free( (void **)&mods[i]->mod_bvalues[j] );
-                               slapi_ch_free( (void **)&mods[i]->mod_bvalues );
-                       }
-               } else {
-                       slapi_ch_free( (void **)&mods[i]->mod_values );
-               }
-               slapi_ch_free_string( &mods[i]->mod_type );
-               slapi_ch_free( (void **)&mods[i] );
-       }
-       slapi_ch_free( (void **)&mods );
+       return modlist;
 }
 
 /*
@@ -3196,16 +3189,22 @@ char *slapi_dn_plus_rdn( const char *dn, const char *rdn )
 
 int slapi_entry_schema_check( Slapi_PBlock *pb, Slapi_Entry *e )
 {
-       Backend *be;
+       Backend *be_orig;
        const char *text;
        char textbuf[SLAP_TEXT_BUFLEN] = { '\0' };
        size_t textlen = sizeof textbuf;
        int rc = LDAP_SUCCESS;
 
-       be = select_backend( &e->e_nname, 0, 0 );
-       if ( be != NULL )
-               rc = entry_schema_check( be, e, NULL, 0,
+       PBLOCK_ASSERT_OP( pb, 0 );
+
+       be_orig = pb->pb_op->o_bd;
+
+       pb->pb_op->o_bd = select_backend( &e->e_nname, 0, 0 );
+       if ( pb->pb_op->o_bd != NULL ) {
+               rc = entry_schema_check( pb->pb_op, e, NULL, 0,
                        &text, textbuf, textlen );
+       }
+       pb->pb_op->o_bd = be_orig;
 
        return ( rc == LDAP_SUCCESS ) ? 0 : 1;
 }
@@ -3453,6 +3452,33 @@ slapi_op_get_type(Slapi_Operation * op)
        return type;
 }
 
+void slapi_be_set_readonly( Slapi_Backend *be, int readonly )
+{
+       if ( be == NULL )
+               return;
+
+       if ( readonly )
+               be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
+       else
+               be->be_restrictops &= ~(SLAP_RESTRICT_OP_WRITES);
+}
+
+int slapi_be_get_readonly( Slapi_Backend *be )
+{
+       if ( be == NULL )
+               return 0;
+
+       return ( (be->be_restrictops & SLAP_RESTRICT_OP_WRITES) == SLAP_RESTRICT_OP_WRITES );
+}
+
+const char *slapi_x_be_get_updatedn( Slapi_Backend *be )
+{
+       if ( be == NULL )
+               return NULL;
+
+       return be->be_update_ndn.bv_val;
+}
+
 #if 0
 void
 slapi_operation_set_flag(Slapi_Operation *op, unsigned long flag)