]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-mdb/dn2id.c
Plug memleak
[openldap] / servers / slapd / back-mdb / dn2id.c
index 2ea6cdbd8ba4cdddabaa6e36353538d1f80343d8..82ec07b7f1c8b5df96b9529f755655b8d2f9a164 100644 (file)
@@ -141,7 +141,7 @@ mdb_dn2id_add(
        Entry           *e )
 {
        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
-       MDB_dbi dbi = mdb->mi_dn2id->mdi_dbi;
+       MDB_dbi dbi = mdb->mi_dn2id;
        MDB_val         key, data;
        ID              nid;
        int             rc, rlen, nrlen;
@@ -211,7 +211,7 @@ mdb_dn2id_delete(
        Entry   *e )
 {
        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
-       MDB_dbi dbi = mdb->mi_dn2id->mdi_dbi;
+       MDB_dbi dbi = mdb->mi_dn2id;
        MDB_val key, data;
        diskNode *d;
        int rc, nrlen;
@@ -246,7 +246,6 @@ mdb_dn2id_delete(
                rc = mdb_del( txn, dbi, &key, &data, MDB_DEL_DUP );
        }
 
-func_leave:
        op->o_tmpfree( d, op->o_tmpmemctx );
 
        Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 );
@@ -264,13 +263,12 @@ mdb_dn2id(
 {
        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
        MDB_cursor *cursor;
-       MDB_dbi dbi = mdb->mi_dn2id->mdi_dbi;
+       MDB_dbi dbi = mdb->mi_dn2id;
        MDB_val         key, data;
        int             rc = 0, nrlen;
        diskNode *d;
        char    *ptr;
        char dn[SLAP_LDAPDN_MAXLEN];
-       unsigned char dlen[2];
        ID pid, nid;
        struct berval tmp;
 
@@ -312,17 +310,8 @@ mdb_dn2id(
                data.mv_data = d;
                rc = mdb_cursor_get( cursor, &key, &data, MDB_GET_BOTH );
                op->o_tmpfree( d, op->o_tmpmemctx );
-               if ( rc == MDB_NOTFOUND ) {
-                       if ( matched && matched->bv_len ) {
-                               ptr = op->o_tmpalloc( matched->bv_len+1, op->o_tmpmemctx );
-                               strcpy( ptr, matched->bv_val );
-                               matched->bv_val = ptr;
-                       }
-               }
-               if ( rc ) {
-                       mdb_cursor_close( cursor );
+               if ( rc )
                        break;
-               }
                ptr = (char *) data.mv_data + data.mv_size - sizeof(ID);
                memcpy( &nid, ptr, sizeof(ID));
 
@@ -352,6 +341,12 @@ mdb_dn2id(
                }
        }
        *id = nid; 
+       mdb_cursor_close( cursor );
+       if ( matched && matched->bv_len ) {
+               ptr = op->o_tmpalloc( matched->bv_len+1, op->o_tmpmemctx );
+               strcpy( ptr, matched->bv_val );
+               matched->bv_val = ptr;
+       }
 
 done:
        if( rc != 0 ) {
@@ -365,6 +360,86 @@ done:
        return rc;
 }
 
+/* return IDs from root to parent of DN */
+int
+mdb_dn2sups(
+       Operation       *op,
+       MDB_txn *txn,
+       struct berval   *in,
+       ID      *ids )
+{
+       struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
+       MDB_cursor *cursor;
+       MDB_dbi dbi = mdb->mi_dn2id;
+       MDB_val         key, data;
+       int             rc = 0, nrlen;
+       diskNode *d;
+       char    *ptr;
+       ID pid, nid;
+       struct berval tmp;
+
+       Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2sups(\"%s\")\n", in->bv_val, 0, 0 );
+
+       if ( !in->bv_len ) {
+               goto done;
+       }
+
+       tmp = *in;
+
+       nrlen = tmp.bv_len - op->o_bd->be_nsuffix[0].bv_len;
+       tmp.bv_val += nrlen;
+       tmp.bv_len = op->o_bd->be_nsuffix[0].bv_len;
+       nid = 0;
+       key.mv_size = sizeof(ID);
+
+       rc = mdb_cursor_open( txn, dbi, &cursor );
+       if ( rc ) return rc;
+
+       for (;;) {
+               key.mv_data = &pid;
+               pid = nid;
+
+               data.mv_size = sizeof(diskNode) + tmp.bv_len;
+               d = op->o_tmpalloc( data.mv_size, op->o_tmpmemctx );
+               d->nrdnlen[1] = tmp.bv_len & 0xff;
+               d->nrdnlen[0] = (tmp.bv_len >> 8) | 0x80;
+               ptr = lutil_strncopy( d->nrdn, tmp.bv_val, tmp.bv_len );
+               *ptr = '\0';
+               data.mv_data = d;
+               rc = mdb_cursor_get( cursor, &key, &data, MDB_GET_BOTH );
+               op->o_tmpfree( d, op->o_tmpmemctx );
+               if ( rc ) {
+                       mdb_cursor_close( cursor );
+                       break;
+               }
+               ptr = (char *) data.mv_data + data.mv_size - sizeof(ID);
+               memcpy( &nid, ptr, sizeof(ID));
+
+               if ( pid )
+                       mdb_idl_insert( ids, pid );
+
+               if ( tmp.bv_val > in->bv_val ) {
+                       for (ptr = tmp.bv_val - 2; ptr > in->bv_val &&
+                               !DN_SEPARATOR(*ptr); ptr--)     /* empty */;
+                       if ( ptr >= in->bv_val ) {
+                               if (DN_SEPARATOR(*ptr)) ptr++;
+                               tmp.bv_len = tmp.bv_val - ptr - 1;
+                               tmp.bv_val = ptr;
+                       }
+               } else {
+                       break;
+               }
+       }
+
+done:
+       if( rc != 0 ) {
+               Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2sups: get failed: %s (%d)\n",
+                       mdb_strerror( rc ), rc, 0 );
+       }
+
+       return rc;
+}
+
 #if 0
 int
 mdb_dn2id_parent(
@@ -431,7 +506,7 @@ mdb_dn2id_children(
        Entry *e )
 {
        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
-       MDB_dbi dbi = mdb->mi_dn2id->mdi_dbi;
+       MDB_dbi dbi = mdb->mi_dn2id;
        MDB_val         key, data;
        MDB_cursor      *cursor;
        int             rc;
@@ -460,12 +535,13 @@ int
 mdb_id2name(
        Operation *op,
        MDB_txn *txn,
+       MDB_cursor **cursp,
        ID id,
        struct berval *name,
        struct berval *nname )
 {
        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
-       MDB_dbi dbi = mdb->mi_dn2id->mdi_dbi;
+       MDB_dbi dbi = mdb->mi_dn2id;
        MDB_val         key, data;
        MDB_cursor      *cursor;
        int             rc, len, nlen;
@@ -475,8 +551,11 @@ mdb_id2name(
 
        key.mv_size = sizeof(ID);
 
-       rc = mdb_cursor_open( txn, dbi, &cursor );
-       if ( rc ) return rc;
+       if ( !*cursp ) {
+               rc = mdb_cursor_open( txn, dbi, cursp );
+               if ( rc ) return rc;
+       }
+       cursor = *cursp;
 
        len = 0;
        nlen = 0;
@@ -515,10 +594,129 @@ mdb_id2name(
                memcpy( nname->bv_val, ndn, nname->bv_len );
                nname->bv_val[nname->bv_len] = '\0';
        }
+       return rc;
+}
+
+/* Find each id in ids that is a child of base and move it to res.
+ */
+int
+mdb_idscope(
+       Operation *op,
+       MDB_txn *txn,
+       ID base,
+       ID *ids,
+       ID *res )
+{
+       struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
+       MDB_dbi dbi = mdb->mi_dn2id;
+       MDB_val         key, data;
+       MDB_cursor      *cursor;
+       ID ida, id, cid, ci0, idc = 0;
+       char    *ptr;
+       int             rc;
+
+       key.mv_size = sizeof(ID);
+
+       MDB_IDL_ZERO( res );
+
+       rc = mdb_cursor_open( txn, dbi, &cursor );
+       if ( rc ) return rc;
+
+       ida = mdb_idl_first( ids, &cid );
+
+       /* Don't bother moving out of ids if it's a range */
+       if (!MDB_IDL_IS_RANGE(ids)) {
+               idc = ids[0];
+               ci0 = cid;
+       }
+
+       while (ida != NOID) {
+               id = ida;
+               while (id) {
+                       key.mv_data = &id;
+                       rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
+                       if ( rc ) {
+                               /* not found, move on to next */
+                               if (idc) {
+                                       if (ci0 != cid)
+                                               ids[ci0] = ids[cid];
+                                       ci0++;
+                               }
+                               break;
+                       }
+                       ptr = data.mv_data;
+                       ptr += data.mv_size - sizeof(ID);
+                       memcpy( &id, ptr, sizeof(ID) );
+                       if ( id == base ) {
+                               res[0]++;
+                               res[res[0]] = ida;
+                               if (idc)
+                                       idc--;
+                               break;
+                       } else {
+                               if (idc) {
+                                       if (ci0 != cid)
+                                               ids[ci0] = ids[cid];
+                                       ci0++;
+                               }
+                       }
+                       if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
+                               break;
+               }
+               ida = mdb_idl_next( ids, &cid );
+       }
+       if (!MDB_IDL_IS_RANGE( ids ))
+               ids[0] = idc;
+
        mdb_cursor_close( cursor );
        return rc;
 }
 
+/* See if base is a child of any of the scopes
+ */
+int
+mdb_idscopes(
+       Operation *op,
+       MDB_txn *txn,
+       MDB_cursor **cursp,
+       ID base,
+       ID *scopes )
+{
+       struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
+       MDB_dbi dbi = mdb->mi_dn2id;
+       MDB_val         key, data;
+       MDB_cursor      *cursor;
+       ID id;
+       char    *ptr;
+       int             rc;
+       unsigned int x;
+
+       key.mv_size = sizeof(ID);
+
+       if ( !*cursp ) {
+               rc = mdb_cursor_open( txn, dbi, cursp );
+               if ( rc ) return rc;
+       }
+       cursor = *cursp;
+
+       id = base;
+       while (id) {
+               key.mv_data = &id;
+               rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
+               if ( rc )
+                       break;
+               ptr = data.mv_data;
+               ptr += data.mv_size - sizeof(ID);
+               memcpy( &id, ptr, sizeof(ID) );
+               x = mdb_idl_search( scopes, id );
+               if ( scopes[x] == id )
+                       return MDB_SUCCESS;
+               if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
+                       break;
+       }
+       return MDB_NOTFOUND;
+}
+
 #if 0
 /* mdb_dn2idl:
  * We can't just use mdb_idl_fetch_key because