HACK LDB_CONTROL_RECALCULATE_SD_OID,
[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                                             req);
526                 if (ret != LDB_SUCCESS) {
527                         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find SD for %s\n",
528                                   ldb_dn_get_linearized(parent_dn));
529                         return ret;
530                 }
531                 if (parent_res->count != 1) {
532                         return ldb_operr(ldb);
533                 }
534                 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
535         }
536
537         schema = dsdb_get_schema(ldb, req);
538
539         objectclass_element = ldb_msg_find_element(req->op.add.message, "objectClass");
540         if (objectclass_element == NULL) {
541                 return ldb_operr(ldb);
542         }
543
544         objectclass = dsdb_get_last_structural_class(schema,
545                                                      objectclass_element);
546         if (objectclass == NULL) {
547                 return ldb_operr(ldb);
548         }
549
550         sd = get_new_descriptor(module, dn, req,
551                                 objectclass, parent_sd,
552                                 user_sd, NULL, 0);
553         msg = ldb_msg_copy_shallow(req, req->op.add.message);
554         if (sd != NULL) {
555                 if (sd_element != NULL) {
556                         sd_element->values[0] = *sd;
557                 } else {
558                         ret = ldb_msg_add_steal_value(msg,
559                                                       "nTSecurityDescriptor",
560                                                       sd);
561                         if (ret != LDB_SUCCESS) {
562                                 return ret;
563                         }
564                 }
565         }
566
567         ret = ldb_build_add_req(&add_req, ldb, req,
568                                 msg,
569                                 req->controls,
570                                 req, dsdb_next_callback,
571                                 req);
572         LDB_REQ_SET_LOCATION(add_req);
573         if (ret != LDB_SUCCESS) {
574                 return ldb_error(ldb, ret,
575                                  "descriptor_add: Error creating new add request.");
576         }
577
578         return ldb_next_request(module, add_req);
579 }
580
581 struct descriptor_modify_state {
582         struct ldb_module *module;
583         struct ldb_request *req;
584 };
585
586 static int descriptor_modify_callback(struct ldb_request *mod_req,
587                                       struct ldb_reply *ares);
588
589 static int descriptor_modify(struct ldb_module *module, struct ldb_request *req)
590 {
591         struct descriptor_modify_state *state = NULL;
592         struct ldb_context *ldb = ldb_module_get_ctx(module);
593         struct ldb_control *sd_recalculate_control, *sd_flags_control, *show_deleted_control;
594         struct ldb_request *mod_req;
595         struct ldb_message *msg;
596         struct ldb_result *current_res, *parent_res;
597         const struct ldb_val *old_sd = NULL;
598         const struct ldb_val *parent_sd = NULL;
599         const struct ldb_val *user_sd;
600         struct ldb_dn *parent_dn, *dn;
601         struct ldb_message_element *objectclass_element;
602         int ret;
603         uint32_t instanceType, sd_flags = 0, flags;
604         const struct dsdb_schema *schema;
605         DATA_BLOB *sd;
606         const struct dsdb_class *objectclass;
607         static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
608         static const char * const current_attrs[] = { "nTSecurityDescriptor",
609                                                       "instanceType",
610                                                       "objectClass", NULL };
611
612         state = talloc_zero(req, struct descriptor_modify_state);
613         if (state == NULL) {
614                 return ldb_oom(ldb);
615         }
616         state->module = module;
617         state->req = req;
618
619         dn = req->op.mod.message->dn;
620         user_sd = ldb_msg_find_ldb_val(req->op.mod.message, "nTSecurityDescriptor");
621         /* This control forces the recalculation of the SD also when
622          * no modification is performed. */
623         show_deleted_control = ldb_request_get_control(req,
624                                              LDB_CONTROL_SHOW_DELETED_OID);
625         sd_recalculate_control = ldb_request_get_control(req,
626                                              LDB_CONTROL_RECALCULATE_SD_OID);
627         if (!user_sd && !sd_recalculate_control) {
628                 return ldb_next_request(module, req);
629         }
630
631         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_modify: %s\n", ldb_dn_get_linearized(dn));
632
633         /* do not manipulate our control entries */
634         if (ldb_dn_is_special(dn)) {
635                 return ldb_next_request(module, req);
636         }
637         flags = DSDB_FLAG_NEXT_MODULE;
638         if (show_deleted_control) {
639                 flags |= DSDB_SEARCH_SHOW_DELETED;
640         }
641         ret = dsdb_module_search_dn(module, state, &current_res, dn,
642                                     current_attrs,
643                                     flags,
644                                     req);
645         if (ret != LDB_SUCCESS) {
646                 ldb_debug(ldb, LDB_DEBUG_ERROR,"descriptor_modify: Could not find %s\n",
647                           ldb_dn_get_linearized(dn));
648                 return ret;
649         }
650
651         instanceType = ldb_msg_find_attr_as_uint(current_res->msgs[0],
652                                                  "instanceType", 0);
653         /* if the object has a parent, retrieve its SD to
654          * use for calculation */
655         if (!ldb_dn_is_null(current_res->msgs[0]->dn) &&
656             !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
657                 parent_dn = ldb_dn_get_parent(req, dn);
658                 if (parent_dn == NULL) {
659                         return ldb_oom(ldb);
660                 }
661                 ret = dsdb_module_search_dn(module, state, &parent_res,
662                                             parent_dn,
663                                             parent_attrs,
664                                             DSDB_FLAG_NEXT_MODULE,
665                                             req);
666                 if (ret != LDB_SUCCESS) {
667                         ldb_debug(ldb, LDB_DEBUG_ERROR, "descriptor_modify: Could not find SD for %s\n",
668                                   ldb_dn_get_linearized(parent_dn));
669                         return ret;
670                 }
671                 if (parent_res->count != 1) {
672                         return ldb_operr(ldb);
673                 }
674                 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
675         }
676         sd_flags_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID);
677
678         schema = dsdb_get_schema(ldb, req);
679
680         objectclass_element = ldb_msg_find_element(current_res->msgs[0], "objectClass");
681         if (objectclass_element == NULL) {
682                 return ldb_operr(ldb);
683         }
684
685         objectclass = dsdb_get_last_structural_class(schema,
686                                                      objectclass_element);
687         if (objectclass == NULL) {
688                 return ldb_operr(ldb);
689         }
690
691         if (sd_flags_control) {
692                 struct ldb_sd_flags_control *sdctr = (struct ldb_sd_flags_control *)sd_flags_control->data;
693                 sd_flags = sdctr->secinfo_flags;
694                 /* we only care for the last 4 bits */
695                 sd_flags = sd_flags & 0x0000000F;
696         }
697         if (sd_flags != 0) {
698                 old_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor");
699         }
700
701         if ((sd_recalculate_control != NULL) &&
702             (sd_recalculate_control->data != NULL))
703         {
704                 if (user_sd != NULL) {
705                         return ldb_error(ldb, ret,
706                                  "descriptor_modify: RECALCULATE_SD with given value rejected");
707                 }
708
709                 sd_flags = 0x0000000F;
710                 old_sd = NULL;
711                 user_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor");
712         }
713
714         sd = get_new_descriptor(module, dn, state,
715                                 objectclass, parent_sd,
716                                 user_sd, old_sd, sd_flags);
717         msg = ldb_msg_copy_shallow(state, req->op.mod.message);
718         if (sd != NULL) {
719                 struct ldb_message_element *sd_element;
720
721                 if (sd_recalculate_control != NULL) {
722                         /* In this branch we really do force the recalculation
723                          * of the SD */
724                         ldb_msg_remove_attr(msg, "nTSecurityDescriptor");
725
726                         ret = ldb_msg_add_steal_value(msg,
727                                                       "nTSecurityDescriptor",
728                                                       sd);
729                         if (ret != LDB_SUCCESS) {
730                                 return ldb_error(ldb, ret,
731                                          "descriptor_modify: Could not replace SD value in message.");
732                         }
733                         sd_element = ldb_msg_find_element(msg,
734                                                           "nTSecurityDescriptor");
735                         sd_element->flags = LDB_FLAG_MOD_REPLACE;
736                 } else if (user_sd != NULL) {
737                         sd_element = ldb_msg_find_element(msg,
738                                                           "nTSecurityDescriptor");
739                         sd_element->values[0] = *sd;
740                 }
741         }
742
743         /* mark the controls as non-critical since we've handled them */
744         if (sd_flags_control != NULL) {
745                 sd_flags_control->critical = 0;
746         }
747         if (sd_recalculate_control != NULL) {
748                 sd_recalculate_control->critical = 0;
749         }
750
751         ret = ldb_build_mod_req(&mod_req, ldb, state,
752                                 msg,
753                                 req->controls,
754                                 state,
755                                 descriptor_modify_callback,
756                                 req);
757         LDB_REQ_SET_LOCATION(mod_req);
758         if (ret != LDB_SUCCESS) {
759                 return ret;
760         }
761
762         return ldb_next_request(module, mod_req);
763 }
764
765 /*
766   used to chain to the callers callback
767  */
768 static int descriptor_modify_callback(struct ldb_request *mod_req,
769                                       struct ldb_reply *ares)
770 {
771         struct descriptor_modify_state *state =
772                 talloc_get_type_abort(mod_req->context,
773                 struct descriptor_modify_state);
774         struct ldb_module *module = state->module;
775         struct ldb_context *ldb = ldb_module_get_ctx(module);
776         struct ldb_request *req = state->req;
777         struct ldb_result *res = NULL;
778         const char * const no_attrs[] = { NULL };
779         unsigned int i;
780         int ret;
781
782         if (!ares) {
783                 return ldb_module_done(req, NULL, NULL,
784                                        LDB_ERR_OPERATIONS_ERROR);
785         }
786
787         if (ares->type == LDB_REPLY_REFERRAL) {
788                 return ldb_module_send_referral(req, ares->referral);
789         }
790
791         if (ares->error != LDB_SUCCESS) {
792                 return ldb_module_done(req, ares->controls,
793                                        ares->response, ares->error);
794         }
795
796         if (ares->type != LDB_REPLY_DONE) {
797                 talloc_free(ares);
798                 return ldb_module_done(req, NULL, NULL,
799                                        LDB_ERR_OPERATIONS_ERROR);
800         }
801
802         ret = dsdb_module_search(module, ares, &res,
803                                  req->op.mod.message->dn,
804                                  LDB_SCOPE_ONELEVEL, no_attrs,
805                                  DSDB_FLAG_NEXT_MODULE |
806                                  DSDB_FLAG_AS_SYSTEM |
807                                  DSDB_SEARCH_SHOW_RECYCLED |
808                                  DSDB_SEARCH_SHOW_DELETED,
809                                  req, "(objectClass=*)");
810         if (ret != LDB_SUCCESS) {
811                 talloc_free(ares);
812                 return ldb_module_done(req, NULL, NULL, ret);
813         }
814
815         for (i=0; i < res->count; i++) {
816                 struct ldb_request *sub_req;
817                 struct ldb_result *mod_res;
818
819                 mod_res = talloc_zero(res, struct ldb_result);
820                 if (!mod_res) {
821                         return ldb_module_done(req, NULL, NULL,
822                                                LDB_ERR_OPERATIONS_ERROR);
823                 }
824
825                 ret = ldb_build_mod_req(&sub_req, ldb, req,
826                                         res->msgs[i],
827                                         NULL,
828                                         mod_res,
829                                         ldb_modify_default_callback,
830                                         req);
831                 LDB_REQ_SET_LOCATION(sub_req);
832                 if (ret != LDB_SUCCESS) {
833                         talloc_free(ares);
834                         return ldb_module_done(req, NULL, NULL,
835                                                LDB_ERR_OPERATIONS_ERROR);
836                 }
837
838                 ldb_req_mark_trusted(sub_req);
839
840                 ret = ldb_request_add_control(sub_req,
841                                               LDB_CONTROL_RECALCULATE_SD_OID,
842                                               true, req);
843                 if (ret != LDB_SUCCESS) {
844                         talloc_free(ares);
845                         return ldb_module_done(req, NULL, NULL,
846                                                LDB_ERR_OPERATIONS_ERROR);
847                 }
848                 ret = ldb_request_add_control(sub_req,
849                                               LDB_CONTROL_AS_SYSTEM_OID,
850                                               false, NULL);
851                 if (ret != LDB_SUCCESS) {
852                         talloc_free(ares);
853                         return ldb_module_done(req, NULL, NULL,
854                                                LDB_ERR_OPERATIONS_ERROR);
855                 }
856
857                 ret = ldb_request_add_control(sub_req,
858                                               LDB_CONTROL_SHOW_DELETED_OID,
859                                               false, NULL);
860                 if (ret != LDB_SUCCESS) {
861                         talloc_free(ares);
862                         return ldb_module_done(req, NULL, NULL,
863                                                LDB_ERR_OPERATIONS_ERROR);
864                 }
865                 ret = ldb_request_add_control(sub_req,
866                                               LDB_CONTROL_SHOW_RECYCLED_OID,
867                                               false, NULL);
868                 if (ret != LDB_SUCCESS) {
869                         talloc_free(ares);
870                         return ldb_module_done(req, NULL, NULL,
871                                                LDB_ERR_OPERATIONS_ERROR);
872                 }
873
874                 ret = descriptor_modify(module, sub_req);
875                 if (ret == LDB_SUCCESS) {
876                         ret = ldb_wait(sub_req->handle, LDB_WAIT_ALL);
877                 }
878                 if (ret != LDB_SUCCESS) {
879                         talloc_free(ares);
880                         return ldb_module_done(req, NULL, NULL,
881                                                LDB_ERR_OPERATIONS_ERROR);
882                 }
883
884                 talloc_free(mod_res);
885         }
886
887         return ldb_module_done(req, ares->controls,
888                                ares->response, ares->error);
889 }
890
891 static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
892 {
893         int ret;
894         struct ldb_context *ldb;
895         struct ldb_control *sd_control;
896         struct ldb_request *down_req;
897         struct descriptor_context *ac;
898
899         sd_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID);
900         if (!sd_control) {
901                 return ldb_next_request(module, req);
902         }
903
904         ldb = ldb_module_get_ctx(module);
905         ac = descriptor_init_context(module, req);
906         if (ac == NULL) {
907                 return ldb_operr(ldb);
908         }
909
910         ret = ldb_build_search_req_ex(&down_req, ldb, ac,
911                                       req->op.search.base,
912                                       req->op.search.scope,
913                                       req->op.search.tree,
914                                       req->op.search.attrs,
915                                       req->controls,
916                                       ac, descriptor_search_callback,
917                                       ac->req);
918         LDB_REQ_SET_LOCATION(down_req);
919         if (ret != LDB_SUCCESS) {
920                 return ret;
921         }
922         /* mark it as handled */
923         if (sd_control) {
924                 sd_control->critical = 0;
925         }
926
927         return ldb_next_request(ac->module, down_req);
928 }
929
930 struct descriptor_rename_state {
931         struct ldb_module *module;
932         struct ldb_request *req;
933 };
934
935 static int descriptor_rename_callback(struct ldb_request *req,
936                                       struct ldb_reply *reply);
937
938 static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
939 {
940         struct ldb_context *ldb = ldb_module_get_ctx(module);
941         struct descriptor_rename_state *state;
942         int ret;
943         struct ldb_request *rename_req = NULL;
944
945         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n",
946                   ldb_dn_get_linearized(req->op.rename.olddn));
947
948         /* do not manipulate our control entries */
949         if (ldb_dn_is_special(req->op.rename.olddn)) {
950                 return ldb_next_request(module, req);
951         }
952
953         state = talloc_zero(req, struct descriptor_rename_state);
954         if (state == NULL) {
955                 return ldb_oom(ldb);
956         }
957         state->module = module;
958         state->req = req;
959
960         ret = ldb_build_rename_req(&rename_req, ldb, state,
961                                    req->op.rename.olddn,
962                                    req->op.rename.newdn,
963                                    req->controls,
964                                    state,
965                                    descriptor_rename_callback,
966                                    req);
967         LDB_REQ_SET_LOCATION(rename_req);
968         if (ret != LDB_SUCCESS) {
969                 return ret;
970         }
971
972         return ldb_next_request(module, rename_req);
973 }
974
975 static int descriptor_rename_callback(struct ldb_request *rename_req,
976                                       struct ldb_reply *ares)
977 {
978         struct descriptor_rename_state *state =
979                 talloc_get_type_abort(rename_req->context,
980                 struct descriptor_rename_state);
981         struct ldb_module *module = state->module;
982         struct ldb_context *ldb = ldb_module_get_ctx(module);
983         struct ldb_request *req = state->req;
984         struct ldb_message *msg;
985         struct ldb_request *mod_req;
986         int ret;
987         struct ldb_result *mod_res;
988
989         if (!ares) {
990                 return ldb_module_done(req, NULL, NULL,
991                                        LDB_ERR_OPERATIONS_ERROR);
992         }
993
994         if (ares->type == LDB_REPLY_REFERRAL) {
995                 return ldb_module_send_referral(req, ares->referral);
996         }
997
998         if (ares->error != LDB_SUCCESS) {
999                 return ldb_module_done(req, ares->controls,
1000                                        ares->response, ares->error);
1001         }
1002
1003         if (ares->type != LDB_REPLY_DONE) {
1004                 talloc_free(ares);
1005                 return ldb_module_done(req, NULL, NULL,
1006                                        LDB_ERR_OPERATIONS_ERROR);
1007         }
1008
1009         msg = ldb_msg_new(ares);
1010         if (msg == NULL) {
1011                 talloc_free(ares);
1012                 return ldb_module_done(req, NULL, NULL,
1013                                        LDB_ERR_OPERATIONS_ERROR);
1014         }
1015         msg->dn = req->op.rename.newdn;
1016
1017         mod_res = talloc_zero(msg, struct ldb_result);
1018         if (mod_res == NULL) {
1019                 talloc_free(ares);
1020                 return ldb_module_done(req, NULL, NULL,
1021                                        LDB_ERR_OPERATIONS_ERROR);
1022         }
1023
1024         ret = ldb_build_mod_req(&mod_req, ldb, msg,
1025                                 msg,
1026                                 NULL,
1027                                 mod_res,
1028                                 ldb_modify_default_callback,
1029                                 req);
1030         LDB_REQ_SET_LOCATION(mod_req);
1031         if (ret != LDB_SUCCESS) {
1032                 talloc_free(ares);
1033                 return ldb_module_done(req, NULL, NULL,
1034                                        LDB_ERR_OPERATIONS_ERROR);
1035         }
1036
1037         ldb_req_mark_trusted(mod_req);
1038
1039         ret = ldb_request_add_control(mod_req,
1040                                       LDB_CONTROL_RECALCULATE_SD_OID,
1041                                       true, req);
1042         if (ret != LDB_SUCCESS) {
1043                 talloc_free(ares);
1044                 return ldb_module_done(req, NULL, NULL,
1045                                        LDB_ERR_OPERATIONS_ERROR);
1046         }
1047         ret = ldb_request_add_control(mod_req,
1048                                       LDB_CONTROL_AS_SYSTEM_OID,
1049                                       false, NULL);
1050         if (ret != LDB_SUCCESS) {
1051                 talloc_free(ares);
1052                 return ldb_module_done(req, NULL, NULL,
1053                                        LDB_ERR_OPERATIONS_ERROR);
1054         }
1055
1056         ret = ldb_request_add_control(mod_req,
1057                                       LDB_CONTROL_SHOW_DELETED_OID,
1058                                       false, NULL);
1059         if (ret != LDB_SUCCESS) {
1060                 talloc_free(ares);
1061                 return ldb_module_done(req, NULL, NULL,
1062                                        LDB_ERR_OPERATIONS_ERROR);
1063         }
1064         ret = ldb_request_add_control(mod_req,
1065                                       LDB_CONTROL_SHOW_RECYCLED_OID,
1066                                       false, NULL);
1067         if (ret != LDB_SUCCESS) {
1068                 talloc_free(ares);
1069                 return ldb_module_done(req, NULL, NULL,
1070                                        LDB_ERR_OPERATIONS_ERROR);
1071         }
1072
1073         ret = descriptor_modify(module, mod_req);
1074         if (ret == LDB_SUCCESS) {
1075                 ret = ldb_wait(mod_req->handle, LDB_WAIT_ALL);
1076         }
1077         if (ret != LDB_SUCCESS) {
1078                 talloc_free(ares);
1079                 return ldb_module_done(req, NULL, NULL,
1080                                        LDB_ERR_OPERATIONS_ERROR);
1081         }
1082
1083         talloc_free(msg);
1084
1085         return ldb_module_done(req, ares->controls,
1086                                ares->response, ares->error);
1087 }
1088
1089 static int descriptor_init(struct ldb_module *module)
1090 {
1091         int ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
1092         struct ldb_context *ldb = ldb_module_get_ctx(module);
1093         if (ret != LDB_SUCCESS) {
1094                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1095                         "descriptor: Unable to register control with rootdse!\n");
1096                 return ldb_operr(ldb);
1097         }
1098         return ldb_next_init(module);
1099 }
1100
1101
1102 static const struct ldb_module_ops ldb_descriptor_module_ops = {
1103         .name          = "descriptor",
1104         .search        = descriptor_search,
1105         .add           = descriptor_add,
1106         .modify        = descriptor_modify,
1107         .rename        = descriptor_rename,
1108         .init_context  = descriptor_init
1109 };
1110
1111 int ldb_descriptor_module_init(const char *version)
1112 {
1113         LDB_MODULE_CHECK_VERSION(version);
1114         return ldb_register_module(&ldb_descriptor_module_ops);
1115 }