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