Пример #1
0
Slapi_DN *slapi_sdn_set_parent( Slapi_DN *sdn, const Slapi_DN *parentdn )
{
	Slapi_RDN rdn;

	slapi_rdn_init_sdn( &rdn, sdn );
	slapi_sdn_set_dn_byref( sdn, slapi_sdn_get_dn( parentdn ) );
	slapi_sdn_add_rdn( sdn, &rdn );
	slapi_rdn_done( &rdn );

	return sdn;
}
Пример #2
0
/* consumer connection extension destructor */
void consumer_connection_extension_destructor (void *ext, void *object, void *parent)
{
	PRUint64 connid = 0;
	if (ext)
	{
		/* Check to see if this replication session has acquired
		 * a replica. If so, release it here.
		 */
		consumer_connection_extension *connext = (consumer_connection_extension *)ext;
		if (NULL != connext->replica_acquired)
		{
            Replica *r = object_get_data ((Object*)connext->replica_acquired);
			/* If a total update was in progress, abort it */
			if (REPL_PROTOCOL_50_TOTALUPDATE == connext->repl_protocol_version)
			{
				Slapi_PBlock *pb = slapi_pblock_new();
				const Slapi_DN *repl_root_sdn = replica_get_root(r);
				PR_ASSERT(NULL != repl_root_sdn);
				if (NULL != repl_root_sdn)
				{
					slapi_pblock_set(pb, SLAPI_CONNECTION, connext->connection);
					slapi_pblock_set(pb, SLAPI_TARGET_SDN, (void*)repl_root_sdn);
					slapi_pblock_get(pb, SLAPI_CONN_ID, &connid);
					slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
									"Aborting total update in progress for replicated "
									"area %s connid=%" NSPRIu64 "\n", slapi_sdn_get_dn(repl_root_sdn),
									connid);
					slapi_stop_bulk_import(pb);
				}
				else
				{
					slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
						"consumer_connection_extension_destructor: can't determine root "
						"of replicated area.\n");
				}
				slapi_pblock_destroy(pb);

				/* allow reaping again */
				replica_set_tombstone_reap_stop(r, PR_FALSE);
			}
			replica_relinquish_exclusive_access(r, connid, -1);
            object_release ((Object*)connext->replica_acquired);
			connext->replica_acquired = NULL;
		}

        if (connext->supplier_ruv)
        {
            ruv_destroy ((RUV **)&connext->supplier_ruv);
        }
		connext->connection = NULL;
		slapi_ch_free((void **)&ext);	
	}
}
Пример #3
0
/*
 * Config. DSE callback for instance entry searches.
 */
int 
ldbm_instance_search_config_entry_callback(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *entryAfter, int *returncode, char *returntext, void *arg)
{
    char buf[BUFSIZ];
    struct berval *vals[2];
    struct berval val;
    ldbm_instance *inst = (ldbm_instance *) arg;
    config_info *config;
    int x;
    const Slapi_DN *suffix;

    vals[0] = &val;
    vals[1] = NULL;  

    returntext[0] = '\0';

    /* show the suffixes */
    attrlist_delete(&e->e_attrs, CONFIG_INSTANCE_SUFFIX);
    x = 0;
    do {
        suffix = slapi_be_getsuffix(inst->inst_be, x);
        if (suffix != NULL) {
            val.bv_val = (char *) slapi_sdn_get_dn(suffix);
            val.bv_len = strlen (val.bv_val);
            attrlist_merge( &e->e_attrs, CONFIG_INSTANCE_SUFFIX, vals );
        }
        x++;
    } while(suffix!=NULL);

    PR_Lock(inst->inst_config_mutex);

    for(config = ldbm_instance_config; config->config_name != NULL; config++) {
        /* Go through the ldbm_config table and fill in the entry. */

        if (!(config->config_flags & (CONFIG_FLAG_ALWAYS_SHOW | CONFIG_FLAG_PREVIOUSLY_SET))) {
            /* This config option shouldn't be shown */
            continue;
        }

        ldbm_config_get((void *) inst, config, buf);

        val.bv_val = buf;
        val.bv_len = strlen(buf);
        slapi_entry_attr_replace(e, config->config_name, vals);
    }
    
    PR_Unlock(inst->inst_config_mutex);

    *returncode = LDAP_SUCCESS;
    return SLAPI_DSE_CALLBACK_OK;
}
Пример #4
0
int
value_dn_normalize_value(Slapi_Value *value)
{
	Slapi_DN *sdn = NULL;
	int rc = 0;

	if (NULL == value) {
		return rc;
	}

	sdn = slapi_sdn_new_dn_passin(value->bv.bv_val);
	if (slapi_sdn_get_dn(sdn)) {
		value->bv.bv_val = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
		value->bv.bv_len = slapi_sdn_get_ndn_len(sdn);
		slapi_sdn_free(&sdn);
		slapi_value_set_flags(value, SLAPI_ATTR_FLAG_NORMALIZED_CES);
	} else {
		rc = 1;
		slapi_ch_free((void **)&sdn); /* free just Slapi_DN */
	}

	return rc;
}
Пример #5
0
static int
handle_agmt_search(Slapi_Entry *e, void *callback_data)
{
	int *agmtcount = (int *)callback_data;
	int rc;

	slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
		"Found replication agreement named \"%s\".\n",
		slapi_sdn_get_dn(slapi_entry_get_sdn(e)));
	rc = add_new_agreement(e);
	if (0 == rc)
	{
		(*agmtcount)++;
	}
	else
	{
		slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "The replication "
			"agreement named \"%s\" could not be correctly parsed. No "
			"replication will occur with this replica.\n",
			slapi_sdn_get_dn(slapi_entry_get_sdn(e)));
	}

	return rc;
}
Пример #6
0
static void
print_suffixes(void)
{
	void *cookie = NULL;
	Slapi_DN *sdn = NULL;
	slapi_log_err(SLAPI_LOG_INFO, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
					"print_suffixes - The following is the list of valid suffixes to use with "
					PAMPT_EXCLUDES_ATTR " and " PAMPT_INCLUDES_ATTR ":\n");
	for (sdn = slapi_get_first_suffix(&cookie, 1);
		 sdn && cookie;
		 sdn = slapi_get_next_suffix(&cookie, 1)) {
		slapi_log_err(SLAPI_LOG_INFO, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
						"print_suffixes -\t%s\n", slapi_sdn_get_dn(sdn));
	}
}
Пример #7
0
/* For preop search we do two things:
 * 1) based on the search base, we preselect the acls.
 * 2) also get hold of a acl_pblock for use 
 */
static int
aclplugin_preop_search ( Slapi_PBlock *pb )
{
	int 		scope;
	const char	*base = NULL;
	Slapi_DN	*sdn = NULL;
	int			optype;
	int			isRoot;
	int			isProxy = 0;
	int			rc = 0;
	char *errtxt = NULL;
	char *proxy_dn = NULL;
			
	TNF_PROBE_0_DEBUG(aclplugin_preop_search_start ,"ACL","");

	slapi_pblock_get ( pb, SLAPI_OPERATION_TYPE, &optype );
	slapi_pblock_get ( pb, SLAPI_REQUESTOR_ISROOT, &isRoot );

	if (LDAP_SUCCESS == proxyauth_get_dn(pb, &proxy_dn, &errtxt) && proxy_dn) {
		isProxy = 1;
	}
	slapi_ch_free_string(&proxy_dn);

	if ( isRoot && !isProxy) {
		TNF_PROBE_1_DEBUG(aclplugin_preop_search_end ,"ACL","",
							tnf_string,isroot,"");
		return rc;
	}

	slapi_pblock_get( pb, SLAPI_SEARCH_TARGET_SDN, &sdn );
	base = slapi_sdn_get_dn(sdn);
	/* For anonymous client  doing search nothing needs to be set up */
	if ( optype == SLAPI_OPERATION_SEARCH && aclanom_is_client_anonymous ( pb )  &&
			! slapi_dn_issuffix( base, "cn=monitor") ) {
				TNF_PROBE_1_DEBUG(aclplugin_preop_search_end ,"ACL","",
									tnf_string,anon,"");
		return rc;
	}

	if ( 0 == ( rc = aclplugin_preop_common( pb ))) {
		slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope );
		acllist_init_scan ( pb, scope, base );
	}

	TNF_PROBE_0_DEBUG(aclplugin_preop_search_end ,"ACL","");

	return rc;
}
Пример #8
0
static int
convert_to_string(Slapi_DN *dn, void *arg)
{
	struct list_to_string_data *data = (struct list_to_string_data *)arg;
	int newlen = slapi_sdn_get_ndn_len(dn) + strlen(data->delimiter) + 1;
	if (data->string) {
		newlen += strlen(data->string);
		data->string = slapi_ch_realloc(data->string, newlen);
	} else {
		data->string = slapi_ch_calloc(1, newlen);
	}
	strcat(data->string, slapi_sdn_get_dn(dn));
	strcat(data->string, data->delimiter);

	return 1;
}
Пример #9
0
static int
agmtlist_add_callback(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *entryAfter,
	int *returncode, char *returntext, void *arg)
{
	int rc;
	slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmt_add: begin\n");

	rc = add_new_agreement(e);
	if (0 != rc) {
		Slapi_DN *sdn = NULL;
		slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "agmtlist_add_callback: "
			"Can't start agreement \"%s\"\n", slapi_sdn_get_dn(sdn));
		*returncode = LDAP_UNWILLING_TO_PERFORM;
		return SLAPI_DSE_CALLBACK_ERROR;
	}
	*returncode = LDAP_SUCCESS;
	return SLAPI_DSE_CALLBACK_OK;
}
Пример #10
0
void
ipa_topo_be_state_change(void *handle, char *be_name,
                              int old_be_state, int new_be_state)
{
    Slapi_Backend *be=NULL;
    const char *be_suffix;

    /* check if different backends require different actions */
    be = slapi_be_select_by_instance_name(be_name);
    be_suffix = slapi_sdn_get_dn(slapi_be_getsuffix(be, 0));
    if (0 == ipa_topo_cfg_plugin_suffix_is_managed(be_suffix)) {
        /* nothing to do */
        return;
    }

    if (new_be_state == SLAPI_BE_STATE_ON) {
        /* backend came back online - check change in domain level */
        slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                        "ipa_topo_be_state_change - "
                        "backend %s is coming online; "
                        "checking domain level and init shared topology\n",
                        be_name);
        ipa_topo_util_set_domain_level();
        ipa_topo_util_check_plugin_active();
        if (ipa_topo_get_plugin_active()) {
            ipa_topo_set_post_init(1);
            ipa_topo_util_start(1);
        }
    } else if (new_be_state == SLAPI_BE_STATE_OFFLINE) {
        /* backend is about to be taken down - inactivate plugin */
        slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                        "ipa_topo_be_state_change"
                        "backend %s is going offline; inactivate plugin\n", be_name);
    } else if (new_be_state == SLAPI_BE_STATE_DELETE) {
        /* backend is about to be removed - disable replication */
        if (old_be_state == SLAPI_BE_STATE_ON) {
             slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
                            "ipa_topo_be_state_change"
                            "backend %s is about to be deleted; inactivate plugin\n", be_name);
        }
    }
}
Пример #11
0
/* 
 * If "dn" is passed, get_entry returns an entry which dn is "dn".
 * If "dn" is not passed, it returns an entry which dn is set in 
 * SLAPI_TARGET_SDN in pblock.
 * Note: pblock is not mandatory for get_entry (e.g., new_passwdPolicy).
 */
Slapi_Entry *get_entry ( Slapi_PBlock *pb, const char *dn)
{
	int             search_result = 0;
	Slapi_Entry     *retentry = NULL;
	Slapi_DN        *target_sdn = NULL;
	const char      *target_dn = dn;
	Slapi_DN        sdn;

	if (pb) {
		slapi_pblock_get( pb, SLAPI_TARGET_SDN, &target_sdn );
		if (target_dn == NULL) {
			target_dn = slapi_sdn_get_dn(target_sdn);
		}
	}

	if (target_dn == NULL) {
		LDAPDebug0Args(LDAP_DEBUG_TRACE,
		               "WARNING: 'get_entry' - no dn specified.\n");
		goto bail;
	}

	if (target_dn == dn) { /* target_dn is NOT from target_sdn */
		slapi_sdn_init_dn_byref(&sdn, target_dn);
		target_sdn = &sdn;
	}

	search_result = slapi_search_internal_get_entry(target_sdn, NULL,
	                                                &retentry, 
	                                                pw_get_componentID());
	if (search_result != LDAP_SUCCESS) {
		LDAPDebug2Args(LDAP_DEBUG_TRACE,
		               "WARNING: 'get_entry' can't find entry '%s', err %d\n",
		               target_dn, search_result);
	}
	if (target_dn == dn) { /* target_dn is NOT from target_sdn */
		slapi_sdn_done(&sdn);
	}
bail:
	return retentry;
}
Пример #12
0
int
ipa_topo_check_entry_move(Slapi_PBlock *pb)
{
    int rc = 0;
    int entry_type = TOPO_IGNORE_ENTRY;
    Slapi_Entry *modrdn_entry;
    slapi_pblock_get(pb,SLAPI_MODRDN_TARGET_ENTRY,&modrdn_entry);
    entry_type = ipa_topo_check_entry_type(modrdn_entry);
    switch (entry_type) {
    case TOPO_SEGMENT_ENTRY:
    case TOPO_CONFIG_ENTRY: {
        Slapi_DN *newsuperior = NULL;
        slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperior);
        if (newsuperior && slapi_sdn_get_dn(newsuperior)) rc = 1;
        break;
        }
    default:
        rc = 0;
        break;
    }
    return rc;
}
Пример #13
0
int set_retry_cnt_mods(Slapi_PBlock *pb, Slapi_Mods *smods, int count)
{
	char 		*timestr;
	time_t		unlock_time;
	char        retry_cnt[8]; /* 1-65535 */
	const char *dn = NULL; 
	Slapi_DN *sdn = NULL; 
	passwdPolicy *pwpolicy = NULL;
	int rc = 0;

	slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
	dn = slapi_sdn_get_dn(sdn);
	pwpolicy = new_passwdPolicy(pb, dn);

	if (smods) {
		sprintf ( retry_cnt, "%d", count );
		slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "passwordRetryCount", retry_cnt);
		/* lock account if reache retry limit */
		if ( count >=  pwpolicy->pw_maxfailure ) {
			/* Remove lock_account function to perform all mods at once */
			/* lock_account ( pb ); */
			/* reach the retry limit, lock the account  */
			if ( pwpolicy->pw_unlock == 0 ) {
				/* lock until admin reset password */
				unlock_time = NO_TIME;
			} else {
				unlock_time = time_plus_sec ( current_time(),
											  pwpolicy->pw_lockduration );
			}
			timestr= format_genTime ( unlock_time );
			slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "accountUnlockTime", timestr);
			slapi_ch_free((void **)&timestr);
			rc = LDAP_CONSTRAINT_VIOLATION;
		}
	}
	return rc;
}
Пример #14
0
/* This function is now fully executed for internal and replicated ops. */
int 
plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
{
	struct slapdplugin	*p;
	int					rc = 0;
	void				*change = NULL;
	void				*mychange[2];
	Slapi_Entry			*te = NULL;
	Slapi_DN			*sdn = NULL;
	Operation			*operation;

	slapi_pblock_get (pb, SLAPI_OPERATION, &operation);

	(void)slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );

	switch ( optype ) {
	  case SLAPI_OPERATION_MODIFY:
		(void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &change );
		break;
	  case SLAPI_OPERATION_ADD:
		(void)slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &change );
		te = (Slapi_Entry *)change;
		if(!slapi_sdn_isempty(slapi_entry_get_sdn(te)))
		{
			sdn = slapi_entry_get_sdn(te);
		}
		break;
	  case SLAPI_OPERATION_MODRDN:
	  {
		char *newrdn = NULL;
		Slapi_DN *psdn = NULL;
		char *pdn = NULL;

		/* newrdn: "change" is normalized but not case-ignored */
		/* The acl plugin expects normalized newrdn, but no need to be case-
		 * ignored. */
		(void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn );
		(void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &psdn );
		if (psdn) {
			pdn = (char *)slapi_sdn_get_dn(psdn);
		} else {
			(void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR, &pdn );
		}
		mychange[0] = newrdn;
		mychange[1] = pdn;
		change = mychange;
		break;
	  }
	}
	
	if (NULL == sdn) {
		slapi_log_err(SLAPI_LOG_ERR, "plugin_call_acl_mods_update", "NULL target DN\n");
		return LDAP_INVALID_DN_SYNTAX;
	}

	/* call the global plugins first and then the backend specific */
	for ( p = get_plugin_list(PLUGIN_LIST_ACL); p != NULL; p = p->plg_next ) {
		if (plugin_invoke_plugin_sdn(p, SLAPI_PLUGIN_ACL_MODS_UPDATE, pb, sdn)){
			rc = (*p->plg_acl_mods_update)(pb, optype, sdn, change );
			if ( rc != LDAP_SUCCESS ) break;
		}
	}

	return rc;
}
Пример #15
0
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);
}
Пример #16
0
void
do_compare( Slapi_PBlock *pb )
{
	BerElement	*ber = pb->pb_op->o_ber;
	char		*rawdn = NULL;
	const char	*dn = NULL;
	struct ava	ava = {0};
	Slapi_Backend		*be = NULL;
	int		err;
	Slapi_DN sdn;
	Slapi_Entry *referral = NULL;
	char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE];

	slapi_log_err(SLAPI_LOG_TRACE, "do_compare", "=>\n");

	/* count the compare request */
	slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsCompareOps);

    /* have to init this here so we can "done" it below if we short circuit */
    slapi_sdn_init(&sdn);

	/*
	 * Parse the compare request.  It looks like this:
	 *
	 *	CompareRequest := [APPLICATION 14] SEQUENCE {
	 *		entry	DistinguishedName,
	 *		ava	SEQUENCE {
	 *			type	AttributeType,
	 *			value	AttributeValue
	 *		}
	 *	}
	 */

	if ( ber_scanf( ber, "{a{ao}}", &rawdn, &ava.ava_type,
	    &ava.ava_value ) == LBER_ERROR ) {
		slapi_log_err(SLAPI_LOG_ERR,
		    "do_compare", "ber_scanf failed (op=Compare; params=DN,Type,Value)\n");
		send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
			NULL );
		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, "CMP",
							rawdn?rawdn:"", "strict: invalid dn");
			send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
							 NULL, "invalid dn", 0, NULL);
			slapi_ch_free((void **) &rawdn);
			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, "CMP", rawdn, "invalid dn");
        send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
                         "invalid dn", 0, NULL);
        slapi_sdn_done(&sdn);
        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 ) {
		send_ldap_result( pb, err, NULL, NULL, 0, NULL );
		goto free_and_return;
	}

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

	slapi_log_err(SLAPI_LOG_ARGS, "do_compare: dn (%s) attr (%s)\n",
	    rawdn, ava.ava_type, 0 );

	slapi_log_access( LDAP_DEBUG_STATS,
	    "conn=%" NSPRIu64 " op=%d CMP dn=\"%s\" attr=\"%s\"\n",
	    pb->pb_conn->c_connid, pb->pb_op->o_opid, dn, ava.ava_type );

	/*
	 * We could be serving multiple database backends.  Select the
	 * appropriate one.
	 */
	if ((err = slapi_mapping_tree_select(pb, &be, &referral, errorbuf, sizeof(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 compare 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;
	}

	if ( be->be_compare != NULL ) {
		int		isroot;
		    
		slapi_pblock_set( pb, SLAPI_BACKEND, be );
		isroot = pb->pb_op->o_isroot;

		slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &isroot );
		/* EXCEPTION: compare target does not allocate memory. */
		/* target never be modified by plugins. */
		slapi_pblock_set( pb, SLAPI_COMPARE_TARGET_SDN, (void*)&sdn );
		slapi_pblock_set( pb, SLAPI_COMPARE_TYPE, ava.ava_type);
		slapi_pblock_set( pb, SLAPI_COMPARE_VALUE, &ava.ava_value );
		/*
		 * call the pre-compare plugins. if they succeed, call
		 * the backend compare function. then call the
		 * post-compare plugins.
		 */
		if ( plugin_call_plugins( pb,
				SLAPI_PLUGIN_PRE_COMPARE_FN ) == 0 ) {
			int	rc;

			slapi_pblock_set( pb, SLAPI_PLUGIN, be->be_database );
			set_db_default_result_handlers(pb);
			rc = (*be->be_compare)( pb );

			slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, &rc );
			plugin_call_plugins( pb, SLAPI_PLUGIN_POST_COMPARE_FN );
		}
	} else {
		send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
		    "Function not implemented", 0, NULL );
	}

free_and_return:;
	if (be)
		slapi_be_Unlock(be);
	slapi_sdn_done(&sdn);
	ava_done( &ava );
}
Пример #17
0
int
_ger_generate_template_entry (
	Slapi_PBlock    *pb
	)
{
	Slapi_Entry	*e = NULL;
	char **gerattrs = NULL;
	char **attrs = NULL;
	char **allowedattrs = NULL;
	char *templateentry = NULL;
	char *object = NULL;
	char *superior = NULL;
	char *p = NULL;
	const char *dn = NULL;
	Slapi_DN *sdn = NULL;
	char *dntype = NULL;
	int siz = 0;
	int len = 0;
	int i = 0;
	int notfirst = 0;
	int rc = LDAP_SUCCESS;

	slapi_pblock_get( pb, SLAPI_SEARCH_GERATTRS, &gerattrs );
	if (NULL == gerattrs)
	{
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
						"_ger_generate_template_entry - Objectclass info is expected "
						"in the attr list, e.g., \"*@person\"\n");
		rc = LDAP_SUCCESS;
		goto bailout;
	}
	for (i = 0; gerattrs && gerattrs[i]; i++)
	{
		object = strchr(gerattrs[i], '@');
		if (NULL != object && '\0' != *(++object))
		{
			break;
		}
	}
	if (NULL == object)
	{
		rc = LDAP_SUCCESS;	/* no objectclass info; ok to return */
		goto bailout;
	}
	/* 
	 * Either @objectclass or @objectclass:dntype is accepted.
	 * If @objectclass, the first MUST attributetype (or the first MAY
	 * attributetype if MUST does not exist) is used for the attribute
	 * type in the leaf RDN.
	 * If @objectclass:dntype, dntype is used for the attribute type in the
	 * leaf RDN.
	 */
	dntype = strchr(object, ':');
	if (dntype) { /* @objectclasse:dntype */
		*dntype++ = '\0';
	}

	attrs = slapi_schema_list_objectclass_attributes(
						(const char *)object, SLAPI_OC_FLAG_REQUIRED);
	allowedattrs = slapi_schema_list_objectclass_attributes(
						(const char *)object, SLAPI_OC_FLAG_ALLOWED);
	charray_merge(&attrs, allowedattrs, 0 /* no copy */);
	slapi_ch_free((void **)&allowedattrs); /* free just allowedattrs */
	if (NULL == attrs) {
		rc = LDAP_SUCCESS;	/* bogus objectclass info; ok to return */
		goto bailout;
	}
	for (i = 0; attrs[i]; i++)
	{
		if (0 == strcasecmp(attrs[i], "objectclass"))
		{
			/* <*attrp>: <object>\n\0 */
			siz += strlen(attrs[i]) + 4 + strlen(object);
		}
		else
		{
			/* <*attrp>: (template_attribute)\n\0 */
			siz += strlen(attrs[i]) + 4 + 20;
		}
	}
	/* get the target dn where the template entry is located */
	slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
	dn = slapi_sdn_get_dn(sdn);
	if (dn)
	{
		/* dn: <attr>=<template_name>,<dn>\n\0 */
		if (dntype) {
			siz += strlen(dntype) + 30 + strlen(object) + strlen(dn);
		} else {
			siz += strlen(attrs[0]) + 30 + strlen(object) + strlen(dn);
		}
	}
	else
	{
		/* dn: <attr>=<template_name>\n\0 */
		if (dntype) {
			siz += strlen(dntype) + 30 + strlen(object);
		} else {
			siz += strlen(attrs[0]) + 30 + strlen(object);
		}
	}
	templateentry = (char *)slapi_ch_malloc(siz);
	if (NULL != dn && strlen(dn) > 0)
	{
		PR_snprintf(templateentry, siz,
		            "dn: %s=template_%s_objectclass,%s\n",
		            dntype?dntype:attrs[0], object, dn);
	}
	else
	{
		PR_snprintf(templateentry, siz,
		            "dn: %s=template_%s_objectclass\n",
		            dntype?dntype:attrs[0], object);
	}
	for (--i; i >= 0; i--)
	{
		len = strlen(templateentry);
		p = templateentry + len;
		if (0 == strcasecmp(attrs[i], "objectclass"))
		{
			PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
		}
		else
		{
			PR_snprintf(p, siz - len, "%s: (template_attribute)\n", attrs[i]);
		}
	}
	charray_free(attrs);

	while ((superior = slapi_schema_get_superior_name(object)) &&
			(0 != strcasecmp(superior, "top")))
	{
		if (notfirst)
		{
			slapi_ch_free_string(&object);
		}
		notfirst = 1;
		object = superior;
		attrs = slapi_schema_list_objectclass_attributes(
						(const char *)superior, SLAPI_OC_FLAG_REQUIRED);
		for (i = 0; attrs && attrs[i]; i++)
		{
			if (0 == strcasecmp(attrs[i], "objectclass"))
			{
				/* <*attrp>: <object>\n\0 */
				siz += strlen(attrs[i]) + 4 + strlen(object);
			}
		}
		templateentry = (char *)slapi_ch_realloc(templateentry, siz);
		for (--i; i >= 0; i--)
		{
			len = strlen(templateentry);
			p = templateentry + len;
			if (0 == strcasecmp(attrs[i], "objectclass"))
			{
				PR_snprintf(p, siz - len, "%s: %s\n", attrs[i], object);
			}
		}
		charray_free(attrs);
	}
	if (notfirst)
	{
		slapi_ch_free_string(&object);
	}
	slapi_ch_free_string(&superior);
	siz += 18; /* objectclass: top\n\0 */
	len = strlen(templateentry);
	templateentry = (char *)slapi_ch_realloc(templateentry, siz);
	p = templateentry + len;
	PR_snprintf(p, siz - len, "objectclass: top\n");

	e = slapi_str2entry(templateentry, SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF);
	/* set the template entry to send the result to clients */
	slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_ENTRY, e);
bailout:
	slapi_ch_free_string(&templateentry);
	return rc;
}
Пример #18
0
static int
_ger_g_permission_granted (
	Slapi_PBlock *pb,
	Slapi_Entry *e,
	const char *subjectdn,
	char **errbuf
	)
{
	char *proxydn = NULL;
	Slapi_DN *requestor_sdn, *entry_sdn;
	char *errtext = NULL;
	int isroot;
	int rc;

	/*
	 * Theorically, we should check if the entry has "g"
	 * permission granted to the requestor. If granted,
	 * allows the effective rights on that entry and its
	 * attributes within the entry to be returned for
	 * ANY subject.
	 *
	 * "G" permission granting has not been implemented yet,
	 * the current release assumes that "g" permission be 
	 * granted to root and owner of any entry.
	 */

	/*
	 * The requestor may be either the bind dn or a proxy dn
	 */
	if ((proxyauth_get_dn( pb, &proxydn, &errtext ) == LDAP_SUCCESS) && ( proxydn != NULL ))
	{
		requestor_sdn = slapi_sdn_new_dn_passin ( proxydn );
	}
	else
	{
		slapi_ch_free_string(&proxydn); /* this could still have been set - free it */
		requestor_sdn = &(pb->pb_op->o_sdn);
	}
	if ( slapi_sdn_get_dn (requestor_sdn) == NULL )
	{
		slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"_ger_g_permission_granted - Anonymous has no g permission\n" );
		rc = LDAP_INSUFFICIENT_ACCESS;
		goto bailout;
	}
	isroot = slapi_dn_isroot ( slapi_sdn_get_dn (requestor_sdn) );
	if ( isroot )
	{
		/* Root has "g" permission on any entry */
		rc = LDAP_SUCCESS;
		goto bailout;
	}

	entry_sdn = slapi_entry_get_sdn ( e );
	if ( entry_sdn == NULL || slapi_sdn_get_dn (entry_sdn) == NULL )
	{
		rc = LDAP_SUCCESS;
		goto bailout;
	}

	if ( slapi_sdn_compare ( requestor_sdn, entry_sdn ) == 0 )
	{
		/* Owner has "g" permission on his own entry */
		rc = LDAP_SUCCESS;
		goto bailout;
	}

	/* if the requestor and the subject user are identical, let's grant it */
	if ( strcasecmp ( slapi_sdn_get_ndn(requestor_sdn), subjectdn ) == 0)
	{
		/* Requestor should see his own permission rights on any entry */
		rc = LDAP_SUCCESS;
		goto bailout;
	}

	aclutil_str_append ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
	slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"_ger_g_permission_granted - %s\n", *errbuf);
	rc = LDAP_INSUFFICIENT_ACCESS;

bailout:
	if ( proxydn )
	{
		/* The ownership of proxydn has passed to requestor_sdn */ 
		slapi_sdn_free ( &requestor_sdn );
	}
	return rc;
}
Пример #19
0
void slapi_rdn_set_sdn( Slapi_RDN *rdn, const Slapi_DN *sdn )
{
	slapi_rdn_set_dn( rdn, slapi_sdn_get_dn( sdn ) );
}
Пример #20
0
/*
 * 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);
	}
}
Пример #21
0
int
aclinit_main()
{
	Slapi_PBlock		*pb;
	int					rv;
	Slapi_DN			*sdn;
	void 				*node;

	if (acl_initialized) {
		/* There is no need to do anything more */
		return 0;
	}

	/* Initialize the LIBACCESS ACL library */
	if (ACL_Init() != 0) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
			 "aclinit_main - ACL Library Initialization failed\n");
		return 1;
	}
	
	/* register all the LASes supported by the DS */
	if (ACL_ERR == __aclinit__RegisterLases()) {
		/* Error is already logged */
		return 1;
	}

	/* Register all the Attrs */
	if (ACL_ERR == __aclinit__RegisterAttributes()) {
		/* Error is already logged */
		return 1;
	}

	/*
	 * Register to get backend state changes so we can add/remove
	 * acis from backends that come up and go down.
	*/

	slapi_register_backend_state_change((void *) NULL, acl_be_state_change_fnc);
	

	/* register the extensions */
	/* ONREPL Moved to the acl_init function because extensions
       need to be registered before any operations are issued
    if  ( 0 != acl_init_ext() ) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
			"Unable to initialize the extensions\n");
		return 1;
	} */

	/* create the mutex array */
	if ( 0 != aclext_alloc_lockarray ( ) ) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
			"aclinit_main - Unable to create the mutext array\n");
		return 1;
	}

    /* Allocate the pool */
	if ( 0 != acl_create_aclpb_pool () ) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
			"aclinit_main - Unable to create the acl private pool\n");
		return 1;
	}

	/*
	 * Now read all the ACLs from all the backends and put it
	 * in a list
	 */
	/* initialize the ACLLIST sub-system */
	if ( 0 != (rv = acllist_init ( ))) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name,
			"aclinit_main - Unable to initialize the plugin:%d\n", rv );
		return 1;
	}

	/* Initialize the anonymous profile i.e., generate it */
	rv = aclanom_init ();

	pb = slapi_pblock_new();
	
	/*
	 * search for the aci_attr_type attributes of all entries.
	 *
	 * slapi_get_fist_suffix() and slapi_get_next_suffix() do not return the 
	 * rootdse entry so we search for acis in there explicitly here.
	*/

	sdn = slapi_sdn_new_ndn_byval("");
	slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"aclinit_main - Searching for all acis(scope base) at suffix ''\n");
	aclinit_search_and_update_aci ( 0,		/* thisbeonly */
										sdn,	/* base */
										NULL,	/* be name*/
										LDAP_SCOPE_BASE, ACL_ADD_ACIS,
										DO_TAKE_ACLCACHE_WRITELOCK);
	slapi_sdn_free(&sdn);	

	sdn = slapi_get_first_suffix( &node, 1 );
	while (sdn)
	{
		slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"aclinit_main - Searching for all acis(scope subtree) at suffix '%s'\n", 
					slapi_sdn_get_dn(sdn) );
		aclinit_search_and_update_aci ( 0,		/* thisbeonly */
										sdn,	/* base */
										NULL,	/* be name*/
										LDAP_SCOPE_SUBTREE, ACL_ADD_ACIS,
										DO_TAKE_ACLCACHE_WRITELOCK);
		sdn = slapi_get_next_suffix( &node, 1 );
	}

	/* Initialize it. */
	acl_initialized = 1;

	/* generate the signatures */
	acl_set_aclsignature ( aclutil_gen_signature ( 100 ) );

	/* Initialize the user-group cache */
	rv = aclgroup_init ( );

	aclanom_gen_anomProfile (DO_TAKE_ACLCACHE_READLOCK);

	/* Register both of the proxied authorization controls (version 1 and 2) */
	slapi_register_supported_control( LDAP_CONTROL_PROXYAUTH,
			SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
			| SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
			| SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN
			| SLAPI_OPERATION_EXTENDED );
	slapi_register_supported_control( LDAP_CONTROL_PROXIEDAUTH,
			SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
			| SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
			| SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN
			| SLAPI_OPERATION_EXTENDED );

	slapi_pblock_destroy ( pb );
	return 0;
}
Пример #22
0
/***************************************************************************
*
* __aclinit_handler
*
*	For each entry, finds if there is any ACL in that entry. If there is
*	then the ACL is processed and stored in the ACL LIST.
*
*
* Input:
*
*
* Returns:
*	None.
*
* Error Handling:
*	If any error found during the ACL generation, the ACL is
*	logged.  Also, set in the callback_data so that caller can act upon it.
*
**************************************************************************/
static int
__aclinit_handler ( Slapi_Entry *e, void *callback_data)	
{
    Slapi_Attr 		*attr;
	aclinit_handler_callback_data_t *call_back_data = 
		(aclinit_handler_callback_data_t*)callback_data;	
	Slapi_DN			*e_sdn;
	int					rv;
	Slapi_Value 		*sval=NULL;

	call_back_data->retCode = 0;		 /* assume success--if there's an error we overwrite it */
    if (e != NULL) {		

		e_sdn = slapi_entry_get_sdn ( e );	

		/*
	 	 * Take the write lock around all the mods--so that
	 	 * other operations will see the acicache either before the whole mod
		 * or after but not, as it was before, during the mod.
		 * This is in line with the LDAP concept of the operation
		 * on the whole entry being the atomic unit.
	 	 * 
		*/
		
		if ( call_back_data->op == ACL_ADD_ACIS ) {
			slapi_log_err(SLAPI_LOG_ACL, plugin_name,
				"Adding acis for entry '%s'\n", slapi_sdn_get_dn(e_sdn));
			slapi_entry_attr_find ( e, aci_attr_type, &attr );

			if ( attr ) {
				
				const struct berval	*attrValue;				
				
				int i;
				if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
					acllist_acicache_WRITE_LOCK();
				}
				i= slapi_attr_first_value ( attr, &sval );
				while(i != -1) {
		        	attrValue = slapi_value_get_berval(sval);									
					
						if ( 0 != (rv=acllist_insert_aci_needsLock (e_sdn, attrValue))) {
							aclutil_print_err(rv, e_sdn, attrValue, NULL); 

							/* We got an error; Log it  and then march along */
							slapi_log_err(SLAPI_LOG_ERR, plugin_name, 
									  "__aclinit_handler - This  (%s) ACL will not be considered for evaluation"
									  " because of syntax errors.\n", 
									  attrValue->bv_val ? attrValue->bv_val: "NULL");
							call_back_data->retCode = rv;
						}				
					i= slapi_attr_next_value( attr, i, &sval );
				}/* while */
				if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
					acllist_acicache_WRITE_UNLOCK();
				}
			}
		} else if (call_back_data->op == ACL_REMOVE_ACIS) {

			/* Here we are deleting the acis. */
				slapi_log_err(SLAPI_LOG_ACL, plugin_name, "__aclinit_handler - Removing acis\n");
				if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
					acllist_acicache_WRITE_LOCK();
				}	
				if ( 0 != (rv=acllist_remove_aci_needsLock(e_sdn, NULL))) {
					aclutil_print_err(rv, e_sdn, NULL, NULL); 

					/* We got an error; Log it  and then march along */
					slapi_log_err(SLAPI_LOG_ERR, plugin_name, 
									  "__aclinit_handler - ACLs not deleted from %s\n",
                                      slapi_sdn_get_dn(e_sdn));
					call_back_data->retCode = rv;
				}
				if ( call_back_data->lock_flag == DO_TAKE_ACLCACHE_WRITELOCK) {
					acllist_acicache_WRITE_UNLOCK();
				}
		}
		
	}

	/*
	 * If we get here it's success.
	 * The call_back_data->error is the error code that counts as it's the
	 * one that the original caller will see--this routine is called off a callbacl.
	*/
	
    return ACL_FALSE;	/* "local" error code--it's 0 */
}
Пример #23
0
int
aclinit_search_and_update_aci ( int thisbeonly, const Slapi_DN *base,
								char *be_name, int scope, int op,
								acl_lock_flag_t lock_flag )
{
	char				*attrs[2] = { "aci", NULL };
	 /* Tell __aclinit_handler whether it's an add or a delete */
	Slapi_PBlock 	*aPb;
	LDAPControl		**ctrls=NULL;
	struct berval	*bval;
	aclinit_handler_callback_data_t call_back_data;

	PR_ASSERT( lock_flag == DONT_TAKE_ACLCACHE_WRITELOCK ||
				lock_flag == DO_TAKE_ACLCACHE_WRITELOCK);

	if ( thisbeonly && be_name == NULL) {
		slapi_log_err(SLAPI_LOG_ERR, plugin_name, 
						"aclinit_search_and_update_aci - be_name must be specified.\n");
		return -1;
	}


	/*
	 * We need to explicitly request (objectclass=ldapsubentry)
	 * in order to get all the subentry acis too.
	 * Note that subentries can be added under subentries (although its not
	 * recommended) so that
	 * there may be non-trivial acis under a subentry.
	*/ 

	/* Use new search internal API                 */
	/* and never retrieve aci from a remote server */
	aPb = slapi_pblock_new ();
		
	/*
	 * Set up the control to say "Only get acis from this Backend--
	 * there may be more backends under this one.
	*/

	if ( thisbeonly ) {		
		
		bval = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
		bval->bv_len = strlen(be_name) + 1;
		bval->bv_val = slapi_ch_strdup(be_name);

		ctrls = (LDAPControl **)slapi_ch_calloc( 2, sizeof(LDAPControl *));
		ctrls[0] = NULL;
		ctrls[1] = NULL;
	
		slapi_build_control_from_berval(
										MTN_CONTROL_USE_ONE_BACKEND_OID,
                						bval,
										1 /* is critical */, 
										ctrls);

	}	

	slapi_search_internal_set_pb (	aPb,
					slapi_sdn_get_dn(base),
					scope,
					"(|(aci=*)(objectclass=ldapsubentry))",
					attrs,
					0 /* attrsonly */,
					ctrls /* controls: SLAPI_ARGCONTROLS */,
					NULL /* uniqueid */,
					aclplugin_get_identity (ACL_PLUGIN_IDENTITY),
					SLAPI_OP_FLAG_NEVER_CHAIN /* actions : get local aci only */);
	
	if (thisbeonly) {
		slapi_pblock_set(aPb, SLAPI_REQCONTROLS, ctrls);
	}

	call_back_data.op = op;
	call_back_data.retCode = 0;
	call_back_data.lock_flag = lock_flag;

	slapi_search_internal_callback_pb(aPb,
					  &call_back_data /* callback_data */,
					  NULL/* result_callback */,
					  __aclinit_handler,
					  NULL /* referral_callback */);

	if (thisbeonly) {				
		slapi_ch_free((void **)&bval);				
	}	

	/*
	 * This frees the control oid, the bv_val and the control itself and the 
	 * ctrls array mem by caling ldap_controls_free()--so we
	 * don't need to do it ourselves.
	*/
	slapi_pblock_destroy (aPb);
	
	return call_back_data.retCode; 

}
Пример #24
0
int
update_integrity(char **argv, Slapi_DN *origSDN,
                 char *newrDN, Slapi_DN *newsuperior, 
                 int logChanges)
{
    Slapi_PBlock *search_result_pb = NULL;
    Slapi_PBlock *mod_pb = slapi_pblock_new();
    Slapi_Entry  **search_entries = NULL;
    Slapi_DN *sdn = NULL;
    Slapi_Attr *attr = NULL;
    void *node = NULL;
    const char *origDN = slapi_sdn_get_dn(origSDN);
    const char *search_base = NULL;
    char *attrName = NULL;
    char *filter = NULL;
    char *attrs[2];
    int search_result;
    int nval = 0;
    int i, j;
    int rc;

    if ( argv == NULL ){
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
            "referint_postop required config file arguments missing\n" );
        rc = -1;
        goto free_and_return;
    } 
    /*
     *  For now, just putting attributes to keep integrity on in conf file,
     *  until resolve the other timing mode issue
     */
    search_result_pb = slapi_pblock_new();

    /* Search each namingContext in turn */
    for ( sdn = slapi_get_first_suffix( &node, 0 ); sdn != NULL;
          sdn = slapi_get_next_suffix( &node, 0 ))
    {
        Slapi_Backend *be = slapi_be_select(sdn);
        search_base = slapi_sdn_get_dn( sdn );

        for(i = 3; argv[i] != NULL; i++){
            filter = slapi_filter_sprintf("(%s=*%s%s)", argv[i], ESC_NEXT_VAL, origDN);
            if ( filter ) {
                /* Need only the current attribute and its subtypes */
                attrs[0] = argv[i];
                attrs[1] = NULL;

                /* Use new search API */
                slapi_pblock_init(search_result_pb);
                slapi_pblock_set(search_result_pb, SLAPI_BACKEND, be);
                slapi_search_internal_set_pb(search_result_pb, search_base, 
                    LDAP_SCOPE_SUBTREE, filter, attrs, 0 /* attrs only */,
                    NULL, NULL, referint_plugin_identity, 0);
                slapi_search_internal_pb(search_result_pb);
  
                slapi_pblock_get( search_result_pb, SLAPI_PLUGIN_INTOP_RESULT, &search_result);

                /* if search successfull then do integrity update */
                if(search_result == LDAP_SUCCESS)
                {
                    slapi_pblock_get(search_result_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
                                     &search_entries);

                    for(j = 0; search_entries[j] != NULL; j++){
                        attr = NULL;
                        attrName = NULL;
                        /*
                         *  Loop over all the attributes of the entry and search
                         *  for the integrity attribute and its subtypes
                         */
                        for (slapi_entry_first_attr(search_entries[j], &attr); attr; 
                             slapi_entry_next_attr(search_entries[j], attr, &attr))
                        {
                            /*
                             *  Take into account only the subtypes of the attribute
                             *  in argv[i] having the necessary value  - origDN
                             */
                            slapi_attr_get_type(attr, &attrName);
                            if (slapi_attr_type_cmp(argv[i], attrName,
                                                    SLAPI_TYPE_CMP_SUBTYPE) == 0)
                            {
                                nval = 0;
                                slapi_attr_get_numvalues(attr, &nval);
                                /* 
                                 * We want to reduce the "modify" call as much as
                                 * possible. But if an entry contains 1000s of 
                                 * attributes which need to be updated by the 
                                 * referint plugin (e.g., a group containing 1000s 
                                 * of members), we want to avoid to allocate too 
                                 * many mods * in one "modify" call.
                                 * This is a compromise: If an attribute type has
                                 * more than 128 values, we update the attribute 
                                 * value one by one. Otherwise, update all values
                                 * in one "modify" call.
                                 */
                                if (nval > 128) {
                                    rc = _update_one_per_mod(
                                         slapi_entry_get_sdn(search_entries[j]),
                                         attr, attrName, origSDN, newrDN, 
                                         slapi_sdn_get_dn(newsuperior),
                                         mod_pb);
                                } else {
                                    rc = _update_all_per_mod(
                                         slapi_entry_get_sdn(search_entries[j]),
                                         attr, attrName, origSDN, newrDN, 
                                         slapi_sdn_get_dn(newsuperior),
                                         mod_pb);
                                }
                                /* Should we stop if one modify returns an error? */
                            }
                        }
                    }
                } else {
                    if (isFatalSearchError(search_result)){
                        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                            "update_integrity search (base=%s filter=%s) returned "
                            "error %d\n", search_base, filter, search_result);
                        rc = -1;
                        goto free_and_return;
                    }
                }
                slapi_ch_free_string(&filter);
            }
            slapi_free_search_results_internal(search_result_pb);
        }
    }
    /* if got here, then everything good rc = 0 */
    rc = 0;

free_and_return:
    /* free filter and search_results_pb */
    slapi_ch_free_string(&filter);

    slapi_pblock_destroy(mod_pb);
    if (search_result_pb) {
        slapi_free_search_results_internal(search_result_pb);
        slapi_pblock_destroy(search_result_pb);
    }
 
    return(rc);
}
Пример #25
0
/*
 * update multiple attribute values per _do_modify
 */
static int
_update_all_per_mod(Slapi_DN *entrySDN,      /* DN of the searched entry */
                    Slapi_Attr *attr,        /* referred attribute */
                    char *attrName,
                    Slapi_DN *origDN,        /* original DN that was modified */
                    char *newRDN,            /* new RDN from modrdn */
                    const char *newsuperior, /* new superior from modrdn */
                    Slapi_PBlock *mod_pb)
{
    Slapi_Mods *smods = NULL;
    char *newDN = NULL;
    char **dnParts = NULL;
    char *sval = NULL;
    char *newvalue = NULL;
    char *p = NULL;
    size_t dnlen = 0;
    int rc = 0;
    int nval = 0;

    slapi_attr_get_numvalues(attr, &nval);

    if (NULL == newRDN && NULL == newsuperior) {
        /* in delete mode */
        LDAPMod *mods[2];
        char *values_del[2];
        LDAPMod attribute1;

        /* delete old dn so set that up */
        values_del[0] = (char *)slapi_sdn_get_dn(origDN);
        values_del[1] = NULL;
        attribute1.mod_type = attrName;
        attribute1.mod_op = LDAP_MOD_DELETE;
        attribute1.mod_values = values_del;
        mods[0] = &attribute1;
        /* terminate list of mods. */
        mods[1] = NULL;
        rc = _do_modify(mod_pb, entrySDN, mods);
        if (rc) {
            slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                "_update_all_per_mod: entry %s: deleting \"%s: %s\" failed (%d)"
                "\n", slapi_sdn_get_dn(entrySDN), attrName, slapi_sdn_get_dn(origDN), rc);
        }
    } else {
        /* in modrdn mode */
        const char *superior = NULL;
        int nval = 0;
        Slapi_Value *v = NULL;

        if (NULL == origDN) {
            slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                            "_update_all_per_mod: NULL dn was passed\n");
            goto bail;
        }
        /* need to put together rdn into a dn */
        dnParts = slapi_ldap_explode_dn( slapi_sdn_get_dn(origDN), 0 );
        if (NULL == dnParts) {
            slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                            "_update_all_per_mod: failed to explode dn %s\n",
                            slapi_sdn_get_dn(origDN));
            goto bail;
        }
        if (NULL == newRDN) {
            newRDN = dnParts[0];
        }
        if (newsuperior) {
            superior = newsuperior;
        } else {
            /* do not free superior */
            superior = slapi_dn_find_parent(slapi_sdn_get_dn(origDN));
        }
        /* newRDN and superior are already normalized. */
        newDN = slapi_ch_smprintf("%s,%s", newRDN, superior);
        slapi_dn_ignore_case(newDN);
        /* 
         * Compare the modified dn with the value of 
         * the target attribute of referint to find out
         * the modified dn is the ancestor (case 2) or
         * the value itself (case 1).
         *
         * E.g., 
         * (case 1) 
         * modrdn: uid=A,ou=B,o=C --> uid=A',ou=B',o=C
         *            (origDN)             (newDN)
         * member: uid=A,ou=B,ou=C --> uid=A',ou=B',ou=C
         *            (sval)               (newDN)
         *
         * (case 2) 
         * modrdn: ou=B,o=C --> ou=B',o=C
         *         (origDN)      (newDN)
         * member: uid=A,ou=B,ou=C --> uid=A,ou=B',ou=C
         *         (sval)              (sval' + newDN)
         */
        slapi_attr_get_numvalues(attr, &nval);
        smods = slapi_mods_new();
        slapi_mods_init(smods, 2 * nval + 1);

        for (nval = slapi_attr_first_value(attr, &v);
             nval != -1;
             nval = slapi_attr_next_value(attr, nval, &v)) {
            p = NULL;
            dnlen = 0;

            /* DN syntax, which should be a string */
            sval = slapi_ch_strdup(slapi_value_get_string(v));
            rc = slapi_dn_normalize_case_ext(sval, 0,  &p, &dnlen);
            if (rc == 0) { /* sval is passed in; not terminated */
                *(p + dnlen) = '\0';
                sval = p;
            } else if (rc > 0) {
                slapi_ch_free_string(&sval);
                sval = p;
            }
            /* else: (rc < 0) Ignore the DN normalization error for now. */

            p = PL_strstr(sval, slapi_sdn_get_ndn(origDN));
            if (p == sval) {
                /* (case 1) */
                slapi_mods_add_string(smods, LDAP_MOD_DELETE, attrName, sval);
                slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newDN);

            } else if (p) {
                /* (case 2) */
                slapi_mods_add_string(smods, LDAP_MOD_DELETE, attrName, sval);
                *p = '\0';
                newvalue = slapi_ch_smprintf("%s%s", sval, newDN);
                slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newvalue);
                slapi_ch_free_string(&newvalue);
            } 
            /* else: value does not include the modified DN.  Ignore it. */
            slapi_ch_free_string(&sval);
        }
        rc = _do_modify(mod_pb, entrySDN, slapi_mods_get_ldapmods_byref(smods));
        if (rc) {
            slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                        "_update_all_per_mod: entry %s failed (%d)\n",
                        slapi_sdn_get_dn(entrySDN), rc);
        }

        /* cleanup memory allocated for dnParts and newDN */
        if (dnParts){
            slapi_ldap_value_free(dnParts);
            dnParts = NULL;
        }
        slapi_ch_free_string(&newDN);
        slapi_mods_free(&smods);
    }

bail:
    return rc;
}
Пример #26
0
Файл: add.c Проект: Firstyear/ds
/* This function is called to process operation that come over external connections */
void
do_add( Slapi_PBlock *pb )
{
	Slapi_Operation *operation;
	BerElement		*ber;
	char			*last;
	ber_len_t		len = LBER_ERROR;
	ber_tag_t		tag;
	Slapi_Entry		*e = NULL;
	int			err;
	int			rc;
	PRBool  searchsubentry=PR_TRUE;

	slapi_log_err(SLAPI_LOG_TRACE, "do_add", "==>\n");

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

	/* count the add request */
	slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps);

	/*
	 * Parse the add request.  It looks like this:
	 *
	 *	AddRequest := [APPLICATION 14] SEQUENCE {
	 *		name	DistinguishedName,
	 *		attrs	SEQUENCE OF SEQUENCE {
	 *			type	AttributeType,
	 *			values	SET OF AttributeValue
	 *		}
	 *	}
	 */
	/* get the name */
	{
		char *rawdn = NULL;
		Slapi_DN mysdn;
		if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR ) {
			slapi_ch_free_string(&rawdn);
			slapi_log_err(SLAPI_LOG_ERR, "do_add",
				"ber_scanf failed (op=Add; params=DN)\n");
			op_shared_log_error_access (pb, "ADD", "???", "decoding error");
			send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
				"decoding error", 0, NULL );
			return;
		}
		/* Check if we should be performing strict validation. */
		if (config_get_dn_validate_strict()) {
			/* check that the dn is formatted correctly */
			rc = slapi_dn_syntax_check(pb, rawdn, 1);
			if (rc) { /* syntax check failed */
				op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"",
										   "strict: invalid dn");
				send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
								 NULL, "invalid dn", 0, NULL);
				slapi_ch_free_string(&rawdn);
				return;
			}
		}
		slapi_sdn_init_dn_passin(&mysdn, rawdn);
		if (rawdn && (strlen(rawdn) > 0) &&
		    (NULL == slapi_sdn_get_dn(&mysdn))) {
			/* normalization failed */
			op_shared_log_error_access(pb, "ADD", rawdn, "invalid dn");
			send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
			                 "invalid dn", 0, NULL);
			slapi_sdn_done(&mysdn);
			return;
		}
		e = slapi_entry_alloc();
		/* Responsibility for DN is passed to the Entry. */
		slapi_entry_init_ext(e, &mysdn, NULL);
		slapi_sdn_done(&mysdn);
	}
	slapi_log_err(SLAPI_LOG_ARGS, "do_add", "dn (%s)\n", (char *)slapi_entry_get_dn_const(e));

	/* get the attrs */
	for ( tag = ber_first_element( ber, &len, &last );
	      tag != LBER_DEFAULT && tag != LBER_END_OF_SEQORSET;
	      tag = ber_next_element( ber, &len, last ) ) {
		char *type = NULL, *normtype = NULL;
		struct berval	**vals = NULL;
		len = -1; /* reset - not used in loop */
		if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) {
			op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error");
			send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
			    "decoding error", 0, NULL );
            slapi_ch_free_string(&type);
            ber_bvecfree( vals );
			goto free_and_return;
		}

		if ( vals == NULL ) {
			slapi_log_err(SLAPI_LOG_ERR, "do_add - no values for type %s\n", type, 0, 0 );
			op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "null value");
			send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL,
			    0, NULL );
            slapi_ch_free_string(&type);
			goto free_and_return;
		}

		normtype = slapi_attr_syntax_normalize(type);
		if ( !normtype || !*normtype ) {
			char ebuf[SLAPI_DSE_RETURNTEXT_SIZE];
			rc = LDAP_INVALID_SYNTAX;
			slapi_create_errormsg(ebuf, sizeof(ebuf), "invalid type '%s'", type);
			op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), ebuf);
			send_ldap_result( pb, rc, NULL, ebuf, 0, NULL );
            slapi_ch_free_string(&type);
			slapi_ch_free( (void**)&normtype );
			ber_bvecfree( vals );
			goto free_and_return;
		}
		slapi_ch_free_string(&type);
	
       /* for now we just ignore attributes that client is not allowed
          to modify so not to break existing clients */
		if (op_shared_is_allowed_attr (normtype, pb->pb_conn->c_isreplication_session)){		
			if (( rc = slapi_entry_add_values( e, normtype, vals ))
				!= LDAP_SUCCESS ) {
				slapi_log_access( LDAP_DEBUG_STATS, 
					"conn=%" NSPRIu64 " op=%d ADD dn=\"%s\", add values for type %s failed\n",
					pb->pb_conn->c_connid, operation->o_opid,
					slapi_entry_get_dn_const(e), normtype );
				send_ldap_result( pb, rc, NULL, NULL, 0, NULL );

				slapi_ch_free( (void**)&normtype );
				ber_bvecfree( vals );
				goto free_and_return;
			}

			/* if this is uniqueid attribute, set uniqueid field of the entry */
			if (strcasecmp (normtype, SLAPI_ATTR_UNIQUEID) == 0)
			{
				e->e_uniqueid = slapi_ch_strdup (vals[0]->bv_val);
			}
			if(searchsubentry) searchsubentry=check_oc_subentry(e,vals,normtype);
		}

		slapi_ch_free( (void**)&normtype );
		ber_bvecfree( vals );
	}

	/* Ensure that created attributes are not used in the RDN. */
	if (check_rdn_for_created_attrs(e)) {
		op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn(slapi_entry_get_sdn_const(e)), "invalid DN");
		send_ldap_result( pb, LDAP_INVALID_DN_SYNTAX, NULL, "illegal attribute in RDN", 0, NULL );
		goto free_and_return;
	}

    /* len, is ber_len_t, which is uint. Can't be -1. May be better to remove (len != 0) check */
	if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) ) {
		op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error");
		send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
		    "decoding error", 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, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), 
								    "failed to decode LDAP controls");
		send_ldap_result( pb, err, NULL, NULL, 0, NULL );
		goto free_and_return;
	}

	slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &operation->o_isroot );
	slapi_pblock_set( pb, SLAPI_ADD_ENTRY, e );

        if (pb->pb_conn->c_flags & CONN_FLAG_IMPORT) {
            /* this add is actually part of a bulk import -- punt */
            handle_fast_add(pb, e);
        } else {
            op_shared_add ( pb );
        }

	/* make sure that we don't free entry if it is successfully added */
	e = NULL;

free_and_return:;
	if (e)
		slapi_entry_free (e);

}
Пример #27
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;
}
Пример #28
0
Slapi_RDN *slapi_rdn_new_sdn( const Slapi_DN *sdn )
{
	return slapi_rdn_new_dn( slapi_sdn_get_dn( sdn ) );
}
Пример #29
0
/*
 *  Write this record to the log file
 */
void
writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn,
                  char *newrdn, Slapi_DN *newsuperior, Slapi_DN *requestorsdn)
{
    PRFileDesc *prfd;
    char buffer[MAX_LINE];
    int len_to_write = 0;
    int rc;
    const char *requestordn = NULL;
    const char *newsuperiordn = NULL;
    size_t reqdn_len = 0;
    
    /*
     * Use this lock to protect file data when update integrity is occuring.
     * If betxn is enabled, this mutex is ignored; transaction itself takes
     * the role.
     */
    referint_lock();
    if (( prfd = PR_Open( logfilename, PR_WRONLY | PR_CREATE_FILE | PR_APPEND,
          REFERINT_DEFAULT_FILE_MODE )) == NULL ) 
    {
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
            "referint_postop could not write integrity log \"%s\" "
        SLAPI_COMPONENT_NAME_NSPR " %d (%s)\n",
            logfilename, PR_GetError(), slapd_pr_strerror(PR_GetError()) );

        PR_Unlock(referint_mutex);
        referint_unlock();
        return;
    }
    /*
     *  Make sure we have enough room in our buffer before trying to write it.
     *  add length of dn +  5(three tabs, a newline, and terminating \0)
     */
    len_to_write = slapi_sdn_get_ndn_len(sdn) + 5;

    if(newrdn == NULL){
        /* add the length of "NULL" */
        len_to_write += 4;
    } else {
        /* add the length of the newrdn */
        len_to_write += strlen(newrdn);
    }
    newsuperiordn = slapi_sdn_get_dn(newsuperior);
    if(NULL == newsuperiordn)
    {
        /* add the length of "NULL" */
        len_to_write += 4;
    } else {
        /* add the length of the newsuperior */
        len_to_write += slapi_sdn_get_ndn_len(newsuperior);
    }
    slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &requestordn);
    if (requestorsdn && (requestordn = slapi_sdn_get_udn(requestorsdn)) &&
        (reqdn_len = strlen(requestordn))) {
        len_to_write += reqdn_len;
    } else {
        len_to_write += 4; /* "NULL" */
    }

    if(len_to_write > MAX_LINE ){
        slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
                         "referint_postop could not write integrity log:"
                         " line length exceeded. It will not be able"
                         " to update references to this entry.\n");
    } else {
        PR_snprintf(buffer, MAX_LINE, "%s\t%s\t%s\t%s\t\n", slapi_sdn_get_dn(sdn),
                    (newrdn != NULL) ? newrdn : "NULL",
                    (newsuperiordn != NULL) ? newsuperiordn : "NULL",
                    requestordn ? requestordn : "NULL");
        if (PR_Write(prfd,buffer,strlen(buffer)) < 0){
            slapi_log_error(SLAPI_LOG_FATAL,REFERINT_PLUGIN_SUBSYSTEM,
                " writeintegritylog: PR_Write failed : The disk"
                " may be full or the file is unwritable :: NSPR error - %d\n",
            PR_GetError());
        }
    }

    /* If file descriptor is closed successfully, PR_SUCCESS */
    rc = PR_Close(prfd);
    if (rc != PR_SUCCESS){
        slapi_log_error(SLAPI_LOG_FATAL,REFERINT_PLUGIN_SUBSYSTEM,
            " writeintegritylog: failed to close the file descriptor prfd; NSPR error - %d\n",
            PR_GetError());
    }
    referint_unlock();
}
Пример #30
0
Файл: add.c Проект: Firstyear/ds
static int 
add_created_attrs(Slapi_PBlock *pb, Slapi_Entry *e)
{
	char   buf[20];
	char   *binddn = NULL;
	char   *plugin_dn = NULL;
	struct berval	bv;
	struct berval	*bvals[2];
	time_t		curtime;
	struct tm	ltm;
	Operation *op;
	struct slapdplugin *plugin = NULL;
	struct slapi_componentid *cid = NULL;
	slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();

	slapi_log_err(SLAPI_LOG_TRACE, "add_created_attrs", "==>\n");

	bvals[0] = &bv;
	bvals[1] = NULL;
	slapi_pblock_get(pb, SLAPI_OPERATION, &op);
	
	if(slapdFrontendConfig->plugin_track){
		/* plugin bindDN tracking is enabled, grab the dn from thread local storage */
		if(slapi_sdn_isempty(&op->o_sdn)){
			bv.bv_val = "";
			bv.bv_len = 0;
		} else {
			slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
			if (cid){
				plugin=(struct slapdplugin *) cid->sci_plugin;
			} else {
				slapi_pblock_get (pb, SLAPI_PLUGIN, &plugin);
			}
			if(plugin)
				plugin_dn = plugin_get_dn (plugin);
			if(plugin_dn){
				bv.bv_val = plugin_dn;
				bv.bv_len = strlen(bv.bv_val);
			} else {
				bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn);
				bv.bv_len = strlen(bv.bv_val);
			}
		}
		slapi_entry_attr_replace(e, "internalCreatorsName", bvals);
		slapi_entry_attr_replace(e, "internalModifiersName", bvals);
		slapi_ch_free_string(&plugin_dn);

		/* Grab the thread data(binddn) */
		slapi_td_get_dn(&binddn);

		if(binddn == NULL){
			/* anonymous bind */
			bv.bv_val = "";
			bv.bv_len = 0;
		} else {
			bv.bv_val = binddn;
			bv.bv_len = strlen(bv.bv_val);
		}
	} else {
		if (slapi_sdn_isempty(&op->o_sdn)) {
			bv.bv_val = "";
			bv.bv_len = 0;
		} else {
			bv.bv_val = (char*)slapi_sdn_get_dn(&op->o_sdn);
			bv.bv_len = strlen(bv.bv_val);
		}
	}

	slapi_entry_attr_replace(e, "creatorsname", bvals);
	slapi_entry_attr_replace(e, "modifiersname", bvals);

	curtime = current_time();
	gmtime_r(&curtime, &ltm);
	strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", &ltm);

	bv.bv_val = buf;
	bv.bv_len = strlen(bv.bv_val);
	slapi_entry_attr_replace(e, "createtimestamp", bvals);

	bv.bv_val = buf;
	bv.bv_len = strlen(bv.bv_val);
	slapi_entry_attr_replace(e, "modifytimestamp", bvals);

	if (add_uniqueid(e) != UID_SUCCESS ) {
		return( -1 );
	}

	return( 0 );
}