0ea91ba60071ee595dd3710c4c151baf7d1c7d5f
[samba.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 "dsdb/samdb/ldb_modules/schema.h"
43 #include "auth/auth.h"
44 #include "param/param.h"
45 #include "util.h"
46
47 struct descriptor_data {
48         int _dummy;
49 };
50
51 struct descriptor_context {
52         struct ldb_module *module;
53         struct ldb_request *req;
54         struct ldb_message *msg;
55         struct ldb_reply *search_res;
56         struct ldb_reply *search_oc_res;
57         struct ldb_val *parentsd_val;
58         struct ldb_message_element *sd_element;
59         struct ldb_val *sd_val;
60         int (*step_fn)(struct descriptor_context *);
61 };
62
63 struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
64                                struct ldb_dn *dn,
65                                struct security_token *token,
66                                struct ldb_context *ldb)
67 {
68         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
69         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
70         struct dom_sid *da_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
71         struct dom_sid *ea_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
72         struct dom_sid *sa_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
73         struct dom_sid *dag_sid;
74         struct ldb_dn *nc_root;
75         int ret;
76
77         ret = dsdb_find_nc_root(ldb, tmp_ctx, dn, &nc_root);
78         if (ret != LDB_SUCCESS) {
79                 talloc_free(tmp_ctx);
80                 return NULL;
81         }
82
83         if (ldb_dn_compare(nc_root, ldb_get_schema_basedn(ldb)) == 0) {
84                 if (security_token_has_sid(token, sa_sid))
85                         dag_sid = dom_sid_dup(mem_ctx, sa_sid);
86                 else if (security_token_has_sid(token, ea_sid))
87                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
88                 else if (security_token_has_sid(token, da_sid))
89                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
90                 else
91                         dag_sid = NULL;
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         } else if (ldb_dn_compare(nc_root, ldb_get_default_basedn(ldb)) == 0) {
100                 if (security_token_has_sid(token, da_sid))
101                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
102                 else if (security_token_has_sid(token, ea_sid))
103                                 dag_sid = dom_sid_dup(mem_ctx, ea_sid);
104                 else
105                         dag_sid = NULL;
106         } else {
107                 dag_sid = NULL;
108         }
109
110         talloc_free(tmp_ctx);
111         return dag_sid;
112 }
113
114 static struct security_descriptor *get_sd_unpacked(struct ldb_module *module, TALLOC_CTX *mem_ctx,
115                                             const struct dsdb_class *objectclass)
116 {
117         struct ldb_context *ldb = ldb_module_get_ctx(module);
118         struct security_descriptor *sd;
119         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
120
121         if (!objectclass->defaultSecurityDescriptor || !domain_sid) {
122                 return NULL;
123         }
124
125         sd = sddl_decode(mem_ctx,
126                          objectclass->defaultSecurityDescriptor,
127                          domain_sid);
128         return sd;
129 }
130
131 static struct dom_sid *get_default_group(TALLOC_CTX *mem_ctx,
132                                          struct ldb_context *ldb,
133                                          struct dom_sid *dag)
134 {
135         if (dsdb_functional_level(ldb) >= DS_DOMAIN_FUNCTION_2008) {
136                 return dag;
137         }
138
139         return NULL;
140 }
141
142 static struct security_descriptor *descr_handle_sd_flags(TALLOC_CTX *mem_ctx,
143                                                          struct security_descriptor *new_sd,
144                                                          struct security_descriptor *old_sd,
145                                                          uint32_t sd_flags)
146 {
147         struct security_descriptor *final_sd; 
148         /* if there is no control or control == 0 modify everything */
149         if (!sd_flags) {
150                 return new_sd;
151         }
152
153         final_sd = talloc_zero(mem_ctx, struct security_descriptor);
154         final_sd->revision = SECURITY_DESCRIPTOR_REVISION_1;
155         final_sd->type = SEC_DESC_SELF_RELATIVE;
156
157         if (sd_flags & (SECINFO_OWNER)) {
158                 final_sd->owner_sid = talloc_memdup(mem_ctx, new_sd->owner_sid, sizeof(struct dom_sid));
159                 final_sd->type |= new_sd->type & SEC_DESC_OWNER_DEFAULTED;
160         }
161         else if (old_sd) {
162                 final_sd->owner_sid = talloc_memdup(mem_ctx, old_sd->owner_sid, sizeof(struct dom_sid));
163                 final_sd->type |= old_sd->type & SEC_DESC_OWNER_DEFAULTED;
164         }
165
166         if (sd_flags & (SECINFO_GROUP)) {
167                 final_sd->group_sid = talloc_memdup(mem_ctx, new_sd->group_sid, sizeof(struct dom_sid));
168                 final_sd->type |= new_sd->type & SEC_DESC_GROUP_DEFAULTED;
169         } 
170         else if (old_sd) {
171                 final_sd->group_sid = talloc_memdup(mem_ctx, old_sd->group_sid, sizeof(struct dom_sid));
172                 final_sd->type |= old_sd->type & SEC_DESC_GROUP_DEFAULTED;
173         }
174
175         if (sd_flags & (SECINFO_SACL)) {
176                 final_sd->sacl = security_acl_dup(mem_ctx,new_sd->sacl);
177                 final_sd->type |= new_sd->type & (SEC_DESC_SACL_PRESENT |
178                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
179                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
180                         SEC_DESC_SERVER_SECURITY);
181         } 
182         else if (old_sd && old_sd->sacl) {
183                 final_sd->sacl = security_acl_dup(mem_ctx,old_sd->sacl);
184                 final_sd->type |= old_sd->type & (SEC_DESC_SACL_PRESENT |
185                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
186                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
187                         SEC_DESC_SERVER_SECURITY);
188         }
189
190         if (sd_flags & (SECINFO_DACL)) {
191                 final_sd->dacl = security_acl_dup(mem_ctx,new_sd->dacl);
192                 final_sd->type |= new_sd->type & (SEC_DESC_DACL_PRESENT |
193                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
194                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
195                         SEC_DESC_DACL_TRUSTED);
196         } 
197         else if (old_sd && old_sd->dacl) {
198                 final_sd->dacl = security_acl_dup(mem_ctx,old_sd->dacl);
199                 final_sd->type |= old_sd->type & (SEC_DESC_DACL_PRESENT |
200                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
201                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
202                         SEC_DESC_DACL_TRUSTED);
203         }
204         /* not so sure about this */
205         final_sd->type |= new_sd->type & SEC_DESC_RM_CONTROL_VALID;
206         return final_sd;
207 }
208
209 static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
210                                      struct ldb_dn *dn,
211                                      TALLOC_CTX *mem_ctx,
212                                      const struct dsdb_class *objectclass,
213                                      const struct ldb_val *parent,
214                                      struct ldb_val *object,
215                                      struct ldb_val *old_sd,
216                                      uint32_t sd_flags)
217 {
218         struct security_descriptor *user_descriptor = NULL, *parent_descriptor = NULL;
219         struct security_descriptor *old_descriptor = NULL;
220         struct security_descriptor *new_sd, *final_sd;
221         DATA_BLOB *linear_sd;
222         enum ndr_err_code ndr_err;
223         struct ldb_context *ldb = ldb_module_get_ctx(module);
224         struct auth_session_info *session_info
225                 = ldb_get_opaque(ldb, "sessionInfo");
226         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
227         char *sddl_sd;
228         struct dom_sid *default_owner;
229         struct dom_sid *default_group;
230
231         if (object) {
232                 user_descriptor = talloc(mem_ctx, struct security_descriptor);
233                 if (!user_descriptor) {
234                         return NULL;
235                 }
236                 ndr_err = ndr_pull_struct_blob(object, user_descriptor, 
237                                                user_descriptor,
238                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
239
240                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
241                         talloc_free(user_descriptor);
242                         return NULL;
243                 }
244         } else {
245                 user_descriptor = get_sd_unpacked(module, mem_ctx, objectclass);
246         }
247
248         if (old_sd) {
249                 old_descriptor = talloc(mem_ctx, struct security_descriptor);
250                 if (!old_descriptor) {
251                         return NULL;
252                 }
253                 ndr_err = ndr_pull_struct_blob(old_sd, old_descriptor, 
254                                                old_descriptor,
255                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
256
257                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
258                         talloc_free(old_descriptor);
259                         return NULL;
260                 }
261         }
262
263         if (parent) {
264                 parent_descriptor = talloc(mem_ctx, struct security_descriptor);
265                 if (!parent_descriptor) {
266                         return NULL;
267                 }
268                 ndr_err = ndr_pull_struct_blob(parent, parent_descriptor, 
269                                                parent_descriptor,
270                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
271
272                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
273                         talloc_free(parent_descriptor);
274                         return NULL;
275                 }
276         }
277
278         default_owner = get_default_ag(mem_ctx, dn,
279                                        session_info->security_token, ldb);
280         default_group = get_default_group(mem_ctx, ldb, default_owner);
281         new_sd = create_security_descriptor(mem_ctx, parent_descriptor, user_descriptor, true,
282                                             NULL, SEC_DACL_AUTO_INHERIT|SEC_SACL_AUTO_INHERIT,
283                                             session_info->security_token,
284                                             default_owner, default_group,
285                                             map_generic_rights_ds);
286         if (!new_sd) {
287                 return NULL;
288         }
289         final_sd = descr_handle_sd_flags(mem_ctx, new_sd, old_descriptor, sd_flags);
290
291         if (!final_sd) {
292                 return NULL;
293         }
294
295         if (final_sd->dacl) {
296                 final_sd->dacl->revision = SECURITY_ACL_REVISION_ADS;
297         }
298         if (final_sd->sacl) {
299                 final_sd->sacl->revision = SECURITY_ACL_REVISION_ADS;
300         }
301
302         sddl_sd = sddl_encode(mem_ctx, final_sd, domain_sid);
303         DEBUG(10, ("Object %s created with desriptor %s\n\n", ldb_dn_get_linearized(dn), sddl_sd));
304
305         linear_sd = talloc(mem_ctx, DATA_BLOB);
306         if (!linear_sd) {
307                 return NULL;
308         }
309
310         ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
311                                        final_sd,
312                                        (ndr_push_flags_fn_t)ndr_push_security_descriptor);
313         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
314                 return NULL;
315         }
316
317         return linear_sd;
318 }
319
320 static DATA_BLOB *descr_get_descriptor_to_show(struct ldb_module *module,
321                                                TALLOC_CTX *mem_ctx,
322                                                struct ldb_val *sd,
323                                                uint32_t sd_flags)
324 {
325         struct security_descriptor *old_sd, *final_sd;
326         DATA_BLOB *linear_sd;
327         enum ndr_err_code ndr_err;
328
329         old_sd = talloc(mem_ctx, struct security_descriptor);
330         if (!old_sd) {
331                 return NULL;
332         }
333         ndr_err = ndr_pull_struct_blob(sd, old_sd, 
334                                        old_sd,
335                                        (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
336
337         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
338                 talloc_free(old_sd);
339                 return NULL;
340         }
341
342         final_sd = descr_handle_sd_flags(mem_ctx, old_sd, NULL, sd_flags);
343
344         if (!final_sd) {
345                 return NULL;
346         }
347
348         linear_sd = talloc(mem_ctx, DATA_BLOB);
349         if (!linear_sd) {
350                 return NULL;
351         }
352
353         ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
354                                        final_sd,
355                                        (ndr_push_flags_fn_t)ndr_push_security_descriptor);
356         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
357                 return NULL;
358         }
359
360         return linear_sd;
361 }
362
363 static struct descriptor_context *descriptor_init_context(struct ldb_module *module,
364                                                           struct ldb_request *req)
365 {
366         struct ldb_context *ldb;
367         struct descriptor_context *ac;
368
369         ldb = ldb_module_get_ctx(module);
370
371         ac = talloc_zero(req, struct descriptor_context);
372         if (ac == NULL) {
373                 ldb_set_errstring(ldb, "Out of Memory");
374                 return NULL;
375         }
376
377         ac->module = module;
378         ac->req = req;
379         return ac;
380 }
381
382 static int get_search_callback(struct ldb_request *req, struct ldb_reply *ares)
383 {
384         struct ldb_context *ldb;
385         struct descriptor_context *ac;
386         int ret;
387
388         ac = talloc_get_type(req->context, struct descriptor_context);
389         ldb = ldb_module_get_ctx(ac->module);
390
391         if (!ares) {
392                 return ldb_module_done(ac->req, NULL, NULL,
393                                         LDB_ERR_OPERATIONS_ERROR);
394         }
395         if (ares->error != LDB_SUCCESS &&
396             ares->error != LDB_ERR_NO_SUCH_OBJECT) {
397                 return ldb_module_done(ac->req, ares->controls,
398                                         ares->response, ares->error);
399         }
400
401         ldb_reset_err_string(ldb);
402
403         switch (ares->type) {
404         case LDB_REPLY_ENTRY:
405                 if (ac->search_res != NULL) {
406                         ldb_set_errstring(ldb, "Too many results");
407                         talloc_free(ares);
408                         return ldb_module_done(ac->req, NULL, NULL,
409                                                 LDB_ERR_OPERATIONS_ERROR);
410                 }
411
412                 ac->search_res = talloc_steal(ac, ares);
413                 break;
414
415         case LDB_REPLY_REFERRAL:
416                 /* ignore */
417                 talloc_free(ares);
418                 break;
419
420         case LDB_REPLY_DONE:
421                 talloc_free(ares);
422                 ret = ac->step_fn(ac);
423                 if (ret != LDB_SUCCESS) {
424                         return ldb_module_done(ac->req, NULL, NULL, ret);
425                 }
426                 break;
427         }
428
429         return LDB_SUCCESS;
430 }
431
432 static int get_search_oc_callback(struct ldb_request *req, struct ldb_reply *ares)
433 {
434         struct ldb_context *ldb;
435         struct descriptor_context *ac;
436         int ret;
437
438         ac = talloc_get_type(req->context, struct descriptor_context);
439         ldb = ldb_module_get_ctx(ac->module);
440
441         if (!ares) {
442                 return ldb_module_done(ac->req, NULL, NULL,
443                                         LDB_ERR_OPERATIONS_ERROR);
444         }
445         if (ares->error != LDB_SUCCESS &&
446             ares->error != LDB_ERR_NO_SUCH_OBJECT) {
447                 return ldb_module_done(ac->req, ares->controls,
448                                         ares->response, ares->error);
449         }
450
451         ldb_reset_err_string(ldb);
452
453         switch (ares->type) {
454         case LDB_REPLY_ENTRY:
455                 if (ac->search_oc_res != NULL) {
456                         ldb_set_errstring(ldb, "Too many results");
457                         talloc_free(ares);
458                         return ldb_module_done(ac->req, NULL, NULL,
459                                                 LDB_ERR_OPERATIONS_ERROR);
460                 }
461
462                 ac->search_oc_res = talloc_steal(ac, ares);
463                 break;
464
465         case LDB_REPLY_REFERRAL:
466                 /* ignore */
467                 talloc_free(ares);
468                 break;
469
470         case LDB_REPLY_DONE:
471                 talloc_free(ares);
472                 ret = ac->step_fn(ac);
473                 if (ret != LDB_SUCCESS) {
474                         return ldb_module_done(ac->req, NULL, NULL, ret);
475                 }
476                 break;
477         }
478
479         return LDB_SUCCESS;
480 }
481
482 static int descriptor_search_callback(struct ldb_request *req, struct ldb_reply *ares)
483 {
484         struct descriptor_context *ac;
485         struct ldb_control *sd_control;
486         struct ldb_val *sd_val = NULL;
487         struct ldb_message_element *sd_el;
488         DATA_BLOB *show_sd;
489         int ret;
490         uint32_t sd_flags = 0;
491
492         ac = talloc_get_type(req->context, struct descriptor_context);
493
494         if (!ares) {
495                 ret = LDB_ERR_OPERATIONS_ERROR;
496                 goto fail;
497         }
498         if (ares->error != LDB_SUCCESS) {
499                 return ldb_module_done(ac->req, ares->controls,
500                                         ares->response, ares->error);
501         }
502
503         sd_control = ldb_request_get_control(ac->req, LDB_CONTROL_SD_FLAGS_OID);
504         if (sd_control) {
505                 struct ldb_sd_flags_control *sdctr = (struct ldb_sd_flags_control *)sd_control->data;
506                 sd_flags = sdctr->secinfo_flags;
507                 /* we only care for the last 4 bits */
508                 sd_flags = sd_flags & 0x0000000F;
509                 if (sd_flags == 0) {
510                         /* MS-ADTS 3.1.1.3.4.1.11 says that no bits
511                            equals all 4 bits */
512                         sd_flags = 0xF;
513                 }
514         }
515
516         switch (ares->type) {
517         case LDB_REPLY_ENTRY:
518                 if (sd_flags != 0) {
519                         sd_el = ldb_msg_find_element(ares->message, "nTSecurityDescriptor");
520                         if (sd_el) {
521                                 sd_val = sd_el->values;
522                         }
523                 }
524                 if (sd_val) {
525                         show_sd = descr_get_descriptor_to_show(ac->module, ac->req,
526                                                                sd_val, sd_flags);
527                         if (!show_sd) {
528                                 ret = LDB_ERR_OPERATIONS_ERROR;
529                                 goto fail;
530                         }
531                         ldb_msg_remove_attr(ares->message, "nTSecurityDescriptor");
532                         ret = ldb_msg_add_steal_value(ares->message, "nTSecurityDescriptor", show_sd);
533                         if (ret != LDB_SUCCESS) {
534                                 goto fail;
535                         }
536                 }
537                 return ldb_module_send_entry(ac->req, ares->message, ares->controls);
538
539         case LDB_REPLY_REFERRAL:
540                 return ldb_module_send_referral(ac->req, ares->referral);
541
542         case LDB_REPLY_DONE:
543                 return ldb_module_done(ac->req, ares->controls,
544                                         ares->response, ares->error);
545         }
546
547 fail:
548         talloc_free(ares);
549         return ldb_module_done(ac->req, NULL, NULL, ret);
550 }
551
552 static int descriptor_do_mod(struct descriptor_context *ac)
553 {
554         struct ldb_context *ldb;
555         const struct dsdb_schema *schema;
556         struct ldb_request *mod_req;
557         struct ldb_message_element *objectclass_element, *oldsd_el;
558         struct ldb_val *oldsd_val = NULL;
559         int ret;
560         DATA_BLOB *sd;
561         const struct dsdb_class *objectclass;
562         struct ldb_control *sd_control;
563         struct ldb_control *sd_control2;
564         uint32_t sd_flags = 0;
565
566         ldb = ldb_module_get_ctx(ac->module);
567         schema = dsdb_get_schema(ldb, ac);
568
569         objectclass_element = ldb_msg_find_element(ac->search_oc_res->message,
570                                                    "objectClass");
571         if (objectclass_element == NULL) {
572                 return ldb_operr(ldb);
573         }
574
575         objectclass = get_last_structural_class(schema, objectclass_element);
576         if (objectclass == NULL) {
577                 return ldb_operr(ldb);
578         }
579
580         sd_control = ldb_request_get_control(ac->req, LDB_CONTROL_SD_FLAGS_OID);
581         sd_control2 = ldb_request_get_control(ac->req,
582                                               LDB_CONTROL_RECALCULATE_SD_OID);
583         if (sd_control) {
584                 struct ldb_sd_flags_control *sdctr = (struct ldb_sd_flags_control *)sd_control->data;
585                 sd_flags = sdctr->secinfo_flags;
586                 /* we only care for the last 4 bits */
587                 sd_flags = sd_flags & 0x0000000F;
588         }
589         if (sd_flags != 0) {
590                 oldsd_el = ldb_msg_find_element(ac->search_oc_res->message,
591                                                 "nTSecurityDescriptor");
592                 if (oldsd_el) {
593                         oldsd_val = oldsd_el->values;
594                 }
595         }
596
597         sd = get_new_descriptor(ac->module, ac->msg->dn, ac,
598                                 objectclass, ac->parentsd_val,
599                                 ac->sd_val, oldsd_val, sd_flags);
600         if (sd != NULL) {
601                 if (ac->sd_val != NULL) {
602                         ac->sd_element->values[0] = *sd;
603                 } else if (sd_control2 != NULL) {
604                         /* In this branch we really do force the recalculation
605                          * of the SD */
606                         ldb_msg_remove_attr(ac->msg, "nTSecurityDescriptor");
607
608                         ret = ldb_msg_add_steal_value(ac->msg,
609                                                       "nTSecurityDescriptor",
610                                                       sd);
611                         if (ret != LDB_SUCCESS) {
612                                 return ret;
613                         }
614                         ac->sd_element = ldb_msg_find_element(ac->msg,
615                                                               "nTSecurityDescriptor");
616                         ac->sd_element->flags = LDB_FLAG_MOD_REPLACE;
617                 }
618         }
619
620         /* mark the controls as non-critical since we've handled them */
621         if (sd_control != NULL) {
622                 sd_control->critical = 0;
623         }
624         if (sd_control2 != NULL) {
625                 sd_control2->critical = 0;
626         }
627
628         ret = ldb_build_mod_req(&mod_req, ldb, ac,
629                                 ac->msg,
630                                 ac->req->controls,
631                                 ac->req, dsdb_next_callback,
632                                 ac->req);
633         LDB_REQ_SET_LOCATION(mod_req);
634         if (ret != LDB_SUCCESS) {
635                 return ret;
636         }
637
638         return ldb_next_request(ac->module, mod_req);
639 }
640
641 static int descriptor_do_add(struct descriptor_context *ac)
642 {
643         struct ldb_context *ldb;
644         const struct dsdb_schema *schema;
645         struct ldb_request *add_req;
646         struct ldb_message_element *objectclass_element;
647         int ret;
648         DATA_BLOB *sd;
649         const struct dsdb_class *objectclass;
650         static const char *const attrs[] = { "objectClass", "nTSecurityDescriptor", NULL };
651         struct ldb_request *search_req;
652
653         ldb = ldb_module_get_ctx(ac->module);
654         schema = dsdb_get_schema(ldb, ac);
655
656         switch (ac->req->operation) {
657         case LDB_ADD:
658                 ac->msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
659                 if (ac->msg == NULL) {
660                         return ldb_module_oom(ac->module);
661                 }
662
663                 objectclass_element = ldb_msg_find_element(ac->msg,
664                                                            "objectClass");
665                 if (objectclass_element == NULL) {
666                         return ldb_operr(ldb);
667                 }
668
669                 objectclass = get_last_structural_class(schema,
670                                                         objectclass_element);
671                 if (objectclass == NULL) {
672                         return ldb_operr(ldb);
673                 }
674                 break;
675         case LDB_MODIFY:
676                 ac->msg = ldb_msg_copy_shallow(ac, ac->req->op.mod.message);
677                 if (ac->msg == NULL) {
678                         return ldb_module_oom(ac->module);
679                 }
680                 break;
681         default:
682                 return ldb_operr(ldb);
683         }
684
685         /* Check if there is a valid security descriptor provided */
686         ac->sd_element = dsdb_get_single_valued_attr(ac->msg,
687                                                      "nTSecurityDescriptor",
688                                                      ac->req->operation);
689         if ((ac->sd_element != NULL) && (ac->sd_element->num_values == 1)) {
690                 ac->sd_val = talloc_memdup(ac,
691                                            &ac->sd_element->values[0],
692                                            sizeof(struct ldb_val));
693         }
694
695         /* If we do have a parent, then please fetch it's security descriptor.
696          * But have in mind: NCs don't have any parents! That means
697          * "CN=Configuration,DC=example,DC=com" has no parent
698          * "DC=example,DC=com" since this is located under another NC! */
699         if (ac->search_res != NULL) {
700                 struct ldb_message_element *parent_element = NULL;
701                 struct ldb_dn *nc_root;
702
703                 ret = dsdb_find_nc_root(ldb, ac, ac->msg->dn, &nc_root);
704                 if (ret != LDB_SUCCESS) {
705                         return ret;
706                 }
707
708                 if (ldb_dn_compare(ac->msg->dn, nc_root) != 0) {
709                         /* we aren't any NC */
710                         parent_element = ldb_msg_find_element(ac->search_res->message,
711                                                               "nTSecurityDescriptor");
712                         if (parent_element != NULL) {
713                                 ac->parentsd_val = talloc_memdup(ac,
714                                                                  &parent_element->values[0],
715                                                                  sizeof(struct ldb_val));
716                         }
717                 }
718         }
719
720         if (ac->req->operation == LDB_ADD) {
721                 /* Get the parent descriptor and the one provided. If not
722                  * provided, get the default. Convert it to a security
723                  * descriptor and calculate the permissions. */
724                 sd = get_new_descriptor(ac->module, ac->msg->dn, ac,
725                                         objectclass, ac->parentsd_val,
726                                         ac->sd_val, NULL, 0);
727                 if (sd != NULL) {
728                         if (ac->sd_val != NULL) {
729                                 ac->sd_element->values[0] = *sd;
730                         } else if (ac->sd_element == NULL) {
731                                 ret = ldb_msg_add_steal_value(ac->msg,
732                                                               "nTSecurityDescriptor",
733                                                               sd);
734                                 if (ret != LDB_SUCCESS) {
735                                         return ret;
736                                 }
737                         }
738                 }
739
740                 ret = ldb_build_add_req(&add_req, ldb, ac,
741                                         ac->msg,
742                                         ac->req->controls,
743                                         ac->req, dsdb_next_callback,
744                                         ac->req);
745                 LDB_REQ_SET_LOCATION(add_req);
746                 if (ret != LDB_SUCCESS) {
747                         return ret;
748                 }
749                 return ldb_next_request(ac->module, add_req);
750         } else {
751                 ret = ldb_build_search_req(&search_req, ldb, ac,
752                                            ac->msg->dn, LDB_SCOPE_BASE,
753                                            "(objectClass=*)", attrs,
754                                            NULL,
755                                            ac, get_search_oc_callback,
756                                            ac->req);
757                 LDB_REQ_SET_LOCATION(search_req);
758                 if (ret != LDB_SUCCESS) {
759                         return ret;
760                 }
761                 ac->step_fn = descriptor_do_mod;
762                 return ldb_next_request(ac->module, search_req);
763         }
764 }
765
766 static int descriptor_change(struct ldb_module *module, struct ldb_request *req)
767 {
768         struct ldb_context *ldb;
769         struct ldb_control *sd_control;
770         struct ldb_request *search_req;
771         struct descriptor_context *ac;
772         struct ldb_dn *parent_dn, *dn;
773         struct ldb_message_element *sd_element;
774         int ret;
775         static const char * const descr_attrs[] = { "nTSecurityDescriptor", NULL };
776
777         ldb = ldb_module_get_ctx(module);
778
779         switch (req->operation) {
780         case LDB_ADD:
781                 dn = req->op.add.message->dn;
782                 break;
783         case LDB_MODIFY:
784                 dn = req->op.mod.message->dn;
785                 sd_element = ldb_msg_find_element(req->op.mod.message,
786                                                   "nTSecurityDescriptor");
787                 /* This control forces the recalculation of the SD also when
788                  * no modification is performed. */
789                 sd_control = ldb_request_get_control(req,
790                                                      LDB_CONTROL_RECALCULATE_SD_OID);
791                 if (!sd_element && !sd_control) {
792                         return ldb_next_request(module, req);
793                 }
794                 break;
795         default:
796                 return ldb_operr(ldb);
797         }
798         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_change: %s\n", ldb_dn_get_linearized(dn));
799
800         /* do not manipulate our control entries */
801         if (ldb_dn_is_special(dn)) {
802                 return ldb_next_request(module, req);
803         }
804
805         ac = descriptor_init_context(module, req);
806         if (ac == NULL) {
807                 return ldb_operr(ldb);
808         }
809
810         /* If there isn't a parent, just go on to the add processing */
811         if (ldb_dn_get_comp_num(dn) == 1) {
812                 return descriptor_do_add(ac);
813         }
814
815         /* get copy of parent DN */
816         parent_dn = ldb_dn_get_parent(ac, dn);
817         if (parent_dn == NULL) {
818                 return ldb_oom(ldb);
819         }
820
821         ret = ldb_build_search_req(&search_req, ldb,
822                                    ac, parent_dn, LDB_SCOPE_BASE,
823                                    "(objectClass=*)", descr_attrs,
824                                    NULL,
825                                    ac, get_search_callback,
826                                    req);
827         LDB_REQ_SET_LOCATION(search_req);
828         if (ret != LDB_SUCCESS) {
829                 return ret;
830         }
831         talloc_steal(search_req, parent_dn);
832
833         ac->step_fn = descriptor_do_add;
834
835         return ldb_next_request(ac->module, search_req);
836 }
837
838 static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
839 {
840         int ret;
841         struct ldb_context *ldb;
842         struct ldb_control *sd_control;
843         struct ldb_request *down_req;
844         struct descriptor_context *ac;
845
846         sd_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID);
847         if (!sd_control) {
848                 return ldb_next_request(module, req);
849         }
850
851         ldb = ldb_module_get_ctx(module);
852         ac = descriptor_init_context(module, req);
853         if (ac == NULL) {
854                 return ldb_operr(ldb);
855         }
856
857         ret = ldb_build_search_req_ex(&down_req, ldb, ac,
858                                       req->op.search.base,
859                                       req->op.search.scope,
860                                       req->op.search.tree,
861                                       req->op.search.attrs,
862                                       req->controls,
863                                       ac, descriptor_search_callback,
864                                       ac->req);
865         LDB_REQ_SET_LOCATION(down_req);
866         if (ret != LDB_SUCCESS) {
867                 return ret;
868         }
869         /* mark it as handled */
870         if (sd_control) {
871                 sd_control->critical = 0;
872         }
873
874         return ldb_next_request(ac->module, down_req);
875 }
876 /* TODO */
877 static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
878 {
879         struct ldb_context *ldb = ldb_module_get_ctx(module);
880         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n", ldb_dn_get_linearized(req->op.rename.olddn));
881
882         /* do not manipulate our control entries */
883         if (ldb_dn_is_special(req->op.rename.olddn)) {
884                 return ldb_next_request(module, req);
885         }
886
887         return ldb_next_request(module, req);
888 }
889
890 static int descriptor_init(struct ldb_module *module)
891 {
892         int ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
893         struct ldb_context *ldb = ldb_module_get_ctx(module);
894         if (ret != LDB_SUCCESS) {
895                 ldb_debug(ldb, LDB_DEBUG_ERROR,
896                         "descriptor: Unable to register control with rootdse!\n");
897                 return ldb_operr(ldb);
898         }
899         return ldb_next_init(module);
900 }
901
902
903 static const struct ldb_module_ops ldb_descriptor_module_ops = {
904         .name          = "descriptor",
905         .search        = descriptor_search,
906         .add           = descriptor_change,
907         .modify        = descriptor_change,
908         .rename        = descriptor_rename,
909         .init_context  = descriptor_init
910 };
911
912 int ldb_descriptor_module_init(const char *version)
913 {
914         LDB_MODULE_CHECK_VERSION(version);
915         return ldb_register_module(&ldb_descriptor_module_ops);
916 }