Commit ceb1c5ce authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Apply fixes for ITS24 & ITS26 from devel.

 * slapd aclgroup deadlock bug fix
 * slapd non-authorized add bug fix
parent 3625743d
......@@ -360,7 +360,9 @@ acl_access_allowed(
/* see if asker is listed in dnattr */
string_expand(buf, sizeof(buf), b->a_group, edn, matches);
if (be_group(be, buf, odn, b->a_objectclassvalue, b->a_groupattrname) == 0) {
if (be_group(be, e, buf, odn,
b->a_objectclassvalue, b->a_groupattrname) == 0)
{
Debug( LDAP_DEBUG_ACL,
"<= acl_access_allowed: matched by clause #%d (group) access granted\n",
i, 0, 0 );
......
......@@ -28,22 +28,22 @@ ldbm_back_add(
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", dn, 0, 0);
pthread_mutex_lock(&li->li_add_mutex);
if ( ( dn2id( be, dn ) ) != NOID ) {
pthread_mutex_unlock(&li->li_add_mutex);
entry_free( e );
free( dn );
send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, "", "" );
return( -1 );
}
/* XXX race condition here til we cache_add_entry_lock below XXX */
if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
pthread_mutex_unlock(&li->li_add_mutex);
Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n",
0, 0, 0 );
/* XXX this should be ok, no other thread should have access
* because e hasn't been added to the cache yet
*/
entry_free( e );
free( dn );
send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION, "",
......@@ -51,28 +51,6 @@ ldbm_back_add(
return( -1 );
}
/*
* Try to add the entry to the cache, assign it a new dnid
* and mark it locked. This should only fail if the entry
* already exists.
*/
e->e_id = next_id( be );
if ( cache_add_entry_lock( &li->li_cache, e, ENTRY_STATE_CREATING )
!= 0 ) {
Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0,
0 );
next_id_return( be, e->e_id );
/* XXX this should be ok, no other thread should have access
* because e hasn't been added to the cache yet
*/
entry_free( e );
free( dn );
send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, "", "" );
return( -1 );
}
/*
* Get the parent dn and see if the corresponding entry exists.
* If the parent does not exist, only allow the "root" user to
......@@ -85,6 +63,7 @@ ldbm_back_add(
/* get entry with reader lock */
if ( (p = dn2entry_r( be, pdn, &matched )) == NULL ) {
pthread_mutex_unlock(&li->li_add_mutex);
Debug( LDAP_DEBUG_TRACE, "parent does not exist\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
......@@ -94,32 +73,62 @@ ldbm_back_add(
free( matched );
}
rc = -1;
goto return_results;
entry_free( e );
free( dn );
return -1;
}
if ( ! access_allowed( be, conn, op, p, "children", NULL,
op->o_dn, ACL_WRITE ) ) {
op->o_dn, ACL_WRITE ) )
{
pthread_mutex_unlock(&li->li_add_mutex);
Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
"", "" );
rc = -1;
goto return_results;
entry_free( e );
free( dn );
return -1;
}
} else {
if ( ! be_isroot( be, op->o_dn ) ) {
pthread_mutex_unlock(&li->li_add_mutex);
Debug( LDAP_DEBUG_TRACE, "no parent & not root\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
"", "" );
rc = -1;
goto return_results;
entry_free( e );
free( dn );
return -1;
}
}
/*
* Try to add the entry to the cache, assign it a new dnid
* and mark it locked. This should only fail if the entry
* already exists.
*/
e->e_id = next_id( be );
if ( cache_add_entry_lock( &li->li_cache, e, ENTRY_STATE_CREATING ) != 0 ) {
pthread_mutex_unlock(&li->li_add_mutex);
Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0,
0 );
next_id_return( be, e->e_id );
/* XXX this should be ok, no other thread should have access
* because e hasn't been added to the cache yet
*/
entry_free( e );
free( dn );
send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, "", "" );
return( -1 );
}
/*
* add it to the id2children index for the parent
*/
......@@ -192,5 +201,8 @@ return_results:;
cache_return_entry_r( &li->li_cache, p );
}
/* it might actually be okay to release this lock sooner */
pthread_mutex_unlock(&li->li_add_mutex);
return( rc );
}
......@@ -106,6 +106,7 @@ struct attrinfo {
struct ldbminfo {
ID li_nextid;
pthread_mutex_t li_add_mutex;
pthread_mutex_t li_nextid_mutex;
int li_mode;
char *li_directory;
......
......@@ -20,6 +20,7 @@
int
ldbm_back_group(
Backend *be,
Entry *target,
char *bdn,
char *edn,
char *objectclassValue,
......@@ -28,6 +29,7 @@ ldbm_back_group(
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
Entry *e;
char *tdn, *xdn;
char *matched;
Attribute *objectClass;
Attribute *member;
......@@ -38,15 +40,34 @@ ldbm_back_group(
Debug( LDAP_DEBUG_TRACE, "=> ldbm_back_group: objectClass: %s attrName: %s\n",
objectclassValue, groupattrName, 0 );
/* can we find bdn entry with reader lock */
if ((e = dn2entry_r(be, bdn, &matched )) == NULL) {
Debug( LDAP_DEBUG_TRACE, "=> ldbm_back_group: cannot find bdn: %s matched: %s\n", bdn, (matched ? matched : ""), 0 );
if (matched != NULL)
free(matched);
return( 1 );
tdn = dn_normalize_case( ch_strdup( target->e_dn ) );
xdn = dn_normalize_case( ch_strdup( bdn ) );
Debug( LDAP_DEBUG_TRACE, "=> ldbm_back_group: tdn: %s\n", tdn, 0, 0 );
if (strcmp(tdn, xdn) == 0) {
/* we already have a LOCKED copy of the entry */
e = target;
Debug( LDAP_DEBUG_ARGS,
"=> ldbm_back_group: target is bdn: %s\n",
bdn, 0, 0 );
} else {
/* can we find bdn entry with reader lock */
if ((e = dn2entry_r(be, bdn, &matched )) == NULL) {
Debug( LDAP_DEBUG_TRACE,
"=> ldbm_back_group: cannot find bdn: %s matched: %s\n",
bdn, (matched ? matched : ""), 0 );
if (matched != NULL)
free(matched);
free(tdn);
free(xdn);
return( 1 );
}
Debug( LDAP_DEBUG_ARGS,
"=> ldbm_back_group: found bdn: %s\n",
bdn, 0, 0 );
}
free(tdn);
free(xdn);
Debug( LDAP_DEBUG_ARGS, "=> ldbm_back_group: found bdn: %s\n", bdn, 0, 0 );
/* check for deleted */
......@@ -90,8 +111,10 @@ ldbm_back_group(
}
}
/* free entry and reader lock */
cache_return_entry_r( &li->li_cache, e );
if( target != e ) {
/* free entry and reader lock */
cache_return_entry_r( &li->li_cache, e );
}
Debug( LDAP_DEBUG_ARGS, "ldbm_back_group: rc: %d\n", rc, 0, 0 );
return(rc);
}
......
......@@ -63,6 +63,7 @@ ldbm_back_init(
free( argv[ 1 ] );
/* initialize various mutex locks & condition variables */
pthread_mutex_init( &li->li_add_mutex, pthread_mutexattr_default );
pthread_mutex_init( &li->li_cache.c_mutex, pthread_mutexattr_default );
pthread_mutex_init( &li->li_nextid_mutex, pthread_mutexattr_default );
pthread_mutex_init( &li->li_dbcache_mutex, pthread_mutexattr_default );
......
......@@ -260,6 +260,7 @@ be_unbind(
int
be_group(
Backend *be,
Entry *e,
char *bdn,
char *edn,
char *objectclassValue,
......@@ -267,7 +268,8 @@ be_group(
)
{
if (be->be_group)
return(be->be_group(be, bdn, edn, objectclassValue, groupattrName));
return(be->be_group(be, e, bdn, edn,
objectclassValue, groupattrName));
else
return(1);
}
......
......@@ -254,7 +254,8 @@ extern struct acl *global_acl;
extern struct objclass *global_oc;
extern time_t currenttime;
extern int be_group LDAP_P((Backend *be, char *bdn, char *edn, char *objectclassValue, char *groupattrName));
extern int be_group LDAP_P((Backend *be, Entry *e,
char *bdn, char *edn, char *objectclassValue, char *groupattrName));
extern void init LDAP_P((void));
extern void be_unbind LDAP_P((Connection *conn, Operation *op));
extern void config_info LDAP_P((Connection *conn, Operation *op));
......@@ -293,7 +294,8 @@ extern void ldbm_back_abandon LDAP_P((Backend *be, Connection *c, Operation *o,
extern void ldbm_back_config LDAP_P((Backend *be, char *fname, int lineno, int argc, char **argv ));
extern void ldbm_back_init LDAP_P((Backend *be));
extern void ldbm_back_close LDAP_P((Backend *be));
extern int ldbm_back_group LDAP_P((Backend *be, char *bdn, char *edn, char *objectclassValue, char *groupattrName ));
extern int ldbm_back_group LDAP_P((Backend *be, Entry *target,
char *bdn, char *edn, char *objectclassValue, char *groupattrName ));
#endif
#ifdef SLAPD_PASSWD
......
......@@ -227,7 +227,9 @@ struct backend {
void (*be_close) LDAP_P((Backend *be));
#ifdef SLAPD_ACLGROUPS
int (*be_group) LDAP_P((Backend *be, char *bdn, char *edn, char *objectclassValue, char *groupattrName ));
int (*be_group) LDAP_P((Backend *be, Entry *e,
char *bdn, char *edn,
char *objectclassValue, char *groupattrName ));
#endif
};
......
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