Example #1
0
/*
 * Create a new protocol instance.
 */
Repl_Protocol *
prot_new(Repl_Agmt *agmt, int protocol_state)
{
	Slapi_DN *replarea_sdn = NULL;
	Repl_Protocol *rp = (Repl_Protocol *)slapi_ch_calloc(1, sizeof(Repl_Protocol));

	rp->prp_incremental = rp->prp_total = rp->prp_active_protocol = NULL;
	if (protocol_state == STATE_PERFORMING_TOTAL_UPDATE)
	{
		rp->state = STATE_PERFORMING_TOTAL_UPDATE;
	}
	else
	{
		rp->state = STATE_PERFORMING_INCREMENTAL_UPDATE;
	}
	rp->next_state = STATE_PERFORMING_INCREMENTAL_UPDATE; 
	if ((rp->lock = PR_NewLock()) == NULL)
	{
		goto loser;
	}
	rp->agmt = agmt;
	rp->conn = NULL;
	/* Acquire the local replica object */
	replarea_sdn = agmt_get_replarea(agmt);
	rp->replica_object = replica_get_replica_from_dn(replarea_sdn);
	if (NULL == rp->replica_object)
	{
		/* Whoa, no local replica!?!? */
		slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
			"prot_new - %s: Unable to locate replica object for local replica %s\n",
			agmt_get_long_name(agmt),
			slapi_sdn_get_dn(replarea_sdn));
		goto loser;
	}

	if (get_agmt_agreement_type(agmt) == REPLICA_TYPE_MULTIMASTER)
	{
		rp->prp_incremental = private_protocol_factory(rp, PROTOCOL_5_INCREMENTAL);
		rp->prp_total = private_protocol_factory(rp, PROTOCOL_5_TOTAL);
		rp->delete_conn = conn_delete;
	} 
	else if  (get_agmt_agreement_type(agmt) == REPLICA_TYPE_WINDOWS)
	{
		rp->prp_incremental = private_protocol_factory(rp, PROTOCOL_WINDOWS_INCREMENTAL);
		rp->prp_total = private_protocol_factory(rp, PROTOCOL_WINDOWS_TOTAL);
		rp->delete_conn = windows_conn_delete;
	}
	/* XXXggood register callback handlers for entries updated, and
		schedule window enter/leave. */
	
	goto done;

loser:
	prot_delete(&rp);

done:
	slapi_sdn_free(&replarea_sdn);

	return rp;
}
Example #2
0
static int
agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *e,
	int *returncode, char *returntext, void *arg)
{
	int i;
	Slapi_DN *sdn = NULL;
	int start_initialize = 0, stop_initialize = 0, cancel_initialize = 0;
    int update_the_schedule = 0;	/* do we need to update the repl sched? */
	Repl_Agmt *agmt = NULL;
	LDAPMod **mods;
    char buff [SLAPI_DSE_RETURNTEXT_SIZE];
    char *errortext = returntext ? returntext : buff;
    int rc = SLAPI_DSE_CALLBACK_OK;
    Slapi_Operation *op;
    void *identity;

    *returncode = LDAP_SUCCESS;

     /* just let internal operations originated from replication plugin to go through */
    slapi_pblock_get (pb, SLAPI_OPERATION, &op);
    slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &identity);                

    if (operation_is_flag_set(op, OP_FLAG_INTERNAL) &&
        (identity == repl_get_plugin_identity (PLUGIN_MULTIMASTER_REPLICATION)))
    {
        goto done;
    }

    slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
    if (NULL == sdn) {
        slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, 
                        "agmtlist_modify_callback: NULL target dn\n");
        goto done;
    }
	agmt = agmtlist_get_by_agmt_name(sdn);
	if (NULL == agmt)
	{
		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "agmtlist_modify_callback: received "
			"a modification for unknown replication agreement \"%s\"\n", 
			slapi_sdn_get_dn(sdn));
		goto done;
	}

	slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
	for (i = 0; NULL != mods && NULL != mods[i]; i++)
	{
		if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaInitialize))
		{
            /* we don't allow delete attribute operations unless it was issued by
               the replication plugin - handled above */
            if (mods[i]->mod_op & LDAP_MOD_DELETE)
            {
                if(strcasecmp (mods[i]->mod_type, type_nsds5ReplicaCleanRUVnotified) == 0){
                    /* allow the deletion of cleanallruv agmt attr */
                    continue;
                }

                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "deletion of %s attribute is not allowed\n", type_nsds5ReplicaInitialize);	
                *returncode = LDAP_UNWILLING_TO_PERFORM;
                rc = SLAPI_DSE_CALLBACK_ERROR;
                break;
            }
            else
            {
                char *val;

                if (mods[i]->mod_bvalues && mods[i]->mod_bvalues[0])
                    val = slapi_berval_get_string_copy (mods[i]->mod_bvalues[0]);
                else
                {
                    slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "no value provided for %s attribute\n", type_nsds5ReplicaInitialize);
                    *returncode = LDAP_UNWILLING_TO_PERFORM;
                    rc = SLAPI_DSE_CALLBACK_ERROR;
                    break;   
                }

			    /* Start replica initialization */
                if (val == NULL)
                {
                    PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "No value supplied for attr (%s)", mods[i]->mod_type);
                    slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: %s\n",
                                    errortext);	  
                    *returncode = LDAP_UNWILLING_TO_PERFORM;
                    rc = SLAPI_DSE_CALLBACK_ERROR;
                    break;
                }
            
                if (strcasecmp (val, "start") == 0)
                {                        
                    start_initialize = 1;
                }
                else if (strcasecmp (val, "stop") == 0)
                {
                    stop_initialize = 1;
                }
                else if (strcasecmp (val, "cancel") == 0)
                {
                    cancel_initialize = 1;
                }
                else
                {
                    PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Invalid value (%s) value supplied for attr (%s)", 
                             val, mods[i]->mod_type);
                    slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: %s\n", errortext);
                }
                slapi_ch_free ((void**)&val);
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaUpdateSchedule))
		{
			/*
			 * Request to update the replication schedule.  Set a flag so
			 * we know to update the schedule later.
			 */
			update_the_schedule = 1;
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaCredentials))
		{
			/* New replica credentials */
			if (agmt_set_credentials_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update credentials for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaTimeout))
		{
			/* New replica timeout */
			if (agmt_set_timeout_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update timeout for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaBusyWaitTime))
		{
			/* New replica busywaittime */
			if (agmt_set_busywaittime_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update busy wait time for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaSessionPauseTime))
		{
			/* New replica pausetime */
			if (agmt_set_pausetime_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update session pause time for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaBindDN))
		{
			/* New replica Bind DN */
			if (agmt_set_binddn_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update bind DN for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
		                                     type_nsds5ReplicaPort))
		{
			/* New replica port */
			if (agmt_set_port_from_entry(agmt, e) != 0)
			{
				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
				                "agmtlist_modify_callback: " 
				                "failed to update port for agreement %s\n",
				                agmt_get_long_name(agmt));	
				*returncode = LDAP_OPERATIONS_ERROR;
				rc = SLAPI_DSE_CALLBACK_ERROR;
			}
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5TransportInfo))
		{
			/* New Transport info */
			if (agmt_set_transportinfo_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update transport info for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicaBindMethod))
		{
			if (agmt_set_bind_method_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update bind method for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicatedAttributeList))
		{
			char **denied_attrs = NULL;
			/* New set of excluded attributes */
			if (agmt_set_replicated_attributes_from_entry(agmt, e) != 0)
            {
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                                "failed to update replicated attributes for agreement %s\n",
                                agmt_get_long_name(agmt));	
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
			/* Check that there are no verboten attributes in the exclude list */
			denied_attrs = agmt_validate_replicated_attributes(agmt, 0 /* incremental */);
			if (denied_attrs)
			{
				/* Report the error to the client */
				PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "attempt to exclude an illegal attribute in a fractional agreement");
				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                            "attempt to exclude an illegal attribute in a fractional agreement\n");

				*returncode = LDAP_UNWILLING_TO_PERFORM;
				rc = SLAPI_DSE_CALLBACK_ERROR;
				/* Free the deny list if we got one */
				slapi_ch_array_free(denied_attrs);
				break;
			}
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
					type_nsds5ReplicatedAttributeListTotal))
		{
			char **denied_attrs = NULL;
			/* New set of excluded attributes */
			if (agmt_set_replicated_attributes_total_from_entry(agmt, e) != 0)
			{
				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
								"failed to update total update replicated attributes for agreement %s\n",
								agmt_get_long_name(agmt));
				*returncode = LDAP_OPERATIONS_ERROR;
				rc = SLAPI_DSE_CALLBACK_ERROR;
			}
			/* Check that there are no verboten attributes in the exclude list */
			denied_attrs = agmt_validate_replicated_attributes(agmt, 1 /* total */);
			if (denied_attrs)
			{
				/* Report the error to the client */
				PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE, "attempt to exclude an illegal total update "
						"attribute in a fractional agreement");
				slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
						"attempt to exclude an illegal total update attribute in a fractional agreement\n");

				*returncode = LDAP_UNWILLING_TO_PERFORM;
				rc = SLAPI_DSE_CALLBACK_ERROR;
				/* Free the deny list if we got one */
				slapi_ch_array_free(denied_attrs);
				break;
			}
		}
		else if (slapi_attr_types_equivalent(mods[i]->mod_type,
											 "nsds5debugreplicatimeout"))
		{
			char *val = slapi_entry_attr_get_charptr(e, "nsds5debugreplicatimeout");
			repl5_set_debug_timeout(val);
			slapi_ch_free_string(&val);
		}
        else if (strcasecmp (mods[i]->mod_type, "modifytimestamp") == 0 ||
                 strcasecmp (mods[i]->mod_type, "modifiersname") == 0 ||
                 strcasecmp (mods[i]->mod_type, "description") == 0)
        {
            /* ignore modifier's name and timestamp attributes and the description. */
            continue;
        }
        else if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaEnabled))
        {
            if(agmt_set_enabled_from_entry(agmt, e, returntext) != 0){
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
                    "failed to set replica agmt state \"enabled/disabled\" for %s\n",agmt_get_long_name(agmt));
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
        }
        else if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaStripAttrs))
        {
            if(agmt_set_attrs_to_strip(agmt, e) != 0){
                slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
                    "failed to set replica agmt attributes to strip for %s\n",agmt_get_long_name(agmt));
                *returncode = LDAP_OPERATIONS_ERROR;
                rc = SLAPI_DSE_CALLBACK_ERROR;
            }
        }
        else if (0 == windows_handle_modify_agreement(agmt, mods[i]->mod_type, e))
        {
            slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                            "modification of %s attribute is not allowed\n", mods[i]->mod_type);
            *returncode = LDAP_UNWILLING_TO_PERFORM;
            rc = SLAPI_DSE_CALLBACK_ERROR;
            break;
        }
	}

	if (stop_initialize)
	{
        agmt_stop (agmt);
    }
    else if (start_initialize)
    {
        if (agmt_initialize_replica(agmt) != 0) {
            /* The suffix/repl agmt is disabled */
            agmt_set_last_init_status(agmt, 0, NSDS50_REPL_DISABLED, NULL);
            if(agmt_is_enabled(agmt)){
                PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Suffix is disabled");
            } else {
                PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Replication agreement is disabled");
            }
            *returncode = LDAP_UNWILLING_TO_PERFORM;
            rc = SLAPI_DSE_CALLBACK_ERROR;
        }
    }
    else if (cancel_initialize)
    {
        agmt_replica_init_done(agmt);
    }

	if (update_the_schedule) 
    {
		if (agmt_set_schedule_from_entry(agmt, e) != 0)
        {
            slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: " 
                            "failed to update replication schedule for agreement %s\n",
                            agmt_get_long_name(agmt));	
            *returncode = LDAP_OPERATIONS_ERROR;
            rc = SLAPI_DSE_CALLBACK_ERROR;
        }
	}

done:
	if (NULL != agmt)
	{
		agmtlist_release_agmt(agmt);
	}

	return rc;
}