TODO pass DSDB_FLAG_AS_SYSTEM...
[metze/samba/wip.git] / source4 / dsdb / samdb / ldb_modules / descriptor.c
1 /*
2    ldb database library
3
4    Copyright (C) Simo Sorce  2006-2008
5    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2007
6    Copyright (C) Nadezhda Ivanova  2009
7
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.
12
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.
17
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/>.
20 */
21
22 /*
23  *  Name: ldb
24  *
25  *  Component: DS Security descriptor module
26  *
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
31  *
32  *  Author: Nadezhda Ivanova
33  */
34
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
46 struct descriptor_data {
47         int _dummy;
48 };
49
50 struct descriptor_context {
51         struct ldb_module *module;
52         struct ldb_request *req;
53         struct ldb_message *msg;
54         struct ldb_reply *search_res;
55         struct ldb_reply *search_oc_res;
56         struct ldb_val *parentsd_val;
57         struct ldb_message_element *sd_element;
58         struct ldb_val *sd_val;
59         int (*step_fn)(struct descriptor_context *);
60 };
61
62 static struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
63                                struct ldb_dn *dn,
64                                struct security_token *token,
65                                struct ldb_context *ldb)
66 {
67         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
68         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
69         struct dom_sid *da_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
70         struct dom_sid *ea_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
71         struct dom_sid *sa_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
72         struct dom_sid *dag_sid;
73         struct ldb_dn *nc_root;
74         int ret;
75
76         ret = dsdb_find_nc_root(ldb, tmp_ctx, dn, &nc_root);
77         if (ret != LDB_SUCCESS) {
78                 talloc_free(tmp_ctx);
79                 return NULL;
80         }
81
82         if (ldb_dn_compare(nc_root, ldb_get_schema_basedn(ldb)) == 0) {
83                 if (security_token_has_sid(token, sa_sid)) {
84                         dag_sid = dom_sid_dup(mem_ctx, sa_sid);
85                 } else if (security_token_has_sid(token, ea_sid)) {
86                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
87                 } else if (security_token_has_sid(token, da_sid)) {
88                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
89                 } else {
90                         dag_sid = NULL;
91                 }
92         } else if (ldb_dn_compare(nc_root, ldb_get_config_basedn(ldb)) == 0) {
93                 if (security_token_has_sid(token, ea_sid)) {
94                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
95                 } else if (security_token_has_sid(token, da_sid)) {
96                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
97                 } else {
98                         dag_sid = NULL;
99                 }
100         } else if (ldb_dn_compare(nc_root, ldb_get_default_basedn(ldb)) == 0) {
101                 if (security_token_has_sid(token, da_sid)) {
102                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
103                 } else if (security_token_has_sid(token, ea_sid)) {
104                                 dag_sid = dom_sid_dup(mem_ctx, ea_sid);
105                 } else {
106                         dag_sid = NULL;
107                 }
108         } else {
109                 dag_sid = NULL;
110         }
111
112         talloc_free(tmp_ctx);
113         return dag_sid;
114 }
115
116 static struct security_descriptor *get_sd_unpacked(struct ldb_module *module, TALLOC_CTX *mem_ctx,
117                                             const struct dsdb_class *objectclass)
118 {
119         struct ldb_context *ldb = ldb_module_get_ctx(module);
120         struct security_descriptor *sd;
121         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
122
123         if (!objectclass->defaultSecurityDescriptor || !domain_sid) {
124                 return NULL;
125         }
126
127         sd = sddl_decode(mem_ctx,
128                          objectclass->defaultSecurityDescriptor,
129                          domain_sid);
130         return sd;
131 }
132
133 static struct dom_sid *get_default_group(TALLOC_CTX *mem_ctx,
134                                          struct ldb_context *ldb,
135                                          struct dom_sid *dag)
136 {
137         if (dsdb_functional_level(ldb) >= DS_DOMAIN_FUNCTION_2008) {
138                 return dag;
139         }
140
141         return NULL;
142 }
143
144 static struct security_descriptor *descr_handle_sd_flags(TALLOC_CTX *mem_ctx,
145                                                          struct security_descriptor *new_sd,
146                                                          struct security_descriptor *old_sd,
147                                                          uint32_t sd_flags)
148 {
149         struct security_descriptor *final_sd; 
150         /* if there is no control or control == 0 modify everything */
151         if (!sd_flags) {
152                 return new_sd;
153         }
154
155         final_sd = talloc_zero(mem_ctx, struct security_descriptor);
156         final_sd->revision = SECURITY_DESCRIPTOR_REVISION_1;
157         final_sd->type = SEC_DESC_SELF_RELATIVE;
158
159         if (sd_flags & (SECINFO_OWNER)) {
160                 final_sd->owner_sid = talloc_memdup(mem_ctx, new_sd->owner_sid, sizeof(struct dom_sid));
161                 final_sd->type |= new_sd->type & SEC_DESC_OWNER_DEFAULTED;
162         }
163         else if (old_sd) {
164                 final_sd->owner_sid = talloc_memdup(mem_ctx, old_sd->owner_sid, sizeof(struct dom_sid));
165                 final_sd->type |= old_sd->type & SEC_DESC_OWNER_DEFAULTED;
166         }
167
168         if (sd_flags & (SECINFO_GROUP)) {
169                 final_sd->group_sid = talloc_memdup(mem_ctx, new_sd->group_sid, sizeof(struct dom_sid));
170                 final_sd->type |= new_sd->type & SEC_DESC_GROUP_DEFAULTED;
171         } 
172         else if (old_sd) {
173                 final_sd->group_sid = talloc_memdup(mem_ctx, old_sd->group_sid, sizeof(struct dom_sid));
174                 final_sd->type |= old_sd->type & SEC_DESC_GROUP_DEFAULTED;
175         }
176
177         if (sd_flags & (SECINFO_SACL)) {
178                 final_sd->sacl = security_acl_dup(mem_ctx,new_sd->sacl);
179                 final_sd->type |= new_sd->type & (SEC_DESC_SACL_PRESENT |
180                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
181                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
182                         SEC_DESC_SERVER_SECURITY);
183         } 
184         else if (old_sd && old_sd->sacl) {
185                 final_sd->sacl = security_acl_dup(mem_ctx,old_sd->sacl);
186                 final_sd->type |= old_sd->type & (SEC_DESC_SACL_PRESENT |
187                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
188                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
189                         SEC_DESC_SERVER_SECURITY);
190         }
191
192         if (sd_flags & (SECINFO_DACL)) {
193                 final_sd->dacl = security_acl_dup(mem_ctx,new_sd->dacl);
194                 final_sd->type |= new_sd->type & (SEC_DESC_DACL_PRESENT |
195                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
196                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
197                         SEC_DESC_DACL_TRUSTED);
198         } 
199         else if (old_sd && old_sd->dacl) {
200                 final_sd->dacl = security_acl_dup(mem_ctx,old_sd->dacl);
201                 final_sd->type |= old_sd->type & (SEC_DESC_DACL_PRESENT |
202                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
203                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
204                         SEC_DESC_DACL_TRUSTED);
205         }
206         /* not so sure about this */
207         final_sd->type |= new_sd->type & SEC_DESC_RM_CONTROL_VALID;
208         return final_sd;
209 }
210
211 static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
212                                      struct ldb_dn *dn,
213                                      TALLOC_CTX *mem_ctx,
214                                      const struct dsdb_class *objectclass,
215                                      const struct ldb_val *parent,
216                                      const struct ldb_val *object,
217                                      const struct ldb_val *old_sd,
218                                      uint32_t sd_flags)
219 {
220         struct security_descriptor *user_descriptor = NULL, *parent_descriptor = NULL;
221         struct security_descriptor *old_descriptor = NULL;
222         struct security_descriptor *new_sd, *final_sd;
223         DATA_BLOB *linear_sd;
224         enum ndr_err_code ndr_err;
225         struct ldb_context *ldb = ldb_module_get_ctx(module);
226         struct auth_session_info *session_info
227                 = ldb_get_opaque(ldb, "sessionInfo");
228         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
229         char *sddl_sd;
230         struct dom_sid *default_owner;
231         struct dom_sid *default_group;
232
233         if (object) {
234                 user_descriptor = talloc(mem_ctx, struct security_descriptor);
235                 if (!user_descriptor) {
236                         return NULL;
237                 }
238                 ndr_err = ndr_pull_struct_blob(object, user_descriptor, 
239                                                user_descriptor,
240                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
241
242                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
243                         talloc_free(user_descriptor);
244                         return NULL;
245                 }
246         } else {
247                 user_descriptor = get_sd_unpacked(module, mem_ctx, objectclass);
248         }
249
250         if (old_sd) {
251                 old_descriptor = talloc(mem_ctx, struct security_descriptor);
252                 if (!old_descriptor) {
253                         return NULL;
254                 }
255                 ndr_err = ndr_pull_struct_blob(old_sd, old_descriptor, 
256                                                old_descriptor,
257                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
258
259                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
260                         talloc_free(old_descriptor);
261                         return NULL;
262                 }
263         }
264
265         if (parent) {
266                 parent_descriptor = talloc(mem_ctx, struct security_descriptor);
267                 if (!parent_descriptor) {
268                         return NULL;
269                 }
270                 ndr_err = ndr_pull_struct_blob(parent, parent_descriptor, 
271                                                parent_descriptor,
272                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
273
274                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
275                         talloc_free(parent_descriptor);
276                         return NULL;
277                 }
278         }
279
280         default_owner = get_default_ag(mem_ctx, dn,
281                                        session_info->security_token, ldb);
282         default_group = get_default_group(mem_ctx, ldb, default_owner);
283         new_sd = create_security_descriptor(mem_ctx, parent_descriptor, user_descriptor, true,
284                                             NULL, SEC_DACL_AUTO_INHERIT|SEC_SACL_AUTO_INHERIT,
285                                             session_info->security_token,
286                                             default_owner, default_group,
287                                             map_generic_rights_ds);
288         if (!new_sd) {
289                 return NULL;
290         }
291         final_sd = descr_handle_sd_flags(mem_ctx, new_sd, old_descriptor, sd_flags);
292
293         if (!final_sd) {
294                 return NULL;
295         }
296
297         if (final_sd->dacl) {
298                 final_sd->dacl->revision = SECURITY_ACL_REVISION_ADS;
299         }
300         if (final_sd->sacl) {
301                 final_sd->sacl->revision = SECURITY_ACL_REVISION_ADS;
302         }
303
304         sddl_sd = sddl_encode(mem_ctx, final_sd, domain_sid);
305         DEBUG(10, ("Object %s created with desriptor %s\n\n", ldb_dn_get_linearized(dn), sddl_sd));
306
307         linear_sd = talloc(mem_ctx, DATA_BLOB);
308         if (!linear_sd) {
309                 return NULL;
310         }
311
312         ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
313                                        final_sd,
314                                        (ndr_push_flags_fn_t)ndr_push_security_descriptor);
315         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
316                 return NULL;
317         }
318
319         return linear_sd;
320 }
321
322 static DATA_BLOB *descr_get_descriptor_to_show(struct ldb_module *module,
323                                                TALLOC_CTX *mem_ctx,
324                                                struct ldb_val *sd,
325                                                uint32_t sd_flags)
326 {
327         struct security_descriptor *old_sd, *final_sd;
328         DATA_BLOB *linear_sd;
329         enum ndr_err_code ndr_err;
330
331         old_sd = talloc(mem_ctx, struct security_descriptor);
332         if (!old_sd) {
333                 return NULL;
334         }
335         ndr_err = ndr_pull_struct_blob(sd, old_sd, 
336                                        old_sd,
337                                        (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
338
339         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
340                 talloc_free(old_sd);
341                 return NULL;
342         }
343
344         final_sd = descr_handle_sd_flags(mem_ctx, old_sd, NULL, sd_flags);
345
346         if (!final_sd) {
347                 return NULL;
348         }
349
350         linear_sd = talloc(mem_ctx, DATA_BLOB);
351         if (!linear_sd) {
352                 return NULL;
353         }
354
355         ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
356                                        final_sd,
357                                        (ndr_push_flags_fn_t)ndr_push_security_descriptor);
358         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
359                 return NULL;
360         }
361
362         return linear_sd;
363 }
364
365 static struct descriptor_context *descriptor_init_context(struct ldb_module *module,
366                                                           struct ldb_request *req)
367 {
368         struct ldb_context *ldb;
369         struct descriptor_context *ac;
370
371         ldb = ldb_module_get_ctx(module);
372
373         ac = talloc_zero(req, struct descriptor_context);
374         if (ac == NULL) {
375                 ldb_set_errstring(ldb, "Out of Memory");
376                 return NULL;
377         }
378
379         ac->module = module;
380         ac->req = req;
381         return ac;
382 }
383
384 static int descriptor_search_callback(struct ldb_request *req, struct ldb_reply *ares)
385 {
386         struct descriptor_context *ac;
387         struct ldb_control *sd_control;
388         struct ldb_val *sd_val = NULL;
389         struct ldb_message_element *sd_el;
390         DATA_BLOB *show_sd;
391         int ret;
392         uint32_t sd_flags = 0;
393
394         ac = talloc_get_type(req->context, struct descriptor_context);
395
396         if (!ares) {
397                 ret = LDB_ERR_OPERATIONS_ERROR;
398                 goto fail;
399         }
400         if (ares->error != LDB_SUCCESS) {
401                 return ldb_module_done(ac->req, ares->controls,
402                                         ares->response, ares->error);
403         }
404
405         sd_control = ldb_request_get_control(ac->req, LDB_CONTROL_SD_FLAGS_OID);
406         if (sd_control) {
407                 struct ldb_sd_flags_control *sdctr = (struct ldb_sd_flags_control *)sd_control->data;
408                 sd_flags = sdctr->secinfo_flags;
409                 /* we only care for the last 4 bits */
410                 sd_flags = sd_flags & 0x0000000F;
411                 if (sd_flags == 0) {
412                         /* MS-ADTS 3.1.1.3.4.1.11 says that no bits
413                            equals all 4 bits */
414                         sd_flags = 0xF;
415                 }
416         }
417
418         switch (ares->type) {
419         case LDB_REPLY_ENTRY:
420                 if (sd_flags != 0) {
421                         sd_el = ldb_msg_find_element(ares->message, "nTSecurityDescriptor");
422                         if (sd_el) {
423                                 sd_val = sd_el->values;
424                         }
425                 }
426                 if (sd_val) {
427                         show_sd = descr_get_descriptor_to_show(ac->module, ac->req,
428                                                                sd_val, sd_flags);
429                         if (!show_sd) {
430                                 ret = LDB_ERR_OPERATIONS_ERROR;
431                                 goto fail;
432                         }
433                         ldb_msg_remove_attr(ares->message, "nTSecurityDescriptor");
434                         ret = ldb_msg_add_steal_value(ares->message, "nTSecurityDescriptor", show_sd);
435                         if (ret != LDB_SUCCESS) {
436                                 goto fail;
437                         }
438                 }
439                 return ldb_module_send_entry(ac->req, ares->message, ares->controls);
440
441         case LDB_REPLY_REFERRAL:
442                 return ldb_module_send_referral(ac->req, ares->referral);
443
444         case LDB_REPLY_DONE:
445                 return ldb_module_done(ac->req, ares->controls,
446                                         ares->response, ares->error);
447         }
448
449 fail:
450         talloc_free(ares);
451         return ldb_module_done(ac->req, NULL, NULL, ret);
452 }
453
454 static int descriptor_add(struct ldb_module *module, struct ldb_request *req)
455 {
456         struct ldb_context *ldb;
457         struct ldb_request *add_req;
458         struct ldb_message *msg;
459         struct ldb_result *parent_res;
460         const struct ldb_val *parent_sd = NULL;
461         const struct ldb_val *user_sd;
462         struct ldb_dn *parent_dn, *dn, *nc_root;
463         struct ldb_message_element *objectclass_element, *sd_element;
464         int ret;
465         const struct dsdb_schema *schema;
466         DATA_BLOB *sd;
467         const struct dsdb_class *objectclass;
468         static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
469         uint32_t instanceType;
470         bool isNC = false;
471
472         ldb = ldb_module_get_ctx(module);
473         dn = req->op.add.message->dn;
474         user_sd = ldb_msg_find_ldb_val(req->op.add.message, "nTSecurityDescriptor");
475         sd_element = ldb_msg_find_element(req->op.add.message, "nTSecurityDescriptor");
476         /* nTSecurityDescriptor without a value is an error, letting through so it is handled */
477         if (user_sd == NULL && sd_element) {
478                 return ldb_next_request(module, req);
479         }
480
481         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: %s\n", ldb_dn_get_linearized(dn));
482
483         /* do not manipulate our control entries */
484         if (ldb_dn_is_special(dn)) {
485                 return ldb_next_request(module, req);
486         }
487
488         instanceType = ldb_msg_find_attr_as_uint(req->op.add.message, "instanceType", 0);
489
490         if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) {
491                 isNC = true;
492         }
493
494         if (!isNC) {
495                 ret = dsdb_find_nc_root(ldb, req, dn, &nc_root);
496                 if (ret != LDB_SUCCESS) {
497                         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find NC root for %s\n",
498                                 ldb_dn_get_linearized(dn));
499                         return ret;
500                 }
501
502                 if (ldb_dn_compare(dn, nc_root) == 0) {
503                         DEBUG(0, ("Found DN %s being a NC by the old method\n", ldb_dn_get_linearized(dn)));
504                         isNC = true;
505                 }
506         }
507
508         if (isNC) {
509                 DEBUG(2, ("DN: %s is a NC\n", ldb_dn_get_linearized(dn)));
510         }
511         if (!isNC) {
512                 /* if the object has a parent, retrieve its SD to
513                  * use for calculation. Unfortunately we do not yet have
514                  * instanceType, so we use dsdb_find_nc_root. */
515
516                 parent_dn = ldb_dn_get_parent(req, dn);
517                 if (parent_dn == NULL) {
518                         return ldb_oom(ldb);
519                 }
520
521                 /* we aren't any NC */
522                 ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn,
523                                             parent_attrs,
524                                             DSDB_FLAG_NEXT_MODULE |
525                                             DSDB_FLAG_AS_SYSTEM,
526                                             req);
527                 if (ret != LDB_SUCCESS) {
528                         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find SD for %s\n",
529                                   ldb_dn_get_linearized(parent_dn));
530                         return ret;
531                 }
532                 if (parent_res->count != 1) {
533                         return ldb_operr(ldb);
534                 }
535                 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
536         }
537
538         schema = dsdb_get_schema(ldb, req);
539
540         objectclass_element = ldb_msg_find_element(req->op.add.message, "objectClass");
541         if (objectclass_element == NULL) {
542                 return ldb_operr(ldb);
543         }
544
545         objectclass = dsdb_get_last_structural_class(schema,
546                                                      objectclass_element);
547         if (objectclass == NULL) {
548                 return ldb_operr(ldb);
549         }
550
551         sd = get_new_descriptor(module, dn, req,
552                                 objectclass, parent_sd,
553                                 user_sd, NULL, 0);
554         msg = ldb_msg_copy_shallow(req, req->op.add.message);
555         if (sd != NULL) {
556                 if (sd_element != NULL) {
557                         sd_element->values[0] = *sd;
558                 } else {
559                         ret = ldb_msg_add_steal_value(msg,
560                                                       "nTSecurityDescriptor",
561                                                       sd);
562                         if (ret != LDB_SUCCESS) {
563                                 return ret;
564                         }
565                 }
566         }
567
568         ret = ldb_build_add_req(&add_req, ldb, req,
569                                 msg,
570                                 req->controls,
571                                 req, dsdb_next_callback,
572                                 req);
573         LDB_REQ_SET_LOCATION(add_req);
574         if (ret != LDB_SUCCESS) {
575                 return ldb_error(ldb, ret,
576                                  "descriptor_add: Error creating new add request.");
577         }
578
579         return ldb_next_request(module, add_req);
580 }
581
582 struct descriptor_modify_state {
583         struct ldb_module *module;
584         struct ldb_request *req;
585 };
586
587 static int descriptor_modify_callback(struct ldb_request *mod_req,
588                                       struct ldb_reply *ares);
589
590 static int descriptor_modify(struct ldb_module *module, struct ldb_request *req)
591 {
592         struct descriptor_modify_state *state = NULL;
593         struct ldb_context *ldb = ldb_module_get_ctx(module);
594         struct ldb_control *sd_recalculate_control, *sd_flags_control, *show_deleted_control;
595         struct ldb_request *mod_req;
596         struct ldb_message *msg;
597         struct ldb_result *current_res, *parent_res;
598         const struct ldb_val *old_sd = NULL;
599         const struct ldb_val *parent_sd = NULL;
600         const struct ldb_val *user_sd;
601         struct ldb_dn *parent_dn, *dn;
602         struct ldb_message_element *objectclass_element;
603         int ret;
604         uint32_t instanceType, sd_flags = 0, flags;
605         const struct dsdb_schema *schema;
606         DATA_BLOB *sd;
607         const struct dsdb_class *objectclass;
608         static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
609         static const char * const current_attrs[] = { "nTSecurityDescriptor",
610                                                       "instanceType",
611                                                       "objectClass", NULL };
612
613         state = talloc_zero(req, struct descriptor_modify_state);
614         if (state == NULL) {
615                 return ldb_oom(ldb);
616         }
617         state->module = module;
618         state->req = req;
619
620         dn = req->op.mod.message->dn;
621         user_sd = ldb_msg_find_ldb_val(req->op.mod.message, "nTSecurityDescriptor");
622         /* This control forces the recalculation of the SD also when
623          * no modification is performed. */
624         show_deleted_control = ldb_request_get_control(req,
625                                              LDB_CONTROL_SHOW_DELETED_OID);
626         sd_recalculate_control = ldb_request_get_control(req,
627                                              LDB_CONTROL_RECALCULATE_SD_OID);
628         if (!user_sd && !sd_recalculate_control) {
629                 return ldb_next_request(module, req);
630         }
631
632         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_modify: %s\n", ldb_dn_get_linearized(dn));
633
634         /* do not manipulate our control entries */
635         if (ldb_dn_is_special(dn)) {
636                 return ldb_next_request(module, req);
637         }
638         flags = DSDB_FLAG_NEXT_MODULE | DSDB_FLAG_AS_SYSTEM;
639         if (show_deleted_control) {
640                 flags |= DSDB_SEARCH_SHOW_DELETED;
641         }
642         ret = dsdb_module_search_dn(module, state, &current_res, dn,
643                                     current_attrs,
644                                     flags,
645                                     req);
646         if (ret != LDB_SUCCESS) {
647                 ldb_debug(ldb, LDB_DEBUG_ERROR,"descriptor_modify: Could not find %s\n",
648                           ldb_dn_get_linearized(dn));
649                 return ret;
650         }
651
652         instanceType = ldb_msg_find_attr_as_uint(current_res->msgs[0],
653                                                  "instanceType", 0);
654         /* if the object has a parent, retrieve its SD to
655          * use for calculation */
656         if (!ldb_dn_is_null(current_res->msgs[0]->dn) &&
657             !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
658                 parent_dn = ldb_dn_get_parent(req, dn);
659                 if (parent_dn == NULL) {
660                         return ldb_oom(ldb);
661                 }
662                 ret = dsdb_module_search_dn(module, state, &parent_res,
663                                             parent_dn,
664                                             parent_attrs,
665                                             DSDB_FLAG_NEXT_MODULE |
666                                             DSDB_FLAG_AS_SYSTEM,
667                                             req);
668                 if (ret != LDB_SUCCESS) {
669                         ldb_debug(ldb, LDB_DEBUG_ERROR, "descriptor_modify: Could not find SD for %s\n",
670                                   ldb_dn_get_linearized(parent_dn));
671                         return ret;
672                 }
673                 if (parent_res->count != 1) {
674                         return ldb_operr(ldb);
675                 }
676                 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
677         }
678         sd_flags_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID);
679
680         schema = dsdb_get_schema(ldb, req);
681
682         objectclass_element = ldb_msg_find_element(current_res->msgs[0], "objectClass");
683         if (objectclass_element == NULL) {
684                 return ldb_operr(ldb);
685         }
686
687         objectclass = dsdb_get_last_structural_class(schema,
688                                                      objectclass_element);
689         if (objectclass == NULL) {
690                 return ldb_operr(ldb);
691         }
692
693         if (sd_flags_control) {
694                 struct ldb_sd_flags_control *sdctr = (struct ldb_sd_flags_control *)sd_flags_control->data;
695                 sd_flags = sdctr->secinfo_flags;
696                 /* we only care for the last 4 bits */
697                 sd_flags = sd_flags & 0x0000000F;
698         }
699         if (sd_flags != 0) {
700                 old_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor");
701         }
702
703         if ((sd_recalculate_control != NULL) &&
704             (sd_recalculate_control->data != NULL))
705         {
706                 if (user_sd != NULL) {
707                         return ldb_error(ldb, ret,
708                                  "descriptor_modify: RECALCULATE_SD with given value rejected");
709                 }
710
711                 sd_flags = 0x0000000F;
712                 old_sd = NULL;
713                 user_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor");
714         }
715
716         sd = get_new_descriptor(module, dn, state,
717                                 objectclass, parent_sd,
718                                 user_sd, old_sd, sd_flags);
719         msg = ldb_msg_copy_shallow(state, req->op.mod.message);
720         if (sd != NULL) {
721                 struct ldb_message_element *sd_element;
722
723                 if (sd_recalculate_control != NULL) {
724                         /* In this branch we really do force the recalculation
725                          * of the SD */
726                         ldb_msg_remove_attr(msg, "nTSecurityDescriptor");
727
728                         ret = ldb_msg_add_steal_value(msg,
729                                                       "nTSecurityDescriptor",
730                                                       sd);
731                         if (ret != LDB_SUCCESS) {
732                                 return ldb_error(ldb, ret,
733                                          "descriptor_modify: Could not replace SD value in message.");
734                         }
735                         sd_element = ldb_msg_find_element(msg,
736                                                           "nTSecurityDescriptor");
737                         sd_element->flags = LDB_FLAG_MOD_REPLACE;
738                 } else if (user_sd != NULL) {
739                         sd_element = ldb_msg_find_element(msg,
740                                                           "nTSecurityDescriptor");
741                         sd_element->values[0] = *sd;
742                 }
743         }
744
745         /* mark the controls as non-critical since we've handled them */
746         if (sd_flags_control != NULL) {
747                 sd_flags_control->critical = 0;
748         }
749         if (sd_recalculate_control != NULL) {
750                 sd_recalculate_control->critical = 0;
751         }
752
753         ret = ldb_build_mod_req(&mod_req, ldb, state,
754                                 msg,
755                                 req->controls,
756                                 state,
757                                 descriptor_modify_callback,
758                                 req);
759         LDB_REQ_SET_LOCATION(mod_req);
760         if (ret != LDB_SUCCESS) {
761                 return ret;
762         }
763
764         return ldb_next_request(module, mod_req);
765 }
766
767 /*
768   used to chain to the callers callback
769  */
770 static int descriptor_modify_callback(struct ldb_request *mod_req,
771                                       struct ldb_reply *ares)
772 {
773         struct descriptor_modify_state *state =
774                 talloc_get_type_abort(mod_req->context,
775                 struct descriptor_modify_state);
776         struct ldb_module *module = state->module;
777         struct ldb_context *ldb = ldb_module_get_ctx(module);
778         struct ldb_request *req = state->req;
779         struct ldb_result *res = NULL;
780         const char * const no_attrs[] = { NULL };
781         unsigned int i;
782         int ret;
783
784         if (!ares) {
785                 return ldb_module_done(req, NULL, NULL,
786                                        LDB_ERR_OPERATIONS_ERROR);
787         }
788
789         if (ares->type == LDB_REPLY_REFERRAL) {
790                 return ldb_module_send_referral(req, ares->referral);
791         }
792
793         if (ares->error != LDB_SUCCESS) {
794                 return ldb_module_done(req, ares->controls,
795                                        ares->response, ares->error);
796         }
797
798         if (ares->type != LDB_REPLY_DONE) {
799                 talloc_free(ares);
800                 return ldb_module_done(req, NULL, NULL,
801                                        LDB_ERR_OPERATIONS_ERROR);
802         }
803
804         ret = dsdb_module_search(module, ares, &res,
805                                  req->op.mod.message->dn,
806                                  LDB_SCOPE_ONELEVEL, no_attrs,
807                                  DSDB_FLAG_NEXT_MODULE |
808                                  DSDB_FLAG_AS_SYSTEM |
809                                  DSDB_SEARCH_SHOW_RECYCLED |
810                                  DSDB_SEARCH_SHOW_DELETED,
811                                  req, "(objectClass=*)");
812         if (ret != LDB_SUCCESS) {
813                 talloc_free(ares);
814                 return ldb_module_done(req, NULL, NULL, ret);
815         }
816
817         for (i=0; i < res->count; i++) {
818                 struct ldb_request *sub_req;
819                 struct ldb_result *mod_res;
820
821                 mod_res = talloc_zero(res, struct ldb_result);
822                 if (!mod_res) {
823                         return ldb_module_done(req, NULL, NULL,
824                                                LDB_ERR_OPERATIONS_ERROR);
825                 }
826
827                 ret = ldb_build_mod_req(&sub_req, ldb, req,
828                                         res->msgs[i],
829                                         NULL,
830                                         mod_res,
831                                         ldb_modify_default_callback,
832                                         req);
833                 LDB_REQ_SET_LOCATION(sub_req);
834                 if (ret != LDB_SUCCESS) {
835                         talloc_free(ares);
836                         return ldb_module_done(req, NULL, NULL,
837                                                LDB_ERR_OPERATIONS_ERROR);
838                 }
839
840                 ldb_req_mark_trusted(sub_req);
841
842                 ret = ldb_request_add_control(sub_req,
843                                               LDB_CONTROL_RECALCULATE_SD_OID,
844                                               true, req);
845                 if (ret != LDB_SUCCESS) {
846                         talloc_free(ares);
847                         return ldb_module_done(req, NULL, NULL,
848                                                LDB_ERR_OPERATIONS_ERROR);
849                 }
850                 ret = ldb_request_add_control(sub_req,
851                                               LDB_CONTROL_AS_SYSTEM_OID,
852                                               false, NULL);
853                 if (ret != LDB_SUCCESS) {
854                         talloc_free(ares);
855                         return ldb_module_done(req, NULL, NULL,
856                                                LDB_ERR_OPERATIONS_ERROR);
857                 }
858
859                 ret = ldb_request_add_control(sub_req,
860                                               LDB_CONTROL_SHOW_DELETED_OID,
861                                               false, NULL);
862                 if (ret != LDB_SUCCESS) {
863                         talloc_free(ares);
864                         return ldb_module_done(req, NULL, NULL,
865                                                LDB_ERR_OPERATIONS_ERROR);
866                 }
867                 ret = ldb_request_add_control(sub_req,
868                                               LDB_CONTROL_SHOW_RECYCLED_OID,
869                                               false, NULL);
870                 if (ret != LDB_SUCCESS) {
871                         talloc_free(ares);
872                         return ldb_module_done(req, NULL, NULL,
873                                                LDB_ERR_OPERATIONS_ERROR);
874                 }
875
876                 ret = descriptor_modify(module, sub_req);
877                 if (ret == LDB_SUCCESS) {
878                         ret = ldb_wait(sub_req->handle, LDB_WAIT_ALL);
879                 }
880                 if (ret != LDB_SUCCESS) {
881                         talloc_free(ares);
882                         return ldb_module_done(req, NULL, NULL,
883                                                LDB_ERR_OPERATIONS_ERROR);
884                 }
885
886                 talloc_free(mod_res);
887         }
888
889         return ldb_module_done(req, ares->controls,
890                                ares->response, ares->error);
891 }
892
893 static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
894 {
895         int ret;
896         struct ldb_context *ldb;
897         struct ldb_control *sd_control;
898         struct ldb_request *down_req;
899         struct descriptor_context *ac;
900
901         sd_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID);
902         if (!sd_control) {
903                 return ldb_next_request(module, req);
904         }
905
906         ldb = ldb_module_get_ctx(module);
907         ac = descriptor_init_context(module, req);
908         if (ac == NULL) {
909                 return ldb_operr(ldb);
910         }
911
912         ret = ldb_build_search_req_ex(&down_req, ldb, ac,
913                                       req->op.search.base,
914                                       req->op.search.scope,
915                                       req->op.search.tree,
916                                       req->op.search.attrs,
917                                       req->controls,
918                                       ac, descriptor_search_callback,
919                                       ac->req);
920         LDB_REQ_SET_LOCATION(down_req);
921         if (ret != LDB_SUCCESS) {
922                 return ret;
923         }
924         /* mark it as handled */
925         if (sd_control) {
926                 sd_control->critical = 0;
927         }
928
929         return ldb_next_request(ac->module, down_req);
930 }
931
932 struct descriptor_rename_state {
933         struct ldb_module *module;
934         struct ldb_request *req;
935 };
936
937 static int descriptor_rename_callback(struct ldb_request *req,
938                                       struct ldb_reply *reply);
939
940 static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
941 {
942         struct ldb_context *ldb = ldb_module_get_ctx(module);
943         struct descriptor_rename_state *state;
944         int ret;
945         struct ldb_request *rename_req = NULL;
946
947         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n",
948                   ldb_dn_get_linearized(req->op.rename.olddn));
949
950         /* do not manipulate our control entries */
951         if (ldb_dn_is_special(req->op.rename.olddn)) {
952                 return ldb_next_request(module, req);
953         }
954
955         state = talloc_zero(req, struct descriptor_rename_state);
956         if (state == NULL) {
957                 return ldb_oom(ldb);
958         }
959         state->module = module;
960         state->req = req;
961
962         ret = ldb_build_rename_req(&rename_req, ldb, state,
963                                    req->op.rename.olddn,
964                                    req->op.rename.newdn,
965                                    req->controls,
966                                    state,
967                                    descriptor_rename_callback,
968                                    req);
969         LDB_REQ_SET_LOCATION(rename_req);
970         if (ret != LDB_SUCCESS) {
971                 return ret;
972         }
973
974         return ldb_next_request(module, rename_req);
975 }
976
977 static int descriptor_rename_callback(struct ldb_request *rename_req,
978                                       struct ldb_reply *ares)
979 {
980         struct descriptor_rename_state *state =
981                 talloc_get_type_abort(rename_req->context,
982                 struct descriptor_rename_state);
983         struct ldb_module *module = state->module;
984         struct ldb_context *ldb = ldb_module_get_ctx(module);
985         struct ldb_request *req = state->req;
986         struct ldb_message *msg;
987         struct ldb_request *mod_req;
988         int ret;
989         struct ldb_result *mod_res;
990
991         if (!ares) {
992                 return ldb_module_done(req, NULL, NULL,
993                                        LDB_ERR_OPERATIONS_ERROR);
994         }
995
996         if (ares->type == LDB_REPLY_REFERRAL) {
997                 return ldb_module_send_referral(req, ares->referral);
998         }
999
1000         if (ares->error != LDB_SUCCESS) {
1001                 return ldb_module_done(req, ares->controls,
1002                                        ares->response, ares->error);
1003         }
1004
1005         if (ares->type != LDB_REPLY_DONE) {
1006                 talloc_free(ares);
1007                 return ldb_module_done(req, NULL, NULL,
1008                                        LDB_ERR_OPERATIONS_ERROR);
1009         }
1010
1011         msg = ldb_msg_new(ares);
1012         if (msg == NULL) {
1013                 talloc_free(ares);
1014                 return ldb_module_done(req, NULL, NULL,
1015                                        LDB_ERR_OPERATIONS_ERROR);
1016         }
1017         msg->dn = req->op.rename.newdn;
1018
1019         mod_res = talloc_zero(msg, struct ldb_result);
1020         if (mod_res == NULL) {
1021                 talloc_free(ares);
1022                 return ldb_module_done(req, NULL, NULL,
1023                                        LDB_ERR_OPERATIONS_ERROR);
1024         }
1025
1026         ret = ldb_build_mod_req(&mod_req, ldb, msg,
1027                                 msg,
1028                                 NULL,
1029                                 mod_res,
1030                                 ldb_modify_default_callback,
1031                                 req);
1032         LDB_REQ_SET_LOCATION(mod_req);
1033         if (ret != LDB_SUCCESS) {
1034                 talloc_free(ares);
1035                 return ldb_module_done(req, NULL, NULL,
1036                                        LDB_ERR_OPERATIONS_ERROR);
1037         }
1038
1039         ldb_req_mark_trusted(mod_req);
1040
1041         ret = ldb_request_add_control(mod_req,
1042                                       LDB_CONTROL_RECALCULATE_SD_OID,
1043                                       true, req);
1044         if (ret != LDB_SUCCESS) {
1045                 talloc_free(ares);
1046                 return ldb_module_done(req, NULL, NULL,
1047                                        LDB_ERR_OPERATIONS_ERROR);
1048         }
1049         ret = ldb_request_add_control(mod_req,
1050                                       LDB_CONTROL_AS_SYSTEM_OID,
1051                                       false, NULL);
1052         if (ret != LDB_SUCCESS) {
1053                 talloc_free(ares);
1054                 return ldb_module_done(req, NULL, NULL,
1055                                        LDB_ERR_OPERATIONS_ERROR);
1056         }
1057
1058         ret = ldb_request_add_control(mod_req,
1059                                       LDB_CONTROL_SHOW_DELETED_OID,
1060                                       false, NULL);
1061         if (ret != LDB_SUCCESS) {
1062                 talloc_free(ares);
1063                 return ldb_module_done(req, NULL, NULL,
1064                                        LDB_ERR_OPERATIONS_ERROR);
1065         }
1066         ret = ldb_request_add_control(mod_req,
1067                                       LDB_CONTROL_SHOW_RECYCLED_OID,
1068                                       false, NULL);
1069         if (ret != LDB_SUCCESS) {
1070                 talloc_free(ares);
1071                 return ldb_module_done(req, NULL, NULL,
1072                                        LDB_ERR_OPERATIONS_ERROR);
1073         }
1074
1075         ret = descriptor_modify(module, mod_req);
1076         if (ret == LDB_SUCCESS) {
1077                 ret = ldb_wait(mod_req->handle, LDB_WAIT_ALL);
1078         }
1079         if (ret != LDB_SUCCESS) {
1080                 talloc_free(ares);
1081                 return ldb_module_done(req, NULL, NULL,
1082                                        LDB_ERR_OPERATIONS_ERROR);
1083         }
1084
1085         talloc_free(msg);
1086
1087         return ldb_module_done(req, ares->controls,
1088                                ares->response, ares->error);
1089 }
1090
1091 static int descriptor_init(struct ldb_module *module)
1092 {
1093         int ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
1094         struct ldb_context *ldb = ldb_module_get_ctx(module);
1095         if (ret != LDB_SUCCESS) {
1096                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1097                         "descriptor: Unable to register control with rootdse!\n");
1098                 return ldb_operr(ldb);
1099         }
1100         return ldb_next_init(module);
1101 }
1102
1103
1104 static const struct ldb_module_ops ldb_descriptor_module_ops = {
1105         .name          = "descriptor",
1106         .search        = descriptor_search,
1107         .add           = descriptor_add,
1108         .modify        = descriptor_modify,
1109         .rename        = descriptor_rename,
1110         .init_context  = descriptor_init
1111 };
1112
1113 int ldb_descriptor_module_init(const char *version)
1114 {
1115         LDB_MODULE_CHECK_VERSION(version);
1116         return ldb_register_module(&ldb_descriptor_module_ops);
1117 }