Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Nadezhda Ivanova
OpenLDAP
Commits
4a5d740e
Commit
4a5d740e
authored
Sep 20, 1998
by
Kurt Zeilenga
Browse files
Merged in per cache entry reader/writer locks from OPENLDAP_DEVEL_THREAD
parent
4caf68cf
Changes
24
Hide whitespace changes
Inline
Side-by-side
Make-common.dist
View file @
4a5d740e
...
...
@@ -205,8 +205,8 @@ LDBMLIB?=
# -DTHREAD_SUNOS4_LWP
# -DTHREAD_SUNOS5_LWP
# and select the appropriate library.
#
THREADS?=-DNO_THREADS
#
THREADSLIB?=
THREADS?=-DNO_THREADS
THREADSLIB?=
# Locations of auxilary programs
# (excepts to below are generally defined in Make-platform)
...
...
libraries/liblthread/rdwr.c
View file @
4a5d740e
...
...
@@ -109,4 +109,4 @@ int pthread_rdwr_rwchk_np(pthread_rdwr_t *rdwrp)
return
(
pthread_rdwr_rchk_np
(
rdwrp
)
||
pthread_rdwr_wchk_np
(
rdwrp
));
}
#endif LDAP_DEBUG
#endif
/*
LDAP_DEBUG
*/
servers/slapd/acl.c
View file @
4a5d740e
...
...
@@ -25,7 +25,6 @@ static int regex_matches();
static
string_expand
(
char
*
newbuf
,
int
bufsiz
,
char
*
pattern
,
char
*
match
,
regmatch_t
*
matches
);
extern
Entry
*
be_dn2entry
(
Backend
*
be
,
char
*
bdn
,
char
**
matched
);
/*
* access_allowed - check whether dn is allowed the requested access
...
...
@@ -549,7 +548,7 @@ regex_matches(
char
error
[
512
];
regerror
(
rc
,
&
re
,
error
,
sizeof
(
error
));
Debug
(
LDAP_DEBUG_
ANY
,
Debug
(
LDAP_DEBUG_
TRACE
,
"compile(
\"
%s
\"
,
\"
%s
\"
) failed %s
\n
"
,
pat
,
str
,
error
);
return
(
0
);
...
...
servers/slapd/add.c
View file @
4a5d740e
...
...
@@ -53,6 +53,8 @@ do_add( conn, op )
*/
e
=
(
Entry
*
)
ch_calloc
(
1
,
sizeof
(
Entry
)
);
/* initialize reader/writer lock */
entry_rdwr_init
(
e
);
/* get the name */
if
(
ber_scanf
(
ber
,
"{a"
,
&
dn
)
==
LBER_ERROR
)
{
...
...
servers/slapd/back-ldbm/add.c
View file @
4a5d740e
...
...
@@ -6,11 +6,11 @@
#include
<sys/socket.h>
#include
"slap.h"
#include
"back-ldbm.h"
#include
"proto-back-ldbm.h"
extern
int
global_schemacheck
;
extern
char
*
dn_parent
();
extern
char
*
dn_normalize
();
extern
Entry
*
dn2entry
();
int
ldbm_back_add
(
...
...
@@ -21,27 +21,30 @@ ldbm_back_add(
)
{
struct
ldbminfo
*
li
=
(
struct
ldbminfo
*
)
be
->
be_private
;
char
*
matched
;
char
*
dn
=
NULL
,
*
pdn
=
NULL
;
Entry
*
p
;
Entry
*
p
=
NULL
;
int
rc
;
dn
=
dn_normalize
(
strdup
(
e
->
e_dn
)
);
matched
=
NULL
;
if
(
(
p
=
dn2entry
(
be
,
dn
,
&
matched
))
!=
NULL
)
{
cache_return_entry
(
&
li
->
li_cache
,
p
);
Debug
(
LDAP_DEBUG_ARGS
,
"==> ldbm_back_add: %s
\n
"
,
dn
,
0
,
0
);
if
(
(
dn2id
(
be
,
dn
)
)
!=
NOID
)
{
entry_free
(
e
);
free
(
dn
);
send_ldap_result
(
conn
,
op
,
LDAP_ALREADY_EXISTS
,
""
,
""
);
return
(
-
1
);
}
if
(
matched
!=
NULL
)
{
free
(
matched
);
}
/* XXX race condition here til we cache_add_entry_lock below XXX */
if
(
global_schemacheck
&&
oc_schema_check
(
e
)
!=
0
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"entry failed schema check
\n
"
,
0
,
0
,
0
);
Debug
(
LDAP_DEBUG_TRACE
,
"entry failed schema check
\n
"
,
0
,
0
,
0
);
/* XXX this should be ok, no other thread should have access
* because e hasn't been added to the cache yet
*/
entry_free
(
e
);
free
(
dn
);
send_ldap_result
(
conn
,
op
,
LDAP_OBJECT_CLASS_VIOLATION
,
""
,
...
...
@@ -61,6 +64,10 @@ ldbm_back_add(
Debug
(
LDAP_DEBUG_ANY
,
"cache_add_entry_lock failed
\n
"
,
0
,
0
,
0
);
next_id_return
(
be
,
e
->
e_id
);
/* XXX this should be ok, no other thread should have access
* because e hasn't been added to the cache yet
*/
entry_free
(
e
);
free
(
dn
);
send_ldap_result
(
conn
,
op
,
LDAP_ALREADY_EXISTS
,
""
,
""
);
...
...
@@ -74,17 +81,22 @@ ldbm_back_add(
*/
if
(
(
pdn
=
dn_parent
(
be
,
dn
))
!=
NULL
)
{
char
*
matched
;
/* no parent */
matched
=
NULL
;
if
(
(
p
=
dn2entry
(
be
,
pdn
,
&
matched
))
==
NULL
)
{
/* get entry with reader lock */
if
(
(
p
=
dn2entry_r
(
be
,
pdn
,
&
matched
))
==
NULL
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"parent does not exist
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_NO_SUCH_OBJECT
,
matched
,
""
);
if
(
matched
!=
NULL
)
{
free
(
matched
);
}
Debug
(
LDAP_DEBUG_TRACE
,
"parent does not exist
\n
"
,
0
,
0
,
0
)
;
goto
error_
return
;
rc
=
-
1
;
goto
return
_results
;
}
if
(
matched
!=
NULL
)
{
free
(
matched
);
...
...
@@ -96,7 +108,9 @@ ldbm_back_add(
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_INSUFFICIENT_ACCESS
,
""
,
""
);
goto
error_return
;
rc
=
-
1
;
goto
return_results
;
}
}
else
{
if
(
!
be_isroot
(
be
,
op
->
o_dn
)
)
{
...
...
@@ -104,9 +118,10 @@ ldbm_back_add(
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_INSUFFICIENT_ACCESS
,
""
,
""
);
goto
error_return
;
rc
=
-
1
;
goto
return_results
;
}
p
=
NULL
;
}
/*
...
...
@@ -116,9 +131,10 @@ ldbm_back_add(
if
(
id2children_add
(
be
,
p
,
e
)
!=
0
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"id2children_add failed
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
""
,
""
);
goto
error_return
;
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
""
,
""
);
rc
=
-
1
;
goto
return_results
;
}
/*
...
...
@@ -131,7 +147,9 @@ ldbm_back_add(
Debug
(
LDAP_DEBUG_TRACE
,
"index_add_entry failed
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
""
,
""
);
goto
error_return
;
rc
=
-
1
;
goto
return_results
;
}
/* dn2id index */
...
...
@@ -139,35 +157,44 @@ ldbm_back_add(
Debug
(
LDAP_DEBUG_TRACE
,
"dn2id_add failed
\n
"
,
0
,
0
,
0
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
""
,
""
);
goto
error_return
;
rc
=
-
1
;
goto
return_results
;
}
/* acquire writer lock */
entry_rdwr_lock
(
e
,
1
);
/* id2entry index */
if
(
id2entry_add
(
be
,
e
)
!=
0
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"id2entry_add failed
\n
"
,
0
,
0
,
0
);
(
void
)
dn2id_delete
(
be
,
dn
);
send_ldap_result
(
conn
,
op
,
LDAP_OPERATIONS_ERROR
,
""
,
""
);
goto
error_return
;
rc
=
-
1
;
goto
return_results
;
}
send_ldap_result
(
conn
,
op
,
LDAP_SUCCESS
,
""
,
""
);
rc
=
0
;
return_results:
;
if
(
dn
!=
NULL
)
free
(
dn
);
if
(
pdn
!=
NULL
)
free
(
pdn
);
cache_set_state
(
&
li
->
li_cache
,
e
,
0
);
cache_return_entry
(
&
li
->
li_cache
,
e
);
return
(
0
);
error_return:
;
if
(
dn
!=
NULL
)
free
(
dn
);
if
(
pdn
!=
NULL
)
free
(
pdn
);
next_id_return
(
be
,
e
->
e_id
);
cache_delete_entry
(
&
li
->
li_cache
,
e
);
cache_return_entry
(
&
li
->
li_cache
,
e
);
/* free entry and writer lock */
cache_return_entry_w
(
&
li
->
li_cache
,
e
);
/* free entry and reader lock */
if
(
p
!=
NULL
)
{
cache_return_entry_r
(
&
li
->
li_cache
,
p
);
}
return
(
-
1
);
return
(
rc
);
}
servers/slapd/back-ldbm/bind.c
View file @
4a5d740e
...
...
@@ -6,6 +6,7 @@
#include
<sys/socket.h>
#include
"slap.h"
#include
"back-ldbm.h"
#include
"proto-back-ldbm.h"
#ifdef KERBEROS
#ifdef KERBEROS_V
#include
<kerberosIV/krb.h>
...
...
@@ -32,7 +33,6 @@ extern char *crypt (char *key, char *salt);
#include
<lutil.h>
extern
Entry
*
dn2entry
();
extern
Attribute
*
attr_find
();
#ifdef KERBEROS
...
...
@@ -140,7 +140,10 @@ ldbm_back_bind(
AUTH_DAT
ad
;
#endif
if
(
(
e
=
dn2entry
(
be
,
dn
,
&
matched
))
==
NULL
)
{
Debug
(
LDAP_DEBUG_ARGS
,
"==> ldbm_back_bind: dn: %s
\n
"
,
dn
,
0
,
0
);
/* get entry with reader lock */
if
(
(
e
=
dn2entry_r
(
be
,
dn
,
&
matched
))
==
NULL
)
{
/* allow noauth binds */
if
(
method
==
LDAP_AUTH_SIMPLE
&&
cred
->
bv_len
==
0
)
{
/*
...
...
@@ -153,8 +156,7 @@ ldbm_back_bind(
/* front end will send result */
rc
=
0
;
}
else
{
send_ldap_result
(
conn
,
op
,
LDAP_NO_SUCH_OBJECT
,
matched
,
NULL
);
send_ldap_result
(
conn
,
op
,
LDAP_NO_SUCH_OBJECT
,
matched
,
NULL
);
rc
=
1
;
}
if
(
matched
!=
NULL
)
{
...
...
@@ -163,25 +165,32 @@ ldbm_back_bind(
return
(
rc
);
}
/* check for deleted */
switch
(
method
)
{
case
LDAP_AUTH_SIMPLE
:
if
(
cred
->
bv_len
==
0
)
{
send_ldap_result
(
conn
,
op
,
LDAP_SUCCESS
,
NULL
,
NULL
);
return
(
1
);
/* stop front end from sending result */
rc
=
1
;
goto
return_results
;
}
else
if
(
be_isroot_pw
(
be
,
dn
,
cred
)
)
{
/* front end will send result */
return
(
0
);
rc
=
0
;
goto
return_results
;
}
if
(
(
a
=
attr_find
(
e
->
e_attrs
,
"userpassword"
))
==
NULL
)
{
if
(
be_isroot_pw
(
be
,
dn
,
cred
)
)
{
/* front end will send result */
return
(
0
);
rc
=
0
;
goto
return_results
;
}
send_ldap_result
(
conn
,
op
,
LDAP_INAPPROPRIATE_AUTH
,
NULL
,
NULL
);
cache_return_entry
(
&
li
->
li_cache
,
e
)
;
return
(
1
)
;
rc
=
1
;
goto
return
_results
;
}
#ifdef LDAP_CRYPT
...
...
@@ -189,16 +198,18 @@ ldbm_back_bind(
#else
if
(
value_find
(
a
->
a_vals
,
cred
,
a
->
a_syntax
,
0
)
!=
0
)
#endif
{
{
if
(
be_isroot_pw
(
be
,
dn
,
cred
)
)
{
/* front end will send result */
return
(
0
);
rc
=
0
;
goto
return_results
;
}
send_ldap_result
(
conn
,
op
,
LDAP_INVALID_CREDENTIALS
,
NULL
,
NULL
);
cache_return_entry
(
&
li
->
li_cache
,
e
)
;
return
(
1
)
;
rc
=
1
;
goto
return
_results
;
}
rc
=
0
;
break
;
#ifdef KERBEROS
...
...
@@ -206,8 +217,8 @@ ldbm_back_bind(
if
(
krbv4_ldap_auth
(
be
,
cred
,
&
ad
)
!=
LDAP_SUCCESS
)
{
send_ldap_result
(
conn
,
op
,
LDAP_INVALID_CREDENTIALS
,
NULL
,
NULL
);
cache_return_entry
(
&
li
->
li_cache
,
e
)
;
return
(
1
)
;
rc
=
0
;
goto
return
_results
;
}
sprintf
(
krbname
,
"%s%s%s@%s"
,
ad
.
pname
,
*
ad
.
pinst
?
"."
:
""
,
ad
.
pinst
,
ad
.
prealm
);
...
...
@@ -216,43 +227,47 @@ ldbm_back_bind(
* no krbName values present: check against DN
*/
if
(
strcasecmp
(
dn
,
krbname
)
==
0
)
{
rc
=
0
;
/* XXX wild ass guess */
break
;
}
send_ldap_result
(
conn
,
op
,
LDAP_INAPPROPRIATE_AUTH
,
NULL
,
NULL
);
cache_return_entry
(
&
li
->
li_cache
,
e
)
;
return
(
1
)
;
rc
=
1
;
goto
return
_results
;
}
else
{
/* look for krbName match */
struct
berval
krbval
;
krbval
.
bv_val
=
krbname
;
krbval
.
bv_len
=
strlen
(
krbname
);
if
(
value_find
(
a
->
a_vals
,
&
krbval
,
a
->
a_syntax
,
3
)
!=
0
)
{
if
(
value_find
(
a
->
a_vals
,
&
krbval
,
a
->
a_syntax
,
3
)
!=
0
)
{
send_ldap_result
(
conn
,
op
,
LDAP_INVALID_CREDENTIALS
,
NULL
,
NULL
);
cache_return_entry
(
&
li
->
li_cache
,
e
)
;
return
(
1
)
;
rc
=
1
;
goto
return
_results
;
}
}
break
;
case
LDAP_AUTH_KRBV42
:
send_ldap_result
(
conn
,
op
,
LDAP_SUCCESS
,
NULL
,
NULL
);
cache_return_entry
(
&
li
->
li_cache
,
e
);
return
(
1
);
/* stop front end from sending result */
rc
=
1
;
goto
return_results
;
#endif
default:
send_ldap_result
(
conn
,
op
,
LDAP_STRONG_AUTH_NOT_SUPPORTED
,
NULL
,
"auth method not supported"
);
cache_return_entry
(
&
li
->
li_cache
,
e
)
;
return
(
1
)
;
rc
=
1
;
goto
return
_results
;
}
cache_return_entry
(
&
li
->
li_cache
,
e
);
return_results:
;
/* free entry and reader lock */
cache_return_entry_r
(
&
li
->
li_cache
,
e
);
/*
success:
front end wi
ll
send result */
return
(
0
);
/* front end wi
th
send result
on success (rc==0)
*/
return
(
rc
);
}
servers/slapd/back-ldbm/cache.c
View file @
4a5d740e
...
...
@@ -52,7 +52,7 @@ cache_set_state( struct cache *cache, Entry *e, int state )
pthread_mutex_unlock
(
&
cache
->
c_mutex
);
}
void
static
void
cache_return_entry
(
struct
cache
*
cache
,
Entry
*
e
)
{
/* set cache mutex */
...
...
@@ -66,6 +66,28 @@ cache_return_entry( struct cache *cache, Entry *e )
pthread_mutex_unlock
(
&
cache
->
c_mutex
);
}
static
void
cache_return_entry_rw
(
struct
cache
*
cache
,
Entry
*
e
,
int
rw
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"====> cache_return_entry_%s
\n
"
,
rw
?
"w"
:
"r"
,
0
,
0
);
entry_rdwr_unlock
(
e
,
rw
);;
cache_return_entry
(
cache
,
e
);
}
void
cache_return_entry_r
(
struct
cache
*
cache
,
Entry
*
e
)
{
cache_return_entry_rw
(
cache
,
e
,
0
);
}
void
cache_return_entry_w
(
struct
cache
*
cache
,
Entry
*
e
)
{
cache_return_entry_rw
(
cache
,
e
,
1
);
}
#define LRU_DELETE( cache, e ) { \
if ( e->e_lruprev != NULL ) { \
e->e_lruprev->e_lrunext = e->e_lrunext; \
...
...
@@ -113,8 +135,8 @@ cache_add_entry_lock(
if
(
avl_insert
(
&
cache
->
c_dntree
,
e
,
cache_entrydn_cmp
,
avl_dup_error
)
!=
0
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"
entry %20s id %d already in dn cache
\n
"
,
e
->
e_dn
,
e
->
e_id
,
0
);
"====> cache_add_entry lock:
entry %20s id %d already in dn cache
\n
"
,
e
->
e_dn
,
e
->
e_id
,
0
);
/* free cache mutex */
pthread_mutex_unlock
(
&
cache
->
c_mutex
);
...
...
@@ -124,13 +146,14 @@ cache_add_entry_lock(
/* id tree */
if
(
avl_insert
(
&
cache
->
c_idtree
,
e
,
cache_entryid_cmp
,
avl_dup_error
)
!=
0
)
{
Debug
(
LDAP_DEBUG_ANY
,
"entry %20s id %d already in id cache
\n
"
,
Debug
(
LDAP_DEBUG_ANY
,
"====> entry %20s id %d already in id cache
\n
"
,
e
->
e_dn
,
e
->
e_id
,
0
);
/* delete from dn tree inserted above */
if
(
avl_delete
(
&
cache
->
c_dntree
,
e
,
cache_entrydn_cmp
)
==
NULL
)
{
Debug
(
LDAP_DEBUG_ANY
,
"can't delete from dn cache
\n
"
,
Debug
(
LDAP_DEBUG_ANY
,
"
====>
can't delete from dn cache
\n
"
,
0
,
0
,
0
);
}
...
...
@@ -168,6 +191,9 @@ cache_add_entry_lock(
==
0
&&
cache
->
c_cursize
>
cache
->
c_maxsize
)
{
e
=
cache
->
c_lrutail
;
/* XXX check for writer lock - should also check no readers pending */
assert
(
pthread_rdwr_wchk_np
(
&
e
->
e_rdwr
));
/* delete from cache and lru q */
rc
=
cache_delete_entry_internal
(
cache
,
e
);
...
...
@@ -181,44 +207,85 @@ cache_add_entry_lock(
}
/*
* cache_find_entry_dn - find an entry in the cache, given dn
* cache_find_entry_dn
2id
- find an entry in the cache, given dn
*/
Entry
*
cache_find_entry_dn
(
ID
cache_find_entry_dn2id
(
Backend
*
be
,
struct
cache
*
cache
,
char
*
dn
)
{
struct
ldbminfo
*
li
=
(
struct
ldbminfo
*
)
be
->
be_private
;
Entry
e
,
*
ep
;
ID
id
;
/* set cache mutex */
pthread_mutex_lock
(
&
cache
->
c_mutex
);
e
.
e_dn
=
dn
;
if
(
(
ep
=
(
Entry
*
)
avl_find
(
cache
->
c_dntree
,
&
e
,
cache_entrydn_cmp
))
!=
NULL
)
{
!=
NULL
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"====> cache_find_entry_dn2id: found dn: %s
\n
"
,
dn
,
0
,
0
);
/*
* entry is deleted or not fully created yet
*/
if
(
ep
->
e_state
==
ENTRY_STATE_DELETED
||
ep
->
e_state
==
ENTRY_STATE_CREATING
)
ep
->
e_state
==
ENTRY_STATE_CREATING
)
{
/* free cache mutex */
pthread_mutex_unlock
(
&
cache
->
c_mutex
);
return
(
N
ULL
);
return
(
N
OID
);
}
/* XXX is this safe without writer lock? */
ep
->
e_refcnt
++
;
/* lru */
LRU_DELETE
(
cache
,
ep
);
LRU_ADD
(
cache
,
ep
);
/* acquire reader lock */
entry_rdwr_lock
(
ep
,
0
);
/* re-check */
if
(
ep
->
e_state
==
ENTRY_STATE_DELETED
||
ep
->
e_state
==
ENTRY_STATE_CREATING
)
{
/* XXX check that is is required */
ep
->
e_refcnt
--
;
/* free reader lock */
entry_rdwr_unlock
(
ep
,
0
);
/* free cache mutex */
pthread_mutex_unlock
(
&
cache
->
c_mutex
);
return
(
NOID
);
}
/* save id */
id
=
ep
->
e_id
;
/* free reader lock */
entry_rdwr_unlock
(
ep
,
0
);
/* free cache mutex */
pthread_mutex_unlock
(
&
cache
->
c_mutex
);
cache_return_entry
(
&
li
->
li_cache
,
ep
);
return
(
id
);
}
/* free cache mutex */
pthread_mutex_unlock
(
&
cache
->
c_mutex
);
return
(
ep
);
return
(
NOID
);
}
/*
...
...
@@ -227,8 +294,9 @@ cache_find_entry_dn(
Entry
*
cache_find_entry_id
(
struct
cache
*
cache
,
ID
id
struct
cache
*
cache
,
ID
id
,
int
rw
)
{
Entry
e
;
...
...
@@ -238,29 +306,64 @@ cache_find_entry_id(
pthread_mutex_lock
(
&
cache
->
c_mutex
);
e
.
e_id
=
id
;
if
(
(
ep
=
(
Entry
*
)
avl_find
(
cache
->
c_idtree
,
&
e
,
cache_entryid_cmp
))
!=
NULL
)
{
!=
NULL
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"====> cache_find_entry_dn2id: found id: %ld rw: %d
\n
"
,
id
,
rw
,
0
);
/*
* entry is deleted or not fully created yet
*/
if
(
ep
->
e_state
==
ENTRY_STATE_DELETED
||
ep
->
e_state
==
ENTRY_STATE_CREATING
)
ep
->
e_state
==
ENTRY_STATE_CREATING
)
{
/* free cache mutex */
pthread_mutex_unlock
(
&
cache
->
c_mutex
);
return
(
NULL
);
}
/* XXX is this safe without writer lock? */
ep
->
e_refcnt
++
;
/* lru */
LRU_DELETE
(
cache
,
ep
);
LRU_ADD
(
cache
,
ep
);