Exemple #1
0
/*
 * detect if the plugin should handle this entry and return the entry type
 */
int
ipa_topo_check_entry_type(Slapi_Entry *entry)
{
    int ret = TOPO_IGNORE_ENTRY;
    Slapi_DN *add_dn = NULL;
    char **ocs;

    add_dn = slapi_entry_get_sdn(entry);
    if (slapi_sdn_issuffix(add_dn,ipa_topo_get_plugin_shared_topo_dn())) {
        /* check if it is a toplogy or a segment */
        /* check if segment's left or right node is the local server*/
        int i;
        ocs = slapi_entry_attr_get_charray(entry,"objectclass");

        for (i=0; ocs && ocs[i]; i++) {
            if (strcasecmp(ocs[i],"ipaReplTopoConf") == 0) {
		ret = TOPO_CONFIG_ENTRY;
                break;
            } else if (strcasecmp(ocs[i],"ipaReplTopoSegment") == 0) {
		ret = TOPO_SEGMENT_ENTRY;
                break;
            }
        }
    } else if (slapi_sdn_isparent(ipa_topo_get_plugin_shared_hosts_dn(),add_dn)) {
        ret = TOPO_HOST_ENTRY;
    } else if (slapi_sdn_issuffix(add_dn,ipa_topo_get_domain_level_entry_dn())) {
        ret = TOPO_DOMLEVEL_ENTRY;
    }

    return ret;
}
Exemple #2
0
/*
 * searchAllSubtrees - search all subtrees in argv for entries
 *   with a named attribute matching the list of values, by
 *   calling search for each one.
 *
 * If 'attr' is NULL, the values are taken from 'values'.
 * If 'attr' is non-NULL, the values are taken from 'attr'.
 *
 * Return:
 *   LDAP_SUCCESS - no matches, or the attribute matches the
 *     target dn.
 *   LDAP_CONSTRAINT_VIOLATION - an entry was found that already
 *     contains the attribute value.
 *   LDAP_OPERATIONS_ERROR - a server failure.
 */
static int
searchAllSubtrees(int argc, char *argv[], const char *attrName,
  Slapi_Attr *attr, struct berval **values, const char *requiredObjectClass,
  Slapi_DN *dn)
{
  int result = LDAP_SUCCESS;

  /*
   * For each DN in the managed list, do uniqueness checking if
   * the target DN is a subnode in the tree.
   */
  for(;argc > 0;argc--,argv++)
  {
    Slapi_DN *sufdn = slapi_sdn_new_dn_byref(*argv);
    /*
     * The DN should already be normalized, so we don't have to
     * worry about that here.
     */
    if (slapi_sdn_issuffix(dn, sufdn)) {
      result = search(sufdn, attrName, attr, values, requiredObjectClass, dn);
      slapi_sdn_free(&sufdn);
      if (result) break;
    } else {
      slapi_sdn_free(&sufdn);
    }
  }
  return result;
}
Exemple #3
0
/*
 * This routine sets up a "context" for evaluation of access control
 * on a given entry for an anonymous user.
 * It just factors out the scope and targetfilter info into a list
 * of indices of the global anom profile list, that apply to this
 * entry, and stores them in the aclpb.
 * It's use relies on the way that access control is checked in the mailine search
 * code in the core server, namely: check filter, check entry, then check each
 * attribute.  So, we call this in acl_access_allowed() before calling
 * aclanom_match_profile()--therafter, aclanom_match_profile() uses the
 * context to evaluate access to the entry and attributes.
 * 
 * If there are no anom profiles, or the anom profiles get cancelled
 * due to complex anon acis, then that's OK, aclanom_match_profile()
 * returns -1 and the mainline acl code kicks in.
 *
 * The lifetime of this context info is the time it takes to check
 * access control for all parts of this entry (filter, entry, attributes).
 * So, if for an example an entry changes and a given anom profile entry
 * no longer applies, we will not notice until the next round of access
 * control checking on the entry--this is acceptable.
 * 
 * The gain on doing this factoring in the following type of search
 * was approx 6%:
 * anon bind, 20 threads, exact match, ~20 attributes returned, 
 * (searchrate & DirectoryMark).
 * 
*/
void
aclanom_get_suffix_info(Slapi_Entry *e,
							struct acl_pblock *aclpb ) {
	int i;
	char     *ndn = NULL;
	Slapi_DN    *e_sdn;
	const char    *aci_ndn;
	struct scoped_entry_anominfo *s_e_anominfo =
			&aclpb->aclpb_scoped_entry_anominfo;

	ANOM_LOCK_READ ();
		
	s_e_anominfo->anom_e_nummatched=0;

	ndn = slapi_entry_get_ndn ( e ) ;
	e_sdn= slapi_entry_get_sdn ( e ) ;
	for (i=acl_anom_profile->anom_numacls-1; i >= 0; i-- ) {
		aci_ndn = slapi_sdn_get_ndn (acl_anom_profile->anom_targetinfo[i].anom_target);
		if (!slapi_sdn_issuffix(e_sdn,acl_anom_profile->anom_targetinfo[i].anom_target)
				|| (!slapi_is_rootdse(ndn) && slapi_is_rootdse(aci_ndn)))
						continue;
		if ( acl_anom_profile->anom_targetinfo[i].anom_filter ) {
			if ( slapi_vattr_filter_test( aclpb->aclpb_pblock, e,
                               		acl_anom_profile->anom_targetinfo[i].anom_filter, 
					0 /*don't do acess chk*/)  != 0)
				continue;
		}
		s_e_anominfo->anom_e_targetInfo[s_e_anominfo->anom_e_nummatched]=i;
		s_e_anominfo->anom_e_nummatched++;
	}
	ANOM_UNLOCK_READ (); 
}
Exemple #4
0
static int ipa_topo_pre_entry_in_scope(Slapi_PBlock *pb)
{
    Slapi_DN *dn;
    static Slapi_DN *config_dn =  NULL;;

    slapi_pblock_get(pb, SLAPI_TARGET_SDN, &dn);
    if (config_dn == NULL) {
        config_dn = slapi_sdn_new_dn_byval("cn=mapping tree,cn=config");
        /* this rules out entries in regular backends and most of
         * cn=config entries.
         */
    }
    return slapi_sdn_issuffix(dn,config_dn);

}
Exemple #5
0
int slapi_sdn_scope_test( const Slapi_DN *dn, const Slapi_DN *base, int scope )
{
	int rc;

	switch ( scope ) {
	case LDAP_SCOPE_BASE:
		rc = ( slapi_sdn_compare( dn, base ) == 0 );
		break;
	case LDAP_SCOPE_ONELEVEL:
		rc = slapi_sdn_isparent( base, dn );
		break;
	case LDAP_SCOPE_SUBTREE:
		rc = slapi_sdn_issuffix( dn, base );
		break;
	default:
		rc = 0;
		break;
	}

	return rc;
}
Exemple #6
0
/* This function is called to process operation that come over external connections */
void
do_modrdn( Slapi_PBlock *pb )
{
	Slapi_Operation *operation;
	BerElement	*ber;
	char		*rawdn = NULL, *rawnewsuperior = NULL;
	const char	*dn = NULL, *newsuperior = NULL;
	char		*newrdn = NULL;
	int		err = 0, deloldrdn = 0;
	ber_len_t	len = 0;
	char		*newdn = NULL;
	char		*parent = NULL;
	Slapi_DN	sdn;
	Slapi_DN	snewdn;
	Slapi_DN	*snewsuperior = NULL;

	LDAPDebug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 );

	/* count the modrdn request */
	slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsModifyRDNOps);

	slapi_pblock_get( pb, SLAPI_OPERATION, &operation);
	ber = operation->o_ber;

	slapi_sdn_init(&sdn);
	slapi_sdn_init(&snewdn);

	/*
	 * Parse the modrdn request.  It looks like this:
	 *
	 *	ModifyRDNRequest := SEQUENCE {
	 *		entry		    DistinguishedName,
	 *		newrdn		    RelativeDistinguishedName,
	 *		deleteoldrdn	    BOOLEAN,
	 *		newSuperior	[0] LDAPDN OPTIONAL -- v3 only
	 *	}
	 */

	if (ber_scanf(ber, "{aab", &rawdn, &newrdn, &deloldrdn) == LBER_ERROR) {
		LDAPDebug( LDAP_DEBUG_ANY,
		    "ber_scanf failed (op=ModRDN; params=DN,newRDN,deleteOldRDN)\n",
		    0, 0, 0 );
		op_shared_log_error_access (pb, "MODRDN", "???", "decoding error");
		send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
		    "unable to decode DN, newRDN, or deleteOldRDN parameters",
		    0, NULL );
        goto free_and_return;
	}

	if ( ber_peek_tag( ber, &len ) == LDAP_TAG_NEWSUPERIOR ) {
		/* This "len" is not used... */
		if ( pb->pb_conn->c_ldapversion < LDAP_VERSION3 ) {
			LDAPDebug( LDAP_DEBUG_ANY,
			    "got newSuperior in LDAPv2 modrdn op\n", 0, 0, 0 );
			op_shared_log_error_access (pb, "MODRDN",
										rawdn?rawdn:"", "decoding error");
			send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
			    "received newSuperior in LDAPv2 modrdn", 0, NULL );
			slapi_ch_free_string( &rawdn );
			slapi_ch_free_string( &newrdn );
			goto free_and_return;
		}
		if ( ber_scanf( ber, "a", &rawnewsuperior ) == LBER_ERROR ) {
			LDAPDebug( LDAP_DEBUG_ANY,
			    "ber_scanf failed (op=ModRDN; params=newSuperior)\n",
			    0, 0, 0 );
			op_shared_log_error_access (pb, "MODRDN", rawdn, "decoding error");
			send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
			    "unable to decode newSuperior parameter", 0, NULL );
			slapi_ch_free_string( &rawdn );
			slapi_ch_free_string( &newrdn );
			goto free_and_return;
		}
	}

	/* Check if we should be performing strict validation. */
	if (config_get_dn_validate_strict()) {
		/* check that the dn is formatted correctly */
		err = slapi_dn_syntax_check(pb, rawdn, 1);
		if (err) { /* syntax check failed */
			op_shared_log_error_access(pb, "MODRDN", rawdn?rawdn:"",
							"strict: invalid dn");
			send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
							 NULL, "invalid dn", 0, NULL);
			slapi_ch_free_string( &rawdn );
			slapi_ch_free_string( &newrdn );
			slapi_ch_free_string( &rawnewsuperior );
			goto free_and_return;
		}
		/* check that the new rdn is formatted correctly */
		err = slapi_dn_syntax_check(pb, newrdn, 1);
		if (err) { /* syntax check failed */
			op_shared_log_error_access(pb, "MODRDN", newrdn?newrdn:"", 
							"strict: invalid new rdn");
			send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
							 NULL, "invalid new rdn", 0, NULL);
			slapi_ch_free_string( &rawdn );
			slapi_ch_free_string( &newrdn );
			slapi_ch_free_string( &rawnewsuperior );
			goto free_and_return;
		}
	}
	slapi_sdn_init_dn_passin(&sdn, rawdn);
	dn = slapi_sdn_get_dn(&sdn);
	if (rawdn && (strlen(rawdn) > 0) && (NULL == dn)) {
		/* normalization failed */
		op_shared_log_error_access(pb, "MODRDN", rawdn, "invalid dn");
		send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, 
		                 "invalid dn", 0, NULL);
		slapi_ch_free_string( &newrdn );
		slapi_ch_free_string( &rawnewsuperior );
		goto free_and_return;
	}

	if (rawnewsuperior) {
		if (config_get_dn_validate_strict()) {
			/* check that the dn is formatted correctly */
			err = slapi_dn_syntax_check(pb, rawnewsuperior, 1);
			if (err) { /* syntax check failed */
				op_shared_log_error_access(pb, "MODRDN", rawnewsuperior,
							"strict: invalid new superior");
				send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
								 NULL, "invalid new superior", 0, NULL);
				slapi_ch_free_string( &rawnewsuperior );
				goto free_and_return;
			}
		}
		snewsuperior = slapi_sdn_new_dn_passin(rawnewsuperior);
		newsuperior = slapi_sdn_get_dn(snewsuperior);
	}

	/*
	 * If newsuperior is myself or my descendent, the modrdn should fail.
	 * Note: need to check the case newrdn is given, and newsuperior
	 * uses the newrdn, as well.
	 */ 
	parent = slapi_dn_parent(slapi_sdn_get_ndn(&sdn));
	newdn = slapi_ch_smprintf("%s,%s", newrdn, parent);
	/* slapi_sdn_init_normdn_passin expects normalized but NOT
	 * decapitalized dn */
	slapi_sdn_init_dn_passin(&snewdn, newdn);
	if (0 == slapi_sdn_compare(&sdn, snewsuperior) ||
	    0 == slapi_sdn_compare(&snewdn, snewsuperior)) {
		op_shared_log_error_access(pb, "MODRDN", newsuperior,
						 "new superior is identical to the entry dn");
		send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
						 "new superior is identical to the entry dn", 0, NULL);
		goto free_and_return;
	}
	if (slapi_sdn_issuffix(snewsuperior, &sdn) ||
	    slapi_sdn_issuffix(snewsuperior, &snewdn)) {
		/* E.g.,
		 * newsuperior: ou=sub,ou=people,dc=example,dc=com
		 * dn: ou=people,dc=example,dc=com
		 */
		op_shared_log_error_access(pb, "MODRDN", newsuperior,
						 "new superior is descendent of the entry");
		send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
						 "new superior is descendent of the entry", 0, NULL);
		goto free_and_return;
	}

	/*
	 * in LDAPv3 there can be optional control extensions on
	 * the end of an LDAPMessage. we need to read them in and
	 * pass them to the backend.
	 */
	if ( (err = get_ldapmessage_controls( pb, ber, NULL )) != 0 ) {
		op_shared_log_error_access (pb, "MODRDN", dn, "failed to decode LDAP controls");
		send_ldap_result( pb, err, NULL, NULL, 0, NULL );
		goto free_and_return;
	}

	LDAPDebug( LDAP_DEBUG_ARGS,
			   "do_modrdn: dn (%s) newrdn (%s) deloldrdn (%d)\n", dn, newrdn,
			   deloldrdn );

	slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &pb->pb_op->o_isroot );
	/* dn, newrdn and newsuperior are all normalized */
	slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET,
	                  (void *)slapi_sdn_get_udn(&sdn) );
	slapi_pblock_set( pb, SLAPI_MODRDN_TARGET_SDN, &sdn );
	slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn );
	slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, (void *)snewsuperior );
	slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, &deloldrdn );

	op_shared_rename(pb, 0 /* do not pass in ownership of string arguments */ );

free_and_return:
	slapi_sdn_done(&sdn);
	slapi_ch_free_string(&newrdn);
	slapi_sdn_free(&snewsuperior);
	slapi_sdn_done(&snewdn);
	slapi_ch_free_string(&parent);

	return;
}
Exemple #7
0
/*
 * memberof_validate_config()
 *
 * Validate the pending changes in the e entry.
 */
int
memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, 
	int *returncode, char *returntext, void *arg)
{
	Slapi_Attr *memberof_attr = NULL;
	Slapi_Attr *group_attr = NULL;
	Slapi_DN *config_sdn = NULL;
	Slapi_DN **include_dn = NULL;
	Slapi_DN **exclude_dn = NULL;
	char *syntaxoid = NULL;
	char *config_dn = NULL;
	char *skip_nested = NULL;
	char *auto_add_oc = NULL;
	char **entry_scopes = NULL;
	char **entry_exclude_scopes = NULL;
	int not_dn_syntax = 0;
	int num_vals = 0;

	*returncode = LDAP_UNWILLING_TO_PERFORM; /* be pessimistic */

	/* Make sure both the group attr and the memberOf attr
	 * config atributes are supplied.  We don't care about &attr
	 * here, but slapi_entry_attr_find() requires us to pass it. */
	if (!slapi_entry_attr_find(e, MEMBEROF_GROUP_ATTR, &group_attr) &&
		!slapi_entry_attr_find(e, MEMBEROF_ATTR, &memberof_attr))
	{
		Slapi_Attr *test_attr = NULL;
		Slapi_Value *value = NULL;
		int hint = 0;

		/* Loop through each group attribute to see if the syntax is correct. */
		hint = slapi_attr_first_value(group_attr, &value);
		while (value && (not_dn_syntax == 0))
		{
			/* We need to create an attribute to find the syntax. */
			test_attr = slapi_attr_new();
			slapi_attr_init(test_attr, slapi_value_get_string(value));

			/* Get the syntax OID and see if it's the Distinguished Name or
			 * Name and Optional UID syntax. */
			slapi_attr_get_syntax_oid_copy(test_attr, &syntaxoid );
			not_dn_syntax = strcmp(syntaxoid, DN_SYNTAX_OID) & strcmp(syntaxoid, NAME_OPT_UID_SYNTAX_OID);
			slapi_ch_free_string(&syntaxoid);

			/* Print an error if the current attribute is not using the Distinguished
			 * Name syntax, otherwise get the next group attribute. */
			if (not_dn_syntax)
			{
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
					"The %s configuration attribute must be set to "
					"an attribute defined to use either the Distinguished "
					"Name or Name and Optional UID syntax. (illegal value: %s)",
					slapi_value_get_string(value), MEMBEROF_GROUP_ATTR);
			}
			else
			{
				hint = slapi_attr_next_value(group_attr, hint, &value);
			}

			/* Free the group attribute. */
			slapi_attr_free(&test_attr);
		}

		if (not_dn_syntax == 0)
		{
			/* Check the syntax of the memberof attribute. */
			slapi_attr_first_value(memberof_attr, &value);
			test_attr = slapi_attr_new();
			slapi_attr_init(test_attr, slapi_value_get_string(value));
			slapi_attr_get_syntax_oid_copy(test_attr, &syntaxoid );
			not_dn_syntax = strcmp(syntaxoid, DN_SYNTAX_OID);
			slapi_ch_free_string(&syntaxoid);
			slapi_attr_free(&test_attr);

			if (not_dn_syntax)
			{
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
					"The %s configuration attribute must be set to "
					"an attribute defined to use the Distinguished "
					"Name syntax.  (illegal value: %s)",
					slapi_value_get_string(value), MEMBEROF_ATTR);
				goto done;
			}
			else
			{
				*returncode = LDAP_SUCCESS;
			}
		}
	} else {
		PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
			"The %s and %s configuration attributes must be provided",
			MEMBEROF_GROUP_ATTR, MEMBEROF_ATTR); 
		goto done;
	}

	if ((skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_ATTR))){
		if(strcasecmp(skip_nested, "on") != 0 && strcasecmp(skip_nested, "off") != 0){
			PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
				"The %s configuration attribute must be set to "
				"\"on\" or \"off\".  (illegal value: %s)",
				MEMBEROF_SKIP_NESTED_ATTR, skip_nested);
			goto done;
		}
	}

	if ((auto_add_oc = slapi_entry_attr_get_charptr(e, MEMBEROF_AUTO_ADD_OC))){
		char *sup = NULL;

		/* Check if the objectclass exists by looking for its superior oc */
		if((sup = slapi_schema_get_superior_name(auto_add_oc)) == NULL){
			PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
				"The %s configuration attribute must be set to "
				"to an existing objectclass  (unknown: %s)",
				MEMBEROF_AUTO_ADD_OC, auto_add_oc);
			*returncode = LDAP_UNWILLING_TO_PERFORM;
			goto done;
		} else {
			slapi_ch_free_string(&sup);
		}
	}

	if ((config_dn = slapi_entry_attr_get_charptr(e, SLAPI_PLUGIN_SHARED_CONFIG_AREA))){
		/* Now check the shared config attribute, validate it now */

		Slapi_Entry *e = NULL;
		int rc = 0;

		rc = slapi_dn_syntax_check(pb, config_dn, 1);
		if (rc) { /* syntax check failed */
			slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_validate_config - "
					"%s does not contain a valid DN (%s)\n",
					SLAPI_PLUGIN_SHARED_CONFIG_AREA, config_dn);
			*returncode = LDAP_INVALID_DN_SYNTAX;
			goto done;
		}
		config_sdn = slapi_sdn_new_dn_byval(config_dn);

		slapi_search_internal_get_entry(config_sdn, NULL, &e, memberof_get_plugin_id());
		if(e){
			slapi_entry_free(e);
			*returncode = LDAP_SUCCESS;
		} else {
			/* config area does not exist! */
			PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
								"The %s configuration attribute points to an entry that  "
								"can not be found.  (%s)",
								SLAPI_PLUGIN_SHARED_CONFIG_AREA, config_dn);
			*returncode = LDAP_UNWILLING_TO_PERFORM;
		}
	}
	/*
	 * Check the entry scopes
	 */
	entry_scopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals);
	if(entry_scopes){
		int i = 0;

		/* Validate the syntax before we create our DN array */
		for (i = 0;i < num_vals; i++){
			if(slapi_dn_syntax_check(pb, entry_scopes[i], 1)){
				/* invalid dn syntax */
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
					"%s: Invalid DN (%s) for include suffix.",
					MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]);
				slapi_ch_array_free(entry_scopes);
				entry_scopes = NULL;
				theConfig.entryScopeCount = 0;
				*returncode = LDAP_UNWILLING_TO_PERFORM;
				goto done;
			}
		}
		/* Now create our SDN array for conflict checking */
		include_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1);
		for (i = 0;i < num_vals; i++){
			include_dn[i] = slapi_sdn_new_dn_passin(entry_scopes[i]);
		}
	}
	/*
	 * Check and process the entry exclude scopes
	 */
	entry_exclude_scopes =
		slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals);
	if(entry_exclude_scopes){
		int i = 0;

		/* Validate the syntax before we create our DN array */
		for (i = 0;i < num_vals; i++){
			if(slapi_dn_syntax_check(pb, entry_exclude_scopes[i], 1)){
				/* invalid dn syntax */
				PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
					"%s: Invalid DN (%s) for exclude suffix.",
					MEMBEROF_PLUGIN_SUBSYSTEM, entry_exclude_scopes[i]);
				slapi_ch_array_free(entry_exclude_scopes);
				entry_exclude_scopes = NULL;
				*returncode = LDAP_UNWILLING_TO_PERFORM;
				goto done;
			}
		}
		/* Now create our SDN array for conflict checking */
		exclude_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1);
		for (i = 0;i < num_vals; i++){
			exclude_dn[i] = slapi_sdn_new_dn_passin(entry_exclude_scopes[i]);
		}
	}
	/*
	 * Need to do conflict checking
	 */
	if(include_dn && exclude_dn){
		/*
		 * Make sure we haven't mixed the same suffix, and there are no
		 * conflicts between the includes and excludes
		 */
		int i = 0;

		while(include_dn[i]){
			int x = 0;
			while(exclude_dn[x]){
				if(slapi_sdn_compare(include_dn[i], exclude_dn[x] ) == 0)
				{
					/* we have a conflict */
					PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
						"%s: include suffix (%s) is also listed as an exclude suffix list",
						MEMBEROF_PLUGIN_SUBSYSTEM, slapi_sdn_get_dn(include_dn[i]));
					*returncode = LDAP_UNWILLING_TO_PERFORM;
					goto done;
			   }
			   x++;
			}
			i++;
		}

		/* Check for parent/child conflicts */
		i = 0;
		while(include_dn[i]){
			int x = 0;
			while(exclude_dn[x]){
				if(slapi_sdn_issuffix(include_dn[i], exclude_dn[x]))
				{
					/* we have a conflict */
					PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
						"%s: include suffix (%s) is a child of the exclude suffix(%s)",
						MEMBEROF_PLUGIN_SUBSYSTEM,
						slapi_sdn_get_dn(include_dn[i]),
						slapi_sdn_get_dn(exclude_dn[i]));
					*returncode = LDAP_UNWILLING_TO_PERFORM;
					goto done;
			   }
			   x++;
			}
			i++;
		}
	}

done:
	memberof_free_scope(exclude_dn, &num_vals);
	memberof_free_scope(include_dn,	&num_vals);
	slapi_ch_free((void**)&entry_scopes);
	slapi_ch_free((void**)&entry_exclude_scopes);
	slapi_sdn_free(&config_sdn);
	slapi_ch_free_string(&config_dn);
	slapi_ch_free_string(&skip_nested);
	slapi_ch_free_string(&auto_add_oc);

	if (*returncode != LDAP_SUCCESS)
	{
		return SLAPI_DSE_CALLBACK_ERROR;
	}
	else
	{
		return SLAPI_DSE_CALLBACK_OK;
	}
}
Exemple #8
0
static int
linked_attrs_add_backlinks_callback(Slapi_Entry *e, void *callback_data)
{
    int rc = 0;
    char *linkdn = slapi_entry_get_dn(e);
    struct configEntry *config = (struct configEntry *)callback_data;
    Slapi_PBlock *pb = slapi_pblock_new();
    int i = 0;
    char **targets = NULL;
    char *val[2];
    LDAPMod mod;
    LDAPMod *mods[2];

    /* Setup the modify operation.  Only the target will
     * change, so we only need to do this once. */
    val[0] = linkdn;
    val[1] = 0;

    mod.mod_op = LDAP_MOD_ADD;
    mod.mod_type = config->managedtype;
    mod.mod_values = val;

    mods[0] = &mod;
    mods[1] = 0;

    targets = slapi_entry_attr_get_charray(e, config->linktype);
    for (i = 0; targets && targets[i]; ++i) {
        char *targetdn = (char *)targets[i];
        int perform_update = 0;
        Slapi_DN *targetsdn = NULL;

        if (slapi_is_shutting_down()) {
            rc = -1;
            goto done;
        }

        targetsdn = slapi_sdn_new_normdn_byref(targetdn);
        if (config->scope) {
            /* Check if the target is within the scope. */
            perform_update = slapi_dn_issuffix(targetdn, config->scope);
        } else {
            /* Find out the root suffix that the linkdn is in
             * and see if the target is in the same backend. */
            Slapi_Backend *be = NULL;
            Slapi_DN *linksdn = slapi_sdn_new_normdn_byref(linkdn);

            if ((be = slapi_be_select(linksdn))) {
                perform_update = slapi_sdn_issuffix(targetsdn, slapi_be_getsuffix(be, 0));
            }

            slapi_sdn_free(&linksdn);
        }

        if (perform_update) {
            slapi_log_error(SLAPI_LOG_PLUGIN, LINK_PLUGIN_SUBSYSTEM,
                            "Adding backpointer (%s) in entry (%s)\n",
                            linkdn, targetdn);

            /* Perform the modify operation. */
            slapi_modify_internal_set_pb_ext(pb, targetsdn, mods, 0, 0,
                                             linked_attrs_get_plugin_id(), 0);
            slapi_modify_internal_pb(pb);

            /* Initialize the pblock so we can reuse it. */
            slapi_pblock_init(pb);
        }
        slapi_sdn_free(&targetsdn);
    }

done:
    slapi_ch_array_free(targets);
    slapi_pblock_destroy(pb);

    return rc;
}