2 Unix SMB/CIFS implementation.
3 Samba utility functions
5 Copyright (C) Andrew Tridgell 2009
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "ldb_module.h"
25 #include "dsdb/samdb/ldb_modules/util.h"
26 #include "dsdb/samdb/samdb.h"
29 add a set of controls to a ldb_request structure based on a set of
30 flags. See util.h for a list of available flags
32 int dsdb_request_add_controls(struct ldb_module *module, struct ldb_request *req, uint32_t dsdb_flags)
35 if (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) {
36 struct ldb_search_options_control *options;
37 /* Using the phantom root control allows us to search all partitions */
38 options = talloc(req, struct ldb_search_options_control);
39 if (options == NULL) {
40 ldb_module_oom(module);
41 return LDB_ERR_OPERATIONS_ERROR;
43 options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT;
45 ret = ldb_request_add_control(req,
46 LDB_CONTROL_SEARCH_OPTIONS_OID,
48 if (ret != LDB_SUCCESS) {
53 if (dsdb_flags & DSDB_SEARCH_SHOW_DELETED) {
54 ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL);
55 if (ret != LDB_SUCCESS) {
60 if (dsdb_flags & DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT) {
61 ret = ldb_request_add_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID, true, NULL);
62 if (ret != LDB_SUCCESS) {
67 if (dsdb_flags & DSDB_SEARCH_SHOW_EXTENDED_DN) {
68 struct ldb_extended_dn_control *extended_ctrl = talloc(req, struct ldb_extended_dn_control);
70 ldb_module_oom(module);
71 return LDB_ERR_OPERATIONS_ERROR;
73 extended_ctrl->type = 1;
75 ret = ldb_request_add_control(req, LDB_CONTROL_EXTENDED_DN_OID, true, extended_ctrl);
76 if (ret != LDB_SUCCESS) {
81 if (dsdb_flags & DSDB_SEARCH_REVEAL_INTERNALS) {
82 ret = ldb_request_add_control(req, LDB_CONTROL_REVEAL_INTERNALS, false, NULL);
83 if (ret != LDB_SUCCESS) {
92 search for attrs on one DN, in the modules below
94 int dsdb_module_search_dn(struct ldb_module *module,
96 struct ldb_result **_res,
97 struct ldb_dn *basedn,
98 const char * const *attrs,
102 struct ldb_request *req;
104 struct ldb_result *res;
106 tmp_ctx = talloc_new(mem_ctx);
108 res = talloc_zero(tmp_ctx, struct ldb_result);
110 return LDB_ERR_OPERATIONS_ERROR;
113 ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
120 ldb_search_default_callback,
122 if (ret != LDB_SUCCESS) {
123 talloc_free(tmp_ctx);
127 ret = dsdb_request_add_controls(module, req, dsdb_flags);
128 if (ret != LDB_SUCCESS) {
129 talloc_free(tmp_ctx);
133 ret = ldb_next_request(module, req);
134 if (ret == LDB_SUCCESS) {
135 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
138 if (ret != LDB_SUCCESS) {
139 talloc_free(tmp_ctx);
143 if (res->count != 1) {
144 /* we may be reading a DB that does not have the 'check base on search' option... */
145 ret = LDB_ERR_NO_SUCH_OBJECT;
146 ldb_asprintf_errstring(ldb_module_get_ctx(module),
147 "dsdb_module_search_dn: did not find base dn %s (%d results)",
148 ldb_dn_get_linearized(basedn), res->count);
150 *_res = talloc_steal(mem_ctx, res);
152 talloc_free(tmp_ctx);
157 search for attrs in the modules below
159 int dsdb_module_search(struct ldb_module *module,
161 struct ldb_result **_res,
162 struct ldb_dn *basedn, enum ldb_scope scope,
163 const char * const *attrs,
165 const char *expression)
168 struct ldb_request *req;
170 struct ldb_result *res;
172 tmp_ctx = talloc_new(mem_ctx);
174 res = talloc_zero(tmp_ctx, struct ldb_result);
176 return LDB_ERR_OPERATIONS_ERROR;
179 ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
186 ldb_search_default_callback,
188 if (ret != LDB_SUCCESS) {
189 talloc_free(tmp_ctx);
193 ret = dsdb_request_add_controls(module, req, dsdb_flags);
194 if (ret != LDB_SUCCESS) {
195 talloc_free(tmp_ctx);
199 ret = ldb_next_request(module, req);
200 if (ret == LDB_SUCCESS) {
201 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
205 if (ret == LDB_SUCCESS) {
206 *_res = talloc_steal(mem_ctx, res);
208 talloc_free(tmp_ctx);
213 find a DN given a GUID. This searches across all partitions
215 int dsdb_module_dn_by_guid(struct ldb_module *module, TALLOC_CTX *mem_ctx,
216 const struct GUID *guid, struct ldb_dn **dn)
218 struct ldb_result *res;
219 const char *attrs[] = { NULL };
221 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
224 expression = talloc_asprintf(tmp_ctx, "objectGUID=%s", GUID_string(tmp_ctx, guid));
226 ldb_module_oom(module);
227 return LDB_ERR_OPERATIONS_ERROR;
230 ret = dsdb_module_search(module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
231 attrs, DSDB_SEARCH_SHOW_DELETED | DSDB_SEARCH_SEARCH_ALL_PARTITIONS,
233 if (ret != LDB_SUCCESS) {
234 talloc_free(tmp_ctx);
237 if (ret->count == 0) {
238 talloc_free(tmp_ctx);
239 return LDB_ERR_NO_SUCH_OBJECT;
241 if (res->count != 1) {
242 ldb_asprintf_errstring(ldb_module_get_ctx(module), "More than one object found matching %s\n",
244 talloc_free(tmp_ctx);
245 return LDB_ERR_OPERATIONS_ERROR;
248 *dn = talloc_steal(mem_ctx, res->msgs[0].dn);
250 talloc_free(tmp_ctx);