Exemplo n.º 1
0
int
slapi_search_internal_callback_pb( Slapi_PBlock *pb,
	void *callback_data,
	plugin_result_callback prc,
	plugin_search_entry_callback psec,
	plugin_referral_entry_callback prec )
{
	int			free_filter = 0;
	SlapReply		*rs;

	if ( pb == NULL ) {
		return -1;
	}

	PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH );

	rs = pb->pb_rs;

	/* search callback and arguments */
	slapi_pblock_set( pb, SLAPI_X_INTOP_RESULT_CALLBACK,         (void *)prc );
	slapi_pblock_set( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK,   (void *)psec );
	slapi_pblock_set( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK, (void *)prec );
	slapi_pblock_set( pb, SLAPI_X_INTOP_CALLBACK_DATA,           (void *)callback_data );

	if ( BER_BVISEMPTY( &pb->pb_op->ors_filterstr )) {
		rs->sr_err = LDAP_PARAM_ERROR;
		goto cleanup;
	}

	if ( pb->pb_op->ors_filter == NULL ) {
		pb->pb_op->ors_filter = slapi_str2filter( pb->pb_op->ors_filterstr.bv_val );
		if ( pb->pb_op->ors_filter == NULL ) {
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto cleanup;
		}

		free_filter = 1;
	}

	slapi_int_func_internal_pb( pb, op_search );

cleanup:
	if ( free_filter ) {
		slapi_filter_free( pb->pb_op->ors_filter, 1 );
		pb->pb_op->ors_filter = NULL;
	}

	slapi_pblock_delete_param( pb, SLAPI_X_INTOP_RESULT_CALLBACK );
	slapi_pblock_delete_param( pb, SLAPI_X_INTOP_SEARCH_ENTRY_CALLBACK );
	slapi_pblock_delete_param( pb, SLAPI_X_INTOP_REFERRAL_ENTRY_CALLBACK );
	slapi_pblock_delete_param( pb, SLAPI_X_INTOP_CALLBACK_DATA );

	return 0;
}
Exemplo n.º 2
0
void windows_agreement_delete(Repl_Agmt *ra)
{

	Dirsync_Private *dp = (Dirsync_Private *) agmt_get_priv(ra);
	LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_delete\n" );

	PR_ASSERT(dp  != NULL);
	
	winsync_plugin_call_destroy_agmt_cb(ra, dp->directory_subtree,
										dp->windows_subtree);

	slapi_sdn_free(&dp->directory_subtree);
	slapi_sdn_free(&dp->windows_subtree);
	slapi_filter_free(dp->directory_filter, 1);
	slapi_filter_free(dp->deleted_filter, 1);
	slapi_entry_free(dp->raw_entry);
	dp->raw_entry = NULL;
	dp->api_cookie = NULL;
	slapi_ch_free((void **)dp);

	LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_delete\n" );

}
Exemplo n.º 3
0
/*
 * __aclanom_del_profile
 *
 *	Cleanup the anonymous user's profile we have.
 * 
 *	ASSUMPTION: A WRITE LOCK HAS BEEN OBTAINED
 *
 */
void
aclanom__del_profile (int closing)
{
	int						i;
	struct	anom_profile	*a_profile;


	if ( (a_profile = acl_anom_profile) == NULL ) {
		return;
	}

	for ( i=0; i < a_profile->anom_numacls; i++ ) {
		int	j = 0;
		char	**destArray = a_profile->anom_targetinfo[i].anom_targetAttrs;

		/* Deallocate target */
		slapi_sdn_free ( &a_profile->anom_targetinfo[i].anom_target );
		
		/* Deallocate filter */
		if ( a_profile->anom_targetinfo[i].anom_filter )
			slapi_filter_free ( a_profile->anom_targetinfo[i].anom_filter, 1 );

		/* Deallocate attrs */
		if ( destArray ) {
			while ( destArray[j] ) {
				slapi_ch_free ( (void **) &destArray[j] );
				j++;
			}
			slapi_ch_free ( (void **) &destArray );
		}
		a_profile->anom_targetinfo[i].anom_targetAttrs = NULL;
		a_profile->anom_targetinfo[i].anom_type = 0;
        a_profile->anom_targetinfo[i].anom_access = 0;
	}
	a_profile->anom_numacls = 0;

	if(closing){
		slapi_destroy_rwlock(anom_rwlock);
		anom_rwlock = NULL;
		slapi_ch_free((void **)&acl_anom_profile);
	}

	/* Don't clean the signatue */
}
Exemplo n.º 4
0
/*
 * Free a config struct.
 */
static void
pam_passthru_free_config_entry(Pam_PassthruConfig **entry)
{
    Pam_PassthruConfig *e = *entry;

    if (e == NULL) {
        return;
    }

    slapi_ch_free_string(&e->dn);
    pam_ptconfig_free_suffixes(e->pamptconfig_includes);
    pam_ptconfig_free_suffixes(e->pamptconfig_excludes);
    slapi_ch_free_string(&e->pamptconfig_pam_ident_attr);
    slapi_ch_free_string(&e->pamptconfig_service);
    slapi_ch_free_string(&e->filter_str);
    slapi_filter_free(e->slapi_filter, 1);

    slapi_ch_free((void **) entry);
}
Exemplo n.º 5
0
/*
 * memberof_free_config()
 *
 * Free's the contents of a config structure.
 */
void
memberof_free_config(MemberOfConfig *config)
{
	if (config)
	{
		int i = 0;

		slapi_ch_array_free(config->groupattrs);
		slapi_filter_free(config->group_filter, 1);

		for (i = 0; config->group_slapiattrs && config->group_slapiattrs[i]; i++)
		{
			slapi_attr_free(&config->group_slapiattrs[i]);
		}
		slapi_ch_free((void **)&config->group_slapiattrs);
		slapi_ch_free_string(&config->auto_add_oc);
		slapi_ch_free_string(&config->memberof_attr);
		memberof_free_scope(config->entryScopes, &config->entryScopeCount);
		memberof_free_scope(config->entryScopeExcludeSubtrees, &config->entryExcludeScopeCount);
	}
}
Exemplo n.º 6
0
/*
 * Validate the pending changes in the e entry.
 * If returntext is NULL, we log messages about invalid config
 * to the errors log.
 */
int 
pam_passthru_validate_config (Slapi_Entry* e, char *returntext)
{
	int rc = PAM_PASSTHRU_FAILURE;
	char *missing_suffix_str = NULL;
	int missing_suffix;
	int ii;
	char **excludes = NULL;
	char **includes = NULL;
	char *pam_ident_attr = NULL;
	char *map_method = NULL;
	char *pam_filter_str = NULL;
	Slapi_Filter *pam_filter = NULL;

	/* first, get the missing_suffix flag and validate it */
	missing_suffix_str = slapi_entry_attr_get_charptr(e, PAMPT_MISSING_SUFFIX_ATTR);
	if ((missing_suffix = missing_suffix_to_int(missing_suffix_str)) < 0 ||
		!check_missing_suffix_flag(missing_suffix)) {
		if (returntext) {
			PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
					"Error: valid values for %s are %s",
					PAMPT_MISSING_SUFFIX_ATTR, get_missing_suffix_values());
		} else {
			slapi_log_err(SLAPI_LOG_ERR, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
					"pam_passthru_validate_config - Valid values for %s are %s\n",
					PAMPT_MISSING_SUFFIX_ATTR, get_missing_suffix_values());
		}
		goto done;
	}

	if (missing_suffix != PAMPT_MISSING_SUFFIX_IGNORE) {
		char **missing_list = NULL;

		/* get the list of excluded suffixes */
		excludes = slapi_entry_attr_get_charray(e, PAMPT_EXCLUDES_ATTR);
		for (ii = 0; excludes && excludes[ii]; ++ii) {
			/* The excludes DNs are already normalized. */
			Slapi_DN *comp_dn = slapi_sdn_new_normdn_byref(excludes[ii]);
			if (!slapi_be_exist(comp_dn)) {
				charray_add(&missing_list, slapi_ch_strdup(excludes[ii]));
			}
			slapi_sdn_free(&comp_dn);
		}

		/* get the list of included suffixes */
		includes = slapi_entry_attr_get_charray(e, PAMPT_INCLUDES_ATTR);
		for (ii = 0; includes && includes[ii]; ++ii) {
			/* The includes DNs are already normalized. */
			Slapi_DN *comp_dn = slapi_sdn_new_normdn_byref(includes[ii]);
			if (!slapi_be_exist(comp_dn)) {
				charray_add(&missing_list, slapi_ch_strdup(includes[ii]));
			}
			slapi_sdn_free(&comp_dn);
		}

		if (missing_list) {
			if (returntext) {
				PRUint32 size =
					PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
								"The following suffixes listed in %s or %s are not present in this "
								"server: ", PAMPT_EXCLUDES_ATTR, PAMPT_INCLUDES_ATTR);
				for (ii = 0; missing_list[ii]; ++ii) {
					if (size < SLAPI_DSE_RETURNTEXT_SIZE) {
						size += PR_snprintf(returntext+size, SLAPI_DSE_RETURNTEXT_SIZE-size,
											"%s%s", (ii > 0) ? "; " : "",
											missing_list[ii]);
					}
				}
			} else {
				slapi_log_err(SLAPI_LOG_ERR, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
							"pam_passthru_validate_config - The suffixes listed in %s or %s are not present in "
							"this server\n", PAMPT_EXCLUDES_ATTR, PAMPT_INCLUDES_ATTR);
			}

			slapi_ch_array_free(missing_list);
			missing_list = NULL;
			print_suffixes();
			if (missing_suffix != PAMPT_MISSING_SUFFIX_ERROR) {
				if (returntext) {
					slapi_log_err(SLAPI_LOG_ERR, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
									"pam_passthru_validate_config - Warning: %s\n", returntext);
					*returntext = 0; /* log error, don't report back to user */
				}
			} else {
				goto done;
			}
		}
	}

	pam_ident_attr = slapi_entry_attr_get_charptr(e, PAMPT_PAM_IDENT_ATTR);
	map_method = slapi_entry_attr_get_charptr(e, PAMPT_MAP_METHOD_ATTR);
	if (map_method) {
		int one, two, three;
		if (PAM_PASSTHRU_SUCCESS !=
			(rc = parse_map_method(map_method, &one, &two, &three, returntext))) {
			goto done; /* returntext set already (or error logged) */
		}
		if (!pam_ident_attr &&
			((one == PAMPT_MAP_METHOD_ENTRY) || (two == PAMPT_MAP_METHOD_ENTRY) ||
			 (three == PAMPT_MAP_METHOD_ENTRY))) {
			if (returntext) {
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: the %s method"
							" was specified, but no %s was given",
							PAMPT_MAP_METHOD_ENTRY_STRING, PAMPT_PAM_IDENT_ATTR);
			} else {
				slapi_log_err(SLAPI_LOG_ERR, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
							"pam_passthru_validate_config - The %s method was specified, but no %s was given\n",
							PAMPT_MAP_METHOD_ENTRY_STRING, PAMPT_PAM_IDENT_ATTR);
			}
			rc = PAM_PASSTHRU_FAILURE;
			goto done;
		}
		if ((one == PAMPT_MAP_METHOD_NONE) && (two == PAMPT_MAP_METHOD_NONE) &&
			(three == PAMPT_MAP_METHOD_NONE)) {
			if (returntext) {
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no method(s)"
							" specified for %s, should be one or more of %s",
							PAMPT_MAP_METHOD_ATTR, get_map_method_values());
			} else {
				slapi_log_err(SLAPI_LOG_ERR, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
							"pam_passthru_validate_config - No method(s) specified for %s, should be "
							"one or more of %s\n", PAMPT_MAP_METHOD_ATTR,
							get_map_method_values());
			}
			rc = PAM_PASSTHRU_FAILURE;
			goto done;
		}
	}

	/* Validate filter by converting to Slapi_Filter */
	pam_filter_str = slapi_entry_attr_get_charptr(e, PAMPT_FILTER_ATTR);
	if (pam_filter_str) {
		pam_filter = slapi_str2filter(pam_filter_str);
		if (pam_filter == NULL) {
			if (returntext) {
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: invalid "
							"filter specified for %s (filter: \"%s\")",
							PAMPT_FILTER_ATTR, pam_filter_str);
			} else {
				slapi_log_err(SLAPI_LOG_ERR, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
							"pam_passthru_validate_config - Invalid filter specified for %s "
							"(filter: \"%s\")\n", PAMPT_FILTER_ATTR,
							pam_filter_str);
			}
			rc = PAM_PASSTHRU_FAILURE;
			goto done;
		}
	}

	/* success */
	rc = PAM_PASSTHRU_SUCCESS;

done:
	slapi_ch_free_string(&map_method);
	slapi_ch_free_string(&pam_ident_attr);
	slapi_ch_array_free(excludes);
	excludes = NULL;
	slapi_ch_array_free(includes);
	includes = NULL;
	slapi_ch_free_string(&missing_suffix_str);
	slapi_ch_free_string(&pam_filter_str);
	slapi_filter_free(pam_filter, 1);

	return rc;
}
Exemplo n.º 7
0
/*
 * memberof_copy_config()
 *
 * Makes a copy of the config in src.  This function will free the
 * elements of dest if they already exist.  This should only be called
 * if you hold the memberof config lock if src was obtained with
 * memberof_get_config().
 */
void
memberof_copy_config(MemberOfConfig *dest, MemberOfConfig *src)
{
	if (dest && src)
	{
		/* Check if the copy is already up to date */
		if (src->groupattrs)
		{
			int i = 0, j = 0;

			/* Copy group attributes string list. */
			slapi_ch_array_free(dest->groupattrs);
			dest->groupattrs = slapi_ch_array_dup(src->groupattrs);

			/* Copy group check filter. */
			slapi_filter_free(dest->group_filter, 1);
			dest->group_filter = slapi_filter_dup(src->group_filter);

			/* Copy group attributes Slapi_Attr list.
			 * First free the old list. */
			for (i = 0; dest->group_slapiattrs && dest->group_slapiattrs[i]; i++)
			{
				slapi_attr_free(&dest->group_slapiattrs[i]);
			}

			/* Count how many values we have in the source list. */
			for (j = 0; src->group_slapiattrs[j]; j++)
			{
				/* Do nothing. */
			}

			/* Realloc dest if necessary. */
			if (i < j)
			{
				dest->group_slapiattrs = (Slapi_Attr **)slapi_ch_realloc((char *)dest->group_slapiattrs, sizeof(Slapi_Attr *) * (j + 1));
			}

			/* Copy the attributes. */
			for (i = 0; src->group_slapiattrs[i]; i++)
			{
				dest->group_slapiattrs[i] = slapi_attr_dup(src->group_slapiattrs[i]);
			}

			/* Terminate the array. */
			dest->group_slapiattrs[i] = NULL;
		}

		if (src->memberof_attr)
		{
			slapi_ch_free_string(&dest->memberof_attr);
			dest->memberof_attr = slapi_ch_strdup(src->memberof_attr);
		}

		if(src->skip_nested){
			dest->skip_nested = src->skip_nested;
		}

		if(src->allBackends)
		{
			dest->allBackends = src->allBackends;
		}

		slapi_ch_free_string(&dest->auto_add_oc);
		dest->auto_add_oc = slapi_ch_strdup(src->auto_add_oc);

		if(src->entryScopes){
			int num_vals = 0;

			dest->entryScopes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),src->entryScopeCount+1);
			for(num_vals = 0; src->entryScopes[num_vals]; num_vals++){
				dest->entryScopes[num_vals] = slapi_sdn_dup(src->entryScopes[num_vals]);
			}
		}
		if(src->entryScopeExcludeSubtrees){
			int num_vals = 0;

			dest->entryScopeExcludeSubtrees = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),src->entryExcludeScopeCount+1);
			for(num_vals = 0; src->entryScopeExcludeSubtrees[num_vals]; num_vals++){
				dest->entryScopeExcludeSubtrees[num_vals] = slapi_sdn_dup(src->entryScopeExcludeSubtrees[num_vals]);
			}
		}
	}
}
Exemplo n.º 8
0
/*
 * memberof_apply_config()
 *
 * Apply the pending changes in the e entry to our config struct.
 * memberof_validate_config()  must have already been called.
 */
int
memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, 
	int *returncode, char *returntext, void *arg)
{
	Slapi_Entry *config_entry = NULL;
	Slapi_DN *config_sdn = NULL;
	char **groupattrs = NULL;
	char *memberof_attr = NULL;
	char *filter_str = NULL;
	int num_groupattrs = 0;
	int groupattr_name_len = 0;
	char *allBackends = NULL;
	char **entryScopes = NULL;
	char **entryScopeExcludeSubtrees = NULL;
	char *sharedcfg = NULL;
	char *skip_nested = NULL;
	char *auto_add_oc = NULL;
	int num_vals = 0;

	*returncode = LDAP_SUCCESS;

	/*
	 * Check if this is a shared config entry
	 */
	sharedcfg = slapi_entry_attr_get_charptr(e, SLAPI_PLUGIN_SHARED_CONFIG_AREA);
	if(sharedcfg){
		if((config_sdn = slapi_sdn_new_dn_byval(sharedcfg))){
			slapi_search_internal_get_entry(config_sdn, NULL, &config_entry, memberof_get_plugin_id());
			if(config_entry){
				/* Set the entry to be the shared config entry.  Validation was done in preop */
				e = config_entry;
			} else {
				/* This should of been checked in preop validation */
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
					"memberof_apply_config - Failed to locate shared config entry (%s)",
					sharedcfg);
				slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM,"%s\n",returntext);
				*returncode = LDAP_UNWILLING_TO_PERFORM;
				goto done;
			}
		}
	}

	/*
	 * Apply the config settings
	 */
	groupattrs = slapi_entry_attr_get_charray(e, MEMBEROF_GROUP_ATTR);
	memberof_attr = slapi_entry_attr_get_charptr(e, MEMBEROF_ATTR);
	allBackends = slapi_entry_attr_get_charptr(e, MEMBEROF_BACKEND_ATTR);
	skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_ATTR);
	auto_add_oc = slapi_entry_attr_get_charptr(e, MEMBEROF_AUTO_ADD_OC);

	/*
	 * We want to be sure we don't change the config in the middle of
	 * a memberOf operation, so we obtain an exclusive lock here
	 */
	memberof_wlock_config();

	if (groupattrs)
	{
		int i = 0;

		slapi_ch_array_free(theConfig.groupattrs);
		theConfig.groupattrs = groupattrs;
		groupattrs = NULL; /* config now owns memory */

		/*
		 * We allocate a list of Slapi_Attr using the groupattrs for
		 * convenience in our memberOf comparison functions
		 */
		for (i = 0; theConfig.group_slapiattrs && theConfig.group_slapiattrs[i]; i++)
		{
			slapi_attr_free(&theConfig.group_slapiattrs[i]);
		}

		/* Count the number of groupattrs. */
		for (num_groupattrs = 0; theConfig.groupattrs && theConfig.groupattrs[num_groupattrs]; num_groupattrs++)
		{
			/*
			 * Add up the total length of all attribute names.  We need
			 * to know this for building the group check filter later.
			 */
			groupattr_name_len += strlen(theConfig.groupattrs[num_groupattrs]);
		}

		/* Realloc the list of Slapi_Attr if necessary. */
		if (i < num_groupattrs)
		{
			theConfig.group_slapiattrs = (Slapi_Attr **)slapi_ch_realloc((char *)theConfig.group_slapiattrs,
							sizeof(Slapi_Attr *) * (num_groupattrs + 1));
		}

		/* Build the new list */
		for (i = 0; theConfig.groupattrs[i]; i++)
		{
			theConfig.group_slapiattrs[i] = slapi_attr_new();
			slapi_attr_init(theConfig.group_slapiattrs[i], theConfig.groupattrs[i]);
		}

		/* Terminate the list. */
		theConfig.group_slapiattrs[i] = NULL;

		/* The filter is based off of the groupattr, so we update it here too. */
		slapi_filter_free(theConfig.group_filter, 1);

		if (num_groupattrs > 1)
		{
			int bytes_out = 0;
			int filter_str_len = groupattr_name_len + (num_groupattrs * 4) + 4;

			/* Allocate enough space for the filter */
			filter_str = slapi_ch_malloc(filter_str_len);

			/* Add beginning of filter. */
			bytes_out = snprintf(filter_str, filter_str_len - bytes_out, "(|");

			/* Add filter section for each groupattr. */
			for (i = 0; theConfig.groupattrs[i]; i++)
			{
				bytes_out += snprintf(filter_str + bytes_out, filter_str_len - bytes_out, "(%s=*)", theConfig.groupattrs[i]);
			}

			/* Add end of filter. */
			snprintf(filter_str + bytes_out, filter_str_len - bytes_out, ")");
		}
		else
		{
			filter_str = slapi_ch_smprintf("(%s=*)", theConfig.groupattrs[0]);
		}

		/*
		 * Log an error if we were unable to build the group filter for some
		 * reason.  If this happens, the memberOf plugin will not be able to
		 * check if an entry is a group, causing it to not catch changes.  This
		 * shouldn't happen, but there may be some garbage configuration that
		 * could trigger this.
		 */
		if ((theConfig.group_filter = slapi_str2filter(filter_str)) == NULL)
		{
			slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM,
				"memberof_apply_config - Unable to create the group check filter.  The memberOf "
				"plug-in will not operate on changes to groups.  Please check "
				"your %s configuration settings. (filter: %s)\n",
				MEMBEROF_GROUP_ATTR, filter_str );
		}

		slapi_ch_free_string(&filter_str);
	}

	if (memberof_attr)
	{
		slapi_ch_free_string(&theConfig.memberof_attr);
		theConfig.memberof_attr = memberof_attr;
		memberof_attr = NULL; /* config now owns memory */
	}

	if (skip_nested){
		if(strcasecmp(skip_nested,"on") == 0){
			theConfig.skip_nested = 1;
		} else {
			theConfig.skip_nested = 0;
		}
	}

	if (allBackends)
	{
		if(strcasecmp(allBackends,"on")==0){
			theConfig.allBackends = 1;
		} else {
			theConfig.allBackends = 0;
		}
	} else {
		theConfig.allBackends = 0;
	}

	theConfig.auto_add_oc = auto_add_oc;

	/*
	 * Check and process the entry scopes
	 */
	memberof_free_scope(theConfig.entryScopes, &theConfig.entryScopeCount);
	entryScopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals);
	if(entryScopes){
		int i = 0;

		/* Validation has already been performed in preop, just build the DN's */
		theConfig.entryScopes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1);
		for (i = 0;i < num_vals; i++){
			theConfig.entryScopes[i] = slapi_sdn_new_dn_passin(entryScopes[i]);
		}
		theConfig.entryScopeCount = num_vals; /* shortcut for config copy */
	}
	/*
	 * Check and process the entry exclude scopes
	 */
	memberof_free_scope(theConfig.entryScopeExcludeSubtrees,
	                    &theConfig.entryExcludeScopeCount);
	entryScopeExcludeSubtrees =
	    slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals);
	if(entryScopeExcludeSubtrees){
		int i = 0;

		/* Validation has already been performed in preop, just build the DN's */
		theConfig.entryScopeExcludeSubtrees =
				(Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1);
		for (i = 0;i < num_vals; i++){
			theConfig.entryScopeExcludeSubtrees[i] =
				slapi_sdn_new_dn_passin(entryScopeExcludeSubtrees[i]);
		}
		theConfig.entryExcludeScopeCount = num_vals; /* shortcut for config copy */
	}

	/* release the lock */
	memberof_unlock_config();

done:
	slapi_sdn_free(&config_sdn);
	slapi_entry_free(config_entry);
	slapi_ch_array_free(groupattrs);
	slapi_ch_free_string(&sharedcfg);
	slapi_ch_free_string(&memberof_attr);
	slapi_ch_free_string(&allBackends);
	slapi_ch_free_string(&skip_nested);
	slapi_ch_free((void **)&entryScopes);
	slapi_ch_free((void **)&entryScopeExcludeSubtrees);

	if (*returncode != LDAP_SUCCESS)
	{
		return SLAPI_DSE_CALLBACK_ERROR;
	}
	else
	{
		return SLAPI_DSE_CALLBACK_OK;
	}
}
Exemplo n.º 9
0
/*
 * Thread routine for sending search results to a client
 * which is persistently waiting for them.
 *
 * This routine will terminate when either (a) the ps_complete
 * flag is set, or (b) the associated operation is abandoned.
 * In any case, the thread won't notice until it wakes from
 * sleeping on the ps_list condition variable, so it needs
 * to be awakened.
 */
static void
ps_send_results( void *arg )
{
    PSearch *ps = (PSearch *)arg;
	PSEQNode *peq, *peqnext;
	struct slapi_filter *filter = 0;
	char *base = NULL;
	Slapi_DN *sdn = NULL;
	char *fstr = NULL;
	char **pbattrs = NULL;
	int conn_acq_flag = 0;
    
    g_incr_active_threadcnt();

    /* need to acquire a reference to this connection so that it will not
       be released or cleaned up out from under us */
    PR_Lock( ps->ps_pblock->pb_conn->c_mutex );
    conn_acq_flag = connection_acquire_nolock(ps->ps_pblock->pb_conn);    
    PR_Unlock( ps->ps_pblock->pb_conn->c_mutex );

	if (conn_acq_flag) {
		slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
						"conn=%" NSPRIu64 " op=%d Could not acquire the connection - psearch aborted\n",
						ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid);
	}

    PR_Lock( psearch_list->pl_cvarlock );

    while ( (conn_acq_flag == 0) && !ps->ps_complete ) {
	/* Check for an abandoned operation */
	if ( ps->ps_pblock->pb_op == NULL || slapi_op_abandoned( ps->ps_pblock ) ) {
		slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
						"conn=%" NSPRIu64 " op=%d The operation has been abandoned\n",
						ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid);
	    break;
	}
	if ( NULL == ps->ps_eq_head ) {
	    /* Nothing to do */
	    PR_WaitCondVar( psearch_list->pl_cvar, PR_INTERVAL_NO_TIMEOUT );
	} else {
	    /* dequeue the item */
	    int		attrsonly;
	    char	**attrs;
	    LDAPControl	**ectrls;
	    Slapi_Entry	*ec;
		Slapi_Filter	*f = NULL;
		
	    PR_Lock( ps->ps_lock );

		peq = ps->ps_eq_head;
		ps->ps_eq_head = peq->pe_next;
	    if ( NULL == ps->ps_eq_head ) {
			ps->ps_eq_tail = NULL;
	    }

	    PR_Unlock( ps->ps_lock );

	    /* Get all the information we need to send the result */
	    ec = peq->pe_entry;
	    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_ATTRS, &attrs );
	    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_ATTRSONLY, &attrsonly );
	    if ( !ps->ps_send_entchg_controls || peq->pe_ctrls[0] == NULL ) {
		ectrls = NULL;
	    } else {
		ectrls = peq->pe_ctrls;
	    }

	    /*
	     * Send the result.  Since send_ldap_search_entry can block for
	     * up to 30 minutes, we relinquish all locks before calling it.
	     */
	    PR_Unlock(psearch_list->pl_cvarlock);

		/*
		 * The entry is in the right scope and matches the filter
		 * but we need to redo the filter test here to check access
		 * controls. See the comments at the slapi_filter_test()
		 * call in ps_service_persistent_searches().		 
		*/
		slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_FILTER, &f );			

		/* See if the entry meets the filter and ACL criteria */
		if ( slapi_vattr_filter_test( ps->ps_pblock, ec, f,
			    1 /* verify_access */ ) == 0 ) {
			int rc = 0;
	    	slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_RESULT_ENTRY, ec );
	    	rc = send_ldap_search_entry( ps->ps_pblock, ec,
										 ectrls, attrs, attrsonly );
			if (rc) {
				slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
								"conn=%" NSPRIu64 " op=%d Error %d sending entry %s with op status %d\n",
								ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid,
								rc, slapi_entry_get_dn_const(ec), ps->ps_pblock->pb_op->o_status);
			}
		}
	    
		PR_Lock(psearch_list->pl_cvarlock);

		/* Deallocate our wrapper for this entry */
		pe_ch_free( &peq );
	}
    }
    PR_Unlock( psearch_list->pl_cvarlock );
    ps_remove( ps );

    /* indicate the end of search */
    plugin_call_plugins( ps->ps_pblock , SLAPI_PLUGIN_POST_SEARCH_FN );

	/* free things from the pblock that were not free'd in do_search() */
	/* we strdup'd this in search.c - need to free */
	slapi_pblock_get( ps->ps_pblock, SLAPI_ORIGINAL_TARGET_DN, &base );
	slapi_pblock_set( ps->ps_pblock, SLAPI_ORIGINAL_TARGET_DN, NULL );
	slapi_ch_free_string(&base);

	/* Free SLAPI_SEARCH_* before deleting op since those are held by op */
	slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_TARGET_SDN, &sdn );
	slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_TARGET_SDN, NULL );
	slapi_sdn_free(&sdn);

    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_STRFILTER, &fstr );
    slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_STRFILTER, NULL );
	slapi_ch_free_string(&fstr);

    slapi_pblock_get( ps->ps_pblock, SLAPI_SEARCH_ATTRS, &pbattrs );
    slapi_pblock_set( ps->ps_pblock, SLAPI_SEARCH_ATTRS, NULL );
	if ( pbattrs != NULL )
	{
		charray_free( pbattrs );
	}
	
	slapi_pblock_get(ps->ps_pblock, SLAPI_SEARCH_FILTER, &filter );
	slapi_pblock_set(ps->ps_pblock, SLAPI_SEARCH_FILTER, NULL );
	slapi_filter_free(filter, 1);

    /* Clean up the connection structure */
    PR_Lock( ps->ps_pblock->pb_conn->c_mutex );

	slapi_log_error(SLAPI_LOG_CONNS, "Persistent Search",
					"conn=%" NSPRIu64 " op=%d Releasing the connection and operation\n",
					ps->ps_pblock->pb_conn->c_connid, ps->ps_pblock->pb_op->o_opid);
    /* Delete this op from the connection's list */
    connection_remove_operation( ps->ps_pblock->pb_conn, ps->ps_pblock->pb_op );
    operation_free(&(ps->ps_pblock->pb_op),ps->ps_pblock->pb_conn);
    ps->ps_pblock->pb_op=NULL;

    /* Decrement the connection refcnt */
    if (conn_acq_flag == 0) { /* we acquired it, so release it */
	connection_release_nolock (ps->ps_pblock->pb_conn);
    }
    PR_Unlock( ps->ps_pblock->pb_conn->c_mutex );

    PR_DestroyLock ( ps->ps_lock );
    ps->ps_lock = NULL;

    slapi_ch_free((void **) &ps->ps_pblock );
	for ( peq = ps->ps_eq_head; peq; peq = peqnext) {
		peqnext = peq->pe_next;
		pe_ch_free( &peq );
	}
    slapi_ch_free((void **) &ps );
    g_decr_active_threadcnt();
}