ITS#2779, cache group ACLs per operation instead of per-connection

This commit is contained in:
Howard Chu 2003-10-23 01:23:45 +00:00
parent e81d17e357
commit 102d8159a7
5 changed files with 27 additions and 36 deletions

View file

@ -1176,9 +1176,7 @@ backend_group(
op->o_bd = select_backend( gr_ndn, 0, 0 ); op->o_bd = select_backend( gr_ndn, 0, 0 );
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); for (g = op->o_groups; g; g=g->ga_next) {
for (g = op->o_conn->c_groups; g; g=g->ga_next) {
if (g->ga_be != op->o_bd || g->ga_oc != group_oc || if (g->ga_be != op->o_bd || g->ga_oc != group_oc ||
g->ga_at != group_at || g->ga_len != gr_ndn->bv_len) g->ga_at != group_at || g->ga_len != gr_ndn->bv_len)
continue; continue;
@ -1186,8 +1184,6 @@ backend_group(
break; break;
} }
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
if (g) { if (g) {
rc = g->ga_res; rc = g->ga_res;
goto done; goto done;
@ -1290,10 +1286,8 @@ backend_group(
g->ga_res = rc; g->ga_res = rc;
g->ga_len = gr_ndn->bv_len; g->ga_len = gr_ndn->bv_len;
strcpy(g->ga_ndn, gr_ndn->bv_val); strcpy(g->ga_ndn, gr_ndn->bv_val);
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); g->ga_next = op->o_groups;
g->ga_next = op->o_conn->c_groups; op->o_groups = g;
op->o_conn->c_groups = g;
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
} }
done: done:
op->o_bd = be; op->o_bd = be;

View file

@ -430,7 +430,6 @@ long connection_init(
c->c_dn.bv_len = 0; c->c_dn.bv_len = 0;
c->c_ndn.bv_val = NULL; c->c_ndn.bv_val = NULL;
c->c_ndn.bv_len = 0; c->c_ndn.bv_len = 0;
c->c_groups = NULL;
c->c_listener = NULL; c->c_listener = NULL;
c->c_peer_domain.bv_val = NULL; c->c_peer_domain.bv_val = NULL;
@ -476,7 +475,6 @@ long connection_init(
assert( c->c_authmech.bv_val == NULL ); assert( c->c_authmech.bv_val == NULL );
assert( c->c_dn.bv_val == NULL ); assert( c->c_dn.bv_val == NULL );
assert( c->c_ndn.bv_val == NULL ); assert( c->c_ndn.bv_val == NULL );
assert( c->c_groups == NULL );
assert( c->c_listener == NULL ); assert( c->c_listener == NULL );
assert( c->c_peer_domain.bv_val == NULL ); assert( c->c_peer_domain.bv_val == NULL );
assert( c->c_peer_name.bv_val == NULL ); assert( c->c_peer_name.bv_val == NULL );
@ -613,15 +611,6 @@ void connection2anonymous( Connection *c )
c->c_ndn.bv_len = 0; c->c_ndn.bv_len = 0;
c->c_authz_backend = NULL; c->c_authz_backend = NULL;
{
GroupAssertion *g, *n;
for (g = c->c_groups; g; g=n) {
n = g->ga_next;
free(g);
}
c->c_groups = NULL;
}
} }
static void static void

View file

@ -69,6 +69,15 @@ slap_op_free( Operation *op )
free( op->o_sync_state.bv_val ); free( op->o_sync_state.bv_val );
} }
{
GroupAssertion *g, *n;
for (g = op->o_groups; g; g=n) {
n = g->ga_next;
free(g);
}
op->o_groups = NULL;
}
#if defined( LDAP_SLAPI ) #if defined( LDAP_SLAPI )
if ( op->o_pb != NULL ) { if ( op->o_pb != NULL ) {
slapi_pblock_destroy( (Slapi_PBlock *)op->o_pb ); slapi_pblock_destroy( (Slapi_PBlock *)op->o_pb );

View file

@ -1823,6 +1823,19 @@ struct slap_csn_entry {
LDAP_TAILQ_ENTRY (slap_csn_entry) csn_link; LDAP_TAILQ_ENTRY (slap_csn_entry) csn_link;
}; };
/*
* Caches the result of a backend_group check for ACL evaluation
*/
typedef struct slap_gacl {
struct slap_gacl *ga_next;
Backend *ga_be;
ObjectClass *ga_oc;
AttributeDescription *ga_at;
int ga_res;
ber_len_t ga_len;
char ga_ndn[1];
} GroupAssertion;
/* /*
* represents an operation pending from an ldap client * represents an operation pending from an ldap client
*/ */
@ -1901,7 +1914,8 @@ typedef struct slap_op {
#define SLAP_CANCEL_ACK 0x02 #define SLAP_CANCEL_ACK 0x02
#define SLAP_CANCEL_DONE 0x03 #define SLAP_CANCEL_DONE 0x03
char o_do_not_cache; /* don't cache from this op */ GroupAssertion *o_groups;
char o_do_not_cache; /* don't cache groups from this op */
char o_is_auth_check; /* authorization in progress */ char o_is_auth_check; /* authorization in progress */
#define SLAP_NO_CONTROL 0 #define SLAP_NO_CONTROL 0
@ -2025,19 +2039,6 @@ typedef void (SEND_LDAP_INTERMEDIATE)(
#define send_ldap_intermediate( op, rs ) \ #define send_ldap_intermediate( op, rs ) \
(op->o_conn->c_send_ldap_intermediate)( op, rs ) (op->o_conn->c_send_ldap_intermediate)( op, rs )
/*
* Caches the result of a backend_group check for ACL evaluation
*/
typedef struct slap_gacl {
struct slap_gacl *ga_next;
Backend *ga_be;
ObjectClass *ga_oc;
AttributeDescription *ga_at;
int ga_res;
ber_len_t ga_len;
char ga_ndn[1];
} GroupAssertion;
typedef struct slap_listener Listener; typedef struct slap_listener Listener;
/* /*
@ -2070,7 +2071,6 @@ typedef struct slap_conn {
Backend *c_authz_backend; Backend *c_authz_backend;
AuthorizationInformation c_authz; AuthorizationInformation c_authz;
GroupAssertion *c_groups;
ber_int_t c_protocol; /* version of the LDAP protocol used by client */ ber_int_t c_protocol; /* version of the LDAP protocol used by client */

View file

@ -168,7 +168,6 @@ slapiConnectionInit(
c->c_dn.bv_len = 0; c->c_dn.bv_len = 0;
c->c_ndn.bv_val = NULL; c->c_ndn.bv_val = NULL;
c->c_ndn.bv_len = 0; c->c_ndn.bv_len = 0;
c->c_groups = NULL;
c->c_listener = &slap_unknown_listener; c->c_listener = &slap_unknown_listener;
ber_dupbv( &c->c_peer_domain, (struct berval *)&slap_unknown_bv ); ber_dupbv( &c->c_peer_domain, (struct berval *)&slap_unknown_bv );