mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-07 14:18:15 +08:00
ITS#9264 add an optional lock to slapo-unique
This commit is contained in:
parent
57d5aefecf
commit
9183abe62c
@ -39,7 +39,7 @@ They should appear after the
|
||||
.B overlay
|
||||
directive.
|
||||
.TP
|
||||
.B unique_uri <[strict ][ignore ]URI[URI...]...>
|
||||
.B unique_uri <[strict ][ignore ][serialize ]URI[URI...]...>
|
||||
Configure the base, attributes, scope, and filter for uniqueness
|
||||
checking. Multiple URIs may be specified within a domain,
|
||||
allowing complex selections of objects. Multiple
|
||||
@ -50,9 +50,10 @@ attributes will create independent domains, each with their own
|
||||
independent lists of URIs and ignore/strict settings.
|
||||
|
||||
Keywords
|
||||
.B strict
|
||||
.BR strict ,
|
||||
.BR ignore ,
|
||||
and
|
||||
.B ignore
|
||||
.B serialize
|
||||
have to be enclosed in quotes (") together with the URI.
|
||||
|
||||
The LDAP URI syntax is a subset of
|
||||
@ -119,6 +120,17 @@ mode extends the concept of uniqueness to include null values, such
|
||||
that only one attribute within a subtree will be allowed to have a
|
||||
null value. Strictness applies to all URIs within a uniqueness
|
||||
domain, but some domains may be strict while others are not.
|
||||
|
||||
It is possible to enforce strict serialization of modifications by
|
||||
prepending the keyword
|
||||
.B serialize.
|
||||
By default, no serialization is performed, so multiple modifications
|
||||
occurring nearly simultaneously may see incomplete uniqueness results.
|
||||
Using
|
||||
.B serialize
|
||||
will force individual write operations to fully complete before allowing
|
||||
any others to proceed, to ensure that each operation's uniqueness checks
|
||||
are consistent.
|
||||
.LP
|
||||
It is not possible to set both URIs and legacy slapo\-unique configuration
|
||||
parameters simultaneously. In general, the legacy configuration options
|
||||
|
@ -58,12 +58,14 @@ typedef struct unique_domain_s {
|
||||
struct unique_domain_uri_s *uri;
|
||||
char ignore; /* polarity of attributes */
|
||||
char strict; /* null considered unique too */
|
||||
char serial; /* serialize execution */
|
||||
} unique_domain;
|
||||
|
||||
typedef struct unique_data_s {
|
||||
struct unique_domain_s *domains;
|
||||
struct unique_domain_s *legacy;
|
||||
char legacy_strict_set;
|
||||
ldap_pvt_thread_mutex_t serial_mutex;
|
||||
} unique_data;
|
||||
|
||||
typedef struct unique_counter_s {
|
||||
@ -76,7 +78,7 @@ enum {
|
||||
UNIQUE_IGNORE,
|
||||
UNIQUE_ATTR,
|
||||
UNIQUE_STRICT,
|
||||
UNIQUE_URI
|
||||
UNIQUE_URI,
|
||||
};
|
||||
|
||||
static ConfigDriver unique_cf_base;
|
||||
@ -315,7 +317,7 @@ unique_new_domain_uri_basic ( unique_domain_uri **urip,
|
||||
*
|
||||
* domain_specs look like
|
||||
*
|
||||
* [strict ][ignore ]uri[[ uri]...]
|
||||
* [strict ][ignore ][serialize ]uri[[ uri]...]
|
||||
* e.g. "ldap:///ou=foo,o=bar?uid?sub ldap:///ou=baz,o=bar?uid?sub"
|
||||
* "strict ldap:///ou=accounts,o=bar?uid,uidNumber?one"
|
||||
* etc
|
||||
@ -346,6 +348,11 @@ unique_new_domain ( unique_domain **domainp,
|
||||
domain->ignore = 1;
|
||||
uri_start += STRLENOF( "ignore " );
|
||||
}
|
||||
if ( strncasecmp ( uri_start, "serialize ",
|
||||
STRLENOF( "serialize " ) ) == 0 ) {
|
||||
domain->serial = 1;
|
||||
uri_start += STRLENOF( "serialize " );
|
||||
}
|
||||
if ( strncasecmp ( uri_start, "strict ",
|
||||
STRLENOF( "strict " ) ) == 0 ) {
|
||||
domain->strict = 1;
|
||||
@ -644,11 +651,7 @@ unique_cf_strict( ConfigArgs *c )
|
||||
* and missing is necessary to add olcUniqueURIs...
|
||||
*/
|
||||
if ( private->legacy_strict_set ) {
|
||||
struct berval bv;
|
||||
bv.bv_val = legacy->strict ? "TRUE" : "FALSE";
|
||||
bv.bv_len = legacy->strict ?
|
||||
STRLENOF("TRUE") :
|
||||
STRLENOF("FALSE");
|
||||
struct berval bv = legacy->strict ? slap_true_bv : slap_false_bv;
|
||||
value_add_one ( &c->rvalue_vals, &bv );
|
||||
}
|
||||
rc = 0;
|
||||
@ -789,11 +792,13 @@ unique_db_init(
|
||||
)
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)be->bd_info;
|
||||
unique_data **privatep = (unique_data **) &on->on_bi.bi_private;
|
||||
unique_data *private;
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE, "==> unique_db_init\n" );
|
||||
|
||||
*privatep = ch_calloc ( 1, sizeof ( unique_data ) );
|
||||
private = ch_calloc ( 1, sizeof ( unique_data ) );
|
||||
ldap_pvt_thread_mutex_init( &private->serial_mutex );
|
||||
on->on_bi.bi_private = private;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -805,8 +810,7 @@ unique_db_destroy(
|
||||
)
|
||||
{
|
||||
slap_overinst *on = (slap_overinst *)be->bd_info;
|
||||
unique_data **privatep = (unique_data **) &on->on_bi.bi_private;
|
||||
unique_data *private = *privatep;
|
||||
unique_data *private = on->on_bi.bi_private;
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE, "==> unique_db_destroy\n" );
|
||||
|
||||
@ -816,8 +820,9 @@ unique_db_destroy(
|
||||
|
||||
unique_free_domain ( domains );
|
||||
unique_free_domain ( legacy );
|
||||
ldap_pvt_thread_mutex_destroy( &private->serial_mutex );
|
||||
ch_free ( private );
|
||||
*privatep = NULL;
|
||||
on->on_bi.bi_private = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1025,6 +1030,21 @@ unique_search(
|
||||
return(rc);
|
||||
}
|
||||
|
||||
static int
|
||||
unique_unlock(
|
||||
Operation *op,
|
||||
SlapReply *rs
|
||||
)
|
||||
{
|
||||
slap_callback *sc = op->o_callback;
|
||||
unique_data *private = sc->sc_private;
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &private->serial_mutex );
|
||||
op->o_callback = sc->sc_next;
|
||||
op->o_tmpfree( sc, op->o_tmpmemctx );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
unique_add(
|
||||
Operation *op,
|
||||
@ -1041,6 +1061,7 @@ unique_add(
|
||||
char *key, *kp;
|
||||
struct berval bvkey;
|
||||
int rc = SLAP_CB_CONTINUE;
|
||||
int locked = 0;
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE, "==> unique_add <%s>\n",
|
||||
op->o_req_dn.bv_val );
|
||||
@ -1100,6 +1121,9 @@ unique_add(
|
||||
/* skip this domain-uri if it isn't involved */
|
||||
if ( !ks ) continue;
|
||||
|
||||
if ( domain->serial && !locked )
|
||||
ldap_pvt_thread_mutex_lock( &private->serial_mutex );
|
||||
|
||||
/* terminating NUL */
|
||||
ks += sizeof("(|)");
|
||||
|
||||
@ -1150,6 +1174,17 @@ unique_add(
|
||||
if ( rc != SLAP_CB_CONTINUE ) break;
|
||||
}
|
||||
|
||||
if ( locked ) {
|
||||
if ( rc != SLAP_CB_CONTINUE ) {
|
||||
ldap_pvt_thread_mutex_unlock( &private->serial_mutex );
|
||||
} else {
|
||||
slap_callback *cb = op->o_tmpcalloc( 1, sizeof(slap_callback), op->o_tmpmemctx );
|
||||
cb->sc_cleanup = unique_unlock;
|
||||
cb->sc_private = private;
|
||||
cb->sc_next = op->o_callback;
|
||||
op->o_callback = cb;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1171,6 +1206,7 @@ unique_modify(
|
||||
char *key, *kp;
|
||||
struct berval bvkey;
|
||||
int rc = SLAP_CB_CONTINUE;
|
||||
int locked = 0;
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE, "==> unique_modify <%s>\n",
|
||||
op->o_req_dn.bv_val );
|
||||
@ -1223,6 +1259,9 @@ unique_modify(
|
||||
/* skip this domain-uri if it isn't involved */
|
||||
if ( !ks ) continue;
|
||||
|
||||
if ( domain->serial && !locked )
|
||||
ldap_pvt_thread_mutex_lock( &private->serial_mutex );
|
||||
|
||||
/* terminating NUL */
|
||||
ks += sizeof("(|)");
|
||||
|
||||
@ -1275,6 +1314,17 @@ unique_modify(
|
||||
if ( rc != SLAP_CB_CONTINUE ) break;
|
||||
}
|
||||
|
||||
if ( locked ) {
|
||||
if ( rc != SLAP_CB_CONTINUE ) {
|
||||
ldap_pvt_thread_mutex_unlock( &private->serial_mutex );
|
||||
} else {
|
||||
slap_callback *cb = op->o_tmpcalloc( 1, sizeof(slap_callback), op->o_tmpmemctx );
|
||||
cb->sc_cleanup = unique_unlock;
|
||||
cb->sc_private = private;
|
||||
cb->sc_next = op->o_callback;
|
||||
op->o_callback = cb;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -1297,6 +1347,7 @@ unique_modrdn(
|
||||
LDAPRDN newrdn;
|
||||
struct berval bv[2];
|
||||
int rc = SLAP_CB_CONTINUE;
|
||||
int locked = 0;
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE, "==> unique_modrdn <%s> <%s>\n",
|
||||
op->o_req_dn.bv_val, op->orr_newrdn.bv_val );
|
||||
@ -1374,6 +1425,9 @@ unique_modrdn(
|
||||
/* skip this domain if it isn't involved */
|
||||
if ( !ks ) continue;
|
||||
|
||||
if ( domain->serial && !locked )
|
||||
ldap_pvt_thread_mutex_lock( &private->serial_mutex );
|
||||
|
||||
/* terminating NUL */
|
||||
ks += sizeof("(|)");
|
||||
|
||||
@ -1426,6 +1480,17 @@ unique_modrdn(
|
||||
if ( rc != SLAP_CB_CONTINUE ) break;
|
||||
}
|
||||
|
||||
if ( locked ) {
|
||||
if ( rc != SLAP_CB_CONTINUE ) {
|
||||
ldap_pvt_thread_mutex_unlock( &private->serial_mutex );
|
||||
} else {
|
||||
slap_callback *cb = op->o_tmpcalloc( 1, sizeof(slap_callback), op->o_tmpmemctx );
|
||||
cb->sc_cleanup = unique_unlock;
|
||||
cb->sc_private = private;
|
||||
cb->sc_next = op->o_callback;
|
||||
op->o_callback = cb;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user