recalc sd trusted...
[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         sd = get_new_descriptor(module, dn, state,
702                                 objectclass, parent_sd,
703                                 user_sd, old_sd, sd_flags);
704         msg = ldb_msg_copy_shallow(state, req->op.mod.message);
705         if (sd != NULL) {
706                 struct ldb_message_element *sd_element;
707                 if (user_sd != NULL) {
708                         sd_element = ldb_msg_find_element(msg,
709                                                           "nTSecurityDescriptor");
710                         sd_element->values[0] = *sd;
711                 } else if (sd_recalculate_control != NULL) {
712                         /* In this branch we really do force the recalculation
713                          * of the SD */
714                         ldb_msg_remove_attr(msg, "nTSecurityDescriptor");
715
716                         ret = ldb_msg_add_steal_value(msg,
717                                                       "nTSecurityDescriptor",
718                                                       sd);
719                         if (ret != LDB_SUCCESS) {
720                                 return ldb_error(ldb, ret,
721                                          "descriptor_modify: Could not replace SD value in message.");
722                         }
723                         sd_element = ldb_msg_find_element(msg,
724                                                           "nTSecurityDescriptor");
725                         sd_element->flags = LDB_FLAG_MOD_REPLACE;
726                 }
727         }
728
729         /* mark the controls as non-critical since we've handled them */
730         if (sd_flags_control != NULL) {
731                 sd_flags_control->critical = 0;
732         }
733         if (sd_recalculate_control != NULL) {
734                 sd_recalculate_control->critical = 0;
735         }
736
737         ret = ldb_build_mod_req(&mod_req, ldb, state,
738                                 msg,
739                                 req->controls,
740                                 state,
741                                 descriptor_modify_callback,
742                                 req);
743         LDB_REQ_SET_LOCATION(mod_req);
744         if (ret != LDB_SUCCESS) {
745                 return ret;
746         }
747
748         return ldb_next_request(module, mod_req);
749 }
750
751 /*
752   used to chain to the callers callback
753  */
754 static int descriptor_modify_callback(struct ldb_request *mod_req,
755                                       struct ldb_reply *ares)
756 {
757         struct descriptor_modify_state *state =
758                 talloc_get_type_abort(mod_req->context,
759                 struct descriptor_modify_state);
760         struct ldb_module *module = state->module;
761         struct ldb_context *ldb = ldb_module_get_ctx(module);
762         struct ldb_request *req = state->req;
763         struct ldb_result *res = NULL;
764         const char * const no_attrs[] = { NULL };
765         unsigned int i;
766         int ret;
767
768         if (!ares) {
769                 return ldb_module_done(req, NULL, NULL,
770                                        LDB_ERR_OPERATIONS_ERROR);
771         }
772
773         if (ares->type == LDB_REPLY_REFERRAL) {
774                 return ldb_module_send_referral(req, ares->referral);
775         }
776
777         if (ares->error != LDB_SUCCESS) {
778                 return ldb_module_done(req, ares->controls,
779                                        ares->response, ares->error);
780         }
781
782         if (ares->type != LDB_REPLY_DONE) {
783                 talloc_free(ares);
784                 return ldb_module_done(req, NULL, NULL,
785                                        LDB_ERR_OPERATIONS_ERROR);
786         }
787
788         ret = dsdb_module_search(module, ares, &res,
789                                  req->op.mod.message->dn,
790                                  LDB_SCOPE_ONELEVEL, no_attrs,
791                                  DSDB_FLAG_NEXT_MODULE |
792                                  DSDB_FLAG_AS_SYSTEM |
793                                  DSDB_SEARCH_SHOW_RECYCLED |
794                                  DSDB_SEARCH_SHOW_DELETED,
795                                  req, "(objectClass=*)");
796         if (ret != LDB_SUCCESS) {
797                 talloc_free(ares);
798                 return ldb_module_done(req, NULL, NULL, ret);
799         }
800
801         for (i=0; i < res->count; i++) {
802                 struct ldb_request *sub_req;
803                 struct ldb_result *mod_res;
804
805                 mod_res = talloc_zero(res, struct ldb_result);
806                 if (!mod_res) {
807                         return ldb_module_done(req, NULL, NULL,
808                                                LDB_ERR_OPERATIONS_ERROR);
809                 }
810
811                 ret = ldb_build_mod_req(&sub_req, ldb, req,
812                                         res->msgs[i],
813                                         NULL,
814                                         mod_res,
815                                         ldb_modify_default_callback,
816                                         req);
817                 LDB_REQ_SET_LOCATION(sub_req);
818                 if (ret != LDB_SUCCESS) {
819                         talloc_free(ares);
820                         return ldb_module_done(req, NULL, NULL,
821                                                LDB_ERR_OPERATIONS_ERROR);
822                 }
823
824                 ldb_req_mark_trusted(sub_req);
825
826                 ret = ldb_request_add_control(sub_req,
827                                               LDB_CONTROL_RECALCULATE_SD_OID,
828                                               true, NULL);
829                 if (ret != LDB_SUCCESS) {
830                         talloc_free(ares);
831                         return ldb_module_done(req, NULL, NULL,
832                                                LDB_ERR_OPERATIONS_ERROR);
833                 }
834                 ret = ldb_request_add_control(sub_req,
835                                               LDB_CONTROL_AS_SYSTEM_OID,
836                                               false, NULL);
837                 if (ret != LDB_SUCCESS) {
838                         talloc_free(ares);
839                         return ldb_module_done(req, NULL, NULL,
840                                                LDB_ERR_OPERATIONS_ERROR);
841                 }
842
843                 ret = ldb_request_add_control(sub_req,
844                                               LDB_CONTROL_SHOW_DELETED_OID,
845                                               false, NULL);
846                 if (ret != LDB_SUCCESS) {
847                         talloc_free(ares);
848                         return ldb_module_done(req, NULL, NULL,
849                                                LDB_ERR_OPERATIONS_ERROR);
850                 }
851                 ret = ldb_request_add_control(sub_req,
852                                               LDB_CONTROL_SHOW_RECYCLED_OID,
853                                               false, NULL);
854                 if (ret != LDB_SUCCESS) {
855                         talloc_free(ares);
856                         return ldb_module_done(req, NULL, NULL,
857                                                LDB_ERR_OPERATIONS_ERROR);
858                 }
859
860                 ret = descriptor_modify(module, sub_req);
861                 if (ret == LDB_SUCCESS) {
862                         ret = ldb_wait(sub_req->handle, LDB_WAIT_ALL);
863                 }
864                 if (ret != LDB_SUCCESS) {
865                         talloc_free(ares);
866                         return ldb_module_done(req, NULL, NULL,
867                                                LDB_ERR_OPERATIONS_ERROR);
868                 }
869
870                 talloc_free(mod_res);
871         }
872
873         return ldb_module_done(req, ares->controls,
874                                ares->response, ares->error);
875 }
876
877 static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
878 {
879         int ret;
880         struct ldb_context *ldb;
881         struct ldb_control *sd_control;
882         struct ldb_request *down_req;
883         struct descriptor_context *ac;
884
885         sd_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID);
886         if (!sd_control) {
887                 return ldb_next_request(module, req);
888         }
889
890         ldb = ldb_module_get_ctx(module);
891         ac = descriptor_init_context(module, req);
892         if (ac == NULL) {
893                 return ldb_operr(ldb);
894         }
895
896         ret = ldb_build_search_req_ex(&down_req, ldb, ac,
897                                       req->op.search.base,
898                                       req->op.search.scope,
899                                       req->op.search.tree,
900                                       req->op.search.attrs,
901                                       req->controls,
902                                       ac, descriptor_search_callback,
903                                       ac->req);
904         LDB_REQ_SET_LOCATION(down_req);
905         if (ret != LDB_SUCCESS) {
906                 return ret;
907         }
908         /* mark it as handled */
909         if (sd_control) {
910                 sd_control->critical = 0;
911         }
912
913         return ldb_next_request(ac->module, down_req);
914 }
915
916 struct descriptor_rename_state {
917         struct ldb_module *module;
918         struct ldb_request *req;
919 };
920
921 static int descriptor_rename_callback(struct ldb_request *req,
922                                       struct ldb_reply *reply);
923
924 static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
925 {
926         struct ldb_context *ldb = ldb_module_get_ctx(module);
927         struct descriptor_rename_state *state;
928         int ret;
929         struct ldb_request *rename_req = NULL;
930
931         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n",
932                   ldb_dn_get_linearized(req->op.rename.olddn));
933
934         /* do not manipulate our control entries */
935         if (ldb_dn_is_special(req->op.rename.olddn)) {
936                 return ldb_next_request(module, req);
937         }
938
939         state = talloc_zero(req, struct descriptor_rename_state);
940         if (state == NULL) {
941                 return ldb_oom(ldb);
942         }
943         state->module = module;
944         state->req = req;
945
946         ret = ldb_build_rename_req(&rename_req, ldb, state,
947                                    req->op.rename.olddn,
948                                    req->op.rename.newdn,
949                                    req->controls,
950                                    state,
951                                    descriptor_rename_callback,
952                                    req);
953         LDB_REQ_SET_LOCATION(rename_req);
954         if (ret != LDB_SUCCESS) {
955                 return ret;
956         }
957
958         return ldb_next_request(module, rename_req);
959 }
960
961 static int descriptor_rename_callback(struct ldb_request *rename_req,
962                                       struct ldb_reply *ares)
963 {
964         struct descriptor_rename_state *state =
965                 talloc_get_type_abort(rename_req->context,
966                 struct descriptor_rename_state);
967         struct ldb_module *module = state->module;
968         struct ldb_context *ldb = ldb_module_get_ctx(module);
969         struct ldb_request *req = state->req;
970         struct ldb_message *msg;
971         struct ldb_request *mod_req;
972         int ret;
973         struct ldb_result *mod_res;
974
975         if (!ares) {
976                 return ldb_module_done(req, NULL, NULL,
977                                        LDB_ERR_OPERATIONS_ERROR);
978         }
979
980         if (ares->type == LDB_REPLY_REFERRAL) {
981                 return ldb_module_send_referral(req, ares->referral);
982         }
983
984         if (ares->error != LDB_SUCCESS) {
985                 return ldb_module_done(req, ares->controls,
986                                        ares->response, ares->error);
987         }
988
989         if (ares->type != LDB_REPLY_DONE) {
990                 talloc_free(ares);
991                 return ldb_module_done(req, NULL, NULL,
992                                        LDB_ERR_OPERATIONS_ERROR);
993         }
994
995         msg = ldb_msg_new(ares);
996         if (msg == NULL) {
997                 talloc_free(ares);
998                 return ldb_module_done(req, NULL, NULL,
999                                        LDB_ERR_OPERATIONS_ERROR);
1000         }
1001         msg->dn = req->op.rename.newdn;
1002
1003         mod_res = talloc_zero(msg, struct ldb_result);
1004         if (mod_res == NULL) {
1005                 talloc_free(ares);
1006                 return ldb_module_done(req, NULL, NULL,
1007                                        LDB_ERR_OPERATIONS_ERROR);
1008         }
1009
1010         ret = ldb_build_mod_req(&mod_req, ldb, msg,
1011                                 msg,
1012                                 NULL,
1013                                 mod_res,
1014                                 ldb_modify_default_callback,
1015                                 req);
1016         LDB_REQ_SET_LOCATION(mod_req);
1017         if (ret != LDB_SUCCESS) {
1018                 talloc_free(ares);
1019                 return ldb_module_done(req, NULL, NULL,
1020                                        LDB_ERR_OPERATIONS_ERROR);
1021         }
1022
1023         ldb_req_mark_trusted(mod_req);
1024
1025         ret = ldb_request_add_control(mod_req,
1026                                       LDB_CONTROL_RECALCULATE_SD_OID,
1027                                       true, NULL);
1028         if (ret != LDB_SUCCESS) {
1029                 talloc_free(ares);
1030                 return ldb_module_done(req, NULL, NULL,
1031                                        LDB_ERR_OPERATIONS_ERROR);
1032         }
1033         ret = ldb_request_add_control(mod_req,
1034                                       LDB_CONTROL_AS_SYSTEM_OID,
1035                                       false, NULL);
1036         if (ret != LDB_SUCCESS) {
1037                 talloc_free(ares);
1038                 return ldb_module_done(req, NULL, NULL,
1039                                        LDB_ERR_OPERATIONS_ERROR);
1040         }
1041
1042         ret = ldb_request_add_control(mod_req,
1043                                       LDB_CONTROL_SHOW_DELETED_OID,
1044                                       false, NULL);
1045         if (ret != LDB_SUCCESS) {
1046                 talloc_free(ares);
1047                 return ldb_module_done(req, NULL, NULL,
1048                                        LDB_ERR_OPERATIONS_ERROR);
1049         }
1050         ret = ldb_request_add_control(mod_req,
1051                                       LDB_CONTROL_SHOW_RECYCLED_OID,
1052                                       false, NULL);
1053         if (ret != LDB_SUCCESS) {
1054                 talloc_free(ares);
1055                 return ldb_module_done(req, NULL, NULL,
1056                                        LDB_ERR_OPERATIONS_ERROR);
1057         }
1058
1059         ret = descriptor_modify(module, mod_req);
1060         if (ret == LDB_SUCCESS) {
1061                 ret = ldb_wait(mod_req->handle, LDB_WAIT_ALL);
1062         }
1063         if (ret != LDB_SUCCESS) {
1064                 talloc_free(ares);
1065                 return ldb_module_done(req, NULL, NULL,
1066                                        LDB_ERR_OPERATIONS_ERROR);
1067         }
1068
1069         talloc_free(msg);
1070
1071         return ldb_module_done(req, ares->controls,
1072                                ares->response, ares->error);
1073 }
1074
1075 static int descriptor_init(struct ldb_module *module)
1076 {
1077         int ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
1078         struct ldb_context *ldb = ldb_module_get_ctx(module);
1079         if (ret != LDB_SUCCESS) {
1080                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1081                         "descriptor: Unable to register control with rootdse!\n");
1082                 return ldb_operr(ldb);
1083         }
1084         return ldb_next_init(module);
1085 }
1086
1087
1088 static const struct ldb_module_ops ldb_descriptor_module_ops = {
1089         .name          = "descriptor",
1090         .search        = descriptor_search,
1091         .add           = descriptor_add,
1092         .modify        = descriptor_modify,
1093         .rename        = descriptor_rename,
1094         .init_context  = descriptor_init
1095 };
1096
1097 int ldb_descriptor_module_init(const char *version)
1098 {
1099         LDB_MODULE_CHECK_VERSION(version);
1100         return ldb_register_module(&ldb_descriptor_module_ops);
1101 }