Index: openldap-2.4.42+dfsg/configure.in
===================================================================
--- openldap-2.4.42+dfsg.orig/configure.in
+++ openldap-2.4.42+dfsg/configure.in
@@ -337,6 +337,7 @@ OL_ARG_ENABLE(sql,[    --enable-sql	  en
 dnl ----------------------------------------------------------------
 dnl SLAPD Overlay Options
 Overlays="accesslog \
+	aldlog \
 	auditlog \
 	collect \
 	constraint \
@@ -364,6 +365,8 @@ OL_ARG_ENABLE(overlays,[    --enable-ove
 	--, [no yes mod])dnl
 OL_ARG_ENABLE(accesslog,[    --enable-accesslog	  In-Directory Access Logging overlay],
 	no, [no yes mod], ol_enable_overlays)
+OL_ARG_ENABLE(aldlog,[    --enable-aldlog	  ALD Logging overlay],
+	no, [no yes mod], ol_enable_overlays)
 OL_ARG_ENABLE(auditlog,[    --enable-auditlog	  Audit Logging overlay],
 	no, [no yes mod], ol_enable_overlays)
 OL_ARG_ENABLE(collect,[    --enable-collect	  Collect overlay],
@@ -550,6 +553,7 @@ BUILD_SOCK=no
 BUILD_SQL=no
 
 BUILD_ACCESSLOG=no
+BUILD_ALDLOG=no
 BUILD_AUDITLOG=no
 BUILD_CONSTRAINT=no
 BUILD_DDS=no
@@ -2830,6 +2834,18 @@ if test "$ol_enable_accesslog" != no ; t
 	AC_DEFINE_UNQUOTED(SLAPD_OVER_ACCESSLOG,$MFLAG,[define for In-Directory Access Logging overlay])
 fi
 
+if test "$ol_enable_aldlog" != no ; then
+	BUILD_ALDLOG=$ol_enable_aldlog
+	if test "$ol_enable_aldlog" = mod ; then
+		MFLAG=SLAPD_MOD_DYNAMIC
+		SLAPD_DYNAMIC_OVERLAYS="$SLAPD_DYNAMIC_OVERLAYS aldlog.la"
+	else
+		MFLAG=SLAPD_MOD_STATIC
+		SLAPD_STATIC_OVERLAYS="$SLAPD_STATIC_OVERLAYS aldlog.o"
+	fi
+	AC_DEFINE_UNQUOTED(SLAPD_OVER_ALDLOG,$MFLAG,[define for ALD Logging overlay])
+fi
+
 if test "$ol_enable_auditlog" != no ; then
 	BUILD_AUDITLOG=$ol_enable_auditlog
 	if test "$ol_enable_auditlog" = mod ; then
@@ -3115,6 +3131,7 @@ dnl backends
   AC_SUBST(BUILD_SQL)
 dnl overlays
   AC_SUBST(BUILD_ACCESSLOG)
+  AC_SUBST(BUILD_ALDLOG)
   AC_SUBST(BUILD_AUDITLOG)
   AC_SUBST(BUILD_COLLECT)
   AC_SUBST(BUILD_CONSTRAINT)
Index: openldap-2.4.42+dfsg/servers/slapd/overlays/Makefile.in
===================================================================
--- openldap-2.4.42+dfsg.orig/servers/slapd/overlays/Makefile.in
+++ openldap-2.4.42+dfsg/servers/slapd/overlays/Makefile.in
@@ -15,6 +15,7 @@
 
 SRCS = overlays.c \
 	accesslog.c \
+	aldlog.c \
 	auditlog.c \
 	constraint.c \
 	dds.c \
@@ -65,6 +66,9 @@ dynamic: $(PROGRAMS)
 accesslog.la : accesslog.lo
 	$(LTLINK_MOD) -module -o $@ accesslog.lo version.lo $(LINK_LIBS)
 
+aldlog.la : aldlog.lo
+	$(LTLINK_MOD) -module -o $@ aldlog.lo version.lo $(LINK_LIBS)
+
 auditlog.la : auditlog.lo
 	$(LTLINK_MOD) -module -o $@ auditlog.lo version.lo $(LINK_LIBS)
 
Index: openldap-2.4.42+dfsg/servers/slapd/overlays/aldlog.c
===================================================================
--- /dev/null
+++ openldap-2.4.42+dfsg/servers/slapd/overlays/aldlog.c
@@ -0,0 +1,629 @@
+/* Rusbitech aldlog.c for ALD
+ *
+ * based on audit.c
+ *
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/timeb.h>
+
+#include <ac/string.h>
+#include <ac/ctype.h>
+
+#include "slap.h"
+#include "config.h"
+#include "ldif.h"
+
+#define ALDroot "1.3.6.1.4.1.32702.1.1.1"
+#define ALDattributeType ALDroot ".1"
+#define ALDobjectClass ALDroot ".2"
+#define ALDSlapdExt ALDroot ".0"
+#define ALDSlapdExtType ALDSlapdExt ".1"
+#define ALDSlapdExtClass ALDSlapdExt ".2"
+
+typedef struct aldlog_template {
+	struct aldlog_template *at_next;
+	struct aldlog_template *at_prev;
+	char *at_name;
+	char *at_suffix;
+	unsigned long at_len;
+#define AT_MODE_NONE	0
+#define AT_MODE_SUCC	1
+#define AT_MODE_FAIL	2
+#define AT_MODE_ALL	(AT_MODE_SUCC | AT_MODE_FAIL);
+	int at_mode;
+} aldlog_template;
+
+typedef struct aldlog_data {
+	ldap_pvt_thread_mutex_t ad_mutex;
+	char *ad_logfile;
+	aldlog_template *ad_templates;
+} aldlog_data;
+
+#define ALDLogFileT ALDSlapdExtType ".1"
+#define ALDLogTplT ALDSlapdExtType ".2"
+
+enum {
+	AL_LOG = 1,
+	AL_TPL
+};
+
+static ConfigDriver al_cf_gen;
+
+static ConfigTable aldlogcfg[] = {
+	{ "aldlog", "filename", 2, 2, 0,
+	  ARG_MAGIC|AL_LOG, al_cf_gen,
+	  "( " ALDLogFileT " NAME 'olcALDLogFile' "
+	  "DESC 'Filename for aldlogging' "
+	  "SYNTAX OMsDirectoryString )", NULL, NULL },
+	{ "aldlogtpl", "name> <tpl> <mode", 4, 4, 0,
+	  ARG_MAGIC|AL_TPL, al_cf_gen,
+	  "( " ALDLogTplT " NAME 'olcALDLogTpl' "
+	  "DESC 'Audit template for aldlogging' "
+	  "EQUALITY caseIgnoreMatch "
+	  "SYNTAX OMsDirectoryString )", NULL, NULL },
+	{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
+};
+
+#define ALDLogConfigC ALDSlapdExtClass ".1"
+
+static ConfigOCs aldlogocs[] = {
+	{ "( " ALDLogConfigC " "
+	  "NAME 'olcALDLogConfig' "
+	  "DESC 'ALDLog configuration' "
+	  "SUP olcOverlayConfig "
+	  "MAY ( olcALDLogFile $ olcALDLogTpl ) )",
+	  Cft_Overlay, aldlogcfg },
+	{ NULL, 0, NULL }
+};
+
+
+void TRACE(char* tag, char* name, char* info)
+{
+  FILE *f = fopen("/tmp/_trace","a");
+  fprintf(f, "%s %s %s\n", tag, name, info);
+  fclose(f);
+}
+
+static void free_tpl(aldlog_template* tpl) {
+  if(tpl) {
+    ch_free(tpl->at_name);
+    ch_free(tpl->at_suffix);
+    ch_free(tpl);
+  }
+}
+
+static void free_templates(aldlog_data *ad) {
+//  TRACE("free_templates", "", "");
+  aldlog_template* tpl = ad->ad_templates;
+  aldlog_template* deltpl = NULL;
+  while(tpl) {
+    deltpl = tpl;
+    tpl = tpl->at_next;
+    free_tpl(deltpl);
+  }
+  ad->ad_templates = NULL;
+}
+
+static void del_tpl(aldlog_data *ad, int idx) {
+  aldlog_template* tpl = ad->ad_templates;
+
+  // find template by idx
+  int pos = 0;
+  while( (tpl != NULL) && (pos++ < idx) )
+    tpl = tpl->at_next;
+  if ( tpl ) {
+//    TRACE("del_tpl", tpl->at_name, "del");
+    if(tpl->at_next)
+      tpl->at_next->at_prev = tpl->at_prev;
+    if (tpl == ad->ad_templates)
+      ad->ad_templates = tpl->at_next;
+    else
+      tpl->at_prev->at_next = tpl->at_next;
+    free_tpl(tpl);
+  }
+}
+
+static int set_tpl(aldlog_data *ad, int argc, char *argv[]) {
+  aldlog_template* tpl = ad->ad_templates;
+  aldlog_template* pretpl = NULL;
+  char* _name = NULL;
+  char* _suffix = NULL;
+  char* _mode = NULL;
+  int imode = AT_MODE_ALL;
+//TRACE("set_tpl", argv[1], "parse");
+  // parse template
+  if (argc > 3) {
+    _name = argv[1];
+    _suffix = argv[2];
+    _mode = argv[3];
+    if (_mode[0] == 'f')
+      imode = AT_MODE_FAIL;
+    else if (_mode[0] == 's')
+      imode = AT_MODE_SUCC;
+    else if (_mode[0] == 'n')
+      imode = AT_MODE_NONE;
+  }
+
+  if(!_name || !_name[0] || !_suffix || !_suffix[0])
+    return 1;
+
+  // find template by name
+  while( tpl != NULL ) {
+    if (!strcmp(tpl->at_name, _name))
+      break;
+    pretpl = tpl;
+    tpl = tpl->at_next;
+  }
+
+  // if not found
+  if ( !tpl ) {
+//TRACE("set_tpl", argv[1], "create");
+    tpl = ch_calloc(1, sizeof(aldlog_template));
+    if ( pretpl )
+      pretpl->at_next = tpl;
+    else
+      ad->ad_templates = tpl;
+    tpl->at_prev = pretpl;
+    tpl->at_name = ch_strdup(_name);
+  }
+  else {
+//TRACE("set_tpl", argv[1], "update");
+    ch_free(tpl->at_suffix);
+  }
+
+  tpl->at_suffix = ch_strdup(_suffix);
+  tpl->at_len = strlen(_suffix);
+  tpl->at_mode = imode;
+
+  return 0;
+}
+
+/*
+* pattern matching - stolen from postgreSQL "LIKE"
+* result:
+* 1 - match
+* 0 - not match
+* -1 - error
+*/
+#define MATCH_TRUE  1
+#define MATCH_FALSE 0
+#define MATCH_ABORT (-1)
+static int match(char *t, int tlen, char *p, int plen)
+{
+#define NextByte(p, plen)	((p)++, (plen)--)
+
+	/* Fast path for match-everything pattern */
+	if (plen == 1 && *p == '*')
+		return MATCH_TRUE;
+
+	/*
+	 * In this loop, we advance by char when matching wildcards (and thus on
+	 * recursive entry to this function we are properly char-synced). On other
+	 * occasions it is safe to advance by byte, as the text and pattern will
+	 * be in lockstep. This allows us to perform all comparisons between the
+	 * text and pattern on a byte by byte basis, even for multi-byte
+	 * encodings.
+	 */
+	while (tlen > 0 && plen > 0) {
+		if (*p == '\\')	{
+			/* Next pattern byte must match literally, whatever it is */
+			NextByte(p, plen);
+			/* ... and there had better be one */
+			if (plen <= 0)
+				return MATCH_ABORT;
+			if (*p != *t)
+				return MATCH_FALSE;
+		}
+		else if (*p == '*')	{
+			char firstpat;
+
+			/*
+			 * % processing is essentially a search for a text position at
+			 * which the remainder of the text matches the remainder of the
+			 * pattern, using a recursive call to check each potential match.
+			 *
+			 * If there are wildcards immediately following the %, we can skip
+			 * over them first, using the idea that any sequence of N _'s and
+			 * one or more %'s is equivalent to N _'s and one % (ie, it will
+			 * match any sequence of at least N text characters).  In this way
+			 * we will always run the recursive search loop using a pattern
+			 * fragment that begins with a literal character-to-match, thereby
+			 * not recursing more than we have to.
+			 */
+			NextByte(p, plen);
+
+			while (plen > 0) {
+				if (*p == '*')
+					NextByte(p, plen);
+				else if (*p == '?')	{
+					/* If not enough text left to match the pattern, ABORT */
+					if (tlen <= 0)
+						return MATCH_ABORT;
+					NextByte(t, tlen);
+					NextByte(p, plen);
+				}
+				else
+					break;		/* Reached a non-wildcard pattern char */
+			}
+
+			/*
+			 * If we're at end of pattern, match: we have a trailing % which
+			 * matches any remaining text string.
+			 */
+			if (plen <= 0)
+				return MATCH_TRUE;
+
+			/*
+			 * Otherwise, scan for a text position at which we can match the
+			 * rest of the pattern.  The first remaining pattern char is known
+			 * to be a regular or escaped literal character, so we can compare
+			 * the first pattern byte to each text byte to avoid recursing
+			 * more than we have to.  This fact also guarantees that we don't
+			 * have to consider a match to the zero-length substring at the
+			 * end of the text.
+			 */
+			if (*p == '\\') {
+				if (plen < 2)
+					return MATCH_ABORT;
+				firstpat = p[1];
+			}
+			else
+				firstpat = *p;
+
+			while (tlen > 0) {
+				if (*t == firstpat) {
+					int	matched = match(t, tlen, p, plen);
+					if (matched != MATCH_FALSE)
+						return matched; /* TRUE or ABORT */
+				}
+
+				NextByte(t, tlen);
+			}
+
+			/*
+			 * End of text with no match, so no point in trying later places
+			 * to start matching this pattern.
+			 */
+			return MATCH_ABORT;
+		}
+		else if (*p == '?')	{
+			/* _ matches any single character, and we know there is one */
+			NextByte(t, tlen);
+			NextByte(p, plen);
+			continue;
+		}
+		else if (*p != *t) {
+			/* non-wildcard pattern char fails to match text char */
+			return MATCH_FALSE;
+		}
+
+		/*
+		 * Pattern and text match, so advance.
+		 */
+		NextByte(t, tlen);
+		NextByte(p, plen);
+	}
+
+	if (tlen > 0)
+		return MATCH_TRUE;		/* end of pattern, but not of text */
+
+	/*
+	 * End of text, but perhaps not of pattern.  Match iff the remaining
+	 * pattern can match a zero-length string, ie, it's zero or more %'s.
+	 */
+	while (plen > 0 && *p == '*')
+		NextByte(p, plen);
+	if (plen <= 0)
+		return MATCH_TRUE;
+
+	/*
+	 * End of text with no match, so no point in trying later places to start
+	 * matching this pattern.
+	 */
+	return MATCH_ABORT;
+}	/* MatchText() */
+
+static aldlog_template* findTpl(aldlog_data *ad, const char *dn) {
+  aldlog_template *tpl = ad->ad_templates;
+  char* dc = strstr(dn, ",dc=");
+  unsigned long len = 0;
+  if (dc)
+    len = dc-dn;
+  else
+    len = strlen(dn);
+  while( tpl != NULL ) {
+    if (len >= tpl->at_len)
+    {
+//      TRACE("findTpl", tpl->at_suffix, (char*)dn);
+      if(match((char*)dn, len, tpl->at_suffix, tpl->at_len) == MATCH_TRUE)
+        return tpl;
+    }
+    tpl = tpl->at_next;
+  }
+  return NULL;
+}
+
+static int attr_needed(aldlog_template* tpl, const char *attr) {
+  if(!attr)
+    return 0;
+  if(!strncmp(attr,"modifyTimestamp", sizeof("modifyTimestamp"))
+    || !strncmp(attr,"modifiersName", sizeof("modifiersName"))
+    || !strncmp(attr,"entryCSN", sizeof("entryCSN"))
+    || !strncmp(attr,"entryUUID", sizeof("entryUUID"))
+    || !strncmp(attr,"creatorsName", sizeof("creatorsName"))
+    || !strncmp(attr,"createTimestamp", sizeof("createTimestamp")))
+    return 0;
+  return 1;
+}
+
+static const char * put_val(const char *attr, const char *val) {
+  if(!attr)
+    return "";
+  if(!strncmp(attr,"jpegPhoto", sizeof("jpegPhoto")))
+    return "<BINARY DATA>";
+  return val;
+}
+
+static char* nameFromDN(const char *dn) {
+  static char buff[1024];
+  char *n, *v;
+  int len = 0;
+  if(!dn)
+    return "";
+  n = strchr(dn, '=');
+  if(!n)
+    return "";
+  ++n;
+  v = strchr(n, ',');
+  if(v)
+    len = v-n;
+  else
+    len = strlen(n);
+  strncpy(buff, n, len);
+  buff[len] = 0;
+  return buff;
+}
+
+static int aldlog_response(Operation *op, SlapReply *rs) {
+	slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+	aldlog_data *ad = on->on_bi.bi_private;
+	FILE *f;
+	Attribute *a;
+	Modifications *m;
+	struct berval *b, *who = NULL, peername;
+	char *what, *whatm;
+	int i;
+	int fc = 0;
+	struct timeb tmb;
+	struct tm* ptm;
+	aldlog_template* tpl = NULL;
+
+	if ( !ad->ad_logfile ) return SLAP_CB_CONTINUE;
+
+//    TRACE("aldlog_response", ad->ad_logfile, op->o_req_dn.bv_val);
+        tpl = findTpl(ad, op->o_req_dn.bv_val);
+	if ( !tpl ) return SLAP_CB_CONTINUE;
+
+//    TRACE("template found!", ad->ad_logfile, tpl->at_name);
+/*
+** add or modify: use modifiersName if present
+**
+*/
+	switch(op->o_tag) {
+		case LDAP_REQ_MODRDN:	what = "modrdn";	break;
+		case LDAP_REQ_DELETE:	what = "delete";	break;
+		case LDAP_REQ_ADD:
+			what = "add";
+			for(a = op->ora_e->e_attrs; a; a = a->a_next)
+				if( a->a_desc == slap_schema.si_ad_modifiersName ) {
+					who = &a->a_vals[0];
+					break;
+				}
+			break;
+		case LDAP_REQ_MODIFY:
+			what = "modify";
+			for(m = op->orm_modlist; m; m = m->sml_next)
+				if( m->sml_desc == slap_schema.si_ad_modifiersName &&
+					( m->sml_op == LDAP_MOD_ADD ||
+					m->sml_op == LDAP_MOD_REPLACE )) {
+					who = &m->sml_values[0];
+					break;
+				}
+			break;
+		default:
+			return SLAP_CB_CONTINUE;
+	}
+
+//	suffix = op->o_bd->be_suffix[0].bv_len ? op->o_bd->be_suffix[0].bv_val :
+//		"global";
+
+/*
+** note: this means requestor's dn when modifiersName is null
+*/
+	if ( !who )
+		who = &op->o_dn;
+
+	peername = op->o_conn->c_peer_name;
+	ldap_pvt_thread_mutex_lock(&ad->ad_mutex);
+	if((f = fopen(ad->ad_logfile, "a")) == NULL) {
+//		TRACE("aldlog_response", "log open error", ad->ad_logfile);
+		ldap_pvt_thread_mutex_unlock(&ad->ad_mutex);
+		return SLAP_CB_CONTINUE;
+	}
+
+	ftime(&tmb);
+	ptm = localtime(&(tmb.time));
+
+	// fix time
+	fprintf(f, "'%2.2d.%2.2d.%4.4d %2.2d:%2.2d:%2.2d.%3.3d' ", ptm->tm_mday, ptm->tm_mon+1,
+		ptm->tm_year+1900, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, tmb.millitm);
+
+	fprintf(f, "[%c] <%s, %s> %s %s '%s'(", !rs->sr_err ? 's': 'f',
+		peername.bv_val ? peername.bv_val: "unknown", who ? nameFromDN(who->bv_val) : "unknown",
+		what, tpl->at_name, op->o_req_dn.bv_val);
+
+	switch(op->o_tag) {
+	  case LDAP_REQ_ADD:
+		for(a = op->ora_e->e_attrs; a; a = a->a_next)
+		  if(((b = a->a_vals) != NULL)
+		    && attr_needed(tpl, a->a_desc->ad_cname.bv_val))
+			for(i = 0; b[i].bv_val; i++)
+			  fprintf(f, "%s%s='%s'", (!fc++? "": ","), a->a_desc->ad_cname.bv_val,
+				  put_val(a->a_desc->ad_cname.bv_val, b[i].bv_val));
+		break;
+
+	  case LDAP_REQ_MODIFY:
+		for(m = op->orm_modlist; m; m = m->sml_next) {
+			if(((b = m->sml_values) != NULL)
+			  && attr_needed(tpl,m->sml_desc->ad_cname.bv_val)) {
+			  switch(m->sml_op & LDAP_MOD_OP) {
+				  case LDAP_MOD_ADD:	 whatm = "+";		break;
+				  case LDAP_MOD_REPLACE:	 whatm = "=";	break;
+				  case LDAP_MOD_DELETE:	 whatm = "-";	break;
+				  case LDAP_MOD_INCREMENT: whatm = "++";	break;
+				  default: whatm = "?";
+			  }
+			  for(i = 0; b[i].bv_val; i++)
+			    fprintf(f, "%s%s%s='%s'", (!fc++? "": ","), whatm, m->sml_desc->ad_cname.bv_val,
+				    put_val(m->sml_desc->ad_cname.bv_val, b[i].bv_val));
+			}
+		}
+		break;
+
+	  case LDAP_REQ_MODRDN:
+		fprintf(f, "rename to %s", op->orr_newrdn.bv_val);
+		break;
+
+	  case LDAP_REQ_DELETE:
+		break;
+	}
+
+	fprintf(f, ")\n");
+	fclose(f);
+
+	ldap_pvt_thread_mutex_unlock(&ad->ad_mutex);
+	return SLAP_CB_CONTINUE;
+}
+
+static slap_overinst aldlog;
+
+static int
+aldlog_db_init(
+	BackendDB *be,
+	ConfigReply *cr
+)
+{
+	slap_overinst *on = (slap_overinst *)be->bd_info;
+	aldlog_data *ad = ch_calloc(1, sizeof(aldlog_data));
+
+	on->on_bi.bi_private = ad;
+	ldap_pvt_thread_mutex_init( &ad->ad_mutex );
+	return 0;
+}
+
+static int
+aldlog_db_close(
+	BackendDB *be,
+	ConfigReply *cr
+)
+{
+	slap_overinst *on = (slap_overinst *)be->bd_info;
+	aldlog_data *ad = on->on_bi.bi_private;
+	free_templates(ad);
+	free( ad->ad_logfile );
+	ad->ad_logfile = NULL;
+
+	return 0;
+}
+
+static int
+aldlog_db_destroy(
+	BackendDB *be,
+	ConfigReply *cr
+)
+{
+	slap_overinst *on = (slap_overinst *)be->bd_info;
+	aldlog_data *ad = on->on_bi.bi_private;
+	free_templates(ad);
+	if(ad->ad_logfile)
+	  ch_free(ad->ad_logfile);
+	ldap_pvt_thread_mutex_destroy( &ad->ad_mutex );
+	free( ad );
+	return 0;
+}
+
+int aldlog_initialize() {
+	int rc;
+
+	aldlog.on_bi.bi_type = "aldlog";
+	aldlog.on_bi.bi_db_init = aldlog_db_init;
+	aldlog.on_bi.bi_db_close = aldlog_db_close;
+	aldlog.on_bi.bi_db_destroy = aldlog_db_destroy;
+	aldlog.on_response = aldlog_response;
+
+	aldlog.on_bi.bi_cf_ocs = aldlogocs;
+	rc = config_register_schema( aldlogcfg, aldlogocs );
+	if ( rc ) return rc;
+
+	return overlay_register(&aldlog);
+}
+
+int
+init_module( int argc, char *argv[] )
+{
+	return aldlog_initialize();
+}
+
+static int
+al_cf_gen(ConfigArgs *c)
+{
+	slap_overinst *on = (slap_overinst *)c->bi;
+	aldlog_data *ad = on->on_bi.bi_private;
+	int rc = 0;
+	switch( c->op ) {
+	case SLAP_CONFIG_EMIT:
+		switch( c->type ) {
+		case AL_LOG:
+//TRACE("	SLAP_CONFIG_EMIT", "AL_LOG ", c->argv[1]? c->argv[1]: "NULL");
+			break;
+		case AL_TPL:
+//TRACE("	SLAP_CONFIG_EMIT", "AL_TPL ", c->argv[1]? c->argv[1]: "NULL");
+			break;
+		}
+		break;
+	case LDAP_MOD_DELETE:
+		switch( c->type ) {
+		case AL_LOG:
+		case AL_TPL:
+//TRACE("	LDAP_MOD_DELETE",  c->argv[0], "");
+			del_tpl(ad, c->valx);
+			break;
+		}
+		break;
+	default:
+		switch( c->type ) {
+		case AL_LOG:
+			if(ad->ad_logfile)
+			  ch_free(ad->ad_logfile);
+			ad->ad_logfile = ch_strdup(c->argv[1]);
+			break;
+		case AL_TPL:
+//TRACE("	SLAP_CONFIG_DEF", "AL_TPL ", c->argv[1]? c->argv[1]: "NULL");
+			if (set_tpl(ad, c->argc, c->argv)) {
+			  snprintf( c->cr_msg, sizeof( c->cr_msg ),
+					"aldlog: invalid template \"%s\"", c->argv[1]);
+				Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
+					c->log, c->cr_msg, c->value_dn.bv_val );
+				rc = 1;
+			}
+			break;
+		}
+		break;
+	}
+	return rc;
+}
+
