コード例 #1
0
ファイル: value.c プロジェクト: Firstyear/ds
Slapi_Value *
slapi_value_new_string(const char *s)
{
    Slapi_Value *v= value_new(NULL,CSN_TYPE_UNKNOWN,NULL);
	slapi_value_set_string(v, s);
	return v;
}
コード例 #2
0
ファイル: value.c プロジェクト: Firstyear/ds
Slapi_Value *
slapi_value_init_string(Slapi_Value *v,const char *s)
{
    value_init(v,NULL,CSN_TYPE_UNKNOWN,NULL);
	slapi_value_set_string(v,s);
	return v;
}
コード例 #3
0
ファイル: testpreop.c プロジェクト: Firstyear/ds
/* Pre-operation plug-in function */
int
testpreop_add( Slapi_PBlock *pb )
{
	Slapi_Entry	*e;
	Slapi_Attr	*a;
	Slapi_Value	*v;
	struct berval	**bvals;
	int		i, hint;
	char		*tmp;
	const char	*s;

	/* Get the entry that is about to be added. */
	if ( slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e ) != 0 ) {
		slapi_log_err(SLAPI_LOG_PLUGIN,
		    "testpreop_add", "Could not get entry\n" );
		return( -1 );
	}

	/* Prepend the name "BOB" to the value of the cn attribute
	   in the entry. */
	if ( slapi_entry_attr_find( e, "cn", &a ) == 0 ) {
		for ( hint = slapi_attr_first_value( a, &v ); hint != -1;
				hint = slapi_attr_next_value( a, hint, &v )) {
			s = slapi_value_get_string( v );
			tmp = (char *) malloc( 5 + strlen( s ));
			strcpy( tmp, "BOB " );
			strcat( tmp + 4, s );
			slapi_value_set_string( v, tmp );
			free( tmp );
		}
	}

	return( 0 );	/* allow the operation to continue */
}
コード例 #4
0
ファイル: valueset.c プロジェクト: ohamada/389ds
/*
 * The string is passed in by value.
 */
void
valueset_add_string(Slapi_ValueSet *vs, const char *s, CSNType t, const CSN *csn)
{
	Slapi_Value v;
	value_init(&v,NULL,t,csn);
	slapi_value_set_string(&v,s);
    valuearray_add_value(&vs->va,&v);
	value_done(&v);
}
コード例 #5
0
ファイル: valueset.c プロジェクト: ohamada/389ds
void
valueset_remove_string(const Slapi_Attr *a, Slapi_ValueSet *vs, const char *s)
{
	Slapi_Value v;
	Slapi_Value *removed;
	value_init(&v,NULL,CSN_TYPE_NONE,NULL);
	slapi_value_set_string(&v,s);
	removed = valuearray_remove_value(a, vs->va, &v);
	if(removed) {
		slapi_value_free(&removed);
	}
	value_done(&v);
}
コード例 #6
0
ファイル: urp.c プロジェクト: ohamada/389ds
/*
 * Return 0 for OK,
 *       -1 for Ignore or Error depending on SLAPI_RESULT_CODE,
 *       >0 for action code
 * Action Code Bit 0: Fetch existing entry.
 * Action Code Bit 1: Fetch parent entry.
 * The function is called as a be pre-op on consumers.
 */
int 
urp_add_operation( Slapi_PBlock *pb )
{
	Slapi_Entry	*existing_uniqueid_entry;
	Slapi_Entry	*existing_dn_entry;
	Slapi_Entry	*addentry;
	const char *adduniqueid;
	CSN *opcsn;
	const char *basedn;
	char sessionid[REPL_SESSION_ID_SIZE];
	int r;
	int op_result= 0;
	int rc= 0; /* OK */
	Slapi_DN *sdn = NULL;

	if ( slapi_op_abandoned(pb) )
	{
		return rc;
	}

	get_repl_session_id (pb, sessionid, &opcsn);
	slapi_pblock_get( pb, SLAPI_ADD_EXISTING_UNIQUEID_ENTRY, &existing_uniqueid_entry );
	if (existing_uniqueid_entry!=NULL)
	{
		/* 
		 * An entry with this uniqueid already exists.
		 * - It could be a replay of the same Add, or
		 * - It could be a UUID generation collision, or
		 */
		/* 
		 * This operation won't be replayed.  That is, this CSN won't update
		 * the max csn in RUV. The CSN is left uncommitted in RUV unless an
		 * error is set to op_result.  Just to get rid of this CSN from RUV,
		 * setting an error to op_result
		 */
		/* op_result = LDAP_SUCCESS; */
		slapi_log_error(slapi_log_urp, sessionid,
		          "urp_add (%s): an entry with this uniqueid already exists.\n",
		          slapi_entry_get_dn_const(existing_uniqueid_entry));
		op_result= LDAP_UNWILLING_TO_PERFORM;
		slapi_pblock_set(pb, SLAPI_RESULT_CODE, &op_result);
		rc = SLAPI_PLUGIN_NOOP; /* Ignore this Operation */
		PROFILE_POINT; /* Add Conflict; UniqueID Exists;  Ignore */
		goto bailout;
	}

	slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &addentry );
	slapi_pblock_get( pb, SLAPI_ADD_EXISTING_DN_ENTRY, &existing_dn_entry );
	if (existing_dn_entry==NULL) /* The target DN does not exist */
	{
		/* Check for parent entry... this could be an orphan. */
		Slapi_Entry *parententry;
		slapi_pblock_get( pb, SLAPI_ADD_PARENT_ENTRY, &parententry );
		rc = urp_add_resolve_parententry (pb, sessionid, addentry, parententry, opcsn);
		PROFILE_POINT; /* Add Entry */
		goto bailout;
	}

	/*
	 * Naming conflict: an entry with the target DN already exists.
	 * Compare the DistinguishedNameCSN of the existing entry
	 * and the OperationCSN. The smaller CSN wins. The loser changes
	 * its RDN to uniqueid+baserdn, and adds operational attribute
	 * ATTR_NSDS5_REPLCONFLIC.
	 */
	basedn = slapi_entry_get_ndn (addentry);
	adduniqueid = slapi_entry_get_uniqueid (addentry);
	r = csn_compare (entry_get_dncsn(existing_dn_entry), opcsn);
	if (r<0)
	{
		/* Entry to be added is a loser */
		char *newdn= get_dn_plus_uniqueid (sessionid, basedn, adduniqueid);
		if(newdn==NULL)
		{
			op_result= LDAP_OPERATIONS_ERROR;
			slapi_pblock_set(pb, SLAPI_RESULT_CODE, &op_result);
			rc = SLAPI_PLUGIN_NOOP; /* Abort this Operation */
			slapi_log_error(slapi_log_urp, sessionid,
			      "urp_add (%s): Add conflict; Unique ID (%s) already in RDN\n",
			      basedn, adduniqueid);
			PROFILE_POINT; /* Add Conflict; Entry Exists; Unique ID already in RDN - Abort this update. */
		}
		else
		{
			/* Add the nsds5ReplConflict attribute in the mods */
			Slapi_Attr *attr = NULL;
			Slapi_Value **vals = NULL;
			Slapi_RDN *rdn;
			char buf[BUFSIZ];

			PR_snprintf(buf, BUFSIZ, "%s %s", REASON_ANNOTATE_DN, basedn);
			if (slapi_entry_attr_find (addentry, ATTR_NSDS5_REPLCONFLICT, &attr) == 0)
			{
				/* ATTR_NSDS5_REPLCONFLICT exists */
				slapi_log_error(SLAPI_LOG_FATAL, sessionid,
				          "urp_add: New entry has nsds5ReplConflict already\n");
				vals = attr_get_present_values (attr); /* this returns a pointer to the contents */
			}
			if ( vals == NULL || *vals == NULL )
			{
				/* Add new attribute */
				slapi_entry_add_string (addentry, ATTR_NSDS5_REPLCONFLICT, buf);
			}
			else
			{
				/*
				 * Replace old attribute. We don't worry about the index
				 * change here since the entry is yet to be added.
				 */
				slapi_value_set_string (*vals, buf);
			}
			/* slapi_pblock_get(pb, SLAPI_ADD_TARGET, &dn); */
			slapi_pblock_get(pb, SLAPI_ADD_TARGET_SDN, &sdn);
			slapi_sdn_free(&sdn);

			slapi_entry_set_normdn(addentry, newdn); /* dn: passin */

			sdn = slapi_sdn_dup(slapi_entry_get_sdn_const(addentry));
			slapi_pblock_set(pb, SLAPI_ADD_TARGET_SDN, sdn);

			rdn = slapi_rdn_new_sdn ( slapi_entry_get_sdn_const(addentry) );
			slapi_log_error (slapi_log_urp, sessionid,
			                 "urp_add: Naming conflict ADD. Add %s instead\n",
			                 slapi_rdn_get_rdn(rdn));
			slapi_rdn_free(&rdn);

			rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY);
			PROFILE_POINT; /* Add Conflict; Entry Exists; Rename Operation Entry */
		}
	}
	else if(r>0)
	{
		/* Existing entry is a loser */
		if (!urp_annotate_dn(sessionid, existing_dn_entry, opcsn, "ADD"))
		{
			op_result= LDAP_OPERATIONS_ERROR;
			slapi_pblock_set(pb, SLAPI_RESULT_CODE, &op_result);
			slapi_log_error(slapi_log_urp, sessionid,
			                "urp_add (%s): Entry to be added is a loser; "
			                "urp_annotate_dn failed.\n", basedn);
			rc = SLAPI_PLUGIN_NOOP; /* Ignore this Operation */
		}
		else
		{
			/* The backend add code should now search for the existing entry again. */
			rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY);
			rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_PARENT_ENTRY);
		}
		PROFILE_POINT; /* Add Conflict; Entry Exists; Rename Existing Entry */
	}
	else /* r==0 */
	{
		/* The CSN of the Operation and the Entry DN are the same.
		 * This could only happen if:
		 * a) There are two replicas with the same ReplicaID.
		 * b) We've seen the Operation before.
		 * Let's go with (b) and ignore the little bastard.
		 */
		/* 
		 * This operation won't be replayed.  That is, this CSN won't update
		 * the max csn in RUV. The CSN is left uncommitted in RUV unless an
		 * error is set to op_result.  Just to get rid of this CSN from RUV,
		 * setting an error to op_result
		 */
		/* op_result = LDAP_SUCCESS; */
		slapi_log_error(slapi_log_urp, sessionid,
		"urp_add (%s): The CSN of the Operation and the Entry DN are the same.",
		slapi_entry_get_dn_const(existing_dn_entry));
		op_result= LDAP_UNWILLING_TO_PERFORM;
		slapi_pblock_set(pb, SLAPI_RESULT_CODE, &op_result);
		rc = SLAPI_PLUGIN_NOOP; /* Ignore this Operation */
		PROFILE_POINT; /* Add Conflict; Entry Exists; Same CSN */
	}

bailout:
	return rc;
}