예제 #1
0
/* if vs is given, delete only those values - otherwise, delete all values */
void
replica_updatedn_list_delete(ReplicaUpdateDNList list, const Slapi_ValueSet *vs)
{
	PLHashTable *hash = list;
	if (!vs || slapi_valueset_count(vs) == 0) { /* just delete everything */
		PL_HashTableEnumerateEntries(hash, replica_destroy_hash_entry, NULL);
	} else {
		Slapi_ValueSet *vs_nc = (Slapi_ValueSet *)vs; /* cast away const */
		Slapi_Value *val = NULL;
		int index = 0;
		for (index = slapi_valueset_first_value(vs_nc, &val); val;
			 index = slapi_valueset_next_value(vs_nc, index, &val)) {
			Slapi_DN *dn = slapi_sdn_new_dn_byval(slapi_value_get_string(val));
			/* locate object */
			Slapi_DN *deldn = (Slapi_DN *)PL_HashTableLookup(hash, slapi_sdn_get_ndn(dn));     
			if (deldn == NULL)
			{
				slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "replica_updatedn_list_delete -"
								"Update DN with value (%s) is not in the update DN list.\n",
								slapi_sdn_get_ndn(dn));
			} else {
				/* remove from hash */
				PL_HashTableRemove(hash, slapi_sdn_get_ndn(dn));
				/* free the pointer */
				slapi_sdn_free(&deldn);
			}
			/* free the temp dn */
			slapi_sdn_free(&dn);
		}
	}

	return;
}
예제 #2
0
파일: urp.c 프로젝트: ohamada/389ds
static char *
get_rdn_plus_uniqueid(char *sessionid, const char *olddn, const char *uniqueid)
{
	char *newrdn;
	/* Check if the RDN already contains the Unique ID */
	Slapi_DN *sdn= slapi_sdn_new_dn_byval(olddn);
	Slapi_RDN *rdn= slapi_rdn_new();
	slapi_sdn_get_rdn(sdn,rdn);
	PR_ASSERT(uniqueid!=NULL);
	if(slapi_rdn_contains(rdn,SLAPI_ATTR_UNIQUEID,uniqueid,strlen(uniqueid)))
	{
		/* The Unique ID is already in the RDN.
		 * This is a highly improbable collision.
		 * It suggests that a duplicate UUID was generated.
		 * This will cause replication divergence and will
		 * require admin intercession
		 */
		slapi_log_error(SLAPI_LOG_FATAL, sessionid,
				"Annotated DN %s has naming conflict\n", olddn );
		newrdn= NULL;
	}
	else
	{
		slapi_rdn_add(rdn,SLAPI_ATTR_UNIQUEID,uniqueid);
		newrdn= slapi_ch_strdup(slapi_rdn_get_rdn(rdn));
	}
	slapi_sdn_free(&sdn);
	slapi_rdn_free(&rdn);
	return newrdn;
}
예제 #3
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);

}
예제 #4
0
/* 
 * add  a list of dns to the ReplicaUpdateDNList.
 * The dn could be the dn of a group, so get the entry 
 * and check the objectclass. If it is a static or dynamic group
 * generate the list of member dns and recursively call 
 * replica_updatedn_list_add().
 * The dn of the group is added to the list, so it will detect 
 * potential circular group definitions
 */
void
replica_updatedn_list_add_ext(ReplicaUpdateDNList list, const Slapi_ValueSet *vs, int group_update)
{
	PLHashTable *hash = list;
	Slapi_ValueSet *vs_nc = (Slapi_ValueSet *)vs; /* cast away const */
	Slapi_Value *val = NULL;
	int index = 0;

	PR_ASSERT(list && vs);

	for (index = slapi_valueset_first_value(vs_nc, &val); val;
		 index = slapi_valueset_next_value(vs_nc, index, &val)) {
		Slapi_DN *dn = slapi_sdn_new_dn_byval(slapi_value_get_string(val));
		const char *ndn = slapi_sdn_get_ndn(dn);

		/* make sure that the name is unique */
		if (PL_HashTableLookup(hash, ndn) != NULL)
		{
			slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "replica_updatedn_list_add - "
							"Update DN with value (%s) already in the update DN list\n",
							ndn);
			slapi_sdn_free(&dn);
		} else {
			Slapi_ValueSet *members = NULL;
			PL_HashTableAdd(hash, ndn, dn);
			/* add it, even if it is a group dn, this will 
			 * prevent problems with circular group definitions
			 * then check if it has mor members to add */
			if (group_update) {
				members = replica_updatedn_list_get_members(dn);
				if (members) {
					replica_updatedn_list_add_ext(list, members, 1);
					/* free members */
					slapi_valueset_free(members);
				}
			}
		}
	}

	return;
}
예제 #5
0
파일: modrdn.c 프로젝트: ohamada/389ds
/*
 * op_shared_rename() -- common frontend code for modDN operations.
 *
 * Beware: this function resets the following pblock elements that were
 * set by the caller:
 *
 *	SLAPI_MODRDN_TARGET_SDN
 *	SLAPI_MODRDN_NEWRDN
 *	SLAPI_MODRDN_NEWSUPERIOR_SDN
 */
static void
op_shared_rename(Slapi_PBlock *pb, int passin_args)
{
	char			*dn, *newrdn, *newdn = NULL;
	const char		*newsuperior;
	char			**rdns;
	int				deloldrdn;
	Slapi_Backend	*be = NULL;
	Slapi_DN		*origsdn = NULL;
	Slapi_Mods		smods;
	int				internal_op, repl_op, lastmod;
	Slapi_Operation *operation;
	Slapi_Entry *referral;
	char errorbuf[BUFSIZ];
	int			err;
	char			*proxydn = NULL;
	char			*proxystr = NULL;
	int			proxy_err = LDAP_SUCCESS;
	char			*errtext = NULL;
	Slapi_DN *sdn = NULL;
	Slapi_DN *newsuperiorsdn = NULL;

	slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET, &dn);
	slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &newrdn);
	slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperiorsdn);
	slapi_pblock_get(pb, SLAPI_MODRDN_DELOLDRDN, &deloldrdn);
	slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &repl_op);
	slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
	slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &origsdn);
	internal_op= operation_is_flag_set(operation, OP_FLAG_INTERNAL);

	/*
	 * If ownership has not been passed to this function, we replace the
	 * string input fields within the pblock with strdup'd copies.  Why?
	 * Because some pre- and post-op plugins may change them, and the
	 * convention is that plugins should place a malloc'd string in the
	 * pblock.  Therefore, we need to be able to retrieve and free them
	 * later.  But the callers of the internal modrdn calls are promised
	 * that we will not free these parameters... so if passin_args is
	 * zero, we need to make copies.
	 *
	 * In the case of SLAPI_MODRDN_TARGET_SDN and SLAPI_MODRDN_NEWSUPERIOR_SDN,
	 * we replace the existing values with normalized values (because plugins
	 * expect these DNs to be normalized).
	 */

	if (NULL == origsdn) {
		sdn = slapi_sdn_new_dn_byval(dn);
		slapi_pblock_set(pb, SLAPI_MODRDN_TARGET_SDN, sdn);
    }
	if (passin_args) {
		if (NULL == sdn) { /* origsdn is not NULL, so use it. */
			sdn = origsdn;
		}
	} else {
		if (NULL == sdn) {
			sdn = slapi_sdn_dup(origsdn);
		}
		newrdn = slapi_ch_strdup(newrdn);
		newsuperiorsdn = slapi_sdn_dup(newsuperiorsdn);
		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, newsuperiorsdn);
	}
	/* normdn = slapi_sdn_get_dn(sdn); */
	newsuperior = slapi_sdn_get_dn(newsuperiorsdn);

	/* get the proxy auth dn if the proxy auth control is present */
	proxy_err = proxyauth_get_dn(pb, &proxydn, &errtext);

	/*
	 * first, log the operation to the access log,
	 * then check rdn and newsuperior,
	 * and - if applicable - log reason of any error to the errors log
	 */
	if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS))
	{
		if (proxydn)
		{
			proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn);
		}

		if ( !internal_op )
		{
			slapi_log_access(LDAP_DEBUG_STATS,
					 "conn=%" NSPRIu64 " op=%d MODRDN dn=\"%s\" newrdn=\"%s\" newsuperior=\"%s\"%s\n",
					 pb->pb_conn->c_connid, 
					 pb->pb_op->o_opid,
					 dn,
					 newrdn ? newrdn : "(null)",
					 newsuperior ? newsuperior : "(null)",
					 proxystr ? proxystr : "");
		}
		else
		{
			slapi_log_access(LDAP_DEBUG_ARGS,
					 "conn=%s op=%d MODRDN dn=\"%s\" newrdn=\"%s\" newsuperior=\"%s\"%s\n",
					 LOG_INTERNAL_OP_CON_ID,
					 LOG_INTERNAL_OP_OP_ID,
					 dn,
					 newrdn ? newrdn : "(null)",
					 newsuperior ? newsuperior : "(null)",
					 proxystr ? proxystr : "");
		}
	}

	/* If we encountered an error parsing the proxy control, return an error
	 * to the client.  We do this here to ensure that we log the operation first. */
	if (proxy_err != LDAP_SUCCESS)
	{
		send_ldap_result(pb, proxy_err, NULL, errtext, 0, NULL);
		goto free_and_return_nolock;
	}

	/* check that the rdn is formatted correctly */
	if ((rdns = slapi_ldap_explode_rdn(newrdn, 0)) == NULL) 
	{
		if ( !internal_op ) {
			slapi_log_error(SLAPI_LOG_ARGS, NULL, 
				 "conn=%" NSPRIu64 " op=%d MODRDN invalid new RDN (\"%s\")\n",
				 pb->pb_conn->c_connid,
				 pb->pb_op->o_opid,
				 (NULL == newrdn) ? "(null)" : newrdn);
		} else {
			slapi_log_error(SLAPI_LOG_ARGS, NULL, 
				 "conn=%s op=%d MODRDN invalid new RDN (\"%s\")\n",
				 LOG_INTERNAL_OP_CON_ID,
				 LOG_INTERNAL_OP_OP_ID,
				 (NULL == newrdn) ? "(null)" : newrdn);
		}
		send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid RDN", 0, NULL);
		goto free_and_return_nolock;
	} 
	else 
	{
		slapi_ldap_value_free(rdns);
	}

	/* check if created attributes are used in the new RDN */
	/* check_rdn_for_created_attrs ignores the cases */
	if (check_rdn_for_created_attrs((const char *)newrdn)) {
		send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid attribute in RDN", 0, NULL);
		goto free_and_return_nolock;
	}

	/* check that the dn is formatted correctly */
	err = slapi_dn_syntax_check(pb, newsuperior, 1);
	if (err)
	{
		LDAPDebug0Args(LDAP_DEBUG_ARGS, "Syntax check of newSuperior failed\n");
		if (!internal_op) {
			slapi_log_error(SLAPI_LOG_ARGS, NULL,
				 "conn=%" NSPRIu64 " op=%d MODRDN invalid new superior (\"%s\")",
				 pb->pb_conn->c_connid,
				 pb->pb_op->o_opid,
				 newsuperior ? newsuperior : "(null)");
		} else {
			slapi_log_error(SLAPI_LOG_ARGS, NULL,
				 "conn=%s op=%d MODRDN invalid new superior (\"%s\")",
				 LOG_INTERNAL_OP_CON_ID,
				 LOG_INTERNAL_OP_OP_ID,
				 newsuperior ? newsuperior : "(null)");
		}
		send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
						 "newSuperior does not look like a DN", 0, NULL);
		goto free_and_return_nolock;
	} 

	if (newsuperior != NULL) 
	{
		LDAPDebug(LDAP_DEBUG_ARGS, "do_moddn: newsuperior (%s)\n", newsuperior, 0, 0);
	}

	/* target spec is used to decide which plugins are applicable for the operation */
	operation_set_target_spec (pb->pb_op, sdn);

	/*
	 * Construct the new DN (code sdn from backend
	 * and modified to handle newsuperior)
	 */
	newdn = slapi_moddn_get_newdn(sdn, newrdn, newsuperior);

	/*
	 * We could be serving multiple database backends.  Select the
	 * appropriate one, or send a referral to our "referral server"
	 * if we don't hold it.
	 */
	/* slapi_mapping_tree_select_and_check ignores the case of newdn
	 * which is generated using newrdn above. */
	if ((err = slapi_mapping_tree_select_and_check(pb, newdn, &be, &referral, errorbuf)) != LDAP_SUCCESS)
	{
		send_ldap_result(pb, err, NULL, errorbuf, 0, NULL);
		goto free_and_return_nolock;
	}

	if (referral)
	{
		int managedsait;

		slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait);
		if (managedsait)
		{
			send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
					"cannot update referral", 0, NULL);
			slapi_entry_free(referral);
			goto free_and_return;
		}
	
		send_referrals_from_entry(pb,referral);
		slapi_entry_free(referral);
		goto free_and_return;
	}

	slapi_pblock_set(pb, SLAPI_BACKEND, be);

	/* can get lastmod only after backend is selected */	
	slapi_pblock_get(pb, SLAPI_BE_LASTMOD, &lastmod);

	/* if it is a replicated operation - leave lastmod attributes alone */
	slapi_mods_init (&smods, 2);
	if (!repl_op && lastmod)
	{
		modify_update_last_modified_attr(pb, &smods);
		slapi_pblock_set(pb, SLAPI_MODIFY_MODS, (void*)slapi_mods_get_ldapmods_passout(&smods));
	}
	else {
		slapi_mods_done (&smods);
	}

	/*
	 * call the pre-modrdn plugins. if they succeed, call
	 * the backend modrdn function. then call the
	 * post-modrdn plugins.
	 */
	if (plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_PRE_MODRDN_FN :
							SLAPI_PLUGIN_PRE_MODRDN_FN) == 0)
	{
		int	rc= LDAP_OPERATIONS_ERROR;
		slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database);
		set_db_default_result_handlers(pb);
		if (be->be_modrdn != NULL)
		{
			if ((rc = (*be->be_modrdn)(pb)) == 0)
			{
				Slapi_Entry	*pse;
				Slapi_Entry	*ecopy;
				/* we don't perform acl check for internal operations */
				/* dont update aci store for remote acis              */
				if ((!internal_op) &&
					(!slapi_be_is_flag_set(be,SLAPI_BE_FLAG_REMOTE_DATA)))
					plugin_call_acl_mods_update (pb, SLAPI_OPERATION_MODRDN);

				if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_AUDIT))
					write_audit_log_entry(pb); /* Record the operation in the audit log */

				slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &pse);
				slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &ecopy);
				/* GGOODREPL persistent search system needs the changenumber, oops. */
				do_ps_service(pse, ecopy, LDAP_CHANGETYPE_MODDN, 0);
			}
		}
		else
		{
			send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Function not implemented", 0, NULL);
		}

		slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &rc);
		plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN : 
							SLAPI_PLUGIN_POST_MODRDN_FN);
	}

free_and_return:
	if (be)
		slapi_be_Unlock(be);
free_and_return_nolock:
	{
		/* Free up everything left in the PBlock */
		Slapi_Entry	*pse;
		Slapi_Entry	*ecopy;
		LDAPMod **mods;
		char	*s;

		if (passin_args) {
			if (NULL == origsdn) {
				slapi_sdn_free(&sdn);
			}
		} else {
			slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &sdn);
			slapi_sdn_free(&sdn);
			/* get newrdn to free the string */
			slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &newrdn);
			slapi_ch_free_string(&newrdn);
			slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperiorsdn);
			slapi_sdn_free(&newsuperiorsdn);
		}
		slapi_ch_free_string(&newdn);

		slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &ecopy);
		slapi_entry_free(ecopy);
		slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &pse);
		slapi_entry_free(pse);
		slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods );
		ldap_mods_free( mods, 1 );
		slapi_ch_free_string(&proxydn);
		slapi_ch_free_string(&proxystr);

		slapi_pblock_get(pb, SLAPI_URP_NAMING_COLLISION_DN, &s);
		slapi_ch_free((void **)&s);
	}
}
예제 #6
0
파일: delete.c 프로젝트: leto/389-ds
static void op_shared_delete (Slapi_PBlock *pb)
{
	char			*rawdn = NULL;
	const char		*dn = NULL;
	Slapi_Backend	*be = NULL;
	int				internal_op;
	Slapi_DN		*sdn = NULL;
	Slapi_Operation *operation;
	Slapi_Entry *referral;
	Slapi_Entry	*ecopy = NULL;
	char errorbuf[BUFSIZ];
	int				err;
	char		*proxydn = NULL;
	char		*proxystr = NULL;
	int		proxy_err = LDAP_SUCCESS;
	char		*errtext = NULL;

	slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET, &rawdn);
	slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
	internal_op= operation_is_flag_set(operation, OP_FLAG_INTERNAL);

	sdn = slapi_sdn_new_dn_byval(rawdn);
	dn = slapi_sdn_get_dn(sdn);
	slapi_pblock_set(pb, SLAPI_DELETE_TARGET_SDN, (void*)sdn);
	if (rawdn && (strlen(rawdn) > 0) && (NULL == dn)) {
		/* normalization failed */
		op_shared_log_error_access(pb, "DEL", rawdn, "invalid dn");
		send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
		                 NULL, "invalid dn", 0, NULL);
		goto free_and_return;
	}

	/* target spec is used to decide which plugins are applicable for the operation */
	operation_set_target_spec (operation, sdn);

	/* get the proxy auth dn if the proxy auth control is present */
	proxy_err = proxyauth_get_dn(pb, &proxydn, &errtext);

	if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS))
	{
		if (proxydn)
		{
			proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn);
		}

		if (!internal_op )
		{
			slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d DEL dn=\"%s\"%s\n",
							pb->pb_conn->c_connid, 
							pb->pb_op->o_opid,
							slapi_sdn_get_dn(sdn),
							proxystr ? proxystr: "");
		}
		else
		{
			slapi_log_access(LDAP_DEBUG_ARGS, "conn=%s op=%d DEL dn=\"%s\"%s\n",
							LOG_INTERNAL_OP_CON_ID,
							LOG_INTERNAL_OP_OP_ID,
							slapi_sdn_get_dn(sdn),
							proxystr ? proxystr: "");
		}
	}

	/* If we encountered an error parsing the proxy control, return an error
	 * to the client.  We do this here to ensure that we log the operation first. */
	if (proxy_err != LDAP_SUCCESS)
	{
		send_ldap_result(pb, proxy_err, NULL, errtext, 0, NULL);
		goto free_and_return;
	}

	/*
	 * We could be serving multiple database backends.  Select the
	 * appropriate one.
	 */
	if ((err = slapi_mapping_tree_select(pb, &be, &referral, errorbuf)) != LDAP_SUCCESS) {
		send_ldap_result(pb, err, NULL, errorbuf, 0, NULL);
		be = NULL;
		goto free_and_return;
	}

	if (referral)
	{
		int managedsait;

		slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait);
		if (managedsait)
		{
			send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
					"cannot delete referral", 0, NULL);
			slapi_entry_free(referral);
			goto free_and_return;
		}
	
		send_referrals_from_entry(pb,referral);
		slapi_entry_free(referral);
		goto free_and_return;
	}

	slapi_pblock_set(pb, SLAPI_BACKEND, be);			

	/*
	 * call the pre-delete plugins. if they succeed, call
	 * the backend delete function. then call the
	 * post-delete plugins.
	 */
	if (plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_PRE_DELETE_FN : 
							SLAPI_PLUGIN_PRE_DELETE_FN) == 0)
	{
		int	rc;

		slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database);
		set_db_default_result_handlers(pb);
		if (be->be_delete != NULL)
		{
			if ((rc = (*be->be_delete)(pb)) == 0)
			{
				/* we don't perform acl check for internal operations */
				/* Dont update aci store for remote acis              */
				if ((!internal_op) && 
					(!slapi_be_is_flag_set(be,SLAPI_BE_FLAG_REMOTE_DATA)))
					plugin_call_acl_mods_update (pb, SLAPI_OPERATION_DELETE);

				if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_AUDIT))
					write_audit_log_entry(pb); /* Record the operation in the audit log */

				slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &ecopy);
				do_ps_service(ecopy, NULL, LDAP_CHANGETYPE_DELETE, 0);
			}
			else
			{
				if (rc == SLAPI_FAIL_DISKFULL)
				{
					operation_out_of_disk_space();
					goto free_and_return;
				}
			}
		}

		slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &rc);
		plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN :
							SLAPI_PLUGIN_POST_DELETE_FN);
	}

free_and_return:
	if (be) {
		slapi_be_Unlock(be);
	}
	{
		char *coldn = NULL;
		Slapi_Entry *epre = NULL, *eparent = NULL;
		slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &epre);
		slapi_pblock_get(pb, SLAPI_DELETE_GLUE_PARENT_ENTRY, &eparent);
		slapi_pblock_set(pb, SLAPI_ENTRY_PRE_OP, NULL);
		slapi_pblock_set(pb, SLAPI_DELETE_GLUE_PARENT_ENTRY, NULL);
		if (epre == eparent) {
			eparent = NULL;
		}
		slapi_entry_free(epre);
		slapi_entry_free(eparent);
		slapi_pblock_get(pb, SLAPI_URP_NAMING_COLLISION_DN, &coldn);
		slapi_ch_free_string(&coldn);
	}

	slapi_pblock_get(pb, SLAPI_DELETE_TARGET_SDN, &sdn);
	slapi_sdn_free(&sdn);
	slapi_ch_free_string(&proxydn);
	slapi_ch_free_string(&proxystr);
}
예제 #7
0
/*
 * Check if we are modifying the config, or changing the shared config entry
 */
int
memberof_shared_config_validate(Slapi_PBlock *pb)
{
	Slapi_Entry *e = 0;
	Slapi_Entry *resulting_e = 0;
	Slapi_Entry *config_entry = NULL;
	Slapi_DN *sdn = NULL;
	Slapi_DN *config_sdn = NULL;
	Slapi_Mods *smods = 0;
	Slapi_Mod *smod = NULL, *nextmod = NULL;
	LDAPMod **mods = NULL;
	char returntext[SLAPI_DSE_RETURNTEXT_SIZE];
	char *configarea_dn = NULL;
	int ret = SLAPI_PLUGIN_SUCCESS;

	slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);

	if (slapi_sdn_compare(sdn, memberof_get_plugin_area()) == 0 ||
	    slapi_sdn_compare(sdn, memberof_get_config_area()) == 0)
	{
		slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e);
		if(e){
			/*
			 * Create a copy of the entry and apply the
			 * mods to create the resulting entry.
			 */
			slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
			smods = slapi_mods_new();
			slapi_mods_init_byref(smods, mods);
			resulting_e = slapi_entry_dup(e);
			if (mods && (slapi_entry_apply_mods(resulting_e, mods) != LDAP_SUCCESS)) {
				/* we don't care about this, the update is invalid and will be caught later */
				goto bail;
			}

			if (slapi_sdn_compare(sdn, memberof_get_plugin_area())){
				/*
				 * This entry is a plugin config area entry, validate it.
				 */
				if( SLAPI_DSE_CALLBACK_ERROR == memberof_validate_config (pb, NULL, resulting_e, &ret, returntext,0)) {
					ret = LDAP_UNWILLING_TO_PERFORM;
				}
			} else {
				/*
				 * This is the memberOf plugin entry, check if we are adding/replacing the
				 * plugin config area.
				 */
				nextmod = slapi_mod_new();
				for (smod = slapi_mods_get_first_smod(smods, nextmod);
					 smod != NULL;
					 smod = slapi_mods_get_next_smod(smods, nextmod) )
				{
					if ( PL_strcasecmp(SLAPI_PLUGIN_SHARED_CONFIG_AREA, slapi_mod_get_type(smod)) == 0 )
					{
						/*
						 * Okay, we are modifying the plugin config area, we only care about
						 * adds and replaces.
						 */
						if(SLAPI_IS_MOD_REPLACE(slapi_mod_get_operation(smod)) ||
						   SLAPI_IS_MOD_ADD(slapi_mod_get_operation(smod)))
						{
						    struct berval *bv = NULL;
						    int rc = 0;

							bv = slapi_mod_get_first_value(smod);
							configarea_dn = slapi_ch_strdup(bv->bv_val);
							if(configarea_dn){
								/* Check the DN syntax */
								rc = slapi_dn_syntax_check(pb, configarea_dn, 1);
								if (rc) { /* syntax check failed */
									PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
										"%s does not contain a valid DN (%s)",
										SLAPI_PLUGIN_SHARED_CONFIG_AREA, configarea_dn);
									ret = LDAP_UNWILLING_TO_PERFORM;
									goto bail;
								}

								/* Check if the plugin config area entry exists */
								if((config_sdn = slapi_sdn_new_dn_byval(configarea_dn))){
									rc = slapi_search_internal_get_entry(config_sdn, NULL, &config_entry,
										memberof_get_plugin_id());
									if(config_entry){
										int err = 0;
										/*
										 * Validate the settings from the new config area.
										 */
										if ( memberof_validate_config(pb, NULL, config_entry, &err, returntext,0)
											 == SLAPI_DSE_CALLBACK_ERROR )
										{
											ret = LDAP_UNWILLING_TO_PERFORM;
											goto bail;

										}
									} else {
										/* The config area does not exist */
										PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
											"Unable to locate shared config entry (%s) error %d",
											slapi_sdn_get_dn(memberof_get_config_area()), rc);
										ret = LDAP_UNWILLING_TO_PERFORM;
										goto bail;
									}
								}
							}
							slapi_ch_free_string(&configarea_dn);
							slapi_sdn_free(&config_sdn);
						}
					}
				}
			}
		} else {
			PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Unable to locate shared config entry (%s)",
				slapi_sdn_get_dn(memberof_get_config_area()));
			ret = LDAP_UNWILLING_TO_PERFORM;
		}
   	}

bail:

	if (ret){
		slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret);
		slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, returntext);
		slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_shared_config_validate - %s/n",
			returntext);
	}
	slapi_sdn_free(&config_sdn);
	if(nextmod)
		slapi_mod_free(&nextmod);
	slapi_mods_free(&smods);
	slapi_entry_free(resulting_e);
	slapi_entry_free(config_entry);
	slapi_ch_free_string(&configarea_dn);

	return ret;
}
예제 #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;
	}
}
예제 #9
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;
	}
}
예제 #10
0
static int
nullsuffix_search( Slapi_PBlock *pb )
{
	char			*dn_base, **attrs, *newStr;
	int				scope, sizelimit, timelimit, deref, attrsonly;
	Slapi_Filter	*filter;
	Slapi_DN		*sdn_base;
	int				ldaperr = LDAP_SUCCESS;	/* optimistic */
	int				nentries = 0;	/* entry count */
	int				i;
	Slapi_Operation	*op;
	Slapi_Entry		*e;

	const char *entrystr =
		"dn:cn=Joe Smith,o=Example\n"
		"objectClass: top\n"
		"objectClass: person\n"
		"objectClass: organizationalPerson\n"
		"objectClass: inetOrgPerson\n"
		"cn:Joe Smith\n"
		"sn:Smith\n"
		"uid:jsmith\n"
		"mail:[email protected]\n";
	
	slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_search\n" );
	if( slapi_op_reserved(pb) ){
		return PLUGIN_OPERATION_IGNORED;
	}

	/* get essential search parameters */
	if ( slapi_pblock_get( pb, SLAPI_SEARCH_TARGET, &dn_base ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope ) != 0 ) {
		slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
				"could not get base DN and scope search parameters\n" );
	}
	if ( dn_base == NULL ) {
		dn_base = "";
	}
	sdn_base = slapi_sdn_new_dn_byval( dn_base );
	slapi_pblock_get(pb, SLAPI_OPERATION, &op);

	/* get remaining search parameters */
	if ( slapi_pblock_get( pb, SLAPI_SEARCH_DEREF, &deref ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_SIZELIMIT, &sizelimit ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_TIMELIMIT, &timelimit ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, &filter ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_ATTRS, &attrs ) != 0 ||
			slapi_pblock_get( pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly ) != 0 ) {
		slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
				"could not get remaining search parameters\n" );
	}

	if ( slapi_pblock_get( pb, SLAPI_OPERATION, &op ) != 0 ) {
		slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
				"could not get operation\n" );
	} else {
		 slapi_operation_set_flag(op, SLAPI_OP_FLAG_NO_ACCESS_CHECK  );
	}

	/* create a fake entry and send it along */
	newStr = slapi_ch_strdup( entrystr );
	if ( NULL == ( e = slapi_str2entry( newStr,
				SLAPI_STR2ENTRY_ADDRDNVALS
				| SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES ))) {
		slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME,
				"nullsuffix_search: slapi_str2entry() failed\n" );
	} else {
		slapi_send_ldap_search_entry( pb, e, NULL /* controls */,
				attrs, attrsonly );
		++nentries;
		slapi_entry_free( e );
	}

	slapi_send_ldap_result( pb, ldaperr, NULL, "kilroy was here",
			nentries, NULL );
	slapi_log_error( SLAPI_LOG_PLUGIN, PLUGIN_NAME, "nullsuffix_search:"
			" handled search based at %s with scope %d; ldaperr=%d\n",
			dn_base, scope, ldaperr );

	slapi_ch_free_string(&newStr);
	slapi_sdn_free(&sdn_base);

	return PLUGIN_OPERATION_HANDLED;
}
예제 #11
0
파일: aclanom.c 프로젝트: Firstyear/ds
/*
 * 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();
	}
}