LCOV - code coverage report
Current view: top level - source4/dsdb/samdb/ldb_modules - descriptor.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 480 585 82.1 %
Date: 2021-09-23 10:06:22 Functions: 25 25 100.0 %

          Line data    Source code
       1             : /*
       2             :    ldb database library
       3             : 
       4             :    Copyright (C) Simo Sorce  2006-2008
       5             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2007
       6             :    Copyright (C) Nadezhda Ivanova  2009
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : /*
      23             :  *  Name: ldb
      24             :  *
      25             :  *  Component: DS Security descriptor module
      26             :  *
      27             :  *  Description:
      28             :  *  - Calculate the security descriptor of a newly created object
      29             :  *  - Perform sd recalculation on a move operation
      30             :  *  - Handle sd modification invariants
      31             :  *
      32             :  *  Author: Nadezhda Ivanova
      33             :  */
      34             : 
      35             : #include "includes.h"
      36             : #include <ldb_module.h>
      37             : #include "util/dlinklist.h"
      38             : #include "dsdb/samdb/samdb.h"
      39             : #include "librpc/ndr/libndr.h"
      40             : #include "librpc/gen_ndr/ndr_security.h"
      41             : #include "libcli/security/security.h"
      42             : #include "auth/auth.h"
      43             : #include "param/param.h"
      44             : #include "dsdb/samdb/ldb_modules/util.h"
      45             : #include "lib/util/binsearch.h"
      46             : 
      47             : struct descriptor_changes {
      48             :         struct descriptor_changes *prev, *next;
      49             :         struct ldb_dn *nc_root;
      50             :         struct GUID guid;
      51             :         bool force_self;
      52             :         bool force_children;
      53             :         struct ldb_dn *stopped_dn;
      54             : };
      55             : 
      56             : struct descriptor_data {
      57             :         TALLOC_CTX *trans_mem;
      58             :         struct descriptor_changes *changes;
      59             : };
      60             : 
      61             : struct descriptor_context {
      62             :         struct ldb_module *module;
      63             :         struct ldb_request *req;
      64             :         struct ldb_message *msg;
      65             :         struct ldb_reply *search_res;
      66             :         struct ldb_reply *search_oc_res;
      67             :         struct ldb_val *parentsd_val;
      68             :         struct ldb_message_element *sd_element;
      69             :         struct ldb_val *sd_val;
      70             :         uint32_t sd_flags;
      71             :         int (*step_fn)(struct descriptor_context *);
      72             : };
      73             : 
      74     1266456 : static struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
      75             :                                struct ldb_dn *dn,
      76             :                                struct security_token *token,
      77             :                                struct ldb_context *ldb)
      78             : {
      79     1266456 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
      80     1266456 :         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
      81     1266456 :         struct dom_sid *da_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
      82     1266456 :         struct dom_sid *ea_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
      83     1266456 :         struct dom_sid *sa_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
      84             :         struct dom_sid *dag_sid;
      85             :         struct ldb_dn *nc_root;
      86             :         int ret;
      87             : 
      88     1266456 :         ret = dsdb_find_nc_root(ldb, tmp_ctx, dn, &nc_root);
      89     1266456 :         if (ret != LDB_SUCCESS) {
      90           0 :                 talloc_free(tmp_ctx);
      91           0 :                 return NULL;
      92             :         }
      93             : 
      94     1266456 :         if (ldb_dn_compare(nc_root, ldb_get_schema_basedn(ldb)) == 0) {
      95      481467 :                 if (security_token_has_sid(token, sa_sid)) {
      96      340196 :                         dag_sid = dom_sid_dup(mem_ctx, sa_sid);
      97      141271 :                 } else if (security_token_has_sid(token, ea_sid)) {
      98          54 :                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
      99      141217 :                 } else if (security_token_has_sid(token, da_sid)) {
     100          27 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     101      141190 :                 } else if (security_token_is_system(token)) {
     102      141172 :                         dag_sid = dom_sid_dup(mem_ctx, sa_sid);
     103             :                 } else {
     104          18 :                         dag_sid = NULL;
     105             :                 }
     106      784989 :         } else if (ldb_dn_compare(nc_root, ldb_get_config_basedn(ldb)) == 0) {
     107      579890 :                 if (security_token_has_sid(token, ea_sid)) {
     108      375665 :                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     109      204225 :                 } else if (security_token_has_sid(token, da_sid)) {
     110          54 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     111      204171 :                 } else if (security_token_is_system(token)) {
     112      204134 :                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     113             :                 } else {
     114          37 :                         dag_sid = NULL;
     115             :                 }
     116      205099 :         } else if (ldb_dn_compare(nc_root, ldb_get_default_basedn(ldb)) == 0) {
     117      191352 :                 if (security_token_has_sid(token, da_sid)) {
     118      115034 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     119       76318 :                 } else if (security_token_has_sid(token, ea_sid)) {
     120          54 :                                 dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     121       76264 :                 } else if (security_token_is_system(token)) {
     122       75890 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     123             :                 } else {
     124         374 :                         dag_sid = NULL;
     125             :                 }
     126             :         } else {
     127       12627 :                 dag_sid = NULL;
     128             :         }
     129             : 
     130     1266456 :         talloc_free(tmp_ctx);
     131     1266456 :         return dag_sid;
     132             : }
     133             : 
     134     1266456 : static struct security_descriptor *get_sd_unpacked(struct ldb_module *module, TALLOC_CTX *mem_ctx,
     135             :                                             const struct dsdb_class *objectclass)
     136             : {
     137     1266456 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     138             :         struct security_descriptor *sd;
     139     1266456 :         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
     140             : 
     141     1266456 :         if (!objectclass->defaultSecurityDescriptor || !domain_sid) {
     142          44 :                 return NULL;
     143             :         }
     144             : 
     145     1266412 :         sd = sddl_decode(mem_ctx,
     146      237069 :                          objectclass->defaultSecurityDescriptor,
     147             :                          domain_sid);
     148     1156514 :         return sd;
     149             : }
     150             : 
     151     1156558 : static struct dom_sid *get_default_group(TALLOC_CTX *mem_ctx,
     152             :                                          struct ldb_context *ldb,
     153             :                                          struct dom_sid *dag)
     154             : {
     155             :         /*
     156             :          * This depends on the function level of the DC
     157             :          * which is 2008R2 in our case. Which means it is
     158             :          * higher than 2003 and we should use the
     159             :          * "default administrator group" also as owning group.
     160             :          *
     161             :          * This matches dcpromo for a 2003 domain
     162             :          * on a Windows 2008R2 DC.
     163             :          */
     164     1156558 :         return dag;
     165             : }
     166             : 
     167     2276847 : static struct security_descriptor *descr_handle_sd_flags(TALLOC_CTX *mem_ctx,
     168             :                                                          struct security_descriptor *new_sd,
     169             :                                                          struct security_descriptor *old_sd,
     170             :                                                          uint32_t sd_flags)
     171             : {
     172             :         struct security_descriptor *final_sd; 
     173             :         /* if there is no control or control == 0 modify everything */
     174     2276847 :         if (!sd_flags) {
     175           0 :                 return new_sd;
     176             :         }
     177             : 
     178     2276847 :         final_sd = talloc_zero(mem_ctx, struct security_descriptor);
     179     2276847 :         final_sd->revision = SECURITY_DESCRIPTOR_REVISION_1;
     180     2276847 :         final_sd->type = SEC_DESC_SELF_RELATIVE;
     181             : 
     182     2276847 :         if (sd_flags & (SECINFO_OWNER)) {
     183     2261263 :                 if (new_sd->owner_sid) {
     184     2261263 :                         final_sd->owner_sid = talloc_memdup(mem_ctx, new_sd->owner_sid, sizeof(struct dom_sid));
     185             :                 }
     186     2261263 :                 final_sd->type |= new_sd->type & SEC_DESC_OWNER_DEFAULTED;
     187             :         }
     188       15584 :         else if (old_sd) {
     189       15397 :                 if (old_sd->owner_sid) {
     190       15397 :                         final_sd->owner_sid = talloc_memdup(mem_ctx, old_sd->owner_sid, sizeof(struct dom_sid));
     191             :                 }
     192       15397 :                 final_sd->type |= old_sd->type & SEC_DESC_OWNER_DEFAULTED;
     193             :         }
     194             : 
     195     2276847 :         if (sd_flags & (SECINFO_GROUP)) {
     196     2261263 :                 if (new_sd->group_sid) {
     197     2261263 :                         final_sd->group_sid = talloc_memdup(mem_ctx, new_sd->group_sid, sizeof(struct dom_sid));
     198             :                 }
     199     2261263 :                 final_sd->type |= new_sd->type & SEC_DESC_GROUP_DEFAULTED;
     200             :         } 
     201       15584 :         else if (old_sd) {
     202       15397 :                 if (old_sd->group_sid) {
     203       15397 :                         final_sd->group_sid = talloc_memdup(mem_ctx, old_sd->group_sid, sizeof(struct dom_sid));
     204             :                 }
     205       15397 :                 final_sd->type |= old_sd->type & SEC_DESC_GROUP_DEFAULTED;
     206             :         }
     207             : 
     208     2276847 :         if (sd_flags & (SECINFO_SACL)) {
     209     2262455 :                 final_sd->sacl = security_acl_dup(mem_ctx,new_sd->sacl);
     210     2262455 :                 final_sd->type |= new_sd->type & (SEC_DESC_SACL_PRESENT |
     211             :                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
     212             :                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
     213             :                         SEC_DESC_SERVER_SECURITY);
     214             :         } 
     215       14392 :         else if (old_sd && old_sd->sacl) {
     216       13965 :                 final_sd->sacl = security_acl_dup(mem_ctx,old_sd->sacl);
     217       13965 :                 final_sd->type |= old_sd->type & (SEC_DESC_SACL_PRESENT |
     218             :                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
     219             :                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
     220             :                         SEC_DESC_SERVER_SECURITY);
     221             :         }
     222             : 
     223     2276847 :         if (sd_flags & (SECINFO_DACL)) {
     224     2276708 :                 final_sd->dacl = security_acl_dup(mem_ctx,new_sd->dacl);
     225     2276708 :                 final_sd->type |= new_sd->type & (SEC_DESC_DACL_PRESENT |
     226             :                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
     227             :                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
     228             :                         SEC_DESC_DACL_TRUSTED);
     229             :         } 
     230         139 :         else if (old_sd && old_sd->dacl) {
     231         112 :                 final_sd->dacl = security_acl_dup(mem_ctx,old_sd->dacl);
     232         112 :                 final_sd->type |= old_sd->type & (SEC_DESC_DACL_PRESENT |
     233             :                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
     234             :                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
     235             :                         SEC_DESC_DACL_TRUSTED);
     236             :         }
     237             :         /* not so sure about this */
     238     2276847 :         final_sd->type |= new_sd->type & SEC_DESC_RM_CONTROL_VALID;
     239     2276847 :         return final_sd;
     240             : }
     241             : 
     242     1266456 : static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
     243             :                                      struct ldb_dn *dn,
     244             :                                      TALLOC_CTX *mem_ctx,
     245             :                                      const struct dsdb_class *objectclass,
     246             :                                      const struct ldb_val *parent,
     247             :                                      const struct ldb_val *object,
     248             :                                      const struct ldb_val *old_sd,
     249             :                                      uint32_t sd_flags)
     250             : {
     251     1266456 :         struct security_descriptor *user_descriptor = NULL, *parent_descriptor = NULL;
     252     1266456 :         struct security_descriptor *old_descriptor = NULL;
     253             :         struct security_descriptor *new_sd, *final_sd;
     254             :         DATA_BLOB *linear_sd;
     255             :         enum ndr_err_code ndr_err;
     256     1266456 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     257     1029379 :         struct auth_session_info *session_info
     258      237077 :                 = ldb_get_opaque(ldb, DSDB_SESSION_INFO);
     259     1266456 :         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
     260             :         struct dom_sid *default_owner;
     261             :         struct dom_sid *default_group;
     262     1266456 :         struct security_descriptor *default_descriptor = NULL;
     263     1266456 :         struct GUID *object_list = NULL;
     264             : 
     265     1266456 :         if (objectclass != NULL) {
     266     1266456 :                 default_descriptor = get_sd_unpacked(module, mem_ctx, objectclass);
     267     1266456 :                 object_list = talloc_zero_array(mem_ctx, struct GUID, 2);
     268     1266456 :                 if (object_list == NULL) {
     269           0 :                         return NULL;
     270             :                 }
     271     1266456 :                 object_list[0] = objectclass->schemaIDGUID;
     272             :         }
     273             : 
     274     1266456 :         if (object) {
     275      781453 :                 user_descriptor = talloc(mem_ctx, struct security_descriptor);
     276      781453 :                 if (!user_descriptor) {
     277           0 :                         return NULL;
     278             :                 }
     279      781453 :                 ndr_err = ndr_pull_struct_blob(object, user_descriptor, 
     280             :                                                user_descriptor,
     281             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     282             : 
     283      781453 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     284           0 :                         talloc_free(user_descriptor);
     285           0 :                         return NULL;
     286             :                 }
     287             :         } else {
     288      409055 :                 user_descriptor = default_descriptor;
     289             :         }
     290             : 
     291     1266456 :         if (old_sd) {
     292      776779 :                 old_descriptor = talloc(mem_ctx, struct security_descriptor);
     293      776779 :                 if (!old_descriptor) {
     294           0 :                         return NULL;
     295             :                 }
     296      776779 :                 ndr_err = ndr_pull_struct_blob(old_sd, old_descriptor, 
     297             :                                                old_descriptor,
     298             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     299             : 
     300      776779 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     301           0 :                         talloc_free(old_descriptor);
     302           0 :                         return NULL;
     303             :                 }
     304             :         }
     305             : 
     306     1266456 :         if (parent) {
     307     1265354 :                 parent_descriptor = talloc(mem_ctx, struct security_descriptor);
     308     1265354 :                 if (!parent_descriptor) {
     309           0 :                         return NULL;
     310             :                 }
     311     1265354 :                 ndr_err = ndr_pull_struct_blob(parent, parent_descriptor, 
     312             :                                                parent_descriptor,
     313             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     314             : 
     315     1265354 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     316           0 :                         talloc_free(parent_descriptor);
     317           0 :                         return NULL;
     318             :                 }
     319             :         }
     320             : 
     321     2295797 :         if (user_descriptor && default_descriptor &&
     322     1266410 :             (user_descriptor->dacl == NULL))
     323             :         {
     324        6905 :                 user_descriptor->dacl = default_descriptor->dacl;
     325        6905 :                 user_descriptor->type |= default_descriptor->type & (
     326             :                         SEC_DESC_DACL_PRESENT |
     327             :                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
     328             :                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
     329             :                         SEC_DESC_DACL_TRUSTED);
     330             :         }
     331             : 
     332     2295797 :         if (user_descriptor && default_descriptor &&
     333     1266410 :             (user_descriptor->sacl == NULL))
     334             :         {
     335      680315 :                 user_descriptor->sacl = default_descriptor->sacl;
     336      680315 :                 user_descriptor->type |= default_descriptor->type & (
     337             :                         SEC_DESC_SACL_PRESENT |
     338             :                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
     339             :                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
     340             :                         SEC_DESC_SERVER_SECURITY);
     341             :         }
     342             : 
     343             : 
     344     1266456 :         if (!(sd_flags & SECINFO_OWNER) && user_descriptor) {
     345       15397 :                 user_descriptor->owner_sid = NULL;
     346             : 
     347             :                 /*
     348             :                  * We need the correct owner sid
     349             :                  * when calculating the DACL or SACL
     350             :                  */
     351       15397 :                 if (old_descriptor) {
     352       15397 :                         user_descriptor->owner_sid = old_descriptor->owner_sid;
     353             :                 }
     354             :         }
     355     1266456 :         if (!(sd_flags & SECINFO_GROUP) && user_descriptor) {
     356       15397 :                 user_descriptor->group_sid = NULL;
     357             : 
     358             :                 /*
     359             :                  * We need the correct group sid
     360             :                  * when calculating the DACL or SACL
     361             :                  */
     362       15397 :                 if (old_descriptor) {
     363       15397 :                         user_descriptor->group_sid = old_descriptor->group_sid;
     364             :                 }
     365             :         }
     366     1266456 :         if (!(sd_flags & SECINFO_DACL) && user_descriptor) {
     367         112 :                 user_descriptor->dacl = NULL;
     368             : 
     369             :                 /*
     370             :                  * We add SEC_DESC_DACL_PROTECTED so that
     371             :                  * create_security_descriptor() skips
     372             :                  * the unused inheritance calculation
     373             :                  */
     374         112 :                 user_descriptor->type |= SEC_DESC_DACL_PROTECTED;
     375             :         }
     376     1266456 :         if (!(sd_flags & SECINFO_SACL) && user_descriptor) {
     377       13965 :                 user_descriptor->sacl = NULL;
     378             : 
     379             :                 /*
     380             :                  * We add SEC_DESC_SACL_PROTECTED so that
     381             :                  * create_security_descriptor() skips
     382             :                  * the unused inheritance calculation
     383             :                  */
     384       13965 :                 user_descriptor->type |= SEC_DESC_SACL_PROTECTED;
     385             :         }
     386             : 
     387     1266456 :         default_owner = get_default_ag(mem_ctx, dn,
     388             :                                        session_info->security_token, ldb);
     389     1266456 :         default_group = get_default_group(mem_ctx, ldb, default_owner);
     390     1266456 :         new_sd = create_security_descriptor(mem_ctx,
     391             :                                             parent_descriptor,
     392             :                                             user_descriptor,
     393             :                                             true,
     394             :                                             object_list,
     395             :                                             SEC_DACL_AUTO_INHERIT |
     396             :                                             SEC_SACL_AUTO_INHERIT,
     397             :                                             session_info->security_token,
     398             :                                             default_owner, default_group,
     399             :                                             map_generic_rights_ds);
     400     1266456 :         if (!new_sd) {
     401           0 :                 return NULL;
     402             :         }
     403     1266456 :         final_sd = descr_handle_sd_flags(mem_ctx, new_sd, old_descriptor, sd_flags);
     404             : 
     405     1266456 :         if (!final_sd) {
     406           0 :                 return NULL;
     407             :         }
     408             : 
     409     1266456 :         if (final_sd->dacl) {
     410     1266456 :                 final_sd->dacl->revision = SECURITY_ACL_REVISION_ADS;
     411             :         }
     412     1266456 :         if (final_sd->sacl) {
     413      691856 :                 final_sd->sacl->revision = SECURITY_ACL_REVISION_ADS;
     414             :         }
     415             : 
     416             :         {
     417     1266456 :                 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     418     1266456 :                 DBG_DEBUG("Object %s created with descriptor %s\n\n",
     419             :                           ldb_dn_get_linearized(dn),
     420             :                           sddl_encode(tmp_ctx, final_sd, domain_sid));
     421     1266456 :                 TALLOC_FREE(tmp_ctx);
     422             :         }
     423             : 
     424     1266456 :         linear_sd = talloc(mem_ctx, DATA_BLOB);
     425     1266456 :         if (!linear_sd) {
     426           0 :                 return NULL;
     427             :         }
     428             : 
     429     1266456 :         ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
     430             :                                        final_sd,
     431             :                                        (ndr_push_flags_fn_t)ndr_push_security_descriptor);
     432     1266456 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     433           0 :                 return NULL;
     434             :         }
     435             : 
     436     1266456 :         return linear_sd;
     437             : }
     438             : 
     439     1010391 : static DATA_BLOB *descr_get_descriptor_to_show(struct ldb_module *module,
     440             :                                                TALLOC_CTX *mem_ctx,
     441             :                                                struct ldb_val *sd,
     442             :                                                uint32_t sd_flags)
     443             : {
     444             :         struct security_descriptor *old_sd, *final_sd;
     445             :         DATA_BLOB *linear_sd;
     446             :         enum ndr_err_code ndr_err;
     447             : 
     448     1010391 :         old_sd = talloc(mem_ctx, struct security_descriptor);
     449     1010391 :         if (!old_sd) {
     450           0 :                 return NULL;
     451             :         }
     452     1010391 :         ndr_err = ndr_pull_struct_blob(sd, old_sd, 
     453             :                                        old_sd,
     454             :                                        (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     455             : 
     456     1010391 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     457           0 :                 talloc_free(old_sd);
     458           0 :                 return NULL;
     459             :         }
     460             : 
     461     1010391 :         final_sd = descr_handle_sd_flags(mem_ctx, old_sd, NULL, sd_flags);
     462             : 
     463     1010391 :         if (!final_sd) {
     464           0 :                 return NULL;
     465             :         }
     466             : 
     467     1010391 :         linear_sd = talloc(mem_ctx, DATA_BLOB);
     468     1010391 :         if (!linear_sd) {
     469           0 :                 return NULL;
     470             :         }
     471             : 
     472     1010391 :         ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
     473             :                                        final_sd,
     474             :                                        (ndr_push_flags_fn_t)ndr_push_security_descriptor);
     475     1010391 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     476           0 :                 return NULL;
     477             :         }
     478             : 
     479      952027 :         return linear_sd;
     480             : }
     481             : 
     482     1721779 : static struct descriptor_context *descriptor_init_context(struct ldb_module *module,
     483             :                                                           struct ldb_request *req)
     484             : {
     485             :         struct ldb_context *ldb;
     486             :         struct descriptor_context *ac;
     487             : 
     488     1721779 :         ldb = ldb_module_get_ctx(module);
     489             : 
     490     1721779 :         ac = talloc_zero(req, struct descriptor_context);
     491     1721779 :         if (ac == NULL) {
     492           0 :                 ldb_set_errstring(ldb, "Out of Memory");
     493           0 :                 return NULL;
     494             :         }
     495             : 
     496     1721779 :         ac->module = module;
     497     1721779 :         ac->req = req;
     498     1721779 :         return ac;
     499             : }
     500             : 
     501     3451705 : static int descriptor_search_callback(struct ldb_request *req, struct ldb_reply *ares)
     502             : {
     503             :         struct descriptor_context *ac;
     504     3451705 :         struct ldb_val *sd_val = NULL;
     505             :         struct ldb_message_element *sd_el;
     506             :         DATA_BLOB *show_sd;
     507     3451705 :         int ret = LDB_SUCCESS;
     508             : 
     509     3451705 :         ac = talloc_get_type(req->context, struct descriptor_context);
     510             : 
     511     3451705 :         if (!ares) {
     512           0 :                 ret = LDB_ERR_OPERATIONS_ERROR;
     513           0 :                 goto fail;
     514             :         }
     515     3451705 :         if (ares->error != LDB_SUCCESS) {
     516           0 :                 return ldb_module_done(ac->req, ares->controls,
     517             :                                         ares->response, ares->error);
     518             :         }
     519             : 
     520     3451705 :         switch (ares->type) {
     521     1727487 :         case LDB_REPLY_ENTRY:
     522     1727487 :                 sd_el = ldb_msg_find_element(ares->message, "nTSecurityDescriptor");
     523     1727487 :                 if (sd_el) {
     524     1010391 :                         sd_val = sd_el->values;
     525             :                 }
     526             : 
     527     1679917 :                 if (sd_val) {
     528     1010391 :                         show_sd = descr_get_descriptor_to_show(ac->module, ac->req,
     529             :                                                                sd_val, ac->sd_flags);
     530     1010391 :                         if (!show_sd) {
     531           0 :                                 ret = LDB_ERR_OPERATIONS_ERROR;
     532           0 :                                 goto fail;
     533             :                         }
     534     1010391 :                         ldb_msg_remove_attr(ares->message, "nTSecurityDescriptor");
     535     1010391 :                         ret = ldb_msg_add_steal_value(ares->message, "nTSecurityDescriptor", show_sd);
     536     1010391 :                         if (ret != LDB_SUCCESS) {
     537           0 :                                 goto fail;
     538             :                         }
     539             :                 }
     540     1727487 :                 return ldb_module_send_entry(ac->req, ares->message, ares->controls);
     541             : 
     542        2439 :         case LDB_REPLY_REFERRAL:
     543        2439 :                 return ldb_module_send_referral(ac->req, ares->referral);
     544             : 
     545     1721779 :         case LDB_REPLY_DONE:
     546     1721779 :                 return ldb_module_done(ac->req, ares->controls,
     547             :                                         ares->response, ares->error);
     548             :         }
     549             : 
     550           0 : fail:
     551           0 :         talloc_free(ares);
     552           0 :         return ldb_module_done(ac->req, NULL, NULL, ret);
     553             : }
     554             : 
     555      490186 : static int descriptor_add(struct ldb_module *module, struct ldb_request *req)
     556             : {
     557      490186 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     558             :         struct ldb_request *add_req;
     559             :         struct ldb_message *msg;
     560             :         struct ldb_result *parent_res;
     561      490186 :         const struct ldb_val *parent_sd = NULL;
     562             :         const struct ldb_val *user_sd;
     563      490186 :         struct ldb_dn *dn = req->op.add.message->dn;
     564             :         struct ldb_dn *parent_dn, *nc_root;
     565             :         struct ldb_message_element *objectclass_element, *sd_element;
     566             :         int ret;
     567             :         const struct dsdb_schema *schema;
     568             :         DATA_BLOB *sd;
     569             :         const struct dsdb_class *objectclass;
     570             :         static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
     571             :         uint32_t instanceType;
     572      490186 :         bool isNC = false;
     573      490186 :         uint32_t sd_flags = dsdb_request_sd_flags(req, NULL);
     574             : 
     575             :         /* do not manipulate our control entries */
     576      490186 :         if (ldb_dn_is_special(dn)) {
     577         508 :                 return ldb_next_request(module, req);
     578             :         }
     579             : 
     580      489678 :         user_sd = ldb_msg_find_ldb_val(req->op.add.message, "nTSecurityDescriptor");
     581      489678 :         sd_element = ldb_msg_find_element(req->op.add.message, "nTSecurityDescriptor");
     582             :         /* nTSecurityDescriptor without a value is an error, letting through so it is handled */
     583      489678 :         if (user_sd == NULL && sd_element) {
     584           1 :                 return ldb_next_request(module, req);
     585             :         }
     586             : 
     587      489677 :         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: %s\n", ldb_dn_get_linearized(dn));
     588             : 
     589      489677 :         instanceType = ldb_msg_find_attr_as_uint(req->op.add.message, "instanceType", 0);
     590             : 
     591      489677 :         if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) {
     592         478 :                 isNC = true;
     593             :         }
     594             : 
     595      413109 :         if (!isNC) {
     596      489096 :                 ret = dsdb_find_nc_root(ldb, req, dn, &nc_root);
     597      489096 :                 if (ret != LDB_SUCCESS) {
     598           0 :                         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find NC root for %s\n",
     599             :                                 ldb_dn_get_linearized(dn));
     600           0 :                         return ret;
     601             :                 }
     602             : 
     603      489096 :                 if (ldb_dn_compare(dn, nc_root) == 0) {
     604           0 :                         DEBUG(0, ("Found DN %s being a NC by the old method\n", ldb_dn_get_linearized(dn)));
     605           0 :                         isNC = true;
     606             :                 }
     607             :         }
     608             : 
     609      489677 :         if (isNC) {
     610         581 :                 DEBUG(2, ("DN: %s is a NC\n", ldb_dn_get_linearized(dn)));
     611             :         }
     612      489677 :         if (!isNC) {
     613             :                 /* if the object has a parent, retrieve its SD to
     614             :                  * use for calculation. Unfortunately we do not yet have
     615             :                  * instanceType, so we use dsdb_find_nc_root. */
     616             : 
     617      489096 :                 parent_dn = ldb_dn_get_parent(req, dn);
     618      489096 :                 if (parent_dn == NULL) {
     619           0 :                         return ldb_oom(ldb);
     620             :                 }
     621             : 
     622             :                 /* we aren't any NC */
     623      489096 :                 ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn,
     624             :                                             parent_attrs,
     625             :                                             DSDB_FLAG_NEXT_MODULE |
     626             :                                             DSDB_FLAG_AS_SYSTEM |
     627             :                                             DSDB_SEARCH_SHOW_RECYCLED,
     628             :                                             req);
     629      489096 :                 if (ret != LDB_SUCCESS) {
     630           0 :                         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find SD for %s\n",
     631             :                                   ldb_dn_get_linearized(parent_dn));
     632           0 :                         return ret;
     633             :                 }
     634      489096 :                 if (parent_res->count != 1) {
     635           0 :                         return ldb_operr(ldb);
     636             :                 }
     637      489096 :                 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
     638             :         }
     639             : 
     640      489677 :         schema = dsdb_get_schema(ldb, req);
     641             : 
     642      489677 :         objectclass_element = ldb_msg_find_element(req->op.add.message, "objectClass");
     643      489677 :         if (objectclass_element == NULL) {
     644           0 :                 return ldb_operr(ldb);
     645             :         }
     646             : 
     647      489677 :         objectclass = dsdb_get_last_structural_class(schema,
     648             :                                                      objectclass_element);
     649      489677 :         if (objectclass == NULL) {
     650           0 :                 return ldb_operr(ldb);
     651             :         }
     652             : 
     653             :         /*
     654             :          * The SD_FLAG control is ignored on add
     655             :          * and we default to all bits set.
     656             :          */
     657      489677 :         sd_flags = SECINFO_OWNER|SECINFO_GROUP|SECINFO_SACL|SECINFO_DACL;
     658             : 
     659      489677 :         sd = get_new_descriptor(module, dn, req,
     660             :                                 objectclass, parent_sd,
     661             :                                 user_sd, NULL, sd_flags);
     662      489677 :         if (sd == NULL) {
     663           0 :                 return ldb_operr(ldb);
     664             :         }
     665      489677 :         msg = ldb_msg_copy_shallow(req, req->op.add.message);
     666      489677 :         if (msg == NULL) {
     667           0 :                 return ldb_oom(ldb);
     668             :         }
     669      489677 :         if (sd_element != NULL) {
     670        4674 :                 sd_element->values[0] = *sd;
     671             :         } else {
     672      485003 :                 ret = ldb_msg_add_steal_value(msg,
     673             :                                               "nTSecurityDescriptor",
     674             :                                               sd);
     675      485003 :                 if (ret != LDB_SUCCESS) {
     676           0 :                         return ret;
     677             :                 }
     678             :         }
     679             : 
     680      489677 :         ret = ldb_build_add_req(&add_req, ldb, req,
     681             :                                 msg,
     682             :                                 req->controls,
     683             :                                 req, dsdb_next_callback,
     684             :                                 req);
     685      489677 :         LDB_REQ_SET_LOCATION(add_req);
     686      489677 :         if (ret != LDB_SUCCESS) {
     687           0 :                 return ldb_error(ldb, ret,
     688             :                                  "descriptor_add: Error creating new add request.");
     689             :         }
     690             : 
     691      489677 :         return ldb_next_request(module, add_req);
     692             : }
     693             : 
     694     1032286 : static int descriptor_modify(struct ldb_module *module, struct ldb_request *req)
     695             : {
     696     1032286 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     697             :         struct ldb_request *mod_req;
     698             :         struct ldb_message *msg;
     699             :         struct ldb_result *current_res, *parent_res;
     700     1032286 :         const struct ldb_val *old_sd = NULL;
     701     1032286 :         const struct ldb_val *parent_sd = NULL;
     702             :         const struct ldb_val *user_sd;
     703     1032286 :         struct ldb_dn *dn = req->op.mod.message->dn;
     704             :         struct ldb_dn *parent_dn;
     705             :         struct ldb_message_element *objectclass_element, *sd_element;
     706             :         int ret;
     707             :         uint32_t instanceType;
     708     1032286 :         bool explicit_sd_flags = false;
     709     1032286 :         uint32_t sd_flags = dsdb_request_sd_flags(req, &explicit_sd_flags);
     710             :         const struct dsdb_schema *schema;
     711             :         DATA_BLOB *sd;
     712             :         const struct dsdb_class *objectclass;
     713             :         static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
     714             :         static const char * const current_attrs[] = { "nTSecurityDescriptor",
     715             :                                                       "instanceType",
     716             :                                                       "objectClass", NULL };
     717             :         struct ldb_control *sd_propagation_control;
     718     1032286 :         int cmp_ret = -1;
     719             : 
     720             :         /* do not manipulate our control entries */
     721     1032286 :         if (ldb_dn_is_special(dn)) {
     722         657 :                 return ldb_next_request(module, req);
     723             :         }
     724             : 
     725     1031629 :         sd_propagation_control = ldb_request_get_control(req,
     726             :                                         DSDB_CONTROL_SEC_DESC_PROPAGATION_OID);
     727     1031629 :         if (sd_propagation_control != NULL) {
     728      752560 :                 if (sd_propagation_control->data != module) {
     729           0 :                         return ldb_operr(ldb);
     730             :                 }
     731      752560 :                 if (req->op.mod.message->num_elements != 0) {
     732           0 :                         return ldb_operr(ldb);
     733             :                 }
     734      752560 :                 if (explicit_sd_flags) {
     735           0 :                         return ldb_operr(ldb);
     736             :                 }
     737      752560 :                 if (sd_flags != 0xF) {
     738           0 :                         return ldb_operr(ldb);
     739             :                 }
     740      752560 :                 if (sd_propagation_control->critical == 0) {
     741           0 :                         return ldb_operr(ldb);
     742             :                 }
     743             : 
     744      752560 :                 sd_propagation_control->critical = 0;
     745             :         }
     746             : 
     747     1031629 :         sd_element = ldb_msg_find_element(req->op.mod.message, "nTSecurityDescriptor");
     748     1031629 :         if (sd_propagation_control == NULL && sd_element == NULL) {
     749      254835 :                 return ldb_next_request(module, req);
     750             :         }
     751             : 
     752             :         /*
     753             :          * nTSecurityDescriptor with DELETE is not supported yet.
     754             :          * TODO: handle this correctly.
     755             :          */
     756      794193 :         if (sd_propagation_control == NULL &&
     757       24234 :             LDB_FLAG_MOD_TYPE(sd_element->flags) == LDB_FLAG_MOD_DELETE)
     758             :         {
     759           7 :                 return ldb_module_error(module,
     760             :                                         LDB_ERR_UNWILLING_TO_PERFORM,
     761             :                                         "MOD_DELETE for nTSecurityDescriptor "
     762             :                                         "not supported yet");
     763             :         }
     764             : 
     765      776787 :         user_sd = ldb_msg_find_ldb_val(req->op.mod.message, "nTSecurityDescriptor");
     766             :         /* nTSecurityDescriptor without a value is an error, letting through so it is handled */
     767      776787 :         if (sd_propagation_control == NULL && user_sd == NULL) {
     768           8 :                 return ldb_next_request(module, req);
     769             :         }
     770             : 
     771      776779 :         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_modify: %s\n", ldb_dn_get_linearized(dn));
     772             : 
     773      776779 :         ret = dsdb_module_search_dn(module, req, &current_res, dn,
     774             :                                     current_attrs,
     775             :                                     DSDB_FLAG_NEXT_MODULE |
     776             :                                     DSDB_FLAG_AS_SYSTEM |
     777             :                                     DSDB_SEARCH_SHOW_RECYCLED |
     778             :                                     DSDB_SEARCH_SHOW_EXTENDED_DN,
     779             :                                     req);
     780      776779 :         if (ret != LDB_SUCCESS) {
     781           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR,"descriptor_modify: Could not find %s\n",
     782             :                           ldb_dn_get_linearized(dn));
     783           0 :                 return ret;
     784             :         }
     785             : 
     786      776779 :         instanceType = ldb_msg_find_attr_as_uint(current_res->msgs[0],
     787             :                                                  "instanceType", 0);
     788             :         /* if the object has a parent, retrieve its SD to
     789             :          * use for calculation */
     790     1425933 :         if (!ldb_dn_is_null(current_res->msgs[0]->dn) &&
     791      776779 :             !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
     792      776258 :                 parent_dn = ldb_dn_get_parent(req, dn);
     793      776258 :                 if (parent_dn == NULL) {
     794           0 :                         return ldb_oom(ldb);
     795             :                 }
     796      776258 :                 ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn,
     797             :                                             parent_attrs,
     798             :                                             DSDB_FLAG_NEXT_MODULE |
     799             :                                             DSDB_FLAG_AS_SYSTEM |
     800             :                                             DSDB_SEARCH_SHOW_RECYCLED,
     801             :                                             req);
     802      776258 :                 if (ret != LDB_SUCCESS) {
     803           0 :                         ldb_debug(ldb, LDB_DEBUG_ERROR, "descriptor_modify: Could not find SD for %s\n",
     804             :                                   ldb_dn_get_linearized(parent_dn));
     805           0 :                         return ret;
     806             :                 }
     807      776258 :                 if (parent_res->count != 1) {
     808           0 :                         return ldb_operr(ldb);
     809             :                 }
     810      776258 :                 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
     811             :         }
     812             : 
     813      776779 :         schema = dsdb_get_schema(ldb, req);
     814             : 
     815      776779 :         objectclass_element = ldb_msg_find_element(current_res->msgs[0], "objectClass");
     816      776779 :         if (objectclass_element == NULL) {
     817           0 :                 return ldb_operr(ldb);
     818             :         }
     819             : 
     820      776779 :         objectclass = dsdb_get_last_structural_class(schema,
     821             :                                                      objectclass_element);
     822      776779 :         if (objectclass == NULL) {
     823           0 :                 return ldb_operr(ldb);
     824             :         }
     825             : 
     826      776779 :         old_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor");
     827      776779 :         if (old_sd == NULL) {
     828           0 :                 return ldb_operr(ldb);
     829             :         }
     830             : 
     831      776779 :         if (sd_propagation_control != NULL) {
     832             :                 /*
     833             :                  * This just triggers a recalculation of the
     834             :                  * inherited aces.
     835             :                  */
     836      752560 :                 user_sd = old_sd;
     837             :         }
     838             : 
     839      776779 :         sd = get_new_descriptor(module, current_res->msgs[0]->dn, req,
     840             :                                 objectclass, parent_sd,
     841             :                                 user_sd, old_sd, sd_flags);
     842      776779 :         if (sd == NULL) {
     843           0 :                 return ldb_operr(ldb);
     844             :         }
     845      776779 :         msg = ldb_msg_copy_shallow(req, req->op.mod.message);
     846      776779 :         if (msg == NULL) {
     847           0 :                 return ldb_oom(ldb);
     848             :         }
     849      776779 :         cmp_ret = data_blob_cmp(old_sd, sd);
     850      776779 :         if (sd_propagation_control != NULL) {
     851      752560 :                 if (cmp_ret == 0) {
     852             :                         /*
     853             :                          * The nTSecurityDescriptor is unchanged,
     854             :                          * which means we can stop the processing.
     855             :                          *
     856             :                          * We mark the control as critical again,
     857             :                          * as we have not processed it, so the caller
     858             :                          * can tell that the descriptor was unchanged.
     859             :                          */
     860      631409 :                         sd_propagation_control->critical = 1;
     861      631409 :                         return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
     862             :                 }
     863             : 
     864      121151 :                 ret = ldb_msg_add_empty(msg, "nTSecurityDescriptor",
     865             :                                         LDB_FLAG_MOD_REPLACE,
     866             :                                         &sd_element);
     867      121151 :                 if (ret != LDB_SUCCESS) {
     868           0 :                         return ldb_oom(ldb);
     869             :                 }
     870      121151 :                 ret = ldb_msg_add_value(msg, "nTSecurityDescriptor",
     871             :                                         sd, NULL);
     872      121151 :                 if (ret != LDB_SUCCESS) {
     873           0 :                         return ldb_oom(ldb);
     874             :                 }
     875       24219 :         } else if (cmp_ret != 0) {
     876             :                 struct GUID guid;
     877             :                 struct ldb_dn *nc_root;
     878             :                 NTSTATUS status;
     879             : 
     880       23353 :                 ret = dsdb_find_nc_root(ldb,
     881             :                                         msg,
     882       23353 :                                         current_res->msgs[0]->dn,
     883             :                                         &nc_root);
     884       23353 :                 if (ret != LDB_SUCCESS) {
     885           0 :                         return ldb_oom(ldb);
     886             :                 }
     887             : 
     888       23353 :                 status = dsdb_get_extended_dn_guid(current_res->msgs[0]->dn,
     889             :                                                    &guid,
     890             :                                                    "GUID");
     891       23353 :                 if (!NT_STATUS_IS_OK(status)) {
     892           0 :                         return ldb_operr(ldb);
     893             :                 }
     894             : 
     895             :                 /*
     896             :                  * Force SD propagation on children of this record
     897             :                  */
     898       23353 :                 ret = dsdb_module_schedule_sd_propagation(module,
     899             :                                                           nc_root,
     900             :                                                           guid,
     901             :                                                           false);
     902       23353 :                 if (ret != LDB_SUCCESS) {
     903           0 :                         return ldb_operr(ldb);
     904             :                 }
     905       23353 :                 sd_element->values[0] = *sd;
     906             :         } else {
     907         866 :                 sd_element->values[0] = *sd;
     908             :         }
     909             : 
     910      145370 :         ret = ldb_build_mod_req(&mod_req, ldb, req,
     911             :                                 msg,
     912             :                                 req->controls,
     913             :                                 req,
     914             :                                 dsdb_next_callback,
     915             :                                 req);
     916      145370 :         LDB_REQ_SET_LOCATION(mod_req);
     917      145370 :         if (ret != LDB_SUCCESS) {
     918           0 :                 return ret;
     919             :         }
     920             : 
     921      145370 :         return ldb_next_request(module, mod_req);
     922             : }
     923             : 
     924    18922570 : static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
     925             : {
     926             :         int ret;
     927             :         struct ldb_context *ldb;
     928             :         struct ldb_request *down_req;
     929             :         struct descriptor_context *ac;
     930    18922570 :         bool explicit_sd_flags = false;
     931    18922570 :         uint32_t sd_flags = dsdb_request_sd_flags(req, &explicit_sd_flags);
     932    18922570 :         bool show_sd = explicit_sd_flags;
     933             : 
     934    36741743 :         if (!show_sd &&
     935    17819173 :             ldb_attr_in_list(req->op.search.attrs, "nTSecurityDescriptor"))
     936             :         {
     937      618363 :                 show_sd = true;
     938             :         }
     939             : 
     940    18922551 :         if (!show_sd) {
     941    17200791 :                 return ldb_next_request(module, req);
     942             :         }
     943             : 
     944     1721779 :         ldb = ldb_module_get_ctx(module);
     945     1721779 :         ac = descriptor_init_context(module, req);
     946     1721779 :         if (ac == NULL) {
     947           0 :                 return ldb_operr(ldb);
     948             :         }
     949     1721779 :         ac->sd_flags = sd_flags;
     950             : 
     951     1721779 :         ret = ldb_build_search_req_ex(&down_req, ldb, ac,
     952             :                                       req->op.search.base,
     953             :                                       req->op.search.scope,
     954             :                                       req->op.search.tree,
     955             :                                       req->op.search.attrs,
     956             :                                       req->controls,
     957             :                                       ac, descriptor_search_callback,
     958             :                                       ac->req);
     959     1721779 :         LDB_REQ_SET_LOCATION(down_req);
     960     1721779 :         if (ret != LDB_SUCCESS) {
     961           0 :                 return ret;
     962             :         }
     963             : 
     964     1721779 :         return ldb_next_request(ac->module, down_req);
     965             : }
     966             : 
     967        1183 : static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
     968             : {
     969        1183 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     970        1183 :         struct ldb_dn *olddn = req->op.rename.olddn;
     971        1183 :         struct ldb_dn *newdn = req->op.rename.newdn;
     972             :         int ret;
     973             : 
     974             :         /* do not manipulate our control entries */
     975        1183 :         if (ldb_dn_is_special(req->op.rename.olddn)) {
     976           0 :                 return ldb_next_request(module, req);
     977             :         }
     978             : 
     979        1183 :         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n",
     980             :                   ldb_dn_get_linearized(olddn));
     981             : 
     982        1183 :         if (ldb_dn_compare(olddn, newdn) != 0) {
     983             :                 struct ldb_dn *nc_root;
     984             :                 struct GUID guid;
     985             : 
     986        1177 :                 ret = dsdb_find_nc_root(ldb, req, newdn, &nc_root);
     987        1177 :                 if (ret != LDB_SUCCESS) {
     988           0 :                         return ldb_oom(ldb);
     989             :                 }
     990             : 
     991        1177 :                 ret = dsdb_module_guid_by_dn(module,
     992             :                                              olddn,
     993             :                                              &guid,
     994             :                                              req);
     995        1177 :                 if (ret == LDB_SUCCESS) {
     996             :                         /*
     997             :                          * Without disturbing any errors if the olddn
     998             :                          * does not exit, force SD propagation on
     999             :                          * this record (get a new inherited SD from
    1000             :                          * the potentially new parent
    1001             :                          */
    1002        1177 :                         ret = dsdb_module_schedule_sd_propagation(module,
    1003             :                                                                   nc_root,
    1004             :                                                                   guid,
    1005             :                                                                   true);
    1006        1177 :                         if (ret != LDB_SUCCESS) {
    1007           0 :                                 return ldb_operr(ldb);
    1008             :                         }
    1009             :                 }
    1010             :         }
    1011             : 
    1012        1183 :         return ldb_next_request(module, req);
    1013             : }
    1014             : 
    1015      330431 : static int descriptor_extended_sec_desc_propagation(struct ldb_module *module,
    1016             :                                                     struct ldb_request *req)
    1017             : {
    1018      307224 :         struct descriptor_data *descriptor_private =
    1019      330431 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1020             :                 struct descriptor_data);
    1021      330431 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1022             :         struct dsdb_extended_sec_desc_propagation_op *op;
    1023      330431 :         TALLOC_CTX *parent_mem = NULL;
    1024             :         struct descriptor_changes *c;
    1025             : 
    1026      330431 :         op = talloc_get_type(req->op.extended.data,
    1027             :                              struct dsdb_extended_sec_desc_propagation_op);
    1028      330431 :         if (op == NULL) {
    1029           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1030             :                           "descriptor_extended_sec_desc_propagation: "
    1031             :                           "invalid extended data\n");
    1032           0 :                 return LDB_ERR_PROTOCOL_ERROR;
    1033             :         }
    1034             : 
    1035      330431 :         if (descriptor_private->trans_mem == NULL) {
    1036           0 :                 return ldb_module_operr(module);
    1037             :         }
    1038             : 
    1039      330431 :         parent_mem = descriptor_private->trans_mem;
    1040             : 
    1041      330431 :         c = talloc_zero(parent_mem, struct descriptor_changes);
    1042      330431 :         if (c == NULL) {
    1043           0 :                 return ldb_module_oom(module);
    1044             :         }
    1045      330431 :         c->nc_root = ldb_dn_copy(c, op->nc_root);
    1046      330431 :         if (c->nc_root == NULL) {
    1047           0 :                 return ldb_module_oom(module);
    1048             :         }
    1049      330431 :         c->guid = op->guid;
    1050      330431 :         if (op->include_self) {
    1051      269746 :                 c->force_self = true;
    1052             :         } else {
    1053       60685 :                 c->force_children = true;
    1054             :         }
    1055             : 
    1056      330431 :         DLIST_ADD_END(descriptor_private->changes, c);
    1057             : 
    1058      330431 :         return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
    1059             : }
    1060             : 
    1061     1442118 : static int descriptor_extended(struct ldb_module *module, struct ldb_request *req)
    1062             : {
    1063     1442118 :         if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SEC_DESC_PROPAGATION_OID) == 0) {
    1064      330431 :                 return descriptor_extended_sec_desc_propagation(module, req);
    1065             :         }
    1066             : 
    1067     1111687 :         return ldb_next_request(module, req);
    1068             : }
    1069             : 
    1070      132453 : static int descriptor_init(struct ldb_module *module)
    1071             : {
    1072      132453 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1073             :         int ret;
    1074             :         struct descriptor_data *descriptor_private;
    1075             : 
    1076      132453 :         ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
    1077      132453 :         if (ret != LDB_SUCCESS) {
    1078           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR,
    1079             :                         "descriptor: Unable to register control with rootdse!\n");
    1080           0 :                 return ldb_operr(ldb);
    1081             :         }
    1082             : 
    1083      132453 :         descriptor_private = talloc_zero(module, struct descriptor_data);
    1084      132453 :         if (descriptor_private == NULL) {
    1085           0 :                 ldb_oom(ldb);
    1086           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    1087             :         }
    1088      132453 :         ldb_module_set_private(module, descriptor_private);
    1089             : 
    1090      132453 :         return ldb_next_init(module);
    1091             : }
    1092             : 
    1093      752560 : static int descriptor_sd_propagation_object(struct ldb_module *module,
    1094             :                                             struct ldb_message *msg,
    1095             :                                             bool *stop)
    1096             : {
    1097      752560 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1098             :         struct ldb_request *sub_req;
    1099             :         struct ldb_result *mod_res;
    1100             :         struct ldb_control *sd_propagation_control;
    1101             :         int ret;
    1102             : 
    1103      752560 :         *stop = false;
    1104             : 
    1105      752560 :         mod_res = talloc_zero(msg, struct ldb_result);
    1106      752560 :         if (mod_res == NULL) {
    1107           0 :                 return ldb_module_oom(module);
    1108             :         }
    1109             : 
    1110      752560 :         ret = ldb_build_mod_req(&sub_req, ldb, mod_res,
    1111             :                                 msg,
    1112             :                                 NULL,
    1113             :                                 mod_res,
    1114             :                                 ldb_modify_default_callback,
    1115             :                                 NULL);
    1116      752560 :         LDB_REQ_SET_LOCATION(sub_req);
    1117      752560 :         if (ret != LDB_SUCCESS) {
    1118           0 :                 return ldb_module_operr(module);
    1119             :         }
    1120             : 
    1121      752560 :         ldb_req_mark_trusted(sub_req);
    1122             : 
    1123      752560 :         ret = ldb_request_add_control(sub_req,
    1124             :                                       DSDB_CONTROL_SEC_DESC_PROPAGATION_OID,
    1125             :                                       true, module);
    1126      752560 :         if (ret != LDB_SUCCESS) {
    1127           0 :                 return ldb_module_operr(module);
    1128             :         }
    1129             : 
    1130      752560 :         sd_propagation_control = ldb_request_get_control(sub_req,
    1131             :                                         DSDB_CONTROL_SEC_DESC_PROPAGATION_OID);
    1132      752560 :         if (sd_propagation_control == NULL) {
    1133           0 :                 return ldb_module_operr(module);
    1134             :         }
    1135             : 
    1136      752560 :         ret = dsdb_request_add_controls(sub_req,
    1137             :                                         DSDB_FLAG_AS_SYSTEM |
    1138             :                                         DSDB_SEARCH_SHOW_RECYCLED);
    1139      752560 :         if (ret != LDB_SUCCESS) {
    1140           0 :                 return ldb_module_operr(module);
    1141             :         }
    1142             : 
    1143      752560 :         ret = descriptor_modify(module, sub_req);
    1144      752560 :         if (ret == LDB_SUCCESS) {
    1145      752560 :                 ret = ldb_wait(sub_req->handle, LDB_WAIT_ALL);
    1146             :         }
    1147      752560 :         if (ret != LDB_SUCCESS) {
    1148           0 :                 ldb_asprintf_errstring(ldb_module_get_ctx(module),
    1149             :                                        "descriptor_modify on %s failed: %s",
    1150             :                                        ldb_dn_get_linearized(msg->dn),
    1151             :                                        ldb_errstring(ldb_module_get_ctx(module)));
    1152           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    1153             :         }
    1154             : 
    1155      752560 :         if (sd_propagation_control->critical != 0) {
    1156      631409 :                 *stop = true;
    1157             :         }
    1158             : 
    1159      752560 :         talloc_free(mod_res);
    1160             : 
    1161      752560 :         return LDB_SUCCESS;
    1162             : }
    1163             : 
    1164     4137359 : static int descriptor_sd_propagation_msg_sort(struct ldb_message **m1,
    1165             :                                               struct ldb_message **m2)
    1166             : {
    1167     4137412 :         struct ldb_dn *dn1 = (*m1)->dn;
    1168     4137412 :         struct ldb_dn *dn2 = (*m2)->dn;
    1169             : 
    1170             :         /*
    1171             :          * This sorts in tree order, parents first
    1172             :          */
    1173     4137412 :         return ldb_dn_compare(dn2, dn1);
    1174             : }
    1175             : 
    1176      329831 : static int descriptor_sd_propagation_recursive(struct ldb_module *module,
    1177             :                                                struct descriptor_changes *change)
    1178             : {
    1179      329831 :         struct ldb_result *guid_res = NULL;
    1180      329831 :         struct ldb_result *res = NULL;
    1181             :         unsigned int i;
    1182      329831 :         const char * const no_attrs[] = { "@__NONE__", NULL };
    1183      329831 :         struct ldb_dn *stopped_dn = NULL;
    1184             :         struct GUID_txt_buf guid_buf;
    1185             :         int ret;
    1186      329831 :         bool stop = false;
    1187             : 
    1188             :         /*
    1189             :          * First confirm this object has children, or exists
    1190             :          * (depending on change->force_self)
    1191             :          * 
    1192             :          * LDB_SCOPE_SUBTREE searches are expensive.
    1193             :          *
    1194             :          * We know this is safe against a rename race as we are in the
    1195             :          * prepare_commit(), so must be in a transaction.
    1196             :          */
    1197             : 
    1198             :         /* Find the DN by GUID, as this is stable under rename */
    1199      329831 :         ret = dsdb_module_search(module,
    1200             :                                  change,
    1201             :                                  &guid_res,
    1202             :                                  change->nc_root,
    1203             :                                  LDB_SCOPE_SUBTREE,
    1204             :                                  no_attrs,
    1205             :                                  DSDB_FLAG_NEXT_MODULE |
    1206             :                                  DSDB_FLAG_AS_SYSTEM |
    1207             :                                  DSDB_SEARCH_SHOW_DELETED |
    1208             :                                  DSDB_SEARCH_SHOW_RECYCLED,
    1209             :                                  NULL, /* parent_req */
    1210             :                                  "(objectGUID=%s)",
    1211      329831 :                                  GUID_buf_string(&change->guid,
    1212             :                                                  &guid_buf));
    1213             : 
    1214      329831 :         if (ret != LDB_SUCCESS) {
    1215           0 :                 return ret;
    1216             :         }
    1217             : 
    1218      329831 :         if (guid_res->count != 1) {
    1219             :                 /*
    1220             :                  * We were just given this GUID during the same
    1221             :                  * transaction, if it is missing this is a big
    1222             :                  * problem.
    1223             :                  *
    1224             :                  * Cleanup of tombstones does not trigger this module
    1225             :                  * as it just does a delete.
    1226             :                  */
    1227           0 :                 ldb_asprintf_errstring(ldb_module_get_ctx(module),
    1228             :                                        "failed to find GUID %s under %s "
    1229             :                                        "for transaction-end SD inheritance: %d results",
    1230           0 :                                        GUID_buf_string(&change->guid,
    1231             :                                                        &guid_buf),
    1232             :                                        ldb_dn_get_linearized(change->nc_root),
    1233           0 :                                        guid_res->count);
    1234           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    1235             :         }
    1236             : 
    1237             :         /*
    1238             :          * OK, so there was a parent, are there children?  Note: that
    1239             :          * this time we do not search for deleted/recycled objects
    1240             :          */
    1241      329831 :         ret = dsdb_module_search(module,
    1242             :                                  change,
    1243             :                                  &res,
    1244      329831 :                                  guid_res->msgs[0]->dn,
    1245             :                                  LDB_SCOPE_ONELEVEL,
    1246             :                                  no_attrs,
    1247             :                                  DSDB_FLAG_NEXT_MODULE |
    1248             :                                  DSDB_FLAG_AS_SYSTEM,
    1249             :                                  NULL, /* parent_req */
    1250             :                                  "(objectClass=*)");
    1251      329831 :         if (ret != LDB_SUCCESS) {
    1252             :                 /*
    1253             :                  * LDB_ERR_NO_SUCH_OBJECT, say if the DN was a deleted
    1254             :                  * object, is ignored by the caller
    1255             :                  */
    1256           0 :                 return ret;
    1257             :         }
    1258             : 
    1259      329831 :         if (res->count == 0 && !change->force_self) {
    1260             :                 /* All done, no children */
    1261       51865 :                 TALLOC_FREE(res);
    1262       51865 :                 return LDB_SUCCESS;
    1263             :         }
    1264             : 
    1265             :         /*
    1266             :          * First, if we are in force_self mode (eg renamed under new
    1267             :          * parent) then apply the SD to the top object
    1268             :          */
    1269      277966 :         if (change->force_self) {
    1270      269146 :                 ret = descriptor_sd_propagation_object(module,
    1271      269146 :                                                        guid_res->msgs[0],
    1272             :                                                        &stop);
    1273      269146 :                 if (ret != LDB_SUCCESS) {
    1274           0 :                         TALLOC_FREE(guid_res);
    1275           0 :                         return ret;
    1276             :                 }
    1277             : 
    1278      269146 :                 if (stop == true && !change->force_children) {
    1279             :                         /* There was no change, nothing more to do */
    1280      269040 :                         TALLOC_FREE(guid_res);
    1281      269035 :                         return LDB_SUCCESS;
    1282             :                 }
    1283             : 
    1284         106 :                 if (res->count == 0) {
    1285             :                         /* All done! */
    1286         103 :                         TALLOC_FREE(guid_res);
    1287         103 :                         return LDB_SUCCESS;
    1288             :                 }
    1289             :         }
    1290             : 
    1291             :         /*
    1292             :          * Look for children
    1293             :          *
    1294             :          * Note: that we do not search for deleted/recycled objects
    1295             :          */
    1296        8823 :         ret = dsdb_module_search(module,
    1297             :                                  change,
    1298             :                                  &res,
    1299        8823 :                                  guid_res->msgs[0]->dn,
    1300             :                                  LDB_SCOPE_SUBTREE,
    1301             :                                  no_attrs,
    1302             :                                  DSDB_FLAG_NEXT_MODULE |
    1303             :                                  DSDB_FLAG_AS_SYSTEM,
    1304             :                                  NULL, /* parent_req */
    1305             :                                  "(objectClass=*)");
    1306        8823 :         if (ret != LDB_SUCCESS) {
    1307           0 :                 return ret;
    1308             :         }
    1309             : 
    1310        8823 :         TYPESAFE_QSORT(res->msgs, res->count,
    1311             :                        descriptor_sd_propagation_msg_sort);
    1312             : 
    1313             :         /* We start from 1, the top object has been done */
    1314      502074 :         for (i = 1; i < res->count; i++) {
    1315             :                 /*
    1316             :                  * ldb_dn_compare_base() does not match for NULL but
    1317             :                  * this is clearer
    1318             :                  */
    1319      493304 :                 if (stopped_dn != NULL) {
    1320      372443 :                         ret = ldb_dn_compare_base(stopped_dn,
    1321      372443 :                                                   res->msgs[i]->dn);
    1322             :                         /*
    1323             :                          * Skip further processing of this
    1324             :                          * sub-subtree
    1325             :                          */
    1326      372443 :                         if (ret == 0) {
    1327        9890 :                                 continue;
    1328             :                         }
    1329             :                 }
    1330      483414 :                 ret = descriptor_sd_propagation_object(module,
    1331      483414 :                                                        res->msgs[i],
    1332             :                                                        &stop);
    1333      483414 :                 if (ret != LDB_SUCCESS) {
    1334           0 :                         return ret;
    1335             :                 }
    1336             : 
    1337      483414 :                 if (stop) {
    1338             :                         /*
    1339             :                          * If this child didn't change, then nothing
    1340             :                          * under it needs to change
    1341             :                          *
    1342             :                          * res has been sorted into tree order so the
    1343             :                          * next few entries can be skipped
    1344             :                          */
    1345      362369 :                         stopped_dn = res->msgs[i]->dn;
    1346             :                 }
    1347             :         }
    1348             : 
    1349        8823 :         TALLOC_FREE(res);
    1350        8823 :         return LDB_SUCCESS;
    1351             : }
    1352             : 
    1353      258849 : static int descriptor_start_transaction(struct ldb_module *module)
    1354             : {
    1355      195440 :         struct descriptor_data *descriptor_private =
    1356      258849 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1357             :                 struct descriptor_data);
    1358             : 
    1359      258849 :         if (descriptor_private->trans_mem != NULL) {
    1360           0 :                 return ldb_module_operr(module);
    1361             :         }
    1362             : 
    1363      258849 :         descriptor_private->trans_mem = talloc_new(descriptor_private);
    1364      258849 :         if (descriptor_private->trans_mem == NULL) {
    1365           0 :                 return ldb_module_oom(module);
    1366             :         }
    1367      258849 :         descriptor_private->changes = NULL;
    1368             : 
    1369      258849 :         return ldb_next_start_trans(module);
    1370             : }
    1371             : 
    1372      231527 : static int descriptor_prepare_commit(struct ldb_module *module)
    1373             : {
    1374      178492 :         struct descriptor_data *descriptor_private =
    1375      231527 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1376             :                 struct descriptor_data);
    1377             :         struct descriptor_changes *c, *n;
    1378             :         int ret;
    1379             : 
    1380      562939 :         for (c = descriptor_private->changes; c; c = n) {
    1381      329831 :                 n = c->next;
    1382      329831 :                 DLIST_REMOVE(descriptor_private->changes, c);
    1383             : 
    1384      329831 :                 ret = descriptor_sd_propagation_recursive(module, c);
    1385      329831 :                 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    1386           0 :                         continue;
    1387             :                 }
    1388      329831 :                 if (ret != LDB_SUCCESS) {
    1389           0 :                         return ret;
    1390             :                 }
    1391             :         }
    1392             : 
    1393      231527 :         return ldb_next_prepare_commit(module);
    1394             : }
    1395             : 
    1396      231525 : static int descriptor_end_transaction(struct ldb_module *module)
    1397             : {
    1398      178490 :         struct descriptor_data *descriptor_private =
    1399      231525 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1400             :                 struct descriptor_data);
    1401             : 
    1402      231525 :         TALLOC_FREE(descriptor_private->trans_mem);
    1403      231525 :         descriptor_private->changes = NULL;
    1404             : 
    1405      231525 :         return ldb_next_end_trans(module);
    1406             : }
    1407             : 
    1408       27322 : static int descriptor_del_transaction(struct ldb_module *module)
    1409             : {
    1410       16948 :         struct descriptor_data *descriptor_private =
    1411       27322 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1412             :                 struct descriptor_data);
    1413             : 
    1414       27322 :         TALLOC_FREE(descriptor_private->trans_mem);
    1415       27322 :         descriptor_private->changes = NULL;
    1416             : 
    1417       27322 :         return ldb_next_del_trans(module);
    1418             : }
    1419             : 
    1420             : static const struct ldb_module_ops ldb_descriptor_module_ops = {
    1421             :         .name              = "descriptor",
    1422             :         .search            = descriptor_search,
    1423             :         .add               = descriptor_add,
    1424             :         .modify            = descriptor_modify,
    1425             :         .rename            = descriptor_rename,
    1426             :         .init_context      = descriptor_init,
    1427             :         .extended          = descriptor_extended,
    1428             :         .start_transaction = descriptor_start_transaction,
    1429             :         .prepare_commit    = descriptor_prepare_commit,
    1430             :         .end_transaction   = descriptor_end_transaction,
    1431             :         .del_transaction   = descriptor_del_transaction,
    1432             : };
    1433             : 
    1434        5536 : int ldb_descriptor_module_init(const char *version)
    1435             : {
    1436        5536 :         LDB_MODULE_CHECK_VERSION(version);
    1437        5536 :         return ldb_register_module(&ldb_descriptor_module_ops);
    1438             : }

Generated by: LCOV version 1.13