Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joe Martin
OpenLDAP
Commits
78ebd3d9
Commit
78ebd3d9
authored
Jul 16, 1999
by
Kurt Zeilenga
Browse files
Integrate LDBM changes into BDB2...
parent
6f72de8c
Changes
11
Hide whitespace changes
Inline
Side-by-side
servers/slapd/back-bdb2/add.c
View file @
78ebd3d9
...
...
@@ -32,7 +32,8 @@ bdb2i_back_add_internal(
if
(
(
bdb2i_dn2id
(
be
,
e
->
e_ndn
)
)
!=
NOID
)
{
entry_free
(
e
);
send_ldap_result
(
conn
,
op
,
LDAP_ALREADY_EXISTS
,
NULL
,
NULL
,
NULL
);
send_ldap_result
(
conn
,
op
,
LDAP_ALREADY_EXISTS
,
NULL
,
NULL
,
NULL
,
NULL
);
return
(
-
1
);
}
...
...
@@ -42,7 +43,7 @@ bdb2i_back_add_internal(
entry_free
(
e
);
send_ldap_result
(
conn
,
op
,
LDAP_OBJECT_CLASS_VIOLATION
,
NULL
,
NULL
,
NULL
);
NULL
,
NULL
,
NULL
,
NULL
);
return
(
-
1
);
}
...
...
@@ -55,19 +56,37 @@ bdb2i_back_add_internal(
pdn
=
dn_parent
(
be
,
e
->
e_ndn
);
if
(
pdn
!=
NULL
&&
*
pdn
!=
'\0'
&&
!
be_issuffix
(
be
,
""
)
)
{
char
*
matched
=
NULL
;
Entry
*
matched
=
NULL
;
assert
(
*
pdn
!=
'\0'
);
/* get parent with writer lock */
if
(
(
p
=
bdb2i_dn2entry_w
(
be
,
pdn
,
&
matched
))
==
NULL
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"parent does not exist
\n
"
,
0
,
0
,
0
);
char
*
matched_dn
;
struct
berval
**
refs
;
if
(
matched
!=
NULL
)
{
matched_dn
=
ch_strdup
(
matched
->
e_dn
);
refs
=
is_entry_referral
(
matched
)
?
get_entry_referrals
(
be
,
conn
,
op
,
matched
)
:
NULL
;
bdb2i_cache_return_entry_w
(
&
li
->
li_cache
,
matched
);
}
else
{
matched_dn
=
NULL
;
refs
=
default_referral
;
}
Debug
(
LDAP_DEBUG_TRACE
,
"parent does not exist
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_NO_SUCH_OBJECT
,
matched
,
NULL
,
NULL
);
matched
_dn
,
NULL
,
NULL
,
NULL
);
if
(
matched
!=
NULL
)
{
free
(
matched
);
ber_bvecfree
(
refs
);
free
(
matched_dn
);
}
entry_free
(
e
);
...
...
@@ -77,21 +96,54 @@ bdb2i_back_add_internal(
free
(
pdn
);
if
(
matched
!=
NULL
)
{
free
(
matched
);
}
if
(
!
access_allowed
(
be
,
conn
,
op
,
p
,
"children"
,
NULL
,
ACL_WRITE
)
)
{
/* free parent and writer lock */
bdb2i_cache_return_entry_w
(
&
li
->
li_cache
,
p
);
Debug
(
LDAP_DEBUG_TRACE
,
"no access to parent
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_INSUFFICIENT_ACCESS
,
NULL
,
NULL
,
NULL
);
NULL
,
NULL
,
NULL
,
NULL
);
entry_free
(
e
);
return
-
1
;
}
if
(
is_entry_alias
(
p
)
)
{
/* parent is an alias, don't allow add */
/* free parent and writer lock */
bdb2i_cache_return_entry_w
(
&
li
->
li_cache
,
p
);
Debug
(
LDAP_DEBUG_TRACE
,
"parent is alias
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_ALIAS_PROBLEM
,
NULL
,
NULL
,
NULL
,
NULL
);
entry_free
(
e
);
return
-
1
;
}
if
(
is_entry_referral
(
p
)
)
{
/* parent is an referral, don't allow add */
char
*
matched_dn
=
ch_strdup
(
matched
->
e_dn
);
struct
berval
**
refs
=
is_entry_referral
(
matched
)
?
get_entry_referrals
(
be
,
conn
,
op
,
matched
)
:
NULL
;
/* free parent and writer lock */
bdb2i_cache_return_entry_w
(
&
li
->
li_cache
,
p
);
Debug
(
LDAP_DEBUG_TRACE
,
"parent is referral
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_REFERRAL
,
matched_dn
,
NULL
,
refs
,
NULL
);
ber_bvecfree
(
refs
);
free
(
matched_dn
);
entry_free
(
e
);
return
-
1
;
}
...
...
@@ -109,7 +161,7 @@ bdb2i_back_add_internal(
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_INSUFFICIENT_ACCESS
,
NULL
,
NULL
,
NULL
);
NULL
,
NULL
,
NULL
,
NULL
);
entry_free
(
e
);
return
-
1
;
...
...
@@ -142,11 +194,9 @@ bdb2i_back_add_internal(
/* free the entry */
entry_free
(
e
);
if
(
rc
>
0
)
{
send_ldap_result
(
conn
,
op
,
LDAP_ALREADY_EXISTS
,
NULL
,
NULL
,
NULL
);
}
else
{
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
);
}
send_ldap_result
(
conn
,
op
,
rc
>
0
?
LDAP_ALREADY_EXISTS
:
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
,
NULL
);
return
(
-
1
);
}
...
...
@@ -162,7 +212,8 @@ bdb2i_back_add_internal(
if
(
bdb2i_id2children_add
(
be
,
p
,
e
)
!=
0
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"bdb2i_id2children_add failed
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
,
NULL
);
bdb2i_stop_timing
(
be
->
bd_info
,
time1
,
"ADD-ID2CHILDREN"
,
conn
,
op
);
...
...
@@ -182,7 +233,8 @@ bdb2i_back_add_internal(
if
(
bdb2i_index_add_entry
(
be
,
e
)
!=
0
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"bdb2i_index_add_entry failed
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
,
NULL
);
bdb2i_stop_timing
(
be
->
bd_info
,
time1
,
"ADD-INDEX"
,
conn
,
op
);
...
...
@@ -197,7 +249,8 @@ bdb2i_back_add_internal(
if
(
bdb2i_dn2id_add
(
be
,
e
->
e_ndn
,
e
->
e_id
)
!=
0
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"bdb2i_dn2id_add failed
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
,
NULL
);
bdb2i_stop_timing
(
be
->
bd_info
,
time1
,
"ADD-DN2ID"
,
conn
,
op
);
...
...
@@ -213,7 +266,8 @@ bdb2i_back_add_internal(
Debug
(
LDAP_DEBUG_TRACE
,
"bdb2i_id2entry_add failed
\n
"
,
0
,
0
,
0
);
(
void
)
bdb2i_dn2id_delete
(
be
,
e
->
e_ndn
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
,
NULL
);
bdb2i_stop_timing
(
be
->
bd_info
,
time1
,
"ADD-ID2ENTRY"
,
conn
,
op
);
...
...
@@ -222,7 +276,8 @@ bdb2i_back_add_internal(
bdb2i_stop_timing
(
be
->
bd_info
,
time1
,
"ADD-ID2ENTRY"
,
conn
,
op
);
send_ldap_result
(
conn
,
op
,
LDAP_SUCCESS
,
NULL
,
NULL
,
NULL
);
send_ldap_result
(
conn
,
op
,
LDAP_SUCCESS
,
NULL
,
NULL
,
NULL
,
NULL
);
rc
=
0
;
return_results:
;
...
...
@@ -255,10 +310,9 @@ bdb2_back_add(
bdb2i_start_timing
(
be
->
bd_info
,
&
time1
);
if
(
bdb2i_enter_backend_w
(
&
lock
)
!=
0
)
{
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
NULL
,
NULL
,
NULL
,
NULL
);
return
(
-
1
);
}
/* check, if a new default attribute index will be created,
...
...
servers/slapd/back-bdb2/alias.c
View file @
78ebd3d9
/*
* Copyright (c) 1998 Will Ballantyne, ITSD, Government of BC
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to ITSD, Government of BC. The name of ITSD
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include
"portable.h"
...
...
@@ -19,302 +12,273 @@
#include
"back-bdb2.h"
#include
"proto-back-bdb2.h"
/*
* given an alias object, dereference it to its end point.
* Entry returned has reader lock or is NULL. Starting entry is not released.
*/
Entry
*
bdb2i_derefAlias_r
(
BackendDB
*
be
,
Connection
*
conn
,
Operation
*
op
,
Entry
*
e
)
static
char
*
get_alias_dn
(
Entry
*
e
,
int
*
err
,
char
**
errmsg
);
static
char
*
new_superior
(
char
*
dn
,
char
*
oldSup
,
char
*
newSup
);
static
int
dnlist_subordinate
(
char
**
dnlist
,
char
*
dn
);
Entry
*
bdb2i_deref_r
(
Backend
*
be
,
Entry
*
alias
,
char
*
dn
,
int
*
err
,
Entry
**
matched
,
char
**
text
)
{
/* to free cache entries */
struct
ldbminfo
*
li
=
(
struct
ldbminfo
*
)
be
->
be_private
;
Attribute
*
a
;
int
depth
;
char
*
matched
;
Entry
*
origDN
=
e
;
if
(
!
e
)
return
NULL
;
/* be sure we have a starting entry */
Debug
(
LDAP_DEBUG_TRACE
,
"<= checking for alias for dn %s
\n
"
,
e
->
e_dn
,
0
,
0
);
/*
* try to deref fully, up to a maximum depth. If the max depth exceeded
* then send an error
*/
for
(
depth
=
0
;
(
(
a
=
attr_find
(
e
->
e_attrs
,
"aliasedobjectname"
)
)
!=
NULL
)
&&
(
depth
<
be
->
be_maxDerefDepth
);
++
depth
)
{
/*
* make sure there is a defined aliasedobjectname.
* can only have one value so just use first value (0) in the attr list.
*/
if
(
a
->
a_vals
[
0
]
&&
a
->
a_vals
[
0
]
->
bv_val
)
{
char
*
newDN
,
*
oldDN
;
Debug
(
LDAP_DEBUG_TRACE
,
"<= %s is an alias for %s
\n
"
,
e
->
e_dn
,
a
->
a_vals
[
0
]
->
bv_val
,
0
);
newDN
=
ch_strdup
(
a
->
a_vals
[
0
]
->
bv_val
);
oldDN
=
ch_strdup
(
e
->
e_ndn
);
/*
* release past lock if not original
*/
if
(
(
depth
>
0
)
&&
e
)
{
bdb2i_cache_return_entry_r
(
&
li
->
li_cache
,
e
);
}
/* make sure new and old DN are not same to avoid loops */
dn_normalize_case
(
newDN
);
if
(
strcmp
(
newDN
,
oldDN
)
==
0
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"<= %s alias is same as current %s
\n
"
,
oldDN
,
newDN
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_ALIAS_DEREF_PROBLEM
,
NULL
,
"circular alias"
,
NULL
);
free
(
newDN
);
free
(
oldDN
);
break
;
}
/* make sure new and original are not same to avoid deadlocks */
if
(
strcmp
(
newDN
,
origDN
->
e_ndn
)
==
0
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"<= %s alias is same as original %s
\n
"
,
oldDN
,
origDN
->
e_ndn
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_ALIAS_DEREF_PROBLEM
,
NULL
,
"circular alias"
,
NULL
);
free
(
newDN
);
free
(
oldDN
);
break
;
}
/*
* ok, so what happens if there is an alias in the DN of a dereferenced
* alias object?
*/
if
(
(
e
=
bdb2i_dn2entry_r
(
be
,
newDN
,
&
matched
))
==
NULL
)
{
/* could not deref return error */
Debug
(
LDAP_DEBUG_TRACE
,
"<= %s is a dangling alias to %s
\n
"
,
oldDN
,
newDN
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_ALIAS_DEREF_PROBLEM
,
NULL
,
"dangling alias"
,
NULL
);
if
(
matched
!=
NULL
)
free
(
matched
);
free
(
newDN
);
free
(
oldDN
);
break
;
}
free
(
newDN
);
free
(
oldDN
);
}
else
{
/*
* there was an aliasedobjectname defined but no data.
* this can't happen, right?
*/
Debug
(
LDAP_DEBUG_TRACE
,
"<= %s has no data in aliasedobjectname attribute
\n
"
,
(
e
&&
e
->
e_dn
)
?
e
->
e_dn
:
"(null)"
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_ALIAS_PROBLEM
,
NULL
,
"alias missing aliasedObjectname"
,
NULL
);
break
;
}
}
/*
* warn if we pulled out due to exceeding the maximum deref depth
*/
if
(
depth
>=
be
->
be_maxDerefDepth
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"<= deref(
\"
%s
\"
) exceeded maximum deref depth (%d) at
\"
%s
\"\n
"
,
origDN
->
e_dn
?
origDN
->
e_dn
:
"(null)"
,
be
->
be_maxDerefDepth
,
(
e
&&
e
->
e_ndn
)
?
e
->
e_ndn
:
"(null)"
);
send_ldap_result
(
conn
,
op
,
LDAP_ALIAS_DEREF_PROBLEM
,
NULL
,
"maximum alias dereference depth exceeded"
,
NULL
);
}
return
e
;
struct
ldbminfo
*
li
=
(
struct
ldbminfo
*
)
be
->
be_private
;
Entry
*
entry
;
Entry
*
sup
;
unsigned
depth
;
char
**
dnlist
;
assert
(
(
alias
!=
NULL
&&
dn
==
NULL
)
||
(
alias
==
NULL
&&
dn
!=
NULL
)
);
*
matched
=
NULL
;
*
err
=
LDAP_SUCCESS
;
*
text
=
NULL
;
if
(
alias
==
NULL
)
{
dn
=
ch_strdup
(
dn
);
entry
=
bdb2i_dn2entry_r
(
be
,
dn
,
&
sup
);
}
else
{
dn
=
ch_strdup
(
alias
->
e_ndn
);
entry
=
alias
;
sup
=
NULL
;
}
dnlist
=
NULL
;
charray_add
(
&
dnlist
,
dn
);
for
(
depth
=
0
;
;
depth
++
)
{
if
(
entry
!=
NULL
)
{
Entry
*
newe
;
char
*
aliasDN
;
/* have entry, may be an alias */
if
(
!
is_entry_alias
(
entry
)
)
{
/* entry is not an alias */
break
;
}
/* entry is alias */
if
(
depth
>
be
->
be_max_deref_depth
)
{
*
matched
=
entry
;
entry
=
NULL
;
*
err
=
LDAP_ALIAS_DEREF_PROBLEM
;
*
text
=
"maximum deref depth exceeded"
;
break
;
}
/* deref entry */
aliasDN
=
get_alias_dn
(
entry
,
err
,
text
);
if
(
aliasDN
==
NULL
)
{
*
matched
=
entry
;
entry
=
NULL
;
break
;
}
/* check if aliasDN is a subordinate of any DN in our list */
if
(
dnlist_subordinate
(
dnlist
,
aliasDN
)
)
{
*
matched
=
entry
;
entry
=
NULL
;
*
err
=
LDAP_ALIAS_PROBLEM
;
*
text
=
"circular alias"
;
break
;
}
/* attempt to dereference alias */
newe
=
bdb2i_dn2entry_r
(
be
,
aliasDN
,
&
sup
);
if
(
newe
!=
NULL
)
{
free
(
dn
);
bdb2i_cache_return_entry_r
(
&
li
->
li_cache
,
entry
);
entry
=
newe
;
dn
=
ch_strdup
(
entry
->
e_ndn
);
charray_add
(
&
dnlist
,
dn
);
continue
;
}
if
(
sup
!=
NULL
)
{
bdb2i_cache_return_entry_r
(
&
li
->
li_cache
,
entry
);
entry
=
NULL
;
continue
;
}
/* no newe and no superior, we're done */
break
;
}
else
if
(
sup
!=
NULL
)
{
/* have superior, may be an alias */
Entry
*
newe
;
Entry
*
newSup
;
char
*
supDN
;
char
*
aliasDN
;
if
(
!
is_entry_alias
(
sup
)
)
{
/* entry is not an alias */
*
matched
=
sup
;
sup
=
NULL
;
break
;
}
/* entry is alias */
if
(
depth
>
be
->
be_max_deref_depth
)
{
*
matched
=
sup
;
entry
=
NULL
;
*
err
=
LDAP_ALIAS_DEREF_PROBLEM
;
*
text
=
"maximum deref depth exceeded"
;
break
;
}
/* deref entry */
supDN
=
get_alias_dn
(
sup
,
err
,
text
);
if
(
supDN
==
NULL
)
{
*
matched
=
sup
;
break
;
}
aliasDN
=
new_superior
(
dn
,
sup
->
e_ndn
,
supDN
);
if
(
aliasDN
==
NULL
)
{
free
(
aliasDN
);
*
matched
=
sup
;
*
err
=
LDAP_ALIAS_PROBLEM
;
*
text
=
"superior alias problem"
;
break
;
}
/* check if aliasDN is a subordinate of any DN in our list */
if
(
dnlist_subordinate
(
dnlist
,
aliasDN
)
)
{
free
(
aliasDN
);
*
matched
=
entry
;
entry
=
NULL
;
*
err
=
LDAP_ALIAS_PROBLEM
;
*
text
=
"subordinate circular alias"
;
break
;
}
/* attempt to dereference alias */
newe
=
bdb2i_dn2entry_r
(
be
,
aliasDN
,
&
newSup
);
if
(
newe
!=
NULL
)
{
free
(
aliasDN
);
free
(
dn
);
bdb2i_cache_return_entry_r
(
&
li
->
li_cache
,
sup
);
entry
=
newe
;
dn
=
ch_strdup
(
entry
->
e_ndn
);
charray_add
(
&
dnlist
,
dn
);
continue
;
}
if
(
newSup
!=
NULL
)
{
free
(
dn
);
bdb2i_cache_return_entry_r
(
&
li
->
li_cache
,
sup
);
sup
=
newSup
;
dn
=
aliasDN
;
continue
;
}
break
;
}
else
{
/* no newe and no superior, we're done */
break
;
}
}
free
(
dn
);
return
entry
;
}
/*
* given a DN fully deref it and return the real DN or original DN if it fails
* This involves finding the last matched part then reconstructing forward
* e.g.
* ou=MyOU,o=MyAliasedOrg,c=MyCountry where o=MyAliasedOrg is an alias for o=MyOrg
* loop starts with newDN = ou=MyOU,o=MyAliasedOrg,c=MyCountry
* dn2entry_r on newDN gives null entry and o=MyAliasedOrg,c=MyCountry matched
* dn2entry_r on matched gives o=MyAliasedOrg,c=MyCountry entry
* remainder is ou=MyOU
* dereferencing o=MyAliasedOrg,c=MyCountry yields entry o=MyOrg,c=MyCountry
* release lock on o=MyAliasedOrg,c=MyCountry entry
* reconstructed dn is ou=MyOU,o=MyOrg,c=MyCountry
* release lock on o=MyOrg,c=MyCountry entry
*/
char
*
bdb2i_derefDN
(
BackendDB
*
be
,
Connection
*
conn
,
Operation
*
op
,
char
*
dn
)
{
struct
ldbminfo
*
li
=
(
struct
ldbminfo
*
)
be
->
be_private
;
char
*
matched
=
0
;
char
*
newDN
=
NULL
;
int
depth
,
i
;
Entry
*
eMatched
;
Entry
*
eDeref
;
Entry
*
eNew
;
if
(
!
dn
)
return
NULL
;
Debug
(
LDAP_DEBUG_TRACE
,
"<= dereferencing dn:
\"
%s
\"\n
"
,
dn
,
0
,
0
);
newDN
=
ch_strdup
(
dn
);
/* while we don't have a matched dn, deref the DN */
for
(
depth
=
0
;
(
(
eMatched
=
bdb2i_dn2entry_r
(
be
,
newDN
,
&
matched
))
==
NULL
)
&&
(
depth
<
be
->
be_maxDerefDepth
);
++
depth
)
{
if
((
matched
!=
NULL
)
&&
*
matched
)
{
char
*
submatch
;
/*
* make sure there actually is an entry for the matched part
*/
if
(
(
eMatched
=
bdb2i_dn2entry_r
(
be
,
matched
,
&
submatch
))
!=
NULL
)
{
char
*
remainder
;
/* part before the aliased part */
int
rlen
=
strlen
(
newDN
)
-
strlen
(
matched
);
Debug
(
LDAP_DEBUG_TRACE
,
"<= matched %s
\n
"
,
matched
,
0
,
0
);
remainder
=
ch_malloc
(
rlen
+
1
);
strncpy
(
remainder
,
newDN
,
rlen
);
remainder
[
rlen
]
=
'\0'
;
Debug
(
LDAP_DEBUG_TRACE
,
"<= remainder %s
\n
"
,
remainder
,
0
,
0
);
if
((
eNew
=
bdb2i_derefAlias_r
(
be
,
conn
,
op
,
eMatched
))
==
NULL
)
{
free
(
matched
);
matched
=
NULL
;
free
(
newDN
);
newDN
=
NULL
;
free
(
remainder
);
remainder
=
NULL
;
bdb2i_cache_return_entry_r
(
&
li
->
li_cache
,
eMatched
);
eMatched
=
NULL
;
break
;
/* no associated entry, dont deref */
static
char
*
get_alias_dn
(
Entry
*
e
,
int
*
err
,