s4: fix SD update and password change in upgrade script
[bbaumbach/samba-autobuild/.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                 return ldb_module_done(ac->req, ares->controls,
576                                         ares->response, ares->error);
577         }
578
579         talloc_free(ares);
580         return LDB_SUCCESS;
581 fail:
582         return ldb_module_done(ac->req, NULL, NULL, ret);
583 }
584
585 static int descriptor_do_mod(struct descriptor_context *ac)
586 {
587         struct ldb_context *ldb;
588         const struct dsdb_schema *schema;
589         struct ldb_request *mod_req;
590         struct ldb_message_element *objectclass_element, *tmp_element, *oldsd_el;
591         struct ldb_val *oldsd_val = NULL;
592         int ret;
593         DATA_BLOB *sd;
594         const struct dsdb_class *objectclass;
595         struct ldb_message *msg;
596         struct ldb_control *sd_control;
597         struct ldb_control *sd_control2;
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         msg = ldb_msg_copy_shallow(ac, ac->req->op.mod.message);
605         objectclass_element = ldb_msg_find_element(ac->search_oc_res->message, "objectClass");
606         objectclass = get_last_structural_class(schema, objectclass_element);
607
608         if (!objectclass) {
609                 ldb_asprintf_errstring(ldb, "No last structural objectclass found on %s",
610                                        ldb_dn_get_linearized(ac->search_oc_res->message->dn));
611                 return LDB_ERR_OPERATIONS_ERROR;
612         }
613         sd_control = ldb_request_get_control(ac->req, LDB_CONTROL_SD_FLAGS_OID);
614         sd_control2 = ldb_request_get_control(ac->req, LDB_CONTROL_RECALCULATE_SD_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                 if (sd_control2) {
642                         tmp_element->flags = LDB_FLAG_MOD_REPLACE;
643                 } else {
644                         tmp_element->flags = flags;
645                 }
646         }
647         ret = ldb_build_mod_req(&mod_req, ldb, ac,
648                                 msg,
649                                 ac->req->controls,
650                                 ac, descriptor_op_callback,
651                                 ac->req);
652         if (ret != LDB_SUCCESS) {
653                 return ret;
654         }
655         /* save it locally and remove it from the list */
656         /* we do not need to replace them later as we
657          * are keeping the original req intact */
658         if (sd_control) {
659                 if (!save_controls(sd_control, mod_req, &saved_controls)) {
660                         return LDB_ERR_OPERATIONS_ERROR;
661                 }
662         }
663
664         return ldb_next_request(ac->module, mod_req);
665 }
666
667 static int descriptor_do_add(struct descriptor_context *ac)
668 {
669         struct ldb_context *ldb;
670         const struct dsdb_schema *schema;
671         struct ldb_request *add_req;
672         struct ldb_message_element *objectclass_element, *sd_element = NULL;
673         struct ldb_message *msg;
674         TALLOC_CTX *mem_ctx;
675         int ret;
676         DATA_BLOB *sd;
677         const struct dsdb_class *objectclass;
678         static const char *const attrs[] = { "objectClass", "nTSecurityDescriptor", NULL };
679         struct ldb_request *search_req;
680
681         ldb = ldb_module_get_ctx(ac->module);
682         schema = dsdb_get_schema(ldb);
683         mem_ctx = talloc_new(ac);
684         if (mem_ctx == NULL) {
685                 return LDB_ERR_OPERATIONS_ERROR;
686         }
687         switch (ac->req->operation) {
688         case LDB_ADD:
689                 msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
690                 objectclass_element = ldb_msg_find_element(msg, "objectClass");
691                 objectclass = get_last_structural_class(schema, objectclass_element);
692
693                 if (!objectclass) {
694                         ldb_asprintf_errstring(ldb, "No last structural objectclass found on %s", ldb_dn_get_linearized(msg->dn));
695                         return LDB_ERR_OPERATIONS_ERROR;
696                 }
697                 break;
698         case LDB_MODIFY:
699                 msg = ldb_msg_copy_shallow(ac, ac->req->op.mod.message);
700                 break;
701         default:
702                 return LDB_ERR_OPERATIONS_ERROR;
703         }
704
705
706         /* get the security descriptor values*/
707         sd_element = ldb_msg_find_element(msg, "nTSecurityDescriptor");
708         if (sd_element) {
709                 ac->sd_val = talloc_memdup(ac, &sd_element->values[0], sizeof(struct ldb_val));
710         }
711         /* NC's have no parent */
712         if ((ldb_dn_compare(msg->dn, (ldb_get_schema_basedn(ldb))) == 0) ||
713             (ldb_dn_compare(msg->dn, (ldb_get_config_basedn(ldb))) == 0) ||
714             (ldb_dn_compare(msg->dn, (ldb_get_root_basedn(ldb))) == 0)) {
715                 ac->parentsd_val = NULL;
716         } else if (ac->search_res != NULL) {
717                 struct ldb_message_element *parent_element = ldb_msg_find_element(ac->search_res->message, "nTSecurityDescriptor");
718                 if (parent_element) {
719                         ac->parentsd_val = talloc_memdup(ac, &parent_element->values[0], sizeof(struct ldb_val));
720                 }
721         }
722
723         if (ac->req->operation == LDB_ADD) {
724         /* get the parent descriptor and the one provided. If not provided, get the default.*/
725         /* convert to security descriptor and calculate */
726                 sd = get_new_descriptor(ac->module, msg->dn, mem_ctx, objectclass,
727                                         ac->parentsd_val, ac->sd_val, NULL, 0);
728                 if (ac->sd_val) {
729                         ldb_msg_remove_attr(msg, "nTSecurityDescriptor");
730                 }
731
732                 if (sd) {
733                         ret = ldb_msg_add_steal_value(msg, "nTSecurityDescriptor", sd);
734                         if (ret != LDB_SUCCESS) {
735                                 return ret;
736                         }
737                 }
738
739                 talloc_free(mem_ctx);
740                 ret = ldb_msg_sanity_check(ldb, msg);
741
742                 if (ret != LDB_SUCCESS) {
743                         ldb_asprintf_errstring(ldb, "No last structural objectclass found on %s",
744                                                ldb_dn_get_linearized(msg->dn));
745                         return ret;
746                 }
747
748                 ret = ldb_build_add_req(&add_req, ldb, ac,
749                                         msg,
750                                         ac->req->controls,
751                                         ac, descriptor_op_callback,
752                                         ac->req);
753                 if (ret != LDB_SUCCESS) {
754                         return ret;
755                 }
756                 return ldb_next_request(ac->module, add_req);
757         } else {
758                 ret = ldb_build_search_req(&search_req, ldb,
759                                    ac, msg->dn, LDB_SCOPE_BASE,
760                                    "(objectClass=*)", attrs,
761                                    NULL,
762                                    ac, get_search_oc_callback,
763                                    ac->req);
764                 if (ret != LDB_SUCCESS) {
765                         return ret;
766                 }
767                 ac->step_fn = descriptor_do_mod;
768                 return ldb_next_request(ac->module, search_req);
769         }
770 }
771
772 static int descriptor_change(struct ldb_module *module, struct ldb_request *req)
773 {
774         struct ldb_context *ldb;
775         struct ldb_control *sd_control;
776         struct ldb_request *search_req;
777         struct descriptor_context *ac;
778         struct ldb_dn *parent_dn, *dn;
779         struct ldb_message_element *sd_element;
780         int ret;
781         static const char * const descr_attrs[] = { "nTSecurityDescriptor", NULL };
782
783         ldb = ldb_module_get_ctx(module);
784
785         switch (req->operation) {
786         case LDB_ADD:
787                 dn = req->op.add.message->dn;
788                 break;
789         case LDB_MODIFY:
790                 dn = req->op.mod.message->dn;
791                 sd_element = ldb_msg_find_element(req->op.mod.message, "nTSecurityDescriptor");
792                 /* This control allow forcing the recalculation of the SD */
793                 sd_control = ldb_request_get_control(req, LDB_CONTROL_RECALCULATE_SD_OID);
794                 if (!sd_element && !sd_control) {
795                         return ldb_next_request(module, req);
796                 }
797                 break;
798         default:
799                 return LDB_ERR_OPERATIONS_ERROR;
800         }
801         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_change: %s\n", ldb_dn_get_linearized(dn));
802
803         if (ldb_dn_is_special(dn)) {
804                 return ldb_next_request(module, req);
805         }
806
807         ac = descriptor_init_context(module, req);
808         if (ac == NULL) {
809                 return LDB_ERR_OPERATIONS_ERROR;
810         }
811
812         /* If there isn't a parent, just go on to the add processing */
813         if (ldb_dn_get_comp_num(dn) == 1) {
814                 return descriptor_do_add(ac);
815         }
816
817         /* get copy of parent DN */
818         parent_dn = ldb_dn_get_parent(ac, dn);
819         if (parent_dn == NULL) {
820                 ldb_oom(ldb);
821                 return LDB_ERR_OPERATIONS_ERROR;
822         }
823
824         ret = ldb_build_search_req(&search_req, ldb,
825                                    ac, parent_dn, LDB_SCOPE_BASE,
826                                    "(objectClass=*)", descr_attrs,
827                                    NULL,
828                                    ac, get_search_callback,
829                                    req);
830         if (ret != LDB_SUCCESS) {
831                 return ret;
832         }
833         talloc_steal(search_req, parent_dn);
834
835         ac->step_fn = descriptor_do_add;
836
837         return ldb_next_request(ac->module, search_req);
838 }
839
840 static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
841 {
842         int ret;
843         struct ldb_context *ldb;
844         struct ldb_control *sd_control;
845         struct ldb_control **saved_controls;
846         struct ldb_request *down_req;
847         struct descriptor_context *ac;
848
849         sd_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID);
850         if (!sd_control) {
851                 return ldb_next_request(module, req);
852         }
853
854         ldb = ldb_module_get_ctx(module);
855         ac = descriptor_init_context(module, req);
856         if (ac == NULL) {
857                 return LDB_ERR_OPERATIONS_ERROR;
858         }
859
860         ret = ldb_build_search_req_ex(&down_req, ldb, ac,
861                                       req->op.search.base,
862                                       req->op.search.scope,
863                                       req->op.search.tree,
864                                       req->op.search.attrs,
865                                       req->controls,
866                                       ac, descriptor_search_callback,
867                                       ac->req);
868         if (ret != LDB_SUCCESS) {
869                 return ret;
870         }
871         /* save it locally and remove it from the list */
872         /* we do not need to replace them later as we
873          * are keeping the original req intact */
874         if (sd_control) {
875                 if (!save_controls(sd_control, down_req, &saved_controls)) {
876                         return LDB_ERR_OPERATIONS_ERROR;
877                 }
878         }
879
880         return ldb_next_request(ac->module, down_req);
881 }
882 /* TODO */
883 static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
884 {
885         struct ldb_context *ldb = ldb_module_get_ctx(module);
886         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n", ldb_dn_get_linearized(req->op.rename.olddn));
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_ERR_OPERATIONS_ERROR;
898         }
899         return ldb_next_init(module);
900 }
901
902
903 _PUBLIC_ 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