On Thu, 2018-03-08 at 14:32 -0500, Harvey, Robert wrote:
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.
Hi there.
As a general development rule, I would strongly advise you enable the
ASAN build functions, as this will help you find data corruptions and
crashes *at the source* rather then when they flow through the
application.
Another general question is "what do you want to achieve" with your
plugin? What's the purpose of it?
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
Try using an enum rather than #defines so that the complier type
checker can assist you.
static void *plugin_id = NULL;
#include "slapi-private.h"
You probably want slapi-plugin.h unless you have something you NEED
from private because this could change (we don't make api guarantees
about it).
#include <plstr.h>
Try to avoid the NSPR str functions as they are slower than the glibc
counterparts, and we want to move away from nspr overtime.
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};
Try and avoid this syntax, using instead
char *dn = NULL;
char *attrs[2] = {SLAPI_USERPWD_ATTR, NULL};
const char *mydn;
int method, rc = LDAP_SUCCESS;
Try to use int32_t rather than int because int is an undefined size.
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);
Well, you aren't freeing &e so there could be some garbage leftover but
I doubt it.
I can not obviously see the crash, so I think I need to see a backtrace
or an ASAN output to really assist.
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);
}
_______________________________________________
389-users mailing list -- 389-users(a)lists.fedoraproject.org
To unsubscribe send an email to 389-users-leave(a)lists.fedoraproject.o
rg
--
Thanks,
William Brown