Commit 9644d6d8 authored by Howard Chu's avatar Howard Chu
Browse files

Added readOnly attribute, can be toggled on individual databases.

parent 781c2d02
......@@ -103,6 +103,7 @@ struct monitorinfo {
AttributeDescription *mi_ad_seeAlso;
AttributeDescription *mi_ad_l;
AttributeDescription *mi_ad_labeledURI;
AttributeDescription *mi_ad_readOnly;
};
/*
......
......@@ -45,6 +45,7 @@ monitor_subsys_database_init(
Entry *e, *e_database, *e_tmp;
int i;
struct monitorentrypriv *mp;
struct berval *tf;
assert( be != NULL );
......@@ -67,6 +68,9 @@ monitor_subsys_database_init(
#endif
return( -1 );
}
tf = (global_restrictops & SLAP_RESTRICT_OP_WRITES) ?
(struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv ;
attr_merge_one( e_database, mi->mi_ad_readOnly, tf, tf );
e_tmp = NULL;
for ( i = nBackendDB; i--; ) {
......@@ -137,6 +141,9 @@ monitor_subsys_database_init(
attr_merge( e_database, slap_schema.si_ad_namingContexts,
be->be_suffix, be->be_nsuffix );
}
tf = (be->be_restrictops & SLAP_RESTRICT_OP_WRITES) ?
(struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv ;
attr_merge_one( e, mi->mi_ad_readOnly, tf, tf );
if ( oi != NULL ) {
slap_overinst *on = oi->oi_list;
......@@ -236,6 +243,120 @@ monitor_subsys_database_init(
return( 0 );
}
int
monitor_subsys_database_modify(
Operation *op,
Entry *e
)
{
struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
int rc = LDAP_OTHER;
Attribute *save_attrs;
Modifications *modlist = op->oq_modify.rs_modlist;
Modifications *ml;
Backend *be;
int gotval = 1, i, n, cur;
i = sscanf( e->e_nname.bv_val, "cn=database %d,", &n );
if ( i != 1 )
return LDAP_UNWILLING_TO_PERFORM;
if ( n < 0 || n >= nBackendDB )
return LDAP_NO_SUCH_OBJECT;
be = &backendDB[n];
cur = (be->be_restrictops & SLAP_RESTRICT_OP_WRITES) ? 1 : 0;
save_attrs = e->e_attrs;
e->e_attrs = attrs_dup( e->e_attrs );
for ( ml=modlist; ml; ml=ml->sml_next ) {
Modification *mod = &ml->sml_mod;
if ( mod->sm_desc == mi->mi_ad_readOnly ) {
int val = -1;
if ( mod->sm_values ) {
/* single-valued */
if ( !BER_BVISNULL(&mod->sm_values[1]) ) {
rc = LDAP_CONSTRAINT_VIOLATION;
break;
}
if ( bvmatch( &slap_true_bv, mod->sm_values )) {
val = 1;
} else if ( bvmatch( &slap_false_bv, mod->sm_values )) {
val = 0;
}
}
switch( mod->sm_op ) {
case LDAP_MOD_DELETE:
if ( val < 0 || val == cur ) {
gotval--;
cur = -1;
} else {
rc = LDAP_NO_SUCH_ATTRIBUTE;
}
break;
case LDAP_MOD_REPLACE:
gotval--;
cur = -1;
/* FALLTHRU */
case LDAP_MOD_ADD:
if ( val < 0 ) {
rc = LDAP_INVALID_SYNTAX;
} else {
gotval++;
cur = val;
}
break;
default:
rc = LDAP_OTHER;
break;
}
if ( rc ) {
break;
}
} else if ( is_at_operational( mod->sm_desc->ad_type )) {
/* accept all operational attributes */
attr_delete( &e->e_attrs, mod->sm_desc );
rc = attr_merge( e, mod->sm_desc, mod->sm_values,
mod->sm_nvalues );
if ( rc ) {
rc = LDAP_OTHER;
break;
}
} else {
rc = LDAP_UNWILLING_TO_PERFORM;
break;
}
}
if ( gotval == 1 && cur >= 0 ) {
struct berval *tf;
tf = cur ? (struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv;
attr_delete( &e->e_attrs, mi->mi_ad_readOnly );
rc = attr_merge_one( e, mi->mi_ad_readOnly, tf, tf );
if ( rc == LDAP_SUCCESS ) {
if ( cur ) {
be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
} else {
be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
}
} else {
rc = LDAP_OTHER;
}
} else {
rc = LDAP_CONSTRAINT_VIOLATION;
}
if ( rc == LDAP_SUCCESS ) {
attrs_free( save_attrs );
} else {
Attribute *tmp = e->e_attrs;
e->e_attrs = save_attrs;
attrs_free( tmp );
}
return rc;
}
#if defined(LDAP_SLAPI)
static int
monitor_back_add_plugin( Backend *be, Entry *e_database )
......
......@@ -55,7 +55,7 @@ struct monitorsubsys monitor_subsys[] = {
monitor_subsys_database_init,
NULL, /* update */
NULL, /* create */
NULL /* modify */
monitor_subsys_database_modify
}, {
SLAPD_MONITOR_BACKEND, SLAPD_MONITOR_BACKEND_NAME,
BER_BVNULL, BER_BVNULL, BER_BVNULL,
......@@ -457,6 +457,14 @@ monitor_back_db_open(
"NO-USER-MODIFICATION "
"USAGE directoryOperation )", SLAP_AT_HIDE,
offsetof(struct monitorinfo, mi_ad_monitorOverlay) },
{ "readOnly", "( 1.3.6.1.4.1.4203.666.1.31 "
"NAME 'readOnly' "
"DESC 'read/write status of a given database' "
"EQUALITY booleanMatch "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
"SINGLE-VALUE "
"USAGE directoryOperation )", SLAP_AT_HIDE,
offsetof(struct monitorinfo, mi_ad_readOnly) },
#ifdef INTEGRATE_CORE_SCHEMA
{ NULL, NULL, 0, -1 }, /* description */
{ NULL, NULL, 0, -1 }, /* seeAlso */
......
......@@ -41,6 +41,7 @@ int monitor_subsys_backend_init LDAP_P(( BackendDB *be ));
* databases
*/
int monitor_subsys_database_init LDAP_P(( BackendDB *be ));
int monitor_subsys_database_modify LDAP_P(( Operation *op, Entry *e ));
/*
* threads
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment