From: Howard Chu Date: Tue, 27 Apr 2004 01:56:38 +0000 (+0000) Subject: Added readOnly attribute, can be toggled on individual databases. X-Git-Tag: OPENDLAP_REL_ENG_2_2_MP~421 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=9644d6d820d749e020c439ba70221a88e809b726;p=openldap Added readOnly attribute, can be toggled on individual databases. --- diff --git a/servers/slapd/back-monitor/back-monitor.h b/servers/slapd/back-monitor/back-monitor.h index cddd899abc..e9e8df1006 100644 --- a/servers/slapd/back-monitor/back-monitor.h +++ b/servers/slapd/back-monitor/back-monitor.h @@ -103,6 +103,7 @@ struct monitorinfo { AttributeDescription *mi_ad_seeAlso; AttributeDescription *mi_ad_l; AttributeDescription *mi_ad_labeledURI; + AttributeDescription *mi_ad_readOnly; }; /* diff --git a/servers/slapd/back-monitor/database.c b/servers/slapd/back-monitor/database.c index 7191e5479b..b754376c33 100644 --- a/servers/slapd/back-monitor/database.c +++ b/servers/slapd/back-monitor/database.c @@ -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 ) diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c index 6173c12949..5ed5b01bb3 100644 --- a/servers/slapd/back-monitor/init.c +++ b/servers/slapd/back-monitor/init.c @@ -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 */ diff --git a/servers/slapd/back-monitor/proto-back-monitor.h b/servers/slapd/back-monitor/proto-back-monitor.h index 9b5980174b..072504e59b 100644 --- a/servers/slapd/back-monitor/proto-back-monitor.h +++ b/servers/slapd/back-monitor/proto-back-monitor.h @@ -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