2007-01-19 16:55:38 +00:00
/*
ldb database library
Copyright ( C ) Simo Sorce 2005
2009-08-25 16:25:55 +10:00
Copyright ( C ) Stefan Metzmacher < metze @ samba . org > 2007
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2009
2010-09-19 18:23:20 +02:00
Copyright ( C ) Matthias Dieter Wallnöfer 2010
2007-01-19 16:55:38 +00:00
2009-09-12 11:21:21 +10:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
2007-01-19 16:55:38 +00:00
2009-09-12 11:21:21 +10:00
This program is distributed in the hope that it will be useful ,
2007-01-19 16:55:38 +00:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2009-09-12 11:21:21 +10:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2007-01-19 16:55:38 +00:00
*/
/*
* Name : ldb
*
* Component : ldb deleted objects control module
*
2010-09-19 18:23:20 +02:00
* Description : this module hides deleted and recylced objects , and returns
* them if the right control is there
2007-01-19 16:55:38 +00:00
*
* Author : Stefan Metzmacher
*/
# include "includes.h"
2011-02-10 14:12:51 +11:00
# include <ldb_module.h>
2007-01-19 16:55:38 +00:00
# include "dsdb/samdb/samdb.h"
2010-01-06 09:23:29 +11:00
# include "dsdb/samdb/ldb_modules/util.h"
2007-01-19 16:55:38 +00:00
static int show_deleted_search ( struct ldb_module * module , struct ldb_request * req )
{
2009-01-30 16:31:19 -05:00
struct ldb_context * ldb ;
2010-09-19 18:23:20 +02:00
struct ldb_control * show_del , * show_rec ;
2007-01-19 16:55:38 +00:00
struct ldb_request * down_req ;
2009-08-25 16:25:55 +10:00
struct ldb_parse_tree * new_tree = req - > op . search . tree ;
2007-01-19 16:55:38 +00:00
int ret ;
2009-01-30 16:31:19 -05:00
ldb = ldb_module_get_ctx ( module ) ;
2008-09-11 18:36:28 -04:00
/* check if there's a show deleted control */
2010-09-19 18:23:20 +02:00
show_del = ldb_request_get_control ( req , LDB_CONTROL_SHOW_DELETED_OID ) ;
/* check if there's a show recycled control */
show_rec = ldb_request_get_control ( req , LDB_CONTROL_SHOW_RECYCLED_OID ) ;
2007-01-19 16:55:38 +00:00
2010-09-19 18:23:20 +02:00
if ( ( show_del = = NULL ) & & ( show_rec = = NULL ) ) {
/* Here we have to suppress all deleted objects:
* MS - ADTS 3.1 .1 .3 .4 .1
*
* Filter : ( & ( ! ( isDeleted = TRUE ) ) ( . . . ) )
*/
/* FIXME: we could use a constant tree here once we are sure
* that no ldb modules modify trees in - site */
2009-12-04 17:46:14 +11:00
new_tree = talloc ( req , struct ldb_parse_tree ) ;
if ( ! new_tree ) {
2010-07-06 13:21:54 +10:00
return ldb_oom ( ldb ) ;
2009-08-25 16:25:55 +10:00
}
2009-12-04 17:46:14 +11:00
new_tree - > operation = LDB_OP_AND ;
new_tree - > u . list . num_elements = 2 ;
new_tree - > u . list . elements = talloc_array ( new_tree , struct ldb_parse_tree * , 2 ) ;
if ( ! new_tree - > u . list . elements ) {
2010-07-06 13:21:54 +10:00
return ldb_oom ( ldb ) ;
2009-12-04 17:46:14 +11:00
}
2010-09-19 18:23:20 +02:00
2009-12-04 17:46:14 +11:00
new_tree - > u . list . elements [ 0 ] = talloc ( new_tree - > u . list . elements , struct ldb_parse_tree ) ;
new_tree - > u . list . elements [ 0 ] - > operation = LDB_OP_NOT ;
new_tree - > u . list . elements [ 0 ] - > u . isnot . child =
talloc ( new_tree - > u . list . elements , struct ldb_parse_tree ) ;
if ( ! new_tree - > u . list . elements [ 0 ] - > u . isnot . child ) {
2010-07-06 13:21:54 +10:00
return ldb_oom ( ldb ) ;
2009-12-04 17:46:14 +11:00
}
new_tree - > u . list . elements [ 0 ] - > u . isnot . child - > operation = LDB_OP_EQUALITY ;
new_tree - > u . list . elements [ 0 ] - > u . isnot . child - > u . equality . attr = " isDeleted " ;
new_tree - > u . list . elements [ 0 ] - > u . isnot . child - > u . equality . value = data_blob_string_const ( " TRUE " ) ;
2010-09-19 18:23:20 +02:00
new_tree - > u . list . elements [ 1 ] = req - > op . search . tree ;
} else if ( ( show_del ! = NULL ) & & ( show_rec = = NULL ) ) {
/* Here we need to suppress all recycled objects:
* MS - ADTS 3.1 .1 .3 .4 .1
*
* Filter : ( & ( ! ( isRecycled = TRUE ) ) ( . . . ) )
*/
/* FIXME: we could use a constant tree here once we are sure
* that no ldb modules modify trees in - site */
new_tree = talloc ( req , struct ldb_parse_tree ) ;
if ( ! new_tree ) {
return ldb_oom ( ldb ) ;
}
new_tree - > operation = LDB_OP_AND ;
new_tree - > u . list . num_elements = 2 ;
new_tree - > u . list . elements = talloc_array ( new_tree , struct ldb_parse_tree * , 2 ) ;
if ( ! new_tree - > u . list . elements ) {
return ldb_oom ( ldb ) ;
}
new_tree - > u . list . elements [ 0 ] = talloc ( new_tree - > u . list . elements , struct ldb_parse_tree ) ;
new_tree - > u . list . elements [ 0 ] - > operation = LDB_OP_NOT ;
new_tree - > u . list . elements [ 0 ] - > u . isnot . child =
talloc ( new_tree - > u . list . elements , struct ldb_parse_tree ) ;
if ( ! new_tree - > u . list . elements [ 0 ] - > u . isnot . child ) {
return ldb_oom ( ldb ) ;
}
new_tree - > u . list . elements [ 0 ] - > u . isnot . child - > operation = LDB_OP_EQUALITY ;
new_tree - > u . list . elements [ 0 ] - > u . isnot . child - > u . equality . attr = " isRecycled " ;
new_tree - > u . list . elements [ 0 ] - > u . isnot . child - > u . equality . value = data_blob_string_const ( " TRUE " ) ;
2009-12-04 17:46:14 +11:00
new_tree - > u . list . elements [ 1 ] = req - > op . search . tree ;
2007-01-19 16:55:38 +00:00
}
2010-09-19 18:23:20 +02:00
2009-08-25 16:25:55 +10:00
ret = ldb_build_search_req_ex ( & down_req , ldb , req ,
req - > op . search . base ,
req - > op . search . scope ,
new_tree ,
req - > op . search . attrs ,
req - > controls ,
2010-01-06 09:23:29 +11:00
req , dsdb_next_callback ,
2009-08-25 16:25:55 +10:00
req ) ;
2010-09-24 12:50:13 -07:00
LDB_REQ_SET_LOCATION ( down_req ) ;
2008-09-11 18:36:28 -04:00
if ( ret ! = LDB_SUCCESS ) {
return ret ;
2007-01-19 16:55:38 +00:00
}
2010-09-19 18:23:20 +02:00
/* mark the controls as done */
if ( show_del ! = NULL ) {
show_del - > critical = 0 ;
}
if ( show_rec ! = NULL ) {
show_rec - > critical = 0 ;
2007-01-19 16:55:38 +00:00
}
2008-09-11 18:36:28 -04:00
/* perform the search */
return ldb_next_request ( module , down_req ) ;
2007-01-19 16:55:38 +00:00
}
static int show_deleted_init ( struct ldb_module * module )
{
2009-01-30 16:31:19 -05:00
struct ldb_context * ldb ;
2007-01-19 16:55:38 +00:00
int ret ;
2009-01-30 16:31:19 -05:00
ldb = ldb_module_get_ctx ( module ) ;
2008-09-11 18:36:28 -04:00
ret = ldb_mod_register_control ( module , LDB_CONTROL_SHOW_DELETED_OID ) ;
2007-01-19 16:55:38 +00:00
if ( ret ! = LDB_SUCCESS ) {
2009-01-30 16:31:19 -05:00
ldb_debug ( ldb , LDB_DEBUG_ERROR ,
2009-05-24 17:40:57 -05:00
" show_deleted: Unable to register control with rootdse! \n " ) ;
2010-07-06 13:21:54 +10:00
return ldb_operr ( ldb ) ;
2007-01-19 16:55:38 +00:00
}
2010-09-19 18:23:20 +02:00
ret = ldb_mod_register_control ( module , LDB_CONTROL_SHOW_RECYCLED_OID ) ;
if ( ret ! = LDB_SUCCESS ) {
ldb_debug ( ldb , LDB_DEBUG_ERROR ,
" show_deleted: Unable to register control with rootdse! \n " ) ;
return ldb_operr ( ldb ) ;
}
2007-01-19 16:55:38 +00:00
return ldb_next_init ( module ) ;
}
2010-11-01 15:28:02 +11:00
static const struct ldb_module_ops ldb_show_deleted_module_ops = {
2007-01-19 16:55:38 +00:00
. name = " show_deleted " ,
. search = show_deleted_search ,
. init_context = show_deleted_init
} ;
2010-11-01 15:28:02 +11:00
int ldb_show_deleted_module_init ( const char * version )
{
2010-11-01 22:30:45 +11:00
LDB_MODULE_CHECK_VERSION ( version ) ;
2010-11-01 15:28:02 +11:00
return ldb_register_module ( & ldb_show_deleted_module_ops ) ;
}