dsdb-descriptor: Avoid segfault copying an SD without an owner or group
[Samba/gebeck_regimport.git] / source4 / dsdb / samdb / ldb_modules / descriptor.c
blob7743baaaa5b8c94eb83a8dd2528d5060c99481b0
1 /*
2 ldb database library
4 Copyright (C) Simo Sorce 2006-2008
5 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2007
6 Copyright (C) Nadezhda Ivanova 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/>.
23 * Name: ldb
25 * Component: DS Security descriptor module
27 * Description:
28 * - Calculate the security descriptor of a newly created object
29 * - Perform sd recalculation on a move operation
30 * - Handle sd modification invariants
32 * Author: Nadezhda Ivanova
35 #include "includes.h"
36 #include <ldb_module.h>
37 #include "util/dlinklist.h"
38 #include "dsdb/samdb/samdb.h"
39 #include "librpc/ndr/libndr.h"
40 #include "librpc/gen_ndr/ndr_security.h"
41 #include "libcli/security/security.h"
42 #include "auth/auth.h"
43 #include "param/param.h"
44 #include "dsdb/samdb/ldb_modules/util.h"
45 #include "lib/util/binsearch.h"
47 struct descriptor_changes {
48 struct descriptor_changes *prev, *next;
49 struct descriptor_changes *children;
50 struct ldb_dn *nc_root;
51 struct ldb_dn *dn;
52 bool force_self;
53 bool force_children;
54 struct ldb_dn *stopped_dn;
57 struct descriptor_data {
58 TALLOC_CTX *trans_mem;
59 struct descriptor_changes *changes;
62 struct descriptor_context {
63 struct ldb_module *module;
64 struct ldb_request *req;
65 struct ldb_message *msg;
66 struct ldb_reply *search_res;
67 struct ldb_reply *search_oc_res;
68 struct ldb_val *parentsd_val;
69 struct ldb_message_element *sd_element;
70 struct ldb_val *sd_val;
71 uint32_t sd_flags;
72 int (*step_fn)(struct descriptor_context *);
75 static struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
76 struct ldb_dn *dn,
77 struct security_token *token,
78 struct ldb_context *ldb)
80 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
81 const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
82 struct dom_sid *da_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
83 struct dom_sid *ea_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
84 struct dom_sid *sa_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
85 struct dom_sid *dag_sid;
86 struct ldb_dn *nc_root;
87 int ret;
89 ret = dsdb_find_nc_root(ldb, tmp_ctx, dn, &nc_root);
90 if (ret != LDB_SUCCESS) {
91 talloc_free(tmp_ctx);
92 return NULL;
95 if (ldb_dn_compare(nc_root, ldb_get_schema_basedn(ldb)) == 0) {
96 if (security_token_has_sid(token, sa_sid)) {
97 dag_sid = dom_sid_dup(mem_ctx, sa_sid);
98 } else if (security_token_has_sid(token, ea_sid)) {
99 dag_sid = dom_sid_dup(mem_ctx, ea_sid);
100 } else if (security_token_has_sid(token, da_sid)) {
101 dag_sid = dom_sid_dup(mem_ctx, da_sid);
102 } else if (security_token_is_system(token)) {
103 dag_sid = dom_sid_dup(mem_ctx, sa_sid);
104 } else {
105 dag_sid = NULL;
107 } else if (ldb_dn_compare(nc_root, ldb_get_config_basedn(ldb)) == 0) {
108 if (security_token_has_sid(token, ea_sid)) {
109 dag_sid = dom_sid_dup(mem_ctx, ea_sid);
110 } else if (security_token_has_sid(token, da_sid)) {
111 dag_sid = dom_sid_dup(mem_ctx, da_sid);
112 } else if (security_token_is_system(token)) {
113 dag_sid = dom_sid_dup(mem_ctx, ea_sid);
114 } else {
115 dag_sid = NULL;
117 } else if (ldb_dn_compare(nc_root, ldb_get_default_basedn(ldb)) == 0) {
118 if (security_token_has_sid(token, da_sid)) {
119 dag_sid = dom_sid_dup(mem_ctx, da_sid);
120 } else if (security_token_has_sid(token, ea_sid)) {
121 dag_sid = dom_sid_dup(mem_ctx, ea_sid);
122 } else if (security_token_is_system(token)) {
123 dag_sid = dom_sid_dup(mem_ctx, da_sid);
124 } else {
125 dag_sid = NULL;
127 } else {
128 dag_sid = NULL;
131 talloc_free(tmp_ctx);
132 return dag_sid;
135 static struct security_descriptor *get_sd_unpacked(struct ldb_module *module, TALLOC_CTX *mem_ctx,
136 const struct dsdb_class *objectclass)
138 struct ldb_context *ldb = ldb_module_get_ctx(module);
139 struct security_descriptor *sd;
140 const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
142 if (!objectclass->defaultSecurityDescriptor || !domain_sid) {
143 return NULL;
146 sd = sddl_decode(mem_ctx,
147 objectclass->defaultSecurityDescriptor,
148 domain_sid);
149 return sd;
152 static struct dom_sid *get_default_group(TALLOC_CTX *mem_ctx,
153 struct ldb_context *ldb,
154 struct dom_sid *dag)
157 * This depends on the function level of the DC
158 * which is 2008R2 in our case. Which means it is
159 * higher than 2003 and we should use the
160 * "default administrator group" also as owning group.
162 * This matches dcpromo for a 2003 domain
163 * on a Windows 2008R2 DC.
165 return dag;
168 static struct security_descriptor *descr_handle_sd_flags(TALLOC_CTX *mem_ctx,
169 struct security_descriptor *new_sd,
170 struct security_descriptor *old_sd,
171 uint32_t sd_flags)
173 struct security_descriptor *final_sd;
174 /* if there is no control or control == 0 modify everything */
175 if (!sd_flags) {
176 return new_sd;
179 final_sd = talloc_zero(mem_ctx, struct security_descriptor);
180 final_sd->revision = SECURITY_DESCRIPTOR_REVISION_1;
181 final_sd->type = SEC_DESC_SELF_RELATIVE;
183 if (sd_flags & (SECINFO_OWNER)) {
184 if (new_sd->owner_sid) {
185 final_sd->owner_sid = talloc_memdup(mem_ctx, new_sd->owner_sid, sizeof(struct dom_sid));
187 final_sd->type |= new_sd->type & SEC_DESC_OWNER_DEFAULTED;
189 else if (old_sd) {
190 if (old_sd->owner_sid) {
191 final_sd->owner_sid = talloc_memdup(mem_ctx, old_sd->owner_sid, sizeof(struct dom_sid));
193 final_sd->type |= old_sd->type & SEC_DESC_OWNER_DEFAULTED;
196 if (sd_flags & (SECINFO_GROUP)) {
197 if (new_sd->group_sid) {
198 final_sd->group_sid = talloc_memdup(mem_ctx, new_sd->group_sid, sizeof(struct dom_sid));
200 final_sd->type |= new_sd->type & SEC_DESC_GROUP_DEFAULTED;
202 else if (old_sd) {
203 if (old_sd->group_sid) {
204 final_sd->group_sid = talloc_memdup(mem_ctx, old_sd->group_sid, sizeof(struct dom_sid));
206 final_sd->type |= old_sd->type & SEC_DESC_GROUP_DEFAULTED;
209 if (sd_flags & (SECINFO_SACL)) {
210 final_sd->sacl = security_acl_dup(mem_ctx,new_sd->sacl);
211 final_sd->type |= new_sd->type & (SEC_DESC_SACL_PRESENT |
212 SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
213 SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
214 SEC_DESC_SERVER_SECURITY);
216 else if (old_sd && old_sd->sacl) {
217 final_sd->sacl = security_acl_dup(mem_ctx,old_sd->sacl);
218 final_sd->type |= old_sd->type & (SEC_DESC_SACL_PRESENT |
219 SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
220 SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
221 SEC_DESC_SERVER_SECURITY);
224 if (sd_flags & (SECINFO_DACL)) {
225 final_sd->dacl = security_acl_dup(mem_ctx,new_sd->dacl);
226 final_sd->type |= new_sd->type & (SEC_DESC_DACL_PRESENT |
227 SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
228 SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
229 SEC_DESC_DACL_TRUSTED);
231 else if (old_sd && old_sd->dacl) {
232 final_sd->dacl = security_acl_dup(mem_ctx,old_sd->dacl);
233 final_sd->type |= old_sd->type & (SEC_DESC_DACL_PRESENT |
234 SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
235 SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
236 SEC_DESC_DACL_TRUSTED);
238 /* not so sure about this */
239 final_sd->type |= new_sd->type & SEC_DESC_RM_CONTROL_VALID;
240 return final_sd;
243 static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
244 struct ldb_dn *dn,
245 TALLOC_CTX *mem_ctx,
246 const struct dsdb_class *objectclass,
247 const struct ldb_val *parent,
248 const struct ldb_val *object,
249 const struct ldb_val *old_sd,
250 uint32_t sd_flags)
252 struct security_descriptor *user_descriptor = NULL, *parent_descriptor = NULL;
253 struct security_descriptor *old_descriptor = NULL;
254 struct security_descriptor *new_sd, *final_sd;
255 DATA_BLOB *linear_sd;
256 enum ndr_err_code ndr_err;
257 struct ldb_context *ldb = ldb_module_get_ctx(module);
258 struct auth_session_info *session_info
259 = ldb_get_opaque(ldb, "sessionInfo");
260 const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
261 char *sddl_sd;
262 struct dom_sid *default_owner;
263 struct dom_sid *default_group;
264 struct security_descriptor *default_descriptor = NULL;
265 struct GUID *object_list = NULL;
267 if (objectclass != NULL) {
268 default_descriptor = get_sd_unpacked(module, mem_ctx, objectclass);
269 object_list = talloc_zero_array(mem_ctx, struct GUID, 2);
270 if (object_list == NULL) {
271 return NULL;
273 object_list[0] = objectclass->schemaIDGUID;
276 if (object) {
277 user_descriptor = talloc(mem_ctx, struct security_descriptor);
278 if (!user_descriptor) {
279 return NULL;
281 ndr_err = ndr_pull_struct_blob(object, user_descriptor,
282 user_descriptor,
283 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
285 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
286 talloc_free(user_descriptor);
287 return NULL;
289 } else {
290 user_descriptor = default_descriptor;
293 if (old_sd) {
294 old_descriptor = talloc(mem_ctx, struct security_descriptor);
295 if (!old_descriptor) {
296 return NULL;
298 ndr_err = ndr_pull_struct_blob(old_sd, old_descriptor,
299 old_descriptor,
300 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
302 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
303 talloc_free(old_descriptor);
304 return NULL;
308 if (parent) {
309 parent_descriptor = talloc(mem_ctx, struct security_descriptor);
310 if (!parent_descriptor) {
311 return NULL;
313 ndr_err = ndr_pull_struct_blob(parent, parent_descriptor,
314 parent_descriptor,
315 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
317 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
318 talloc_free(parent_descriptor);
319 return NULL;
323 if (user_descriptor && default_descriptor &&
324 (user_descriptor->dacl == NULL))
326 user_descriptor->dacl = default_descriptor->dacl;
327 user_descriptor->type |= default_descriptor->type & (
328 SEC_DESC_DACL_PRESENT |
329 SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
330 SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
331 SEC_DESC_DACL_TRUSTED);
334 if (user_descriptor && default_descriptor &&
335 (user_descriptor->sacl == NULL))
337 user_descriptor->sacl = default_descriptor->sacl;
338 user_descriptor->type |= default_descriptor->type & (
339 SEC_DESC_SACL_PRESENT |
340 SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
341 SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
342 SEC_DESC_SERVER_SECURITY);
346 if (!(sd_flags & SECINFO_OWNER) && user_descriptor) {
347 user_descriptor->owner_sid = NULL;
350 * We need the correct owner sid
351 * when calculating the DACL or SACL
353 if (old_descriptor) {
354 user_descriptor->owner_sid = old_descriptor->owner_sid;
357 if (!(sd_flags & SECINFO_GROUP) && user_descriptor) {
358 user_descriptor->group_sid = NULL;
361 * We need the correct group sid
362 * when calculating the DACL or SACL
364 if (old_descriptor) {
365 user_descriptor->group_sid = old_descriptor->group_sid;
368 if (!(sd_flags & SECINFO_DACL) && user_descriptor) {
369 user_descriptor->dacl = NULL;
372 * We add SEC_DESC_DACL_PROTECTED so that
373 * create_security_descriptor() skips
374 * the unused inheritance calculation
376 user_descriptor->type |= SEC_DESC_DACL_PROTECTED;
378 if (!(sd_flags & SECINFO_SACL) && user_descriptor) {
379 user_descriptor->sacl = NULL;
382 * We add SEC_DESC_SACL_PROTECTED so that
383 * create_security_descriptor() skips
384 * the unused inheritance calculation
386 user_descriptor->type |= SEC_DESC_SACL_PROTECTED;
389 default_owner = get_default_ag(mem_ctx, dn,
390 session_info->security_token, ldb);
391 default_group = get_default_group(mem_ctx, ldb, default_owner);
392 new_sd = create_security_descriptor(mem_ctx,
393 parent_descriptor,
394 user_descriptor,
395 true,
396 object_list,
397 SEC_DACL_AUTO_INHERIT |
398 SEC_SACL_AUTO_INHERIT,
399 session_info->security_token,
400 default_owner, default_group,
401 map_generic_rights_ds);
402 if (!new_sd) {
403 return NULL;
405 final_sd = descr_handle_sd_flags(mem_ctx, new_sd, old_descriptor, sd_flags);
407 if (!final_sd) {
408 return NULL;
411 if (final_sd->dacl) {
412 final_sd->dacl->revision = SECURITY_ACL_REVISION_ADS;
414 if (final_sd->sacl) {
415 final_sd->sacl->revision = SECURITY_ACL_REVISION_ADS;
418 sddl_sd = sddl_encode(mem_ctx, final_sd, domain_sid);
419 DEBUG(10, ("Object %s created with desriptor %s\n\n", ldb_dn_get_linearized(dn), sddl_sd));
421 linear_sd = talloc(mem_ctx, DATA_BLOB);
422 if (!linear_sd) {
423 return NULL;
426 ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
427 final_sd,
428 (ndr_push_flags_fn_t)ndr_push_security_descriptor);
429 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
430 return NULL;
433 return linear_sd;
436 static DATA_BLOB *descr_get_descriptor_to_show(struct ldb_module *module,
437 TALLOC_CTX *mem_ctx,
438 struct ldb_val *sd,
439 uint32_t sd_flags)
441 struct security_descriptor *old_sd, *final_sd;
442 DATA_BLOB *linear_sd;
443 enum ndr_err_code ndr_err;
445 old_sd = talloc(mem_ctx, struct security_descriptor);
446 if (!old_sd) {
447 return NULL;
449 ndr_err = ndr_pull_struct_blob(sd, old_sd,
450 old_sd,
451 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
453 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
454 talloc_free(old_sd);
455 return NULL;
458 final_sd = descr_handle_sd_flags(mem_ctx, old_sd, NULL, sd_flags);
460 if (!final_sd) {
461 return NULL;
464 linear_sd = talloc(mem_ctx, DATA_BLOB);
465 if (!linear_sd) {
466 return NULL;
469 ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
470 final_sd,
471 (ndr_push_flags_fn_t)ndr_push_security_descriptor);
472 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
473 return NULL;
476 return linear_sd;
479 static struct descriptor_context *descriptor_init_context(struct ldb_module *module,
480 struct ldb_request *req)
482 struct ldb_context *ldb;
483 struct descriptor_context *ac;
485 ldb = ldb_module_get_ctx(module);
487 ac = talloc_zero(req, struct descriptor_context);
488 if (ac == NULL) {
489 ldb_set_errstring(ldb, "Out of Memory");
490 return NULL;
493 ac->module = module;
494 ac->req = req;
495 return ac;
498 static int descriptor_search_callback(struct ldb_request *req, struct ldb_reply *ares)
500 struct descriptor_context *ac;
501 struct ldb_val *sd_val = NULL;
502 struct ldb_message_element *sd_el;
503 DATA_BLOB *show_sd;
504 int ret;
506 ac = talloc_get_type(req->context, struct descriptor_context);
508 if (!ares) {
509 ret = LDB_ERR_OPERATIONS_ERROR;
510 goto fail;
512 if (ares->error != LDB_SUCCESS) {
513 return ldb_module_done(ac->req, ares->controls,
514 ares->response, ares->error);
517 switch (ares->type) {
518 case LDB_REPLY_ENTRY:
519 sd_el = ldb_msg_find_element(ares->message, "nTSecurityDescriptor");
520 if (sd_el) {
521 sd_val = sd_el->values;
524 if (sd_val) {
525 show_sd = descr_get_descriptor_to_show(ac->module, ac->req,
526 sd_val, ac->sd_flags);
527 if (!show_sd) {
528 ret = LDB_ERR_OPERATIONS_ERROR;
529 goto fail;
531 ldb_msg_remove_attr(ares->message, "nTSecurityDescriptor");
532 ret = ldb_msg_add_steal_value(ares->message, "nTSecurityDescriptor", show_sd);
533 if (ret != LDB_SUCCESS) {
534 goto fail;
537 return ldb_module_send_entry(ac->req, ares->message, ares->controls);
539 case LDB_REPLY_REFERRAL:
540 return ldb_module_send_referral(ac->req, ares->referral);
542 case LDB_REPLY_DONE:
543 return ldb_module_done(ac->req, ares->controls,
544 ares->response, ares->error);
547 fail:
548 talloc_free(ares);
549 return ldb_module_done(ac->req, NULL, NULL, ret);
552 static int descriptor_add(struct ldb_module *module, struct ldb_request *req)
554 struct ldb_context *ldb = ldb_module_get_ctx(module);
555 struct ldb_request *add_req;
556 struct ldb_message *msg;
557 struct ldb_result *parent_res;
558 const struct ldb_val *parent_sd = NULL;
559 const struct ldb_val *user_sd;
560 struct ldb_dn *dn = req->op.add.message->dn;
561 struct ldb_dn *parent_dn, *nc_root;
562 struct ldb_message_element *objectclass_element, *sd_element;
563 int ret;
564 const struct dsdb_schema *schema;
565 DATA_BLOB *sd;
566 const struct dsdb_class *objectclass;
567 static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
568 uint32_t instanceType;
569 bool isNC = false;
570 uint32_t sd_flags = dsdb_request_sd_flags(req, NULL);
572 /* do not manipulate our control entries */
573 if (ldb_dn_is_special(dn)) {
574 return ldb_next_request(module, req);
577 user_sd = ldb_msg_find_ldb_val(req->op.add.message, "nTSecurityDescriptor");
578 sd_element = ldb_msg_find_element(req->op.add.message, "nTSecurityDescriptor");
579 /* nTSecurityDescriptor without a value is an error, letting through so it is handled */
580 if (user_sd == NULL && sd_element) {
581 return ldb_next_request(module, req);
584 ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: %s\n", ldb_dn_get_linearized(dn));
586 instanceType = ldb_msg_find_attr_as_uint(req->op.add.message, "instanceType", 0);
588 if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) {
589 isNC = true;
592 if (!isNC) {
593 ret = dsdb_find_nc_root(ldb, req, dn, &nc_root);
594 if (ret != LDB_SUCCESS) {
595 ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find NC root for %s\n",
596 ldb_dn_get_linearized(dn));
597 return ret;
600 if (ldb_dn_compare(dn, nc_root) == 0) {
601 DEBUG(0, ("Found DN %s being a NC by the old method\n", ldb_dn_get_linearized(dn)));
602 isNC = true;
606 if (isNC) {
607 DEBUG(2, ("DN: %s is a NC\n", ldb_dn_get_linearized(dn)));
609 if (!isNC) {
610 /* if the object has a parent, retrieve its SD to
611 * use for calculation. Unfortunately we do not yet have
612 * instanceType, so we use dsdb_find_nc_root. */
614 parent_dn = ldb_dn_get_parent(req, dn);
615 if (parent_dn == NULL) {
616 return ldb_oom(ldb);
619 /* we aren't any NC */
620 ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn,
621 parent_attrs,
622 DSDB_FLAG_NEXT_MODULE |
623 DSDB_FLAG_AS_SYSTEM |
624 DSDB_SEARCH_SHOW_RECYCLED,
625 req);
626 if (ret != LDB_SUCCESS) {
627 ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find SD for %s\n",
628 ldb_dn_get_linearized(parent_dn));
629 return ret;
631 if (parent_res->count != 1) {
632 return ldb_operr(ldb);
634 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
637 schema = dsdb_get_schema(ldb, req);
639 objectclass_element = ldb_msg_find_element(req->op.add.message, "objectClass");
640 if (objectclass_element == NULL) {
641 return ldb_operr(ldb);
644 objectclass = dsdb_get_last_structural_class(schema,
645 objectclass_element);
646 if (objectclass == NULL) {
647 return ldb_operr(ldb);
651 * The SD_FLAG control is ignored on add
652 * and we default to all bits set.
654 sd_flags = SECINFO_OWNER|SECINFO_GROUP|SECINFO_SACL|SECINFO_DACL;
656 sd = get_new_descriptor(module, dn, req,
657 objectclass, parent_sd,
658 user_sd, NULL, sd_flags);
659 if (sd == NULL) {
660 return ldb_operr(ldb);
662 msg = ldb_msg_copy_shallow(req, req->op.add.message);
663 if (msg == NULL) {
664 return ldb_oom(ldb);
666 if (sd_element != NULL) {
667 sd_element->values[0] = *sd;
668 } else {
669 ret = ldb_msg_add_steal_value(msg,
670 "nTSecurityDescriptor",
671 sd);
672 if (ret != LDB_SUCCESS) {
673 return ret;
677 ret = ldb_build_add_req(&add_req, ldb, req,
678 msg,
679 req->controls,
680 req, dsdb_next_callback,
681 req);
682 LDB_REQ_SET_LOCATION(add_req);
683 if (ret != LDB_SUCCESS) {
684 return ldb_error(ldb, ret,
685 "descriptor_add: Error creating new add request.");
688 return ldb_next_request(module, add_req);
691 static int descriptor_modify(struct ldb_module *module, struct ldb_request *req)
693 struct ldb_context *ldb = ldb_module_get_ctx(module);
694 struct ldb_request *mod_req;
695 struct ldb_message *msg;
696 struct ldb_result *current_res, *parent_res;
697 const struct ldb_val *old_sd = NULL;
698 const struct ldb_val *parent_sd = NULL;
699 const struct ldb_val *user_sd;
700 struct ldb_dn *dn = req->op.mod.message->dn;
701 struct ldb_dn *parent_dn;
702 struct ldb_message_element *objectclass_element, *sd_element;
703 int ret;
704 uint32_t instanceType;
705 bool explicit_sd_flags = false;
706 uint32_t sd_flags = dsdb_request_sd_flags(req, &explicit_sd_flags);
707 const struct dsdb_schema *schema;
708 DATA_BLOB *sd;
709 const struct dsdb_class *objectclass;
710 static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
711 static const char * const current_attrs[] = { "nTSecurityDescriptor",
712 "instanceType",
713 "objectClass", NULL };
714 struct ldb_control *sd_propagation_control;
715 int cmp_ret = -1;
717 /* do not manipulate our control entries */
718 if (ldb_dn_is_special(dn)) {
719 return ldb_next_request(module, req);
722 sd_propagation_control = ldb_request_get_control(req,
723 DSDB_CONTROL_SEC_DESC_PROPAGATION_OID);
724 if (sd_propagation_control != NULL) {
725 if (sd_propagation_control->data != module) {
726 return ldb_operr(ldb);
728 if (req->op.mod.message->num_elements != 0) {
729 return ldb_operr(ldb);
731 if (explicit_sd_flags) {
732 return ldb_operr(ldb);
734 if (sd_flags != 0xF) {
735 return ldb_operr(ldb);
737 if (sd_propagation_control->critical == 0) {
738 return ldb_operr(ldb);
741 sd_propagation_control->critical = 0;
744 sd_element = ldb_msg_find_element(req->op.mod.message, "nTSecurityDescriptor");
745 if (sd_propagation_control == NULL && sd_element == NULL) {
746 return ldb_next_request(module, req);
750 * nTSecurityDescriptor with DELETE is not supported yet.
751 * TODO: handle this correctly.
753 if (sd_propagation_control == NULL &&
754 LDB_FLAG_MOD_TYPE(sd_element->flags) == LDB_FLAG_MOD_DELETE)
756 return ldb_module_error(module,
757 LDB_ERR_UNWILLING_TO_PERFORM,
758 "MOD_DELETE for nTSecurityDescriptor "
759 "not supported yet");
762 user_sd = ldb_msg_find_ldb_val(req->op.mod.message, "nTSecurityDescriptor");
763 /* nTSecurityDescriptor without a value is an error, letting through so it is handled */
764 if (sd_propagation_control == NULL && user_sd == NULL) {
765 return ldb_next_request(module, req);
768 ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_modify: %s\n", ldb_dn_get_linearized(dn));
770 ret = dsdb_module_search_dn(module, req, &current_res, dn,
771 current_attrs,
772 DSDB_FLAG_NEXT_MODULE |
773 DSDB_FLAG_AS_SYSTEM |
774 DSDB_SEARCH_SHOW_RECYCLED,
775 req);
776 if (ret != LDB_SUCCESS) {
777 ldb_debug(ldb, LDB_DEBUG_ERROR,"descriptor_modify: Could not find %s\n",
778 ldb_dn_get_linearized(dn));
779 return ret;
782 instanceType = ldb_msg_find_attr_as_uint(current_res->msgs[0],
783 "instanceType", 0);
784 /* if the object has a parent, retrieve its SD to
785 * use for calculation */
786 if (!ldb_dn_is_null(current_res->msgs[0]->dn) &&
787 !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
788 parent_dn = ldb_dn_get_parent(req, dn);
789 if (parent_dn == NULL) {
790 return ldb_oom(ldb);
792 ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn,
793 parent_attrs,
794 DSDB_FLAG_NEXT_MODULE |
795 DSDB_FLAG_AS_SYSTEM |
796 DSDB_SEARCH_SHOW_RECYCLED,
797 req);
798 if (ret != LDB_SUCCESS) {
799 ldb_debug(ldb, LDB_DEBUG_ERROR, "descriptor_modify: Could not find SD for %s\n",
800 ldb_dn_get_linearized(parent_dn));
801 return ret;
803 if (parent_res->count != 1) {
804 return ldb_operr(ldb);
806 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
809 schema = dsdb_get_schema(ldb, req);
811 objectclass_element = ldb_msg_find_element(current_res->msgs[0], "objectClass");
812 if (objectclass_element == NULL) {
813 return ldb_operr(ldb);
816 objectclass = dsdb_get_last_structural_class(schema,
817 objectclass_element);
818 if (objectclass == NULL) {
819 return ldb_operr(ldb);
822 old_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor");
823 if (old_sd == NULL) {
824 return ldb_operr(ldb);
827 if (sd_propagation_control != NULL) {
829 * This just triggers a recalculation of the
830 * inherited aces.
832 user_sd = old_sd;
835 sd = get_new_descriptor(module, dn, req,
836 objectclass, parent_sd,
837 user_sd, old_sd, sd_flags);
838 if (sd == NULL) {
839 return ldb_operr(ldb);
841 msg = ldb_msg_copy_shallow(req, req->op.mod.message);
842 if (msg == NULL) {
843 return ldb_oom(ldb);
845 cmp_ret = data_blob_cmp(old_sd, sd);
846 if (sd_propagation_control != NULL) {
847 if (cmp_ret == 0) {
849 * The nTSecurityDescriptor is unchanged,
850 * which means we can stop the processing.
852 * We mark the control as critical again,
853 * as we have not processed it, so the caller
854 * can tell that the descriptor was unchanged.
856 sd_propagation_control->critical = 1;
857 return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
860 ret = ldb_msg_add_empty(msg, "nTSecurityDescriptor",
861 LDB_FLAG_MOD_REPLACE,
862 &sd_element);
863 if (ret != LDB_SUCCESS) {
864 return ldb_oom(ldb);
866 ret = ldb_msg_add_value(msg, "nTSecurityDescriptor",
867 sd, NULL);
868 if (ret != LDB_SUCCESS) {
869 return ldb_oom(ldb);
871 } else if (cmp_ret != 0) {
872 struct ldb_dn *nc_root;
874 ret = dsdb_find_nc_root(ldb, msg, dn, &nc_root);
875 if (ret != LDB_SUCCESS) {
876 return ldb_oom(ldb);
879 ret = dsdb_module_schedule_sd_propagation(module, nc_root,
880 dn, false);
881 if (ret != LDB_SUCCESS) {
882 return ldb_operr(ldb);
884 sd_element->values[0] = *sd;
885 } else {
886 sd_element->values[0] = *sd;
889 ret = ldb_build_mod_req(&mod_req, ldb, req,
890 msg,
891 req->controls,
892 req,
893 dsdb_next_callback,
894 req);
895 LDB_REQ_SET_LOCATION(mod_req);
896 if (ret != LDB_SUCCESS) {
897 return ret;
900 return ldb_next_request(module, mod_req);
903 static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
905 int ret;
906 struct ldb_context *ldb;
907 struct ldb_request *down_req;
908 struct descriptor_context *ac;
909 bool explicit_sd_flags = false;
910 uint32_t sd_flags = dsdb_request_sd_flags(req, &explicit_sd_flags);
911 bool show_sd = explicit_sd_flags;
913 if (!show_sd &&
914 ldb_attr_in_list(req->op.search.attrs, "nTSecurityDescriptor"))
916 show_sd = true;
919 if (!show_sd) {
920 return ldb_next_request(module, req);
923 ldb = ldb_module_get_ctx(module);
924 ac = descriptor_init_context(module, req);
925 if (ac == NULL) {
926 return ldb_operr(ldb);
928 ac->sd_flags = sd_flags;
930 ret = ldb_build_search_req_ex(&down_req, ldb, ac,
931 req->op.search.base,
932 req->op.search.scope,
933 req->op.search.tree,
934 req->op.search.attrs,
935 req->controls,
936 ac, descriptor_search_callback,
937 ac->req);
938 LDB_REQ_SET_LOCATION(down_req);
939 if (ret != LDB_SUCCESS) {
940 return ret;
943 return ldb_next_request(ac->module, down_req);
946 static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
948 struct ldb_context *ldb = ldb_module_get_ctx(module);
949 struct ldb_dn *olddn = req->op.rename.olddn;
950 struct ldb_dn *newdn = req->op.rename.newdn;
951 int ret;
953 /* do not manipulate our control entries */
954 if (ldb_dn_is_special(req->op.rename.olddn)) {
955 return ldb_next_request(module, req);
958 ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n",
959 ldb_dn_get_linearized(olddn));
961 if (ldb_dn_compare(olddn, newdn) != 0) {
962 struct ldb_dn *nc_root;
964 ret = dsdb_find_nc_root(ldb, req, newdn, &nc_root);
965 if (ret != LDB_SUCCESS) {
966 return ldb_oom(ldb);
969 ret = dsdb_module_schedule_sd_propagation(module, nc_root,
970 newdn, true);
971 if (ret != LDB_SUCCESS) {
972 return ldb_operr(ldb);
976 return ldb_next_request(module, req);
979 static int descriptor_extended_sec_desc_propagation(struct ldb_module *module,
980 struct ldb_request *req)
982 struct descriptor_data *descriptor_private =
983 talloc_get_type_abort(ldb_module_get_private(module),
984 struct descriptor_data);
985 struct ldb_context *ldb = ldb_module_get_ctx(module);
986 struct dsdb_extended_sec_desc_propagation_op *op;
987 TALLOC_CTX *parent_mem = NULL;
988 struct descriptor_changes *parent_change = NULL;
989 struct descriptor_changes *c;
990 int ret;
992 op = talloc_get_type(req->op.extended.data,
993 struct dsdb_extended_sec_desc_propagation_op);
994 if (op == NULL) {
995 ldb_debug(ldb, LDB_DEBUG_FATAL,
996 "descriptor_extended_sec_desc_propagation: "
997 "invalid extended data\n");
998 return LDB_ERR_PROTOCOL_ERROR;
1001 if (descriptor_private->trans_mem == NULL) {
1002 return ldb_module_operr(module);
1005 parent_mem = descriptor_private->trans_mem;
1007 for (c = descriptor_private->changes; c; c = c->next) {
1008 ret = ldb_dn_compare(c->nc_root, op->nc_root);
1009 if (ret != 0) {
1010 continue;
1013 ret = ldb_dn_compare(c->dn, op->dn);
1014 if (ret == 0) {
1015 if (op->include_self) {
1016 c->force_self = true;
1017 } else {
1018 c->force_children = true;
1020 return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
1023 ret = ldb_dn_compare_base(c->dn, op->dn);
1024 if (ret != 0) {
1025 continue;
1028 parent_mem = c;
1029 parent_change = c;
1030 break;
1033 c = talloc_zero(parent_mem, struct descriptor_changes);
1034 if (c == NULL) {
1035 return ldb_module_oom(module);
1037 c->nc_root = ldb_dn_copy(c, op->nc_root);
1038 if (c->nc_root == NULL) {
1039 return ldb_module_oom(module);
1041 c->dn = ldb_dn_copy(c, op->dn);
1042 if (c->dn == NULL) {
1043 return ldb_module_oom(module);
1045 if (op->include_self) {
1046 c->force_self = true;
1047 } else {
1048 c->force_children = true;
1051 if (parent_change != NULL) {
1052 DLIST_ADD_END(parent_change->children, c, NULL);
1053 } else {
1054 DLIST_ADD_END(descriptor_private->changes, c, NULL);
1057 return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
1060 static int descriptor_extended(struct ldb_module *module, struct ldb_request *req)
1062 if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SEC_DESC_PROPAGATION_OID) == 0) {
1063 return descriptor_extended_sec_desc_propagation(module, req);
1066 return ldb_next_request(module, req);
1069 static int descriptor_init(struct ldb_module *module)
1071 struct ldb_context *ldb = ldb_module_get_ctx(module);
1072 int ret;
1073 struct descriptor_data *descriptor_private;
1075 ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
1076 if (ret != LDB_SUCCESS) {
1077 ldb_debug(ldb, LDB_DEBUG_ERROR,
1078 "descriptor: Unable to register control with rootdse!\n");
1079 return ldb_operr(ldb);
1082 descriptor_private = talloc_zero(module, struct descriptor_data);
1083 if (descriptor_private == NULL) {
1084 ldb_oom(ldb);
1085 return LDB_ERR_OPERATIONS_ERROR;
1087 ldb_module_set_private(module, descriptor_private);
1089 return ldb_next_init(module);
1092 static int descriptor_sd_propagation_object(struct ldb_module *module,
1093 struct ldb_message *msg,
1094 bool *stop)
1096 struct ldb_context *ldb = ldb_module_get_ctx(module);
1097 struct ldb_request *sub_req;
1098 struct ldb_result *mod_res;
1099 struct ldb_control *sd_propagation_control;
1100 int ret;
1102 *stop = false;
1104 mod_res = talloc_zero(msg, struct ldb_result);
1105 if (mod_res == NULL) {
1106 return ldb_module_oom(module);
1109 ret = ldb_build_mod_req(&sub_req, ldb, mod_res,
1110 msg,
1111 NULL,
1112 mod_res,
1113 ldb_modify_default_callback,
1114 NULL);
1115 LDB_REQ_SET_LOCATION(sub_req);
1116 if (ret != LDB_SUCCESS) {
1117 return ldb_module_operr(module);
1120 ldb_req_mark_trusted(sub_req);
1122 ret = ldb_request_add_control(sub_req,
1123 DSDB_CONTROL_SEC_DESC_PROPAGATION_OID,
1124 true, module);
1125 if (ret != LDB_SUCCESS) {
1126 return ldb_module_operr(module);
1129 sd_propagation_control = ldb_request_get_control(sub_req,
1130 DSDB_CONTROL_SEC_DESC_PROPAGATION_OID);
1131 if (sd_propagation_control == NULL) {
1132 return ldb_module_operr(module);
1135 ret = dsdb_request_add_controls(sub_req,
1136 DSDB_FLAG_AS_SYSTEM |
1137 DSDB_SEARCH_SHOW_RECYCLED);
1138 if (ret != LDB_SUCCESS) {
1139 return ldb_module_operr(module);
1142 ret = descriptor_modify(module, sub_req);
1143 if (ret == LDB_SUCCESS) {
1144 ret = ldb_wait(sub_req->handle, LDB_WAIT_ALL);
1146 if (ret != LDB_SUCCESS) {
1147 return ldb_module_operr(module);
1150 if (sd_propagation_control->critical != 0) {
1151 *stop = true;
1154 talloc_free(mod_res);
1156 return LDB_SUCCESS;
1159 static int descriptor_sd_propagation_msg_sort(struct ldb_message **m1,
1160 struct ldb_message **m2)
1162 struct ldb_dn *dn1 = (*m1)->dn;
1163 struct ldb_dn *dn2 = (*m2)->dn;
1166 * This sorts in tree order, parents first
1168 return ldb_dn_compare(dn2, dn1);
1171 static int descriptor_sd_propagation_dn_sort(struct ldb_dn *dn1,
1172 struct ldb_dn *dn2)
1175 * This sorts in tree order, parents first
1177 return ldb_dn_compare(dn2, dn1);
1180 static int descriptor_sd_propagation_recursive(struct ldb_module *module,
1181 struct descriptor_changes *change)
1183 struct ldb_context *ldb = ldb_module_get_ctx(module);
1184 struct ldb_result *res = NULL;
1185 unsigned int i;
1186 const char * const no_attrs[] = { "@__NONE__", NULL };
1187 struct descriptor_changes *c;
1188 struct descriptor_changes *stopped_stack = NULL;
1189 int ret;
1192 * Note: that we do not search for deleted/recycled objects
1194 ret = dsdb_module_search(module,
1195 change,
1196 &res,
1197 change->dn,
1198 LDB_SCOPE_SUBTREE,
1199 no_attrs,
1200 DSDB_FLAG_NEXT_MODULE |
1201 DSDB_FLAG_AS_SYSTEM,
1202 NULL, /* parent_req */
1203 "(objectClass=*)");
1204 if (ret != LDB_SUCCESS) {
1205 return ret;
1208 TYPESAFE_QSORT(res->msgs, res->count,
1209 descriptor_sd_propagation_msg_sort);
1211 for (c = change->children; c; c = c->next) {
1212 struct ldb_message *msg = NULL;
1214 BINARY_ARRAY_SEARCH_P(res->msgs, res->count, dn, c->dn,
1215 descriptor_sd_propagation_dn_sort,
1216 msg);
1218 if (msg == NULL) {
1219 ldb_debug(ldb, LDB_DEBUG_WARNING,
1220 "descriptor_sd_propagation_recursive: "
1221 "%s not found under %s",
1222 ldb_dn_get_linearized(c->dn),
1223 ldb_dn_get_linearized(change->dn));
1224 continue;
1227 msg->elements = (struct ldb_message_element *)c;
1230 DLIST_ADD(stopped_stack, change);
1232 if (change->force_self) {
1233 i = 0;
1234 } else {
1235 i = 1;
1238 for (; i < res->count; i++) {
1239 struct descriptor_changes *cur;
1240 bool stop = false;
1242 cur = talloc_get_type(res->msgs[i]->elements,
1243 struct descriptor_changes);
1244 res->msgs[i]->elements = NULL;
1245 res->msgs[i]->num_elements = 0;
1247 if (cur != NULL) {
1248 DLIST_REMOVE(change->children, cur);
1251 for (c = stopped_stack; c; c = stopped_stack) {
1252 ret = ldb_dn_compare_base(c->dn,
1253 res->msgs[i]->dn);
1254 if (ret == 0) {
1255 break;
1258 c->stopped_dn = NULL;
1259 DLIST_REMOVE(stopped_stack, c);
1262 if (cur != NULL) {
1263 DLIST_ADD(stopped_stack, cur);
1266 if (stopped_stack->stopped_dn != NULL) {
1267 ret = ldb_dn_compare_base(stopped_stack->stopped_dn,
1268 res->msgs[i]->dn);
1269 if (ret == 0) {
1270 continue;
1272 stopped_stack->stopped_dn = NULL;
1275 ret = descriptor_sd_propagation_object(module, res->msgs[i],
1276 &stop);
1277 if (ret != LDB_SUCCESS) {
1278 return ret;
1281 if (cur != NULL && cur->force_children) {
1282 continue;
1285 if (stop) {
1286 stopped_stack->stopped_dn = res->msgs[i]->dn;
1287 continue;
1291 TALLOC_FREE(res);
1292 return LDB_SUCCESS;
1295 static int descriptor_start_transaction(struct ldb_module *module)
1297 struct descriptor_data *descriptor_private =
1298 talloc_get_type_abort(ldb_module_get_private(module),
1299 struct descriptor_data);
1301 if (descriptor_private->trans_mem != NULL) {
1302 return ldb_module_operr(module);
1305 descriptor_private->trans_mem = talloc_new(descriptor_private);
1306 if (descriptor_private->trans_mem == NULL) {
1307 return ldb_module_oom(module);
1309 descriptor_private->changes = NULL;
1311 return ldb_next_start_trans(module);
1314 static int descriptor_prepare_commit(struct ldb_module *module)
1316 struct descriptor_data *descriptor_private =
1317 talloc_get_type_abort(ldb_module_get_private(module),
1318 struct descriptor_data);
1319 struct descriptor_changes *c, *n;
1320 int ret;
1322 for (c = descriptor_private->changes; c; c = n) {
1323 n = c->next;
1324 DLIST_REMOVE(descriptor_private->changes, c);
1326 ret = descriptor_sd_propagation_recursive(module, c);
1327 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
1328 continue;
1330 if (ret != LDB_SUCCESS) {
1331 return ret;
1335 return ldb_next_prepare_commit(module);
1338 static int descriptor_end_transaction(struct ldb_module *module)
1340 struct descriptor_data *descriptor_private =
1341 talloc_get_type_abort(ldb_module_get_private(module),
1342 struct descriptor_data);
1344 TALLOC_FREE(descriptor_private->trans_mem);
1345 descriptor_private->changes = NULL;
1347 return ldb_next_end_trans(module);
1350 static int descriptor_del_transaction(struct ldb_module *module)
1352 struct descriptor_data *descriptor_private =
1353 talloc_get_type_abort(ldb_module_get_private(module),
1354 struct descriptor_data);
1356 TALLOC_FREE(descriptor_private->trans_mem);
1357 descriptor_private->changes = NULL;
1359 return ldb_next_del_trans(module);
1362 static const struct ldb_module_ops ldb_descriptor_module_ops = {
1363 .name = "descriptor",
1364 .search = descriptor_search,
1365 .add = descriptor_add,
1366 .modify = descriptor_modify,
1367 .rename = descriptor_rename,
1368 .init_context = descriptor_init,
1369 .extended = descriptor_extended,
1370 .start_transaction = descriptor_start_transaction,
1371 .prepare_commit = descriptor_prepare_commit,
1372 .end_transaction = descriptor_end_transaction,
1373 .del_transaction = descriptor_del_transaction,
1376 int ldb_descriptor_module_init(const char *version)
1378 LDB_MODULE_CHECK_VERSION(version);
1379 return ldb_register_module(&ldb_descriptor_module_ops);