Convert mtime from a time_t to a struct timespec.
[Samba.git] / source4 / dsdb / samdb / ldb_modules / show_deleted.c
blobbef4c06090254d37d8e6c47b6b8ce23d0926c116
1 /*
2 ldb database library
4 Copyright (C) Simo Sorce 2005
5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2007
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
7 Copyright (C) Matthias Dieter Wallnöfer 2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * Name: ldb
26 * Component: ldb deleted objects control module
28 * Description: this module hides deleted and recylced objects, and returns
29 * them if the right control is there
31 * Author: Stefan Metzmacher
34 #include "includes.h"
35 #include <ldb_module.h>
36 #include "dsdb/samdb/samdb.h"
37 #include "dsdb/samdb/ldb_modules/util.h"
39 static int show_deleted_search(struct ldb_module *module, struct ldb_request *req)
41 struct ldb_context *ldb;
42 struct ldb_control *show_del, *show_rec;
43 struct ldb_request *down_req;
44 struct ldb_parse_tree *new_tree = req->op.search.tree;
45 int ret;
47 ldb = ldb_module_get_ctx(module);
49 /* check if there's a show deleted control */
50 show_del = ldb_request_get_control(req, LDB_CONTROL_SHOW_DELETED_OID);
51 /* check if there's a show recycled control */
52 show_rec = ldb_request_get_control(req, LDB_CONTROL_SHOW_RECYCLED_OID);
54 if ((show_del == NULL) && (show_rec == NULL)) {
55 /* Here we have to suppress all deleted objects:
56 * MS-ADTS 3.1.1.3.4.1
58 * Filter: (&(!(isDeleted=TRUE))(...))
60 /* FIXME: we could use a constant tree here once we are sure
61 * that no ldb modules modify trees in-site */
62 new_tree = talloc(req, struct ldb_parse_tree);
63 if (!new_tree) {
64 return ldb_oom(ldb);
66 new_tree->operation = LDB_OP_AND;
67 new_tree->u.list.num_elements = 2;
68 new_tree->u.list.elements = talloc_array(new_tree, struct ldb_parse_tree *, 2);
69 if (!new_tree->u.list.elements) {
70 return ldb_oom(ldb);
73 new_tree->u.list.elements[0] = talloc(new_tree->u.list.elements, struct ldb_parse_tree);
74 new_tree->u.list.elements[0]->operation = LDB_OP_NOT;
75 new_tree->u.list.elements[0]->u.isnot.child =
76 talloc(new_tree->u.list.elements, struct ldb_parse_tree);
77 if (!new_tree->u.list.elements[0]->u.isnot.child) {
78 return ldb_oom(ldb);
80 new_tree->u.list.elements[0]->u.isnot.child->operation = LDB_OP_EQUALITY;
81 new_tree->u.list.elements[0]->u.isnot.child->u.equality.attr = "isDeleted";
82 new_tree->u.list.elements[0]->u.isnot.child->u.equality.value = data_blob_string_const("TRUE");
84 new_tree->u.list.elements[1] = req->op.search.tree;
85 } else if ((show_del != NULL) && (show_rec == NULL)) {
86 /* Here we need to suppress all recycled objects:
87 * MS-ADTS 3.1.1.3.4.1
89 * Filter: (&(!(isRecycled=TRUE))(...))
91 /* FIXME: we could use a constant tree here once we are sure
92 * that no ldb modules modify trees in-site */
93 new_tree = talloc(req, struct ldb_parse_tree);
94 if (!new_tree) {
95 return ldb_oom(ldb);
97 new_tree->operation = LDB_OP_AND;
98 new_tree->u.list.num_elements = 2;
99 new_tree->u.list.elements = talloc_array(new_tree, struct ldb_parse_tree *, 2);
100 if (!new_tree->u.list.elements) {
101 return ldb_oom(ldb);
104 new_tree->u.list.elements[0] = talloc(new_tree->u.list.elements, struct ldb_parse_tree);
105 new_tree->u.list.elements[0]->operation = LDB_OP_NOT;
106 new_tree->u.list.elements[0]->u.isnot.child =
107 talloc(new_tree->u.list.elements, struct ldb_parse_tree);
108 if (!new_tree->u.list.elements[0]->u.isnot.child) {
109 return ldb_oom(ldb);
111 new_tree->u.list.elements[0]->u.isnot.child->operation = LDB_OP_EQUALITY;
112 new_tree->u.list.elements[0]->u.isnot.child->u.equality.attr = "isRecycled";
113 new_tree->u.list.elements[0]->u.isnot.child->u.equality.value = data_blob_string_const("TRUE");
115 new_tree->u.list.elements[1] = req->op.search.tree;
118 ret = ldb_build_search_req_ex(&down_req, ldb, req,
119 req->op.search.base,
120 req->op.search.scope,
121 new_tree,
122 req->op.search.attrs,
123 req->controls,
124 req, dsdb_next_callback,
125 req);
126 LDB_REQ_SET_LOCATION(down_req);
127 if (ret != LDB_SUCCESS) {
128 return ret;
131 /* mark the controls as done */
132 if (show_del != NULL) {
133 show_del->critical = 0;
135 if (show_rec != NULL) {
136 show_rec->critical = 0;
139 /* perform the search */
140 return ldb_next_request(module, down_req);
143 static int show_deleted_init(struct ldb_module *module)
145 struct ldb_context *ldb;
146 int ret;
148 ldb = ldb_module_get_ctx(module);
150 ret = ldb_mod_register_control(module, LDB_CONTROL_SHOW_DELETED_OID);
151 if (ret != LDB_SUCCESS) {
152 ldb_debug(ldb, LDB_DEBUG_ERROR,
153 "show_deleted: Unable to register control with rootdse!\n");
154 return ldb_operr(ldb);
157 ret = ldb_mod_register_control(module, LDB_CONTROL_SHOW_RECYCLED_OID);
158 if (ret != LDB_SUCCESS) {
159 ldb_debug(ldb, LDB_DEBUG_ERROR,
160 "show_deleted: Unable to register control with rootdse!\n");
161 return ldb_operr(ldb);
164 return ldb_next_init(module);
167 static const struct ldb_module_ops ldb_show_deleted_module_ops = {
168 .name = "show_deleted",
169 .search = show_deleted_search,
170 .init_context = show_deleted_init
173 int ldb_show_deleted_module_init(const char *version)
175 LDB_MODULE_CHECK_VERSION(version);
176 return ldb_register_module(&ldb_show_deleted_module_ops);