Skip to content
Snippets Groups Projects
Commit 9644d6d8 authored by Howard Chu's avatar Howard Chu
Browse files

Added readOnly attribute, can be toggled on individual databases.

parent 781c2d02
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment