s4-dsdb Don't talloc_free() ares on failure, as LDB might free it later
[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         return ldb_module_done(ac->req, NULL, NULL, ret);
549 }
550
551 static int descriptor_do_mod(struct descriptor_context *ac)
552 {
553         struct ldb_context *ldb;
554         const struct dsdb_schema *schema;
555         struct ldb_request *mod_req;
556         struct ldb_message_element *objectclass_element, *oldsd_el;
557         struct ldb_val *oldsd_val = NULL;
558         int ret;
559         DATA_BLOB *sd;
560         const struct dsdb_class *objectclass;
561         struct ldb_control *sd_control;
562         struct ldb_control *sd_control2;
563         uint32_t sd_flags = 0;
564
565         ldb = ldb_module_get_ctx(ac->module);
566         schema = dsdb_get_schema(ldb, ac);
567
568         objectclass_element = ldb_msg_find_element(ac->search_oc_res->message,
569                                                    "objectClass");
570         if (objectclass_element == NULL) {
571                 return ldb_operr(ldb);
572         }
573
574         objectclass = get_last_structural_class(schema, objectclass_element);
575         if (objectclass == NULL) {
576                 return ldb_operr(ldb);
577         }
578
579         sd_control = ldb_request_get_control(ac->req, LDB_CONTROL_SD_FLAGS_OID);
580         sd_control2 = ldb_request_get_control(ac->req,
581                                               LDB_CONTROL_RECALCULATE_SD_OID);
582         if (sd_control) {
583                 struct ldb_sd_flags_control *sdctr = (struct ldb_sd_flags_control *)sd_control->data;
584                 sd_flags = sdctr->secinfo_flags;
585                 /* we only care for the last 4 bits */
586                 sd_flags = sd_flags & 0x0000000F;
587         }
588         if (sd_flags != 0) {
589                 oldsd_el = ldb_msg_find_element(ac->search_oc_res->message,
590                                                 "nTSecurityDescriptor");
591                 if (oldsd_el) {
592                         oldsd_val = oldsd_el->values;
593                 }
594         }
595
596         sd = get_new_descriptor(ac->module, ac->msg->dn, ac,
597                                 objectclass, ac->parentsd_val,
598                                 ac->sd_val, oldsd_val, sd_flags);
599         if (sd != NULL) {
600                 if (ac->sd_val != NULL) {
601                         ac->sd_element->values[0] = *sd;
602                 } else if (sd_control2 != NULL) {
603                         /* In this branch we really do force the recalculation
604                          * of the SD */
605                         ldb_msg_remove_attr(ac->msg, "nTSecurityDescriptor");
606
607                         ret = ldb_msg_add_steal_value(ac->msg,
608                                                       "nTSecurityDescriptor",
609                                                       sd);
610                         if (ret != LDB_SUCCESS) {
611                                 return ret;
612                         }
613                         ac->sd_element = ldb_msg_find_element(ac->msg,
614                                                               "nTSecurityDescriptor");
615                         ac->sd_element->flags = LDB_FLAG_MOD_REPLACE;
616                 }
617         }
618
619         /* mark the controls as non-critical since we've handled them */
620         if (sd_control != NULL) {
621                 sd_control->critical = 0;
622         }
623         if (sd_control2 != NULL) {
624                 sd_control2->critical = 0;
625         }
626
627         ret = ldb_build_mod_req(&mod_req, ldb, ac,
628                                 ac->msg,
629                                 ac->req->controls,
630                                 ac->req, dsdb_next_callback,
631                                 ac->req);
632         LDB_REQ_SET_LOCATION(mod_req);
633         if (ret != LDB_SUCCESS) {
634                 return ret;
635         }
636
637         return ldb_next_request(ac->module, mod_req);
638 }
639
640 static int descriptor_do_add(struct descriptor_context *ac)
641 {
642         struct ldb_context *ldb;
643         const struct dsdb_schema *schema;
644         struct ldb_request *add_req;
645         struct ldb_message_element *objectclass_element;
646         int ret;
647         DATA_BLOB *sd;
648         const struct dsdb_class *objectclass;
649         static const char *const attrs[] = { "objectClass", "nTSecurityDescriptor", NULL };
650         struct ldb_request *search_req;
651
652         ldb = ldb_module_get_ctx(ac->module);
653         schema = dsdb_get_schema(ldb, ac);
654
655         switch (ac->req->operation) {
656         case LDB_ADD:
657                 ac->msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
658                 if (ac->msg == NULL) {
659                         return ldb_module_oom(ac->module);
660                 }
661
662                 objectclass_element = ldb_msg_find_element(ac->msg,
663                                                            "objectClass");
664                 if (objectclass_element == NULL) {
665                         return ldb_operr(ldb);
666                 }
667
668                 objectclass = get_last_structural_class(schema,
669                                                         objectclass_element);
670                 if (objectclass == NULL) {
671                         return ldb_operr(ldb);
672                 }
673                 break;
674         case LDB_MODIFY:
675                 ac->msg = ldb_msg_copy_shallow(ac, ac->req->op.mod.message);
676                 if (ac->msg == NULL) {
677                         return ldb_module_oom(ac->module);
678                 }
679                 break;
680         default:
681                 return ldb_operr(ldb);
682         }
683
684         /* Check if there is a valid security descriptor provided */
685         ac->sd_element = dsdb_get_single_valued_attr(ac->msg,
686                                                      "nTSecurityDescriptor",
687                                                      ac->req->operation);
688         if ((ac->sd_element != NULL) && (ac->sd_element->num_values == 1)) {
689                 ac->sd_val = talloc_memdup(ac,
690                                            &ac->sd_element->values[0],
691                                            sizeof(struct ldb_val));
692         }
693
694         /* If we do have a parent, then please fetch it's security descriptor.
695          * But have in mind: NCs don't have any parents! That means
696          * "CN=Configuration,DC=example,DC=com" has no parent
697          * "DC=example,DC=com" since this is located under another NC! */
698         if (ac->search_res != NULL) {
699                 struct ldb_message_element *parent_element = NULL;
700                 struct ldb_dn *nc_root;
701
702                 ret = dsdb_find_nc_root(ldb, ac, ac->msg->dn, &nc_root);
703                 if (ret != LDB_SUCCESS) {
704                         return ret;
705                 }
706
707                 if (ldb_dn_compare(ac->msg->dn, nc_root) != 0) {
708                         /* we aren't any NC */
709                         parent_element = ldb_msg_find_element(ac->search_res->message,
710                                                               "nTSecurityDescriptor");
711                         if (parent_element != NULL) {
712                                 ac->parentsd_val = talloc_memdup(ac,
713                                                                  &parent_element->values[0],
714                                                                  sizeof(struct ldb_val));
715                         }
716                 }
717         }
718
719         if (ac->req->operation == LDB_ADD) {
720                 /* Get the parent descriptor and the one provided. If not
721                  * provided, get the default. Convert it to a security
722                  * descriptor and calculate the permissions. */
723                 sd = get_new_descriptor(ac->module, ac->msg->dn, ac,
724                                         objectclass, ac->parentsd_val,
725                                         ac->sd_val, NULL, 0);
726                 if (sd != NULL) {
727                         if (ac->sd_val != NULL) {
728                                 ac->sd_element->values[0] = *sd;
729                         } else if (ac->sd_element == NULL) {
730                                 ret = ldb_msg_add_steal_value(ac->msg,
731                                                               "nTSecurityDescriptor",
732                                                               sd);
733                                 if (ret != LDB_SUCCESS) {
734                                         return ret;
735                                 }
736                         }
737                 }
738
739                 ret = ldb_build_add_req(&add_req, ldb, ac,
740                                         ac->msg,
741                                         ac->req->controls,
742                                         ac->req, dsdb_next_callback,
743                                         ac->req);
744                 LDB_REQ_SET_LOCATION(add_req);
745                 if (ret != LDB_SUCCESS) {
746                         return ret;
747                 }
748                 return ldb_next_request(ac->module, add_req);
749         } else {
750                 ret = ldb_build_search_req(&search_req, ldb, ac,
751                                            ac->msg->dn, LDB_SCOPE_BASE,
752                                            "(objectClass=*)", attrs,
753                                            NULL,
754                                            ac, get_search_oc_callback,
755                                            ac->req);
756                 LDB_REQ_SET_LOCATION(search_req);
757                 if (ret != LDB_SUCCESS) {
758                         return ret;
759                 }
760                 ac->step_fn = descriptor_do_mod;
761                 return ldb_next_request(ac->module, search_req);
762         }
763 }
764
765 static int descriptor_change(struct ldb_module *module, struct ldb_request *req)
766 {
767         struct ldb_context *ldb;
768         struct ldb_control *sd_control;
769         struct ldb_request *search_req;
770         struct descriptor_context *ac;
771         struct ldb_dn *parent_dn, *dn;
772         struct ldb_message_element *sd_element;
773         int ret;
774         static const char * const descr_attrs[] = { "nTSecurityDescriptor", NULL };
775
776         ldb = ldb_module_get_ctx(module);
777
778         switch (req->operation) {
779         case LDB_ADD:
780                 dn = req->op.add.message->dn;
781                 break;
782         case LDB_MODIFY:
783                 dn = req->op.mod.message->dn;
784                 sd_element = ldb_msg_find_element(req->op.mod.message,
785                                                   "nTSecurityDescriptor");
786                 /* This control forces the recalculation of the SD also when
787                  * no modification is performed. */
788                 sd_control = ldb_request_get_control(req,
789                                                      LDB_CONTROL_RECALCULATE_SD_OID);
790                 if (!sd_element && !sd_control) {
791                         return ldb_next_request(module, req);
792                 }
793                 break;
794         default:
795                 return ldb_operr(ldb);
796         }
797         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_change: %s\n", ldb_dn_get_linearized(dn));
798
799         /* do not manipulate our control entries */
800         if (ldb_dn_is_special(dn)) {
801                 return ldb_next_request(module, req);
802         }
803
804         ac = descriptor_init_context(module, req);
805         if (ac == NULL) {
806                 return ldb_operr(ldb);
807         }
808
809         /* If there isn't a parent, just go on to the add processing */
810         if (ldb_dn_get_comp_num(dn) == 1) {
811                 return descriptor_do_add(ac);
812         }
813
814         /* get copy of parent DN */
815         parent_dn = ldb_dn_get_parent(ac, dn);
816         if (parent_dn == NULL) {
817                 return ldb_oom(ldb);
818         }
819
820         ret = ldb_build_search_req(&search_req, ldb,
821                                    ac, parent_dn, LDB_SCOPE_BASE,
822                                    "(objectClass=*)", descr_attrs,
823                                    NULL,
824                                    ac, get_search_callback,
825                                    req);
826         LDB_REQ_SET_LOCATION(search_req);
827         if (ret != LDB_SUCCESS) {
828                 return ret;
829         }
830         talloc_steal(search_req, parent_dn);
831
832         ac->step_fn = descriptor_do_add;
833
834         return ldb_next_request(ac->module, search_req);
835 }
836
837 static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
838 {
839         int ret;
840         struct ldb_context *ldb;
841         struct ldb_control *sd_control;
842         struct ldb_request *down_req;
843         struct descriptor_context *ac;
844
845         sd_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID);
846         if (!sd_control) {
847                 return ldb_next_request(module, req);
848         }
849
850         ldb = ldb_module_get_ctx(module);
851         ac = descriptor_init_context(module, req);
852         if (ac == NULL) {
853                 return ldb_operr(ldb);
854         }
855
856         ret = ldb_build_search_req_ex(&down_req, ldb, ac,
857                                       req->op.search.base,
858                                       req->op.search.scope,
859                                       req->op.search.tree,
860                                       req->op.search.attrs,
861                                       req->controls,
862                                       ac, descriptor_search_callback,
863                                       ac->req);
864         LDB_REQ_SET_LOCATION(down_req);
865         if (ret != LDB_SUCCESS) {
866                 return ret;
867         }
868         /* mark it as handled */
869         if (sd_control) {
870                 sd_control->critical = 0;
871         }
872
873         return ldb_next_request(ac->module, down_req);
874 }
875 /* TODO */
876 static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
877 {
878         struct ldb_context *ldb = ldb_module_get_ctx(module);
879         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n", ldb_dn_get_linearized(req->op.rename.olddn));
880
881         /* do not manipulate our control entries */
882         if (ldb_dn_is_special(req->op.rename.olddn)) {
883                 return ldb_next_request(module, req);
884         }
885
886         return ldb_next_request(module, req);
887 }
888
889 static int descriptor_init(struct ldb_module *module)
890 {
891         int ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
892         struct ldb_context *ldb = ldb_module_get_ctx(module);
893         if (ret != LDB_SUCCESS) {
894                 ldb_debug(ldb, LDB_DEBUG_ERROR,
895                         "descriptor: Unable to register control with rootdse!\n");
896                 return ldb_operr(ldb);
897         }
898         return ldb_next_init(module);
899 }
900
901
902 static const struct ldb_module_ops ldb_descriptor_module_ops = {
903         .name          = "descriptor",
904         .search        = descriptor_search,
905         .add           = descriptor_change,
906         .modify        = descriptor_change,
907         .rename        = descriptor_rename,
908         .init_context  = descriptor_init
909 };
910
911 int ldb_descriptor_module_init(const char *version)
912 {
913         LDB_MODULE_CHECK_VERSION(version);
914         return ldb_register_module(&ldb_descriptor_module_ops);
915 }