|
|
dc8c34 |
From 6946341b5d2a9a65ebcadcf31410f5578fefd552 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
dc8c34 |
Date: Fri, 9 Jan 2015 13:53:20 -0500
|
|
|
dc8c34 |
Subject: [PATCH 298/305] Ticket 47973 - During schema reload sometimes the
|
|
|
dc8c34 |
search returns no results
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Bug Description: During a schema reload operation the search of an existing
|
|
|
dc8c34 |
entry may randomly report no results. This is because during
|
|
|
dc8c34 |
the schema reload all existing attribute syntaxes are removed,
|
|
|
dc8c34 |
and there is a small window where ldap operations can be performed
|
|
|
dc8c34 |
before the new schema is loaded. During this window, attribute
|
|
|
dc8c34 |
values are normalized to NULL which causes operation to unexpectedly
|
|
|
dc8c34 |
fail.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Fix Description: Instead of wiping out the existing attribute syntax hastables
|
|
|
dc8c34 |
in the middle of the task, instead load the new schema into
|
|
|
dc8c34 |
temporary hash tables. Once the reload is complete, then take
|
|
|
dc8c34 |
the asi write lock, remove the old hash tables, and swap in the
|
|
|
dc8c34 |
new ones.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/47973
|
|
|
dc8c34 |
|
|
|
dc8c34 |
valgrind: PASSED
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed by: nhosoi(Thanks!)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
(cherry picked from commit 3fafcbe0a2ada038f02efdfdce77c1768f0e1819)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Conflicts:
|
|
|
dc8c34 |
ldap/servers/slapd/attrsyntax.c
|
|
|
dc8c34 |
ldap/servers/slapd/proto-slap.h
|
|
|
dc8c34 |
|
|
|
dc8c34 |
(cherry picked from commit 457252f5c97aa8b72d94376e328e63c5d47a825b)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/plugins/schema_reload/schema_reload.c | 7 -
|
|
|
dc8c34 |
ldap/servers/slapd/attr.c | 8 +-
|
|
|
dc8c34 |
ldap/servers/slapd/attrsyntax.c | 230 +++++++++++++++------
|
|
|
dc8c34 |
ldap/servers/slapd/opshared.c | 2 +-
|
|
|
dc8c34 |
ldap/servers/slapd/proto-slap.h | 12 +-
|
|
|
dc8c34 |
ldap/servers/slapd/schema.c | 116 ++++++-----
|
|
|
dc8c34 |
6 files changed, 243 insertions(+), 132 deletions(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/plugins/schema_reload/schema_reload.c b/ldap/servers/plugins/schema_reload/schema_reload.c
|
|
|
dc8c34 |
index efc0de2..4e5c7f0 100644
|
|
|
dc8c34 |
--- a/ldap/servers/plugins/schema_reload/schema_reload.c
|
|
|
dc8c34 |
+++ b/ldap/servers/plugins/schema_reload/schema_reload.c
|
|
|
dc8c34 |
@@ -170,13 +170,6 @@ schemareload_thread(void *arg)
|
|
|
dc8c34 |
slapi_task_log_notice(task, "Schema reload task finished.");
|
|
|
dc8c34 |
slapi_task_log_status(task, "Schema reload task finished.");
|
|
|
dc8c34 |
slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema reload task finished.\n");
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- slapi_log_error(SLAPI_LOG_FATAL, "schemareload",
|
|
|
dc8c34 |
- "Register internal schema.\n");
|
|
|
dc8c34 |
- rv = slapi_reload_internal_attr_syntax();
|
|
|
dc8c34 |
- slapi_log_error(SLAPI_LOG_FATAL, "schemareload",
|
|
|
dc8c34 |
- "Register internal schema finished.\n");
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
slapi_task_log_notice(task, "Schema reload task failed.");
|
|
|
dc8c34 |
slapi_task_log_status(task, "Schema reload task failed.");
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/attr.c b/ldap/servers/slapd/attr.c
|
|
|
dc8c34 |
index 983e286..a4d8a96 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/attr.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/attr.c
|
|
|
dc8c34 |
@@ -175,8 +175,8 @@ slapi_attr_types_equivalent(const char *t1, const char *t2)
|
|
|
dc8c34 |
return 0;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- asi1 = attr_syntax_get_by_name(t1);
|
|
|
dc8c34 |
- asi2 = attr_syntax_get_by_name(t2);
|
|
|
dc8c34 |
+ asi1 = attr_syntax_get_by_name(t1, 0);
|
|
|
dc8c34 |
+ asi2 = attr_syntax_get_by_name(t2, 0);
|
|
|
dc8c34 |
if (NULL != asi1) {
|
|
|
dc8c34 |
if (NULL != asi2) {
|
|
|
dc8c34 |
/* Both found - compare normalized names */
|
|
|
dc8c34 |
@@ -277,7 +277,7 @@ slapi_attr_init_locking_optional(Slapi_Attr *a, const char *type, PRBool use_loc
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
basetype = tmp; /* basetype was malloc'd */
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- asi = attr_syntax_get_by_name_locking_optional(basetype, use_lock);
|
|
|
dc8c34 |
+ asi = attr_syntax_get_by_name_locking_optional(basetype, use_lock, 0);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
if(NULL == asi)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -288,7 +288,7 @@ slapi_attr_init_locking_optional(Slapi_Attr *a, const char *type, PRBool use_loc
|
|
|
dc8c34 |
* attribute type that has that syntax.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
asi = attr_syntax_get_by_name_locking_optional(
|
|
|
dc8c34 |
- ATTR_WITH_OCTETSTRING_SYNTAX, use_lock);
|
|
|
dc8c34 |
+ ATTR_WITH_OCTETSTRING_SYNTAX, use_lock, 0);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
else
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c
|
|
|
dc8c34 |
index 75114e0..d92728a 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/attrsyntax.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/attrsyntax.c
|
|
|
dc8c34 |
@@ -73,14 +73,19 @@ static Slapi_RWLock *name2asi_lock = NULL;
|
|
|
dc8c34 |
#define AS_UNLOCK_READ(l) slapi_rwlock_unlock(l)
|
|
|
dc8c34 |
#define AS_UNLOCK_WRITE(l) slapi_rwlock_unlock(l)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+/*
|
|
|
dc8c34 |
+ * For the schema reload task, we need to use separate temporary hashtables & linked lists
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+static PLHashTable *oid2asi_tmp = NULL;
|
|
|
dc8c34 |
+static PLHashTable *name2asi_tmp = NULL;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
static struct asyntaxinfo *default_asi = NULL;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
static void *attr_syntax_get_plugin_by_name_with_default( const char *type );
|
|
|
dc8c34 |
static void attr_syntax_delete_no_lock( struct asyntaxinfo *asip,
|
|
|
dc8c34 |
- PRBool remove_from_oid_table );
|
|
|
dc8c34 |
+ PRBool remove_from_oid_table, PRUint32 schema_flags );
|
|
|
dc8c34 |
static struct asyntaxinfo *attr_syntax_get_by_oid_locking_optional( const
|
|
|
dc8c34 |
- char *oid, PRBool use_lock);
|
|
|
dc8c34 |
+ char *oid, PRBool use_lock, PRUint32 schema_flags);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
#ifdef ATTR_LDAP_DEBUG
|
|
|
dc8c34 |
static void attr_syntax_print();
|
|
|
dc8c34 |
@@ -198,8 +203,6 @@ attr_syntax_check_oids()
|
|
|
dc8c34 |
void
|
|
|
dc8c34 |
attr_syntax_free( struct asyntaxinfo *a )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- PR_ASSERT( a->asi_refcnt == 0 );
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
cool_charray_free( a->asi_aliases );
|
|
|
dc8c34 |
slapi_ch_free( (void**)&a->asi_name );
|
|
|
dc8c34 |
slapi_ch_free( (void **)&a->asi_desc );
|
|
|
dc8c34 |
@@ -228,9 +231,9 @@ attr_syntax_new()
|
|
|
dc8c34 |
* be returned by calling to attr_syntax_return().
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
struct asyntaxinfo *
|
|
|
dc8c34 |
-attr_syntax_get_by_oid(const char *oid)
|
|
|
dc8c34 |
+attr_syntax_get_by_oid(const char *oid, PRUint32 schema_flags)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- return attr_syntax_get_by_oid_locking_optional( oid, PR_TRUE);
|
|
|
dc8c34 |
+ return attr_syntax_get_by_oid_locking_optional( oid, PR_TRUE, schema_flags);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -243,15 +246,30 @@ attr_syntax_get_by_oid(const char *oid)
|
|
|
dc8c34 |
* same use_lock parameter.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
static struct asyntaxinfo *
|
|
|
dc8c34 |
-attr_syntax_get_by_oid_locking_optional( const char *oid, PRBool use_lock )
|
|
|
dc8c34 |
+attr_syntax_get_by_oid_locking_optional( const char *oid, PRBool use_lock, PRUint32 schema_flags )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
struct asyntaxinfo *asi = 0;
|
|
|
dc8c34 |
- if (oid2asi)
|
|
|
dc8c34 |
+ PLHashTable *ht = oid2asi;
|
|
|
dc8c34 |
+ int using_tmp_ht = 0;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if (schema_flags & DSE_SCHEMA_LOCKED){
|
|
|
dc8c34 |
+ ht = oid2asi_tmp;
|
|
|
dc8c34 |
+ using_tmp_ht = 1;
|
|
|
dc8c34 |
+ use_lock = 0;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (ht)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
if ( use_lock ) {
|
|
|
dc8c34 |
AS_LOCK_READ(oid2asi_lock);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- asi = (struct asyntaxinfo *)PL_HashTableLookup_const(oid2asi, oid);
|
|
|
dc8c34 |
+ if (!using_tmp_ht){
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * The oid2asi pointer could have been rewritten by the schema_reload task
|
|
|
dc8c34 |
+ * while waiting on the lock, so grab it again.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ ht = oid2asi;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ asi = (struct asyntaxinfo *)PL_HashTableLookup_const(ht, oid);
|
|
|
dc8c34 |
if (asi)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
PR_AtomicIncrement( &asi->asi_refcnt );
|
|
|
dc8c34 |
@@ -272,18 +290,22 @@ attr_syntax_get_by_oid_locking_optional( const char *oid, PRBool use_lock )
|
|
|
dc8c34 |
* to worry about resource contention.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
static void
|
|
|
dc8c34 |
-attr_syntax_add_by_oid(const char *oid, struct asyntaxinfo *a, int lock)
|
|
|
dc8c34 |
+attr_syntax_add_by_oid(const char *oid, struct asyntaxinfo *a, PRUint32 schema_flags, int lock)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
if (0 != attr_syntax_init()) return;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if (lock) {
|
|
|
dc8c34 |
- AS_LOCK_WRITE(oid2asi_lock);
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
+ if(schema_flags & DSE_SCHEMA_LOCKED){
|
|
|
dc8c34 |
+ PL_HashTableAdd(oid2asi_tmp, oid, a);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ if (lock) {
|
|
|
dc8c34 |
+ AS_LOCK_WRITE(oid2asi_lock);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- PL_HashTableAdd(oid2asi, oid, a);
|
|
|
dc8c34 |
+ PL_HashTableAdd(oid2asi, oid, a);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if (lock) {
|
|
|
dc8c34 |
- AS_UNLOCK_WRITE(oid2asi_lock);
|
|
|
dc8c34 |
+ if (lock) {
|
|
|
dc8c34 |
+ AS_UNLOCK_WRITE(oid2asi_lock);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -296,18 +318,19 @@ attr_syntax_add_by_oid(const char *oid, struct asyntaxinfo *a, int lock)
|
|
|
dc8c34 |
* be returned by calling to attr_syntax_return().
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
struct asyntaxinfo *
|
|
|
dc8c34 |
-attr_syntax_get_by_name(const char *name)
|
|
|
dc8c34 |
+attr_syntax_get_by_name(const char *name, PRUint32 schema_flags)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- return attr_syntax_get_by_name_locking_optional(name, PR_TRUE);
|
|
|
dc8c34 |
+ return attr_syntax_get_by_name_locking_optional(name, PR_TRUE, schema_flags);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
struct asyntaxinfo *
|
|
|
dc8c34 |
attr_syntax_get_by_name_with_default(const char *name)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
struct asyntaxinfo *asi = NULL;
|
|
|
dc8c34 |
- asi = attr_syntax_get_by_name_locking_optional(name, PR_TRUE);
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ asi = attr_syntax_get_by_name_locking_optional(name, PR_TRUE, 0);
|
|
|
dc8c34 |
if (asi == NULL)
|
|
|
dc8c34 |
- asi = attr_syntax_get_by_name(ATTR_WITH_OCTETSTRING_SYNTAX);
|
|
|
dc8c34 |
+ asi = attr_syntax_get_by_name(ATTR_WITH_OCTETSTRING_SYNTAX, 0);
|
|
|
dc8c34 |
if ( asi == NULL )
|
|
|
dc8c34 |
asi = default_asi;
|
|
|
dc8c34 |
return asi;
|
|
|
dc8c34 |
@@ -322,15 +345,30 @@ attr_syntax_get_by_name_with_default(const char *name)
|
|
|
dc8c34 |
* same use_lock parameter.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
struct asyntaxinfo *
|
|
|
dc8c34 |
-attr_syntax_get_by_name_locking_optional(const char *name, PRBool use_lock)
|
|
|
dc8c34 |
+attr_syntax_get_by_name_locking_optional(const char *name, PRBool use_lock, PRUint32 schema_flags)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
struct asyntaxinfo *asi = 0;
|
|
|
dc8c34 |
- if (name2asi)
|
|
|
dc8c34 |
+ PLHashTable *ht = name2asi;
|
|
|
dc8c34 |
+ int using_tmp_ht = 0;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if (schema_flags & DSE_SCHEMA_LOCKED){
|
|
|
dc8c34 |
+ ht = name2asi_tmp;
|
|
|
dc8c34 |
+ using_tmp_ht = 1;
|
|
|
dc8c34 |
+ use_lock = 0;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (ht)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
if ( use_lock ) {
|
|
|
dc8c34 |
AS_LOCK_READ(name2asi_lock);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
- asi = (struct asyntaxinfo *)PL_HashTableLookup_const(name2asi, name);
|
|
|
dc8c34 |
+ if(!using_tmp_ht){
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * The name2asi pointer could have been rewritten by the schema_reload task
|
|
|
dc8c34 |
+ * while waiting on the lock, so grab it again.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ ht = name2asi;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ asi = (struct asyntaxinfo *)PL_HashTableLookup_const(ht, name);
|
|
|
dc8c34 |
if ( NULL != asi ) {
|
|
|
dc8c34 |
PR_AtomicIncrement( &asi->asi_refcnt );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -339,7 +377,7 @@ attr_syntax_get_by_name_locking_optional(const char *name, PRBool use_lock)
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
if (!asi) /* given name may be an OID */
|
|
|
dc8c34 |
- asi = attr_syntax_get_by_oid_locking_optional(name, use_lock);
|
|
|
dc8c34 |
+ asi = attr_syntax_get_by_oid_locking_optional(name, use_lock, schema_flags);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
return asi;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -402,26 +440,37 @@ attr_syntax_return_locking_optional(struct asyntaxinfo *asi, PRBool use_lock)
|
|
|
dc8c34 |
* to worry about resource contention.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
static void
|
|
|
dc8c34 |
-attr_syntax_add_by_name(struct asyntaxinfo *a, int lock)
|
|
|
dc8c34 |
+attr_syntax_add_by_name(struct asyntaxinfo *a, PRUint32 schema_flags, int lock)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
if (0 != attr_syntax_init()) return;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if (lock) {
|
|
|
dc8c34 |
- AS_LOCK_WRITE(name2asi_lock);
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
+ if (schema_flags & DSE_SCHEMA_LOCKED ){
|
|
|
dc8c34 |
+ PL_HashTableAdd(name2asi_tmp, a->asi_name, a);
|
|
|
dc8c34 |
+ if ( a->asi_aliases != NULL ) {
|
|
|
dc8c34 |
+ int i;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ for ( i = 0; a->asi_aliases[i] != NULL; ++i ) {
|
|
|
dc8c34 |
+ PL_HashTableAdd(name2asi_tmp, a->asi_aliases[i], a);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ if (lock) {
|
|
|
dc8c34 |
+ AS_LOCK_WRITE(name2asi_lock);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- PL_HashTableAdd(name2asi, a->asi_name, a);
|
|
|
dc8c34 |
- if ( a->asi_aliases != NULL ) {
|
|
|
dc8c34 |
- int i;
|
|
|
dc8c34 |
+ PL_HashTableAdd(name2asi, a->asi_name, a);
|
|
|
dc8c34 |
+ if ( a->asi_aliases != NULL ) {
|
|
|
dc8c34 |
+ int i;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- for ( i = 0; a->asi_aliases[i] != NULL; ++i ) {
|
|
|
dc8c34 |
- PL_HashTableAdd(name2asi, a->asi_aliases[i], a);
|
|
|
dc8c34 |
+ for ( i = 0; a->asi_aliases[i] != NULL; ++i ) {
|
|
|
dc8c34 |
+ PL_HashTableAdd(name2asi, a->asi_aliases[i], a);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (lock) {
|
|
|
dc8c34 |
+ AS_UNLOCK_WRITE(name2asi_lock);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if (lock) {
|
|
|
dc8c34 |
- AS_UNLOCK_WRITE(name2asi_lock);
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -430,7 +479,7 @@ attr_syntax_add_by_name(struct asyntaxinfo *a, int lock)
|
|
|
dc8c34 |
* and oids.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
void
|
|
|
dc8c34 |
-attr_syntax_delete( struct asyntaxinfo *asi )
|
|
|
dc8c34 |
+attr_syntax_delete( struct asyntaxinfo *asi, PRUint32 schema_flags )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
PR_ASSERT( asi );
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -438,7 +487,7 @@ attr_syntax_delete( struct asyntaxinfo *asi )
|
|
|
dc8c34 |
AS_LOCK_WRITE(oid2asi_lock);
|
|
|
dc8c34 |
AS_LOCK_WRITE(name2asi_lock);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- attr_syntax_delete_no_lock( asi, PR_TRUE );
|
|
|
dc8c34 |
+ attr_syntax_delete_no_lock( asi, PR_TRUE, schema_flags );
|
|
|
dc8c34 |
|
|
|
dc8c34 |
AS_UNLOCK_WRITE(name2asi_lock);
|
|
|
dc8c34 |
AS_UNLOCK_WRITE(oid2asi_lock);
|
|
|
dc8c34 |
@@ -452,19 +501,34 @@ attr_syntax_delete( struct asyntaxinfo *asi )
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
static void
|
|
|
dc8c34 |
attr_syntax_delete_no_lock( struct asyntaxinfo *asi,
|
|
|
dc8c34 |
- PRBool remove_from_oidtable )
|
|
|
dc8c34 |
+ PRBool remove_from_oidtable, PRUint32 schema_flags )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- int i;
|
|
|
dc8c34 |
+ PLHashTable *ht = NULL;
|
|
|
dc8c34 |
+ int using_tmp_ht = 0;
|
|
|
dc8c34 |
+ int i;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+ if (schema_flags & DSE_SCHEMA_LOCKED){
|
|
|
dc8c34 |
+ using_tmp_ht = 1;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
if (oid2asi && remove_from_oidtable ) {
|
|
|
dc8c34 |
- PL_HashTableRemove(oid2asi, asi->asi_oid);
|
|
|
dc8c34 |
+ if (using_tmp_ht){
|
|
|
dc8c34 |
+ ht = oid2asi_tmp;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ ht = oid2asi;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ PL_HashTableRemove(ht, asi->asi_oid);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if(name2asi) {
|
|
|
dc8c34 |
- PL_HashTableRemove(name2asi, asi->asi_name);
|
|
|
dc8c34 |
+ if (using_tmp_ht){
|
|
|
dc8c34 |
+ ht = name2asi_tmp;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ ht = name2asi;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ PL_HashTableRemove(ht, asi->asi_name);
|
|
|
dc8c34 |
if ( asi->asi_aliases != NULL ) {
|
|
|
dc8c34 |
for ( i = 0; asi->asi_aliases[i] != NULL; ++i ) {
|
|
|
dc8c34 |
- PL_HashTableRemove(name2asi, asi->asi_aliases[i]);
|
|
|
dc8c34 |
+ PL_HashTableRemove(ht, asi->asi_aliases[i]);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
if ( asi->asi_refcnt > 0 ) {
|
|
|
dc8c34 |
@@ -496,7 +560,7 @@ slapi_attr_syntax_normalize( const char *s )
|
|
|
dc8c34 |
struct asyntaxinfo *asi = NULL;
|
|
|
dc8c34 |
char *r = NULL;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if((asi=attr_syntax_get_by_name(s)) != NULL ) {
|
|
|
dc8c34 |
+ if((asi=attr_syntax_get_by_name(s, 0)) != NULL ) {
|
|
|
dc8c34 |
r = slapi_ch_strdup(asi->asi_name);
|
|
|
dc8c34 |
attr_syntax_return( asi );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -507,7 +571,6 @@ slapi_attr_syntax_normalize( const char *s )
|
|
|
dc8c34 |
return r;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
* attr_syntax_exists: return 1 if attr_name exists, 0 otherwise
|
|
|
dc8c34 |
*
|
|
|
dc8c34 |
@@ -517,7 +580,8 @@ attr_syntax_exists(const char *attr_name)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
struct asyntaxinfo *asi;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- asi = attr_syntax_get_by_name(attr_name);
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ asi = attr_syntax_get_by_name(attr_name, 0);
|
|
|
dc8c34 |
attr_syntax_return( asi );
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ( asi != NULL )
|
|
|
dc8c34 |
@@ -686,13 +750,13 @@ attr_syntax_get_plugin_by_name_with_default( const char *type )
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
* first we look for this attribute type explictly
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
- if ( (asi = attr_syntax_get_by_name(type)) == NULL ) {
|
|
|
dc8c34 |
+ if ( (asi = attr_syntax_get_by_name(type, 0)) == NULL ) {
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
* no syntax for this type... return Octet String
|
|
|
dc8c34 |
* syntax. we accomplish this by looking up a well known
|
|
|
dc8c34 |
* attribute type that has that syntax.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
- asi = attr_syntax_get_by_name(ATTR_WITH_OCTETSTRING_SYNTAX);
|
|
|
dc8c34 |
+ asi = attr_syntax_get_by_name(ATTR_WITH_OCTETSTRING_SYNTAX, 0);
|
|
|
dc8c34 |
if (asi == NULL)
|
|
|
dc8c34 |
asi = default_asi;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -729,14 +793,13 @@ attr_syntax_dup( struct asyntaxinfo *a )
|
|
|
dc8c34 |
return( newas );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
* Add a new attribute type to the schema.
|
|
|
dc8c34 |
*
|
|
|
dc8c34 |
* Returns an LDAP error code (LDAP_SUCCESS if all goes well).
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
int
|
|
|
dc8c34 |
-attr_syntax_add( struct asyntaxinfo *asip )
|
|
|
dc8c34 |
+attr_syntax_add( struct asyntaxinfo *asip, PRUint32 schema_flags )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
int i, rc = LDAP_SUCCESS;
|
|
|
dc8c34 |
int nolock = asip->asi_flags & SLAPI_ATTR_FLAG_NOLOCKING;
|
|
|
dc8c34 |
@@ -748,7 +811,7 @@ attr_syntax_add( struct asyntaxinfo *asip )
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* make sure the oid is unique */
|
|
|
dc8c34 |
if ( NULL != ( oldas_from_oid = attr_syntax_get_by_oid_locking_optional(
|
|
|
dc8c34 |
- asip->asi_oid, !nolock))) {
|
|
|
dc8c34 |
+ asip->asi_oid, !nolock, schema_flags))) {
|
|
|
dc8c34 |
if ( 0 == (asip->asi_flags & SLAPI_ATTR_FLAG_OVERRIDE)) {
|
|
|
dc8c34 |
/* failure - OID is in use; no override flag */
|
|
|
dc8c34 |
rc = LDAP_TYPE_OR_VALUE_EXISTS;
|
|
|
dc8c34 |
@@ -760,7 +823,7 @@ attr_syntax_add( struct asyntaxinfo *asip )
|
|
|
dc8c34 |
* the primary name and OID point to the same schema definition.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
if ( NULL != ( oldas_from_name = attr_syntax_get_by_name_locking_optional(
|
|
|
dc8c34 |
- asip->asi_name, !nolock))) {
|
|
|
dc8c34 |
+ asip->asi_name, !nolock, schema_flags))) {
|
|
|
dc8c34 |
if ( 0 == (asip->asi_flags & SLAPI_ATTR_FLAG_OVERRIDE)
|
|
|
dc8c34 |
|| ( oldas_from_oid != oldas_from_name )) {
|
|
|
dc8c34 |
/* failure; no override flag OR OID and name don't match */
|
|
|
dc8c34 |
@@ -768,7 +831,7 @@ attr_syntax_add( struct asyntaxinfo *asip )
|
|
|
dc8c34 |
goto cleanup_and_return;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
/* Flag for deletion. We are going to override this attr */
|
|
|
dc8c34 |
- attr_syntax_delete(oldas_from_name);
|
|
|
dc8c34 |
+ attr_syntax_delete(oldas_from_name, schema_flags);
|
|
|
dc8c34 |
} else if ( NULL != oldas_from_oid ) {
|
|
|
dc8c34 |
/* failure - OID is in use but name does not exist */
|
|
|
dc8c34 |
rc = LDAP_TYPE_OR_VALUE_EXISTS;
|
|
|
dc8c34 |
@@ -782,11 +845,11 @@ attr_syntax_add( struct asyntaxinfo *asip )
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ( NULL != ( tmpasi =
|
|
|
dc8c34 |
attr_syntax_get_by_name_locking_optional(
|
|
|
dc8c34 |
- asip->asi_aliases[i], !nolock))) {
|
|
|
dc8c34 |
+ asip->asi_aliases[i], !nolock, schema_flags))) {
|
|
|
dc8c34 |
if (asip->asi_flags & SLAPI_ATTR_FLAG_OVERRIDE) {
|
|
|
dc8c34 |
/* Flag for tmpasi for deletion. It will be free'd
|
|
|
dc8c34 |
* when attr_syntax_return is called. */
|
|
|
dc8c34 |
- attr_syntax_delete(tmpasi);
|
|
|
dc8c34 |
+ attr_syntax_delete(tmpasi, schema_flags);
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
/* failure - one of the aliases is already in use */
|
|
|
dc8c34 |
rc = LDAP_TYPE_OR_VALUE_EXISTS;
|
|
|
dc8c34 |
@@ -805,8 +868,8 @@ attr_syntax_add( struct asyntaxinfo *asip )
|
|
|
dc8c34 |
/* ditto for the override one */
|
|
|
dc8c34 |
asip->asi_flags &= ~SLAPI_ATTR_FLAG_OVERRIDE;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- attr_syntax_add_by_oid( asip->asi_oid, asip, !nolock);
|
|
|
dc8c34 |
- attr_syntax_add_by_name( asip, !nolock);
|
|
|
dc8c34 |
+ attr_syntax_add_by_oid( asip->asi_oid, asip, schema_flags, !nolock);
|
|
|
dc8c34 |
+ attr_syntax_add_by_name( asip, schema_flags, !nolock);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
cleanup_and_return:
|
|
|
dc8c34 |
attr_syntax_return_locking_optional( oldas_from_oid, !nolock );
|
|
|
dc8c34 |
@@ -979,7 +1042,7 @@ slapi_attr_type2plugin( const char *type, void **pi )
|
|
|
dc8c34 |
int
|
|
|
dc8c34 |
slapi_attr_get_oid( const Slapi_Attr *a, char **oid )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- struct asyntaxinfo *asi = attr_syntax_get_by_name(a->a_type);
|
|
|
dc8c34 |
+ struct asyntaxinfo *asi = attr_syntax_get_by_name(a->a_type, 0);
|
|
|
dc8c34 |
if (asi) {
|
|
|
dc8c34 |
*oid = asi->asi_oid;
|
|
|
dc8c34 |
attr_syntax_return(asi);
|
|
|
dc8c34 |
@@ -995,7 +1058,7 @@ slapi_attr_get_oid( const Slapi_Attr *a, char **oid )
|
|
|
dc8c34 |
int
|
|
|
dc8c34 |
slapi_attr_get_oid_copy( const Slapi_Attr *a, char **oidp )
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- struct asyntaxinfo *asi = attr_syntax_get_by_name(a->a_type);
|
|
|
dc8c34 |
+ struct asyntaxinfo *asi = attr_syntax_get_by_name(a->a_type, 0);
|
|
|
dc8c34 |
if (asi) {
|
|
|
dc8c34 |
*oidp = slapi_ch_strdup( asi->asi_oid );
|
|
|
dc8c34 |
attr_syntax_return(asi);
|
|
|
dc8c34 |
@@ -1191,7 +1254,7 @@ attr_syntax_delete_if_not_flagged(struct asyntaxinfo *asip, void *arg)
|
|
|
dc8c34 |
PR_ASSERT( fi != NULL );
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ( 0 == ( asip->asi_flags & fi->asef_flag )) {
|
|
|
dc8c34 |
- attr_syntax_delete_no_lock( asip, PR_FALSE );
|
|
|
dc8c34 |
+ attr_syntax_delete_no_lock( asip, PR_FALSE, 0 );
|
|
|
dc8c34 |
return ATTR_SYNTAX_ENUM_REMOVE;
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
return ATTR_SYNTAX_ENUM_NEXT;
|
|
|
dc8c34 |
@@ -1207,7 +1270,7 @@ attr_syntax_force_to_delete(struct asyntaxinfo *asip, void *arg)
|
|
|
dc8c34 |
fi = (struct attr_syntax_enum_flaginfo *)arg;
|
|
|
dc8c34 |
PR_ASSERT( fi != NULL );
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- attr_syntax_delete_no_lock( asip, PR_FALSE );
|
|
|
dc8c34 |
+ attr_syntax_delete_no_lock( asip, PR_FALSE, 0 );
|
|
|
dc8c34 |
return ATTR_SYNTAX_ENUM_REMOVE;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -1272,6 +1335,7 @@ attr_syntax_delete_all_for_schemareload(unsigned long flag)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
#define ATTR_DEFAULT_SYNTAX_OID "1.1"
|
|
|
dc8c34 |
#define ATTR_DEFAULT_SYNTAX "defaultdirstringsyntax"
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
static int
|
|
|
dc8c34 |
attr_syntax_init(void)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -1290,6 +1354,14 @@ attr_syntax_init(void)
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+ if (!oid2asi_tmp)
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
+ /* temporary hash table for schema reload */
|
|
|
dc8c34 |
+ oid2asi_tmp = PL_NewHashTable(2047, hashNocaseString,
|
|
|
dc8c34 |
+ hashNocaseCompare,
|
|
|
dc8c34 |
+ PL_CompareValues, 0, 0);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
if (!name2asi)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
name2asi = PL_NewHashTable(2047, hashNocaseString,
|
|
|
dc8c34 |
@@ -1310,6 +1382,14 @@ attr_syntax_init(void)
|
|
|
dc8c34 |
DIRSTRING_SYNTAX_OID,
|
|
|
dc8c34 |
SLAPI_ATTR_FLAG_NOUSERMOD );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ if (!name2asi_tmp)
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
+ /* temporary hash table for schema reload */
|
|
|
dc8c34 |
+ name2asi_tmp = PL_NewHashTable(2047, hashNocaseString,
|
|
|
dc8c34 |
+ hashNocaseCompare,
|
|
|
dc8c34 |
+ PL_CompareValues, 0, 0);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
return 0;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -1379,7 +1459,7 @@ slapi_add_internal_attr_syntax( const char *name, const char *oid,
|
|
|
dc8c34 |
&asip );
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ( rc == LDAP_SUCCESS ) {
|
|
|
dc8c34 |
- rc = attr_syntax_add( asip );
|
|
|
dc8c34 |
+ rc = attr_syntax_add( asip, 0 );
|
|
|
dc8c34 |
if ( rc == LDAP_SUCCESS ) {
|
|
|
dc8c34 |
if (attr_syntax_internal_asi_add_ht(asip)) {
|
|
|
dc8c34 |
slapi_log_error(SLAPI_LOG_FATAL,
|
|
|
dc8c34 |
@@ -1387,6 +1467,8 @@ slapi_add_internal_attr_syntax( const char *name, const char *oid,
|
|
|
dc8c34 |
"Failed to stash internal asyntaxinfo: %s.\n",
|
|
|
dc8c34 |
asip->asi_name);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ attr_syntax_free(asip);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -1406,7 +1488,7 @@ attr_syntax_internal_asi_add(struct asyntaxinfo *asip, void *arg)
|
|
|
dc8c34 |
/* Copy is needed since when reloading the schema,
|
|
|
dc8c34 |
* existing syntax info is cleaned up. */
|
|
|
dc8c34 |
asip_copy = attr_syntax_dup(asip);
|
|
|
dc8c34 |
- rc = attr_syntax_add(asip_copy);
|
|
|
dc8c34 |
+ rc = attr_syntax_add(asip_copy, 0);
|
|
|
dc8c34 |
if (LDAP_SUCCESS != rc) {
|
|
|
dc8c34 |
attr_syntax_free(asip_copy);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -1426,3 +1508,25 @@ slapi_reload_internal_attr_syntax()
|
|
|
dc8c34 |
attr_syntax_enumerate_attrs_ext(internalasi, attr_syntax_internal_asi_add, NULL);
|
|
|
dc8c34 |
return rc;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+/*
|
|
|
dc8c34 |
+ * schema reload - now that we have loaded the schema into temporary
|
|
|
dc8c34 |
+ * hash tables, swap out the old for the new.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+void
|
|
|
dc8c34 |
+attr_syntax_swap_ht()
|
|
|
dc8c34 |
+{
|
|
|
dc8c34 |
+ /* Remove the old hash tables */
|
|
|
dc8c34 |
+ PL_HashTableDestroy(name2asi);
|
|
|
dc8c34 |
+ PL_HashTableDestroy(oid2asi);
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Swap the hash table/linked list pointers, and set the
|
|
|
dc8c34 |
+ * temporary pointers to NULL
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ name2asi = name2asi_tmp;
|
|
|
dc8c34 |
+ name2asi_tmp = NULL;
|
|
|
dc8c34 |
+ oid2asi = oid2asi_tmp;
|
|
|
dc8c34 |
+ oid2asi_tmp = NULL;
|
|
|
dc8c34 |
+}
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
index 7a0b544..a7367a7 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/opshared.c
|
|
|
dc8c34 |
@@ -91,7 +91,7 @@ int op_shared_is_allowed_attr (const char *attr_name, int replicated_op)
|
|
|
dc8c34 |
struct asyntaxinfo *asi;
|
|
|
dc8c34 |
int no_user_mod = 0;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- asi = attr_syntax_get_by_name( attr_name );
|
|
|
dc8c34 |
+ asi = attr_syntax_get_by_name( attr_name, 0 );
|
|
|
dc8c34 |
if ( NULL != asi &&
|
|
|
dc8c34 |
0 != ( asi->asi_flags & SLAPI_ATTR_FLAG_NOUSERMOD ))
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
|
|
dc8c34 |
index 0891608..da9c925 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/proto-slap.h
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/proto-slap.h
|
|
|
dc8c34 |
@@ -117,7 +117,7 @@ void attr_syntax_write_lock(void);
|
|
|
dc8c34 |
void attr_syntax_unlock_read(void);
|
|
|
dc8c34 |
void attr_syntax_unlock_write(void);
|
|
|
dc8c34 |
int attr_syntax_exists (const char *attr_name);
|
|
|
dc8c34 |
-void attr_syntax_delete ( struct asyntaxinfo *asip );
|
|
|
dc8c34 |
+void attr_syntax_delete ( struct asyntaxinfo *asip, PRUint32 schema_flags );
|
|
|
dc8c34 |
#define SLAPI_SYNTAXLENGTH_NONE (-1) /* for syntaxlength parameter */
|
|
|
dc8c34 |
int attr_syntax_create( const char *attr_oid, char *const*attr_names,
|
|
|
dc8c34 |
int num_names, const char *attr_desc, const char *attr_superior,
|
|
|
dc8c34 |
@@ -126,15 +126,17 @@ int attr_syntax_create( const char *attr_oid, char *const*attr_names,
|
|
|
dc8c34 |
const char *attr_syntax, int syntaxlength, unsigned long flags,
|
|
|
dc8c34 |
struct asyntaxinfo **asip );
|
|
|
dc8c34 |
void attr_syntax_free( struct asyntaxinfo *a );
|
|
|
dc8c34 |
-int attr_syntax_add( struct asyntaxinfo *asip );
|
|
|
dc8c34 |
+int attr_syntax_add( struct asyntaxinfo *asip, PRUint32 schema_flags );
|
|
|
dc8c34 |
char *attr_syntax_normalize_no_lookup( const char *s );
|
|
|
dc8c34 |
void attr_syntax_enumerate_attrs(AttrEnumFunc aef, void *arg, PRBool writelock);
|
|
|
dc8c34 |
void attr_syntax_all_clear_flag( unsigned long flag );
|
|
|
dc8c34 |
void attr_syntax_delete_all_not_flagged( unsigned long flag );
|
|
|
dc8c34 |
-struct asyntaxinfo *attr_syntax_get_by_oid ( const char *oid );
|
|
|
dc8c34 |
-struct asyntaxinfo *attr_syntax_get_by_name ( const char *name );
|
|
|
dc8c34 |
-struct asyntaxinfo *attr_syntax_get_by_name_locking_optional ( const char *name, PRBool use_lock );
|
|
|
dc8c34 |
+struct asyntaxinfo *attr_syntax_get_by_oid ( const char *oid, PRUint32 schema_flags );
|
|
|
dc8c34 |
+struct asyntaxinfo *attr_syntax_get_by_name ( const char *name, PRUint32 schema_flags );
|
|
|
dc8c34 |
struct asyntaxinfo *attr_syntax_get_by_name_with_default ( const char *name );
|
|
|
dc8c34 |
+struct asyntaxinfo *attr_syntax_get_by_name_locking_optional ( const char *name, PRBool use_lock, PRUint32 schema_flags );
|
|
|
dc8c34 |
+struct asyntaxinfo *attr_syntax_get_global_at();
|
|
|
dc8c34 |
+void attr_syntax_swap_ht(void);
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
* Call attr_syntax_return() when you are done using a value returned
|
|
|
dc8c34 |
* by attr_syntax_get_by_oid() or attr_syntax_get_by_name().
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
|
|
|
dc8c34 |
index 18ae152..798d905 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/schema.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/schema.c
|
|
|
dc8c34 |
@@ -154,6 +154,8 @@ static int schema_strcmp( const char *s1, const char *s2 );
|
|
|
dc8c34 |
static int schema_strcmp_array( char **sa1, char **sa2,
|
|
|
dc8c34 |
const char *ignorestr );
|
|
|
dc8c34 |
static PRBool schema_type_is_interesting( const char *type );
|
|
|
dc8c34 |
+static void reload_schemafile_lock(void);
|
|
|
dc8c34 |
+static void reload_schemafile_unlock(void);
|
|
|
dc8c34 |
static void schema_create_errormsg( char *errorbuf, size_t errorbufsize,
|
|
|
dc8c34 |
const char *prefix, const char *name, const char *fmt, ... )
|
|
|
dc8c34 |
#ifdef __GNUC__
|
|
|
dc8c34 |
@@ -2125,7 +2127,7 @@ schema_delete_attributes ( Slapi_Entry *entryBefore, LDAPMod *mod,
|
|
|
dc8c34 |
|
|
|
dc8c34 |
sscanf (attr_ldif, "%s name %s syntax %s",
|
|
|
dc8c34 |
psbAttrOid->buffer, psbAttrName->buffer, psbAttrSyntax->buffer);
|
|
|
dc8c34 |
- if ((a = attr_syntax_get_by_name ( psbAttrName->buffer)) != NULL ) {
|
|
|
dc8c34 |
+ if ((a = attr_syntax_get_by_name ( psbAttrName->buffer, 0 )) != NULL ) {
|
|
|
dc8c34 |
/* only modify attrs which were user defined */
|
|
|
dc8c34 |
if (a->asi_flags & SLAPI_ATTR_FLAG_STD_ATTR) {
|
|
|
dc8c34 |
schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_at,
|
|
|
dc8c34 |
@@ -2177,7 +2179,7 @@ schema_delete_attributes ( Slapi_Entry *entryBefore, LDAPMod *mod,
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* Delete it. */
|
|
|
dc8c34 |
- attr_syntax_delete( a );
|
|
|
dc8c34 |
+ attr_syntax_delete( a, 0 );
|
|
|
dc8c34 |
attr_syntax_return( a );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
else {
|
|
|
dc8c34 |
@@ -2300,7 +2302,7 @@ add_oc_internal(struct objclass *pnew_oc, char *errorbuf, size_t errorbufsize,
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* check to see if the oid is already in use by an attribute */
|
|
|
dc8c34 |
- if (!rc && (pasyntaxinfo = attr_syntax_get_by_oid(pnew_oc->oc_oid))) {
|
|
|
dc8c34 |
+ if (!rc && (pasyntaxinfo = attr_syntax_get_by_oid(pnew_oc->oc_oid, flags))) {
|
|
|
dc8c34 |
schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_oc,
|
|
|
dc8c34 |
pnew_oc->oc_name,
|
|
|
dc8c34 |
"The OID \"%s\" is also used by the attribute type \"%s\"",
|
|
|
dc8c34 |
@@ -2419,7 +2421,7 @@ schema_replace_attributes ( Slapi_PBlock *pb, LDAPMod *mod, char *errorbuf,
|
|
|
dc8c34 |
* handle the various cases.
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
if ( NULL == ( oldasip =
|
|
|
dc8c34 |
- attr_syntax_get_by_oid( newasip->asi_oid ))) {
|
|
|
dc8c34 |
+ attr_syntax_get_by_oid( newasip->asi_oid, 0 ))) {
|
|
|
dc8c34 |
/* new attribute type */
|
|
|
dc8c34 |
LDAPDebug( LDAP_DEBUG_TRACE, "schema_replace_attributes:"
|
|
|
dc8c34 |
" new type %s (OID %s)\n",
|
|
|
dc8c34 |
@@ -2437,14 +2439,14 @@ schema_replace_attributes ( Slapi_PBlock *pb, LDAPMod *mod, char *errorbuf,
|
|
|
dc8c34 |
" replacing type %s (OID %s)\n",
|
|
|
dc8c34 |
newasip->asi_name, newasip->asi_oid, 0 );
|
|
|
dc8c34 |
/* flag for deletion */
|
|
|
dc8c34 |
- attr_syntax_delete( oldasip );
|
|
|
dc8c34 |
+ attr_syntax_delete( oldasip, 0 );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
attr_syntax_return( oldasip );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ( NULL != newasip ) { /* add new or replacement definition */
|
|
|
dc8c34 |
- rc = attr_syntax_add( newasip );
|
|
|
dc8c34 |
+ rc = attr_syntax_add( newasip, 0 );
|
|
|
dc8c34 |
if ( LDAP_SUCCESS != rc ) {
|
|
|
dc8c34 |
schema_create_errormsg( errorbuf, errorbufsize,
|
|
|
dc8c34 |
schema_errprefix_at, newasip->asi_name,
|
|
|
dc8c34 |
@@ -3355,7 +3357,7 @@ read_at_ldif(const char *input, struct asyntaxinfo **asipp, char *errorbuf,
|
|
|
dc8c34 |
if (!status && (NULL != pSuperior)) {
|
|
|
dc8c34 |
struct asyntaxinfo *asi_parent;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- asi_parent = attr_syntax_get_by_name(pSuperior);
|
|
|
dc8c34 |
+ asi_parent = attr_syntax_get_by_name(pSuperior, schema_flags);
|
|
|
dc8c34 |
/* if we find no match then server won't start or add the attribute type */
|
|
|
dc8c34 |
if (asi_parent == NULL) {
|
|
|
dc8c34 |
LDAPDebug (LDAP_DEBUG_PARSE,
|
|
|
dc8c34 |
@@ -3467,7 +3469,7 @@ read_at_ldif(const char *input, struct asyntaxinfo **asipp, char *errorbuf,
|
|
|
dc8c34 |
struct asyntaxinfo *tmpasi;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if (!(flags & SLAPI_ATTR_FLAG_OVERRIDE) &&
|
|
|
dc8c34 |
- ( NULL != ( tmpasi = attr_syntax_get_by_oid(pOid)))) {
|
|
|
dc8c34 |
+ ( NULL != ( tmpasi = attr_syntax_get_by_oid(pOid, schema_flags)))) {
|
|
|
dc8c34 |
schema_create_errormsg( errorbuf, errorbufsize,
|
|
|
dc8c34 |
schema_errprefix_at, first_attr_name,
|
|
|
dc8c34 |
"Could not be added because the OID \"%s\" is already in use",
|
|
|
dc8c34 |
@@ -3490,7 +3492,7 @@ read_at_ldif(const char *input, struct asyntaxinfo **asipp, char *errorbuf,
|
|
|
dc8c34 |
if ( NULL != asipp ) {
|
|
|
dc8c34 |
*asipp = tmpasip; /* just return it */
|
|
|
dc8c34 |
} else { /* add the new attribute to the global store */
|
|
|
dc8c34 |
- status = attr_syntax_add( tmpasip );
|
|
|
dc8c34 |
+ status = attr_syntax_add( tmpasip, schema_flags );
|
|
|
dc8c34 |
if ( LDAP_SUCCESS != status ) {
|
|
|
dc8c34 |
if ( 0 != (flags & SLAPI_ATTR_FLAG_OVERRIDE) &&
|
|
|
dc8c34 |
LDAP_TYPE_OR_VALUE_EXISTS == status ) {
|
|
|
dc8c34 |
@@ -4307,6 +4309,59 @@ get_tagged_oid( const char *tag, const char **inputp,
|
|
|
dc8c34 |
return( oid );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+/*
|
|
|
dc8c34 |
+ * Reload the schema files
|
|
|
dc8c34 |
+ *
|
|
|
dc8c34 |
+ * This is only called from the schema_reload task. The flag DSE_SCHEMA_LOCKED
|
|
|
dc8c34 |
+ * is also only set been called from this function. To not interrupt clients
|
|
|
dc8c34 |
+ * we will rebuild the schema in separate hash tables, and then swap the
|
|
|
dc8c34 |
+ * hash tables once the schema is completely reloaded. We use the DSE_SCHEMA_LOCKED
|
|
|
dc8c34 |
+ * flag to tell the attribute syntax functions to use the temporary hashtables.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+int
|
|
|
dc8c34 |
+slapi_reload_schema_files(char *schemadir)
|
|
|
dc8c34 |
+{
|
|
|
dc8c34 |
+ int rc = LDAP_SUCCESS;
|
|
|
dc8c34 |
+ struct dse *my_pschemadse = NULL;
|
|
|
dc8c34 |
+ /* get be to lock */
|
|
|
dc8c34 |
+ Slapi_Backend *be = slapi_be_select_by_instance_name( DSE_SCHEMA );
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if (NULL == be)
|
|
|
dc8c34 |
+ {
|
|
|
dc8c34 |
+ slapi_log_error( SLAPI_LOG_FATAL, "schema_reload",
|
|
|
dc8c34 |
+ "schema file reload failed\n" );
|
|
|
dc8c34 |
+ return LDAP_LOCAL_ERROR;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ slapi_be_Wlock(be); /* be lock must be outer of schemafile lock */
|
|
|
dc8c34 |
+ reload_schemafile_lock();
|
|
|
dc8c34 |
+ oc_delete_all_nolock();
|
|
|
dc8c34 |
+ rc = init_schema_dse_ext(schemadir, be, &my_pschemadse,
|
|
|
dc8c34 |
+ DSE_SCHEMA_NO_CHECK | DSE_SCHEMA_LOCKED);
|
|
|
dc8c34 |
+ if (rc) {
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * The schema has been reloaded into the temporary hash tables.
|
|
|
dc8c34 |
+ * Take the write lock, wipe out the existing hash tables, and
|
|
|
dc8c34 |
+ * swap in the new ones.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ attr_syntax_write_lock();
|
|
|
dc8c34 |
+ attr_syntax_delete_all_for_schemareload(SLAPI_ATTR_FLAG_KEEP);
|
|
|
dc8c34 |
+ attr_syntax_swap_ht();
|
|
|
dc8c34 |
+ attr_syntax_unlock_write();
|
|
|
dc8c34 |
+ slapi_reload_internal_attr_syntax();
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ dse_destroy(pschemadse);
|
|
|
dc8c34 |
+ pschemadse = my_pschemadse;
|
|
|
dc8c34 |
+ reload_schemafile_unlock();
|
|
|
dc8c34 |
+ slapi_be_Unlock(be);
|
|
|
dc8c34 |
+ return LDAP_SUCCESS;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ reload_schemafile_unlock();
|
|
|
dc8c34 |
+ slapi_be_Unlock(be);
|
|
|
dc8c34 |
+ slapi_log_error( SLAPI_LOG_FATAL, "schema_reload",
|
|
|
dc8c34 |
+ "schema file reload failed\n" );
|
|
|
dc8c34 |
+ return LDAP_LOCAL_ERROR;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
* sprintf to `outp' the contents of `tag' followed by `oid' followed by a
|
|
|
dc8c34 |
@@ -4818,49 +4873,6 @@ slapi_validate_schema_files(char *schemadir)
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
- * API to reload the schema files.
|
|
|
dc8c34 |
- * Rule: this function is called when slapi_validate_schema_files is passed.
|
|
|
dc8c34 |
- * Schema checking is skipped in this function.
|
|
|
dc8c34 |
- */
|
|
|
dc8c34 |
-int
|
|
|
dc8c34 |
-slapi_reload_schema_files(char *schemadir)
|
|
|
dc8c34 |
-{
|
|
|
dc8c34 |
- int rc = LDAP_SUCCESS;
|
|
|
dc8c34 |
- struct dse *my_pschemadse = NULL;
|
|
|
dc8c34 |
- /* get be to lock */
|
|
|
dc8c34 |
- Slapi_Backend *be = slapi_be_select_by_instance_name( DSE_SCHEMA );
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- if (NULL == be)
|
|
|
dc8c34 |
- {
|
|
|
dc8c34 |
- slapi_log_error( SLAPI_LOG_FATAL, "schema_reload",
|
|
|
dc8c34 |
- "schema file reload failed\n" );
|
|
|
dc8c34 |
- return LDAP_LOCAL_ERROR;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
- slapi_be_Wlock(be); /* be lock must be outer of schemafile lock */
|
|
|
dc8c34 |
- reload_schemafile_lock();
|
|
|
dc8c34 |
- /* Exclude attr_syntax not to grab from the hash table while cleaning up */
|
|
|
dc8c34 |
- attr_syntax_write_lock();
|
|
|
dc8c34 |
- attr_syntax_delete_all_for_schemareload(SLAPI_ATTR_FLAG_KEEP);
|
|
|
dc8c34 |
- oc_delete_all_nolock();
|
|
|
dc8c34 |
- attr_syntax_unlock_write();
|
|
|
dc8c34 |
- rc = init_schema_dse_ext(schemadir, be, &my_pschemadse,
|
|
|
dc8c34 |
- DSE_SCHEMA_NO_CHECK | DSE_SCHEMA_LOCKED);
|
|
|
dc8c34 |
- if (rc) {
|
|
|
dc8c34 |
- dse_destroy(pschemadse);
|
|
|
dc8c34 |
- pschemadse = my_pschemadse;
|
|
|
dc8c34 |
- reload_schemafile_unlock();
|
|
|
dc8c34 |
- slapi_be_Unlock(be);
|
|
|
dc8c34 |
- return LDAP_SUCCESS;
|
|
|
dc8c34 |
- } else {
|
|
|
dc8c34 |
- reload_schemafile_unlock();
|
|
|
dc8c34 |
- slapi_be_Unlock(be);
|
|
|
dc8c34 |
- slapi_log_error( SLAPI_LOG_FATAL, "schema_reload",
|
|
|
dc8c34 |
- "schema file reload failed\n" );
|
|
|
dc8c34 |
- return LDAP_LOCAL_ERROR;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
-}
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
-/*
|
|
|
dc8c34 |
* slapi_schema_list_objectclass_attributes:
|
|
|
dc8c34 |
* Return the list of attributes belonging to the objectclass
|
|
|
dc8c34 |
*
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.9.3
|
|
|
dc8c34 |
|