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 );
}