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"
31 add a set of controls to a ldb_request structure based on a set of
32 flags. See util.h for a list of available flags
34 int dsdb_request_add_controls(struct ldb_module
*module
, struct ldb_request
*req
, uint32_t dsdb_flags
)
37 if (dsdb_flags
& DSDB_SEARCH_SEARCH_ALL_PARTITIONS
) {
38 struct ldb_search_options_control
*options
;
39 /* Using the phantom root control allows us to search all partitions */
40 options
= talloc(req
, struct ldb_search_options_control
);
41 if (options
== NULL
) {
42 ldb_module_oom(module
);
43 return LDB_ERR_OPERATIONS_ERROR
;
45 options
->search_options
= LDB_SEARCH_OPTION_PHANTOM_ROOT
;
47 ret
= ldb_request_add_control(req
,
48 LDB_CONTROL_SEARCH_OPTIONS_OID
,
50 if (ret
!= LDB_SUCCESS
) {
55 if (dsdb_flags
& DSDB_SEARCH_SHOW_DELETED
) {
56 ret
= ldb_request_add_control(req
, LDB_CONTROL_SHOW_DELETED_OID
, true, NULL
);
57 if (ret
!= LDB_SUCCESS
) {
62 if (dsdb_flags
& DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT
) {
63 ret
= ldb_request_add_control(req
, DSDB_CONTROL_DN_STORAGE_FORMAT_OID
, true, NULL
);
64 if (ret
!= LDB_SUCCESS
) {
69 if (dsdb_flags
& DSDB_SEARCH_SHOW_EXTENDED_DN
) {
70 struct ldb_extended_dn_control
*extended_ctrl
= talloc(req
, struct ldb_extended_dn_control
);
72 ldb_module_oom(module
);
73 return LDB_ERR_OPERATIONS_ERROR
;
75 extended_ctrl
->type
= 1;
77 ret
= ldb_request_add_control(req
, LDB_CONTROL_EXTENDED_DN_OID
, true, extended_ctrl
);
78 if (ret
!= LDB_SUCCESS
) {
83 if (dsdb_flags
& DSDB_SEARCH_REVEAL_INTERNALS
) {
84 ret
= ldb_request_add_control(req
, LDB_CONTROL_REVEAL_INTERNALS
, false, NULL
);
85 if (ret
!= LDB_SUCCESS
) {
94 search for attrs on one DN, in the modules below
96 int dsdb_module_search_dn(struct ldb_module
*module
,
98 struct ldb_result
**_res
,
99 struct ldb_dn
*basedn
,
100 const char * const *attrs
,
104 struct ldb_request
*req
;
106 struct ldb_result
*res
;
108 tmp_ctx
= talloc_new(mem_ctx
);
110 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
112 return LDB_ERR_OPERATIONS_ERROR
;
115 ret
= ldb_build_search_req(&req
, ldb_module_get_ctx(module
), tmp_ctx
,
122 ldb_search_default_callback
,
124 if (ret
!= LDB_SUCCESS
) {
125 talloc_free(tmp_ctx
);
129 ret
= dsdb_request_add_controls(module
, req
, dsdb_flags
);
130 if (ret
!= LDB_SUCCESS
) {
131 talloc_free(tmp_ctx
);
135 ret
= ldb_next_request(module
, req
);
136 if (ret
== LDB_SUCCESS
) {
137 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
140 if (ret
!= LDB_SUCCESS
) {
141 talloc_free(tmp_ctx
);
145 if (res
->count
!= 1) {
146 /* we may be reading a DB that does not have the 'check base on search' option... */
147 ret
= LDB_ERR_NO_SUCH_OBJECT
;
148 ldb_asprintf_errstring(ldb_module_get_ctx(module
),
149 "dsdb_module_search_dn: did not find base dn %s (%d results)",
150 ldb_dn_get_linearized(basedn
), res
->count
);
152 *_res
= talloc_steal(mem_ctx
, res
);
154 talloc_free(tmp_ctx
);
159 search for attrs in the modules below
161 int dsdb_module_search(struct ldb_module
*module
,
163 struct ldb_result
**_res
,
164 struct ldb_dn
*basedn
, enum ldb_scope scope
,
165 const char * const *attrs
,
167 const char *expression
)
170 struct ldb_request
*req
;
172 struct ldb_result
*res
;
174 tmp_ctx
= talloc_new(mem_ctx
);
176 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
178 return LDB_ERR_OPERATIONS_ERROR
;
181 ret
= ldb_build_search_req(&req
, ldb_module_get_ctx(module
), tmp_ctx
,
188 ldb_search_default_callback
,
190 if (ret
!= LDB_SUCCESS
) {
191 talloc_free(tmp_ctx
);
195 ret
= dsdb_request_add_controls(module
, req
, dsdb_flags
);
196 if (ret
!= LDB_SUCCESS
) {
197 talloc_free(tmp_ctx
);
201 ret
= ldb_next_request(module
, req
);
202 if (ret
== LDB_SUCCESS
) {
203 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
207 if (ret
== LDB_SUCCESS
) {
208 *_res
= talloc_steal(mem_ctx
, res
);
210 talloc_free(tmp_ctx
);
215 find a DN given a GUID. This searches across all partitions
217 int dsdb_module_dn_by_guid(struct ldb_module
*module
, TALLOC_CTX
*mem_ctx
,
218 const struct GUID
*guid
, struct ldb_dn
**dn
)
220 struct ldb_result
*res
;
221 const char *attrs
[] = { NULL
};
223 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
226 expression
= talloc_asprintf(tmp_ctx
, "objectGUID=%s", GUID_string(tmp_ctx
, guid
));
228 ldb_module_oom(module
);
229 return LDB_ERR_OPERATIONS_ERROR
;
232 ret
= dsdb_module_search(module
, tmp_ctx
, &res
, NULL
, LDB_SCOPE_SUBTREE
,
234 DSDB_SEARCH_SHOW_DELETED
|
235 DSDB_SEARCH_SEARCH_ALL_PARTITIONS
|
236 DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT
,
238 if (ret
!= LDB_SUCCESS
) {
239 talloc_free(tmp_ctx
);
242 if (res
->count
== 0) {
243 talloc_free(tmp_ctx
);
244 return LDB_ERR_NO_SUCH_OBJECT
;
246 if (res
->count
!= 1) {
247 ldb_asprintf_errstring(ldb_module_get_ctx(module
), "More than one object found matching %s\n",
249 talloc_free(tmp_ctx
);
250 return LDB_ERR_OPERATIONS_ERROR
;
253 *dn
= talloc_steal(mem_ctx
, res
->msgs
[0]->dn
);
255 talloc_free(tmp_ctx
);
260 a ldb_modify request operating on modules below the
263 int dsdb_module_modify(struct ldb_module
*module
,
264 const struct ldb_message
*message
,
267 struct ldb_request
*mod_req
;
269 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
270 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
272 ret
= ldb_build_mod_req(&mod_req
, ldb
, tmp_ctx
,
276 ldb_op_default_callback
,
278 if (ret
!= LDB_SUCCESS
) {
279 talloc_free(tmp_ctx
);
283 ret
= dsdb_request_add_controls(module
, mod_req
, dsdb_flags
);
284 if (ret
!= LDB_SUCCESS
) {
285 talloc_free(tmp_ctx
);
289 /* Run the new request */
290 ret
= ldb_next_request(module
, mod_req
);
291 if (ret
== LDB_SUCCESS
) {
292 ret
= ldb_wait(mod_req
->handle
, LDB_WAIT_ALL
);
295 talloc_free(tmp_ctx
);
302 a ldb_rename request operating on modules below the
305 int dsdb_module_rename(struct ldb_module
*module
,
306 struct ldb_dn
*olddn
, struct ldb_dn
*newdn
,
309 struct ldb_request
*req
;
311 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
312 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
314 ret
= ldb_build_rename_req(&req
, ldb
, tmp_ctx
,
319 ldb_op_default_callback
,
321 if (ret
!= LDB_SUCCESS
) {
322 talloc_free(tmp_ctx
);
326 ret
= dsdb_request_add_controls(module
, req
, dsdb_flags
);
327 if (ret
!= LDB_SUCCESS
) {
328 talloc_free(tmp_ctx
);
332 /* Run the new request */
333 ret
= ldb_next_request(module
, req
);
334 if (ret
== LDB_SUCCESS
) {
335 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
338 talloc_free(tmp_ctx
);
342 const struct dsdb_class
* get_last_structural_class(const struct dsdb_schema
*schema
,const struct ldb_message_element
*element
)
344 const struct dsdb_class
*last_class
= NULL
;
347 for (i
= 0; i
< element
->num_values
; i
++){
348 const struct dsdb_class
*tmp_class
= dsdb_class_by_lDAPDisplayName_ldb_val(schema
, &element
->values
[i
]);
350 if(tmp_class
== NULL
) {
354 if(tmp_class
->objectClassCategory
== 3) {
359 last_class
= tmp_class
;
361 if (tmp_class
->subClass_order
> last_class
->subClass_order
)
362 last_class
= tmp_class
;