Back to index

openldap  2.4.31
Classes | Typedefs | Functions
dn2id.c File Reference
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include "back-mdb.h"
#include "idl.h"
#include "lutil.h"

Go to the source code of this file.

Classes

struct  diskNode

Typedefs

typedef struct diskNode diskNode

Functions

int mdb_dup_compare (const MDB_val *usrkey, const MDB_val *curkey)
int mdb_dn2id_add (Operation *op, MDB_cursor *mcp, MDB_cursor *mcd, ID pid, Entry *e)
int mdb_dn2id_delete (Operation *op, MDB_cursor *mc, ID id)
int mdb_dn2id (Operation *op, MDB_txn *txn, MDB_cursor *mc, struct berval *in, ID *id, struct berval *matched, struct berval *nmatched)
int mdb_dn2sups (Operation *op, MDB_txn *txn, struct berval *in, ID *ids)
int mdb_dn2id_children (Operation *op, MDB_txn *txn, Entry *e)
int mdb_id2name (Operation *op, MDB_txn *txn, MDB_cursor **cursp, ID id, struct berval *name, struct berval *nname)
int mdb_idscope (Operation *op, MDB_txn *txn, ID base, ID *ids, ID *res)
int mdb_idscopes (Operation *op, IdScopes *isc)

Class Documentation

struct diskNode

Definition at line 42 of file dn2id.c.

Class Members
unsigned char entryID
char nrdn
unsigned char nrdnlen
char rdn

Typedef Documentation

typedef struct diskNode diskNode

Function Documentation

int mdb_dn2id ( Operation op,
MDB_txn txn,
MDB_cursor mc,
struct berval in,
ID id,
struct berval matched,
struct berval nmatched 
)

Definition at line 247 of file dn2id.c.

{
       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;
       char dn[SLAP_LDAPDN_MAXLEN];
       ID pid, nid;
       struct berval tmp;

       Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id(\"%s\")\n", in->bv_val ? in->bv_val : "", 0, 0 );

       if ( matched ) {
              matched->bv_val = dn + sizeof(dn) - 1;
              matched->bv_len = 0;
              *matched->bv_val-- = '\0';
       }
       if ( nmatched ) {
              nmatched->bv_len = 0;
              nmatched->bv_val = 0;
       }

       if ( !in->bv_len ) {
              *id = 0;
              nid = 0;
              goto done;
       }

       tmp = *in;

       if ( op->o_bd->be_nsuffix[0].bv_len ) {
              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;
       } else {
              for ( ptr = tmp.bv_val + tmp.bv_len - 1; ptr >= tmp.bv_val; ptr-- )
                     if (DN_SEPARATOR(*ptr))
                            break;
              ptr++;
              tmp.bv_len -= ptr - tmp.bv_val;
              tmp.bv_val = ptr;
       }
       nid = 0;
       key.mv_size = sizeof(ID);

       if ( mc ) {
              cursor = mc;
       } else {
              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 )
                     break;
              ptr = (char *) data.mv_data + data.mv_size - sizeof(ID);
              memcpy( &nid, ptr, sizeof(ID));

              /* grab the non-normalized RDN */
              if ( matched ) {
                     int rlen;
                     d = data.mv_data;
                     rlen = data.mv_size - sizeof(diskNode) - tmp.bv_len;
                     matched->bv_len += rlen;
                     matched->bv_val -= rlen + 1;
                     ptr = lutil_strcopy( matched->bv_val, d->rdn + tmp.bv_len );
                     if ( pid ) {
                            *ptr = ',';
                            matched->bv_len++;
                     }
              }
              if ( nmatched ) {
                     nmatched->bv_val = tmp.bv_val;
              }

              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;
              }
       }
       *id = nid; 
       if ( !mc )
              mdb_cursor_close( cursor );
done:
       if ( matched ) {
              if ( matched->bv_len ) {
                     ptr = op->o_tmpalloc( matched->bv_len+1, op->o_tmpmemctx );
                     strcpy( ptr, matched->bv_val );
                     matched->bv_val = ptr;
              } else {
                     if ( BER_BVISEMPTY( &op->o_bd->be_nsuffix[0] ) && !nid ) {
                            ber_dupbv( matched, (struct berval *)&slap_empty_bv );
                     } else {
                            matched->bv_val = NULL;
                     }
              }
       }
       if ( nmatched ) {
              if ( nmatched->bv_val ) {
                     nmatched->bv_len = in->bv_len - (nmatched->bv_val - in->bv_val);
              } else {
                     *nmatched = slap_empty_bv;
              }
       }

       if( rc != 0 ) {
              Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id: get failed: %s (%d)\n",
                     mdb_strerror( rc ), rc, 0 );
       } else {
              Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id: got id=0x%lx\n",
                     nid, 0, 0 );
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_dn2id_add ( Operation op,
MDB_cursor mcp,
MDB_cursor mcd,
ID  pid,
Entry e 
)

Definition at line 137 of file dn2id.c.

{
       struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
       MDB_val              key, data;
       ID            nid;
       int           rc, rlen, nrlen;
       diskNode *d;
       char *ptr;

       Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id_add 0x%lx: \"%s\"\n",
              e->e_id, e->e_ndn ? e->e_ndn : "", 0 );

       nrlen = dn_rdnlen( op->o_bd, &e->e_nname );
       if (nrlen) {
              rlen = dn_rdnlen( op->o_bd, &e->e_name );
       } else {
              nrlen = e->e_nname.bv_len;
              rlen = e->e_name.bv_len;
       }

       d = op->o_tmpalloc(sizeof(diskNode) + rlen + nrlen, op->o_tmpmemctx);
       d->nrdnlen[1] = nrlen & 0xff;
       d->nrdnlen[0] = (nrlen >> 8) | 0x80;
       ptr = lutil_strncopy( d->nrdn, e->e_nname.bv_val, nrlen );
       *ptr++ = '\0';
       ptr = lutil_strncopy( ptr, e->e_name.bv_val, rlen );
       *ptr++ = '\0';
       memcpy( ptr, &e->e_id, sizeof( ID ));

       key.mv_size = sizeof(ID);
       key.mv_data = &nid;

       nid = pid;

       /* Need to make dummy root node once. Subsequent attempts
        * will fail harmlessly.
        */
       if ( pid == 0 ) {
              diskNode dummy = {{0, 0}, "", "", ""};
              data.mv_data = &dummy;
              data.mv_size = sizeof(diskNode);

              mdb_cursor_put( mcp, &key, &data, MDB_NODUPDATA );
       }

       data.mv_data = d;
       data.mv_size = sizeof(diskNode) + rlen + nrlen;

       rc = mdb_cursor_put( mcp, &key, &data, MDB_NODUPDATA );

       if (rc == 0) {
              int flag = MDB_NODUPDATA;
              nid = e->e_id;
              memcpy( ptr, &pid, sizeof( ID ));
              d->nrdnlen[0] ^= 0x80;

              if (slapMode & SLAP_TOOL_MODE)
                     flag |= MDB_APPEND;
              rc = mdb_cursor_put( mcd, &key, &data, flag );
       }

fail:
       op->o_tmpfree( d, op->o_tmpmemctx );
       Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_add 0x%lx: %d\n", e->e_id, rc, 0 );

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_dn2id_children ( Operation op,
MDB_txn txn,
Entry e 
)

Definition at line 532 of file dn2id.c.

{
       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;
       int           rc;
       ID            id;

       key.mv_size = sizeof(ID);
       key.mv_data = &id;
       id = e->e_id;

       rc = mdb_cursor_open( txn, dbi, &cursor );
       if ( rc ) return rc;

       rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
       if ( rc == 0 ) {
              size_t dkids;
              rc = mdb_cursor_count( cursor, &dkids );
              if ( rc == 0 ) {
                     if ( dkids < 2 ) rc = MDB_NOTFOUND;
              }
       }
       mdb_cursor_close( cursor );
       return rc;
}

Here is the call graph for this function:

int mdb_dn2id_delete ( Operation op,
MDB_cursor mc,
ID  id 
)

Definition at line 212 of file dn2id.c.

{
       int rc;

       Debug( LDAP_DEBUG_TRACE, "=> mdb_dn2id_delete 0x%lx\n",
              id, 0, 0 );

       /* Delete our ID from the parent's list */
       rc = mdb_cursor_del( mc, 0 );

       /* Delete our ID from the tree. With sorted duplicates, this
        * will leave any child nodes still hanging around. This is OK
        * for modrdn, which will add our info back in later.
        */
       if ( rc == 0 ) {
              MDB_val       key;
              key.mv_size = sizeof(ID);
              key.mv_data = &id;
              rc = mdb_cursor_get( mc, &key, NULL, MDB_SET );
              if ( rc == 0 )
                     rc = mdb_cursor_del( mc, 0 );
       }

       Debug( LDAP_DEBUG_TRACE, "<= mdb_dn2id_delete 0x%lx: %d\n", id, rc, 0 );
       return rc;
}

Here is the call graph for this function:

int mdb_dn2sups ( Operation op,
MDB_txn txn,
struct berval in,
ID ids 
)

Definition at line 394 of file dn2id.c.

{
       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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_dup_compare ( const MDB_val usrkey,
const MDB_val curkey 
)

Definition at line 53 of file dn2id.c.

{
       diskNode *un, *cn;
       int rc, nrlen;

       un = (diskNode *)usrkey->mv_data;
       cn = (diskNode *)curkey->mv_data;

       /* data is not aligned, cannot compare directly */
       rc = un->nrdnlen[0] - cn->nrdnlen[0];
       if ( rc ) return rc;
       rc = un->nrdnlen[1] - cn->nrdnlen[1];
       if ( rc ) return rc;

       nrlen = (un->nrdnlen[0] << 8) | un->nrdnlen[1];
       return strncmp( un->nrdn, cn->nrdn, nrlen );
}
int mdb_id2name ( Operation op,
MDB_txn txn,
MDB_cursor **  cursp,
ID  id,
struct berval name,
struct berval nname 
)

Definition at line 564 of file dn2id.c.

{
       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;
       int           rc, len, nlen;
       char dn[SLAP_LDAPDN_MAXLEN], ndn[SLAP_LDAPDN_MAXLEN], *ptr;
       char *dptr, *nptr;
       diskNode *d;

       key.mv_size = sizeof(ID);

       if ( !*cursp ) {
              rc = mdb_cursor_open( txn, dbi, cursp );
              if ( rc ) return rc;
       }
       cursor = *cursp;

       len = 0;
       nlen = 0;
       dptr = dn;
       nptr = ndn;
       while (id) {
              unsigned int nrlen, rlen;
              key.mv_data = &id;
              data.mv_size = 0;
              data.mv_data = "";
              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) );
              d = data.mv_data;
              nrlen = (d->nrdnlen[0] << 8) | d->nrdnlen[1];
              rlen = data.mv_size - sizeof(diskNode) - nrlen;
              assert( nrlen < 1024 && rlen < 1024 );    /* FIXME: Sanity check */
              if (nptr > ndn) {
                     *nptr++ = ',';
                     *dptr++ = ',';
              }
              /* copy name and trailing NUL */
              memcpy( nptr, d->nrdn, nrlen+1 );
              memcpy( dptr, d->nrdn+nrlen+1, rlen+1 );
              nptr += nrlen;
              dptr += rlen;
       }
       if ( rc == 0 ) {
              name->bv_len = dptr - dn;
              nname->bv_len = nptr - ndn;
              name->bv_val = op->o_tmpalloc( name->bv_len + 1, op->o_tmpmemctx );
              nname->bv_val = op->o_tmpalloc( nname->bv_len + 1, op->o_tmpmemctx );
              memcpy( name->bv_val, dn, name->bv_len );
              name->bv_val[name->bv_len] = '\0';
              memcpy( nname->bv_val, ndn, nname->bv_len );
              nname->bv_val[nname->bv_len] = '\0';
       }
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_idscope ( Operation op,
MDB_txn txn,
ID  base,
ID ids,
ID res 
)

Definition at line 633 of file dn2id.c.

{
       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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int mdb_idscopes ( Operation op,
IdScopes isc 
)

Definition at line 708 of file dn2id.c.

{
       struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
       MDB_dbi dbi = mdb->mi_dn2id;
       MDB_val              key, data;
       ID id;
       ID2 id2;
       char   *ptr;
       int           rc = 0;
       unsigned int x;
       unsigned int nrlen, rlen;
       diskNode *d;

       key.mv_size = sizeof(ID);

       if ( !isc->mc ) {
              rc = mdb_cursor_open( isc->mt, dbi, &isc->mc );
              if ( rc ) return rc;
       }

       id = isc->id;
       while (id) {
              if ( !rc ) {
                     key.mv_data = &id;
                     rc = mdb_cursor_get( isc->mc, &key, &data, MDB_SET );
                     if ( rc )
                            break;

                     /* save RDN info */
              }
              d = data.mv_data;
              nrlen = (d->nrdnlen[0] << 8) | d->nrdnlen[1];
              rlen = data.mv_size - sizeof(diskNode) - nrlen;
              isc->nrdns[isc->numrdns].bv_len = nrlen;
              isc->nrdns[isc->numrdns].bv_val = d->nrdn;
              isc->rdns[isc->numrdns].bv_len = rlen;
              isc->rdns[isc->numrdns].bv_val = d->nrdn+nrlen+1;
              isc->numrdns++;

              if (!rc && id != isc->id) {
                     id2.mid = id;
                     id2.mval = data;
                     mdb_id2l_insert( isc->scopes, &id2 );
              }
              ptr = data.mv_data;
              ptr += data.mv_size - sizeof(ID);
              memcpy( &id, ptr, sizeof(ID) );
              x = mdb_id2l_search( isc->scopes, id );
              if ( x <= isc->scopes[0].mid && isc->scopes[x].mid == id ) {
                     if ( !isc->scopes[x].mval.mv_data ) {
                            isc->nscope = x;
                            return MDB_SUCCESS;
                     }
                     data = isc->scopes[x].mval;
                     rc = 1;
              }
              if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
                     break;
       }
       return MDB_NOTFOUND;
}

Here is the call graph for this function: