2 Unix SMB/CIFS implementation.
3 Samba utility functions
5 Copyright (C) Andrew Tridgell 2009
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
7 Copyright (C) Matthieu Patou <mat@matws.net> 2011
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/>.
25 #include "ldb_module.h"
26 #include "librpc/ndr/libndr.h"
27 #include "dsdb/samdb/ldb_modules/util.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "dsdb/common/util.h"
30 #include "libcli/security/security.h"
33 search for attrs on one DN, in the modules below
35 int dsdb_module_search_dn(struct ldb_module
*module
,
37 struct ldb_result
**_res
,
38 struct ldb_dn
*basedn
,
39 const char * const *attrs
,
41 struct ldb_request
*parent
)
44 struct ldb_request
*req
;
46 struct ldb_result
*res
;
48 tmp_ctx
= talloc_new(mem_ctx
);
50 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
53 return ldb_oom(ldb_module_get_ctx(module
));
56 ret
= ldb_build_search_req(&req
, ldb_module_get_ctx(module
), tmp_ctx
,
63 ldb_search_default_callback
,
65 LDB_REQ_SET_LOCATION(req
);
66 if (ret
!= LDB_SUCCESS
) {
71 ret
= dsdb_request_add_controls(req
, dsdb_flags
);
72 if (ret
!= LDB_SUCCESS
) {
77 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
78 ldb_req_mark_trusted(req
);
81 /* Run the new request */
82 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
83 ret
= ldb_next_request(module
, req
);
84 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
85 ret
= ldb_request(ldb_module_get_ctx(module
), req
);
87 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
88 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
89 ret
= ops
->search(module
, req
);
91 if (ret
== LDB_SUCCESS
) {
92 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
95 if (ret
!= LDB_SUCCESS
) {
100 if (res
->count
!= 1) {
101 /* we may be reading a DB that does not have the 'check base on search' option... */
102 ret
= LDB_ERR_NO_SUCH_OBJECT
;
103 ldb_asprintf_errstring(ldb_module_get_ctx(module
),
104 "dsdb_module_search_dn: did not find base dn %s (%d results)",
105 ldb_dn_get_linearized(basedn
), res
->count
);
107 *_res
= talloc_steal(mem_ctx
, res
);
109 talloc_free(tmp_ctx
);
113 int dsdb_module_search_tree(struct ldb_module
*module
,
115 struct ldb_result
**_res
,
116 struct ldb_dn
*basedn
,
117 enum ldb_scope scope
,
118 struct ldb_parse_tree
*tree
,
119 const char * const *attrs
,
121 struct ldb_request
*parent
)
124 struct ldb_request
*req
;
126 struct ldb_result
*res
;
128 tmp_ctx
= talloc_new(mem_ctx
);
130 /* cross-partitions searches with a basedn break multi-domain support */
131 SMB_ASSERT(basedn
== NULL
|| (dsdb_flags
& DSDB_SEARCH_SEARCH_ALL_PARTITIONS
) == 0);
133 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
135 talloc_free(tmp_ctx
);
136 return ldb_oom(ldb_module_get_ctx(module
));
139 ret
= ldb_build_search_req_ex(&req
, ldb_module_get_ctx(module
), tmp_ctx
,
146 ldb_search_default_callback
,
148 LDB_REQ_SET_LOCATION(req
);
149 if (ret
!= LDB_SUCCESS
) {
150 talloc_free(tmp_ctx
);
154 ret
= dsdb_request_add_controls(req
, dsdb_flags
);
155 if (ret
!= LDB_SUCCESS
) {
156 talloc_free(tmp_ctx
);
160 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
161 ldb_req_mark_trusted(req
);
164 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
165 ret
= ldb_next_request(module
, req
);
166 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
167 ret
= ldb_request(ldb_module_get_ctx(module
), req
);
169 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
170 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
171 ret
= ops
->search(module
, req
);
173 if (ret
== LDB_SUCCESS
) {
174 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
177 if (dsdb_flags
& DSDB_SEARCH_ONE_ONLY
) {
178 if (res
->count
== 0) {
179 talloc_free(tmp_ctx
);
180 ldb_reset_err_string(ldb_module_get_ctx(module
));
181 return LDB_ERR_NO_SUCH_OBJECT
;
183 if (res
->count
!= 1) {
184 talloc_free(tmp_ctx
);
185 ldb_reset_err_string(ldb_module_get_ctx(module
));
186 return LDB_ERR_CONSTRAINT_VIOLATION
;
191 if (ret
== LDB_SUCCESS
) {
192 *_res
= talloc_steal(mem_ctx
, res
);
194 talloc_free(tmp_ctx
);
199 search for attrs in the modules below
201 int dsdb_module_search(struct ldb_module
*module
,
203 struct ldb_result
**_res
,
204 struct ldb_dn
*basedn
, enum ldb_scope scope
,
205 const char * const *attrs
,
207 struct ldb_request
*parent
,
208 const char *format
, ...) _PRINTF_ATTRIBUTE(9, 10)
214 struct ldb_parse_tree
*tree
;
216 /* cross-partitions searches with a basedn break multi-domain support */
217 SMB_ASSERT(basedn
== NULL
|| (dsdb_flags
& DSDB_SEARCH_SEARCH_ALL_PARTITIONS
) == 0);
219 tmp_ctx
= talloc_new(mem_ctx
);
222 va_start(ap
, format
);
223 expression
= talloc_vasprintf(tmp_ctx
, format
, ap
);
227 talloc_free(tmp_ctx
);
228 return ldb_oom(ldb_module_get_ctx(module
));
234 tree
= ldb_parse_tree(tmp_ctx
, expression
);
236 talloc_free(tmp_ctx
);
237 ldb_set_errstring(ldb_module_get_ctx(module
),
238 "Unable to parse search expression");
239 return LDB_ERR_OPERATIONS_ERROR
;
242 ret
= dsdb_module_search_tree(module
,
252 talloc_free(tmp_ctx
);
257 find a DN given a GUID. This searches across all partitions
259 int dsdb_module_dn_by_guid(struct ldb_module
*module
, TALLOC_CTX
*mem_ctx
,
260 const struct GUID
*guid
, struct ldb_dn
**dn
,
261 struct ldb_request
*parent
)
263 struct ldb_result
*res
;
264 const char *attrs
[] = { NULL
};
265 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
268 ret
= dsdb_module_search(module
, tmp_ctx
, &res
, NULL
, LDB_SCOPE_SUBTREE
,
270 DSDB_FLAG_NEXT_MODULE
|
271 DSDB_SEARCH_SHOW_RECYCLED
|
272 DSDB_SEARCH_SEARCH_ALL_PARTITIONS
|
273 DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT
,
275 "objectGUID=%s", GUID_string(tmp_ctx
, guid
));
276 if (ret
!= LDB_SUCCESS
) {
277 talloc_free(tmp_ctx
);
280 if (res
->count
== 0) {
281 talloc_free(tmp_ctx
);
282 return LDB_ERR_NO_SUCH_OBJECT
;
284 if (res
->count
!= 1) {
285 ldb_asprintf_errstring(ldb_module_get_ctx(module
), "More than one object found matching objectGUID %s\n",
286 GUID_string(tmp_ctx
, guid
));
287 talloc_free(tmp_ctx
);
288 return LDB_ERR_OPERATIONS_ERROR
;
291 *dn
= talloc_steal(mem_ctx
, res
->msgs
[0]->dn
);
293 talloc_free(tmp_ctx
);
298 find a GUID given a DN.
300 int dsdb_module_guid_by_dn(struct ldb_module
*module
, struct ldb_dn
*dn
, struct GUID
*guid
,
301 struct ldb_request
*parent
)
303 const char *attrs
[] = { NULL
};
304 struct ldb_result
*res
;
305 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
309 ret
= dsdb_module_search_dn(module
, tmp_ctx
, &res
, dn
, attrs
,
310 DSDB_FLAG_NEXT_MODULE
|
311 DSDB_SEARCH_SHOW_RECYCLED
|
312 DSDB_SEARCH_SHOW_EXTENDED_DN
,
314 if (ret
!= LDB_SUCCESS
) {
315 ldb_asprintf_errstring(ldb_module_get_ctx(module
), "Failed to find GUID for %s",
316 ldb_dn_get_linearized(dn
));
317 talloc_free(tmp_ctx
);
321 status
= dsdb_get_extended_dn_guid(res
->msgs
[0]->dn
, guid
, "GUID");
322 if (!NT_STATUS_IS_OK(status
)) {
323 talloc_free(tmp_ctx
);
324 return ldb_operr(ldb_module_get_ctx(module
));
327 talloc_free(tmp_ctx
);
333 a ldb_extended request operating on modules below the
336 Note that this does not automatically start a transaction. If you
337 need a transaction the caller needs to start it as needed.
339 int dsdb_module_extended(struct ldb_module
*module
,
341 struct ldb_result
**_res
,
342 const char* oid
, void* data
,
344 struct ldb_request
*parent
)
346 struct ldb_request
*req
;
348 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
349 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
350 struct ldb_result
*res
;
356 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
358 talloc_free(tmp_ctx
);
359 return ldb_oom(ldb_module_get_ctx(module
));
362 ret
= ldb_build_extended_req(&req
, ldb
,
367 res
, ldb_extended_default_callback
,
370 LDB_REQ_SET_LOCATION(req
);
371 if (ret
!= LDB_SUCCESS
) {
372 talloc_free(tmp_ctx
);
376 ret
= dsdb_request_add_controls(req
, dsdb_flags
);
377 if (ret
!= LDB_SUCCESS
) {
378 talloc_free(tmp_ctx
);
382 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
383 ldb_req_mark_trusted(req
);
386 /* Run the new request */
387 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
388 ret
= ldb_next_request(module
, req
);
389 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
390 ret
= ldb_request(ldb_module_get_ctx(module
), req
);
392 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
393 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
394 ret
= ops
->extended(module
, req
);
396 if (ret
== LDB_SUCCESS
) {
397 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
400 if (_res
!= NULL
&& ret
== LDB_SUCCESS
) {
401 (*_res
) = talloc_steal(mem_ctx
, res
);
404 talloc_free(tmp_ctx
);
410 a ldb_modify request operating on modules below the
413 int dsdb_module_modify(struct ldb_module
*module
,
414 const struct ldb_message
*message
,
416 struct ldb_request
*parent
)
418 struct ldb_request
*mod_req
;
420 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
421 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
422 struct ldb_result
*res
;
424 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
426 talloc_free(tmp_ctx
);
427 return ldb_oom(ldb_module_get_ctx(module
));
430 ret
= ldb_build_mod_req(&mod_req
, ldb
, tmp_ctx
,
434 ldb_modify_default_callback
,
436 LDB_REQ_SET_LOCATION(mod_req
);
437 if (ret
!= LDB_SUCCESS
) {
438 talloc_free(tmp_ctx
);
442 ret
= dsdb_request_add_controls(mod_req
, dsdb_flags
);
443 if (ret
!= LDB_SUCCESS
) {
444 talloc_free(tmp_ctx
);
448 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
449 ldb_req_mark_trusted(mod_req
);
452 /* Run the new request */
453 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
454 ret
= ldb_next_request(module
, mod_req
);
455 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
456 ret
= ldb_request(ldb_module_get_ctx(module
), mod_req
);
458 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
459 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
460 ret
= ops
->modify(module
, mod_req
);
462 if (ret
== LDB_SUCCESS
) {
463 ret
= ldb_wait(mod_req
->handle
, LDB_WAIT_ALL
);
466 talloc_free(tmp_ctx
);
473 a ldb_rename request operating on modules below the
476 int dsdb_module_rename(struct ldb_module
*module
,
477 struct ldb_dn
*olddn
, struct ldb_dn
*newdn
,
479 struct ldb_request
*parent
)
481 struct ldb_request
*req
;
483 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
484 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
485 struct ldb_result
*res
;
487 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
489 talloc_free(tmp_ctx
);
490 return ldb_oom(ldb_module_get_ctx(module
));
493 ret
= ldb_build_rename_req(&req
, ldb
, tmp_ctx
,
498 ldb_modify_default_callback
,
500 LDB_REQ_SET_LOCATION(req
);
501 if (ret
!= LDB_SUCCESS
) {
502 talloc_free(tmp_ctx
);
506 ret
= dsdb_request_add_controls(req
, dsdb_flags
);
507 if (ret
!= LDB_SUCCESS
) {
508 talloc_free(tmp_ctx
);
512 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
513 ldb_req_mark_trusted(req
);
516 /* Run the new request */
517 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
518 ret
= ldb_next_request(module
, req
);
519 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
520 ret
= ldb_request(ldb_module_get_ctx(module
), req
);
522 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
523 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
524 ret
= ops
->rename(module
, req
);
526 if (ret
== LDB_SUCCESS
) {
527 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
530 talloc_free(tmp_ctx
);
535 a ldb_add request operating on modules below the
538 int dsdb_module_add(struct ldb_module
*module
,
539 const struct ldb_message
*message
,
541 struct ldb_request
*parent
)
543 struct ldb_request
*req
;
545 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
546 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
547 struct ldb_result
*res
;
549 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
551 talloc_free(tmp_ctx
);
552 return ldb_oom(ldb_module_get_ctx(module
));
555 ret
= ldb_build_add_req(&req
, ldb
, tmp_ctx
,
559 ldb_modify_default_callback
,
561 LDB_REQ_SET_LOCATION(req
);
562 if (ret
!= LDB_SUCCESS
) {
563 talloc_free(tmp_ctx
);
567 ret
= dsdb_request_add_controls(req
, dsdb_flags
);
568 if (ret
!= LDB_SUCCESS
) {
569 talloc_free(tmp_ctx
);
573 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
574 ldb_req_mark_trusted(req
);
577 /* Run the new request */
578 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
579 ret
= ldb_next_request(module
, req
);
580 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
581 ret
= ldb_request(ldb_module_get_ctx(module
), req
);
583 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
584 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
585 ret
= ops
->add(module
, req
);
587 if (ret
== LDB_SUCCESS
) {
588 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
591 talloc_free(tmp_ctx
);
596 a ldb_delete request operating on modules below the
599 int dsdb_module_del(struct ldb_module
*module
,
602 struct ldb_request
*parent
)
604 struct ldb_request
*req
;
606 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
607 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
608 struct ldb_result
*res
;
610 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
612 talloc_free(tmp_ctx
);
616 ret
= ldb_build_del_req(&req
, ldb
, tmp_ctx
,
620 ldb_modify_default_callback
,
622 LDB_REQ_SET_LOCATION(req
);
623 if (ret
!= LDB_SUCCESS
) {
624 talloc_free(tmp_ctx
);
628 ret
= dsdb_request_add_controls(req
, dsdb_flags
);
629 if (ret
!= LDB_SUCCESS
) {
630 talloc_free(tmp_ctx
);
634 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
635 ldb_req_mark_trusted(req
);
638 /* Run the new request */
639 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
640 ret
= ldb_next_request(module
, req
);
641 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
642 ret
= ldb_request(ldb_module_get_ctx(module
), req
);
644 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
645 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
646 ret
= ops
->del(module
, req
);
648 if (ret
== LDB_SUCCESS
) {
649 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
652 talloc_free(tmp_ctx
);
657 check if a single valued link has multiple non-deleted values
659 This is needed when we will be using the RELAX control to stop
660 ldb_tdb from checking single valued links
662 int dsdb_check_single_valued_link(const struct dsdb_attribute
*attr
,
663 const struct ldb_message_element
*el
)
665 bool found_active
= false;
668 if (!(attr
->ldb_schema_attribute
->flags
& LDB_ATTR_FLAG_SINGLE_VALUE
) ||
669 el
->num_values
< 2) {
673 for (i
=0; i
<el
->num_values
; i
++) {
674 if (!dsdb_dn_is_deleted_val(&el
->values
[i
])) {
676 return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
;
686 check if an optional feature is enabled on our own NTDS DN
688 Note that features can be marked as enabled in more than one
689 place. For example, the recyclebin feature is marked as enabled both
690 on the CN=Partitions,CN=Configurration object and on the NTDS DN of
691 each DC in the forest. It seems likely that it is the job of the KCC
692 to propogate between the two
694 int dsdb_check_optional_feature(struct ldb_module
*module
, struct GUID op_feature_guid
, bool *feature_enabled
)
697 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
698 struct ldb_result
*res
;
699 struct ldb_dn
*search_dn
;
700 struct GUID search_guid
;
701 const char *attrs
[] = {"msDS-EnabledFeature", NULL
};
704 struct ldb_message_element
*el
;
705 struct ldb_dn
*feature_dn
;
707 tmp_ctx
= talloc_new(ldb
);
709 feature_dn
= samdb_ntds_settings_dn(ldb_module_get_ctx(module
), tmp_ctx
);
710 if (feature_dn
== NULL
) {
711 talloc_free(tmp_ctx
);
712 return ldb_operr(ldb_module_get_ctx(module
));
715 *feature_enabled
= false;
717 ret
= dsdb_module_search_dn(module
, tmp_ctx
, &res
, feature_dn
, attrs
, DSDB_FLAG_NEXT_MODULE
, NULL
);
718 if (ret
!= LDB_SUCCESS
) {
719 ldb_asprintf_errstring(ldb
,
720 "Could not find the feature object - dn: %s\n",
721 ldb_dn_get_linearized(feature_dn
));
722 talloc_free(tmp_ctx
);
723 return LDB_ERR_OPERATIONS_ERROR
;
725 if (res
->msgs
[0]->num_elements
> 0) {
726 const char *attrs2
[] = {"msDS-OptionalFeatureGUID", NULL
};
728 el
= ldb_msg_find_element(res
->msgs
[0],"msDS-EnabledFeature");
730 for (i
=0; i
<el
->num_values
; i
++) {
731 search_dn
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, &el
->values
[i
]);
733 ret
= dsdb_module_search_dn(module
, tmp_ctx
, &res
,
734 search_dn
, attrs2
, DSDB_FLAG_NEXT_MODULE
, NULL
);
735 if (ret
!= LDB_SUCCESS
) {
736 ldb_asprintf_errstring(ldb
,
737 "Could no find object dn: %s\n",
738 ldb_dn_get_linearized(search_dn
));
739 talloc_free(tmp_ctx
);
740 return LDB_ERR_OPERATIONS_ERROR
;
743 search_guid
= samdb_result_guid(res
->msgs
[0], "msDS-OptionalFeatureGUID");
745 if (GUID_equal(&search_guid
, &op_feature_guid
)) {
746 *feature_enabled
= true;
751 talloc_free(tmp_ctx
);
756 find the NTDS GUID from a computers DN record
758 int dsdb_module_find_ntdsguid_for_computer(struct ldb_module
*module
,
760 struct ldb_dn
*computer_dn
,
761 struct GUID
*ntds_guid
,
762 struct ldb_request
*parent
)
767 *ntds_guid
= GUID_zero();
769 ret
= dsdb_module_reference_dn(module
, mem_ctx
, computer_dn
,
770 "serverReferenceBL", &dn
, parent
);
771 if (ret
!= LDB_SUCCESS
) {
775 if (!ldb_dn_add_child_fmt(dn
, "CN=NTDS Settings")) {
777 return LDB_ERR_OPERATIONS_ERROR
;
780 ret
= dsdb_module_guid_by_dn(module
, dn
, ntds_guid
, parent
);
786 find a 'reference' DN that points at another object
787 (eg. serverReference, rIDManagerReference etc)
789 int dsdb_module_reference_dn(struct ldb_module
*module
, TALLOC_CTX
*mem_ctx
, struct ldb_dn
*base
,
790 const char *attribute
, struct ldb_dn
**dn
, struct ldb_request
*parent
)
792 const char *attrs
[2];
793 struct ldb_result
*res
;
796 attrs
[0] = attribute
;
799 ret
= dsdb_module_search_dn(module
, mem_ctx
, &res
, base
, attrs
,
800 DSDB_FLAG_NEXT_MODULE
| DSDB_SEARCH_SHOW_EXTENDED_DN
, parent
);
801 if (ret
!= LDB_SUCCESS
) {
805 *dn
= ldb_msg_find_attr_as_dn(ldb_module_get_ctx(module
),
806 mem_ctx
, res
->msgs
[0], attribute
);
808 ldb_reset_err_string(ldb_module_get_ctx(module
));
810 return LDB_ERR_NO_SUCH_ATTRIBUTE
;
818 find the RID Manager$ DN via the rIDManagerReference attribute in the
821 int dsdb_module_rid_manager_dn(struct ldb_module
*module
, TALLOC_CTX
*mem_ctx
, struct ldb_dn
**dn
,
822 struct ldb_request
*parent
)
824 return dsdb_module_reference_dn(module
, mem_ctx
,
825 ldb_get_default_basedn(ldb_module_get_ctx(module
)),
826 "rIDManagerReference", dn
, parent
);
830 used to chain to the callers callback
832 int dsdb_next_callback(struct ldb_request
*req
, struct ldb_reply
*ares
)
834 struct ldb_request
*up_req
= talloc_get_type(req
->context
, struct ldb_request
);
836 talloc_steal(up_req
, req
);
837 return up_req
->callback(up_req
, ares
);
841 load the uSNHighest and the uSNUrgent attributes from the @REPLCHANGED
842 object for a partition
844 int dsdb_module_load_partition_usn(struct ldb_module
*module
, struct ldb_dn
*dn
,
845 uint64_t *uSN
, uint64_t *urgent_uSN
, struct ldb_request
*parent
)
847 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
848 struct ldb_request
*req
;
850 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
851 struct dsdb_control_current_partition
*p_ctrl
;
852 struct ldb_result
*res
;
854 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
856 talloc_free(tmp_ctx
);
857 return ldb_module_oom(module
);
860 ret
= ldb_build_search_req(&req
, ldb
, tmp_ctx
,
861 ldb_dn_new(tmp_ctx
, ldb
, "@REPLCHANGED"),
865 res
, ldb_search_default_callback
,
867 LDB_REQ_SET_LOCATION(req
);
868 if (ret
!= LDB_SUCCESS
) {
869 talloc_free(tmp_ctx
);
873 p_ctrl
= talloc(req
, struct dsdb_control_current_partition
);
874 if (p_ctrl
== NULL
) {
875 talloc_free(tmp_ctx
);
876 return ldb_module_oom(module
);
878 p_ctrl
->version
= DSDB_CONTROL_CURRENT_PARTITION_VERSION
;
882 ret
= ldb_request_add_control(req
,
883 DSDB_CONTROL_CURRENT_PARTITION_OID
,
885 if (ret
!= LDB_SUCCESS
) {
886 talloc_free(tmp_ctx
);
890 /* Run the new request */
891 ret
= ldb_next_request(module
, req
);
893 if (ret
== LDB_SUCCESS
) {
894 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
897 if (ret
== LDB_ERR_NO_SUCH_OBJECT
|| ret
== LDB_ERR_INVALID_DN_SYNTAX
) {
898 /* it hasn't been created yet, which means
899 an implicit value of zero */
901 talloc_free(tmp_ctx
);
902 ldb_reset_err_string(ldb
);
906 if (ret
!= LDB_SUCCESS
) {
907 talloc_free(tmp_ctx
);
911 if (res
->count
!= 1) {
917 *uSN
= ldb_msg_find_attr_as_uint64(res
->msgs
[0], "uSNHighest", 0);
919 *urgent_uSN
= ldb_msg_find_attr_as_uint64(res
->msgs
[0], "uSNUrgent", 0);
923 talloc_free(tmp_ctx
);
929 save uSNHighest and uSNUrgent attributes in the @REPLCHANGED object for a
932 int dsdb_module_save_partition_usn(struct ldb_module
*module
, struct ldb_dn
*dn
,
933 uint64_t uSN
, uint64_t urgent_uSN
,
934 struct ldb_request
*parent
)
936 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
937 struct ldb_request
*req
;
938 struct ldb_message
*msg
;
939 struct dsdb_control_current_partition
*p_ctrl
;
941 struct ldb_result
*res
;
943 msg
= ldb_msg_new(module
);
945 return ldb_module_oom(module
);
948 msg
->dn
= ldb_dn_new(msg
, ldb
, "@REPLCHANGED");
949 if (msg
->dn
== NULL
) {
951 return ldb_operr(ldb_module_get_ctx(module
));
954 res
= talloc_zero(msg
, struct ldb_result
);
957 return ldb_module_oom(module
);
960 ret
= samdb_msg_add_uint64(ldb
, msg
, msg
, "uSNHighest", uSN
);
961 if (ret
!= LDB_SUCCESS
) {
965 msg
->elements
[0].flags
= LDB_FLAG_MOD_REPLACE
;
967 /* urgent_uSN is optional so may not be stored */
969 ret
= samdb_msg_add_uint64(ldb
, msg
, msg
, "uSNUrgent",
971 if (ret
!= LDB_SUCCESS
) {
975 msg
->elements
[1].flags
= LDB_FLAG_MOD_REPLACE
;
979 p_ctrl
= talloc(msg
, struct dsdb_control_current_partition
);
980 if (p_ctrl
== NULL
) {
984 p_ctrl
->version
= DSDB_CONTROL_CURRENT_PARTITION_VERSION
;
986 ret
= ldb_build_mod_req(&req
, ldb
, msg
,
990 ldb_modify_default_callback
,
992 LDB_REQ_SET_LOCATION(req
);
994 if (ret
!= LDB_SUCCESS
) {
999 ret
= ldb_request_add_control(req
,
1000 DSDB_CONTROL_CURRENT_PARTITION_OID
,
1002 if (ret
!= LDB_SUCCESS
) {
1007 /* Run the new request */
1008 ret
= ldb_next_request(module
, req
);
1010 if (ret
== LDB_SUCCESS
) {
1011 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1013 if (ret
== LDB_ERR_NO_SUCH_OBJECT
) {
1014 ret
= ldb_build_add_req(&req
, ldb
, msg
,
1018 ldb_modify_default_callback
,
1020 LDB_REQ_SET_LOCATION(req
);
1029 bool dsdb_module_am_system(struct ldb_module
*module
)
1031 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
1032 struct auth_session_info
*session_info
1033 = talloc_get_type(ldb_get_opaque(ldb
, "sessionInfo"), struct auth_session_info
);
1034 return security_session_user_level(session_info
, NULL
) == SECURITY_SYSTEM
;
1037 bool dsdb_module_am_administrator(struct ldb_module
*module
)
1039 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
1040 struct auth_session_info
*session_info
1041 = talloc_get_type(ldb_get_opaque(ldb
, "sessionInfo"), struct auth_session_info
);
1042 return security_session_user_level(session_info
, NULL
) == SECURITY_ADMINISTRATOR
;
1046 check if the recyclebin is enabled
1048 int dsdb_recyclebin_enabled(struct ldb_module
*module
, bool *enabled
)
1050 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
1051 struct GUID recyclebin_guid
;
1054 GUID_from_string(DS_GUID_FEATURE_RECYCLE_BIN
, &recyclebin_guid
);
1056 ret
= dsdb_check_optional_feature(module
, recyclebin_guid
, enabled
);
1057 if (ret
!= LDB_SUCCESS
) {
1058 ldb_asprintf_errstring(ldb
, "Could not verify if Recycle Bin is enabled \n");
1059 return LDB_ERR_UNWILLING_TO_PERFORM
;
1065 int dsdb_msg_constrainted_update_int32(struct ldb_module
*module
,
1066 struct ldb_message
*msg
,
1068 const int32_t *old_val
,
1069 const int32_t *new_val
)
1071 struct ldb_message_element
*el
;
1076 ret
= ldb_msg_add_empty(msg
, attr
, LDB_FLAG_MOD_DELETE
, &el
);
1077 if (ret
!= LDB_SUCCESS
) {
1081 el
->values
= talloc_array(msg
, struct ldb_val
, el
->num_values
);
1083 return ldb_module_oom(module
);
1085 vstring
= talloc_asprintf(el
->values
, "%ld", (long)*old_val
);
1087 return ldb_module_oom(module
);
1089 *el
->values
= data_blob_string_const(vstring
);
1093 ret
= ldb_msg_add_empty(msg
, attr
, LDB_FLAG_MOD_ADD
, &el
);
1094 if (ret
!= LDB_SUCCESS
) {
1098 el
->values
= talloc_array(msg
, struct ldb_val
, el
->num_values
);
1100 return ldb_module_oom(module
);
1102 vstring
= talloc_asprintf(el
->values
, "%ld", (long)*new_val
);
1104 return ldb_module_oom(module
);
1106 *el
->values
= data_blob_string_const(vstring
);
1112 int dsdb_msg_constrainted_update_uint32(struct ldb_module
*module
,
1113 struct ldb_message
*msg
,
1115 const uint32_t *old_val
,
1116 const uint32_t *new_val
)
1118 return dsdb_msg_constrainted_update_int32(module
, msg
, attr
,
1119 (const int32_t *)old_val
,
1120 (const int32_t *)new_val
);
1123 int dsdb_msg_constrainted_update_int64(struct ldb_module
*module
,
1124 struct ldb_message
*msg
,
1126 const int64_t *old_val
,
1127 const int64_t *new_val
)
1129 struct ldb_message_element
*el
;
1134 ret
= ldb_msg_add_empty(msg
, attr
, LDB_FLAG_MOD_DELETE
, &el
);
1135 if (ret
!= LDB_SUCCESS
) {
1139 el
->values
= talloc_array(msg
, struct ldb_val
, el
->num_values
);
1141 return ldb_module_oom(module
);
1143 vstring
= talloc_asprintf(el
->values
, "%lld", (long long)*old_val
);
1145 return ldb_module_oom(module
);
1147 *el
->values
= data_blob_string_const(vstring
);
1151 ret
= ldb_msg_add_empty(msg
, attr
, LDB_FLAG_MOD_ADD
, &el
);
1152 if (ret
!= LDB_SUCCESS
) {
1156 el
->values
= talloc_array(msg
, struct ldb_val
, el
->num_values
);
1158 return ldb_module_oom(module
);
1160 vstring
= talloc_asprintf(el
->values
, "%lld", (long long)*new_val
);
1162 return ldb_module_oom(module
);
1164 *el
->values
= data_blob_string_const(vstring
);
1170 int dsdb_msg_constrainted_update_uint64(struct ldb_module
*module
,
1171 struct ldb_message
*msg
,
1173 const uint64_t *old_val
,
1174 const uint64_t *new_val
)
1176 return dsdb_msg_constrainted_update_int64(module
, msg
, attr
,
1177 (const int64_t *)old_val
,
1178 (const int64_t *)new_val
);
1182 update an int32 attribute safely via a constrained delete/add
1184 int dsdb_module_constrainted_update_int32(struct ldb_module
*module
,
1187 const int32_t *old_val
,
1188 const int32_t *new_val
,
1189 struct ldb_request
*parent
)
1191 struct ldb_message
*msg
;
1194 msg
= ldb_msg_new(module
);
1197 ret
= dsdb_msg_constrainted_update_int32(module
,
1201 if (ret
!= LDB_SUCCESS
) {
1206 ret
= dsdb_module_modify(module
, msg
, DSDB_FLAG_NEXT_MODULE
, parent
);
1211 int dsdb_module_constrainted_update_uint32(struct ldb_module
*module
,
1214 const uint32_t *old_val
,
1215 const uint32_t *new_val
,
1216 struct ldb_request
*parent
)
1218 return dsdb_module_constrainted_update_int32(module
, dn
, attr
,
1219 (const int32_t *)old_val
,
1220 (const int32_t *)new_val
, parent
);
1224 update an int64 attribute safely via a constrained delete/add
1226 int dsdb_module_constrainted_update_int64(struct ldb_module
*module
,
1229 const int64_t *old_val
,
1230 const int64_t *new_val
,
1231 struct ldb_request
*parent
)
1233 struct ldb_message
*msg
;
1236 msg
= ldb_msg_new(module
);
1239 ret
= dsdb_msg_constrainted_update_int64(module
,
1243 if (ret
!= LDB_SUCCESS
) {
1248 ret
= dsdb_module_modify(module
, msg
, DSDB_FLAG_NEXT_MODULE
, parent
);
1253 int dsdb_module_constrainted_update_uint64(struct ldb_module
*module
,
1256 const uint64_t *old_val
,
1257 const uint64_t *new_val
,
1258 struct ldb_request
*parent
)
1260 return dsdb_module_constrainted_update_int64(module
, dn
, attr
,
1261 (const int64_t *)old_val
,
1262 (const int64_t *)new_val
,
1267 const struct ldb_val
*dsdb_module_find_dsheuristics(struct ldb_module
*module
,
1268 TALLOC_CTX
*mem_ctx
, struct ldb_request
*parent
)
1271 struct ldb_dn
*new_dn
;
1272 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
1273 static const char *attrs
[] = { "dSHeuristics", NULL
};
1274 struct ldb_result
*res
;
1276 new_dn
= ldb_dn_copy(mem_ctx
, ldb_get_config_basedn(ldb
));
1277 if (!ldb_dn_add_child_fmt(new_dn
,
1278 "CN=Directory Service,CN=Windows NT,CN=Services")) {
1279 talloc_free(new_dn
);
1282 ret
= dsdb_module_search_dn(module
, mem_ctx
, &res
,
1285 DSDB_FLAG_NEXT_MODULE
,
1287 if (ret
== LDB_SUCCESS
&& res
->count
== 1) {
1288 talloc_free(new_dn
);
1289 return ldb_msg_find_ldb_val(res
->msgs
[0],
1292 talloc_free(new_dn
);
1296 bool dsdb_block_anonymous_ops(struct ldb_module
*module
, struct ldb_request
*parent
)
1298 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
1300 const struct ldb_val
*hr_val
= dsdb_module_find_dsheuristics(module
,
1302 if (hr_val
== NULL
|| hr_val
->length
< DS_HR_BLOCK_ANONYMOUS_OPS
) {
1304 } else if (hr_val
->data
[DS_HR_BLOCK_ANONYMOUS_OPS
-1] == '2') {
1310 talloc_free(tmp_ctx
);
1314 bool dsdb_user_password_support(struct ldb_module
*module
,
1315 TALLOC_CTX
*mem_ctx
,
1316 struct ldb_request
*parent
)
1318 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1320 const struct ldb_val
*hr_val
= dsdb_module_find_dsheuristics(module
,
1323 if (hr_val
== NULL
|| hr_val
->length
< DS_HR_USER_PASSWORD_SUPPORT
) {
1325 } else if ((hr_val
->data
[DS_HR_USER_PASSWORD_SUPPORT
-1] == '2') ||
1326 (hr_val
->data
[DS_HR_USER_PASSWORD_SUPPORT
-1] == '0')) {
1332 talloc_free(tmp_ctx
);
1337 show the chain of requests, useful for debugging async requests
1339 void dsdb_req_chain_debug(struct ldb_request
*req
, int level
)
1341 char *s
= ldb_module_call_chain(req
, req
);
1342 DEBUG(level
, ("%s\n", s
));
1347 * Gets back a single-valued attribute by the rules of the DSDB triggers when
1348 * performing a modify operation.
1350 * In order that the constraint checking by the "objectclass_attrs" LDB module
1351 * does work properly, the change request should remain similar or only be
1352 * enhanced (no other modifications as deletions, variations).
1354 struct ldb_message_element
*dsdb_get_single_valued_attr(const struct ldb_message
*msg
,
1355 const char *attr_name
,
1356 enum ldb_request_type operation
)
1358 struct ldb_message_element
*el
= NULL
;
1361 /* We've to walk over all modification entries and consider the last
1362 * non-delete one which belongs to "attr_name".
1364 * If "el" is NULL afterwards then that means there was no interesting
1366 for (i
= 0; i
< msg
->num_elements
; i
++) {
1367 if (ldb_attr_cmp(msg
->elements
[i
].name
, attr_name
) == 0) {
1368 if ((operation
== LDB_MODIFY
) &&
1369 (LDB_FLAG_MOD_TYPE(msg
->elements
[i
].flags
)
1370 == LDB_FLAG_MOD_DELETE
)) {
1373 el
= &msg
->elements
[i
];
1381 * This function determines the (last) structural or 88 object class of a passed
1382 * "objectClass" attribute - per MS-ADTS 3.1.1.1.4 this is the last value.
1383 * Without schema this does not work and hence NULL is returned.
1385 const struct dsdb_class
*dsdb_get_last_structural_class(const struct dsdb_schema
*schema
,
1386 const struct ldb_message_element
*element
)
1388 const struct dsdb_class
*last_class
;
1390 if (schema
== NULL
) {
1394 if (element
->num_values
== 0) {
1398 last_class
= dsdb_class_by_lDAPDisplayName_ldb_val(schema
,
1399 &element
->values
[element
->num_values
-1]);
1400 if (last_class
== NULL
) {
1403 if (last_class
->objectClassCategory
> 1) {
1410 const struct dsdb_class
*dsdb_get_structural_oc_from_msg(const struct dsdb_schema
*schema
,
1411 const struct ldb_message
*msg
)
1413 struct ldb_message_element
*oc_el
;
1415 oc_el
= ldb_msg_find_element(msg
, "objectClass");
1420 return dsdb_get_last_structural_class(schema
, oc_el
);
1423 /* Fix the DN so that the relative attribute names are in upper case so that the DN:
1424 cn=Adminstrator,cn=users,dc=samba,dc=example,dc=com becomes
1425 CN=Adminstrator,CN=users,DC=samba,DC=example,DC=com
1427 int dsdb_fix_dn_rdncase(struct ldb_context
*ldb
, struct ldb_dn
*dn
)
1430 char *upper_rdn_attr
;
1432 for (i
=0; i
< ldb_dn_get_comp_num(dn
); i
++) {
1433 /* We need the attribute name in upper case */
1434 upper_rdn_attr
= strupper_talloc(dn
,
1435 ldb_dn_get_component_name(dn
, i
));
1436 if (!upper_rdn_attr
) {
1437 return ldb_oom(ldb
);
1439 ret
= ldb_dn_set_component(dn
, i
, upper_rdn_attr
,
1440 *ldb_dn_get_component_val(dn
, i
));
1441 talloc_free(upper_rdn_attr
);
1442 if (ret
!= LDB_SUCCESS
) {
1450 * Make most specific objectCategory for the objectClass of passed object
1451 * NOTE: In this implementation we count that it is called on already
1452 * verified objectClass attribute value. See objectclass.c thorough
1453 * implementation for all the magic that involves
1455 * @param ldb ldb context
1456 * @param schema cached schema for ldb. We may get it, but it is very time consuming.
1457 * Hence leave the responsibility to the caller.
1458 * @param obj AD object to determint objectCategory for
1459 * @param mem_ctx Memory context - usually it is obj actually
1460 * @param pobjectcategory location to store found objectCategory
1462 * @return LDB_SUCCESS or error including out of memory error
1464 int dsdb_make_object_category(struct ldb_context
*ldb
, const struct dsdb_schema
*schema
,
1465 struct ldb_message
*obj
,
1466 TALLOC_CTX
*mem_ctx
, const char **pobjectcategory
)
1468 const struct dsdb_class
*objectclass
;
1469 struct ldb_message_element
*objectclass_element
;
1470 struct dsdb_extended_dn_store_format
*dn_format
;
1472 objectclass_element
= ldb_msg_find_element(obj
, "objectClass");
1473 if (!objectclass_element
) {
1474 ldb_asprintf_errstring(ldb
, "dsdb: Cannot add %s, no objectclass specified!",
1475 ldb_dn_get_linearized(obj
->dn
));
1476 return LDB_ERR_OBJECT_CLASS_VIOLATION
;
1478 if (objectclass_element
->num_values
== 0) {
1479 ldb_asprintf_errstring(ldb
, "dsdb: Cannot add %s, at least one (structural) objectclass has to be specified!",
1480 ldb_dn_get_linearized(obj
->dn
));
1481 return LDB_ERR_CONSTRAINT_VIOLATION
;
1485 * Get the new top-most structural object class and check for
1486 * unrelated structural classes
1488 objectclass
= dsdb_get_last_structural_class(schema
,
1489 objectclass_element
);
1490 if (objectclass
== NULL
) {
1491 ldb_asprintf_errstring(ldb
,
1492 "Failed to find a structural class for %s",
1493 ldb_dn_get_linearized(obj
->dn
));
1494 return LDB_ERR_UNWILLING_TO_PERFORM
;
1497 dn_format
= talloc_get_type(ldb_get_opaque(ldb
, DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME
),
1498 struct dsdb_extended_dn_store_format
);
1499 if (dn_format
&& dn_format
->store_extended_dn_in_ldb
== false) {
1500 /* Strip off extended components */
1501 struct ldb_dn
*dn
= ldb_dn_new(mem_ctx
, ldb
,
1502 objectclass
->defaultObjectCategory
);
1503 *pobjectcategory
= ldb_dn_alloc_linearized(mem_ctx
, dn
);
1506 *pobjectcategory
= talloc_strdup(mem_ctx
, objectclass
->defaultObjectCategory
);
1509 if (*pobjectcategory
== NULL
) {
1510 return ldb_oom(ldb
);