Initial implementation of the show_deleted overlay
authorNadezhda Ivanova <nivanova@symas.com>
Sun, 20 Apr 2014 17:44:28 +0000 (20:44 +0300)
committerNadezhda Ivanova <nivanova@symas.com>
Sat, 19 Jul 2014 20:07:24 +0000 (23:07 +0300)
The show_deleted and show_recycled controls enable the deleted and
recycled objects to be included in the search results. The module filters them
out if the controls are not provided.

contrib/slapd-modules/samba4/Makefile
contrib/slapd-modules/samba4/show_deleted.c [new file with mode: 0644]

index 01ef3fd93cf784281d777dbd66cbd26366e56c73..b7f8b9e7260e637a8236429dadcb27666d4f90a7 100644 (file)
@@ -14,7 +14,7 @@
 
 LDAP_SRC = ../../..
 LDAP_BUILD = ../../..
-LDAP_INC = -I$(LDAP_BUILD)/include -I$(LDAP_SRC)/include -I$(LDAP_SRC)/servers/slapd
+LDAP_INC = -I$(LDAP_BUILD)/include -I$(LDAP_SRC)/include -I$(LDAP_SRC)/servers/slapd -I/usr/local/samba/include
 LDAP_LIB = $(LDAP_BUILD)/libraries/libldap_r/libldap_r.la \
        $(LDAP_BUILD)/libraries/liblber/liblber.la
 
@@ -25,12 +25,14 @@ DEFS = -DSLAPD_OVER_RDNVAL=SLAPD_MOD_DYNAMIC \
        -DSLAPD_OVER_PGUID=SLAPD_MOD_DYNAMIC \
        -DSLAPD_OVER_VERNUM=SLAPD_MOD_DYNAMIC \
        -DSLAPD_OVER_INSTANCETYPE=SLAPD_MOD_DYNAMIC \
-       -DSLAPD_OVER_SYNTAXCHECKS=SLAPD_MOD_DYNAMIC
+       -DSLAPD_OVER_SYNTAXCHECKS=SLAPD_MOD_DYNAMIC \
+       -DSLAPD_OVER_SHOWDELETED=SLAPD_MOD_DYNAMIC
 
 INCS = $(LDAP_INC)
 LIBS = $(LDAP_LIB)
 
-PROGRAMS = pguid.la rdnval.la vernum.la instancetype.la syntax_checks.la
+PROGRAMS = pguid.la rdnval.la vernum.la \
+          syntax_checks.la instancetype.la show_deleted.la
 LTVER = 0:0:0
 
 prefix=/usr/local
@@ -68,6 +70,9 @@ syntax_checks.la: syntax_checks.lo
        $(LIBTOOL) --mode=link $(CC) $(OPT) -version-info $(LTVER) \
        -rpath $(moduledir) -module -o $@ $? $(LIBS)
 
+show_deleted.la: show_deleted.lo
+       $(LIBTOOL) --mode=link $(CC) $(OPT) -version-info $(LTVER) \
+       -rpath $(moduledir) -module -o $@ $? $(LIBS)
 
 clean:
        rm -rf *.o *.lo *.la .libs
diff --git a/contrib/slapd-modules/samba4/show_deleted.c b/contrib/slapd-modules/samba4/show_deleted.c
new file mode 100644 (file)
index 0000000..8cb9bb1
--- /dev/null
@@ -0,0 +1,164 @@
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2013 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+/* This is an overlay responsible for the hiding or displaying
+ deleted or recicled objects depending on the presence of controls */
+
+#include "portable.h"
+
+#ifdef SLAPD_OVER_SHOWDELETED
+
+#include <stdio.h>
+
+#include "ac/string.h"
+#include "ac/socket.h"
+
+#include "slap.h"
+#include "config.h"
+
+#include "lutil.h"
+#include "ldap_rq.h"
+#include "ldb.h"
+
+static slap_overinst           show_deleted;
+static int show_deleted_cid;
+static int show_recycled_cid;
+#define o_show_deleted                 o_ctrlflag[show_deleted_cid]
+#define o_ctrl_show_deleted            o_controls[show_deleted_cid]
+#define o_show_recycled                        o_ctrlflag[show_recycled_cid]
+#define o_ctrl_show_recycled           o_controls[show_recycled_cid]
+
+
+static int
+show_deleted_parseCtrl(
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       op->o_show_deleted = SLAP_CONTROL_NONCRITICAL;
+       ctrl->ldctl_iscritical = 0;
+       return LDAP_SUCCESS;
+}
+
+static int
+show_recycled_parseCtrl(
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       op->o_show_recycled = SLAP_CONTROL_NONCRITICAL;
+       ctrl->ldctl_iscritical = 0;
+       return LDAP_SUCCESS;
+}
+
+static int show_deleted_op_search( Operation *op, SlapReply *rs )
+{
+
+/*TODO Implement checking of partition settings, for now we assume
+ *recycling is enabled */
+       const char deleted_filter[] = "(!(isDeleted=TRUE))";
+       const char recycled_filter[] = "(!(isRecycled=TRUE))";
+       struct berval *old_fstring = &op->ors_filterstr;
+       struct berval new_fstring;
+       char *tmp_ptr;
+       new_fstring.bv_len = old_fstring->bv_len + STRLENOF( "(&" ) + STRLENOF( ")" );
+       if (op->o_show_deleted != 0 && op->o_show_recycled != 0) {
+               /* nothing to do here, we display both */
+               return SLAP_CB_CONTINUE;
+       } else if (op->o_show_recycled != 0) {
+               /* show isRecycled = TRUE, hide isDeleted=TRUE */
+               new_fstring.bv_len += STRLENOF( deleted_filter );
+               new_fstring.bv_val = op->o_tmpalloc( new_fstring.bv_len+1, op->o_tmpmemctx );
+               tmp_ptr = new_fstring.bv_val;
+               tmp_ptr = lutil_strcopy( tmp_ptr, "(&" );
+               tmp_ptr = lutil_strncopy( tmp_ptr, old_fstring->bv_val, old_fstring->bv_len );
+               tmp_ptr = lutil_strcopy( tmp_ptr, deleted_filter );
+               tmp_ptr = lutil_strcopy( tmp_ptr, ")" );
+               *tmp_ptr = '\0';
+       } else if (op->o_show_deleted != 0) {
+               /* show isDeleted = TRUE, hide isRecycled=TRUE */
+               new_fstring.bv_len += STRLENOF( recycled_filter );
+               new_fstring.bv_val = op->o_tmpalloc( new_fstring.bv_len+1, op->o_tmpmemctx );
+               tmp_ptr = new_fstring.bv_val;
+               tmp_ptr = lutil_strcopy( tmp_ptr, "(&" );
+               tmp_ptr = lutil_strncopy( tmp_ptr, old_fstring->bv_val, old_fstring->bv_len );
+               tmp_ptr = lutil_strcopy( tmp_ptr, recycled_filter );
+               tmp_ptr = lutil_strcopy( tmp_ptr, ")" );
+               *tmp_ptr = '\0';
+       } else {
+               new_fstring.bv_len += STRLENOF( deleted_filter ) + STRLENOF( recycled_filter );
+               new_fstring.bv_val = op->o_tmpalloc( new_fstring.bv_len+1, op->o_tmpmemctx );
+               tmp_ptr = new_fstring.bv_val;
+               tmp_ptr = lutil_strcopy( tmp_ptr, "(&" );
+               tmp_ptr = lutil_strncopy( tmp_ptr, old_fstring->bv_val, old_fstring->bv_len );
+               tmp_ptr = lutil_strcopy( tmp_ptr, deleted_filter );
+               tmp_ptr = lutil_strcopy( tmp_ptr, recycled_filter );
+               tmp_ptr = lutil_strcopy( tmp_ptr, ")" );
+               *tmp_ptr = '\0';
+       }
+       /* todo THIS crashes during provisioning, although it works after, find out why!!!*/
+       if ( op->ors_filter != NULL) {
+               filter_free_x( op, op->ors_filter, 1 );
+       }
+       if ( op->ors_filterstr.bv_val != NULL) {
+               op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
+       }
+       op->ors_filterstr.bv_len = new_fstring.bv_len;
+       op->ors_filterstr.bv_val = new_fstring.bv_val;
+       op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val );
+       assert( op->ors_filter != NULL );
+       return SLAP_CB_CONTINUE;
+}
+
+
+int show_deleted_initialize(void)
+{
+       int rc;
+       rc = register_supported_control(LDB_CONTROL_SHOW_DELETED_OID ,
+                                        SLAP_CTRL_SEARCH,
+                                        NULL,
+                                        show_deleted_parseCtrl, &show_deleted_cid );
+       if ( rc != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "show_deleted_initialize: Failed to register control (%d)\n",
+                       rc, 0, 0 );
+               return -1;
+               }
+
+       rc = register_supported_control( LDB_CONTROL_SHOW_RECYCLED_OID,
+                                        SLAP_CTRL_SEARCH,
+                                        NULL,
+                                        show_recycled_parseCtrl, &show_recycled_cid );
+       if ( rc != LDAP_SUCCESS ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "show_deleted_initialize: Failed to register control (%d)\n",
+                       rc, 0, 0 );
+               return -1;
+               }
+       show_deleted.on_bi.bi_type = "show_deleted";
+       show_deleted.on_bi.bi_op_search = show_deleted_op_search;
+       Debug(LDAP_DEBUG_TRACE, "show_deleted_initialize\n",0,0,0);
+       return overlay_register(&show_deleted);
+}
+
+
+#if SLAPD_OVER_SHOWDELETED == SLAPD_MOD_DYNAMIC
+int init_module( int argc, char *argv[] )
+{
+       return show_deleted_initialize();
+}
+#endif /* SLAPD_OVER_SHOWDELETED == SLAPD_MOD_DYNAMIC */
+
+#endif /*SLAPD_OVER_SHOWDELETED*/