LCOV - code coverage report
Current view: top level - source4/dsdb/samdb/ldb_modules - descriptor.c (source / functions) Hit Total Coverage
Test: coverage report for vadcx-master-patch-75612 fe003de8 Lines: 729 873 83.5 %
Date: 2024-02-29 22:57:05 Functions: 28 28 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/util_tdb.h"
      46             : #include "lib/dbwrap/dbwrap.h"
      47             : #include "lib/dbwrap/dbwrap_rbt.h"
      48             : 
      49             : struct descriptor_changes {
      50             :         struct descriptor_changes *prev, *next;
      51             :         struct ldb_dn *nc_root;
      52             :         struct GUID guid;
      53             :         struct GUID parent_guid;
      54             :         bool force_self;
      55             :         bool force_children;
      56             :         struct ldb_dn *stopped_dn;
      57             :         size_t ref_count;
      58             :         size_t sort_count;
      59             : };
      60             : 
      61             : struct descriptor_transaction {
      62             :         TALLOC_CTX *mem;
      63             :         struct {
      64             :                 /*
      65             :                  * We used to have a list of changes, appended with each
      66             :                  * DSDB_EXTENDED_SEC_DESC_PROPAGATION_OID operation.
      67             :                  *
      68             :                  * But the main problem was that a replication
      69             :                  * cycle (mainly the initial replication) calls
      70             :                  * DSDB_EXTENDED_SEC_DESC_PROPAGATION_OID for the
      71             :                  * same object[GUID] more than once. With
      72             :                  * DRSUAPI_DRS_GET_TGT we'll get the naming
      73             :                  * context head object and other top level
      74             :                  * containers, every often.
      75             :                  *
      76             :                  * It means we'll process objects more
      77             :                  * than once and waste a lot of time
      78             :                  * doing the same work again and again.
      79             :                  *
      80             :                  * We use an objectGUID based map in order to
      81             :                  * avoid registering objects more than once.
      82             :                  * In an domain with 22000 object it can
      83             :                  * reduce the work from 4 hours down to ~ 3.5 minutes.
      84             :                  */
      85             :                 struct descriptor_changes *list;
      86             :                 struct db_context *map;
      87             :                 size_t num_registrations;
      88             :                 size_t num_registered;
      89             :                 size_t num_toplevel;
      90             :                 size_t num_processed;
      91             :         } changes;
      92             :         struct {
      93             :                 struct db_context *map;
      94             :                 size_t num_processed;
      95             :                 size_t num_skipped;
      96             :         } objects;
      97             : };
      98             : 
      99             : struct descriptor_data {
     100             :         struct descriptor_transaction transaction;
     101             : };
     102             : 
     103             : struct descriptor_context {
     104             :         struct ldb_module *module;
     105             :         struct ldb_request *req;
     106             :         struct ldb_message *msg;
     107             :         struct ldb_reply *search_res;
     108             :         struct ldb_reply *search_oc_res;
     109             :         struct ldb_val *parentsd_val;
     110             :         struct ldb_message_element *sd_element;
     111             :         struct ldb_val *sd_val;
     112             :         uint32_t sd_flags;
     113             :         int (*step_fn)(struct descriptor_context *);
     114             : };
     115             : 
     116     2179544 : static struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
     117             :                                struct ldb_dn *dn,
     118             :                                const struct security_token *token,
     119             :                                struct ldb_context *ldb)
     120             : {
     121     2179544 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     122     2179544 :         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
     123     2179544 :         struct dom_sid *da_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
     124     2179544 :         struct dom_sid *ea_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
     125     2179544 :         struct dom_sid *sa_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
     126      207781 :         struct dom_sid *dag_sid;
     127      207781 :         struct ldb_dn *nc_root;
     128      207781 :         int ret;
     129             : 
     130     2179544 :         ret = dsdb_find_nc_root(ldb, tmp_ctx, dn, &nc_root);
     131     2179544 :         if (ret != LDB_SUCCESS) {
     132           0 :                 talloc_free(tmp_ctx);
     133           0 :                 return NULL;
     134             :         }
     135             : 
     136     2179544 :         if (ldb_dn_compare(nc_root, ldb_get_schema_basedn(ldb)) == 0) {
     137     1056550 :                 if (security_token_has_sid(token, sa_sid)) {
     138      874837 :                         dag_sid = dom_sid_dup(mem_ctx, sa_sid);
     139      181713 :                 } else if (security_token_has_sid(token, ea_sid)) {
     140          90 :                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     141      181623 :                 } else if (security_token_has_sid(token, da_sid)) {
     142          45 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     143      181578 :                 } else if (security_token_is_system(token)) {
     144      181542 :                         dag_sid = dom_sid_dup(mem_ctx, sa_sid);
     145             :                 } else {
     146          36 :                         dag_sid = NULL;
     147             :                 }
     148     1122994 :         } else if (ldb_dn_compare(nc_root, ldb_get_config_basedn(ldb)) == 0) {
     149      756266 :                 if (security_token_has_sid(token, ea_sid)) {
     150      619582 :                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     151      136684 :                 } else if (security_token_has_sid(token, da_sid)) {
     152          90 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     153      136594 :                 } else if (security_token_is_system(token)) {
     154      136520 :                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     155             :                 } else {
     156          74 :                         dag_sid = NULL;
     157             :                 }
     158      366728 :         } else if (ldb_dn_compare(nc_root, ldb_get_default_basedn(ldb)) == 0) {
     159      343070 :                 if (security_token_has_sid(token, da_sid)) {
     160      262651 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     161       80419 :                 } else if (security_token_has_sid(token, ea_sid)) {
     162         108 :                                 dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     163       80311 :                 } else if (security_token_is_system(token)) {
     164       77645 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     165             :                 } else {
     166        2666 :                         dag_sid = NULL;
     167             :                 }
     168             :         } else {
     169       21082 :                 dag_sid = NULL;
     170             :         }
     171             : 
     172     2179544 :         talloc_free(tmp_ctx);
     173     2179544 :         return dag_sid;
     174             : }
     175             : 
     176     2179463 : static struct security_descriptor *get_sd_unpacked(struct ldb_module *module, TALLOC_CTX *mem_ctx,
     177             :                                             const struct dsdb_class *objectclass)
     178             : {
     179     2179463 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     180      207781 :         struct security_descriptor *sd;
     181     2179463 :         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
     182             : 
     183     2179463 :         if (!objectclass->defaultSecurityDescriptor || !domain_sid) {
     184          88 :                 return NULL;
     185             :         }
     186             : 
     187     2179375 :         sd = sddl_decode(mem_ctx,
     188     1971594 :                          objectclass->defaultSecurityDescriptor,
     189             :                          domain_sid);
     190     2179375 :         return sd;
     191             : }
     192             : 
     193     1971682 : static struct dom_sid *get_default_group(TALLOC_CTX *mem_ctx,
     194             :                                          struct ldb_context *ldb,
     195             :                                          struct dom_sid *dag)
     196             : {
     197             :         /*
     198             :          * This depends on the function level of the DC
     199             :          * which is 2008R2 in our case. Which means it is
     200             :          * higher than 2003 and we should use the
     201             :          * "default administrator group" also as owning group.
     202             :          *
     203             :          * This matches dcpromo for a 2003 domain
     204             :          * on a Windows 2008R2 DC.
     205             :          */
     206     1971682 :         return dag;
     207             : }
     208             : 
     209     3489347 : static struct security_descriptor *descr_handle_sd_flags(TALLOC_CTX *mem_ctx,
     210             :                                                          struct security_descriptor *new_sd,
     211             :                                                          struct security_descriptor *old_sd,
     212             :                                                          uint32_t sd_flags)
     213             : {
     214      280215 :         struct security_descriptor *final_sd; 
     215             :         /* if there is no control or control == 0 modify everything */
     216     3489347 :         if (!sd_flags) {
     217           0 :                 return new_sd;
     218             :         }
     219             : 
     220     3489347 :         final_sd = talloc_zero(mem_ctx, struct security_descriptor);
     221     3489347 :         final_sd->revision = SECURITY_DESCRIPTOR_REVISION_1;
     222     3489347 :         final_sd->type = SEC_DESC_SELF_RELATIVE;
     223             : 
     224     3489347 :         if (sd_flags & (SECINFO_OWNER)) {
     225     3471508 :                 if (new_sd->owner_sid) {
     226     3471508 :                         final_sd->owner_sid = talloc_memdup(mem_ctx, new_sd->owner_sid, sizeof(struct dom_sid));
     227             :                 }
     228     3471508 :                 final_sd->type |= new_sd->type & SEC_DESC_OWNER_DEFAULTED;
     229             :         }
     230       17839 :         else if (old_sd) {
     231       15978 :                 if (old_sd->owner_sid) {
     232       15978 :                         final_sd->owner_sid = talloc_memdup(mem_ctx, old_sd->owner_sid, sizeof(struct dom_sid));
     233             :                 }
     234       15978 :                 final_sd->type |= old_sd->type & SEC_DESC_OWNER_DEFAULTED;
     235             :         }
     236             : 
     237     3489347 :         if (sd_flags & (SECINFO_GROUP)) {
     238     3471409 :                 if (new_sd->group_sid) {
     239     3471409 :                         final_sd->group_sid = talloc_memdup(mem_ctx, new_sd->group_sid, sizeof(struct dom_sid));
     240             :                 }
     241     3471409 :                 final_sd->type |= new_sd->type & SEC_DESC_GROUP_DEFAULTED;
     242             :         } 
     243       17938 :         else if (old_sd) {
     244       16077 :                 if (old_sd->group_sid) {
     245       16077 :                         final_sd->group_sid = talloc_memdup(mem_ctx, old_sd->group_sid, sizeof(struct dom_sid));
     246             :                 }
     247       16077 :                 final_sd->type |= old_sd->type & SEC_DESC_GROUP_DEFAULTED;
     248             :         }
     249             : 
     250     3489347 :         if (sd_flags & (SECINFO_SACL)) {
     251     3472212 :                 final_sd->sacl = security_acl_dup(mem_ctx,new_sd->sacl);
     252     3472212 :                 final_sd->type |= new_sd->type & (SEC_DESC_SACL_PRESENT |
     253             :                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
     254             :                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
     255             :                         SEC_DESC_SERVER_SECURITY);
     256             :         } 
     257       17135 :         else if (old_sd && old_sd->sacl) {
     258       14708 :                 final_sd->sacl = security_acl_dup(mem_ctx,old_sd->sacl);
     259       14708 :                 final_sd->type |= old_sd->type & (SEC_DESC_SACL_PRESENT |
     260             :                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
     261             :                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
     262             :                         SEC_DESC_SERVER_SECURITY);
     263             :         }
     264             : 
     265     3489347 :         if (sd_flags & (SECINFO_DACL)) {
     266     3489065 :                 final_sd->dacl = security_acl_dup(mem_ctx,new_sd->dacl);
     267     3489065 :                 final_sd->type |= new_sd->type & (SEC_DESC_DACL_PRESENT |
     268             :                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
     269             :                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
     270             :                         SEC_DESC_DACL_TRUSTED);
     271             :         } 
     272         282 :         else if (old_sd && old_sd->dacl) {
     273         255 :                 final_sd->dacl = security_acl_dup(mem_ctx,old_sd->dacl);
     274         255 :                 final_sd->type |= old_sd->type & (SEC_DESC_DACL_PRESENT |
     275             :                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
     276             :                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
     277             :                         SEC_DESC_DACL_TRUSTED);
     278             :         }
     279             :         /* not so sure about this */
     280     3489347 :         final_sd->type |= new_sd->type & SEC_DESC_RM_CONTROL_VALID;
     281     3489347 :         return final_sd;
     282             : }
     283             : 
     284     2179463 : static struct security_descriptor *get_new_descriptor_nonlinear(struct ldb_module *module,
     285             :                                                                 struct ldb_dn *dn,
     286             :                                                                 TALLOC_CTX *mem_ctx,
     287             :                                                                 const struct dsdb_class *objectclass,
     288             :                                                                 const struct ldb_val *parent,
     289             :                                                                 const struct ldb_val *object,
     290             :                                                                 const struct ldb_val *old_sd,
     291             :                                                                 uint32_t sd_flags)
     292             : {
     293     2179463 :         struct security_descriptor *user_descriptor = NULL, *parent_descriptor = NULL;
     294     2179463 :         struct security_descriptor *old_descriptor = NULL;
     295      207781 :         struct security_descriptor *new_sd, *final_sd;
     296      207781 :         enum ndr_err_code ndr_err;
     297     2179463 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     298      207781 :         struct auth_session_info *session_info
     299     2179463 :                 = ldb_get_opaque(ldb, DSDB_SESSION_INFO);
     300     2179463 :         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
     301      207781 :         struct dom_sid *default_owner;
     302      207781 :         struct dom_sid *default_group;
     303     2179463 :         struct security_descriptor *default_descriptor = NULL;
     304     2179463 :         struct GUID *object_list = NULL;
     305             : 
     306     2179463 :         if (objectclass != NULL) {
     307     2179463 :                 default_descriptor = get_sd_unpacked(module, mem_ctx, objectclass);
     308     2179463 :                 object_list = talloc_zero_array(mem_ctx, struct GUID, 2);
     309     2179463 :                 if (object_list == NULL) {
     310           0 :                         return NULL;
     311             :                 }
     312     2179463 :                 object_list[0] = objectclass->schemaIDGUID;
     313             :         }
     314             : 
     315     2179463 :         if (object) {
     316     1104004 :                 user_descriptor = talloc(mem_ctx, struct security_descriptor);
     317     1104004 :                 if (!user_descriptor) {
     318           0 :                         return NULL;
     319             :                 }
     320     1104004 :                 ndr_err = ndr_pull_struct_blob(object, user_descriptor, 
     321             :                                                user_descriptor,
     322             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     323             : 
     324     1104004 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     325           0 :                         talloc_free(user_descriptor);
     326           0 :                         return NULL;
     327             :                 }
     328             :         } else {
     329      909985 :                 user_descriptor = default_descriptor;
     330             :         }
     331             : 
     332     2179463 :         if (old_sd) {
     333     1093905 :                 old_descriptor = talloc(mem_ctx, struct security_descriptor);
     334     1093905 :                 if (!old_descriptor) {
     335           0 :                         return NULL;
     336             :                 }
     337     1093905 :                 ndr_err = ndr_pull_struct_blob(old_sd, old_descriptor, 
     338             :                                                old_descriptor,
     339             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     340             : 
     341     1093905 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     342           0 :                         talloc_free(old_descriptor);
     343           0 :                         return NULL;
     344             :                 }
     345             :         }
     346             : 
     347     2179463 :         if (parent) {
     348     2177263 :                 parent_descriptor = talloc(mem_ctx, struct security_descriptor);
     349     2177263 :                 if (!parent_descriptor) {
     350           0 :                         return NULL;
     351             :                 }
     352     2177263 :                 ndr_err = ndr_pull_struct_blob(parent, parent_descriptor, 
     353             :                                                parent_descriptor,
     354             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     355             : 
     356     2177263 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     357           0 :                         talloc_free(parent_descriptor);
     358           0 :                         return NULL;
     359             :                 }
     360             :         }
     361             : 
     362     2179463 :         if (user_descriptor && default_descriptor &&
     363     2179067 :             (user_descriptor->dacl == NULL))
     364             :         {
     365        7660 :                 user_descriptor->dacl = default_descriptor->dacl;
     366        7660 :                 user_descriptor->type |= default_descriptor->type & (
     367             :                         SEC_DESC_DACL_PRESENT |
     368             :                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
     369             :                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
     370             :                         SEC_DESC_DACL_TRUSTED);
     371             :         }
     372             : 
     373     2179463 :         if (user_descriptor && default_descriptor &&
     374     2179067 :             (user_descriptor->sacl == NULL))
     375             :         {
     376      984172 :                 user_descriptor->sacl = default_descriptor->sacl;
     377      984172 :                 user_descriptor->type |= default_descriptor->type & (
     378             :                         SEC_DESC_SACL_PRESENT |
     379             :                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
     380             :                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
     381             :                         SEC_DESC_SERVER_SECURITY);
     382             :         }
     383             : 
     384             : 
     385     2179463 :         if (!(sd_flags & SECINFO_OWNER) && user_descriptor) {
     386       15978 :                 user_descriptor->owner_sid = NULL;
     387             : 
     388             :                 /*
     389             :                  * We need the correct owner sid
     390             :                  * when calculating the DACL or SACL
     391             :                  */
     392       15978 :                 if (old_descriptor) {
     393       15978 :                         user_descriptor->owner_sid = old_descriptor->owner_sid;
     394             :                 }
     395             :         }
     396     2179463 :         if (!(sd_flags & SECINFO_GROUP) && user_descriptor) {
     397       16077 :                 user_descriptor->group_sid = NULL;
     398             : 
     399             :                 /*
     400             :                  * We need the correct group sid
     401             :                  * when calculating the DACL or SACL
     402             :                  */
     403       16077 :                 if (old_descriptor) {
     404       16077 :                         user_descriptor->group_sid = old_descriptor->group_sid;
     405             :                 }
     406             :         }
     407     2179463 :         if (!(sd_flags & SECINFO_DACL) && user_descriptor) {
     408         255 :                 user_descriptor->dacl = NULL;
     409             : 
     410             :                 /*
     411             :                  * We add SEC_DESC_DACL_PROTECTED so that
     412             :                  * create_security_descriptor() skips
     413             :                  * the unused inheritance calculation
     414             :                  */
     415         255 :                 user_descriptor->type |= SEC_DESC_DACL_PROTECTED;
     416             :         }
     417     2179463 :         if (!(sd_flags & SECINFO_SACL) && user_descriptor) {
     418       14718 :                 user_descriptor->sacl = NULL;
     419             : 
     420             :                 /*
     421             :                  * We add SEC_DESC_SACL_PROTECTED so that
     422             :                  * create_security_descriptor() skips
     423             :                  * the unused inheritance calculation
     424             :                  */
     425       14718 :                 user_descriptor->type |= SEC_DESC_SACL_PROTECTED;
     426             :         }
     427             : 
     428     2387244 :         default_owner = get_default_ag(mem_ctx, dn,
     429     2179463 :                                        session_info->security_token, ldb);
     430     2179463 :         default_group = get_default_group(mem_ctx, ldb, default_owner);
     431     2179463 :         new_sd = create_security_descriptor(mem_ctx,
     432             :                                             parent_descriptor,
     433             :                                             user_descriptor,
     434             :                                             true,
     435             :                                             object_list,
     436             :                                             SEC_DACL_AUTO_INHERIT |
     437             :                                             SEC_SACL_AUTO_INHERIT,
     438             :                                             session_info->security_token,
     439             :                                             default_owner, default_group,
     440             :                                             map_generic_rights_ds);
     441     2179463 :         if (!new_sd) {
     442           0 :                 return NULL;
     443             :         }
     444     2179463 :         final_sd = descr_handle_sd_flags(mem_ctx, new_sd, old_descriptor, sd_flags);
     445             : 
     446     2179463 :         if (!final_sd) {
     447           0 :                 return NULL;
     448             :         }
     449             : 
     450     2179463 :         if (final_sd->dacl) {
     451     2179463 :                 final_sd->dacl->revision = SECURITY_ACL_REVISION_ADS;
     452             :         }
     453     2179463 :         if (final_sd->sacl) {
     454     1430043 :                 final_sd->sacl->revision = SECURITY_ACL_REVISION_ADS;
     455             :         }
     456             : 
     457             :         {
     458     2179463 :                 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     459     2179463 :                 DBG_DEBUG("Object %s created with descriptor %s\n\n",
     460             :                           ldb_dn_get_linearized(dn),
     461             :                           sddl_encode(tmp_ctx, final_sd, domain_sid));
     462     2179463 :                 TALLOC_FREE(tmp_ctx);
     463             :         }
     464             : 
     465     1971682 :         return final_sd;
     466             : }
     467             : 
     468     1636684 : static DATA_BLOB *get_new_descriptor(struct ldb_module *module,
     469             :                                      struct ldb_dn *dn,
     470             :                                      TALLOC_CTX *mem_ctx,
     471             :                                      const struct dsdb_class *objectclass,
     472             :                                      const struct ldb_val *parent,
     473             :                                      const struct ldb_val *object,
     474             :                                      const struct ldb_val *old_sd,
     475             :                                      uint32_t sd_flags)
     476             : {
     477     1636684 :         struct security_descriptor *final_sd = NULL;
     478      124192 :         enum ndr_err_code ndr_err;
     479     1636684 :         DATA_BLOB *linear_sd = talloc(mem_ctx, DATA_BLOB);
     480             : 
     481     1636684 :         if (!linear_sd) {
     482           0 :                 return NULL;
     483             :         }
     484             : 
     485     1636684 :         final_sd = get_new_descriptor_nonlinear(module,
     486             :                                                 dn,
     487             :                                                 mem_ctx,
     488             :                                                 objectclass,
     489             :                                                 parent,
     490             :                                                 object,
     491             :                                                 old_sd,
     492             :                                                 sd_flags);
     493     1636684 :         if (final_sd == NULL) {
     494           0 :                 return NULL;
     495             :         }
     496             : 
     497     1636684 :         ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
     498             :                                        final_sd,
     499             :                                        (ndr_push_flags_fn_t)ndr_push_security_descriptor);
     500     1636684 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     501           0 :                 return NULL;
     502             :         }
     503             : 
     504     1512492 :         return linear_sd;
     505             : }
     506             : 
     507     1309884 : static DATA_BLOB *descr_get_descriptor_to_show(struct ldb_module *module,
     508             :                                                TALLOC_CTX *mem_ctx,
     509             :                                                struct ldb_val *sd,
     510             :                                                uint32_t sd_flags)
     511             : {
     512       72434 :         struct security_descriptor *old_sd, *final_sd;
     513       72434 :         DATA_BLOB *linear_sd;
     514       72434 :         enum ndr_err_code ndr_err;
     515             : 
     516     1309884 :         old_sd = talloc(mem_ctx, struct security_descriptor);
     517     1309884 :         if (!old_sd) {
     518           0 :                 return NULL;
     519             :         }
     520     1309884 :         ndr_err = ndr_pull_struct_blob(sd, old_sd, 
     521             :                                        old_sd,
     522             :                                        (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     523             : 
     524     1309884 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     525           0 :                 talloc_free(old_sd);
     526           0 :                 return NULL;
     527             :         }
     528             : 
     529     1309884 :         final_sd = descr_handle_sd_flags(mem_ctx, old_sd, NULL, sd_flags);
     530             : 
     531     1309884 :         if (!final_sd) {
     532           0 :                 return NULL;
     533             :         }
     534             : 
     535     1309884 :         linear_sd = talloc(mem_ctx, DATA_BLOB);
     536     1309884 :         if (!linear_sd) {
     537           0 :                 return NULL;
     538             :         }
     539             : 
     540     1309884 :         ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
     541             :                                        final_sd,
     542             :                                        (ndr_push_flags_fn_t)ndr_push_security_descriptor);
     543     1309884 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     544           0 :                 return NULL;
     545             :         }
     546             : 
     547     1237450 :         return linear_sd;
     548             : }
     549             : 
     550     2071161 : static struct descriptor_context *descriptor_init_context(struct ldb_module *module,
     551             :                                                           struct ldb_request *req)
     552             : {
     553      122590 :         struct ldb_context *ldb;
     554      122590 :         struct descriptor_context *ac;
     555             : 
     556     2071161 :         ldb = ldb_module_get_ctx(module);
     557             : 
     558     2071161 :         ac = talloc_zero(req, struct descriptor_context);
     559     2071161 :         if (ac == NULL) {
     560           0 :                 ldb_set_errstring(ldb, "Out of Memory");
     561           0 :                 return NULL;
     562             :         }
     563             : 
     564     2071161 :         ac->module = module;
     565     2071161 :         ac->req = req;
     566     2071161 :         return ac;
     567             : }
     568             : 
     569     4144315 : static int descriptor_search_callback(struct ldb_request *req, struct ldb_reply *ares)
     570             : {
     571      245190 :         struct descriptor_context *ac;
     572     4144315 :         struct ldb_val *sd_val = NULL;
     573      245190 :         struct ldb_message_element *sd_el;
     574      245190 :         DATA_BLOB *show_sd;
     575     4144315 :         int ret = LDB_SUCCESS;
     576             : 
     577     4144315 :         ac = talloc_get_type(req->context, struct descriptor_context);
     578             : 
     579     4144315 :         if (!ares) {
     580           0 :                 ret = LDB_ERR_OPERATIONS_ERROR;
     581           0 :                 goto fail;
     582             :         }
     583     4144315 :         if (ares->error != LDB_SUCCESS) {
     584           0 :                 return ldb_module_done(ac->req, ares->controls,
     585             :                                         ares->response, ares->error);
     586             :         }
     587             : 
     588     4144315 :         switch (ares->type) {
     589     2071787 :         case LDB_REPLY_ENTRY:
     590     2071787 :                 sd_el = ldb_msg_find_element(ares->message, "nTSecurityDescriptor");
     591     2071787 :                 if (sd_el) {
     592     1309884 :                         sd_val = sd_el->values;
     593             :                 }
     594             : 
     595     2021616 :                 if (sd_val) {
     596     1309884 :                         show_sd = descr_get_descriptor_to_show(ac->module, ac->req,
     597             :                                                                sd_val, ac->sd_flags);
     598     1309884 :                         if (!show_sd) {
     599           0 :                                 ret = LDB_ERR_OPERATIONS_ERROR;
     600           0 :                                 goto fail;
     601             :                         }
     602     1309884 :                         ldb_msg_remove_attr(ares->message, "nTSecurityDescriptor");
     603     1309884 :                         ret = ldb_msg_add_steal_value(ares->message, "nTSecurityDescriptor", show_sd);
     604     1309884 :                         if (ret != LDB_SUCCESS) {
     605           0 :                                 goto fail;
     606             :                         }
     607             :                 }
     608     2071787 :                 return ldb_module_send_entry(ac->req, ares->message, ares->controls);
     609             : 
     610        2894 :         case LDB_REPLY_REFERRAL:
     611        2894 :                 return ldb_module_send_referral(ac->req, ares->referral);
     612             : 
     613     2069634 :         case LDB_REPLY_DONE:
     614     2069634 :                 return ldb_module_done(ac->req, ares->controls,
     615             :                                         ares->response, ares->error);
     616             :         }
     617             : 
     618           0 : fail:
     619           0 :         talloc_free(ares);
     620           0 :         return ldb_module_done(ac->req, NULL, NULL, ret);
     621             : }
     622             : 
     623       15690 : static bool can_write_owner(TALLOC_CTX *mem_ctx,
     624             :                             struct ldb_context *ldb,
     625             :                             struct ldb_dn *dn,
     626             :                             const struct security_token *security_token,
     627             :                             const struct dom_sid *owner_sid)
     628             : {
     629       15690 :         const struct dom_sid *default_owner = NULL;
     630             : 
     631             :         /* If the user possesses SE_RESTORE_PRIVILEGE, the write is allowed. */
     632       15690 :         bool ok = security_token_has_privilege(security_token, SEC_PRIV_RESTORE);
     633       15690 :         if (ok) {
     634       14925 :                 return true;
     635             :         }
     636             : 
     637             :         /* The user can write their own SID to a security descriptor. */
     638         410 :         ok = security_token_is_sid(security_token, owner_sid);
     639         410 :         if (ok) {
     640         329 :                 return true;
     641             :         }
     642             : 
     643             :         /*
     644             :          * The user can write the SID of the "default administrators group" that
     645             :          * they are a member of.
     646             :          */
     647          81 :         default_owner = get_default_ag(mem_ctx, dn,
     648             :                                        security_token, ldb);
     649          81 :         if (default_owner != NULL) {
     650           0 :                 ok = security_token_is_sid(security_token, owner_sid);
     651             :         }
     652             : 
     653          81 :         return ok;
     654             : }
     655             : 
     656      543328 : static int descriptor_add(struct ldb_module *module, struct ldb_request *req)
     657             : {
     658      543328 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     659       83657 :         struct ldb_request *add_req;
     660       83657 :         struct ldb_message *msg;
     661       83657 :         struct ldb_result *parent_res;
     662      543328 :         const struct ldb_val *parent_sd = NULL;
     663      543328 :         const struct ldb_val *user_sd = NULL;
     664      543328 :         struct ldb_dn *dn = req->op.add.message->dn;
     665       83657 :         struct ldb_dn *parent_dn, *nc_root;
     666       83657 :         struct ldb_message_element *objectclass_element, *sd_element;
     667       83657 :         int ret;
     668       83657 :         const struct dsdb_schema *schema;
     669       83657 :         DATA_BLOB *sd;
     670       83657 :         const struct dsdb_class *objectclass;
     671       83657 :         static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
     672       83657 :         uint32_t instanceType;
     673      543328 :         bool isNC = false;
     674       83657 :         enum ndr_err_code ndr_err;
     675      543328 :         struct dsdb_control_calculated_default_sd *control_sd = NULL;
     676      543328 :         uint32_t sd_flags = dsdb_request_sd_flags(req, NULL);
     677      543328 :         struct security_descriptor *user_descriptor = NULL;
     678             : 
     679             :         /* do not manipulate our control entries */
     680      543328 :         if (ldb_dn_is_special(dn)) {
     681         538 :                 return ldb_next_request(module, req);
     682             :         }
     683             : 
     684      542790 :         user_sd = ldb_msg_find_ldb_val(req->op.add.message, "nTSecurityDescriptor");
     685      542790 :         sd_element = ldb_msg_find_element(req->op.add.message, "nTSecurityDescriptor");
     686             :         /* nTSecurityDescriptor without a value is an error, letting through so it is handled */
     687      542790 :         if (user_sd == NULL && sd_element) {
     688           1 :                 return ldb_next_request(module, req);
     689             :         }
     690             : 
     691      542789 :         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: %s\n", ldb_dn_get_linearized(dn));
     692             : 
     693      542789 :         instanceType = ldb_msg_find_attr_as_uint(req->op.add.message, "instanceType", 0);
     694             : 
     695      542789 :         if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) {
     696         503 :                 isNC = true;
     697             :         }
     698             : 
     699      542681 :         if (!isNC) {
     700      542178 :                 ret = dsdb_find_nc_root(ldb, req, dn, &nc_root);
     701      542178 :                 if (ret != LDB_SUCCESS) {
     702           1 :                         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find NC root for %s\n",
     703             :                                 ldb_dn_get_linearized(dn));
     704           1 :                         return ret;
     705             :                 }
     706             : 
     707      542177 :                 if (ldb_dn_compare(dn, nc_root) == 0) {
     708           0 :                         DEBUG(0, ("Found DN %s being a NC by the old method\n", ldb_dn_get_linearized(dn)));
     709           0 :                         isNC = true;
     710             :                 }
     711             :         }
     712             : 
     713      542788 :         if (isNC) {
     714         611 :                 DEBUG(2, ("DN: %s is a NC\n", ldb_dn_get_linearized(dn)));
     715             :         }
     716      542788 :         if (!isNC) {
     717             :                 /* if the object has a parent, retrieve its SD to
     718             :                  * use for calculation. Unfortunately we do not yet have
     719             :                  * instanceType, so we use dsdb_find_nc_root. */
     720             : 
     721      542177 :                 parent_dn = ldb_dn_get_parent(req, dn);
     722      542177 :                 if (parent_dn == NULL) {
     723           0 :                         return ldb_oom(ldb);
     724             :                 }
     725             : 
     726             :                 /* we aren't any NC */
     727      542177 :                 ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn,
     728             :                                             parent_attrs,
     729             :                                             DSDB_FLAG_NEXT_MODULE |
     730             :                                             DSDB_FLAG_AS_SYSTEM |
     731             :                                             DSDB_SEARCH_SHOW_RECYCLED,
     732             :                                             req);
     733      542177 :                 if (ret != LDB_SUCCESS) {
     734           0 :                         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find SD for %s\n",
     735             :                                   ldb_dn_get_linearized(parent_dn));
     736           0 :                         return ret;
     737             :                 }
     738      542177 :                 if (parent_res->count != 1) {
     739           0 :                         return ldb_operr(ldb);
     740             :                 }
     741      542177 :                 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
     742             :         }
     743             : 
     744      542788 :         schema = dsdb_get_schema(ldb, req);
     745             : 
     746      542788 :         objectclass_element = ldb_msg_find_element(req->op.add.message, "objectClass");
     747      542788 :         if (objectclass_element == NULL) {
     748           0 :                 return ldb_operr(ldb);
     749             :         }
     750             : 
     751      542788 :         objectclass = dsdb_get_last_structural_class(schema,
     752             :                                                      objectclass_element);
     753      542788 :         if (objectclass == NULL) {
     754           0 :                 return ldb_operr(ldb);
     755             :         }
     756             : 
     757             :         /*
     758             :          * The SD_FLAG control is ignored on add
     759             :          * and we default to all bits set.
     760             :          */
     761      542788 :         sd_flags = SECINFO_OWNER|SECINFO_GROUP|SECINFO_SACL|SECINFO_DACL;
     762             : 
     763      542788 :         control_sd = talloc(req, struct dsdb_control_calculated_default_sd);
     764      542788 :         if (control_sd == NULL) {
     765           0 :                 return ldb_operr(ldb);
     766             :         }
     767      542788 :         control_sd->specified_sd = false;
     768      542788 :         control_sd->specified_sacl = false;
     769      542788 :         if (user_sd != NULL) {
     770       10108 :                 user_descriptor = talloc(req, struct security_descriptor);
     771       10108 :                 if (user_descriptor == NULL) {
     772           0 :                         return ldb_operr(ldb);
     773             :                 }
     774       10108 :                 ndr_err = ndr_pull_struct_blob(user_sd, user_descriptor,
     775             :                                                user_descriptor,
     776             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     777             : 
     778       10108 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     779           0 :                         talloc_free(user_descriptor);
     780           0 :                         return ldb_operr(ldb);
     781             :                 }
     782             :                 /*
     783             :                  * calculate the permissions needed, since in acl we no longer have
     784             :                  * access to the original user descriptor
     785             :                  */
     786       10108 :                 control_sd->specified_sd = true;
     787       10108 :                 control_sd->specified_sacl = user_descriptor->sacl != NULL;
     788             : 
     789       10108 :                 if (user_descriptor->owner_sid != NULL) {
     790             :                         /* Verify the owner of the security descriptor. */
     791             : 
     792         300 :                         const struct auth_session_info *session_info
     793        2605 :                                 = ldb_get_opaque(ldb, DSDB_SESSION_INFO);
     794             : 
     795        2905 :                         bool ok = can_write_owner(req,
     796             :                                                   ldb,
     797             :                                                   dn,
     798        2605 :                                                   session_info->security_token,
     799        2605 :                                                   user_descriptor->owner_sid);
     800        2605 :                         talloc_free(user_descriptor);
     801        2605 :                         if (!ok) {
     802           9 :                                 return dsdb_module_werror(module,
     803             :                                                           LDB_ERR_CONSTRAINT_VIOLATION,
     804             :                                                           WERR_INVALID_OWNER,
     805             :                                                           "invalid addition of owner SID");
     806             :                         }
     807             :                 }
     808             :         }
     809             : 
     810      542779 :         sd = get_new_descriptor(module, dn, req,
     811             :                                 objectclass, parent_sd,
     812             :                                 user_sd, NULL, sd_flags);
     813      542779 :         if (sd == NULL) {
     814           0 :                 return ldb_operr(ldb);
     815             :         }
     816             : 
     817      542779 :         control_sd->default_sd = get_new_descriptor_nonlinear(module,
     818             :                                                               dn,
     819             :                                                               req,
     820             :                                                               objectclass,
     821             :                                                               parent_sd,
     822             :                                                               NULL,
     823             :                                                               NULL,
     824             :                                                               sd_flags);
     825      542779 :         if (control_sd->default_sd == NULL) {
     826           0 :                 return ldb_operr(ldb);
     827             :         }
     828             : 
     829      542779 :         msg = ldb_msg_copy_shallow(req, req->op.add.message);
     830      542779 :         if (msg == NULL) {
     831           0 :                 return ldb_oom(ldb);
     832             :         }
     833      542779 :         if (sd_element != NULL) {
     834       10099 :                 sd_element->values[0] = *sd;
     835             :         } else {
     836      532680 :                 ret = ldb_msg_add_steal_value(msg,
     837             :                                               "nTSecurityDescriptor",
     838             :                                               sd);
     839      532680 :                 if (ret != LDB_SUCCESS) {
     840           0 :                         return ret;
     841             :                 }
     842             :         }
     843             : 
     844      542779 :         ret = ldb_build_add_req(&add_req, ldb, req,
     845             :                                 msg,
     846             :                                 req->controls,
     847             :                                 req, dsdb_next_callback,
     848             :                                 req);
     849             : 
     850      542779 :         LDB_REQ_SET_LOCATION(add_req);
     851      542779 :         if (ret != LDB_SUCCESS) {
     852           0 :                 return ldb_error(ldb, ret,
     853             :                                  "descriptor_add: Error creating new add request.");
     854             :         }
     855             : 
     856      542779 :         *control_sd->default_sd->owner_sid = global_sid_NULL;
     857      542779 :         ret = ldb_request_add_control(add_req,
     858             :                                       DSDB_CONTROL_CALCULATED_DEFAULT_SD_OID,
     859             :                                       false, (void *)control_sd);
     860      542779 :         if (ret != LDB_SUCCESS) {
     861           0 :                 return ldb_module_operr(module);
     862             :         }
     863      542779 :         return ldb_next_request(module, add_req);
     864             : }
     865             : 
     866     1387152 : static int descriptor_modify(struct ldb_module *module, struct ldb_request *req)
     867             : {
     868     1387152 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     869       57463 :         struct ldb_request *mod_req;
     870       57463 :         struct ldb_message *msg;
     871       57463 :         struct ldb_result *current_res, *parent_res;
     872     1387152 :         const struct ldb_val *old_sd = NULL;
     873     1387152 :         const struct ldb_val *parent_sd = NULL;
     874     1387152 :         const struct ldb_val *user_sd = NULL;
     875     1387152 :         struct ldb_dn *dn = req->op.mod.message->dn;
     876       57463 :         struct ldb_dn *parent_dn;
     877       57463 :         struct ldb_message_element *objectclass_element, *sd_element;
     878       57463 :         int ret;
     879       57463 :         uint32_t instanceType;
     880     1387152 :         bool explicit_sd_flags = false;
     881     1387152 :         uint32_t sd_flags = dsdb_request_sd_flags(req, &explicit_sd_flags);
     882       57463 :         const struct dsdb_schema *schema;
     883       57463 :         DATA_BLOB *sd;
     884       57463 :         const struct dsdb_class *objectclass;
     885       57463 :         static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
     886       57463 :         static const char * const current_attrs[] = { "nTSecurityDescriptor",
     887             :                                                       "instanceType",
     888             :                                                       "objectClass", NULL };
     889     1387152 :         struct GUID parent_guid = { .time_low = 0 };
     890       57463 :         struct ldb_control *sd_propagation_control;
     891     1387152 :         int cmp_ret = -1;
     892             : 
     893             :         /* do not manipulate our control entries */
     894     1387152 :         if (ldb_dn_is_special(dn)) {
     895         715 :                 return ldb_next_request(module, req);
     896             :         }
     897             : 
     898     1386437 :         sd_propagation_control = ldb_request_get_control(req,
     899             :                                         DSDB_CONTROL_SEC_DESC_PROPAGATION_OID);
     900     1386437 :         if (sd_propagation_control != NULL) {
     901     1064914 :                 if (sd_propagation_control->data != module) {
     902           0 :                         return ldb_operr(ldb);
     903             :                 }
     904     1064914 :                 if (req->op.mod.message->num_elements != 0) {
     905           0 :                         return ldb_operr(ldb);
     906             :                 }
     907     1064914 :                 if (explicit_sd_flags) {
     908           0 :                         return ldb_operr(ldb);
     909             :                 }
     910     1064914 :                 if (sd_flags != 0xF) {
     911           0 :                         return ldb_operr(ldb);
     912             :                 }
     913     1064914 :                 if (sd_propagation_control->critical == 0) {
     914           0 :                         return ldb_operr(ldb);
     915             :                 }
     916             : 
     917     1064914 :                 sd_propagation_control->critical = 0;
     918             :         }
     919             : 
     920     1386437 :         sd_element = ldb_msg_find_element(req->op.mod.message, "nTSecurityDescriptor");
     921     1386437 :         if (sd_propagation_control == NULL && sd_element == NULL) {
     922      292445 :                 return ldb_next_request(module, req);
     923             :         }
     924             : 
     925             :         /*
     926             :          * nTSecurityDescriptor with DELETE is not supported yet.
     927             :          * TODO: handle this correctly.
     928             :          */
     929     1093992 :         if (sd_propagation_control == NULL &&
     930       29078 :             LDB_FLAG_MOD_TYPE(sd_element->flags) == LDB_FLAG_MOD_DELETE)
     931             :         {
     932           7 :                 return ldb_module_error(module,
     933             :                                         LDB_ERR_UNWILLING_TO_PERFORM,
     934             :                                         "MOD_DELETE for nTSecurityDescriptor "
     935             :                                         "not supported yet");
     936             :         }
     937             : 
     938     1093985 :         user_sd = ldb_msg_find_ldb_val(req->op.mod.message, "nTSecurityDescriptor");
     939             :         /* nTSecurityDescriptor without a value is an error, letting through so it is handled */
     940     1093985 :         if (sd_propagation_control == NULL && user_sd == NULL) {
     941           8 :                 return ldb_next_request(module, req);
     942             :         }
     943             : 
     944     1093977 :         if (sd_flags & SECINFO_OWNER && user_sd != NULL) {
     945             :                 /* Verify the new owner of the security descriptor. */
     946             : 
     947       13085 :                 struct security_descriptor *user_descriptor = NULL;
     948          55 :                 enum ndr_err_code ndr_err;
     949          55 :                 const struct auth_session_info *session_info;
     950          55 :                 bool ok;
     951             : 
     952       13085 :                 user_descriptor = talloc(req, struct security_descriptor);
     953             : 
     954       13085 :                 if (user_descriptor == NULL) {
     955           0 :                         return ldb_operr(ldb);
     956             :                 }
     957       13085 :                 ndr_err = ndr_pull_struct_blob(user_sd, user_descriptor,
     958             :                                                user_descriptor,
     959             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     960             : 
     961       13085 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     962           0 :                         talloc_free(user_descriptor);
     963           0 :                         return ldb_operr(ldb);
     964             :                 }
     965             : 
     966       13085 :                 session_info = ldb_get_opaque(ldb, DSDB_SESSION_INFO);
     967             : 
     968       13140 :                 ok = can_write_owner(req,
     969             :                                      ldb,
     970             :                                      dn,
     971       13085 :                                      session_info->security_token,
     972       13085 :                                      user_descriptor->owner_sid);
     973       13085 :                 talloc_free(user_descriptor);
     974       13085 :                 if (!ok) {
     975          72 :                         return dsdb_module_werror(module,
     976             :                                                   LDB_ERR_CONSTRAINT_VIOLATION,
     977             :                                                   WERR_INVALID_OWNER,
     978             :                                                   "invalid modification of owner SID");
     979             :                 }
     980             :         }
     981             : 
     982     1093905 :         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_modify: %s\n", ldb_dn_get_linearized(dn));
     983             : 
     984     1093905 :         ret = dsdb_module_search_dn(module, req, &current_res, dn,
     985             :                                     current_attrs,
     986             :                                     DSDB_FLAG_NEXT_MODULE |
     987             :                                     DSDB_FLAG_AS_SYSTEM |
     988             :                                     DSDB_SEARCH_SHOW_RECYCLED |
     989             :                                     DSDB_SEARCH_SHOW_EXTENDED_DN,
     990             :                                     req);
     991     1093905 :         if (ret != LDB_SUCCESS) {
     992           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR,"descriptor_modify: Could not find %s\n",
     993             :                           ldb_dn_get_linearized(dn));
     994           0 :                 return ret;
     995             :         }
     996             : 
     997     1093905 :         instanceType = ldb_msg_find_attr_as_uint(current_res->msgs[0],
     998             :                                                  "instanceType", 0);
     999             :         /* if the object has a parent, retrieve its SD to
    1000             :          * use for calculation */
    1001     1093905 :         if (!ldb_dn_is_null(current_res->msgs[0]->dn) &&
    1002     1093905 :             !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
    1003       40545 :                 NTSTATUS status;
    1004             : 
    1005     1092927 :                 parent_dn = ldb_dn_get_parent(req, dn);
    1006     1092927 :                 if (parent_dn == NULL) {
    1007           0 :                         return ldb_oom(ldb);
    1008             :                 }
    1009     1092927 :                 ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn,
    1010             :                                             parent_attrs,
    1011             :                                             DSDB_FLAG_NEXT_MODULE |
    1012             :                                             DSDB_FLAG_AS_SYSTEM |
    1013             :                                             DSDB_SEARCH_SHOW_RECYCLED |
    1014             :                                             DSDB_SEARCH_SHOW_EXTENDED_DN,
    1015             :                                             req);
    1016     1092927 :                 if (ret != LDB_SUCCESS) {
    1017           0 :                         ldb_debug(ldb, LDB_DEBUG_ERROR, "descriptor_modify: Could not find SD for %s\n",
    1018             :                                   ldb_dn_get_linearized(parent_dn));
    1019           0 :                         return ret;
    1020             :                 }
    1021     1092927 :                 if (parent_res->count != 1) {
    1022           0 :                         return ldb_operr(ldb);
    1023             :                 }
    1024     1092927 :                 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
    1025             : 
    1026     1092927 :                 status = dsdb_get_extended_dn_guid(parent_res->msgs[0]->dn,
    1027             :                                                    &parent_guid,
    1028             :                                                    "GUID");
    1029     1092927 :                 if (!NT_STATUS_IS_OK(status)) {
    1030           0 :                         return ldb_operr(ldb);
    1031             :                 }
    1032             :         }
    1033             : 
    1034     1093905 :         schema = dsdb_get_schema(ldb, req);
    1035             : 
    1036     1093905 :         objectclass_element = ldb_msg_find_element(current_res->msgs[0], "objectClass");
    1037     1093905 :         if (objectclass_element == NULL) {
    1038           0 :                 return ldb_operr(ldb);
    1039             :         }
    1040             : 
    1041     1093905 :         objectclass = dsdb_get_last_structural_class(schema,
    1042             :                                                      objectclass_element);
    1043     1093905 :         if (objectclass == NULL) {
    1044           0 :                 return ldb_operr(ldb);
    1045             :         }
    1046             : 
    1047     1093905 :         old_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor");
    1048     1093905 :         if (old_sd == NULL) {
    1049           0 :                 return ldb_operr(ldb);
    1050             :         }
    1051             : 
    1052     1093905 :         if (sd_propagation_control != NULL) {
    1053             :                 /*
    1054             :                  * This just triggers a recalculation of the
    1055             :                  * inherited aces.
    1056             :                  */
    1057     1064914 :                 user_sd = old_sd;
    1058             :         }
    1059             : 
    1060     1093905 :         sd = get_new_descriptor(module, current_res->msgs[0]->dn, req,
    1061             :                                 objectclass, parent_sd,
    1062             :                                 user_sd, old_sd, sd_flags);
    1063     1093905 :         if (sd == NULL) {
    1064           0 :                 return ldb_operr(ldb);
    1065             :         }
    1066     1093905 :         msg = ldb_msg_copy_shallow(req, req->op.mod.message);
    1067     1093905 :         if (msg == NULL) {
    1068           0 :                 return ldb_oom(ldb);
    1069             :         }
    1070     1093905 :         cmp_ret = data_blob_cmp(old_sd, sd);
    1071     1093905 :         if (sd_propagation_control != NULL) {
    1072     1064914 :                 if (cmp_ret == 0) {
    1073             :                         /*
    1074             :                          * The nTSecurityDescriptor is unchanged,
    1075             :                          * which means we can stop the processing.
    1076             :                          *
    1077             :                          * We mark the control as critical again,
    1078             :                          * as we have not processed it, so the caller
    1079             :                          * can tell that the descriptor was unchanged.
    1080             :                          */
    1081      794783 :                         sd_propagation_control->critical = 1;
    1082      794783 :                         return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
    1083             :                 }
    1084             : 
    1085      270131 :                 ret = ldb_msg_append_value(msg, "nTSecurityDescriptor",
    1086             :                                            sd, LDB_FLAG_MOD_REPLACE);
    1087      270131 :                 if (ret != LDB_SUCCESS) {
    1088           0 :                         return ldb_oom(ldb);
    1089             :                 }
    1090       28991 :         } else if (cmp_ret != 0) {
    1091         347 :                 struct GUID guid;
    1092         347 :                 struct ldb_dn *nc_root;
    1093         347 :                 NTSTATUS status;
    1094             : 
    1095       28454 :                 ret = dsdb_find_nc_root(ldb,
    1096             :                                         msg,
    1097       28107 :                                         current_res->msgs[0]->dn,
    1098             :                                         &nc_root);
    1099       28107 :                 if (ret != LDB_SUCCESS) {
    1100           0 :                         return ldb_oom(ldb);
    1101             :                 }
    1102             : 
    1103       28107 :                 status = dsdb_get_extended_dn_guid(current_res->msgs[0]->dn,
    1104             :                                                    &guid,
    1105             :                                                    "GUID");
    1106       28107 :                 if (!NT_STATUS_IS_OK(status)) {
    1107           0 :                         return ldb_operr(ldb);
    1108             :                 }
    1109             : 
    1110             :                 /*
    1111             :                  * Force SD propagation on children of this record
    1112             :                  */
    1113       28107 :                 ret = dsdb_module_schedule_sd_propagation(module,
    1114             :                                                           nc_root,
    1115             :                                                           guid,
    1116             :                                                           parent_guid,
    1117             :                                                           false);
    1118       28107 :                 if (ret != LDB_SUCCESS) {
    1119           0 :                         return ldb_operr(ldb);
    1120             :                 }
    1121       28107 :                 sd_element->values[0] = *sd;
    1122             :         } else {
    1123         884 :                 sd_element->values[0] = *sd;
    1124             :         }
    1125             : 
    1126      299122 :         ret = ldb_build_mod_req(&mod_req, ldb, req,
    1127             :                                 msg,
    1128             :                                 req->controls,
    1129             :                                 req,
    1130             :                                 dsdb_next_callback,
    1131             :                                 req);
    1132      299122 :         LDB_REQ_SET_LOCATION(mod_req);
    1133      299122 :         if (ret != LDB_SUCCESS) {
    1134           0 :                 return ret;
    1135             :         }
    1136             : 
    1137      299122 :         return ldb_next_request(module, mod_req);
    1138             : }
    1139             : 
    1140    29780946 : static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
    1141             : {
    1142     1602849 :         int ret;
    1143     1602849 :         struct ldb_context *ldb;
    1144     1602849 :         struct ldb_request *down_req;
    1145     1602849 :         struct descriptor_context *ac;
    1146    29780946 :         bool explicit_sd_flags = false;
    1147    29780946 :         uint32_t sd_flags = dsdb_request_sd_flags(req, &explicit_sd_flags);
    1148    29780946 :         bool show_sd = explicit_sd_flags;
    1149             : 
    1150    58268684 :         if (!show_sd &&
    1151    28487738 :             ldb_attr_in_list(req->op.search.attrs, "nTSecurityDescriptor"))
    1152             :         {
    1153      776406 :                 show_sd = true;
    1154             :         }
    1155             : 
    1156    29780926 :         if (!show_sd) {
    1157    27711312 :                 return ldb_next_request(module, req);
    1158             :         }
    1159             : 
    1160     2069634 :         ldb = ldb_module_get_ctx(module);
    1161     2069634 :         ac = descriptor_init_context(module, req);
    1162     2069634 :         if (ac == NULL) {
    1163           0 :                 return ldb_operr(ldb);
    1164             :         }
    1165     2069634 :         ac->sd_flags = sd_flags;
    1166             : 
    1167     2069634 :         ret = ldb_build_search_req_ex(&down_req, ldb, ac,
    1168             :                                       req->op.search.base,
    1169             :                                       req->op.search.scope,
    1170             :                                       req->op.search.tree,
    1171             :                                       req->op.search.attrs,
    1172             :                                       req->controls,
    1173             :                                       ac, descriptor_search_callback,
    1174             :                                       ac->req);
    1175     2069634 :         LDB_REQ_SET_LOCATION(down_req);
    1176     2069634 :         if (ret != LDB_SUCCESS) {
    1177           0 :                 return ret;
    1178             :         }
    1179             : 
    1180     2069634 :         return ldb_next_request(ac->module, down_req);
    1181             : }
    1182             : 
    1183        1527 : static int descriptor_rename_callback(struct ldb_request *req,
    1184             :                                       struct ldb_reply *ares)
    1185             : {
    1186        1527 :         struct descriptor_context *ac = NULL;
    1187        1527 :         struct ldb_context *ldb = NULL;
    1188        1527 :         struct ldb_dn *newdn = req->op.rename.newdn;
    1189           5 :         struct GUID guid;
    1190           5 :         struct ldb_dn *nc_root;
    1191        1527 :         struct GUID parent_guid = { .time_low = 0 };
    1192           5 :         int ret;
    1193             : 
    1194        1527 :         ac = talloc_get_type_abort(req->context, struct descriptor_context);
    1195        1527 :         ldb = ldb_module_get_ctx(ac->module);
    1196             : 
    1197        1527 :         if (!ares) {
    1198           0 :                 return ldb_module_done(ac->req, NULL, NULL,
    1199             :                                         LDB_ERR_OPERATIONS_ERROR);
    1200             :         }
    1201        1527 :         if (ares->error != LDB_SUCCESS) {
    1202          70 :                 return ldb_module_done(ac->req, ares->controls,
    1203             :                                         ares->response, ares->error);
    1204             :         }
    1205             : 
    1206        1457 :         if (ares->type != LDB_REPLY_DONE) {
    1207           0 :                 return ldb_module_done(ac->req, NULL, NULL,
    1208             :                                         LDB_ERR_OPERATIONS_ERROR);
    1209             :         }
    1210             : 
    1211        1457 :         ret = dsdb_module_guid_by_dn(ac->module,
    1212             :                                      newdn,
    1213             :                                      &guid,
    1214             :                                      req);
    1215        1457 :         if (ret != LDB_SUCCESS) {
    1216           0 :                 return ldb_module_done(ac->req, NULL, NULL,
    1217             :                                        ret);
    1218             :         }
    1219        1457 :         ret = dsdb_find_nc_root(ldb, req, newdn, &nc_root);
    1220        1457 :         if (ret != LDB_SUCCESS) {
    1221           0 :                 return ldb_module_done(ac->req, NULL, NULL,
    1222             :                                        ret);
    1223             :         }
    1224             : 
    1225             :         /*
    1226             :          * After a successful rename, force SD propagation on this
    1227             :          * record (get a new inherited SD from the potentially new
    1228             :          * parent
    1229             :          *
    1230             :          * We don't know the parent guid here (it is filled in as
    1231             :          * all-zero in the initialiser above), but we're not in a hot
    1232             :          * code path here, as the "descriptor" module is located above
    1233             :          * the "repl_meta_data", only originating changes are handled
    1234             :          * here.
    1235             :          *
    1236             :          * If it turns out to be a problem we may search for the new
    1237             :          * parent guid.
    1238             :          */
    1239             : 
    1240        1457 :         ret = dsdb_module_schedule_sd_propagation(ac->module,
    1241             :                                                   nc_root,
    1242             :                                                   guid,
    1243             :                                                   parent_guid,
    1244             :                                                   true);
    1245        1457 :         if (ret != LDB_SUCCESS) {
    1246           0 :                 ret = ldb_operr(ldb);
    1247           0 :                 return ldb_module_done(ac->req, NULL, NULL,
    1248             :                                        ret);
    1249             :         }
    1250             : 
    1251        1457 :         return ldb_module_done(ac->req, ares->controls,
    1252             :                                ares->response, ares->error);
    1253             : }
    1254             : 
    1255             : 
    1256             : 
    1257             : 
    1258        1533 : static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
    1259             : {
    1260        1533 :         struct descriptor_context *ac = NULL;
    1261        1533 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1262        1533 :         struct ldb_dn *olddn = req->op.rename.olddn;
    1263        1533 :         struct ldb_dn *newdn = req->op.rename.newdn;
    1264           5 :         struct ldb_request *down_req;
    1265           5 :         int ret;
    1266             : 
    1267             :         /* do not manipulate our control entries */
    1268        1533 :         if (ldb_dn_is_special(req->op.rename.olddn)) {
    1269           0 :                 return ldb_next_request(module, req);
    1270             :         }
    1271             : 
    1272        1533 :         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n",
    1273             :                   ldb_dn_get_linearized(olddn));
    1274             : 
    1275        1533 :         if (ldb_dn_compare(olddn, newdn) == 0) {
    1276             :                 /* No special work required for a case-only rename */
    1277           6 :                 return ldb_next_request(module, req);
    1278             :         }
    1279             : 
    1280        1527 :         ac = descriptor_init_context(module, req);
    1281        1527 :         if (ac == NULL) {
    1282           0 :                 return ldb_operr(ldb);
    1283             :         }
    1284             : 
    1285        1527 :         ret = ldb_build_rename_req(&down_req, ldb, ac,
    1286             :                                    req->op.rename.olddn,
    1287             :                                    req->op.rename.newdn,
    1288             :                                    req->controls,
    1289             :                                    ac, descriptor_rename_callback,
    1290             :                                    req);
    1291        1527 :         LDB_REQ_SET_LOCATION(down_req);
    1292        1527 :         if (ret != LDB_SUCCESS) {
    1293           0 :                 return ret;
    1294             :         }
    1295             : 
    1296        1527 :         return ldb_next_request(module, down_req);
    1297             : }
    1298             : 
    1299      642169 : static void descriptor_changes_parser(TDB_DATA key, TDB_DATA data, void *private_data)
    1300             : {
    1301      642169 :         struct descriptor_changes **c_ptr = (struct descriptor_changes **)private_data;
    1302      642169 :         uintptr_t ptr = 0;
    1303             : 
    1304      642169 :         SMB_ASSERT(data.dsize == sizeof(ptr));
    1305             : 
    1306      642169 :         memcpy(&ptr, data.dptr, data.dsize);
    1307             : 
    1308      642169 :         *c_ptr = talloc_get_type_abort((void *)ptr, struct descriptor_changes);
    1309      642169 : }
    1310             : 
    1311      133867 : static void descriptor_object_parser(TDB_DATA key, TDB_DATA data, void *private_data)
    1312             : {
    1313      133867 :         SMB_ASSERT(data.dsize == 0);
    1314      133867 : }
    1315             : 
    1316      371610 : static int descriptor_extended_sec_desc_propagation(struct ldb_module *module,
    1317             :                                                     struct ldb_request *req)
    1318             : {
    1319         352 :         struct descriptor_data *descriptor_private =
    1320      371610 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1321             :                 struct descriptor_data);
    1322      371610 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1323      371610 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1324         352 :         struct dsdb_extended_sec_desc_propagation_op *op;
    1325      371610 :         struct descriptor_changes *c = NULL;
    1326         352 :         TDB_DATA key;
    1327         352 :         NTSTATUS status;
    1328             : 
    1329      371610 :         op = talloc_get_type(req->op.extended.data,
    1330             :                              struct dsdb_extended_sec_desc_propagation_op);
    1331      371610 :         if (op == NULL) {
    1332           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1333             :                           "descriptor_extended_sec_desc_propagation: "
    1334             :                           "invalid extended data\n");
    1335           0 :                 return LDB_ERR_PROTOCOL_ERROR;
    1336             :         }
    1337             : 
    1338      371610 :         if (t->mem == NULL) {
    1339           0 :                 return ldb_module_operr(module);
    1340             :         }
    1341             : 
    1342      371610 :         if (GUID_equal(&op->parent_guid, &op->guid)) {
    1343             :                 /*
    1344             :                  * This is an unexpected situation,
    1345             :                  * it should never happen!
    1346             :                  */
    1347           0 :                 DBG_ERR("ERROR: Object %s is its own parent (nc_root=%s)\n",
    1348             :                         GUID_string(t->mem, &op->guid),
    1349             :                         ldb_dn_get_extended_linearized(t->mem, op->nc_root, 1));
    1350           0 :                 return ldb_module_operr(module);
    1351             :         }
    1352             : 
    1353             :         /*
    1354             :          * First we check if we already have an registration
    1355             :          * for the given object.
    1356             :          */
    1357             : 
    1358      371610 :         key = make_tdb_data((const void*)&op->guid, sizeof(op->guid));
    1359      371610 :         status = dbwrap_parse_record(t->changes.map, key,
    1360             :                                      descriptor_changes_parser, &c);
    1361      371610 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    1362      329078 :                 c = NULL;
    1363      329078 :                 status = NT_STATUS_OK;
    1364             :         }
    1365      371610 :         if (!NT_STATUS_IS_OK(status)) {
    1366           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1367             :                           "dbwrap_parse_record() - %s\n",
    1368             :                           nt_errstr(status));
    1369           0 :                 return ldb_module_operr(module);
    1370             :         }
    1371             : 
    1372      371610 :         if (c == NULL) {
    1373             :                 /*
    1374             :                  * Create a new structure if we
    1375             :                  * don't know about the object yet.
    1376             :                  */
    1377             : 
    1378      329078 :                 c = talloc_zero(t->mem, struct descriptor_changes);
    1379      329078 :                 if (c == NULL) {
    1380           0 :                         return ldb_module_oom(module);
    1381             :                 }
    1382      329078 :                 c->nc_root = ldb_dn_copy(c, op->nc_root);
    1383      329078 :                 if (c->nc_root == NULL) {
    1384           0 :                         return ldb_module_oom(module);
    1385             :                 }
    1386      329078 :                 c->guid = op->guid;
    1387             :         }
    1388             : 
    1389      371610 :         if (ldb_dn_compare(c->nc_root, op->nc_root) != 0) {
    1390             :                 /*
    1391             :                  * This is an unexpected situation,
    1392             :                  * we don't expect the nc root to change
    1393             :                  * during a replication cycle.
    1394             :                  */
    1395           0 :                 DBG_ERR("ERROR: Object %s nc_root changed %s => %s\n",
    1396             :                         GUID_string(c, &c->guid),
    1397             :                         ldb_dn_get_extended_linearized(c, c->nc_root, 1),
    1398             :                         ldb_dn_get_extended_linearized(c, op->nc_root, 1));
    1399           0 :                 return ldb_module_operr(module);
    1400             :         }
    1401             : 
    1402      371610 :         c->ref_count += 1;
    1403             : 
    1404             :         /*
    1405             :          * always use the last known parent_guid.
    1406             :          */
    1407      371610 :         c->parent_guid = op->parent_guid;
    1408             : 
    1409             :         /*
    1410             :          * Note that we only set, but don't clear values here,
    1411             :          * it means c->force_self and c->force_children can
    1412             :          * both be true in the end.
    1413             :          */
    1414      371610 :         if (op->include_self) {
    1415      297880 :                 c->force_self = true;
    1416             :         } else {
    1417       73730 :                 c->force_children = true;
    1418             :         }
    1419             : 
    1420      371610 :         if (c->ref_count == 1) {
    1421      329078 :                 struct TDB_DATA val = make_tdb_data((const void*)&c, sizeof(c));
    1422             : 
    1423             :                 /*
    1424             :                  * Remember the change by objectGUID in order
    1425             :                  * to avoid processing it more than once.
    1426             :                  */
    1427             : 
    1428      329078 :                 status = dbwrap_store(t->changes.map, key, val, TDB_INSERT);
    1429      329078 :                 if (!NT_STATUS_IS_OK(status)) {
    1430           0 :                         ldb_debug(ldb, LDB_DEBUG_FATAL,
    1431             :                                   "dbwrap_parse_record() - %s\n",
    1432             :                                   nt_errstr(status));
    1433           0 :                         return ldb_module_operr(module);
    1434             :                 }
    1435             : 
    1436      329078 :                 DLIST_ADD_END(t->changes.list, c);
    1437      329078 :                 t->changes.num_registered += 1;
    1438             :         }
    1439      371610 :         t->changes.num_registrations += 1;
    1440             : 
    1441      371610 :         return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
    1442             : }
    1443             : 
    1444     1678200 : static int descriptor_extended(struct ldb_module *module, struct ldb_request *req)
    1445             : {
    1446     1678200 :         if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SEC_DESC_PROPAGATION_OID) == 0) {
    1447      371610 :                 return descriptor_extended_sec_desc_propagation(module, req);
    1448             :         }
    1449             : 
    1450     1306590 :         return ldb_next_request(module, req);
    1451             : }
    1452             : 
    1453      179900 : static int descriptor_init(struct ldb_module *module)
    1454             : {
    1455      179900 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1456        5975 :         int ret;
    1457        5975 :         struct descriptor_data *descriptor_private;
    1458             : 
    1459      179900 :         ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
    1460      179900 :         if (ret != LDB_SUCCESS) {
    1461           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR,
    1462             :                         "descriptor: Unable to register control with rootdse!\n");
    1463           0 :                 return ldb_operr(ldb);
    1464             :         }
    1465             : 
    1466      179900 :         descriptor_private = talloc_zero(module, struct descriptor_data);
    1467      179900 :         if (descriptor_private == NULL) {
    1468           0 :                 ldb_oom(ldb);
    1469           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    1470             :         }
    1471      179900 :         ldb_module_set_private(module, descriptor_private);
    1472             : 
    1473      179900 :         return ldb_next_init(module);
    1474             : }
    1475             : 
    1476     1198781 : static int descriptor_sd_propagation_object(struct ldb_module *module,
    1477             :                                             struct ldb_message *msg,
    1478             :                                             bool *stop)
    1479             : {
    1480       40663 :         struct descriptor_data *descriptor_private =
    1481     1198781 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1482             :                 struct descriptor_data);
    1483     1198781 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1484     1198781 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1485       40663 :         struct ldb_request *sub_req;
    1486       40663 :         struct ldb_result *mod_res;
    1487       40663 :         struct ldb_control *sd_propagation_control;
    1488       40663 :         struct GUID guid;
    1489       40663 :         int ret;
    1490       40663 :         TDB_DATA key;
    1491     1198781 :         TDB_DATA empty_val = { .dsize = 0, };
    1492       40663 :         NTSTATUS status;
    1493     1198781 :         struct descriptor_changes *c = NULL;
    1494             : 
    1495     1198781 :         *stop = false;
    1496             : 
    1497             :         /*
    1498             :          * We get the GUID of the object
    1499             :          * in order to have the cache key
    1500             :          * for the object.
    1501             :          */
    1502             : 
    1503     1198781 :         status = dsdb_get_extended_dn_guid(msg->dn, &guid, "GUID");
    1504     1198781 :         if (!NT_STATUS_IS_OK(status)) {
    1505           0 :                 return ldb_operr(ldb);
    1506             :         }
    1507     1198781 :         key = make_tdb_data((const void*)&guid, sizeof(guid));
    1508             : 
    1509             :         /*
    1510             :          * Check if we already processed this object.
    1511             :          */
    1512     1198781 :         status = dbwrap_parse_record(t->objects.map, key,
    1513             :                                      descriptor_object_parser, NULL);
    1514     1198781 :         if (NT_STATUS_IS_OK(status)) {
    1515             :                 /*
    1516             :                  * All work is already one
    1517             :                  */
    1518      133867 :                 t->objects.num_skipped += 1;
    1519      133867 :                 *stop = true;
    1520      133867 :                 return LDB_SUCCESS;
    1521             :         }
    1522     1064914 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    1523           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1524             :                           "dbwrap_parse_record() - %s\n",
    1525             :                           nt_errstr(status));
    1526           0 :                 return ldb_module_operr(module);
    1527             :         }
    1528             : 
    1529     1064914 :         t->objects.num_processed += 1;
    1530             : 
    1531             :         /*
    1532             :          * Remember that we're processing this object.
    1533             :          */
    1534     1064914 :         status = dbwrap_store(t->objects.map, key, empty_val, TDB_INSERT);
    1535     1064914 :         if (!NT_STATUS_IS_OK(status)) {
    1536           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1537             :                           "dbwrap_parse_record() - %s\n",
    1538             :                           nt_errstr(status));
    1539           0 :                 return ldb_module_operr(module);
    1540             :         }
    1541             : 
    1542             :         /*
    1543             :          * Check that if there's a descriptor_change in our list,
    1544             :          * which we may be able to remove from the pending list
    1545             :          * when we processed the object.
    1546             :          */
    1547             : 
    1548     1064914 :         status = dbwrap_parse_record(t->changes.map, key, descriptor_changes_parser, &c);
    1549     1064914 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    1550      758065 :                 c = NULL;
    1551      758065 :                 status = NT_STATUS_OK;
    1552             :         }
    1553     1064914 :         if (!NT_STATUS_IS_OK(status)) {
    1554           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1555             :                           "dbwrap_parse_record() - %s\n",
    1556             :                           nt_errstr(status));
    1557           0 :                 return ldb_module_operr(module);
    1558             :         }
    1559             : 
    1560     1064914 :         mod_res = talloc_zero(msg, struct ldb_result);
    1561     1064914 :         if (mod_res == NULL) {
    1562           0 :                 return ldb_module_oom(module);
    1563             :         }
    1564             : 
    1565     1064914 :         ret = ldb_build_mod_req(&sub_req, ldb, mod_res,
    1566             :                                 msg,
    1567             :                                 NULL,
    1568             :                                 mod_res,
    1569             :                                 ldb_modify_default_callback,
    1570             :                                 NULL);
    1571     1064914 :         LDB_REQ_SET_LOCATION(sub_req);
    1572     1064914 :         if (ret != LDB_SUCCESS) {
    1573           0 :                 return ldb_module_operr(module);
    1574             :         }
    1575             : 
    1576     1064914 :         ldb_req_mark_trusted(sub_req);
    1577             : 
    1578     1064914 :         ret = ldb_request_add_control(sub_req,
    1579             :                                       DSDB_CONTROL_SEC_DESC_PROPAGATION_OID,
    1580             :                                       true, module);
    1581     1064914 :         if (ret != LDB_SUCCESS) {
    1582           0 :                 return ldb_module_operr(module);
    1583             :         }
    1584             : 
    1585     1064914 :         sd_propagation_control = ldb_request_get_control(sub_req,
    1586             :                                         DSDB_CONTROL_SEC_DESC_PROPAGATION_OID);
    1587     1064914 :         if (sd_propagation_control == NULL) {
    1588           0 :                 return ldb_module_operr(module);
    1589             :         }
    1590             : 
    1591     1064914 :         ret = dsdb_request_add_controls(sub_req,
    1592             :                                         DSDB_FLAG_AS_SYSTEM |
    1593             :                                         DSDB_SEARCH_SHOW_RECYCLED);
    1594     1064914 :         if (ret != LDB_SUCCESS) {
    1595           0 :                 return ldb_module_operr(module);
    1596             :         }
    1597             : 
    1598     1064914 :         ret = descriptor_modify(module, sub_req);
    1599     1064914 :         if (ret == LDB_SUCCESS) {
    1600     1064914 :                 ret = ldb_wait(sub_req->handle, LDB_WAIT_ALL);
    1601             :         }
    1602     1064914 :         if (ret != LDB_SUCCESS) {
    1603           0 :                 ldb_asprintf_errstring(ldb_module_get_ctx(module),
    1604             :                                        "descriptor_modify on %s failed: %s",
    1605             :                                        ldb_dn_get_linearized(msg->dn),
    1606             :                                        ldb_errstring(ldb_module_get_ctx(module)));
    1607           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    1608             :         }
    1609             : 
    1610     1064914 :         if (sd_propagation_control->critical != 0) {
    1611      794783 :                 if (c == NULL) {
    1612             :                         /*
    1613             :                          * If we don't have a
    1614             :                          * descriptor_changes structure
    1615             :                          * we're done.
    1616             :                          */
    1617      494888 :                         *stop = true;
    1618      299895 :                 } else if (!c->force_children) {
    1619             :                         /*
    1620             :                          * If we don't need to
    1621             :                          * propagate to children,
    1622             :                          * we're done.
    1623             :                          */
    1624      248634 :                         *stop = true;
    1625             :                 }
    1626             :         }
    1627             : 
    1628     1064914 :         if (c != NULL && !c->force_children) {
    1629             :                 /*
    1630             :                  * Remove the pending change,
    1631             :                  * we already done all required work,
    1632             :                  * there's no need to do it again.
    1633             :                  *
    1634             :                  * Note DLIST_REMOVE() is a noop
    1635             :                  * if the element is not part of
    1636             :                  * the list.
    1637             :                  */
    1638      255542 :                 DLIST_REMOVE(t->changes.list, c);
    1639             :         }
    1640             : 
    1641     1064914 :         talloc_free(mod_res);
    1642             : 
    1643     1064914 :         return LDB_SUCCESS;
    1644             : }
    1645             : 
    1646     7925003 : static int descriptor_sd_propagation_msg_sort(struct ldb_message **m1,
    1647             :                                               struct ldb_message **m2)
    1648             : {
    1649     7925003 :         struct ldb_dn *dn1 = (*m1)->dn;
    1650     7925003 :         struct ldb_dn *dn2 = (*m2)->dn;
    1651             : 
    1652             :         /*
    1653             :          * This sorts in tree order, parents first
    1654             :          */
    1655     7925003 :         return ldb_dn_compare(dn2, dn1);
    1656             : }
    1657             : 
    1658      320404 : static int descriptor_sd_propagation_recursive(struct ldb_module *module,
    1659             :                                                struct descriptor_changes *change)
    1660             : {
    1661         330 :         struct descriptor_data *descriptor_private =
    1662      320404 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1663             :                 struct descriptor_data);
    1664      320404 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1665      320404 :         struct ldb_result *guid_res = NULL;
    1666      320404 :         struct ldb_result *res = NULL;
    1667         330 :         unsigned int i;
    1668      320404 :         const char * const no_attrs[] = { "@__NONE__", NULL };
    1669      320404 :         struct ldb_dn *stopped_dn = NULL;
    1670         330 :         struct GUID_txt_buf guid_buf;
    1671         330 :         int ret;
    1672      320404 :         bool stop = false;
    1673             : 
    1674      320404 :         t->changes.num_processed += 1;
    1675             : 
    1676             :         /*
    1677             :          * First confirm this object has children, or exists
    1678             :          * (depending on change->force_self)
    1679             :          * 
    1680             :          * LDB_SCOPE_SUBTREE searches are expensive.
    1681             :          *
    1682             :          * We know this is safe against a rename race as we are in the
    1683             :          * prepare_commit(), so must be in a transaction.
    1684             :          */
    1685             : 
    1686             :         /* Find the DN by GUID, as this is stable under rename */
    1687      320404 :         ret = dsdb_module_search(module,
    1688             :                                  change,
    1689             :                                  &guid_res,
    1690             :                                  change->nc_root,
    1691             :                                  LDB_SCOPE_SUBTREE,
    1692             :                                  no_attrs,
    1693             :                                  DSDB_FLAG_NEXT_MODULE |
    1694             :                                  DSDB_FLAG_AS_SYSTEM |
    1695             :                                  DSDB_SEARCH_SHOW_DELETED |
    1696             :                                  DSDB_SEARCH_SHOW_RECYCLED |
    1697             :                                  DSDB_SEARCH_SHOW_EXTENDED_DN,
    1698             :                                  NULL, /* parent_req */
    1699             :                                  "(objectGUID=%s)",
    1700      320404 :                                  GUID_buf_string(&change->guid,
    1701             :                                                  &guid_buf));
    1702             : 
    1703      320404 :         if (ret != LDB_SUCCESS) {
    1704           0 :                 return ret;
    1705             :         }
    1706             : 
    1707      320404 :         if (guid_res->count != 1) {
    1708             :                 /*
    1709             :                  * We were just given this GUID during the same
    1710             :                  * transaction, if it is missing this is a big
    1711             :                  * problem.
    1712             :                  *
    1713             :                  * Cleanup of tombstones does not trigger this module
    1714             :                  * as it just does a delete.
    1715             :                  */
    1716           0 :                 ldb_asprintf_errstring(ldb_module_get_ctx(module),
    1717             :                                        "failed to find GUID %s under %s "
    1718             :                                        "for transaction-end SD inheritance: %d results",
    1719           0 :                                        GUID_buf_string(&change->guid,
    1720             :                                                        &guid_buf),
    1721             :                                        ldb_dn_get_linearized(change->nc_root),
    1722           0 :                                        guid_res->count);
    1723           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    1724             :         }
    1725             : 
    1726             :         /*
    1727             :          * OK, so there was a parent, are there children?  Note: that
    1728             :          * this time we do not search for deleted/recycled objects
    1729             :          */
    1730      320734 :         ret = dsdb_module_search(module,
    1731             :                                  change,
    1732             :                                  &res,
    1733      320404 :                                  guid_res->msgs[0]->dn,
    1734             :                                  LDB_SCOPE_ONELEVEL,
    1735             :                                  no_attrs,
    1736             :                                  DSDB_FLAG_NEXT_MODULE |
    1737             :                                  DSDB_FLAG_AS_SYSTEM,
    1738             :                                  NULL, /* parent_req */
    1739             :                                  "(objectClass=*)");
    1740      320404 :         if (ret != LDB_SUCCESS) {
    1741             :                 /*
    1742             :                  * LDB_ERR_NO_SUCH_OBJECT, say if the DN was a deleted
    1743             :                  * object, is ignored by the caller
    1744             :                  */
    1745           0 :                 return ret;
    1746             :         }
    1747             : 
    1748      320404 :         if (res->count == 0 && !change->force_self) {
    1749             :                 /* All done, no children */
    1750       22495 :                 TALLOC_FREE(res);
    1751       22495 :                 return LDB_SUCCESS;
    1752             :         }
    1753             : 
    1754             :         /*
    1755             :          * First, if we are in force_self mode (eg renamed under new
    1756             :          * parent) then apply the SD to the top object
    1757             :          */
    1758      297909 :         if (change->force_self) {
    1759      289333 :                 ret = descriptor_sd_propagation_object(module,
    1760      289328 :                                                        guid_res->msgs[0],
    1761             :                                                        &stop);
    1762      289328 :                 if (ret != LDB_SUCCESS) {
    1763           0 :                         TALLOC_FREE(guid_res);
    1764           0 :                         return ret;
    1765             :                 }
    1766             : 
    1767      289328 :                 if (stop == true && !change->force_children) {
    1768             :                         /* There was no change, nothing more to do */
    1769      240375 :                         TALLOC_FREE(guid_res);
    1770      240375 :                         return LDB_SUCCESS;
    1771             :                 }
    1772             : 
    1773       48953 :                 if (res->count == 0) {
    1774             :                         /* All done! */
    1775       46942 :                         TALLOC_FREE(guid_res);
    1776       46942 :                         return LDB_SUCCESS;
    1777             :                 }
    1778             :         }
    1779             : 
    1780             :         /*
    1781             :          * Look for children
    1782             :          *
    1783             :          * Note: that we do not search for deleted/recycled objects
    1784             :          */
    1785       10685 :         ret = dsdb_module_search(module,
    1786             :                                  change,
    1787             :                                  &res,
    1788       10592 :                                  guid_res->msgs[0]->dn,
    1789             :                                  LDB_SCOPE_SUBTREE,
    1790             :                                  no_attrs,
    1791             :                                  DSDB_FLAG_NEXT_MODULE |
    1792             :                                  DSDB_FLAG_AS_SYSTEM |
    1793             :                                  DSDB_SEARCH_SHOW_EXTENDED_DN,
    1794             :                                  NULL, /* parent_req */
    1795             :                                  "(objectClass=*)");
    1796       10592 :         if (ret != LDB_SUCCESS) {
    1797           0 :                 return ret;
    1798             :         }
    1799             : 
    1800       10592 :         TYPESAFE_QSORT(res->msgs, res->count,
    1801             :                        descriptor_sd_propagation_msg_sort);
    1802             : 
    1803             :         /* We start from 1, the top object has been done */
    1804      931687 :         for (i = 1; i < res->count; i++) {
    1805             :                 /*
    1806             :                  * ldb_dn_compare_base() does not match for NULL but
    1807             :                  * this is clearer
    1808             :                  */
    1809      921095 :                 if (stopped_dn != NULL) {
    1810      653697 :                         ret = ldb_dn_compare_base(stopped_dn,
    1811      616993 :                                                   res->msgs[i]->dn);
    1812             :                         /*
    1813             :                          * Skip further processing of this
    1814             :                          * sub-subtree
    1815             :                          */
    1816      616993 :                         if (ret == 0) {
    1817       11642 :                                 continue;
    1818             :                         }
    1819             :                 }
    1820      950111 :                 ret = descriptor_sd_propagation_object(module,
    1821      909453 :                                                        res->msgs[i],
    1822             :                                                        &stop);
    1823      909453 :                 if (ret != LDB_SUCCESS) {
    1824           0 :                         return ret;
    1825             :                 }
    1826             : 
    1827      909453 :                 if (stop) {
    1828             :                         /*
    1829             :                          * If this child didn't change, then nothing
    1830             :                          * under it needs to change
    1831             :                          *
    1832             :                          * res has been sorted into tree order so the
    1833             :                          * next few entries can be skipped
    1834             :                          */
    1835      595053 :                         stopped_dn = res->msgs[i]->dn;
    1836             :                 }
    1837             :         }
    1838             : 
    1839       10592 :         TALLOC_FREE(res);
    1840       10592 :         return LDB_SUCCESS;
    1841             : }
    1842             : 
    1843      349183 : static int descriptor_start_transaction(struct ldb_module *module)
    1844             : {
    1845        2157 :         struct descriptor_data *descriptor_private =
    1846      349183 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1847             :                 struct descriptor_data);
    1848      349183 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1849             : 
    1850      349183 :         if (t->mem != NULL) {
    1851           0 :                 return ldb_module_operr(module);
    1852             :         }
    1853             : 
    1854      349183 :         *t = (struct descriptor_transaction) { .mem = NULL, };
    1855      349183 :         t->mem = talloc_new(descriptor_private);
    1856      349183 :         if (t->mem == NULL) {
    1857           0 :                 return ldb_module_oom(module);
    1858             :         }
    1859      349183 :         t->changes.map = db_open_rbt(t->mem);
    1860      349183 :         if (t->changes.map == NULL) {
    1861           0 :                 TALLOC_FREE(t->mem);
    1862           0 :                 *t = (struct descriptor_transaction) { .mem = NULL, };
    1863           0 :                 return ldb_module_oom(module);
    1864             :         }
    1865      349183 :         t->objects.map = db_open_rbt(t->mem);
    1866      349183 :         if (t->objects.map == NULL) {
    1867           0 :                 TALLOC_FREE(t->mem);
    1868           0 :                 *t = (struct descriptor_transaction) { .mem = NULL, };
    1869           0 :                 return ldb_module_oom(module);
    1870             :         }
    1871             : 
    1872      349183 :         return ldb_next_start_trans(module);
    1873             : }
    1874             : 
    1875      304240 : static int descriptor_prepare_commit(struct ldb_module *module)
    1876             : {
    1877        2152 :         struct descriptor_data *descriptor_private =
    1878      304240 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1879             :                 struct descriptor_data);
    1880      304240 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1881      304240 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1882        2152 :         struct descriptor_changes *c, *n;
    1883        2152 :         int ret;
    1884             : 
    1885      304240 :         DBG_NOTICE("changes: num_registrations=%zu\n",
    1886             :                    t->changes.num_registrations);
    1887      304240 :         DBG_NOTICE("changes: num_registered=%zu\n",
    1888             :                    t->changes.num_registered);
    1889             : 
    1890             :         /*
    1891             :          * The security descriptor propagation
    1892             :          * needs to apply the inheritance from
    1893             :          * an object to itself and/or all it's
    1894             :          * children.
    1895             :          *
    1896             :          * In the initial replication during
    1897             :          * a join, we have every object in our
    1898             :          * list.
    1899             :          *
    1900             :          * In order to avoid useless work it's
    1901             :          * better to start with toplevel objects and
    1902             :          * move down to the leaf object from there.
    1903             :          *
    1904             :          * So if the parent_guid is also in our list,
    1905             :          * we better move the object behind its parent.
    1906             :          *
    1907             :          * It allows that the recursive processing of
    1908             :          * the parent already does the work needed
    1909             :          * for the child.
    1910             :          *
    1911             :          * If we have a list for this directory tree:
    1912             :          *
    1913             :          *  A
    1914             :          *    -> B
    1915             :          *        -> C
    1916             :          *            -> D
    1917             :          *                -> E
    1918             :          *
    1919             :          * The initial list would have the order D, E, B, A, C
    1920             :          *
    1921             :          * By still processing from the front, we ensure that,
    1922             :          * when D is found to be below C, that E follows because
    1923             :          * we keep peeling items off the front for checking and
    1924             :          * move them behind their parent.
    1925             :          *
    1926             :          * So we would go:
    1927             :          *
    1928             :          * E B A C D
    1929             :          *
    1930             :          * B A C D E
    1931             :          *
    1932             :          * A B C D E
    1933             :          */
    1934      634318 :         for (c = t->changes.list; c; c = n) {
    1935      330078 :                 struct descriptor_changes *pc = NULL;
    1936      330078 :                 n = c->next;
    1937             : 
    1938      330078 :                 if (c->sort_count >= t->changes.num_registered) {
    1939             :                         /*
    1940             :                          * This should never happen, but it's
    1941             :                          * a sanity check in order to avoid
    1942             :                          * endless loops. Just stop sorting.
    1943             :                          */
    1944           0 :                         break;
    1945             :                 }
    1946             : 
    1947             :                 /*
    1948             :                  * Check if we have the parent also in the list.
    1949             :                  */
    1950      330078 :                 if (!GUID_all_zero((const void*)&c->parent_guid)) {
    1951         503 :                         TDB_DATA pkey;
    1952         503 :                         NTSTATUS status;
    1953             : 
    1954      327559 :                         pkey = make_tdb_data((const void*)&c->parent_guid,
    1955             :                                              sizeof(c->parent_guid));
    1956             : 
    1957      327559 :                         status = dbwrap_parse_record(t->changes.map, pkey,
    1958             :                                                      descriptor_changes_parser, &pc);
    1959      327559 :                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    1960       34771 :                                 pc = NULL;
    1961       34771 :                                 status = NT_STATUS_OK;
    1962             :                         }
    1963      327559 :                         if (!NT_STATUS_IS_OK(status)) {
    1964           0 :                                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1965             :                                           "dbwrap_parse_record() - %s\n",
    1966             :                                           nt_errstr(status));
    1967           0 :                                 return ldb_module_operr(module);
    1968             :                         }
    1969             :                 }
    1970             : 
    1971      330078 :                 if (pc == NULL) {
    1972             :                         /*
    1973             :                          * There is no parent in the list
    1974             :                          */
    1975       37290 :                         t->changes.num_toplevel += 1;
    1976       37290 :                         continue;
    1977             :                 }
    1978             : 
    1979             :                 /*
    1980             :                  * Move the child after the parent
    1981             :                  *
    1982             :                  * Note that we do that multiple times
    1983             :                  * in case the parent already moved itself.
    1984             :                  *
    1985             :                  * See the comment above the loop.
    1986             :                  */
    1987      292788 :                 DLIST_REMOVE(t->changes.list, c);
    1988      292788 :                 DLIST_ADD_AFTER(t->changes.list, c, pc);
    1989             : 
    1990             :                 /*
    1991             :                  * Remember how often we moved the object
    1992             :                  * in order to avoid endless loops.
    1993             :                  */
    1994      292788 :                 c->sort_count += 1;
    1995             :         }
    1996             : 
    1997      304240 :         DBG_NOTICE("changes: num_toplevel=%zu\n", t->changes.num_toplevel);
    1998             : 
    1999      624644 :         while (t->changes.list != NULL) {
    2000      320404 :                 c = t->changes.list;
    2001             : 
    2002      320404 :                 DLIST_REMOVE(t->changes.list, c);
    2003             : 
    2004             :                 /*
    2005             :                  * Note that descriptor_sd_propagation_recursive()
    2006             :                  * may also remove other elements of the list,
    2007             :                  * so we can't use a next pointer
    2008             :                  */
    2009      320404 :                 ret = descriptor_sd_propagation_recursive(module, c);
    2010      320404 :                 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    2011           0 :                         continue;
    2012             :                 }
    2013      320404 :                 if (ret != LDB_SUCCESS) {
    2014           0 :                         return ret;
    2015             :                 }
    2016             :         }
    2017             : 
    2018      304240 :         DBG_NOTICE("changes: num_processed=%zu\n", t->changes.num_processed);
    2019      304240 :         DBG_NOTICE("objects: num_processed=%zu\n", t->objects.num_processed);
    2020      304240 :         DBG_NOTICE("objects: num_skipped=%zu\n", t->objects.num_skipped);
    2021             : 
    2022      304240 :         return ldb_next_prepare_commit(module);
    2023             : }
    2024             : 
    2025      304237 : static int descriptor_end_transaction(struct ldb_module *module)
    2026             : {
    2027        2152 :         struct descriptor_data *descriptor_private =
    2028      304237 :                 talloc_get_type_abort(ldb_module_get_private(module),
    2029             :                 struct descriptor_data);
    2030      304237 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    2031             : 
    2032      304237 :         TALLOC_FREE(t->mem);
    2033      304237 :         *t = (struct descriptor_transaction) { .mem = NULL, };
    2034             : 
    2035      304237 :         return ldb_next_end_trans(module);
    2036             : }
    2037             : 
    2038       44944 : static int descriptor_del_transaction(struct ldb_module *module)
    2039             : {
    2040           4 :         struct descriptor_data *descriptor_private =
    2041       44944 :                 talloc_get_type_abort(ldb_module_get_private(module),
    2042             :                 struct descriptor_data);
    2043       44944 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    2044             : 
    2045       44944 :         TALLOC_FREE(t->mem);
    2046       44944 :         *t = (struct descriptor_transaction) { .mem = NULL, };
    2047             : 
    2048       44944 :         return ldb_next_del_trans(module);
    2049             : }
    2050             : 
    2051             : static const struct ldb_module_ops ldb_descriptor_module_ops = {
    2052             :         .name              = "descriptor",
    2053             :         .search            = descriptor_search,
    2054             :         .add               = descriptor_add,
    2055             :         .modify            = descriptor_modify,
    2056             :         .rename            = descriptor_rename,
    2057             :         .init_context      = descriptor_init,
    2058             :         .extended          = descriptor_extended,
    2059             :         .start_transaction = descriptor_start_transaction,
    2060             :         .prepare_commit    = descriptor_prepare_commit,
    2061             :         .end_transaction   = descriptor_end_transaction,
    2062             :         .del_transaction   = descriptor_del_transaction,
    2063             : };
    2064             : 
    2065        5950 : int ldb_descriptor_module_init(const char *version)
    2066             : {
    2067        5950 :         LDB_MODULE_CHECK_VERSION(version);
    2068        5950 :         return ldb_register_module(&ldb_descriptor_module_ops);
    2069             : }

Generated by: LCOV version 1.14