/** BEGIN COPYRIGHT BLOCK
 * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 *
 * License: GPL (version 3 or any later version).
 * See LICENSE for details.
 * END COPYRIGHT BLOCK **/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/************************************************************

 testentry.c

 This source file provides examples of entry store and
 entry fetch plug-in functions.  These plug-in functions are
 called by the server before writing an entry to disk and
 after reading an entry from disk.

 Entry store and entry fetch plug-in functions are passed
 the string representation (in LDIF -- LDAP Data Interchange
 Format) of the entry.

 In this example, the entry store function performs a bitwise
 exclusive-OR operation on each character in the entry
 against the value 0xaa (10101010).  The entry fetch
 function performs this again to revert each character
 back to its initial value.

 NOTE: The Directory Server caches recently added and retrieved
 entries in memory.  The entry fetch plug-in function is called
 only when reading the entry from the disk, *not* when reading
 the entry from the cache.

 For example, if you add an entry and search for it, you will
 not see a message in the server error log indicating that
 the entry fetch plug-in function was called. In the process
 of adding the entry to the directory, the server also added
 the entry to the cache; the server then reads the entry from
 the cache instead of from the disk and does not need to call
 the entry fetch plug-in function.

 You can flush the cache by shutting down the server.

 To test this plug-in function, stop the server, edit the dse.ldif file
 (in the <server_root>/slapd-<server_id>/config directory)
 and add the following lines before restarting the server :

dn: cn=Test entry,cn=plugins,cn=config
objectClass: top
objectClass: nsSlapdPlugin
objectClass: extensibleObject
cn: Test entry
nsslapd-pluginPath: <server_root>/plugins/slapd/slapi/examples/libtest-plugin.so
nsslapd-pluginInitfunc: testentry_init
nsslapd-pluginType: ldbmentryfetchstore
nsslapd-pluginEnabled: on
nsslapd-pluginId: test-entry

 ************************************************************/

#include <stdio.h>
#include <string.h>
#include "slapi-plugin.h"

Slapi_PluginDesc entrypdesc = {"test-entry", VENDOR, DS_PACKAGE_VERSION,
                               "sample entry modification plugin"};

/* Entry store plug-in function */
int
testentry_scramble(char **entry, unsigned long *len)
{
    unsigned long i;

    /* Log an entry to the server's error log file whenever
       this function is called. */
    slapi_log_err(SLAPI_LOG_PLUGIN, "testentry_scramble",
                  "Entry data scrambled.\n");

    /* Perform a bitwise exclusive-OR operation on each
       character in the entry. */
    for (i = 0; i < *len - 1; i++) {
        (*entry)[i] ^= 0xaa;
    }

    return (0);
}

/* Entry fetch plug-in function */
int
testentry_unscramble(char **entry, unsigned long *len)
{
    unsigned long i;

    /* Some entries will not be scrambled, so check if the entry is
       scrambled before attempting to unscramble the entry. */
    if (!strncmp(*entry, "dn:", 3)) {
        return (0);
    }

    /* Perform a bitwise exclusive-OR operation on each
       character in the entry. */
    for (i = 0; i < *len - 1; i++) {
        (*entry)[i] ^= 0xaa;
    }

    slapi_log_err(SLAPI_LOG_PLUGIN, "testentry_unscramble",
                  "Entry data unscrambled.\n");
    return (0);
}

int
testentry_init(Slapi_PBlock *pb)
{
    /* Register the store/fetch functions and specify
       the server plug-in version. */
    if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
                         SLAPI_PLUGIN_VERSION_01) != 0 ||
        slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
                         (void *)&entrypdesc) != 0 ||
        slapi_pblock_set(pb, SLAPI_PLUGIN_ENTRY_FETCH_FUNC,
                         (void *)testentry_unscramble) != 0 ||
        slapi_pblock_set(pb, SLAPI_PLUGIN_ENTRY_STORE_FUNC,
                         (void *)testentry_scramble) != 0) {

        slapi_log_err(SLAPI_LOG_PLUGIN, "testentry_init",
                      "Failed to set version and functions\n");
        return (-1);
    }

    return 0;
}
