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 "librpc/ndr/libndr.h"
26 #include "dsdb/samdb/ldb_modules/util.h"
27 #include "dsdb/samdb/samdb.h"
30 add a set of controls to a ldb_request structure based on a set of
31 flags. See util.h for a list of available flags
33 int dsdb_request_add_controls(struct ldb_module *module, struct ldb_request *req, uint32_t dsdb_flags)
36 if (dsdb_flags & DSDB_SEARCH_SEARCH_ALL_PARTITIONS) {
37 struct ldb_search_options_control *options;
38 /* Using the phantom root control allows us to search all partitions */
39 options = talloc(req, struct ldb_search_options_control);
40 if (options == NULL) {
41 ldb_module_oom(module);
42 return LDB_ERR_OPERATIONS_ERROR;
44 options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT;
46 ret = ldb_request_add_control(req,
47 LDB_CONTROL_SEARCH_OPTIONS_OID,
49 if (ret != LDB_SUCCESS) {
54 if (dsdb_flags & DSDB_SEARCH_SHOW_DELETED) {
55 ret = ldb_request_add_control(req, LDB_CONTROL_SHOW_DELETED_OID, true, NULL);
56 if (ret != LDB_SUCCESS) {
61 if (dsdb_flags & DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT) {
62 ret = ldb_request_add_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID, true, NULL);
63 if (ret != LDB_SUCCESS) {
68 if (dsdb_flags & DSDB_SEARCH_SHOW_EXTENDED_DN) {
69 struct ldb_extended_dn_control *extended_ctrl = talloc(req, struct ldb_extended_dn_control);
71 ldb_module_oom(module);
72 return LDB_ERR_OPERATIONS_ERROR;
74 extended_ctrl->type = 1;
76 ret = ldb_request_add_control(req, LDB_CONTROL_EXTENDED_DN_OID, true, extended_ctrl);
77 if (ret != LDB_SUCCESS) {
82 if (dsdb_flags & DSDB_SEARCH_REVEAL_INTERNALS) {
83 ret = ldb_request_add_control(req, LDB_CONTROL_REVEAL_INTERNALS, false, NULL);
84 if (ret != LDB_SUCCESS) {
93 search for attrs on one DN, in the modules below
95 int dsdb_module_search_dn(struct ldb_module *module,
97 struct ldb_result **_res,
98 struct ldb_dn *basedn,
99 const char * const *attrs,
103 struct ldb_request *req;
105 struct ldb_result *res;
107 tmp_ctx = talloc_new(mem_ctx);
109 res = talloc_zero(tmp_ctx, struct ldb_result);
111 return LDB_ERR_OPERATIONS_ERROR;
114 ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
121 ldb_search_default_callback,
123 if (ret != LDB_SUCCESS) {
124 talloc_free(tmp_ctx);
128 ret = dsdb_request_add_controls(module, req, dsdb_flags);
129 if (ret != LDB_SUCCESS) {
130 talloc_free(tmp_ctx);
134 ret = ldb_next_request(module, req);
135 if (ret == LDB_SUCCESS) {
136 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
139 if (ret != LDB_SUCCESS) {
140 talloc_free(tmp_ctx);
144 if (res->count != 1) {
145 /* we may be reading a DB that does not have the 'check base on search' option... */
146 ret = LDB_ERR_NO_SUCH_OBJECT;
147 ldb_asprintf_errstring(ldb_module_get_ctx(module),
148 "dsdb_module_search_dn: did not find base dn %s (%d results)",
149 ldb_dn_get_linearized(basedn), res->count);
151 *_res = talloc_steal(mem_ctx, res);
153 talloc_free(tmp_ctx);
158 search for attrs in the modules below
160 int dsdb_module_search(struct ldb_module *module,
162 struct ldb_result **_res,
163 struct ldb_dn *basedn, enum ldb_scope scope,
164 const char * const *attrs,
166 const char *expression)
169 struct ldb_request *req;
171 struct ldb_result *res;
173 tmp_ctx = talloc_new(mem_ctx);
175 res = talloc_zero(tmp_ctx, struct ldb_result);
177 return LDB_ERR_OPERATIONS_ERROR;
180 ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
187 ldb_search_default_callback,
189 if (ret != LDB_SUCCESS) {
190 talloc_free(tmp_ctx);
194 ret = dsdb_request_add_controls(module, req, dsdb_flags);
195 if (ret != LDB_SUCCESS) {
196 talloc_free(tmp_ctx);
200 ret = ldb_next_request(module, req);
201 if (ret == LDB_SUCCESS) {
202 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
206 if (ret == LDB_SUCCESS) {
207 *_res = talloc_steal(mem_ctx, res);
209 talloc_free(tmp_ctx);
214 find a DN given a GUID. This searches across all partitions
216 int dsdb_module_dn_by_guid(struct ldb_module *module, TALLOC_CTX *mem_ctx,
217 const struct GUID *guid, struct ldb_dn **dn)
219 struct ldb_result *res;
220 const char *attrs[] = { NULL };
222 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
225 expression = talloc_asprintf(tmp_ctx, "objectGUID=%s", GUID_string(tmp_ctx, guid));
227 ldb_module_oom(module);
228 return LDB_ERR_OPERATIONS_ERROR;
231 ret = dsdb_module_search(module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
233 DSDB_SEARCH_SHOW_DELETED |
234 DSDB_SEARCH_SEARCH_ALL_PARTITIONS |
235 DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
237 if (ret != LDB_SUCCESS) {
238 talloc_free(tmp_ctx);
241 if (res->count == 0) {
242 talloc_free(tmp_ctx);
243 return LDB_ERR_NO_SUCH_OBJECT;
245 if (res->count != 1) {
246 ldb_asprintf_errstring(ldb_module_get_ctx(module), "More than one object found matching %s\n",
248 talloc_free(tmp_ctx);
249 return LDB_ERR_OPERATIONS_ERROR;
252 *dn = talloc_steal(mem_ctx, res->msgs[0]->dn);
254 talloc_free(tmp_ctx);