mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
Pierangelo Masarati's bugfixes and enhancements for suffix-massaging.
See the Changes file for detailed description.
This commit is contained in:
parent
a728b2c073
commit
4703fe82b2
121
servers/slapd/back-ldap/Changes
Normal file
121
servers/slapd/back-ldap/Changes
Normal file
@ -0,0 +1,121 @@
|
||||
Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
|
||||
The backend back-ldap has been modified as follows:
|
||||
|
||||
* The LDAP handlers have been put under an avl tree, in an attempt
|
||||
to improve the access to connections in heavy loaded environments
|
||||
(many clients connecting simultaneously for long times, e.g.
|
||||
authenticators that make successive searches and binds without
|
||||
renewing the handler).
|
||||
This required to change the lcs member of struct ldapinfo into
|
||||
an (Avlnode *) member called conntree.
|
||||
The member next in the ldapconn struct has been eliminated because
|
||||
it is no longer needed.
|
||||
|
||||
* The ldap_back_dobind function has been forced to return the value
|
||||
of the bound flag instead of void; there is no longer need to test
|
||||
for the flag outside the function as a test was already in.
|
||||
Now the function can be called as
|
||||
|
||||
if ( !ldap_back_dobind( lc, op ) ) {
|
||||
/* handle error */
|
||||
}
|
||||
|
||||
* The suffix of the operations can be "massaged", i.e. changed to
|
||||
a different suffix to implement what has been termed a
|
||||
"virtual naming context": an incoming request with a certain
|
||||
base or related to a certain dn is turned into a request to a different
|
||||
server with the base or the dn changed in its terminal part (the naming
|
||||
context). The resulting entries, if any, have the real naming context
|
||||
changed back into the virtual naming context.
|
||||
|
||||
This required to add a suffixMassage configuration line of the form
|
||||
|
||||
suffix "virtual naming context"
|
||||
suffixMassage "virtual naming context" "real naming context"
|
||||
|
||||
(the name of the configuration parameter will be changed to something
|
||||
more appropriate as will result from a debate in the -devel mailing
|
||||
list).
|
||||
The "virtual naming context" must appear in a suffix configuration line
|
||||
so the server can select the appropriate backend; then the suffixMassage
|
||||
configuration line maps the "virtual" and the "real" naming contexts
|
||||
back and forth.
|
||||
This allows one to map multiple real naming contexts as branches
|
||||
of a single naming context, provided these reside on the same server:
|
||||
|
||||
suffix "ou=Branch 1, o=My Org, c=IT"
|
||||
suffixMassage "ou=Branch 1, o=My Org, c=IT" "o=Org 1, c=IT"
|
||||
suffix "ou=Branch 2, o=My Org, c=IT"
|
||||
suffixMassage "ou=Branch 2, o=My Org, c=IT" "dc=host, dc=net"
|
||||
suffix "o=My Org, c=IT"
|
||||
suffixMassage "o=My Org, c=IT" "dc=host, dc=it"
|
||||
|
||||
Note that the "same server" limitation can be overcome by using
|
||||
multiple back-ldap databases, each pointing to the appropriate
|
||||
server.
|
||||
|
||||
Another choice, which would not allow multiple naming contexts
|
||||
being served by the same database, is to use the "dn" part of the
|
||||
"uri" configuration parameter, e.g.:
|
||||
|
||||
suffix "virtual naming context"
|
||||
uri "ldap://ldap.my.org:port/real naming context"
|
||||
|
||||
This has not been implemented yet.
|
||||
|
||||
A possible future enhancement will allow the ldap backend to handle
|
||||
multiple servers within a single naming context.
|
||||
|
||||
Two functions, ldap_back_dn_massage and ldap_back_dn_restore, have
|
||||
been added. The former changes the bind dn or the search base,
|
||||
in case its terminal portion matches the "virtual naming context"
|
||||
of a suffixMassage entry, to the corresponding "real naming context"
|
||||
suffixed value.
|
||||
The latter turns the entry's dn back to the "virtual naming context"
|
||||
suffixed form if the real dn terminal portion matches any "real naming
|
||||
context" part of a suffixMassage configuration line.
|
||||
The deferred bind required to add the bound_dn member to the ldapconn
|
||||
struct.
|
||||
As of the time of this writing, all the backend operations that
|
||||
require writing (add, delete, modify, modrdn) have been added the
|
||||
massaging capability; it can be safely turned off by turning on
|
||||
the readonly mode at the backend level. The massaging is performed
|
||||
only on the dn of the entry that is modified, and in the modrdn
|
||||
operation it affects both the old and the newSuperior dn.
|
||||
|
||||
* Cleanup/minor bug fixes/software enhancements:
|
||||
|
||||
- the suffix member (unused) has been eliminated (commented out)
|
||||
from the ldapinfo struct.
|
||||
|
||||
- bind.c:ldap_back_op_result: a check of the value of "match" and
|
||||
"msg" variables is added before freeing them (got a NULL "match"
|
||||
when the server the backend points to was restarted).
|
||||
|
||||
- search.c:ldap_send_entry: the member a_desc in the (Attribute *)
|
||||
"attr" must be set to NULL before calling slap_str2ad, otherwise
|
||||
an assertion fails (ITS #919).
|
||||
|
||||
- search.c:ldap_send_entry: the entry's ent.e_dn and ent.e_ndn members
|
||||
need be freed before returning because they were allocated inside
|
||||
the routine.
|
||||
|
||||
- modify.c:ldap_back_modify: the Modifications member sml_op needs be
|
||||
ORed with LDAP_MOD_BVALUES to force the ldap_modify_s routine
|
||||
handle the modifications as bervals:
|
||||
|
||||
mods[i].mod_op = ml->sml_op | LDAP_MOD_BVALUES;
|
||||
|
||||
* Notes:
|
||||
- there a possible memory leak in the backend, because the memory
|
||||
occupation of the slapd processes steadily grows when it is
|
||||
repeatedly accessed.
|
||||
|
||||
- when writing (add/modify) lastmod must be set to OFF otherwise
|
||||
the lastmod attributes will be added to the entry mods and the
|
||||
target server will complain about
|
||||
|
||||
ldap_modify: Constraint violation
|
||||
ldap_modify: additional info: no user modification allowed
|
||||
|
@ -21,3 +21,13 @@ to the following restrictions:
|
||||
ever read sources, credits should appear in the documentation.
|
||||
|
||||
4. This notice may not be removed or altered.
|
||||
|
||||
|
||||
|
||||
Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
|
||||
This software is being modified by Pierangelo Masarati.
|
||||
The previously reported conditions apply to the modified code as well.
|
||||
Changes in the original code are highlighted where required.
|
||||
Credits for the original code go to the author, Howard Chu.
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
# $OpenLDAP$
|
||||
|
||||
SRCS = init.c config.c search.c bind.c unbind.c add.c compare.c \
|
||||
delete.c modify.c modrdn.c group.c attribute.c
|
||||
delete.c modify.c modrdn.c group.c attribute.c \
|
||||
suffixmassage.c
|
||||
OBJS = init.lo config.lo search.lo bind.lo unbind.lo add.lo compare.lo \
|
||||
delete.lo modify.lo modrdn.lo group.lo attribute.lo
|
||||
delete.lo modify.lo modrdn.lo group.lo attribute.lo \
|
||||
suffixmassage.lo
|
||||
|
||||
LDAP_INCDIR= ../../../include
|
||||
LDAP_LIBDIR= ../../../libraries
|
||||
|
101
servers/slapd/back-ldap/TODO.proxy
Normal file
101
servers/slapd/back-ldap/TODO.proxy
Normal file
@ -0,0 +1,101 @@
|
||||
back-proxy
|
||||
|
||||
A proxy that handles a pool of URI associated to a unique suffix.
|
||||
Each request is spread over the different URIs and results are
|
||||
masqueraded to appear as coming from a unique server.
|
||||
|
||||
Suppose a company has two branches, whose existing DS have URIs
|
||||
|
||||
"ldap://ldap.branch1.com/o=Branch 1, c=US"
|
||||
"ldap://ldap.branch2.it/o=Branch 2, c=IT"
|
||||
|
||||
and it wants to propose to the outer world as a unique URI
|
||||
|
||||
"ldap://ldap.company.net/dc=company, dc=net"
|
||||
|
||||
It could do some rewriting to map everything that comes in with a base dn
|
||||
of "o=Branch 1, dc=company, dc=net" as the URI of the Branch 1, and
|
||||
everything that comes in with a base dn of "o=Branch 2, dc=company, dc=net"
|
||||
as the URI of Branch 2, and by rewriting all the dns back to the new, uniform
|
||||
base. Everything that comes in with a base dn of "dc=company, dc=net" should
|
||||
be handled locally and propagated to the two branch URIs if a subtree
|
||||
(or at least onelevel) search is required.
|
||||
|
||||
Operations:
|
||||
|
||||
- bind
|
||||
- unbind
|
||||
- search
|
||||
- compare
|
||||
- add
|
||||
- modify
|
||||
- modrdn
|
||||
- delete
|
||||
- abandon
|
||||
|
||||
The input of each operation may be related to:
|
||||
|
||||
exact dn exact parent ancestor
|
||||
-------------------------------------------------------------
|
||||
bind x
|
||||
unbind
|
||||
search x x x
|
||||
compare x
|
||||
add x
|
||||
modify x
|
||||
modrdn x
|
||||
delete x
|
||||
abandon
|
||||
|
||||
The backend must rely on a dn fetching mechanism. Each operation requires
|
||||
to determine as early as possible which URI will be able to satisfy it.
|
||||
Apart from searches, which by definition are usually allowed to return
|
||||
multiple results, and apart from unbind and abandon, which do not return any
|
||||
result, all the remaining operations require the related entry to be unique.
|
||||
|
||||
A major problem isposed by the uniqueness of the dns. As far as the suffixes
|
||||
are masqueraded by a common suffix, tyhe dns are no longer guaranteed to be
|
||||
unique. This backend relies on the assumption that the uniqueness of the
|
||||
dns is guaranteed.
|
||||
|
||||
Two layers of depth in dn fetching are envisaged.
|
||||
The first layer is provided by a backend-side cache made of previously
|
||||
retrieved entries. The cache relates each rdn (i.e. the dn apart from the
|
||||
common suffix) to the pool of URIs that are expected to contain a subset
|
||||
of its children.
|
||||
|
||||
The second layer is provided by a fetching function that spawns a search for
|
||||
each URI in the pool determined by the cache if the correct URI has not been
|
||||
directly determined.
|
||||
|
||||
Note that, as the remote servers may have been updated by some direct
|
||||
operation, this mechanism does not guarantee the uniqueness of the result.
|
||||
So write operations will require to skip the cache search and to perform
|
||||
the exaustive search of all the URIs unless some hint mechanism is provided
|
||||
to the backend (e.g. a server is read-only).
|
||||
|
||||
Again, the lag between the fetching of the required dn and the actual
|
||||
read/write may result in a failure; however, this applies to any LDAP
|
||||
operation AFAIK.
|
||||
|
||||
- bind
|
||||
if updates are to be strictly honored, a bind operation is performed against
|
||||
each URI; otherwise, it is performed against the URIs resulting from a
|
||||
cache-level dn fetch.
|
||||
|
||||
- unbind
|
||||
nothing to say; all the open handles related to the connection are reset.
|
||||
|
||||
- search
|
||||
if updates are to be strictly honored, a search operation is performed agaist
|
||||
each URI. Note that this needs be performed also when the backend suffix
|
||||
is used as base. In case the base is stricter, the URI pool may be restricted
|
||||
by performing a cache dn fetch of the base first.
|
||||
|
||||
- compare
|
||||
the same applies to the compare dn.
|
||||
|
||||
- add
|
||||
this operation is delicate. Unless the dn up to the top-level part excluded
|
||||
can be uniquely associated to a URI, and unless its uniqueness can be trusted,
|
||||
no add operation should be allowed.
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
@ -50,18 +59,20 @@ ldap_back_add(
|
||||
Attribute *a;
|
||||
LDAPMod **attrs;
|
||||
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if (!lc)
|
||||
return( -1 );
|
||||
char *mdn;
|
||||
|
||||
if (!lc->bound) {
|
||||
ldap_back_dobind(lc, op);
|
||||
if (!lc->bound)
|
||||
return( -1 );
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if ( !lc || !ldap_back_dobind( lc, op ) ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
mdn = ldap_back_dn_massage( li, ch_strdup( e->e_dn ), 0 );
|
||||
if ( mdn == NULL ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Count number of attributes in entry */
|
||||
for (i=1, a=e->e_attrs; a; i++, a=a->a_next)
|
||||
for (i = 1, a = e->e_attrs; a; i++, a = a->a_next)
|
||||
;
|
||||
|
||||
/* Create array of LDAPMods for ldap_add() */
|
||||
@ -75,9 +86,10 @@ ldap_back_add(
|
||||
attrs[i]->mod_vals.modv_bvals = a->a_vals;
|
||||
}
|
||||
|
||||
ldap_add_s(lc->ld, e->e_dn, attrs);
|
||||
ldap_add_s(lc->ld, mdn, attrs);
|
||||
for (--i; i>= 0; --i)
|
||||
free(attrs[i]);
|
||||
free(attrs);
|
||||
free( mdn );
|
||||
return( ldap_back_op_result( lc, op ));
|
||||
}
|
||||
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#ifndef SLAPD_LDAP_H
|
||||
@ -37,28 +46,37 @@ struct slap_conn;
|
||||
struct slap_op;
|
||||
|
||||
struct ldapconn {
|
||||
struct ldapconn *next;
|
||||
struct slap_conn *conn;
|
||||
LDAP *ld;
|
||||
char *bound_dn;
|
||||
int bound;
|
||||
};
|
||||
|
||||
struct ldapinfo {
|
||||
char *url;
|
||||
#if 0 /* unused! */
|
||||
char *suffix;
|
||||
#endif /* 0 */
|
||||
char **suffix_massage;
|
||||
char *binddn;
|
||||
char *bindpw;
|
||||
ldap_pvt_thread_mutex_t conn_mutex;
|
||||
struct ldapconn *lcs;
|
||||
Avlnode *conntree;
|
||||
};
|
||||
|
||||
struct ldapconn *ldap_back_getconn(struct ldapinfo *li, struct slap_conn *conn,
|
||||
struct slap_op *op);
|
||||
void ldap_back_dobind(struct ldapconn *lc, Operation *op);
|
||||
int ldap_back_dobind(struct ldapconn *lc, Operation *op);
|
||||
int ldap_back_map_result(int err);
|
||||
int ldap_back_op_result(struct ldapconn *lc, Operation *op);
|
||||
int back_ldap_LTX_init_module(int argc, char *argv[]);
|
||||
|
||||
char *ldap_back_dn_massage(struct ldapinfo *li, char *dn, int normalized);
|
||||
char *ldap_back_dn_restore(struct ldapinfo *li, char *dn, int normalized);
|
||||
|
||||
int conn_cmp(const void *, const void *);
|
||||
int conn_dup(void *, void *);
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
#endif
|
||||
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
@ -33,6 +42,8 @@
|
||||
#include <ac/socket.h>
|
||||
#include <ac/string.h>
|
||||
|
||||
|
||||
#define AVL_INTERNAL
|
||||
#include "slap.h"
|
||||
#include "back-ldap.h"
|
||||
|
||||
@ -51,35 +62,116 @@ ldap_back_bind(
|
||||
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
|
||||
struct ldapconn *lc;
|
||||
|
||||
char *mdn = NULL;
|
||||
int rc = 0;
|
||||
|
||||
*edn = NULL;
|
||||
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if (!lc)
|
||||
if ( !lc ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if (ldap_bind_s(lc->ld, dn, cred->bv_val, method) != LDAP_SUCCESS)
|
||||
return( ldap_back_op_result(lc, op) );
|
||||
mdn = ldap_back_dn_massage( li, ch_strdup( dn ), 0 );
|
||||
if ( mdn == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
lc->bound = 1;
|
||||
return( 0 );
|
||||
if (ldap_bind_s(lc->ld, mdn, cred->bv_val, method) != LDAP_SUCCESS) {
|
||||
rc = ldap_back_op_result( lc, op );
|
||||
} else {
|
||||
lc->bound = 1;
|
||||
}
|
||||
|
||||
free( mdn );
|
||||
|
||||
return( rc );
|
||||
}
|
||||
|
||||
/*
|
||||
* conn_cmp
|
||||
*
|
||||
* compares two struct ldapconn based on the value of the conn pointer;
|
||||
* used by avl stuff
|
||||
*/
|
||||
int
|
||||
conn_cmp(
|
||||
const void *c1,
|
||||
const void *c2
|
||||
)
|
||||
{
|
||||
struct ldapconn *lc1 = (struct ldapconn *)c1;
|
||||
struct ldapconn *lc2 = (struct ldapconn *)c2;
|
||||
|
||||
return ( ( lc1->conn < lc2->conn ) ? -1 : ( ( lc1->conn > lc2-> conn ) ? 1 : 0 ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* conn_dup
|
||||
*
|
||||
* returns -1 in case a duplicate struct ldapconn has been inserted;
|
||||
* used by avl stuff
|
||||
*/
|
||||
int
|
||||
conn_dup(
|
||||
void *c1,
|
||||
void *c2
|
||||
)
|
||||
{
|
||||
struct ldapconn *lc1 = (struct ldapconn *)c1;
|
||||
struct ldapconn *lc2 = (struct ldapconn *)c2;
|
||||
|
||||
return( ( lc1->conn == lc2->conn ) ? -1 : 0 );
|
||||
}
|
||||
|
||||
static void ravl_print( Avlnode *root, int depth )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( root == 0 )
|
||||
return;
|
||||
|
||||
ravl_print( root->avl_right, depth+1 );
|
||||
|
||||
for ( i = 0; i < depth; i++ )
|
||||
printf( " " );
|
||||
|
||||
printf( "c(%d) %d\n", ((struct ldapconn *) root->avl_data)->conn->c_connid, root->avl_bf );
|
||||
|
||||
ravl_print( root->avl_left, depth+1 );
|
||||
}
|
||||
|
||||
static void myprint( Avlnode *root )
|
||||
{
|
||||
printf( "********\n" );
|
||||
|
||||
if ( root == 0 )
|
||||
printf( "\tNULL\n" );
|
||||
|
||||
else
|
||||
ravl_print( root, 0 );
|
||||
|
||||
printf( "********\n" );
|
||||
}
|
||||
|
||||
struct ldapconn *
|
||||
ldap_back_getconn(struct ldapinfo *li, Connection *conn, Operation *op)
|
||||
{
|
||||
struct ldapconn *lc;
|
||||
struct ldapconn *lc, lc_curr;
|
||||
LDAP *ld;
|
||||
|
||||
/* Searches for a ldapconn in the avl tree */
|
||||
lc_curr.conn = conn;
|
||||
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
|
||||
for (lc = li->lcs; lc; lc=lc->next)
|
||||
if (lc->conn == conn)
|
||||
break;
|
||||
lc = (struct ldapconn *)avl_find( li->conntree,
|
||||
(caddr_t)&lc_curr, conn_cmp );
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
|
||||
/* Looks like we didn't get a bind. Open a new session... */
|
||||
if (!lc) {
|
||||
int vers = conn->c_protocol;
|
||||
int err = ldap_initialize(&ld, li->url);
|
||||
|
||||
if (err != LDAP_SUCCESS) {
|
||||
err = ldap_back_map_result(err);
|
||||
send_ldap_result( conn, op, err,
|
||||
@ -94,26 +186,65 @@ ldap_back_getconn(struct ldapinfo *li, Connection *conn, Operation *op)
|
||||
lc = (struct ldapconn *)ch_malloc(sizeof(struct ldapconn));
|
||||
lc->conn = conn;
|
||||
lc->ld = ld;
|
||||
if ( lc->conn->c_cdn != NULL && lc->conn->c_cdn[0] != '\0' ) {
|
||||
lc->bound_dn = ldap_back_dn_massage( li,
|
||||
ch_strdup( lc->conn->c_cdn ), 0 );
|
||||
} else {
|
||||
lc->bound_dn = NULL;
|
||||
}
|
||||
lc->bound = 0;
|
||||
|
||||
/* Inserts the newly created ldapconn in the avl tree */
|
||||
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
|
||||
lc->next = li->lcs;
|
||||
li->lcs = lc;
|
||||
err = avl_insert( &li->conntree, (caddr_t)lc,
|
||||
conn_cmp, conn_dup );
|
||||
|
||||
#if 1
|
||||
myprint( li->conntree );
|
||||
#endif
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=>ldap_back_getconn: conn %d inserted\n",
|
||||
lc->conn->c_connid, 0, 0 );
|
||||
|
||||
/* Err could be -1 in case a duplicate ldapconn is inserted */
|
||||
if ( err != 0 ) {
|
||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
||||
NULL, "internal server error", NULL, NULL );
|
||||
/* better destroy the ldapconn struct? */
|
||||
return( NULL );
|
||||
}
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=>ldap_back_getconn: conn %d fetched\n",
|
||||
lc->conn->c_connid, 0, 0 );
|
||||
}
|
||||
|
||||
return( lc );
|
||||
}
|
||||
|
||||
void
|
||||
/*
|
||||
* ldap_back_dobind
|
||||
*
|
||||
* Note: as the check for the value of lc->bound was already here, I removed
|
||||
* it from all the callers, and I made the function return the flag, so
|
||||
* it can be used to simplify the check.
|
||||
*/
|
||||
int
|
||||
ldap_back_dobind(struct ldapconn *lc, Operation *op)
|
||||
{
|
||||
if (lc->bound)
|
||||
return;
|
||||
if (lc->bound) {
|
||||
return( lc->bound );
|
||||
}
|
||||
|
||||
if (ldap_bind_s(lc->ld, lc->conn->c_cdn, NULL, LDAP_AUTH_SIMPLE) !=
|
||||
LDAP_SUCCESS)
|
||||
if (ldap_bind_s(lc->ld, lc->bound_dn, NULL, LDAP_AUTH_SIMPLE) !=
|
||||
LDAP_SUCCESS) {
|
||||
ldap_back_op_result(lc, op);
|
||||
else
|
||||
lc->bound = 1;
|
||||
return( 0 );
|
||||
} /* else */
|
||||
return( lc->bound = 1 );
|
||||
}
|
||||
|
||||
/* Map API errors to protocol errors... */
|
||||
@ -166,16 +297,17 @@ ldap_back_map_result(int err)
|
||||
int
|
||||
ldap_back_op_result(struct ldapconn *lc, Operation *op)
|
||||
{
|
||||
int err;
|
||||
char *msg;
|
||||
char *match;
|
||||
int err = LDAP_SUCCESS;
|
||||
char *msg = NULL;
|
||||
char *match = NULL;
|
||||
|
||||
ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &err);
|
||||
ldap_get_option(lc->ld, LDAP_OPT_ERROR_STRING, &msg);
|
||||
ldap_get_option(lc->ld, LDAP_OPT_MATCHED_DN, &match);
|
||||
err = ldap_back_map_result(err);
|
||||
send_ldap_result( lc->conn, op, err, match, msg, NULL, NULL );
|
||||
free(match);
|
||||
free(msg);
|
||||
/* better test the pointers before freeing? */
|
||||
if ( match ) free( match );
|
||||
if ( msg ) free( msg );
|
||||
return( (err==LDAP_SUCCESS) ? 0 : -1 );
|
||||
}
|
||||
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
@ -48,17 +57,21 @@ ldap_back_compare(
|
||||
{
|
||||
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
|
||||
struct ldapconn *lc;
|
||||
char *mdn;
|
||||
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if (!lc)
|
||||
if (!lc || !ldap_back_dobind( lc, op ) ) {
|
||||
return( -1 );
|
||||
|
||||
if (!lc->bound) {
|
||||
ldap_back_dobind(lc, op);
|
||||
if (!lc->bound)
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
ldap_compare_s( lc->ld, dn, ava->aa_desc->ad_cname->bv_val, ava->aa_value->bv_val );
|
||||
mdn = ldap_back_dn_massage( li, ch_strdup( dn ), 0 );
|
||||
if ( mdn == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ldap_compare_s( lc->ld, mdn, ava->aa_desc->ad_cname->bv_val, ava->aa_value->bv_val );
|
||||
|
||||
free( mdn );
|
||||
|
||||
return( ldap_back_op_result( lc, op ) );
|
||||
}
|
||||
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
@ -101,6 +110,49 @@ ldap_back_db_config(
|
||||
return( 1 );
|
||||
}
|
||||
li->bindpw = ch_strdup(argv[1]);
|
||||
|
||||
/* dn massaging */
|
||||
} else if ( strcasecmp( argv[0], "suffixmassage" ) == 0 ) {
|
||||
char *dn, *massaged_dn;
|
||||
BackendDB *tmp_be;
|
||||
|
||||
if ( argc != 3 ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: syntax is \"suffixMassage <suffix> <massaged suffix>\"\n",
|
||||
fname, lineno );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
tmp_be = select_backend( argv[1], 0 );
|
||||
if ( tmp_be != NULL && tmp_be != be ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: suffix already in use by another backend in"
|
||||
" \"suffixMassage <suffix> <massaged suffix>\"\n",
|
||||
fname, lineno );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
tmp_be = select_backend( argv[2], 0 );
|
||||
if ( tmp_be != NULL ) {
|
||||
fprintf( stderr,
|
||||
"%s: line %d: massaged suffix already in use by another backend in"
|
||||
" \"suffixMassage <suffix> <massaged suffix>\"\n",
|
||||
fname, lineno );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
dn = ch_strdup( argv[1] );
|
||||
charray_add( &li->suffix_massage, dn );
|
||||
(void) dn_normalize( dn );
|
||||
charray_add( &li->suffix_massage, dn );
|
||||
|
||||
massaged_dn = ch_strdup( argv[2] );
|
||||
charray_add( &li->suffix_massage, massaged_dn );
|
||||
(void) dn_normalize( massaged_dn );
|
||||
charray_add( &li->suffix_massage, massaged_dn );
|
||||
|
||||
free( dn );
|
||||
free( massaged_dn );
|
||||
|
||||
/* anything else */
|
||||
} else {
|
||||
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
@ -48,16 +57,22 @@ ldap_back_delete(
|
||||
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
|
||||
struct ldapconn *lc;
|
||||
|
||||
lc = ldap_back_getconn( li, conn, op );
|
||||
if (!lc)
|
||||
return( -1 );
|
||||
char *mdn;
|
||||
|
||||
if (!lc->bound) {
|
||||
ldap_back_dobind(lc, op);
|
||||
if (!lc->bound)
|
||||
return( -1 );
|
||||
lc = ldap_back_getconn( li, conn, op );
|
||||
|
||||
if ( !lc || !ldap_back_dobind( lc, op ) ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
ldap_delete_s( lc->ld, dn );
|
||||
mdn = ldap_back_dn_massage( li, ch_strdup( dn ), 0 );
|
||||
if ( mdn == NULL ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
ldap_delete_s( lc->ld, mdn );
|
||||
|
||||
free( mdn );
|
||||
|
||||
return( ldap_back_op_result( lc, op ) );
|
||||
}
|
||||
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
@ -103,6 +112,16 @@ ldap_back_db_init(
|
||||
return li == NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
conn_free(
|
||||
struct ldapconn *lc
|
||||
)
|
||||
{
|
||||
ldap_unbind(lc->ld);
|
||||
if ( lc->bound_dn) free( lc->bound_dn );
|
||||
free( lc );
|
||||
}
|
||||
|
||||
int
|
||||
ldap_back_db_destroy(
|
||||
Backend *be
|
||||
@ -112,6 +131,9 @@ ldap_back_db_destroy(
|
||||
|
||||
if (be->be_private) {
|
||||
li = (struct ldapinfo *)be->be_private;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
|
||||
|
||||
if (li->url) {
|
||||
free(li->url);
|
||||
li->url = NULL;
|
||||
@ -124,6 +146,15 @@ ldap_back_db_destroy(
|
||||
free(li->bindpw);
|
||||
li->bindpw = NULL;
|
||||
}
|
||||
if (li->suffix_massage) {
|
||||
ldap_value_free( li->suffix_massage );
|
||||
li->suffix_massage = NULL;
|
||||
}
|
||||
if (li->conntree) {
|
||||
avl_free( li->conntree, (AVL_FREE) conn_free );
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
ldap_pvt_thread_mutex_destroy( &li->conn_mutex );
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
@ -53,14 +62,16 @@ ldap_back_modify(
|
||||
Modifications *ml;
|
||||
int i;
|
||||
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if (!lc)
|
||||
return( -1 );
|
||||
char *mdn;
|
||||
|
||||
if (!lc->bound) {
|
||||
ldap_back_dobind(lc, op);
|
||||
if (!lc->bound)
|
||||
return( -1 );
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if ( !lc || !ldap_back_dobind( lc, op ) ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
mdn = ldap_back_dn_massage( li, ch_strdup( dn ), 0 );
|
||||
if ( mdn == NULL ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
for (i=0, ml=modlist; ml; i++,ml=ml->sml_next)
|
||||
@ -79,13 +90,16 @@ ldap_back_modify(
|
||||
|
||||
for (i=0, ml=modlist; ml; i++, ml=ml->sml_next) {
|
||||
modv[i] = &mods[i];
|
||||
mods[i].mod_op = ml->sml_op;
|
||||
mods[i].mod_op = ml->sml_op | LDAP_MOD_BVALUES;
|
||||
mods[i].mod_type = ml->sml_desc->ad_cname->bv_val;
|
||||
mods[i].mod_bvalues = ml->sml_bvalues;
|
||||
}
|
||||
|
||||
ldap_modify_s( lc->ld, dn, modv );
|
||||
free(mods);
|
||||
free(modv);
|
||||
|
||||
|
||||
ldap_modify_s( lc->ld, mdn, modv );
|
||||
free( mdn );
|
||||
free(mods);
|
||||
free(modv);
|
||||
return( ldap_back_op_result( lc, op ));
|
||||
}
|
||||
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
@ -51,21 +60,37 @@ ldap_back_modrdn(
|
||||
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
|
||||
struct ldapconn *lc;
|
||||
|
||||
char *mdn, *mnewSuperior;
|
||||
|
||||
lc = ldap_back_getconn( li, conn, op );
|
||||
if (!lc)
|
||||
if ( !lc ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if (newSuperior) {
|
||||
int version = LDAP_VERSION3;
|
||||
ldap_set_option( lc->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
|
||||
}
|
||||
|
||||
if (!lc->bound) {
|
||||
ldap_back_dobind(lc, op);
|
||||
if (!lc->bound)
|
||||
|
||||
mnewSuperior = ldap_back_dn_massage( li,
|
||||
ch_strdup( newSuperior ), 0 );
|
||||
if ( mnewSuperior == NULL ) {
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
ldap_rename2_s( lc->ld, dn, newrdn, newSuperior, deleteoldrdn );
|
||||
if ( !ldap_back_dobind(lc, op) ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
mdn = ldap_back_dn_massage( li, ch_strdup( dn ), 0 );
|
||||
if ( mdn == NULL ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
ldap_rename2_s( lc->ld, mdn, newrdn, mnewSuperior, deleteoldrdn );
|
||||
|
||||
free( mdn );
|
||||
if ( mnewSuperior ) free( mnewSuperior );
|
||||
|
||||
return( ldap_back_op_result( lc, op ) );
|
||||
}
|
||||
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
@ -64,9 +73,12 @@ ldap_back_search(
|
||||
int i, rc, msgid, sres = LDAP_SUCCESS;
|
||||
char *match = NULL, *err = NULL;
|
||||
|
||||
char *mbase;
|
||||
|
||||
lc = ldap_back_getconn(li, conn, op);
|
||||
if (!lc)
|
||||
if ( !lc ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if (deref != -1)
|
||||
ldap_set_option( lc->ld, LDAP_OPT_DEREF, (void *)&deref);
|
||||
@ -74,13 +86,17 @@ ldap_back_search(
|
||||
ldap_set_option( lc->ld, LDAP_OPT_TIMELIMIT, (void *)&time);
|
||||
if (size != -1)
|
||||
ldap_set_option( lc->ld, LDAP_OPT_SIZELIMIT, (void *)&size);
|
||||
if (!lc->bound) {
|
||||
ldap_back_dobind(lc, op);
|
||||
if (!lc->bound)
|
||||
return( -1 );
|
||||
|
||||
if ( !ldap_back_dobind( lc, op ) ) {
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if ((msgid = ldap_search(lc->ld, base, scope, filterstr, attrs,
|
||||
mbase = ldap_back_dn_massage( li, ch_strdup( base ), 0 );
|
||||
if ( mbase == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((msgid = ldap_search(lc->ld, mbase, scope, filterstr, attrs,
|
||||
attrsonly)) == -1)
|
||||
fail: return( ldap_back_op_result(lc, op) );
|
||||
|
||||
@ -132,6 +148,8 @@ fail: return( ldap_back_op_result(lc, op) );
|
||||
free(match);
|
||||
if (err)
|
||||
free(err);
|
||||
if (mbase)
|
||||
free(mbase);
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@ -145,6 +163,7 @@ ldap_send_entry(
|
||||
int attrsonly
|
||||
)
|
||||
{
|
||||
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
|
||||
char *a;
|
||||
Entry ent;
|
||||
BerElement *ber = NULL;
|
||||
@ -152,8 +171,8 @@ ldap_send_entry(
|
||||
struct berval *dummy = NULL;
|
||||
const char *text;
|
||||
|
||||
ent.e_dn = ldap_get_dn(lc->ld, e);
|
||||
ent.e_ndn = ch_strdup( ent.e_dn);
|
||||
ent.e_dn = ldap_back_dn_restore( li, ldap_get_dn(lc->ld, e), 0 );
|
||||
ent.e_ndn = ch_strdup( ent.e_dn );
|
||||
(void) dn_normalize( ent.e_ndn );
|
||||
ent.e_id = 0;
|
||||
ent.e_attrs = 0;
|
||||
@ -187,4 +206,9 @@ ldap_send_entry(
|
||||
}
|
||||
if (ber)
|
||||
ber_free(ber,0);
|
||||
|
||||
if ( ent.e_dn )
|
||||
free( ent.e_dn );
|
||||
if ( ent.e_ndn )
|
||||
free( ent.e_ndn );
|
||||
}
|
||||
|
157
servers/slapd/back-ldap/suffixmassage.c
Normal file
157
servers/slapd/back-ldap/suffixmassage.c
Normal file
@ -0,0 +1,157 @@
|
||||
/* suffixmassage.c - massages ldap backend dns */
|
||||
/* $OpenLDAP$ */
|
||||
|
||||
/*
|
||||
* Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* Module back-ldap, originally developed by Howard Chu
|
||||
*
|
||||
* has been modified by Pierangelo Masarati. The original copyright
|
||||
* notice has been maintained.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose
|
||||
* on any computer system, and to alter it and redistribute it, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. The author is not responsible for the consequences of use of this
|
||||
* software, no matter how awful, even if they arise from flaws in it.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Since few users ever read sources,
|
||||
* credits should appear in the documentation.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software. Since few users
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/socket.h>
|
||||
|
||||
#include "slap.h"
|
||||
#include "back-ldap.h"
|
||||
|
||||
/*
|
||||
* ldap_back_dn_massage
|
||||
*
|
||||
* Aliases the suffix; based on suffix_alias (servers/slapd/suffixalias.c).
|
||||
*/
|
||||
char *
|
||||
ldap_back_dn_massage(
|
||||
struct ldapinfo *li,
|
||||
char *dn,
|
||||
int normalized
|
||||
)
|
||||
{
|
||||
int i, dnLength;
|
||||
|
||||
if ( dn == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
if ( li == NULL ) {
|
||||
return dn;
|
||||
}
|
||||
|
||||
dnLength = strlen ( dn );
|
||||
|
||||
for ( i = 0;
|
||||
li->suffix_massage != NULL && li->suffix_massage[i] != NULL;
|
||||
i += 4 ) {
|
||||
int aliasLength = strlen( li->suffix_massage[i+normalized] );
|
||||
int diff = dnLength - aliasLength;
|
||||
|
||||
if ( diff < 0 ) {
|
||||
/* alias is longer than dn */
|
||||
continue;
|
||||
} else if ( diff > 0 ) {
|
||||
if ( normalized && ( ! DN_SEPARATOR(dn[diff-1]) ) ) {
|
||||
/* boundary is not at a DN separator */
|
||||
continue;
|
||||
}
|
||||
/* At a DN Separator */
|
||||
/* XXX or an escaped separator... oh well */
|
||||
}
|
||||
|
||||
if ( !strcmp( li->suffix_massage[i+normalized], &dn[diff] ) ) {
|
||||
char *oldDN = dn;
|
||||
dn = ch_malloc( diff + strlen( li->suffix_massage[i+2+normalized] ) + 1 );
|
||||
strncpy( dn, oldDN, diff );
|
||||
strcpy( &dn[diff], li->suffix_massage[i+2+normalized] );
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"ldap_back_dn_massage:"
|
||||
" converted \"%s\" to \"%s\"\n",
|
||||
oldDN, dn, 0 );
|
||||
free( oldDN );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dn;
|
||||
}
|
||||
|
||||
/*
|
||||
* ldap_back_dn_restore
|
||||
*
|
||||
* Restores the original suffix;
|
||||
* based on suffix_alias (servers/slapd/suffixalias.c).
|
||||
*/
|
||||
char *
|
||||
ldap_back_dn_restore(
|
||||
struct ldapinfo *li,
|
||||
char *dn,
|
||||
int normalized
|
||||
)
|
||||
{
|
||||
int i, dnLength;
|
||||
|
||||
if ( dn == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
if ( li == NULL ) {
|
||||
return dn;
|
||||
}
|
||||
|
||||
dnLength = strlen ( dn );
|
||||
|
||||
for ( i = 0;
|
||||
li->suffix_massage != NULL && li->suffix_massage[i] != NULL;
|
||||
i += 4 ) {
|
||||
int aliasLength = strlen( li->suffix_massage[i+2+normalized] );
|
||||
int diff = dnLength - aliasLength;
|
||||
|
||||
if ( diff < 0 ) {
|
||||
/* alias is longer than dn */
|
||||
continue;
|
||||
|
||||
} else if ( diff > 0 ) {
|
||||
if ( normalized && ( ! DN_SEPARATOR(dn[diff-1]) ) ) {
|
||||
/* boundary is not at a DN separator */
|
||||
continue;
|
||||
}
|
||||
/* At a DN Separator */
|
||||
/* XXX or an escaped separator... oh well */
|
||||
}
|
||||
|
||||
if ( !strcmp( li->suffix_massage[i+2+normalized], &dn[diff] ) ) {
|
||||
char *oldDN = dn;
|
||||
dn = ch_malloc( diff + strlen( li->suffix_massage[i+normalized] ) + 1 );
|
||||
strncpy( dn, oldDN, diff );
|
||||
strcpy( &dn[diff], li->suffix_massage[i+normalized] );
|
||||
Debug( LDAP_DEBUG_ARGS,
|
||||
"ldap_back_dn_restore:"
|
||||
" converted \"%s\" to \"%s\"\n",
|
||||
oldDN, dn, 0 );
|
||||
free( oldDN );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dn;
|
||||
}
|
||||
|
@ -24,6 +24,15 @@
|
||||
* ever read sources, credits should appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
|
||||
*
|
||||
* This software is being modified by Pierangelo Masarati.
|
||||
* The previously reported conditions apply to the modified code as well.
|
||||
* Changes in the original code are highlighted where required.
|
||||
* Credits for the original code go to the author, Howard Chu.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
@ -43,20 +52,34 @@ ldap_back_conn_destroy(
|
||||
)
|
||||
{
|
||||
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
|
||||
struct ldapconn *lc, *lp;
|
||||
struct ldapconn *lc, lc_curr;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=>ldap_back_conn_destroy: fetching conn %d\n",
|
||||
conn->c_connid, 0, 0 );
|
||||
|
||||
|
||||
lc_curr.conn = conn;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
|
||||
for (lc = li->lcs, lp = (struct ldapconn *)&li->lcs; lc;
|
||||
lp=lc, lc=lc->next)
|
||||
if (lc->conn == conn) {
|
||||
lp->next = lc->next;
|
||||
break;
|
||||
}
|
||||
lc = avl_delete( &li->conntree, (caddr_t)&lc_curr, conn_cmp );
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
|
||||
if (lc) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=>ldap_back_conn_destroy: destroying conn %d\n",
|
||||
lc->conn->c_connid, 0, 0 );
|
||||
|
||||
/*
|
||||
* Needs a test because the handler may be corrupted,
|
||||
* and calling ldap_unbind on a corrupted header results
|
||||
* in a segmentation fault
|
||||
*/
|
||||
ldap_unbind(lc->ld);
|
||||
free(lc);
|
||||
if ( lc->bound_dn ) {
|
||||
free( lc->bound_dn );
|
||||
}
|
||||
free( lc );
|
||||
}
|
||||
|
||||
/* no response to unbind */
|
||||
|
Loading…
Reference in New Issue
Block a user