I'm hoping that someone can help me find out why my pre-bind plugin clauses ns-slapd to crash when the slapi_search_internal_get_entry function is called. What I'm seeing is that after starting ns-slapd, the plugin will crash slapd consistently or it will work consistently. This is with the same plugin in place and with the same user. So after some restarts the plugin crashes the slapd and after other starts I can bind and unbind with the same account dozens of times successfully. 

 

This what I have installed:

[root@njbbldapp21 ~]# rpm -qa | grep 389
389-ds-base-libs-1.3.6.1-26.el7_4.x86_64
389-dsgw-1.1.11-5.el7.x86_64
389-console-1.1.18-1.el7.noarch
389-adminutil-1.1.21-2.el7.x86_64
389-admin-console-1.1.12-1.el7.noarch
389-ds-console-1.2.16-1.el7.noarch
389-ds-console-doc-1.2.16-1.el7.noarch
389-ds-1.2.2-6.el7.noarch
389-ds-base-1.3.6.1-26.el7_4.x86_64
389-ds-base-devel-1.3.6.1-26.el7_4.x86_64
389-admin-console-doc-1.1.12-1.el7.noarch
389-admin-1.1.46-1.el7.x86_64

Here's my Makefile:

CC = gcc
LD = ld

INCLUDE_FLAGS = -I /usr/lib64/dirsrv/plugins -I /opt/adminhome/aharvero/slap/389-ds-base-1.4.0.5/ldap/servers/slapd -I /usr/include/nspr4  -I /opt/adminhome/aharvero/slap/389-ds-base-1.4.0.5/ldap/include 

#CFLAGS = $(INCLUDE_FLAGS) -D_REENTRANT -fPIC -z defs -shared
CFLAGS = $(INCLUDE_FLAGS) -D_REENTRANT -fPIC -z defs -shared  -lsladpd -ltcmalloc -lldap_r -llber -lsasl2 -l svrcore -lssl3 -l nss3 -lkrb5 -l k5crypto -lcom_err -lpcre -lpthread -lsystemd -l plc4 -l plds4 -lc
#LDFLAGS = -G

LDFLAGS = -G -fPIC -z defs -shared -lc -l:libplc4.so -l:libslapd.so.0.1.0 -l:libldap_r-2.4.so.2 -l:liblber-2.4.so.2 -L /usr/lib64/dirsrv -L /lib64

OBJS =  mybind.o

all: libmybind-plugin.so


libmybind-plugin.so: $(OBJS)
    $(LD) $(LDFLAGS) -o $@ $(OBJS)

.c.o:
    $(CC) $(CFLAGS) -c $<

clean:
    -rm -f $(OBJS) libmybind-plugin.so


Here's the plugin:


$ cat mybind.c

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

/************************************************************
 mybind.c

 This source file provides an example of a pre-operation plug-in
 function that handles authentication.

 dn: cn=mybind,cn=plugins,cn=config
 objectClass: top
 objectClass: nsSlapdPlugin
 objectClass: extensibleObject
 cn: mybind
 nsslapd-pluginPath: libmybind-plugin
 nsslapd-pluginInitfunc: mybind_init
 nsslapd-pluginType: preoperation
 nsslapd-pluginEnabled: on
 nsslapd-plugin-depends-on-type: database
 nsslapd-pluginId: mybind

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

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

#define VENDOR "myco"
#define DS_PACKAGE_VERSION "1.1.1.1"
#define MYPLUGINID "mybind"

#define CALLBACK_OK 0
#define CALLBACK_ERR -1

static void *plugin_id = NULL;

#include "slapi-private.h"
#include <plstr.h>

static Slapi_PluginDesc bindpdesc = { MYPLUGINID, VENDOR, DS_PACKAGE_VERSION,
                                        "mybind control plugin" };

/* Pre-operation plug-in function */
int
test_bind(Slapi_PBlock *pb)
{
    char *dn , *attrs[2] = {SLAPI_USERPWD_ATTR, NULL};
    const char *mydn;
    int method, rc = LDAP_SUCCESS;
    struct berval *credentials;
    struct berval **pwvals;
    Slapi_DN *sdn = NULL;
    Slapi_Entry *e = NULL;
    Slapi_Attr *attr = NULL;

    Slapi_Value *sv_creds = NULL;

    /* Log a message to the server error log. */
    slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID ,
                  "Pre-operation bind function called.\n");
    /* Gets parameters available when processing an LDAP bind
       operation. */
    if (slapi_pblock_get(pb, SLAPI_BIND_TARGET, &dn) != 0 ||
        slapi_pblock_get(pb, SLAPI_BIND_METHOD, &method) != 0 ||
         slapi_pblock_get(pb, SLAPI_BIND_CREDENTIALS, &credentials) != 0) {
          slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                      "Could not get parameters for bind operation\n");
          slapi_send_ldap_result(pb, LDAP_OPERATIONS_ERROR,
                               NULL, NULL, 0, NULL);
          return (1);
      }

    /* The plugin wouldn't get called for anonymous binds but let's check */
    if (dn == NULL) {
       return 0;
    }

    slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                      "Authenticated: %s\n", dn);
    slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                      "Method: %d\n", method);
    sv_creds = slapi_value_new_berval(credentials);  /* wrap in Slapi_Value* */

     slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                      "Method: : LDAP_AUTH_SIMPLE\n");
   

        sdn = slapi_sdn_new_dn_byref(dn);

        slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID, "before search  \n");

/* Half the time this will crash slapd !!!!! */

        rc = slapi_search_internal_get_entry(sdn, attrs, &e, plugin_id);

        slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID, "after search \n");

        if ( sdn != NULL )
          {
          slapi_sdn_free(&sdn);
          }

      if (rc != LDAP_SUCCESS) {
        slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                          "Could not find entry %s (error %d)\n",
                          dn, rc);
        return 0;
        }
     slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                         "Found entry %s (error %d)\n",
                          dn, rc);
       
return 0;
    return (1);
}

/* Pre-operation plug-in function */
int
test_search(Slapi_PBlock *pb)
{
    char *reqdn;

    /* Log a message to the server error log. */
    slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                  "Pre-operation search function called.\n");

    /* Get requestor of search operation.  This is not critical
       to performing the search (this plug-in just serves as
       confirmation that the bind plug-in works), so return 0
       if this fails. */
    if (slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &reqdn) != 0) {

        slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                      "Could not get requestor parameter for search operation\n");
        return (0);
    }

    /* Indicate who is requesting the search */
    if (reqdn != NULL && *reqdn != '\0') {
        slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                      "Search requested by %s\n", reqdn);
    } else {
        slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                      "Search requested by anonymous client\n");
    }
    return (0);
}

/* Initialization function */
int
mybind_init(Slapi_PBlock *pb)
{
    slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID , "mybind running mybind init function.\n");

    int enabled;

    slapi_pblock_get(pb, SLAPI_PLUGIN_ENABLED, &enabled);

    if (slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &plugin_id) != 0) {
        slapi_log_error(SLAPI_LOG_ERR, MYPLUGINID ,
                      "mybind_init - Failed to get plugin identity\n");
        return (CALLBACK_ERR);
    }

    PR_ASSERT(plugin_id);

    slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                      "init function Plugin ID: %s\n", plugin_id);

    if ( slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
                         SLAPI_PLUGIN_VERSION_03) != 0 ||
       slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
                         (void *)&bindpdesc) != 0 ||
       slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_BIND_FN,
                         (void *)test_bind) != 0  )
     {
     slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                      "Failed to set version and functions in the init function\n");

     return (CALLBACK_ERR);
     }
     slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID,
                      "Registration set was good in the init function\n");

    slapi_log_error(SLAPI_LOG_PLUGIN, MYPLUGINID , "end of mybind init function.\n");

    return (0);
}