浏览代码

Resolves: 220532
Summary: Add access to RUV by users other than "cn=Directory Manager".

Nathan Kinder 17 年之前
父节点
当前提交
6e5a17f526

+ 8 - 2
ldap/servers/slapd/back-ldbm/ldbm_search.c

@@ -1203,11 +1203,17 @@ ldbm_back_next_search_entry_ext( Slapi_PBlock *pb, int use_extension )
           if((slapi_entry_flag_is_set(e->ep_entry,SLAPI_ENTRY_LDAPSUBENTRY) 
              && !filter_flag_is_set(filter,SLAPI_FILTER_LDAPSUBENTRY)) ||
             (slapi_entry_flag_is_set(e->ep_entry,SLAPI_ENTRY_FLAG_TOMBSTONE)
-             && (!isroot || !filter_flag_is_set(filter, SLAPI_FILTER_TOMBSTONE))))
+             && ((!isroot && !filter_flag_is_set(filter, SLAPI_FILTER_RUV)) ||
+             !filter_flag_is_set(filter, SLAPI_FILTER_TOMBSTONE))))
           {
             /* If the entry is an LDAP subentry and filter don't filter subentries OR 
              * the entry is a TombStone and filter don't filter Tombstone 
-             * don't return the entry
+             * don't return the entry.  We make a special case to allow a non-root user
+             * to search for the RUV entry using a filter of:
+             *
+             *     "(&(objectclass=nstombstone)(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff))"
+             *
+             * For this RUV case, we let the ACL check apply.
              */
             /* ugaston - we don't want to mistake this filter failure with the one below due to ACL, 
              * because whereas the former should be read as 'no entry must be returned', the latter

+ 41 - 10
ldap/servers/slapd/filter.c

@@ -54,14 +54,15 @@
 static int
 get_filter_list( Connection *conn, BerElement *ber,
 		struct slapi_filter **f, char **fstr, int maxdepth, int curdepth,
-		int *subentry_dont_rewrite, int *has_tombstone_filter);
+		int *subentry_dont_rewrite, int *has_tombstone_filter, int *has_ruv_filter);
 static int	get_substring_filter();
 static int	get_extensible_filter( BerElement *ber, mr_filter_t* );
 
 static int get_filter_internal( Connection *conn, BerElement *ber,
 		struct slapi_filter **filt, char **fstr, int maxdepth, int curdepth,
-		int *subentry_dont_rewrite, int *has_tombstone_filter);
+		int *subentry_dont_rewrite, int *has_tombstone_filter, int *has_ruv_filter);
 static int tombstone_check_filter(Slapi_Filter *f);
+static int ruv_check_filter(Slapi_Filter *f);
 static void filter_optimize(Slapi_Filter *f);
 
 
@@ -83,20 +84,23 @@ get_filter( Connection *conn, BerElement *ber, int scope,
 {
 	int subentry_dont_rewrite = 0; /* Re-write unless we're told not to */
 	int has_tombstone_filter = 0; /* Check if nsTombstone appears */
+	int has_ruv_filter = 0;       /* Check if searching for RUV */
 	int return_value = 0;
 	char 	*logbuf = NULL;
 	size_t	logbufsize = 0;
 
 	return_value = get_filter_internal(conn, ber, filt, fstr,
 			config_get_max_filter_nest_level(),	/* maximum depth */
-			0, /* current depth */
-			&subentry_dont_rewrite, &has_tombstone_filter);
+			0, /* current depth */ &subentry_dont_rewrite,
+			&has_tombstone_filter, &has_ruv_filter);
 
 	if (0 == return_value) { /* Don't try to re-write if there was an error */
 		if (subentry_dont_rewrite || scope == LDAP_SCOPE_BASE)
 		  (*filt)->f_flags |= SLAPI_FILTER_LDAPSUBENTRY;
 		if (has_tombstone_filter)
 			(*filt)->f_flags |= SLAPI_FILTER_TOMBSTONE;
+		if (has_ruv_filter)
+			(*filt)->f_flags |= SLAPI_FILTER_RUV;
 	}
 
 	if (LDAPDebugLevelIsSet( LDAP_DEBUG_FILTER ) && *filt != NULL
@@ -175,7 +179,7 @@ filter_escape_filter_value(struct slapi_filter *f, const char *fmt, size_t len)
 static int
 get_filter_internal( Connection *conn, BerElement *ber, 
 	struct slapi_filter **filt, char **fstr, int maxdepth, int curdepth,
-	int *subentry_dont_rewrite, int *has_tombstone_filter )
+	int *subentry_dont_rewrite, int *has_tombstone_filter, int *has_ruv_filter )
 {
     ber_len_t	len;
     int		err;
@@ -272,6 +276,18 @@ get_filter_internal( Connection *conn, BerElement *ber,
 					*has_tombstone_filter = tombstone_check_filter(f);
 				}
 			} 
+
+			if ( 0 == strcasecmp ( f->f_avtype, "nsuniqueid")) {
+				/*
+				 * Check if it's a RUV filter.
+				 * We need to do it once per filter, so if flag is already set,
+				 * don't bother doing it
+				 */
+				if (!(*has_ruv_filter)) {
+					*has_ruv_filter = ruv_check_filter(f);
+				}
+			}
+
 			*fstr=filter_escape_filter_value(f, FILTER_EQ_FMT, FILTER_EQ_LEN);
 		}
 		break;
@@ -342,7 +358,8 @@ get_filter_internal( Connection *conn, BerElement *ber,
 	case LDAP_FILTER_AND:
 		LDAPDebug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
 		if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp, maxdepth,
-					curdepth, subentry_dont_rewrite, has_tombstone_filter ))
+					curdepth, subentry_dont_rewrite,
+					has_tombstone_filter, has_ruv_filter ))
 					== 0 ) {
 			filter_compute_hash(f);
 			*fstr = slapi_ch_smprintf( "(&%s)", ftmp );
@@ -353,7 +370,8 @@ get_filter_internal( Connection *conn, BerElement *ber,
 	case LDAP_FILTER_OR:
 		LDAPDebug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
 		if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp, maxdepth,
-					curdepth, subentry_dont_rewrite, has_tombstone_filter ))
+					curdepth, subentry_dont_rewrite,
+					has_tombstone_filter, has_ruv_filter ))
 					== 0 ) {
 			filter_compute_hash(f);
 			*fstr = slapi_ch_smprintf( "(|%s)", ftmp );
@@ -365,7 +383,8 @@ get_filter_internal( Connection *conn, BerElement *ber,
 		LDAPDebug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
 		(void) ber_skip_tag( ber, &len );
 		if ( (err = get_filter_internal( conn, ber, &f->f_not, &ftmp, maxdepth,
-					curdepth, subentry_dont_rewrite, has_tombstone_filter ))
+					curdepth, subentry_dont_rewrite,
+					has_tombstone_filter, has_ruv_filter ))
 					== 0 ) {
 			filter_compute_hash(f);
 			*fstr = slapi_ch_smprintf( "(!%s)", ftmp );
@@ -394,7 +413,7 @@ static int
 get_filter_list( Connection *conn, BerElement *ber,
 				struct slapi_filter **f, char **fstr, int maxdepth,
 				int curdepth, int *subentry_dont_rewrite,
-				int *has_tombstone_filter)
+				int *has_tombstone_filter, int* has_ruv_filter)
 {
 	struct slapi_filter	**new;
 	int		err;
@@ -411,7 +430,8 @@ get_filter_list( Connection *conn, BerElement *ber,
 	    tag = ber_next_element( ber, &len, last ) ) {
 		char *ftmp;
 		if ( (err = get_filter_internal( conn, ber, new, &ftmp, maxdepth,
-					curdepth, subentry_dont_rewrite, has_tombstone_filter))
+					curdepth, subentry_dont_rewrite,
+					has_tombstone_filter, has_ruv_filter))
 					!= 0 ) {
 		    if ( *fstr != NULL ) {
 			slapi_ch_free((void**)fstr );
@@ -1450,6 +1470,17 @@ tombstone_check_filter(Slapi_Filter *f)
 	return 0; /* Not nsTombstone filter */
 }
 
+
+static int
+ruv_check_filter(Slapi_Filter *f)
+{
+	if ( 0 == strcasecmp ( f->f_avvalue.bv_val, "ffffffff-ffffffff-ffffffff-ffffffff")) {
+		return 1; /* Contains a RUV filter */
+	}
+	return 0; /* Not a RUV filter */
+}
+
+
 /* filter_optimize
  * ---------------
  * takes a filter and optimizes it for fast evaluation

+ 5 - 1
ldap/servers/slapd/plugin_internal_op.c

@@ -720,7 +720,11 @@ static int search_internal_callback_pb (Slapi_PBlock *pb, void *callback_data,
     op->o_search_referral_handler = internal_ref_entry_callback;
 	
     filter = slapi_str2filter(ifstr ? (fstr = slapi_ch_strdup(ifstr)) : NULL);
-    if(scope == LDAP_SCOPE_BASE) filter->f_flags |= (SLAPI_FILTER_LDAPSUBENTRY | SLAPI_FILTER_TOMBSTONE);
+    if(scope == LDAP_SCOPE_BASE) {
+        filter->f_flags |= (SLAPI_FILTER_LDAPSUBENTRY |
+                            SLAPI_FILTER_TOMBSTONE | SLAPI_FILTER_RUV);
+    }
+
     if (NULL == filter) 
 	{
     	send_ldap_result(pb, LDAP_FILTER_ERROR, NULL, NULL, 0, NULL);

+ 1 - 0
ldap/servers/slapd/slapi-private.h

@@ -68,6 +68,7 @@ extern "C" {
 /* filter */
 #define SLAPI_FILTER_LDAPSUBENTRY 1
 #define SLAPI_FILTER_TOMBSTONE 2
+#define SLAPI_FILTER_RUV 4
 #define SLAPI_ENTRY_LDAPSUBENTRY 2
 
 /*

+ 8 - 0
ldap/servers/slapd/str2filter.c

@@ -162,6 +162,7 @@ str2list( char *str, unsigned long ftype )
 		str = next;
 		f->f_flags |= ((*fp)->f_flags & SLAPI_FILTER_LDAPSUBENTRY);
 		f->f_flags |= ((*fp)->f_flags & SLAPI_FILTER_TOMBSTONE);
+		f->f_flags |= ((*fp)->f_flags & SLAPI_FILTER_RUV);
 		fp = &(*fp)->f_next;
 	}
 	*fp = NULL;
@@ -331,6 +332,13 @@ str2simple( char *str , int unescape_filter)
 			if (0 == strcasecmp (unqstr,SLAPI_ATTR_VALUE_TOMBSTONE))
 				f->f_flags |= SLAPI_FILTER_TOMBSTONE;
 		}
+
+		if((f->f_choice == LDAP_FILTER_EQUALITY) &&
+		   (0 == strncasecmp (str,"nsuniqueid",strlen("nsuniqueid")))) {
+			if (0 == strcasecmp (unqstr, "ffffffff-ffffffff-ffffffff-ffffffff"))
+				f->f_flags |= SLAPI_FILTER_RUV;
+		}
+
 	} if ( !unescape_filter ) {
 		f->f_avtype = slapi_ch_strdup( str );
 		f->f_avvalue.bv_val = slapi_ch_strdup ( value );