An example of DN partitioning function
A sample DN partition program that gets the
rdn "cn=ck" from
the dn "cn=ck,ou=India,o=sample" regardless
of what the base or suffix is, and generates a partition number that
is based on the rdn value, in this case it is "ck"#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <slapi-plugin.h>
#ifdef __cplusplus
extern "C" {
#endif
int MyDNInit(Slapi_PBlock *pb);
#ifdef __cplusplus
}
#endif
int get_value_from_dn_fn( Slapi_PBlock *pb );
static char * get_hash_rdn( const char * dn, const char * base )
{
char * rdn = NULL;
size_t rdnLen = 0;
size_t dnLen = 0;
size_t baseLen = 0;
size_t startNdx = 0;
size_t endNdx = 0;
if ((dn == NULL) || (base == NULL))
return NULL;
dnLen = strlen( dn );
baseLen = strlen( base );
/* If the base is longer than the dn, there's no rdn */
if (baseLen > dnLen)
return NULL;
/* If the dn and base are the same, there's no rdn */
if ((dnLen == baseLen) && (strcmp( dn, base ) == 0))
return NULL;
/* Check if the dn is under the base */
if ((dn[dnLen - baseLen - 1] != ',') ||
(strcmp([&dn[dnLen - baseLen], base) != 0))
return NULL;
/* Find the next previous comma */
endNdx = dnLen - baseLen - 2;
for (startNdx = endNdx; startNdx > 0; startNdx--)
{
if (dn[startNdx] == ',')
{
startNdx++;
break;
}
}
rdnLen = endNdx - startNdx + 1;
rdn = (char *) calloc( 1, rdnLen + 1 );
memcpy( rdn, &dn[startNdx], rdnLen );
return rdn;
}
/* The function takes the RDN as input and generates the Partition number. */
/* If you add an entry with RDN 'cn=wrong' then it generates wrong partition number.
This will help to check if client utility gives
Operation Error for wrong partition number.
*/
int ck_new_get_hash_value( const char * str, int numPartitions )
{
char temp[100];
// static int cnt = 0;
char *sub_string;
unsigned int sum = 0;
int len, partitionNum,i=0;
sub_string = strchr (str, '=');
sub_string++;
strcpy(temp , sub_string);
/* Remove the comment for code below if you want to check the Server
behavior for wrong partition number generation at Start up.
*/
/* if ( strcasecmp ( "ibmpolicies",temp ) == 0 && cnt == 1)
{
return (numPartitions + 5) ;
} */
if ( strcasecmp ( "WRONG",temp ) == 0 )
{
return ( numPartitions + 5 ) ;
}
else
{
len = strlen( temp );
for(i = 0; i < len; str++, i++)
{
sum += temp[i] ;
}
partitionNum = ( (sum * len ) % numPartitions ) + 1 ;
return ( partitionNum );
}
}
// Function registered for generating Partition Number
int get_value_from_dn_fn( Slapi_PBlock *pb )
{
int rc = 0;
char *dn = NULL;
char *base = NULL;
int numPartitions = 0;
char * rdn = NULL;
int value = 0;
SLAPI_LDAPDN *ldapDn ;
Slapi_ldapRDN **ret_rdn = NULL;
// Get the parameters from PBlock
if ( (rc = slapi_pblock_get( (Slapi_PBlock *)pb, SLAPI_TARGET_DN,
(void *)&dn ) != 0 ) || (rc = slapi_pblock_get( (Slapi_PBlock *)pb,
SLAPI_PARTITION_BASE, (void *) &base ) != 0 ) || (rc =
slapi_pblock_get( (Slapi_PBlock *)pb, SLAPI_NUMBER_OF_PARTITIONS,
(void *) &numPartitions ) != 0 ) )
{
fprintf( stderr, "Cannot get the PBlock values!\n" );
return -1;
}
if ( (dn == NULL) || (base == NULL) || (numPartitions <= 0) )
{
fprintf( stderr,"Wrong values set in PBlock" );
return -1;
}
/* If the DN and base are the same, it hashes 1 */
if ( strcasecmp( dn, base ) == 0 )
{
fprintf( stderr, "Since the Base and DN are same set the
SLAPI_PARTITION_NUMBER to 1\n");
if ( (rc = slapi_pblock_set( (Slapi_PBlock *)pb,
SLAPI_PARTITION_NUMBER, (void *)1 ) ) != 0 )
{
fprintf( stderr, "Was not able to set value in PBlock!\n" );
return -1;
}
else
{
return 0;
}
}
// Get the Partition number based on the leftmost rdn value
rdn = get_hash_rdn( dn, base );
value = ck_new_get_hash_value( rdn , numPartitions );
fprintf(stderr,"\n\n*** Partition Value is : %d",value );
if ( (rc = slapi_pblock_set( (Slapi_PBlock *)pb,
SLAPI_PARTITION_NUMBER, (void *)value ) ) != 0 )
{
fprintf( stderr, "Failed to set value in PBlock!\n" );
free( rdn );
return -1;
}
slapi_dn_free_ldapdn(&ldapDn);
slapi_dn_free_rdn(ret_rdn);
free( rdn );
return 0;
}
// My Initialization Function
int MyDNInit( Slapi_PBlock * pb )
{
if ( slapi_pblock_set( pb, SLAPI_PLUGIN_PROXY_DN_PARTITION_FN,
( void * ) get_value_from_dn_fn ) != 0 )
{
fprintf(stderr,"Cannot register Function in PBlock \n");
return ( -1 );
}
return ( 0 );
}