summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@totoro.usersys.redhat.com>2012-09-21 19:35:18 (GMT)
committerNoriko Hosoi <nhosoi@totoro.usersys.redhat.com>2012-09-21 20:40:02 (GMT)
commit5beb93d42efb807838c09c5fab898876876f8d09 (patch)
treef17e02877b7f86eb4a97b0c8ee9dbe7ed479bf38
parent940ac98613957b69c3b32e47ed50cd25d5a80542 (diff)
downloadds-5beb93d42efb807838c09c5fab898876876f8d09.zip
ds-5beb93d42efb807838c09c5fab898876876f8d09.tar.gz
ds-5beb93d42efb807838c09c5fab898876876f8d09.tar.xz
Trac Ticket #340 - Change on SLAPI_MODRDN_NEWSUPERIOR is not
evaluated in acl https://fedorahosted.org/389/ticket/340 Bug Description: When modrdn operation was executed, only newrdn change was passed to the acl plugin. Also, the change was used only for the acl search, but not for the acl target in the items in the acl cache. Fix Description: This patch also passes the newsuperior update to the acl plugin. And the modrdn updates are applied to the acl target in the acl cache.
-rw-r--r--ldap/servers/plugins/acl/acl.c77
-rw-r--r--ldap/servers/plugins/acl/acl.h5
-rw-r--r--ldap/servers/plugins/acl/aclgroup.c2
-rw-r--r--ldap/servers/plugins/acl/acllist.c48
-rw-r--r--ldap/servers/slapd/dn.c2
-rw-r--r--ldap/servers/slapd/plugin_acl.c30
6 files changed, 106 insertions, 58 deletions
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index 15e474e..3389404 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -170,9 +170,9 @@ acl_access_allowed_modrdn(
* Test if have access to make the first rdn of dn in entry e.
*/
-static int check_rdn_access( Slapi_PBlock *pb, Slapi_Entry *e, const char *dn,
- int access) {
-
+static int
+check_rdn_access( Slapi_PBlock *pb, Slapi_Entry *e, const char *dn, int access)
+{
char **dns;
char **rdns;
int retCode = LDAP_INSUFFICIENT_ACCESS;
@@ -655,7 +655,8 @@ cleanup_and_ret:
}
-static void print_access_control_summary( char *source, int ret_val, char *clientDn,
+static void
+print_access_control_summary( char *source, int ret_val, char *clientDn,
struct acl_pblock *aclpb,
char *right,
char *attr,
@@ -1524,11 +1525,12 @@ acl_check_mods(
*
**************************************************************************/
extern void
-acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
+acl_modified (Slapi_PBlock *pb, int optype, Slapi_DN *e_sdn, void *change)
{
struct berval **bvalue;
char **value;
int rv=0; /* returned value */
+ const char* n_dn;
char* new_RDN;
char* parent_DN;
char* new_DN;
@@ -1537,10 +1539,12 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
int j;
Slapi_Attr *attr = NULL;
Slapi_Entry *e = NULL;
- Slapi_DN *e_sdn;
aclUserGroup *ugroup = NULL;
- e_sdn = slapi_sdn_new_normdn_byval ( n_dn );
+ if (NULL == e_sdn) {
+ return;
+ }
+ n_dn = slapi_sdn_get_dn(e_sdn);
/* Before we proceed, Let's first check if we are changing any groups.
** If we are, then we need to change the signature
*/
@@ -1768,45 +1772,64 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
}
break;
- }/* case op is modify*/
+ }/* case op is modify*/
- case SLAPI_OPERATION_MODRDN:
-
- new_RDN = (char*) change;
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "acl_modified (MODRDN %s => \"%s\"\n",
- n_dn, new_RDN);
+ case SLAPI_OPERATION_MODRDN:
+ {
+ char **rdn_parent;
+ rdn_parent = (char **)change;
+ new_RDN = rdn_parent[0];
+ parent_DN = rdn_parent[1];
/* compute new_DN: */
- parent_DN = slapi_dn_parent (n_dn);
- if (parent_DN == NULL) {
- new_DN = new_RDN;
+ if (NULL == parent_DN) {
+ parent_DN = slapi_dn_parent(n_dn);
+ }
+ if (NULL == parent_DN) {
+ if (NULL == new_RDN) {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acl_modified (MODRDN %s => \"no change\"\n",
+ n_dn);
+ break;
+ } else {
+ new_DN = new_RDN;
+ }
} else {
- new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
+ if (NULL == new_RDN) {
+ Slapi_RDN *rdn= slapi_rdn_new();
+ slapi_sdn_get_rdn(e_sdn, rdn);
+ new_DN = slapi_create_dn_string("%s,%s", slapi_rdn_get_rdn(rdn),
+ parent_DN);
+ slapi_rdn_free(&rdn);
+ } else {
+ new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
+ }
}
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acl_modified (MODRDN %s => \"%s\"\n", n_dn, new_RDN);
/* Change the acls */
- acllist_acicache_WRITE_LOCK();
+ acllist_acicache_WRITE_LOCK();
/* acllist_moddn_aci_needsLock expects normalized new_DN,
* which is no need to be case-ignored */
acllist_moddn_aci_needsLock ( e_sdn, new_DN );
acllist_acicache_WRITE_UNLOCK();
/* deallocat the parent_DN */
- if (parent_DN != NULL) {
- slapi_ch_free ( (void **) &new_DN );
- slapi_ch_free ( (void **) &parent_DN );
+ if (parent_DN != NULL) {
+ slapi_ch_free_string(&new_DN);
+ if (parent_DN != rdn_parent[1]) {
+ slapi_ch_free_string(&parent_DN);
+ }
}
break;
-
- default:
+ } /* case op is modrdn */
+ default:
/* print ERROR */
break;
} /*optype switch */
-
- slapi_sdn_free ( &e_sdn );
-
}
+
/***************************************************************************
*
* acl__scan_for_acis
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index 4fa3e3f..28c38e7 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -796,7 +796,8 @@ int acl_read_access_allowed_on_attr ( Slapi_PBlock *pb, Slapi_Entry *e, char
struct berval *val, int access);
void acl_set_acllist (Slapi_PBlock *pb, int scope, char *base);
void acl_gen_err_msg(int access, char *edn, char *attr, char **errbuf);
-void acl_modified ( Slapi_PBlock *pb, int optype, char *dn, void *change);
+void acl_modified (Slapi_PBlock *pb, int optype, Slapi_DN *e_sdn, void *change);
+
int acl_access_allowed_disjoint_resource( Slapi_PBlock *pb, Slapi_Entry *e,
char *attr, struct berval *val, int access );
int acl_access_allowed_main ( Slapi_PBlock *pb, Slapi_Entry *e, char **attrs,
@@ -866,7 +867,7 @@ void acllist_print_tree ( Avlnode *root, int *depth, char *start, char *side);
AciContainer *acllist_get_aciContainer_new ( );
void acllist_done_aciContainer ( AciContainer *);
-aclUserGroup* aclg_find_userGroup (char *n_dn);
+aclUserGroup* aclg_find_userGroup (const char *n_dn);
void aclg_regen_ugroup_signature( aclUserGroup *ugroup);
void aclg_markUgroupForRemoval ( aclUserGroup *u_group );
void aclg_reader_incr_ugroup_refcnt(aclUserGroup* u_group);
diff --git a/ldap/servers/plugins/acl/aclgroup.c b/ldap/servers/plugins/acl/aclgroup.c
index c694293..2231304 100644
--- a/ldap/servers/plugins/acl/aclgroup.c
+++ b/ldap/servers/plugins/acl/aclgroup.c
@@ -213,7 +213,7 @@ aclg_reset_userGroup ( struct acl_pblock *aclpb )
*/
aclUserGroup*
-aclg_find_userGroup(char *n_dn)
+aclg_find_userGroup(const char *n_dn)
{
aclUserGroup *u_group = NULL;
int i;
diff --git a/ldap/servers/plugins/acl/acllist.c b/ldap/servers/plugins/acl/acllist.c
index 9b5363a..e8198af 100644
--- a/ldap/servers/plugins/acl/acllist.c
+++ b/ldap/servers/plugins/acl/acllist.c
@@ -600,7 +600,6 @@ void
acllist_init_scan (Slapi_PBlock *pb, int scope, const char *base)
{
Acl_PBlock *aclpb;
- int i;
AciContainer *root;
char *basedn = NULL;
int index;
@@ -671,11 +670,6 @@ acllist_init_scan (Slapi_PBlock *pb, int scope, const char *base)
aclpb->aclpb_state &= ~ACLPB_SEARCH_BASED_ON_LIST ;
acllist_acicache_READ_UNLOCK();
-
- i = 0;
- while ( i < aclpb_max_selected_acls && aclpb->aclpb_base_handles_index[i] != -1 ) {
- i++;
- }
}
/*
@@ -893,34 +887,50 @@ acllist_acicache_WRITE_LOCK( )
int
acllist_moddn_aci_needsLock ( Slapi_DN *oldsdn, char *newdn )
{
-
-
AciContainer *aciListHead;
AciContainer *head;
+ aci_t *acip;
+ const char *oldndn;
/* first get the container */
aciListHead = acllist_get_aciContainer_new ( );
slapi_sdn_free(&aciListHead->acic_sdn);
- aciListHead->acic_sdn = oldsdn;
-
+ aciListHead->acic_sdn = oldsdn;
if ( NULL == (head = (AciContainer *) avl_find( acllistRoot, aciListHead,
- (IFP) __acllist_aciContainer_node_cmp ) ) ) {
+ (IFP) __acllist_aciContainer_node_cmp ) ) ) {
slapi_log_error ( SLAPI_PLUGIN_ACL, plugin_name,
- "Can't find the acl in the tree for moddn operation:olddn%s\n",
- slapi_sdn_get_ndn ( oldsdn ));
+ "Can't find the acl in the tree for moddn operation:olddn%s\n",
+ slapi_sdn_get_ndn ( oldsdn ));
aciListHead->acic_sdn = NULL;
__acllist_free_aciContainer ( &aciListHead );
- return 1;
+ return 1;
}
-
- /* Now set the new DN */
- slapi_sdn_done ( head->acic_sdn );
- slapi_sdn_set_normdn_byval ( head->acic_sdn, newdn );
-
+ /* Now set the new DN */
+ slapi_sdn_set_normdn_byval(head->acic_sdn, newdn);
+
+ /* If necessary, reset the target DNs, as well. */
+ oldndn = slapi_sdn_get_ndn(oldsdn);
+ for (acip = head->acic_list; acip; acip = acip->aci_next) {
+ const char *ndn = slapi_sdn_get_ndn(acip->aci_sdn);
+ char *p = PL_strstr(ndn, oldndn);
+ if (p) {
+ if (p == ndn) {
+ /* target dn is identical, replace it with new DN*/
+ slapi_sdn_set_normdn_byval(acip->aci_sdn, newdn);
+ } else {
+ /* target dn is a descendent of olddn, merge it with new DN*/
+ char *mynewdn;
+ *p = '\0';
+ mynewdn = slapi_ch_smprintf("%s%s", ndn, newdn);
+ slapi_sdn_set_normdn_passin(acip->aci_sdn, mynewdn);
+ }
+ }
+ }
+
aciListHead->acic_sdn = NULL;
__acllist_free_aciContainer ( &aciListHead );
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 11e56a9..b79d0f2 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -2097,7 +2097,7 @@ slapi_sdn_set_normdn_byval(Slapi_DN *sdn, const char *normdn)
slapi_sdn_done(sdn);
sdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_DN);
if(normdn == NULL) {
- sdn->dn = slapi_ch_strdup(normdn);
+ sdn->dn = NULL;
sdn->ndn_len = 0;
} else {
sdn->dn = slapi_ch_strdup(normdn);
diff --git a/ldap/servers/slapd/plugin_acl.c b/ldap/servers/slapd/plugin_acl.c
index b878156..3bc3f21 100644
--- a/ldap/servers/slapd/plugin_acl.c
+++ b/ldap/servers/slapd/plugin_acl.c
@@ -134,11 +134,10 @@ int
plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
{
struct slapdplugin *p;
- char *dn;
int rc = 0;
- void *change = NULL;
- Slapi_Entry *te = NULL;
- Slapi_DN *sdn = NULL;
+ void *change = NULL;
+ Slapi_Entry *te = NULL;
+ Slapi_DN *sdn = NULL;
Operation *operation;
slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
@@ -146,7 +145,7 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
(void)slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
switch ( optype ) {
- case SLAPI_OPERATION_MODIFY:
+ case SLAPI_OPERATION_MODIFY:
(void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &change );
break;
case SLAPI_OPERATION_ADD:
@@ -158,11 +157,27 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
}
break;
case SLAPI_OPERATION_MODRDN:
+ {
+ void *mychange[2];
+ char *newrdn = NULL;
+ Slapi_DN *psdn = NULL;
+ char *pdn = NULL;
+
/* newrdn: "change" is normalized but not case-ignored */
/* The acl plugin expects normalized newrdn, but no need to be case-
* ignored. */
- (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &change );
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn );
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &psdn );
+ if (psdn) {
+ pdn = (char *)slapi_sdn_get_dn(psdn);
+ } else {
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR, &pdn );
+ }
+ mychange[0] = newrdn;
+ mychange[1] = pdn;
+ change = mychange;
break;
+ }
}
if (NULL == sdn) {
@@ -172,10 +187,9 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
}
/* call the global plugins first and then the backend specific */
- dn = (char*)slapi_sdn_get_ndn(sdn); /* jcm - Had to cast away const */
for ( p = get_plugin_list(PLUGIN_LIST_ACL); p != NULL; p = p->plg_next ) {
if (plugin_invoke_plugin_sdn(p, SLAPI_PLUGIN_ACL_MODS_UPDATE, pb, sdn)){
- rc = (*p->plg_acl_mods_update)(pb, optype, dn, change );
+ rc = (*p->plg_acl_mods_update)(pb, optype, sdn, change );
if ( rc != LDAP_SUCCESS ) break;
}
}