andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone

Blame 0000-Trac-Ticket-340-Change-on-SLAPI_MODRDN_NEWSUPERIOR-i.patch

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