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 return ldb_error(ldb_module_get_ctx(module
), LDB_ERR_NO_SUCH_OBJECT
, __func__
);
182 if (res
->count
!= 1) {
183 talloc_free(tmp_ctx
);
184 ldb_reset_err_string(ldb_module_get_ctx(module
));
185 return LDB_ERR_CONSTRAINT_VIOLATION
;
190 if (ret
== LDB_SUCCESS
) {
191 *_res
= talloc_steal(mem_ctx
, res
);
193 talloc_free(tmp_ctx
);
198 search for attrs in the modules below
200 int dsdb_module_search(struct ldb_module
*module
,
202 struct ldb_result
**_res
,
203 struct ldb_dn
*basedn
, enum ldb_scope scope
,
204 const char * const *attrs
,
206 struct ldb_request
*parent
,
207 const char *format
, ...) _PRINTF_ATTRIBUTE(9, 10)
213 struct ldb_parse_tree
*tree
;
215 /* cross-partitions searches with a basedn break multi-domain support */
216 SMB_ASSERT(basedn
== NULL
|| (dsdb_flags
& DSDB_SEARCH_SEARCH_ALL_PARTITIONS
) == 0);
218 tmp_ctx
= talloc_new(mem_ctx
);
221 va_start(ap
, format
);
222 expression
= talloc_vasprintf(tmp_ctx
, format
, ap
);
226 talloc_free(tmp_ctx
);
227 return ldb_oom(ldb_module_get_ctx(module
));
233 tree
= ldb_parse_tree(tmp_ctx
, expression
);
235 talloc_free(tmp_ctx
);
236 ldb_set_errstring(ldb_module_get_ctx(module
),
237 "Unable to parse search expression");
238 return LDB_ERR_OPERATIONS_ERROR
;
241 ret
= dsdb_module_search_tree(module
,
251 talloc_free(tmp_ctx
);
256 find a DN given a GUID. This searches across all partitions
258 int dsdb_module_dn_by_guid(struct ldb_module
*module
, TALLOC_CTX
*mem_ctx
,
259 const struct GUID
*guid
, struct ldb_dn
**dn
,
260 struct ldb_request
*parent
)
262 struct ldb_result
*res
;
263 const char *attrs
[] = { NULL
};
264 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
267 ret
= dsdb_module_search(module
, tmp_ctx
, &res
, NULL
, LDB_SCOPE_SUBTREE
,
269 DSDB_FLAG_NEXT_MODULE
|
270 DSDB_SEARCH_SHOW_RECYCLED
|
271 DSDB_SEARCH_SEARCH_ALL_PARTITIONS
|
272 DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT
,
274 "objectGUID=%s", GUID_string(tmp_ctx
, guid
));
275 if (ret
!= LDB_SUCCESS
) {
276 talloc_free(tmp_ctx
);
279 if (res
->count
== 0) {
280 talloc_free(tmp_ctx
);
281 return ldb_error(ldb_module_get_ctx(module
), LDB_ERR_NO_SUCH_OBJECT
, __func__
);
283 if (res
->count
!= 1) {
284 ldb_asprintf_errstring(ldb_module_get_ctx(module
), "More than one object found matching objectGUID %s\n",
285 GUID_string(tmp_ctx
, guid
));
286 talloc_free(tmp_ctx
);
287 return LDB_ERR_OPERATIONS_ERROR
;
290 *dn
= talloc_steal(mem_ctx
, res
->msgs
[0]->dn
);
292 talloc_free(tmp_ctx
);
297 find a GUID given a DN.
299 int dsdb_module_guid_by_dn(struct ldb_module
*module
, struct ldb_dn
*dn
, struct GUID
*guid
,
300 struct ldb_request
*parent
)
302 const char *attrs
[] = { NULL
};
303 struct ldb_result
*res
;
304 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
308 ret
= dsdb_module_search_dn(module
, tmp_ctx
, &res
, dn
, attrs
,
309 DSDB_FLAG_NEXT_MODULE
|
310 DSDB_SEARCH_SHOW_RECYCLED
|
311 DSDB_SEARCH_SHOW_EXTENDED_DN
,
313 if (ret
!= LDB_SUCCESS
) {
314 ldb_asprintf_errstring(ldb_module_get_ctx(module
), "Failed to find GUID for %s",
315 ldb_dn_get_linearized(dn
));
316 talloc_free(tmp_ctx
);
320 status
= dsdb_get_extended_dn_guid(res
->msgs
[0]->dn
, guid
, "GUID");
321 if (!NT_STATUS_IS_OK(status
)) {
322 talloc_free(tmp_ctx
);
323 return ldb_operr(ldb_module_get_ctx(module
));
326 talloc_free(tmp_ctx
);
332 a ldb_extended request operating on modules below the
335 Note that this does not automatically start a transaction. If you
336 need a transaction the caller needs to start it as needed.
338 int dsdb_module_extended(struct ldb_module
*module
,
340 struct ldb_result
**_res
,
341 const char* oid
, void* data
,
343 struct ldb_request
*parent
)
345 struct ldb_request
*req
;
347 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
348 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
349 struct ldb_result
*res
;
355 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
357 talloc_free(tmp_ctx
);
358 return ldb_oom(ldb_module_get_ctx(module
));
361 ret
= ldb_build_extended_req(&req
, ldb
,
366 res
, ldb_extended_default_callback
,
369 LDB_REQ_SET_LOCATION(req
);
370 if (ret
!= LDB_SUCCESS
) {
371 talloc_free(tmp_ctx
);
375 ret
= dsdb_request_add_controls(req
, dsdb_flags
);
376 if (ret
!= LDB_SUCCESS
) {
377 talloc_free(tmp_ctx
);
381 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
382 ldb_req_mark_trusted(req
);
385 /* Run the new request */
386 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
387 ret
= ldb_next_request(module
, req
);
388 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
389 ret
= ldb_request(ldb_module_get_ctx(module
), req
);
391 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
392 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
393 ret
= ops
->extended(module
, req
);
395 if (ret
== LDB_SUCCESS
) {
396 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
399 if (_res
!= NULL
&& ret
== LDB_SUCCESS
) {
400 (*_res
) = talloc_steal(mem_ctx
, res
);
403 talloc_free(tmp_ctx
);
409 a ldb_modify request operating on modules below the
412 int dsdb_module_modify(struct ldb_module
*module
,
413 const struct ldb_message
*message
,
415 struct ldb_request
*parent
)
417 struct ldb_request
*mod_req
;
419 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
420 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
421 struct ldb_result
*res
;
423 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
425 talloc_free(tmp_ctx
);
426 return ldb_oom(ldb_module_get_ctx(module
));
429 ret
= ldb_build_mod_req(&mod_req
, ldb
, tmp_ctx
,
433 ldb_modify_default_callback
,
435 LDB_REQ_SET_LOCATION(mod_req
);
436 if (ret
!= LDB_SUCCESS
) {
437 talloc_free(tmp_ctx
);
441 ret
= dsdb_request_add_controls(mod_req
, dsdb_flags
);
442 if (ret
!= LDB_SUCCESS
) {
443 talloc_free(tmp_ctx
);
447 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
448 ldb_req_mark_trusted(mod_req
);
451 /* Run the new request */
452 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
453 ret
= ldb_next_request(module
, mod_req
);
454 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
455 ret
= ldb_request(ldb_module_get_ctx(module
), mod_req
);
457 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
458 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
459 ret
= ops
->modify(module
, mod_req
);
461 if (ret
== LDB_SUCCESS
) {
462 ret
= ldb_wait(mod_req
->handle
, LDB_WAIT_ALL
);
465 talloc_free(tmp_ctx
);
472 a ldb_rename request operating on modules below the
475 int dsdb_module_rename(struct ldb_module
*module
,
476 struct ldb_dn
*olddn
, struct ldb_dn
*newdn
,
478 struct ldb_request
*parent
)
480 struct ldb_request
*req
;
482 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
483 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
484 struct ldb_result
*res
;
486 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
488 talloc_free(tmp_ctx
);
489 return ldb_oom(ldb_module_get_ctx(module
));
492 ret
= ldb_build_rename_req(&req
, ldb
, tmp_ctx
,
497 ldb_modify_default_callback
,
499 LDB_REQ_SET_LOCATION(req
);
500 if (ret
!= LDB_SUCCESS
) {
501 talloc_free(tmp_ctx
);
505 ret
= dsdb_request_add_controls(req
, dsdb_flags
);
506 if (ret
!= LDB_SUCCESS
) {
507 talloc_free(tmp_ctx
);
511 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
512 ldb_req_mark_trusted(req
);
515 /* Run the new request */
516 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
517 ret
= ldb_next_request(module
, req
);
518 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
519 ret
= ldb_request(ldb_module_get_ctx(module
), req
);
521 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
522 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
523 ret
= ops
->rename(module
, req
);
525 if (ret
== LDB_SUCCESS
) {
526 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
529 talloc_free(tmp_ctx
);
534 a ldb_add request operating on modules below the
537 int dsdb_module_add(struct ldb_module
*module
,
538 const struct ldb_message
*message
,
540 struct ldb_request
*parent
)
542 struct ldb_request
*req
;
544 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
545 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
546 struct ldb_result
*res
;
548 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
550 talloc_free(tmp_ctx
);
551 return ldb_oom(ldb_module_get_ctx(module
));
554 ret
= ldb_build_add_req(&req
, ldb
, tmp_ctx
,
558 ldb_modify_default_callback
,
560 LDB_REQ_SET_LOCATION(req
);
561 if (ret
!= LDB_SUCCESS
) {
562 talloc_free(tmp_ctx
);
566 ret
= dsdb_request_add_controls(req
, dsdb_flags
);
567 if (ret
!= LDB_SUCCESS
) {
568 talloc_free(tmp_ctx
);
572 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
573 ldb_req_mark_trusted(req
);
576 /* Run the new request */
577 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
578 ret
= ldb_next_request(module
, req
);
579 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
580 ret
= ldb_request(ldb_module_get_ctx(module
), req
);
582 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
583 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
584 ret
= ops
->add(module
, req
);
586 if (ret
== LDB_SUCCESS
) {
587 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
590 talloc_free(tmp_ctx
);
595 a ldb_delete request operating on modules below the
598 int dsdb_module_del(struct ldb_module
*module
,
601 struct ldb_request
*parent
)
603 struct ldb_request
*req
;
605 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
606 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
607 struct ldb_result
*res
;
609 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
611 talloc_free(tmp_ctx
);
615 ret
= ldb_build_del_req(&req
, ldb
, tmp_ctx
,
619 ldb_modify_default_callback
,
621 LDB_REQ_SET_LOCATION(req
);
622 if (ret
!= LDB_SUCCESS
) {
623 talloc_free(tmp_ctx
);
627 ret
= dsdb_request_add_controls(req
, dsdb_flags
);
628 if (ret
!= LDB_SUCCESS
) {
629 talloc_free(tmp_ctx
);
633 if (dsdb_flags
& DSDB_FLAG_TRUSTED
) {
634 ldb_req_mark_trusted(req
);
637 /* Run the new request */
638 if (dsdb_flags
& DSDB_FLAG_NEXT_MODULE
) {
639 ret
= ldb_next_request(module
, req
);
640 } else if (dsdb_flags
& DSDB_FLAG_TOP_MODULE
) {
641 ret
= ldb_request(ldb_module_get_ctx(module
), req
);
643 const struct ldb_module_ops
*ops
= ldb_module_get_ops(module
);
644 SMB_ASSERT(dsdb_flags
& DSDB_FLAG_OWN_MODULE
);
645 ret
= ops
->del(module
, req
);
647 if (ret
== LDB_SUCCESS
) {
648 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
651 talloc_free(tmp_ctx
);
656 check if a single valued link has multiple non-deleted values
658 This is needed when we will be using the RELAX control to stop
659 ldb_tdb from checking single valued links
661 int dsdb_check_single_valued_link(const struct dsdb_attribute
*attr
,
662 const struct ldb_message_element
*el
)
664 bool found_active
= false;
667 if (!(attr
->ldb_schema_attribute
->flags
& LDB_ATTR_FLAG_SINGLE_VALUE
) ||
668 el
->num_values
< 2) {
672 for (i
=0; i
<el
->num_values
; i
++) {
673 if (!dsdb_dn_is_deleted_val(&el
->values
[i
])) {
675 return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS
;
685 check if an optional feature is enabled on our own NTDS DN
687 Note that features can be marked as enabled in more than one
688 place. For example, the recyclebin feature is marked as enabled both
689 on the CN=Partitions,CN=Configurration object and on the NTDS DN of
690 each DC in the forest. It seems likely that it is the job of the KCC
691 to propogate between the two
693 int dsdb_check_optional_feature(struct ldb_module
*module
, struct GUID op_feature_guid
, bool *feature_enabled
)
696 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
697 struct ldb_result
*res
;
698 struct ldb_dn
*search_dn
;
699 struct GUID search_guid
;
700 const char *attrs
[] = {"msDS-EnabledFeature", NULL
};
703 struct ldb_message_element
*el
;
704 struct ldb_dn
*feature_dn
;
706 tmp_ctx
= talloc_new(ldb
);
708 feature_dn
= samdb_ntds_settings_dn(ldb_module_get_ctx(module
), tmp_ctx
);
709 if (feature_dn
== NULL
) {
710 talloc_free(tmp_ctx
);
711 return ldb_operr(ldb_module_get_ctx(module
));
714 *feature_enabled
= false;
716 ret
= dsdb_module_search_dn(module
, tmp_ctx
, &res
, feature_dn
, attrs
, DSDB_FLAG_NEXT_MODULE
, NULL
);
717 if (ret
!= LDB_SUCCESS
) {
718 ldb_asprintf_errstring(ldb
,
719 "Could not find the feature object - dn: %s\n",
720 ldb_dn_get_linearized(feature_dn
));
721 talloc_free(tmp_ctx
);
722 return LDB_ERR_NO_SUCH_OBJECT
;
724 if (res
->msgs
[0]->num_elements
> 0) {
725 const char *attrs2
[] = {"msDS-OptionalFeatureGUID", NULL
};
727 el
= ldb_msg_find_element(res
->msgs
[0],"msDS-EnabledFeature");
729 for (i
=0; i
<el
->num_values
; i
++) {
730 search_dn
= ldb_dn_from_ldb_val(tmp_ctx
, ldb
, &el
->values
[i
]);
732 ret
= dsdb_module_search_dn(module
, tmp_ctx
, &res
,
733 search_dn
, attrs2
, DSDB_FLAG_NEXT_MODULE
, NULL
);
734 if (ret
!= LDB_SUCCESS
) {
735 ldb_asprintf_errstring(ldb
,
736 "Could no find object dn: %s\n",
737 ldb_dn_get_linearized(search_dn
));
738 talloc_free(tmp_ctx
);
739 return LDB_ERR_OPERATIONS_ERROR
;
742 search_guid
= samdb_result_guid(res
->msgs
[0], "msDS-OptionalFeatureGUID");
744 if (GUID_equal(&search_guid
, &op_feature_guid
)) {
745 *feature_enabled
= true;
750 talloc_free(tmp_ctx
);
755 find the NTDS GUID from a computers DN record
757 int dsdb_module_find_ntdsguid_for_computer(struct ldb_module
*module
,
759 struct ldb_dn
*computer_dn
,
760 struct GUID
*ntds_guid
,
761 struct ldb_request
*parent
)
766 *ntds_guid
= GUID_zero();
768 ret
= dsdb_module_reference_dn(module
, mem_ctx
, computer_dn
,
769 "serverReferenceBL", &dn
, parent
);
770 if (ret
!= LDB_SUCCESS
) {
774 if (!ldb_dn_add_child_fmt(dn
, "CN=NTDS Settings")) {
776 return LDB_ERR_OPERATIONS_ERROR
;
779 ret
= dsdb_module_guid_by_dn(module
, dn
, ntds_guid
, parent
);
785 find a 'reference' DN that points at another object
786 (eg. serverReference, rIDManagerReference etc)
788 int dsdb_module_reference_dn(struct ldb_module
*module
, TALLOC_CTX
*mem_ctx
, struct ldb_dn
*base
,
789 const char *attribute
, struct ldb_dn
**dn
, struct ldb_request
*parent
)
791 const char *attrs
[2];
792 struct ldb_result
*res
;
795 attrs
[0] = attribute
;
798 ret
= dsdb_module_search_dn(module
, mem_ctx
, &res
, base
, attrs
,
799 DSDB_FLAG_NEXT_MODULE
| DSDB_SEARCH_SHOW_EXTENDED_DN
, parent
);
800 if (ret
!= LDB_SUCCESS
) {
804 *dn
= ldb_msg_find_attr_as_dn(ldb_module_get_ctx(module
),
805 mem_ctx
, res
->msgs
[0], attribute
);
807 ldb_reset_err_string(ldb_module_get_ctx(module
));
809 return LDB_ERR_NO_SUCH_ATTRIBUTE
;
817 find the RID Manager$ DN via the rIDManagerReference attribute in the
820 int dsdb_module_rid_manager_dn(struct ldb_module
*module
, TALLOC_CTX
*mem_ctx
, struct ldb_dn
**dn
,
821 struct ldb_request
*parent
)
823 return dsdb_module_reference_dn(module
, mem_ctx
,
824 ldb_get_default_basedn(ldb_module_get_ctx(module
)),
825 "rIDManagerReference", dn
, parent
);
829 used to chain to the callers callback
831 int dsdb_next_callback(struct ldb_request
*req
, struct ldb_reply
*ares
)
833 struct ldb_request
*up_req
= talloc_get_type(req
->context
, struct ldb_request
);
835 talloc_steal(up_req
, req
);
836 return up_req
->callback(up_req
, ares
);
840 load the uSNHighest and the uSNUrgent attributes from the @REPLCHANGED
841 object for a partition
843 int dsdb_module_load_partition_usn(struct ldb_module
*module
, struct ldb_dn
*dn
,
844 uint64_t *uSN
, uint64_t *urgent_uSN
, struct ldb_request
*parent
)
846 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
847 struct ldb_request
*req
;
849 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
850 struct dsdb_control_current_partition
*p_ctrl
;
851 struct ldb_result
*res
;
853 res
= talloc_zero(tmp_ctx
, struct ldb_result
);
855 talloc_free(tmp_ctx
);
856 return ldb_module_oom(module
);
859 ret
= ldb_build_search_req(&req
, ldb
, tmp_ctx
,
860 ldb_dn_new(tmp_ctx
, ldb
, "@REPLCHANGED"),
864 res
, ldb_search_default_callback
,
866 LDB_REQ_SET_LOCATION(req
);
867 if (ret
!= LDB_SUCCESS
) {
868 talloc_free(tmp_ctx
);
872 p_ctrl
= talloc(req
, struct dsdb_control_current_partition
);
873 if (p_ctrl
== NULL
) {
874 talloc_free(tmp_ctx
);
875 return ldb_module_oom(module
);
877 p_ctrl
->version
= DSDB_CONTROL_CURRENT_PARTITION_VERSION
;
881 ret
= ldb_request_add_control(req
,
882 DSDB_CONTROL_CURRENT_PARTITION_OID
,
884 if (ret
!= LDB_SUCCESS
) {
885 talloc_free(tmp_ctx
);
889 /* Run the new request */
890 ret
= ldb_next_request(module
, req
);
892 if (ret
== LDB_SUCCESS
) {
893 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
896 if (ret
== LDB_ERR_NO_SUCH_OBJECT
|| ret
== LDB_ERR_INVALID_DN_SYNTAX
) {
897 /* it hasn't been created yet, which means
898 an implicit value of zero */
900 talloc_free(tmp_ctx
);
901 ldb_reset_err_string(ldb
);
905 if (ret
!= LDB_SUCCESS
) {
906 talloc_free(tmp_ctx
);
910 if (res
->count
!= 1) {
916 *uSN
= ldb_msg_find_attr_as_uint64(res
->msgs
[0], "uSNHighest", 0);
918 *urgent_uSN
= ldb_msg_find_attr_as_uint64(res
->msgs
[0], "uSNUrgent", 0);
922 talloc_free(tmp_ctx
);
928 save uSNHighest and uSNUrgent attributes in the @REPLCHANGED object for a
931 int dsdb_module_save_partition_usn(struct ldb_module
*module
, struct ldb_dn
*dn
,
932 uint64_t uSN
, uint64_t urgent_uSN
,
933 struct ldb_request
*parent
)
935 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
936 struct ldb_request
*req
;
937 struct ldb_message
*msg
;
938 struct dsdb_control_current_partition
*p_ctrl
;
940 struct ldb_result
*res
;
942 msg
= ldb_msg_new(module
);
944 return ldb_module_oom(module
);
947 msg
->dn
= ldb_dn_new(msg
, ldb
, "@REPLCHANGED");
948 if (msg
->dn
== NULL
) {
950 return ldb_operr(ldb_module_get_ctx(module
));
953 res
= talloc_zero(msg
, struct ldb_result
);
956 return ldb_module_oom(module
);
959 ret
= samdb_msg_add_uint64(ldb
, msg
, msg
, "uSNHighest", uSN
);
960 if (ret
!= LDB_SUCCESS
) {
964 msg
->elements
[0].flags
= LDB_FLAG_MOD_REPLACE
;
966 /* urgent_uSN is optional so may not be stored */
968 ret
= samdb_msg_add_uint64(ldb
, msg
, msg
, "uSNUrgent",
970 if (ret
!= LDB_SUCCESS
) {
974 msg
->elements
[1].flags
= LDB_FLAG_MOD_REPLACE
;
978 p_ctrl
= talloc(msg
, struct dsdb_control_current_partition
);
979 if (p_ctrl
== NULL
) {
983 p_ctrl
->version
= DSDB_CONTROL_CURRENT_PARTITION_VERSION
;
985 ret
= ldb_build_mod_req(&req
, ldb
, msg
,
989 ldb_modify_default_callback
,
991 LDB_REQ_SET_LOCATION(req
);
993 if (ret
!= LDB_SUCCESS
) {
998 ret
= ldb_request_add_control(req
,
999 DSDB_CONTROL_CURRENT_PARTITION_OID
,
1001 if (ret
!= LDB_SUCCESS
) {
1006 /* Run the new request */
1007 ret
= ldb_next_request(module
, req
);
1009 if (ret
== LDB_SUCCESS
) {
1010 ret
= ldb_wait(req
->handle
, LDB_WAIT_ALL
);
1012 if (ret
== LDB_ERR_NO_SUCH_OBJECT
) {
1013 ret
= ldb_build_add_req(&req
, ldb
, msg
,
1017 ldb_modify_default_callback
,
1019 LDB_REQ_SET_LOCATION(req
);
1028 bool dsdb_module_am_system(struct ldb_module
*module
)
1030 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
1031 struct auth_session_info
*session_info
1032 = talloc_get_type(ldb_get_opaque(ldb
, "sessionInfo"), struct auth_session_info
);
1033 return security_session_user_level(session_info
, NULL
) == SECURITY_SYSTEM
;
1036 bool dsdb_module_am_administrator(struct ldb_module
*module
)
1038 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
1039 struct auth_session_info
*session_info
1040 = talloc_get_type(ldb_get_opaque(ldb
, "sessionInfo"), struct auth_session_info
);
1041 return security_session_user_level(session_info
, NULL
) == SECURITY_ADMINISTRATOR
;
1045 check if the recyclebin is enabled
1047 int dsdb_recyclebin_enabled(struct ldb_module
*module
, bool *enabled
)
1049 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
1050 struct GUID recyclebin_guid
;
1053 GUID_from_string(DS_GUID_FEATURE_RECYCLE_BIN
, &recyclebin_guid
);
1055 ret
= dsdb_check_optional_feature(module
, recyclebin_guid
, enabled
);
1056 if (ret
!= LDB_SUCCESS
) {
1057 ldb_asprintf_errstring(ldb
, "Could not verify if Recycle Bin is enabled \n");
1064 int dsdb_msg_constrainted_update_int32(struct ldb_module
*module
,
1065 struct ldb_message
*msg
,
1067 const int32_t *old_val
,
1068 const int32_t *new_val
)
1070 struct ldb_message_element
*el
;
1075 ret
= ldb_msg_add_empty(msg
, attr
, LDB_FLAG_MOD_DELETE
, &el
);
1076 if (ret
!= LDB_SUCCESS
) {
1080 el
->values
= talloc_array(msg
, struct ldb_val
, el
->num_values
);
1082 return ldb_module_oom(module
);
1084 vstring
= talloc_asprintf(el
->values
, "%ld", (long)*old_val
);
1086 return ldb_module_oom(module
);
1088 *el
->values
= data_blob_string_const(vstring
);
1092 ret
= ldb_msg_add_empty(msg
, attr
, LDB_FLAG_MOD_ADD
, &el
);
1093 if (ret
!= LDB_SUCCESS
) {
1097 el
->values
= talloc_array(msg
, struct ldb_val
, el
->num_values
);
1099 return ldb_module_oom(module
);
1101 vstring
= talloc_asprintf(el
->values
, "%ld", (long)*new_val
);
1103 return ldb_module_oom(module
);
1105 *el
->values
= data_blob_string_const(vstring
);
1111 int dsdb_msg_constrainted_update_uint32(struct ldb_module
*module
,
1112 struct ldb_message
*msg
,
1114 const uint32_t *old_val
,
1115 const uint32_t *new_val
)
1117 return dsdb_msg_constrainted_update_int32(module
, msg
, attr
,
1118 (const int32_t *)old_val
,
1119 (const int32_t *)new_val
);
1122 int dsdb_msg_constrainted_update_int64(struct ldb_module
*module
,
1123 struct ldb_message
*msg
,
1125 const int64_t *old_val
,
1126 const int64_t *new_val
)
1128 struct ldb_message_element
*el
;
1133 ret
= ldb_msg_add_empty(msg
, attr
, LDB_FLAG_MOD_DELETE
, &el
);
1134 if (ret
!= LDB_SUCCESS
) {
1138 el
->values
= talloc_array(msg
, struct ldb_val
, el
->num_values
);
1140 return ldb_module_oom(module
);
1142 vstring
= talloc_asprintf(el
->values
, "%lld", (long long)*old_val
);
1144 return ldb_module_oom(module
);
1146 *el
->values
= data_blob_string_const(vstring
);
1150 ret
= ldb_msg_add_empty(msg
, attr
, LDB_FLAG_MOD_ADD
, &el
);
1151 if (ret
!= LDB_SUCCESS
) {
1155 el
->values
= talloc_array(msg
, struct ldb_val
, el
->num_values
);
1157 return ldb_module_oom(module
);
1159 vstring
= talloc_asprintf(el
->values
, "%lld", (long long)*new_val
);
1161 return ldb_module_oom(module
);
1163 *el
->values
= data_blob_string_const(vstring
);
1169 int dsdb_msg_constrainted_update_uint64(struct ldb_module
*module
,
1170 struct ldb_message
*msg
,
1172 const uint64_t *old_val
,
1173 const uint64_t *new_val
)
1175 return dsdb_msg_constrainted_update_int64(module
, msg
, attr
,
1176 (const int64_t *)old_val
,
1177 (const int64_t *)new_val
);
1181 update an int32 attribute safely via a constrained delete/add
1183 int dsdb_module_constrainted_update_int32(struct ldb_module
*module
,
1186 const int32_t *old_val
,
1187 const int32_t *new_val
,
1188 struct ldb_request
*parent
)
1190 struct ldb_message
*msg
;
1193 msg
= ldb_msg_new(module
);
1195 return ldb_module_oom(module
);
1199 ret
= dsdb_msg_constrainted_update_int32(module
,
1203 if (ret
!= LDB_SUCCESS
) {
1208 ret
= dsdb_module_modify(module
, msg
, DSDB_FLAG_NEXT_MODULE
, parent
);
1213 int dsdb_module_constrainted_update_uint32(struct ldb_module
*module
,
1216 const uint32_t *old_val
,
1217 const uint32_t *new_val
,
1218 struct ldb_request
*parent
)
1220 return dsdb_module_constrainted_update_int32(module
, dn
, attr
,
1221 (const int32_t *)old_val
,
1222 (const int32_t *)new_val
, parent
);
1226 update an int64 attribute safely via a constrained delete/add
1228 int dsdb_module_constrainted_update_int64(struct ldb_module
*module
,
1231 const int64_t *old_val
,
1232 const int64_t *new_val
,
1233 struct ldb_request
*parent
)
1235 struct ldb_message
*msg
;
1238 msg
= ldb_msg_new(module
);
1240 return ldb_module_oom(module
);
1244 ret
= dsdb_msg_constrainted_update_int64(module
,
1248 if (ret
!= LDB_SUCCESS
) {
1253 ret
= dsdb_module_modify(module
, msg
, DSDB_FLAG_NEXT_MODULE
, parent
);
1258 int dsdb_module_constrainted_update_uint64(struct ldb_module
*module
,
1261 const uint64_t *old_val
,
1262 const uint64_t *new_val
,
1263 struct ldb_request
*parent
)
1265 return dsdb_module_constrainted_update_int64(module
, dn
, attr
,
1266 (const int64_t *)old_val
,
1267 (const int64_t *)new_val
,
1272 const struct ldb_val
*dsdb_module_find_dsheuristics(struct ldb_module
*module
,
1273 TALLOC_CTX
*mem_ctx
, struct ldb_request
*parent
)
1276 struct ldb_dn
*new_dn
;
1277 struct ldb_context
*ldb
= ldb_module_get_ctx(module
);
1278 static const char *attrs
[] = { "dSHeuristics", NULL
};
1279 struct ldb_result
*res
;
1281 new_dn
= ldb_dn_copy(mem_ctx
, ldb_get_config_basedn(ldb
));
1282 if (!ldb_dn_add_child_fmt(new_dn
,
1283 "CN=Directory Service,CN=Windows NT,CN=Services")) {
1284 talloc_free(new_dn
);
1287 ret
= dsdb_module_search_dn(module
, mem_ctx
, &res
,
1290 DSDB_FLAG_NEXT_MODULE
,
1292 if (ret
== LDB_SUCCESS
&& res
->count
== 1) {
1293 talloc_free(new_dn
);
1294 return ldb_msg_find_ldb_val(res
->msgs
[0],
1297 talloc_free(new_dn
);
1301 bool dsdb_block_anonymous_ops(struct ldb_module
*module
, struct ldb_request
*parent
)
1303 TALLOC_CTX
*tmp_ctx
= talloc_new(module
);
1305 const struct ldb_val
*hr_val
= dsdb_module_find_dsheuristics(module
,
1307 if (hr_val
== NULL
|| hr_val
->length
< DS_HR_BLOCK_ANONYMOUS_OPS
) {
1309 } else if (hr_val
->data
[DS_HR_BLOCK_ANONYMOUS_OPS
-1] == '2') {
1315 talloc_free(tmp_ctx
);
1319 bool dsdb_user_password_support(struct ldb_module
*module
,
1320 TALLOC_CTX
*mem_ctx
,
1321 struct ldb_request
*parent
)
1323 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
1325 const struct ldb_val
*hr_val
= dsdb_module_find_dsheuristics(module
,
1328 if (hr_val
== NULL
|| hr_val
->length
< DS_HR_USER_PASSWORD_SUPPORT
) {
1330 } else if ((hr_val
->data
[DS_HR_USER_PASSWORD_SUPPORT
-1] == '2') ||
1331 (hr_val
->data
[DS_HR_USER_PASSWORD_SUPPORT
-1] == '0')) {
1337 talloc_free(tmp_ctx
);
1342 show the chain of requests, useful for debugging async requests
1344 void dsdb_req_chain_debug(struct ldb_request
*req
, int level
)
1346 char *s
= ldb_module_call_chain(req
, req
);
1347 DEBUG(level
, ("%s\n", s
));
1352 * Gets back a single-valued attribute by the rules of the DSDB triggers when
1353 * performing a modify operation.
1355 * In order that the constraint checking by the "objectclass_attrs" LDB module
1356 * does work properly, the change request should remain similar or only be
1357 * enhanced (no other modifications as deletions, variations).
1359 struct ldb_message_element
*dsdb_get_single_valued_attr(const struct ldb_message
*msg
,
1360 const char *attr_name
,
1361 enum ldb_request_type operation
)
1363 struct ldb_message_element
*el
= NULL
;
1366 /* We've to walk over all modification entries and consider the last
1367 * non-delete one which belongs to "attr_name".
1369 * If "el" is NULL afterwards then that means there was no interesting
1371 for (i
= 0; i
< msg
->num_elements
; i
++) {
1372 if (ldb_attr_cmp(msg
->elements
[i
].name
, attr_name
) == 0) {
1373 if ((operation
== LDB_MODIFY
) &&
1374 (LDB_FLAG_MOD_TYPE(msg
->elements
[i
].flags
)
1375 == LDB_FLAG_MOD_DELETE
)) {
1378 el
= &msg
->elements
[i
];
1386 * This function determines the (last) structural or 88 object class of a passed
1387 * "objectClass" attribute - per MS-ADTS 3.1.1.1.4 this is the last value.
1388 * Without schema this does not work and hence NULL is returned.
1390 const struct dsdb_class
*dsdb_get_last_structural_class(const struct dsdb_schema
*schema
,
1391 const struct ldb_message_element
*element
)
1393 const struct dsdb_class
*last_class
;
1395 if (schema
== NULL
) {
1399 if (element
->num_values
== 0) {
1403 last_class
= dsdb_class_by_lDAPDisplayName_ldb_val(schema
,
1404 &element
->values
[element
->num_values
-1]);
1405 if (last_class
== NULL
) {
1408 if (last_class
->objectClassCategory
> 1) {
1415 const struct dsdb_class
*dsdb_get_structural_oc_from_msg(const struct dsdb_schema
*schema
,
1416 const struct ldb_message
*msg
)
1418 struct ldb_message_element
*oc_el
;
1420 oc_el
= ldb_msg_find_element(msg
, "objectClass");
1425 return dsdb_get_last_structural_class(schema
, oc_el
);
1428 /* Fix the DN so that the relative attribute names are in upper case so that the DN:
1429 cn=Adminstrator,cn=users,dc=samba,dc=example,dc=com becomes
1430 CN=Adminstrator,CN=users,DC=samba,DC=example,DC=com
1432 int dsdb_fix_dn_rdncase(struct ldb_context
*ldb
, struct ldb_dn
*dn
)
1435 char *upper_rdn_attr
;
1437 for (i
=0; i
< ldb_dn_get_comp_num(dn
); i
++) {
1438 /* We need the attribute name in upper case */
1439 upper_rdn_attr
= strupper_talloc(dn
,
1440 ldb_dn_get_component_name(dn
, i
));
1441 if (!upper_rdn_attr
) {
1442 return ldb_oom(ldb
);
1444 ret
= ldb_dn_set_component(dn
, i
, upper_rdn_attr
,
1445 *ldb_dn_get_component_val(dn
, i
));
1446 talloc_free(upper_rdn_attr
);
1447 if (ret
!= LDB_SUCCESS
) {
1455 * Make most specific objectCategory for the objectClass of passed object
1456 * NOTE: In this implementation we count that it is called on already
1457 * verified objectClass attribute value. See objectclass.c thorough
1458 * implementation for all the magic that involves
1460 * @param ldb ldb context
1461 * @param schema cached schema for ldb. We may get it, but it is very time consuming.
1462 * Hence leave the responsibility to the caller.
1463 * @param obj AD object to determint objectCategory for
1464 * @param mem_ctx Memory context - usually it is obj actually
1465 * @param pobjectcategory location to store found objectCategory
1467 * @return LDB_SUCCESS or error including out of memory error
1469 int dsdb_make_object_category(struct ldb_context
*ldb
, const struct dsdb_schema
*schema
,
1470 const struct ldb_message
*obj
,
1471 TALLOC_CTX
*mem_ctx
, const char **pobjectcategory
)
1473 const struct dsdb_class
*objectclass
;
1474 struct ldb_message_element
*objectclass_element
;
1475 struct dsdb_extended_dn_store_format
*dn_format
;
1477 objectclass_element
= ldb_msg_find_element(obj
, "objectClass");
1478 if (!objectclass_element
) {
1479 ldb_asprintf_errstring(ldb
, "dsdb: Cannot add %s, no objectclass specified!",
1480 ldb_dn_get_linearized(obj
->dn
));
1481 return LDB_ERR_OBJECT_CLASS_VIOLATION
;
1483 if (objectclass_element
->num_values
== 0) {
1484 ldb_asprintf_errstring(ldb
, "dsdb: Cannot add %s, at least one (structural) objectclass has to be specified!",
1485 ldb_dn_get_linearized(obj
->dn
));
1486 return LDB_ERR_CONSTRAINT_VIOLATION
;
1490 * Get the new top-most structural object class and check for
1491 * unrelated structural classes
1493 objectclass
= dsdb_get_last_structural_class(schema
,
1494 objectclass_element
);
1495 if (objectclass
== NULL
) {
1496 ldb_asprintf_errstring(ldb
,
1497 "Failed to find a structural class for %s",
1498 ldb_dn_get_linearized(obj
->dn
));
1499 return LDB_ERR_UNWILLING_TO_PERFORM
;
1502 dn_format
= talloc_get_type(ldb_get_opaque(ldb
, DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME
),
1503 struct dsdb_extended_dn_store_format
);
1504 if (dn_format
&& dn_format
->store_extended_dn_in_ldb
== false) {
1505 /* Strip off extended components */
1506 struct ldb_dn
*dn
= ldb_dn_new(mem_ctx
, ldb
,
1507 objectclass
->defaultObjectCategory
);
1508 *pobjectcategory
= ldb_dn_alloc_linearized(mem_ctx
, dn
);
1511 *pobjectcategory
= talloc_strdup(mem_ctx
, objectclass
->defaultObjectCategory
);
1514 if (*pobjectcategory
== NULL
) {
1515 return ldb_oom(ldb
);