Exemplo n.º 1
0
/* Function which wraps a filter with (AND !(objectclass=ldapsubentry)) */
void subentry_create_filter(Slapi_Filter** filter)
{
	Slapi_Filter *sub_filter = NULL;
	Slapi_Filter *new_filter = NULL;
    char *buf = slapi_ch_strdup("(!(objectclass=ldapsubentry))");
    sub_filter = slapi_str2filter( buf );
    new_filter = slapi_filter_join( LDAP_FILTER_AND, *filter, sub_filter );
	*filter = new_filter;
	slapi_ch_free((void **)&buf);
}
Exemplo n.º 2
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.º 3
0
/* Returns a copy of the Slapi_Filter pointer.  The caller should not free it */
Slapi_Filter* windows_private_get_deleted_filter(const Repl_Agmt *ra)
{
		Dirsync_Private *dp;

		LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_deleted_filter\n" );

	PR_ASSERT(ra);

		dp = (Dirsync_Private *) agmt_get_priv(ra);
		PR_ASSERT (dp);

		if (dp->deleted_filter == NULL) {
			char *string_filter = slapi_ch_strdup("(isdeleted=*)");
			/* The filter gets freed in windows_agreement_delete() */
			dp->deleted_filter = slapi_str2filter( string_filter );
			slapi_ch_free_string(&string_filter);
		}

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

		return dp->deleted_filter;
}
Exemplo n.º 4
0
/* Returns a copy of the Slapi_Filter pointer.  The caller should not free it */
Slapi_Filter* windows_private_get_directory_filter(const Repl_Agmt *ra)
{
		Dirsync_Private *dp;

		LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_get_directory_filter\n" );

	PR_ASSERT(ra);

		dp = (Dirsync_Private *) agmt_get_priv(ra);
		PR_ASSERT (dp);

		if (dp->directory_filter == NULL) {
			char *string_filter = slapi_ch_strdup("(&(|(objectclass=ntuser)(objectclass=ntgroup))(ntUserDomainId=*))");
			/* The filter gets freed in windows_agreement_delete() */
                        dp->directory_filter = slapi_str2filter( string_filter );
			slapi_ch_free_string(&string_filter);
		}

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

		return dp->directory_filter;
}
Exemplo n.º 5
0
/*
  Apply the pending changes in the e entry to our config struct.
  validate must have already been called
*/
static int 
pam_passthru_apply_config (Slapi_Entry* e)
{
    int rc = PAM_PASSTHRU_SUCCESS;
    char **excludes = NULL;
    char **includes = NULL;
    char *new_service = NULL;
    char *pam_ident_attr = NULL;
    char *map_method = NULL;
    char *dn = NULL;
    PRBool fallback;
    PRBool secure;
    Pam_PassthruConfig *entry = NULL;
    PRCList *list;
    Slapi_Attr *a = NULL;
    char *filter_str = NULL;
    int inserted = 0;

    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);
    new_service = slapi_entry_attr_get_charptr(e, PAMPT_SERVICE_ATTR);
    excludes = slapi_entry_attr_get_charray(e, PAMPT_EXCLUDES_ATTR);
    includes = slapi_entry_attr_get_charray(e, PAMPT_INCLUDES_ATTR);
    fallback = slapi_entry_attr_get_bool(e, PAMPT_FALLBACK_ATTR);
    filter_str = slapi_entry_attr_get_charptr(e, PAMPT_FILTER_ATTR);
    /* Require SSL/TLS if the secure attr is not specified.  We
     * need to check if the attribute is present to make this
     * determiniation. */
    if (slapi_entry_attr_find(e, PAMPT_SECURE_ATTR, &a) == 0) {
        secure = slapi_entry_attr_get_bool(e, PAMPT_SECURE_ATTR);
    } else {
        secure = PR_TRUE;
    }

    /* Allocate a config struct. */
    entry = (Pam_PassthruConfig *)
        slapi_ch_calloc(1, sizeof(Pam_PassthruConfig));
    if (NULL == entry) {
        rc = PAM_PASSTHRU_FAILURE;
        goto bail;
    }

    /* use the RDN method to derive the PAM identity by default*/
    entry->pamptconfig_map_method1 = PAMPT_MAP_METHOD_RDN;
    entry->pamptconfig_map_method2 = PAMPT_MAP_METHOD_NONE;
    entry->pamptconfig_map_method3 = PAMPT_MAP_METHOD_NONE;

    /* Fill in the struct. */
    dn = slapi_entry_get_ndn(e);
    if (dn) {
        entry->dn = slapi_ch_strdup(dn);
    }

    entry->pamptconfig_fallback = fallback;
    entry->pamptconfig_secure = secure;

    if (!entry->pamptconfig_service ||
        (new_service && PL_strcmp(entry->pamptconfig_service, new_service))) {
        slapi_ch_free_string(&entry->pamptconfig_service);
        entry->pamptconfig_service = new_service;
        new_service = NULL; /* config now owns memory */
    }

    /* get the list of excluded suffixes */
    pam_ptconfig_free_suffixes(entry->pamptconfig_excludes);
    entry->pamptconfig_excludes = pam_ptconfig_add_suffixes(excludes);

    /* get the list of included suffixes */
    pam_ptconfig_free_suffixes(entry->pamptconfig_includes);
    entry->pamptconfig_includes = pam_ptconfig_add_suffixes(includes);

    if (!entry->pamptconfig_pam_ident_attr ||
        (pam_ident_attr && PL_strcmp(entry->pamptconfig_pam_ident_attr, pam_ident_attr))) {
        slapi_ch_free_string(&entry->pamptconfig_pam_ident_attr);
        entry->pamptconfig_pam_ident_attr = pam_ident_attr;
        pam_ident_attr = NULL; /* config now owns memory */
    }

    if (map_method) {
        parse_map_method(map_method,
        &entry->pamptconfig_map_method1,
        &entry->pamptconfig_map_method2,
        &entry->pamptconfig_map_method3,
        NULL);
    }

    if (filter_str) {
        entry->filter_str = filter_str;
        filter_str = NULL; /* config now owns memory */
        entry->slapi_filter = slapi_str2filter(entry->filter_str);
    }

    /* Add config to list.  We just store at the tail. */
    if (!PR_CLIST_IS_EMPTY(pam_passthru_global_config)) {
        list = PR_LIST_HEAD(pam_passthru_global_config);
        while (list != pam_passthru_global_config) {
            list = PR_NEXT_LINK(list);

            if (pam_passthru_global_config == list) {
                /* add to tail */
                PR_INSERT_BEFORE(&(entry->list), list);
                slapi_log_err(SLAPI_LOG_CONFIG, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
                                "pam_passthru_apply_config - store [%s] at tail\n", entry->dn);
                inserted = 1;
                break;
            }
        }
    } else {
        /* first entry */
        PR_INSERT_LINK(&(entry->list), pam_passthru_global_config);
        slapi_log_err(SLAPI_LOG_CONFIG, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
                        "pam_passthru_apply_config - store [%s] at head \n", entry->dn);
        inserted = 1;
    }

  bail:
    if(!inserted){
    	pam_passthru_free_config_entry(&entry);
    }
    slapi_ch_free_string(&new_service);
    slapi_ch_free_string(&map_method);
    slapi_ch_free_string(&pam_ident_attr);
    slapi_ch_free_string(&filter_str);
    slapi_ch_array_free(excludes);
    slapi_ch_array_free(includes);

    return rc;
}
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_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.º 8
0
/*
 * Depending on the context, this routine may need to take the
 * acicache read lock.
*/
void
aclanom_gen_anomProfile (acl_lock_flag_t lock_flag)
{
	aci_t					*aci = NULL;
	int						i;
	Targetattr				**srcattrArray;
	Targetattr				*attr;
	struct	anom_profile	*a_profile;
	PRUint32				cookie;

	PR_ASSERT( lock_flag == DO_TAKE_ACLCACHE_READLOCK ||
				lock_flag == DONT_TAKE_ACLCACHE_READLOCK);

	/*
	 * This routine requires two locks:
	 * the one for the global cache in acllist_acicache_READ_LOCK() and
	 * the one for the anom profile.
	 * They _must_ be taken in the order presented here or there
	 * is a deadlock scenario with acllist_remove_aci_needsLock() which
	 * takes them is this order.
	*/

	if ( lock_flag == DO_TAKE_ACLCACHE_READLOCK ) {
		acllist_acicache_READ_LOCK();
	}
	ANOM_LOCK_WRITE  ();
	a_profile = acl_anom_profile;

	if ( (!acl_get_aclsignature()) || ( !a_profile) ||
			(a_profile->anom_signature ==  acl_get_aclsignature()) ) {
		ANOM_UNLOCK_WRITE ();
		if ( lock_flag == DO_TAKE_ACLCACHE_READLOCK ) {
			acllist_acicache_READ_UNLOCK();
		}
		return;
	}

	/* D0 we have one already. If we do, then clean it up */
	aclanom__del_profile(0);

	/* We have a new signature now */
	a_profile->anom_signature =  acl_get_aclsignature();

	slapi_log_err(SLAPI_LOG_ACL, plugin_name, "aclanom_gen_anomProfile - GENERATING ANOM USER PROFILE\n");
	/*
	** Go thru the ACL list and find all the ACLs  which apply to the 
	** anonymous user i.e anyone. we can generate a profile for that.
	** We will llok at the simple case i.e it matches 
	** cases not handled:
	**  1) When there is a mix if rule types ( allows & denies )
	**
	*/

	aci = acllist_get_first_aci ( NULL, &cookie );	
	while ( aci ) {
		int			a_numacl;
		struct slapi_filter	*f;
		char			**destattrArray;


		/* 
		 * We must not have a  rule like:  deny ( all )  userdn != "xyz" 
		 * or groupdn !=
		*/
		if ( (aci->aci_type &  ACI_HAS_DENY_RULE) &&
			( (aci->aci_type & ACI_CONTAIN_NOT_USERDN ) ||
			  (aci->aci_type & ACI_CONTAIN_NOT_GROUPDN)	||
				(aci->aci_type & ACI_CONTAIN_NOT_ROLEDN)) ){
			slapi_log_err(SLAPI_LOG_ACL, plugin_name, 
				"aclanom_gen_anomProfile - CANCELLING ANOM USER PROFILE BECAUSE OF DENY RULE\n");
			goto cleanup;
		}

		/* Must be a anyone rule */
		if ( aci->aci_elevel != ACI_ELEVEL_USERDN_ANYONE ) {
			aci =  acllist_get_next_aci ( NULL, aci, &cookie);
			continue;
		}
		if (! (aci->aci_access &  ( SLAPI_ACL_READ | SLAPI_ACL_SEARCH)) ) {
			aci =  acllist_get_next_aci ( NULL, aci, &cookie);
			continue;
		}
		/* If the rule has anything other than userdn = "ldap:///anyone"
		** let's not consider complex rules - let's make this lean.
		*/
		if ( aci->aci_ruleType & ~ACI_USERDN_RULE ){
			slapi_log_err(SLAPI_LOG_ACL, plugin_name, 
				"aclanom_gen_anomProfile - CANCELLING ANOM USER PROFILE BECAUSE OF COMPLEX RULE\n");
			goto cleanup;
		}

		/* Must not be a or have a 
		** 1 ) DENY RULE   2) targetfilter
		** 3) no target pattern ( skip monitor acl  )
		*/
		if ( aci->aci_type & ( ACI_HAS_DENY_RULE  | ACI_TARGET_PATTERN |
					ACI_TARGET_NOT | ACI_TARGET_FILTER_NOT )) {
			const char	*dn = slapi_sdn_get_dn ( aci->aci_sdn );

			/* see if this is a monitor acl */
			if (( strcasecmp ( dn, "cn=monitor") == 0 )  ||
			    /* cn=monitor,cn=ldbm: No such object */
			    ( strcasecmp ( dn, "cn=monitor,cn=ldbm") == 0 )) {
				aci =  acllist_get_next_aci ( NULL, aci, &cookie);
				continue;
			} else {
				/* clean up before leaving */
				slapi_log_err(SLAPI_LOG_ACL, plugin_name, 
					"aclanom_gen_anomProfile - CANCELLING ANOM USER PROFILE 1\n");
				goto cleanup;
			}

		}

		/* Now we have an ALLOW ACL which applies to anyone */
		a_numacl = a_profile->anom_numacls++;

		if ( a_profile->anom_numacls == ACL_ANOM_MAX_ACL ) {
			slapi_log_err(SLAPI_LOG_ACL, plugin_name, "aclanom_gen_anomProfile - CANCELLING ANOM USER PROFILE 2\n");
			goto cleanup;
		}

		if ( (f = aci->target) != NULL ) {
			char            *avaType;
			struct berval   *avaValue;
			slapi_filter_get_ava ( f, &avaType, &avaValue );

			a_profile->anom_targetinfo[a_numacl].anom_target = 
						slapi_sdn_new_dn_byval ( avaValue->bv_val );
		} else {
			a_profile->anom_targetinfo[a_numacl].anom_target = 
						slapi_sdn_dup ( aci->aci_sdn );
		}

		a_profile->anom_targetinfo[a_numacl].anom_filter =  NULL;
		if ( aci->targetFilterStr ) {
			a_profile->anom_targetinfo[a_numacl].anom_filter =  slapi_str2filter ( aci->targetFilterStr );
			if (NULL == a_profile->anom_targetinfo[a_numacl].anom_filter) {
				const char	*dn = slapi_sdn_get_dn ( aci->aci_sdn );
				slapi_log_err(SLAPI_LOG_ERR, plugin_name,
								"aclanom_gen_anomProfile - Invalid filter [%s] in anonymous aci in entry [%s]\n",
								aci->targetFilterStr, dn);
				goto cleanup;
			}
		}				

		i = 0;
		srcattrArray = aci->targetAttr;
		while ( srcattrArray[i])
			i++;

		a_profile->anom_targetinfo[a_numacl].anom_targetAttrs = 
					(char **) slapi_ch_calloc ( 1, (i+1) * sizeof(char *));

		srcattrArray = aci->targetAttr;
		destattrArray = a_profile->anom_targetinfo[a_numacl].anom_targetAttrs;

		i = 0;
		while ( srcattrArray[i] ) {
			attr = srcattrArray[i];
			if ( attr->attr_type & ACL_ATTR_FILTER ) {
				/* Do'nt want to support these kind now */
				destattrArray[i] = NULL;
				/* clean up before leaving */
				aclanom__del_profile (0);
				slapi_log_err(SLAPI_LOG_ACL, plugin_name, 
					"aclanom_gen_anomProfile - CANCELLING ANOM USER PROFILE 3\n");
				goto cleanup;
			}

			destattrArray[i] = slapi_ch_strdup ( attr->u.attr_str );
			i++;
		}	

		destattrArray[i] = NULL;

		aclutil_print_aci ( aci, "anom" );	
		/*  Here we are storing att the info from the acls. However
		** we are only interested in a few things like ACI_TARGETATTR_NOT.
		*/
		a_profile->anom_targetinfo[a_numacl].anom_type = aci->aci_type;
		a_profile->anom_targetinfo[a_numacl].anom_access = aci->aci_access;
		
		aci =  acllist_get_next_aci ( NULL, aci, &cookie);
	}

	ANOM_UNLOCK_WRITE ();
	if ( lock_flag == DO_TAKE_ACLCACHE_READLOCK ) {
		acllist_acicache_READ_UNLOCK();
	}
	return;

cleanup:
	aclanom__del_profile (0);
	ANOM_UNLOCK_WRITE ();
	if ( lock_flag == DO_TAKE_ACLCACHE_READLOCK ) {
		acllist_acicache_READ_UNLOCK();
	}
}