LCOV - code coverage report
Current view: top level - source4/dsdb/samdb/ldb_modules - descriptor.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 592 725 81.7 %
Date: 2024-06-13 04:01:37 Functions: 26 26 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      999114 : static struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
     117             :                                struct ldb_dn *dn,
     118             :                                struct security_token *token,
     119             :                                struct ldb_context *ldb)
     120             : {
     121      999114 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     122      999114 :         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
     123      999114 :         struct dom_sid *da_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
     124      999114 :         struct dom_sid *ea_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
     125      999114 :         struct dom_sid *sa_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
     126             :         struct dom_sid *dag_sid;
     127             :         struct ldb_dn *nc_root;
     128             :         int ret;
     129             : 
     130      999114 :         ret = dsdb_find_nc_root(ldb, tmp_ctx, dn, &nc_root);
     131      999114 :         if (ret != LDB_SUCCESS) {
     132           0 :                 talloc_free(tmp_ctx);
     133           0 :                 return NULL;
     134             :         }
     135             : 
     136      999114 :         if (ldb_dn_compare(nc_root, ldb_get_schema_basedn(ldb)) == 0) {
     137      477872 :                 if (security_token_has_sid(token, sa_sid)) {
     138      334512 :                         dag_sid = dom_sid_dup(mem_ctx, sa_sid);
     139      143360 :                 } else if (security_token_has_sid(token, ea_sid)) {
     140          54 :                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     141      143306 :                 } else if (security_token_has_sid(token, da_sid)) {
     142          27 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     143      143279 :                 } else if (security_token_is_system(token)) {
     144      143261 :                         dag_sid = dom_sid_dup(mem_ctx, sa_sid);
     145             :                 } else {
     146          18 :                         dag_sid = NULL;
     147             :                 }
     148      521242 :         } else if (ldb_dn_compare(nc_root, ldb_get_config_basedn(ldb)) == 0) {
     149      355940 :                 if (security_token_has_sid(token, ea_sid)) {
     150      236827 :                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     151      119113 :                 } else if (security_token_has_sid(token, da_sid)) {
     152          54 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     153      119059 :                 } else if (security_token_is_system(token)) {
     154      119022 :                         dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     155             :                 } else {
     156          37 :                         dag_sid = NULL;
     157             :                 }
     158      165302 :         } else if (ldb_dn_compare(nc_root, ldb_get_default_basedn(ldb)) == 0) {
     159      154829 :                 if (security_token_has_sid(token, da_sid)) {
     160      101138 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     161       53691 :                 } else if (security_token_has_sid(token, ea_sid)) {
     162          54 :                                 dag_sid = dom_sid_dup(mem_ctx, ea_sid);
     163       53637 :                 } else if (security_token_is_system(token)) {
     164       52759 :                         dag_sid = dom_sid_dup(mem_ctx, da_sid);
     165             :                 } else {
     166         878 :                         dag_sid = NULL;
     167             :                 }
     168             :         } else {
     169       10473 :                 dag_sid = NULL;
     170             :         }
     171             : 
     172      999114 :         talloc_free(tmp_ctx);
     173      999114 :         return dag_sid;
     174             : }
     175             : 
     176      999114 : static struct security_descriptor *get_sd_unpacked(struct ldb_module *module, TALLOC_CTX *mem_ctx,
     177             :                                             const struct dsdb_class *objectclass)
     178             : {
     179      999114 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     180             :         struct security_descriptor *sd;
     181      999114 :         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
     182             : 
     183      999114 :         if (!objectclass->defaultSecurityDescriptor || !domain_sid) {
     184          38 :                 return NULL;
     185             :         }
     186             : 
     187      999076 :         sd = sddl_decode(mem_ctx,
     188      189779 :                          objectclass->defaultSecurityDescriptor,
     189             :                          domain_sid);
     190      999076 :         return sd;
     191             : }
     192             : 
     193      999114 : 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      999114 :         return dag;
     207             : }
     208             : 
     209     1923157 : 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             :         struct security_descriptor *final_sd; 
     215             :         /* if there is no control or control == 0 modify everything */
     216     1923157 :         if (!sd_flags) {
     217           0 :                 return new_sd;
     218             :         }
     219             : 
     220     1923157 :         final_sd = talloc_zero(mem_ctx, struct security_descriptor);
     221     1923157 :         final_sd->revision = SECURITY_DESCRIPTOR_REVISION_1;
     222     1923157 :         final_sd->type = SEC_DESC_SELF_RELATIVE;
     223             : 
     224     1923157 :         if (sd_flags & (SECINFO_OWNER)) {
     225     1907864 :                 if (new_sd->owner_sid) {
     226     1907864 :                         final_sd->owner_sid = talloc_memdup(mem_ctx, new_sd->owner_sid, sizeof(struct dom_sid));
     227             :                 }
     228     1907864 :                 final_sd->type |= new_sd->type & SEC_DESC_OWNER_DEFAULTED;
     229             :         }
     230       15293 :         else if (old_sd) {
     231       15175 :                 if (old_sd->owner_sid) {
     232       15175 :                         final_sd->owner_sid = talloc_memdup(mem_ctx, old_sd->owner_sid, sizeof(struct dom_sid));
     233             :                 }
     234       15175 :                 final_sd->type |= old_sd->type & SEC_DESC_OWNER_DEFAULTED;
     235             :         }
     236             : 
     237     1923157 :         if (sd_flags & (SECINFO_GROUP)) {
     238     1907864 :                 if (new_sd->group_sid) {
     239     1907864 :                         final_sd->group_sid = talloc_memdup(mem_ctx, new_sd->group_sid, sizeof(struct dom_sid));
     240             :                 }
     241     1907864 :                 final_sd->type |= new_sd->type & SEC_DESC_GROUP_DEFAULTED;
     242             :         } 
     243       15293 :         else if (old_sd) {
     244       15175 :                 if (old_sd->group_sid) {
     245       15175 :                         final_sd->group_sid = talloc_memdup(mem_ctx, old_sd->group_sid, sizeof(struct dom_sid));
     246             :                 }
     247       15175 :                 final_sd->type |= old_sd->type & SEC_DESC_GROUP_DEFAULTED;
     248             :         }
     249             : 
     250     1923157 :         if (sd_flags & (SECINFO_SACL)) {
     251     1908920 :                 final_sd->sacl = security_acl_dup(mem_ctx,new_sd->sacl);
     252     1908920 :                 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       14237 :         else if (old_sd && old_sd->sacl) {
     258       13961 :                 final_sd->sacl = security_acl_dup(mem_ctx,old_sd->sacl);
     259       13961 :                 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     1923157 :         if (sd_flags & (SECINFO_DACL)) {
     266     1923022 :                 final_sd->dacl = security_acl_dup(mem_ctx,new_sd->dacl);
     267     1923022 :                 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         135 :         else if (old_sd && old_sd->dacl) {
     273         108 :                 final_sd->dacl = security_acl_dup(mem_ctx,old_sd->dacl);
     274         108 :                 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     1923157 :         final_sd->type |= new_sd->type & SEC_DESC_RM_CONTROL_VALID;
     281     1923157 :         return final_sd;
     282             : }
     283             : 
     284      999114 : static DATA_BLOB *get_new_descriptor(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      999114 :         struct security_descriptor *user_descriptor = NULL, *parent_descriptor = NULL;
     294      999114 :         struct security_descriptor *old_descriptor = NULL;
     295             :         struct security_descriptor *new_sd, *final_sd;
     296             :         DATA_BLOB *linear_sd;
     297             :         enum ndr_err_code ndr_err;
     298      999114 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     299      809327 :         struct auth_session_info *session_info
     300      189787 :                 = ldb_get_opaque(ldb, DSDB_SESSION_INFO);
     301      999114 :         const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
     302             :         struct dom_sid *default_owner;
     303             :         struct dom_sid *default_group;
     304      999114 :         struct security_descriptor *default_descriptor = NULL;
     305      999114 :         struct GUID *object_list = NULL;
     306             : 
     307      999114 :         if (objectclass != NULL) {
     308      999114 :                 default_descriptor = get_sd_unpacked(module, mem_ctx, objectclass);
     309      999114 :                 object_list = talloc_zero_array(mem_ctx, struct GUID, 2);
     310      999114 :                 if (object_list == NULL) {
     311           0 :                         return NULL;
     312             :                 }
     313      999114 :                 object_list[0] = objectclass->schemaIDGUID;
     314             :         }
     315             : 
     316      999114 :         if (object) {
     317      683013 :                 user_descriptor = talloc(mem_ctx, struct security_descriptor);
     318      683013 :                 if (!user_descriptor) {
     319           0 :                         return NULL;
     320             :                 }
     321      683013 :                 ndr_err = ndr_pull_struct_blob(object, user_descriptor, 
     322             :                                                user_descriptor,
     323             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     324             : 
     325      683013 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     326           0 :                         talloc_free(user_descriptor);
     327           0 :                         return NULL;
     328             :                 }
     329             :         } else {
     330      316101 :                 user_descriptor = default_descriptor;
     331             :         }
     332             : 
     333      999114 :         if (old_sd) {
     334      679209 :                 old_descriptor = talloc(mem_ctx, struct security_descriptor);
     335      679209 :                 if (!old_descriptor) {
     336           0 :                         return NULL;
     337             :                 }
     338      679209 :                 ndr_err = ndr_pull_struct_blob(old_sd, old_descriptor, 
     339             :                                                old_descriptor,
     340             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     341             : 
     342      679209 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     343           0 :                         talloc_free(old_descriptor);
     344           0 :                         return NULL;
     345             :                 }
     346             :         }
     347             : 
     348      999114 :         if (parent) {
     349      998198 :                 parent_descriptor = talloc(mem_ctx, struct security_descriptor);
     350      998198 :                 if (!parent_descriptor) {
     351           0 :                         return NULL;
     352             :                 }
     353      998198 :                 ndr_err = ndr_pull_struct_blob(parent, parent_descriptor, 
     354             :                                                parent_descriptor,
     355             :                                                (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     356             : 
     357      998198 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     358           0 :                         talloc_free(parent_descriptor);
     359           0 :                         return NULL;
     360             :                 }
     361             :         }
     362             : 
     363     1808409 :         if (user_descriptor && default_descriptor &&
     364      999074 :             (user_descriptor->dacl == NULL))
     365             :         {
     366        6879 :                 user_descriptor->dacl = default_descriptor->dacl;
     367        6879 :                 user_descriptor->type |= default_descriptor->type & (
     368             :                         SEC_DESC_DACL_PRESENT |
     369             :                         SEC_DESC_DACL_DEFAULTED|SEC_DESC_DACL_AUTO_INHERIT_REQ |
     370             :                         SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_PROTECTED |
     371             :                         SEC_DESC_DACL_TRUSTED);
     372             :         }
     373             : 
     374     1808409 :         if (user_descriptor && default_descriptor &&
     375      999074 :             (user_descriptor->sacl == NULL))
     376             :         {
     377      439314 :                 user_descriptor->sacl = default_descriptor->sacl;
     378      439314 :                 user_descriptor->type |= default_descriptor->type & (
     379             :                         SEC_DESC_SACL_PRESENT |
     380             :                         SEC_DESC_SACL_DEFAULTED|SEC_DESC_SACL_AUTO_INHERIT_REQ |
     381             :                         SEC_DESC_SACL_AUTO_INHERITED|SEC_DESC_SACL_PROTECTED |
     382             :                         SEC_DESC_SERVER_SECURITY);
     383             :         }
     384             : 
     385             : 
     386      999114 :         if (!(sd_flags & SECINFO_OWNER) && user_descriptor) {
     387       15175 :                 user_descriptor->owner_sid = NULL;
     388             : 
     389             :                 /*
     390             :                  * We need the correct owner sid
     391             :                  * when calculating the DACL or SACL
     392             :                  */
     393       15175 :                 if (old_descriptor) {
     394       15175 :                         user_descriptor->owner_sid = old_descriptor->owner_sid;
     395             :                 }
     396             :         }
     397      999114 :         if (!(sd_flags & SECINFO_GROUP) && user_descriptor) {
     398       15175 :                 user_descriptor->group_sid = NULL;
     399             : 
     400             :                 /*
     401             :                  * We need the correct group sid
     402             :                  * when calculating the DACL or SACL
     403             :                  */
     404       15175 :                 if (old_descriptor) {
     405       15175 :                         user_descriptor->group_sid = old_descriptor->group_sid;
     406             :                 }
     407             :         }
     408      999114 :         if (!(sd_flags & SECINFO_DACL) && user_descriptor) {
     409         108 :                 user_descriptor->dacl = NULL;
     410             : 
     411             :                 /*
     412             :                  * We add SEC_DESC_DACL_PROTECTED so that
     413             :                  * create_security_descriptor() skips
     414             :                  * the unused inheritance calculation
     415             :                  */
     416         108 :                 user_descriptor->type |= SEC_DESC_DACL_PROTECTED;
     417             :         }
     418      999114 :         if (!(sd_flags & SECINFO_SACL) && user_descriptor) {
     419       13961 :                 user_descriptor->sacl = NULL;
     420             : 
     421             :                 /*
     422             :                  * We add SEC_DESC_SACL_PROTECTED so that
     423             :                  * create_security_descriptor() skips
     424             :                  * the unused inheritance calculation
     425             :                  */
     426       13961 :                 user_descriptor->type |= SEC_DESC_SACL_PROTECTED;
     427             :         }
     428             : 
     429      999114 :         default_owner = get_default_ag(mem_ctx, dn,
     430             :                                        session_info->security_token, ldb);
     431      999114 :         default_group = get_default_group(mem_ctx, ldb, default_owner);
     432      999114 :         new_sd = create_security_descriptor(mem_ctx,
     433             :                                             parent_descriptor,
     434             :                                             user_descriptor,
     435             :                                             true,
     436             :                                             object_list,
     437             :                                             SEC_DACL_AUTO_INHERIT |
     438             :                                             SEC_SACL_AUTO_INHERIT,
     439             :                                             session_info->security_token,
     440             :                                             default_owner, default_group,
     441             :                                             map_generic_rights_ds);
     442      999114 :         if (!new_sd) {
     443           0 :                 return NULL;
     444             :         }
     445      999114 :         final_sd = descr_handle_sd_flags(mem_ctx, new_sd, old_descriptor, sd_flags);
     446             : 
     447      999114 :         if (!final_sd) {
     448           0 :                 return NULL;
     449             :         }
     450             : 
     451      999114 :         if (final_sd->dacl) {
     452      999114 :                 final_sd->dacl->revision = SECURITY_ACL_REVISION_ADS;
     453             :         }
     454      999114 :         if (final_sd->sacl) {
     455      646657 :                 final_sd->sacl->revision = SECURITY_ACL_REVISION_ADS;
     456             :         }
     457             : 
     458             :         {
     459      999114 :                 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     460      999114 :                 DBG_DEBUG("Object %s created with descriptor %s\n\n",
     461             :                           ldb_dn_get_linearized(dn),
     462             :                           sddl_encode(tmp_ctx, final_sd, domain_sid));
     463      999114 :                 TALLOC_FREE(tmp_ctx);
     464             :         }
     465             : 
     466      999114 :         linear_sd = talloc(mem_ctx, DATA_BLOB);
     467      999114 :         if (!linear_sd) {
     468           0 :                 return NULL;
     469             :         }
     470             : 
     471      999114 :         ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
     472             :                                        final_sd,
     473             :                                        (ndr_push_flags_fn_t)ndr_push_security_descriptor);
     474      999114 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     475           0 :                 return NULL;
     476             :         }
     477             : 
     478      999114 :         return linear_sd;
     479             : }
     480             : 
     481      924043 : static DATA_BLOB *descr_get_descriptor_to_show(struct ldb_module *module,
     482             :                                                TALLOC_CTX *mem_ctx,
     483             :                                                struct ldb_val *sd,
     484             :                                                uint32_t sd_flags)
     485             : {
     486             :         struct security_descriptor *old_sd, *final_sd;
     487             :         DATA_BLOB *linear_sd;
     488             :         enum ndr_err_code ndr_err;
     489             : 
     490      924043 :         old_sd = talloc(mem_ctx, struct security_descriptor);
     491      924043 :         if (!old_sd) {
     492           0 :                 return NULL;
     493             :         }
     494      924043 :         ndr_err = ndr_pull_struct_blob(sd, old_sd, 
     495             :                                        old_sd,
     496             :                                        (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     497             : 
     498      924043 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     499           0 :                 talloc_free(old_sd);
     500           0 :                 return NULL;
     501             :         }
     502             : 
     503      924043 :         final_sd = descr_handle_sd_flags(mem_ctx, old_sd, NULL, sd_flags);
     504             : 
     505      924043 :         if (!final_sd) {
     506           0 :                 return NULL;
     507             :         }
     508             : 
     509      924043 :         linear_sd = talloc(mem_ctx, DATA_BLOB);
     510      924043 :         if (!linear_sd) {
     511           0 :                 return NULL;
     512             :         }
     513             : 
     514      924043 :         ndr_err = ndr_push_struct_blob(linear_sd, mem_ctx,
     515             :                                        final_sd,
     516             :                                        (ndr_push_flags_fn_t)ndr_push_security_descriptor);
     517      924043 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     518           0 :                 return NULL;
     519             :         }
     520             : 
     521      924043 :         return linear_sd;
     522             : }
     523             : 
     524     1435487 : static struct descriptor_context *descriptor_init_context(struct ldb_module *module,
     525             :                                                           struct ldb_request *req)
     526             : {
     527             :         struct ldb_context *ldb;
     528             :         struct descriptor_context *ac;
     529             : 
     530     1435487 :         ldb = ldb_module_get_ctx(module);
     531             : 
     532     1435487 :         ac = talloc_zero(req, struct descriptor_context);
     533     1435487 :         if (ac == NULL) {
     534           0 :                 ldb_set_errstring(ldb, "Out of Memory");
     535           0 :                 return NULL;
     536             :         }
     537             : 
     538     1435487 :         ac->module = module;
     539     1435487 :         ac->req = req;
     540     1435487 :         return ac;
     541             : }
     542             : 
     543     2872644 : static int descriptor_search_callback(struct ldb_request *req, struct ldb_reply *ares)
     544             : {
     545             :         struct descriptor_context *ac;
     546     2872644 :         struct ldb_val *sd_val = NULL;
     547             :         struct ldb_message_element *sd_el;
     548             :         DATA_BLOB *show_sd;
     549     2872644 :         int ret = LDB_SUCCESS;
     550             : 
     551     2872644 :         ac = talloc_get_type(req->context, struct descriptor_context);
     552             : 
     553     2872644 :         if (!ares) {
     554           0 :                 ret = LDB_ERR_OPERATIONS_ERROR;
     555           0 :                 goto fail;
     556             :         }
     557     2872644 :         if (ares->error != LDB_SUCCESS) {
     558           0 :                 return ldb_module_done(ac->req, ares->controls,
     559             :                                         ares->response, ares->error);
     560             :         }
     561             : 
     562     2872644 :         switch (ares->type) {
     563     1436820 :         case LDB_REPLY_ENTRY:
     564     1436820 :                 sd_el = ldb_msg_find_element(ares->message, "nTSecurityDescriptor");
     565     1436820 :                 if (sd_el) {
     566      924043 :                         sd_val = sd_el->values;
     567             :                 }
     568             : 
     569     1436820 :                 if (sd_val) {
     570      924043 :                         show_sd = descr_get_descriptor_to_show(ac->module, ac->req,
     571             :                                                                sd_val, ac->sd_flags);
     572      924043 :                         if (!show_sd) {
     573           0 :                                 ret = LDB_ERR_OPERATIONS_ERROR;
     574           0 :                                 goto fail;
     575             :                         }
     576      924043 :                         ldb_msg_remove_attr(ares->message, "nTSecurityDescriptor");
     577      924043 :                         ret = ldb_msg_add_steal_value(ares->message, "nTSecurityDescriptor", show_sd);
     578      924043 :                         if (ret != LDB_SUCCESS) {
     579           0 :                                 goto fail;
     580             :                         }
     581             :                 }
     582     1436820 :                 return ldb_module_send_entry(ac->req, ares->message, ares->controls);
     583             : 
     584        1256 :         case LDB_REPLY_REFERRAL:
     585        1256 :                 return ldb_module_send_referral(ac->req, ares->referral);
     586             : 
     587     1434568 :         case LDB_REPLY_DONE:
     588     1434568 :                 return ldb_module_done(ac->req, ares->controls,
     589             :                                         ares->response, ares->error);
     590             :         }
     591             : 
     592           0 : fail:
     593           0 :         talloc_free(ares);
     594           0 :         return ldb_module_done(ac->req, NULL, NULL, ret);
     595             : }
     596             : 
     597      320278 : static int descriptor_add(struct ldb_module *module, struct ldb_request *req)
     598             : {
     599      320278 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     600             :         struct ldb_request *add_req;
     601             :         struct ldb_message *msg;
     602             :         struct ldb_result *parent_res;
     603      320278 :         const struct ldb_val *parent_sd = NULL;
     604             :         const struct ldb_val *user_sd;
     605      320278 :         struct ldb_dn *dn = req->op.add.message->dn;
     606             :         struct ldb_dn *parent_dn, *nc_root;
     607             :         struct ldb_message_element *objectclass_element, *sd_element;
     608             :         int ret;
     609             :         const struct dsdb_schema *schema;
     610             :         DATA_BLOB *sd;
     611             :         const struct dsdb_class *objectclass;
     612             :         static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
     613             :         uint32_t instanceType;
     614      320278 :         bool isNC = false;
     615      320278 :         uint32_t sd_flags = dsdb_request_sd_flags(req, NULL);
     616             : 
     617             :         /* do not manipulate our control entries */
     618      320278 :         if (ldb_dn_is_special(dn)) {
     619         371 :                 return ldb_next_request(module, req);
     620             :         }
     621             : 
     622      319907 :         user_sd = ldb_msg_find_ldb_val(req->op.add.message, "nTSecurityDescriptor");
     623      319907 :         sd_element = ldb_msg_find_element(req->op.add.message, "nTSecurityDescriptor");
     624             :         /* nTSecurityDescriptor without a value is an error, letting through so it is handled */
     625      319907 :         if (user_sd == NULL && sd_element) {
     626           1 :                 return ldb_next_request(module, req);
     627             :         }
     628             : 
     629      319906 :         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: %s\n", ldb_dn_get_linearized(dn));
     630             : 
     631      319906 :         instanceType = ldb_msg_find_attr_as_uint(req->op.add.message, "instanceType", 0);
     632             : 
     633      319906 :         if (instanceType & INSTANCE_TYPE_IS_NC_HEAD) {
     634         358 :                 isNC = true;
     635             :         }
     636             : 
     637      319906 :         if (!isNC) {
     638      319548 :                 ret = dsdb_find_nc_root(ldb, req, dn, &nc_root);
     639      319548 :                 if (ret != LDB_SUCCESS) {
     640           1 :                         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find NC root for %s\n",
     641             :                                 ldb_dn_get_linearized(dn));
     642           1 :                         return ret;
     643             :                 }
     644             : 
     645      319547 :                 if (ldb_dn_compare(dn, nc_root) == 0) {
     646           0 :                         DEBUG(0, ("Found DN %s being a NC by the old method\n", ldb_dn_get_linearized(dn)));
     647           0 :                         isNC = true;
     648             :                 }
     649             :         }
     650             : 
     651      319905 :         if (isNC) {
     652         358 :                 DEBUG(2, ("DN: %s is a NC\n", ldb_dn_get_linearized(dn)));
     653             :         }
     654      319905 :         if (!isNC) {
     655             :                 /* if the object has a parent, retrieve its SD to
     656             :                  * use for calculation. Unfortunately we do not yet have
     657             :                  * instanceType, so we use dsdb_find_nc_root. */
     658             : 
     659      319547 :                 parent_dn = ldb_dn_get_parent(req, dn);
     660      319547 :                 if (parent_dn == NULL) {
     661           0 :                         return ldb_oom(ldb);
     662             :                 }
     663             : 
     664             :                 /* we aren't any NC */
     665      319547 :                 ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn,
     666             :                                             parent_attrs,
     667             :                                             DSDB_FLAG_NEXT_MODULE |
     668             :                                             DSDB_FLAG_AS_SYSTEM |
     669             :                                             DSDB_SEARCH_SHOW_RECYCLED,
     670             :                                             req);
     671      319547 :                 if (ret != LDB_SUCCESS) {
     672           0 :                         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find SD for %s\n",
     673             :                                   ldb_dn_get_linearized(parent_dn));
     674           0 :                         return ret;
     675             :                 }
     676      319547 :                 if (parent_res->count != 1) {
     677           0 :                         return ldb_operr(ldb);
     678             :                 }
     679      319547 :                 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
     680             :         }
     681             : 
     682      319905 :         schema = dsdb_get_schema(ldb, req);
     683             : 
     684      319905 :         objectclass_element = ldb_msg_find_element(req->op.add.message, "objectClass");
     685      319905 :         if (objectclass_element == NULL) {
     686           0 :                 return ldb_operr(ldb);
     687             :         }
     688             : 
     689      319905 :         objectclass = dsdb_get_last_structural_class(schema,
     690             :                                                      objectclass_element);
     691      319905 :         if (objectclass == NULL) {
     692           0 :                 return ldb_operr(ldb);
     693             :         }
     694             : 
     695             :         /*
     696             :          * The SD_FLAG control is ignored on add
     697             :          * and we default to all bits set.
     698             :          */
     699      319905 :         sd_flags = SECINFO_OWNER|SECINFO_GROUP|SECINFO_SACL|SECINFO_DACL;
     700             : 
     701      319905 :         sd = get_new_descriptor(module, dn, req,
     702             :                                 objectclass, parent_sd,
     703             :                                 user_sd, NULL, sd_flags);
     704      319905 :         if (sd == NULL) {
     705           0 :                 return ldb_operr(ldb);
     706             :         }
     707      319905 :         msg = ldb_msg_copy_shallow(req, req->op.add.message);
     708      319905 :         if (msg == NULL) {
     709           0 :                 return ldb_oom(ldb);
     710             :         }
     711      319905 :         if (sd_element != NULL) {
     712        3804 :                 sd_element->values[0] = *sd;
     713             :         } else {
     714      316101 :                 ret = ldb_msg_add_steal_value(msg,
     715             :                                               "nTSecurityDescriptor",
     716             :                                               sd);
     717      316101 :                 if (ret != LDB_SUCCESS) {
     718           0 :                         return ret;
     719             :                 }
     720             :         }
     721             : 
     722      319905 :         ret = ldb_build_add_req(&add_req, ldb, req,
     723             :                                 msg,
     724             :                                 req->controls,
     725             :                                 req, dsdb_next_callback,
     726             :                                 req);
     727      319905 :         LDB_REQ_SET_LOCATION(add_req);
     728      319905 :         if (ret != LDB_SUCCESS) {
     729           0 :                 return ldb_error(ldb, ret,
     730             :                                  "descriptor_add: Error creating new add request.");
     731             :         }
     732             : 
     733      319905 :         return ldb_next_request(module, add_req);
     734             : }
     735             : 
     736      895948 : static int descriptor_modify(struct ldb_module *module, struct ldb_request *req)
     737             : {
     738      895948 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     739             :         struct ldb_request *mod_req;
     740             :         struct ldb_message *msg;
     741             :         struct ldb_result *current_res, *parent_res;
     742      895948 :         const struct ldb_val *old_sd = NULL;
     743      895948 :         const struct ldb_val *parent_sd = NULL;
     744             :         const struct ldb_val *user_sd;
     745      895948 :         struct ldb_dn *dn = req->op.mod.message->dn;
     746             :         struct ldb_dn *parent_dn;
     747             :         struct ldb_message_element *objectclass_element, *sd_element;
     748             :         int ret;
     749             :         uint32_t instanceType;
     750      895948 :         bool explicit_sd_flags = false;
     751      895948 :         uint32_t sd_flags = dsdb_request_sd_flags(req, &explicit_sd_flags);
     752             :         const struct dsdb_schema *schema;
     753             :         DATA_BLOB *sd;
     754             :         const struct dsdb_class *objectclass;
     755             :         static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL };
     756             :         static const char * const current_attrs[] = { "nTSecurityDescriptor",
     757             :                                                       "instanceType",
     758             :                                                       "objectClass", NULL };
     759      895948 :         struct GUID parent_guid = { .time_low = 0 };
     760             :         struct ldb_control *sd_propagation_control;
     761      895948 :         int cmp_ret = -1;
     762             : 
     763             :         /* do not manipulate our control entries */
     764      895948 :         if (ldb_dn_is_special(dn)) {
     765         558 :                 return ldb_next_request(module, req);
     766             :         }
     767             : 
     768      895390 :         sd_propagation_control = ldb_request_get_control(req,
     769             :                                         DSDB_CONTROL_SEC_DESC_PROPAGATION_OID);
     770      895390 :         if (sd_propagation_control != NULL) {
     771      652611 :                 if (sd_propagation_control->data != module) {
     772           0 :                         return ldb_operr(ldb);
     773             :                 }
     774      652611 :                 if (req->op.mod.message->num_elements != 0) {
     775           0 :                         return ldb_operr(ldb);
     776             :                 }
     777      652611 :                 if (explicit_sd_flags) {
     778           0 :                         return ldb_operr(ldb);
     779             :                 }
     780      652611 :                 if (sd_flags != 0xF) {
     781           0 :                         return ldb_operr(ldb);
     782             :                 }
     783      652611 :                 if (sd_propagation_control->critical == 0) {
     784           0 :                         return ldb_operr(ldb);
     785             :                 }
     786             : 
     787      652611 :                 sd_propagation_control->critical = 0;
     788             :         }
     789             : 
     790      895390 :         sd_element = ldb_msg_find_element(req->op.mod.message, "nTSecurityDescriptor");
     791      895390 :         if (sd_propagation_control == NULL && sd_element == NULL) {
     792      216166 :                 return ldb_next_request(module, req);
     793             :         }
     794             : 
     795             :         /*
     796             :          * nTSecurityDescriptor with DELETE is not supported yet.
     797             :          * TODO: handle this correctly.
     798             :          */
     799      698694 :         if (sd_propagation_control == NULL &&
     800       26613 :             LDB_FLAG_MOD_TYPE(sd_element->flags) == LDB_FLAG_MOD_DELETE)
     801             :         {
     802           7 :                 return ldb_module_error(module,
     803             :                                         LDB_ERR_UNWILLING_TO_PERFORM,
     804             :                                         "MOD_DELETE for nTSecurityDescriptor "
     805             :                                         "not supported yet");
     806             :         }
     807             : 
     808      679217 :         user_sd = ldb_msg_find_ldb_val(req->op.mod.message, "nTSecurityDescriptor");
     809             :         /* nTSecurityDescriptor without a value is an error, letting through so it is handled */
     810      679217 :         if (sd_propagation_control == NULL && user_sd == NULL) {
     811           8 :                 return ldb_next_request(module, req);
     812             :         }
     813             : 
     814      679209 :         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_modify: %s\n", ldb_dn_get_linearized(dn));
     815             : 
     816      679209 :         ret = dsdb_module_search_dn(module, req, &current_res, dn,
     817             :                                     current_attrs,
     818             :                                     DSDB_FLAG_NEXT_MODULE |
     819             :                                     DSDB_FLAG_AS_SYSTEM |
     820             :                                     DSDB_SEARCH_SHOW_RECYCLED |
     821             :                                     DSDB_SEARCH_SHOW_EXTENDED_DN,
     822             :                                     req);
     823      679209 :         if (ret != LDB_SUCCESS) {
     824           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR,"descriptor_modify: Could not find %s\n",
     825             :                           ldb_dn_get_linearized(dn));
     826           0 :                 return ret;
     827             :         }
     828             : 
     829      679209 :         instanceType = ldb_msg_find_attr_as_uint(current_res->msgs[0],
     830             :                                                  "instanceType", 0);
     831             :         /* if the object has a parent, retrieve its SD to
     832             :          * use for calculation */
     833     1231157 :         if (!ldb_dn_is_null(current_res->msgs[0]->dn) &&
     834      679209 :             !(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
     835             :                 NTSTATUS status;
     836             : 
     837      678651 :                 parent_dn = ldb_dn_get_parent(req, dn);
     838      678651 :                 if (parent_dn == NULL) {
     839           0 :                         return ldb_oom(ldb);
     840             :                 }
     841      678651 :                 ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn,
     842             :                                             parent_attrs,
     843             :                                             DSDB_FLAG_NEXT_MODULE |
     844             :                                             DSDB_FLAG_AS_SYSTEM |
     845             :                                             DSDB_SEARCH_SHOW_RECYCLED |
     846             :                                             DSDB_SEARCH_SHOW_EXTENDED_DN,
     847             :                                             req);
     848      678651 :                 if (ret != LDB_SUCCESS) {
     849           0 :                         ldb_debug(ldb, LDB_DEBUG_ERROR, "descriptor_modify: Could not find SD for %s\n",
     850             :                                   ldb_dn_get_linearized(parent_dn));
     851           0 :                         return ret;
     852             :                 }
     853      678651 :                 if (parent_res->count != 1) {
     854           0 :                         return ldb_operr(ldb);
     855             :                 }
     856      678651 :                 parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor");
     857             : 
     858      678651 :                 status = dsdb_get_extended_dn_guid(parent_res->msgs[0]->dn,
     859             :                                                    &parent_guid,
     860             :                                                    "GUID");
     861      678651 :                 if (!NT_STATUS_IS_OK(status)) {
     862           0 :                         return ldb_operr(ldb);
     863             :                 }
     864             :         }
     865             : 
     866      679209 :         schema = dsdb_get_schema(ldb, req);
     867             : 
     868      679209 :         objectclass_element = ldb_msg_find_element(current_res->msgs[0], "objectClass");
     869      679209 :         if (objectclass_element == NULL) {
     870           0 :                 return ldb_operr(ldb);
     871             :         }
     872             : 
     873      679209 :         objectclass = dsdb_get_last_structural_class(schema,
     874             :                                                      objectclass_element);
     875      679209 :         if (objectclass == NULL) {
     876           0 :                 return ldb_operr(ldb);
     877             :         }
     878             : 
     879      679209 :         old_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor");
     880      679209 :         if (old_sd == NULL) {
     881           0 :                 return ldb_operr(ldb);
     882             :         }
     883             : 
     884      679209 :         if (sd_propagation_control != NULL) {
     885             :                 /*
     886             :                  * This just triggers a recalculation of the
     887             :                  * inherited aces.
     888             :                  */
     889      652611 :                 user_sd = old_sd;
     890             :         }
     891             : 
     892      679209 :         sd = get_new_descriptor(module, current_res->msgs[0]->dn, req,
     893             :                                 objectclass, parent_sd,
     894             :                                 user_sd, old_sd, sd_flags);
     895      679209 :         if (sd == NULL) {
     896           0 :                 return ldb_operr(ldb);
     897             :         }
     898      679209 :         msg = ldb_msg_copy_shallow(req, req->op.mod.message);
     899      679209 :         if (msg == NULL) {
     900           0 :                 return ldb_oom(ldb);
     901             :         }
     902      679209 :         cmp_ret = data_blob_cmp(old_sd, sd);
     903      679209 :         if (sd_propagation_control != NULL) {
     904      652611 :                 if (cmp_ret == 0) {
     905             :                         /*
     906             :                          * The nTSecurityDescriptor is unchanged,
     907             :                          * which means we can stop the processing.
     908             :                          *
     909             :                          * We mark the control as critical again,
     910             :                          * as we have not processed it, so the caller
     911             :                          * can tell that the descriptor was unchanged.
     912             :                          */
     913      529594 :                         sd_propagation_control->critical = 1;
     914      529594 :                         return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
     915             :                 }
     916             : 
     917      123017 :                 ret = ldb_msg_append_value(msg, "nTSecurityDescriptor",
     918             :                                            sd, LDB_FLAG_MOD_REPLACE);
     919      123017 :                 if (ret != LDB_SUCCESS) {
     920           0 :                         return ldb_oom(ldb);
     921             :                 }
     922       26598 :         } else if (cmp_ret != 0) {
     923             :                 struct GUID guid;
     924             :                 struct ldb_dn *nc_root;
     925             :                 NTSTATUS status;
     926             : 
     927       25732 :                 ret = dsdb_find_nc_root(ldb,
     928             :                                         msg,
     929       25732 :                                         current_res->msgs[0]->dn,
     930             :                                         &nc_root);
     931       25732 :                 if (ret != LDB_SUCCESS) {
     932           0 :                         return ldb_oom(ldb);
     933             :                 }
     934             : 
     935       25732 :                 status = dsdb_get_extended_dn_guid(current_res->msgs[0]->dn,
     936             :                                                    &guid,
     937             :                                                    "GUID");
     938       25732 :                 if (!NT_STATUS_IS_OK(status)) {
     939           0 :                         return ldb_operr(ldb);
     940             :                 }
     941             : 
     942             :                 /*
     943             :                  * Force SD propagation on children of this record
     944             :                  */
     945       25732 :                 ret = dsdb_module_schedule_sd_propagation(module,
     946             :                                                           nc_root,
     947             :                                                           guid,
     948             :                                                           parent_guid,
     949             :                                                           false);
     950       25732 :                 if (ret != LDB_SUCCESS) {
     951           0 :                         return ldb_operr(ldb);
     952             :                 }
     953       25732 :                 sd_element->values[0] = *sd;
     954             :         } else {
     955         866 :                 sd_element->values[0] = *sd;
     956             :         }
     957             : 
     958      149615 :         ret = ldb_build_mod_req(&mod_req, ldb, req,
     959             :                                 msg,
     960             :                                 req->controls,
     961             :                                 req,
     962             :                                 dsdb_next_callback,
     963             :                                 req);
     964      149615 :         LDB_REQ_SET_LOCATION(mod_req);
     965      149615 :         if (ret != LDB_SUCCESS) {
     966           0 :                 return ret;
     967             :         }
     968             : 
     969      149615 :         return ldb_next_request(module, mod_req);
     970             : }
     971             : 
     972    17789936 : static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
     973             : {
     974             :         int ret;
     975             :         struct ldb_context *ldb;
     976             :         struct ldb_request *down_req;
     977             :         struct descriptor_context *ac;
     978    17789936 :         bool explicit_sd_flags = false;
     979    17789936 :         uint32_t sd_flags = dsdb_request_sd_flags(req, &explicit_sd_flags);
     980    17789936 :         bool show_sd = explicit_sd_flags;
     981             : 
     982    34753237 :         if (!show_sd &&
     983    16963301 :             ldb_attr_in_list(req->op.search.attrs, "nTSecurityDescriptor"))
     984             :         {
     985      607933 :                 show_sd = true;
     986             :         }
     987             : 
     988    17789936 :         if (!show_sd) {
     989    16355368 :                 return ldb_next_request(module, req);
     990             :         }
     991             : 
     992     1434568 :         ldb = ldb_module_get_ctx(module);
     993     1434568 :         ac = descriptor_init_context(module, req);
     994     1434568 :         if (ac == NULL) {
     995           0 :                 return ldb_operr(ldb);
     996             :         }
     997     1434568 :         ac->sd_flags = sd_flags;
     998             : 
     999     1434568 :         ret = ldb_build_search_req_ex(&down_req, ldb, ac,
    1000             :                                       req->op.search.base,
    1001             :                                       req->op.search.scope,
    1002             :                                       req->op.search.tree,
    1003             :                                       req->op.search.attrs,
    1004             :                                       req->controls,
    1005             :                                       ac, descriptor_search_callback,
    1006             :                                       ac->req);
    1007     1434568 :         LDB_REQ_SET_LOCATION(down_req);
    1008     1434568 :         if (ret != LDB_SUCCESS) {
    1009           0 :                 return ret;
    1010             :         }
    1011             : 
    1012     1434568 :         return ldb_next_request(ac->module, down_req);
    1013             : }
    1014             : 
    1015         919 : static int descriptor_rename_callback(struct ldb_request *req,
    1016             :                                       struct ldb_reply *ares)
    1017             : {
    1018         919 :         struct descriptor_context *ac = NULL;
    1019         919 :         struct ldb_context *ldb = NULL;
    1020         919 :         struct ldb_dn *newdn = req->op.rename.newdn;
    1021             :         struct GUID guid;
    1022             :         struct ldb_dn *nc_root;
    1023         919 :         struct GUID parent_guid = { .time_low = 0 };
    1024             :         int ret;
    1025             : 
    1026         919 :         ac = talloc_get_type_abort(req->context, struct descriptor_context);
    1027         919 :         ldb = ldb_module_get_ctx(ac->module);
    1028             : 
    1029         919 :         if (!ares) {
    1030           0 :                 return ldb_module_done(ac->req, NULL, NULL,
    1031             :                                         LDB_ERR_OPERATIONS_ERROR);
    1032             :         }
    1033         919 :         if (ares->error != LDB_SUCCESS) {
    1034          70 :                 return ldb_module_done(ac->req, ares->controls,
    1035             :                                         ares->response, ares->error);
    1036             :         }
    1037             : 
    1038         849 :         if (ares->type != LDB_REPLY_DONE) {
    1039           0 :                 return ldb_module_done(ac->req, NULL, NULL,
    1040             :                                         LDB_ERR_OPERATIONS_ERROR);
    1041             :         }
    1042             : 
    1043         849 :         ret = dsdb_module_guid_by_dn(ac->module,
    1044             :                                      newdn,
    1045             :                                      &guid,
    1046             :                                      req);
    1047         849 :         if (ret != LDB_SUCCESS) {
    1048           0 :                 return ldb_module_done(ac->req, NULL, NULL,
    1049             :                                        ret);
    1050             :         }
    1051         849 :         ret = dsdb_find_nc_root(ldb, req, newdn, &nc_root);
    1052         849 :         if (ret != LDB_SUCCESS) {
    1053           0 :                 return ldb_module_done(ac->req, NULL, NULL,
    1054             :                                        ret);
    1055             :         }
    1056             : 
    1057             :         /*
    1058             :          * After a successful rename, force SD propagation on this
    1059             :          * record (get a new inherited SD from the potentially new
    1060             :          * parent
    1061             :          *
    1062             :          * We don't know the parent guid here (it is filled in as
    1063             :          * all-zero in the initialiser above), but we're not in a hot
    1064             :          * code path here, as the "descriptor" module is located above
    1065             :          * the "repl_meta_data", only originating changes are handled
    1066             :          * here.
    1067             :          *
    1068             :          * If it turns out to be a problem we may search for the new
    1069             :          * parent guid.
    1070             :          */
    1071             : 
    1072         849 :         ret = dsdb_module_schedule_sd_propagation(ac->module,
    1073             :                                                   nc_root,
    1074             :                                                   guid,
    1075             :                                                   parent_guid,
    1076             :                                                   true);
    1077         849 :         if (ret != LDB_SUCCESS) {
    1078           0 :                 ret = ldb_operr(ldb);
    1079           0 :                 return ldb_module_done(ac->req, NULL, NULL,
    1080             :                                        ret);
    1081             :         }
    1082             : 
    1083         849 :         return ldb_module_done(ac->req, ares->controls,
    1084             :                                ares->response, ares->error);
    1085             : }
    1086             : 
    1087             : 
    1088             : 
    1089             : 
    1090         925 : static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
    1091             : {
    1092         925 :         struct descriptor_context *ac = NULL;
    1093         925 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1094         925 :         struct ldb_dn *olddn = req->op.rename.olddn;
    1095         925 :         struct ldb_dn *newdn = req->op.rename.newdn;
    1096             :         struct ldb_request *down_req;
    1097             :         int ret;
    1098             : 
    1099             :         /* do not manipulate our control entries */
    1100         925 :         if (ldb_dn_is_special(req->op.rename.olddn)) {
    1101           0 :                 return ldb_next_request(module, req);
    1102             :         }
    1103             : 
    1104         925 :         ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n",
    1105             :                   ldb_dn_get_linearized(olddn));
    1106             : 
    1107         925 :         if (ldb_dn_compare(olddn, newdn) == 0) {
    1108             :                 /* No special work required for a case-only rename */
    1109           6 :                 return ldb_next_request(module, req);
    1110             :         }
    1111             : 
    1112         919 :         ac = descriptor_init_context(module, req);
    1113         919 :         if (ac == NULL) {
    1114           0 :                 return ldb_operr(ldb);
    1115             :         }
    1116             : 
    1117         919 :         ret = ldb_build_rename_req(&down_req, ldb, ac,
    1118             :                                    req->op.rename.olddn,
    1119             :                                    req->op.rename.newdn,
    1120             :                                    req->controls,
    1121             :                                    ac, descriptor_rename_callback,
    1122             :                                    req);
    1123         919 :         LDB_REQ_SET_LOCATION(down_req);
    1124         919 :         if (ret != LDB_SUCCESS) {
    1125           0 :                 return ret;
    1126             :         }
    1127             : 
    1128         919 :         return ldb_next_request(module, down_req);
    1129             : }
    1130             : 
    1131      577392 : static void descriptor_changes_parser(TDB_DATA key, TDB_DATA data, void *private_data)
    1132             : {
    1133      577392 :         struct descriptor_changes **c_ptr = (struct descriptor_changes **)private_data;
    1134      577392 :         uintptr_t ptr = 0;
    1135             : 
    1136      577392 :         SMB_ASSERT(data.dsize == sizeof(ptr));
    1137             : 
    1138      577392 :         memcpy(&ptr, data.dptr, data.dsize);
    1139             : 
    1140      577392 :         *c_ptr = talloc_get_type_abort((void *)ptr, struct descriptor_changes);
    1141      577392 : }
    1142             : 
    1143      116047 : static void descriptor_object_parser(TDB_DATA key, TDB_DATA data, void *private_data)
    1144             : {
    1145      116047 :         SMB_ASSERT(data.dsize == 0);
    1146      116047 : }
    1147             : 
    1148      333437 : static int descriptor_extended_sec_desc_propagation(struct ldb_module *module,
    1149             :                                                     struct ldb_request *req)
    1150             : {
    1151      320084 :         struct descriptor_data *descriptor_private =
    1152      333437 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1153             :                 struct descriptor_data);
    1154      333437 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1155      333437 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1156             :         struct dsdb_extended_sec_desc_propagation_op *op;
    1157      333437 :         struct descriptor_changes *c = NULL;
    1158             :         TDB_DATA key;
    1159             :         NTSTATUS status;
    1160             : 
    1161      333437 :         op = talloc_get_type(req->op.extended.data,
    1162             :                              struct dsdb_extended_sec_desc_propagation_op);
    1163      333437 :         if (op == NULL) {
    1164           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1165             :                           "descriptor_extended_sec_desc_propagation: "
    1166             :                           "invalid extended data\n");
    1167           0 :                 return LDB_ERR_PROTOCOL_ERROR;
    1168             :         }
    1169             : 
    1170      333437 :         if (t->mem == NULL) {
    1171           0 :                 return ldb_module_operr(module);
    1172             :         }
    1173             : 
    1174      333437 :         if (GUID_equal(&op->parent_guid, &op->guid)) {
    1175             :                 /*
    1176             :                  * This is an unexpected situation,
    1177             :                  * it should never happen!
    1178             :                  */
    1179           0 :                 DBG_ERR("ERROR: Object %s is its own parent (nc_root=%s)\n",
    1180             :                         GUID_string(t->mem, &op->guid),
    1181             :                         ldb_dn_get_extended_linearized(t->mem, op->nc_root, 1));
    1182           0 :                 return ldb_module_operr(module);
    1183             :         }
    1184             : 
    1185             :         /*
    1186             :          * First we check if we already have an registration
    1187             :          * for the given object.
    1188             :          */
    1189             : 
    1190      333437 :         key = make_tdb_data((const void*)&op->guid, sizeof(op->guid));
    1191      333437 :         status = dbwrap_parse_record(t->changes.map, key,
    1192             :                                      descriptor_changes_parser, &c);
    1193      333437 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    1194      296780 :                 c = NULL;
    1195      296780 :                 status = NT_STATUS_OK;
    1196             :         }
    1197      333437 :         if (!NT_STATUS_IS_OK(status)) {
    1198           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1199             :                           "dbwrap_parse_record() - %s\n",
    1200             :                           nt_errstr(status));
    1201           0 :                 return ldb_module_operr(module);
    1202             :         }
    1203             : 
    1204      333437 :         if (c == NULL) {
    1205             :                 /*
    1206             :                  * Create a new structure if we
    1207             :                  * don't know about the object yet.
    1208             :                  */
    1209             : 
    1210      296780 :                 c = talloc_zero(t->mem, struct descriptor_changes);
    1211      296780 :                 if (c == NULL) {
    1212           0 :                         return ldb_module_oom(module);
    1213             :                 }
    1214      296780 :                 c->nc_root = ldb_dn_copy(c, op->nc_root);
    1215      296780 :                 if (c->nc_root == NULL) {
    1216           0 :                         return ldb_module_oom(module);
    1217             :                 }
    1218      296780 :                 c->guid = op->guid;
    1219             :         }
    1220             : 
    1221      333437 :         if (ldb_dn_compare(c->nc_root, op->nc_root) != 0) {
    1222             :                 /*
    1223             :                  * This is an unexpected situation,
    1224             :                  * we don't expect the nc root to change
    1225             :                  * during a replication cycle.
    1226             :                  */
    1227           0 :                 DBG_ERR("ERROR: Object %s nc_root changed %s => %s\n",
    1228             :                         GUID_string(c, &c->guid),
    1229             :                         ldb_dn_get_extended_linearized(c, c->nc_root, 1),
    1230             :                         ldb_dn_get_extended_linearized(c, op->nc_root, 1));
    1231           0 :                 return ldb_module_operr(module);
    1232             :         }
    1233             : 
    1234      333437 :         c->ref_count += 1;
    1235             : 
    1236             :         /*
    1237             :          * always use the last known parent_guid.
    1238             :          */
    1239      333437 :         c->parent_guid = op->parent_guid;
    1240             : 
    1241             :         /*
    1242             :          * Note that we only set, but don't clear values here,
    1243             :          * it means c->force_self and c->force_children can
    1244             :          * both be true in the end.
    1245             :          */
    1246      333437 :         if (op->include_self) {
    1247      268642 :                 c->force_self = true;
    1248             :         } else {
    1249       64795 :                 c->force_children = true;
    1250             :         }
    1251             : 
    1252      333437 :         if (c->ref_count == 1) {
    1253      296780 :                 struct TDB_DATA val = make_tdb_data((const void*)&c, sizeof(c));
    1254             : 
    1255             :                 /*
    1256             :                  * Remember the change by objectGUID in order
    1257             :                  * to avoid processing it more than once.
    1258             :                  */
    1259             : 
    1260      296780 :                 status = dbwrap_store(t->changes.map, key, val, TDB_INSERT);
    1261      296780 :                 if (!NT_STATUS_IS_OK(status)) {
    1262           0 :                         ldb_debug(ldb, LDB_DEBUG_FATAL,
    1263             :                                   "dbwrap_parse_record() - %s\n",
    1264             :                                   nt_errstr(status));
    1265           0 :                         return ldb_module_operr(module);
    1266             :                 }
    1267             : 
    1268      296780 :                 DLIST_ADD_END(t->changes.list, c);
    1269      296780 :                 t->changes.num_registered += 1;
    1270             :         }
    1271      333437 :         t->changes.num_registrations += 1;
    1272             : 
    1273      333437 :         return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
    1274             : }
    1275             : 
    1276     1226402 : static int descriptor_extended(struct ldb_module *module, struct ldb_request *req)
    1277             : {
    1278     1226402 :         if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SEC_DESC_PROPAGATION_OID) == 0) {
    1279      333437 :                 return descriptor_extended_sec_desc_propagation(module, req);
    1280             :         }
    1281             : 
    1282      892965 :         return ldb_next_request(module, req);
    1283             : }
    1284             : 
    1285      108013 : static int descriptor_init(struct ldb_module *module)
    1286             : {
    1287      108013 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1288             :         int ret;
    1289             :         struct descriptor_data *descriptor_private;
    1290             : 
    1291      108013 :         ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
    1292      108013 :         if (ret != LDB_SUCCESS) {
    1293           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR,
    1294             :                         "descriptor: Unable to register control with rootdse!\n");
    1295           0 :                 return ldb_operr(ldb);
    1296             :         }
    1297             : 
    1298      108013 :         descriptor_private = talloc_zero(module, struct descriptor_data);
    1299      108013 :         if (descriptor_private == NULL) {
    1300           0 :                 ldb_oom(ldb);
    1301           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    1302             :         }
    1303      108013 :         ldb_module_set_private(module, descriptor_private);
    1304             : 
    1305      108013 :         return ldb_next_init(module);
    1306             : }
    1307             : 
    1308      768658 : static int descriptor_sd_propagation_object(struct ldb_module *module,
    1309             :                                             struct ldb_message *msg,
    1310             :                                             bool *stop)
    1311             : {
    1312      648536 :         struct descriptor_data *descriptor_private =
    1313      768658 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1314             :                 struct descriptor_data);
    1315      768658 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1316      768658 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1317             :         struct ldb_request *sub_req;
    1318             :         struct ldb_result *mod_res;
    1319             :         struct ldb_control *sd_propagation_control;
    1320             :         struct GUID guid;
    1321             :         int ret;
    1322             :         TDB_DATA key;
    1323      768658 :         TDB_DATA empty_val = { .dsize = 0, };
    1324             :         NTSTATUS status;
    1325      768658 :         struct descriptor_changes *c = NULL;
    1326             : 
    1327      768658 :         *stop = false;
    1328             : 
    1329             :         /*
    1330             :          * We get the GUID of the object
    1331             :          * in order to have the cache key
    1332             :          * for the object.
    1333             :          */
    1334             : 
    1335      768658 :         status = dsdb_get_extended_dn_guid(msg->dn, &guid, "GUID");
    1336      768658 :         if (!NT_STATUS_IS_OK(status)) {
    1337           0 :                 return ldb_operr(ldb);
    1338             :         }
    1339      768658 :         key = make_tdb_data((const void*)&guid, sizeof(guid));
    1340             : 
    1341             :         /*
    1342             :          * Check if we already processed this object.
    1343             :          */
    1344      768658 :         status = dbwrap_parse_record(t->objects.map, key,
    1345             :                                      descriptor_object_parser, NULL);
    1346      768658 :         if (NT_STATUS_IS_OK(status)) {
    1347             :                 /*
    1348             :                  * All work is already one
    1349             :                  */
    1350      116047 :                 t->objects.num_skipped += 1;
    1351      116047 :                 *stop = true;
    1352      116047 :                 return LDB_SUCCESS;
    1353             :         }
    1354      652611 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    1355           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1356             :                           "dbwrap_parse_record() - %s\n",
    1357             :                           nt_errstr(status));
    1358           0 :                 return ldb_module_operr(module);
    1359             :         }
    1360             : 
    1361      652611 :         t->objects.num_processed += 1;
    1362             : 
    1363             :         /*
    1364             :          * Remember that we're processing this object.
    1365             :          */
    1366      652611 :         status = dbwrap_store(t->objects.map, key, empty_val, TDB_INSERT);
    1367      652611 :         if (!NT_STATUS_IS_OK(status)) {
    1368           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1369             :                           "dbwrap_parse_record() - %s\n",
    1370             :                           nt_errstr(status));
    1371           0 :                 return ldb_module_operr(module);
    1372             :         }
    1373             : 
    1374             :         /*
    1375             :          * Check that if there's a descriptor_change in our list,
    1376             :          * which we may be able to remove from the pending list
    1377             :          * when we processed the object.
    1378             :          */
    1379             : 
    1380      652611 :         status = dbwrap_parse_record(t->changes.map, key, descriptor_changes_parser, &c);
    1381      652611 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    1382      375916 :                 c = NULL;
    1383      375916 :                 status = NT_STATUS_OK;
    1384             :         }
    1385      652611 :         if (!NT_STATUS_IS_OK(status)) {
    1386           0 :                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1387             :                           "dbwrap_parse_record() - %s\n",
    1388             :                           nt_errstr(status));
    1389           0 :                 return ldb_module_operr(module);
    1390             :         }
    1391             : 
    1392      652611 :         mod_res = talloc_zero(msg, struct ldb_result);
    1393      652611 :         if (mod_res == NULL) {
    1394           0 :                 return ldb_module_oom(module);
    1395             :         }
    1396             : 
    1397      652611 :         ret = ldb_build_mod_req(&sub_req, ldb, mod_res,
    1398             :                                 msg,
    1399             :                                 NULL,
    1400             :                                 mod_res,
    1401             :                                 ldb_modify_default_callback,
    1402             :                                 NULL);
    1403      652611 :         LDB_REQ_SET_LOCATION(sub_req);
    1404      652611 :         if (ret != LDB_SUCCESS) {
    1405           0 :                 return ldb_module_operr(module);
    1406             :         }
    1407             : 
    1408      652611 :         ldb_req_mark_trusted(sub_req);
    1409             : 
    1410      652611 :         ret = ldb_request_add_control(sub_req,
    1411             :                                       DSDB_CONTROL_SEC_DESC_PROPAGATION_OID,
    1412             :                                       true, module);
    1413      652611 :         if (ret != LDB_SUCCESS) {
    1414           0 :                 return ldb_module_operr(module);
    1415             :         }
    1416             : 
    1417      652611 :         sd_propagation_control = ldb_request_get_control(sub_req,
    1418             :                                         DSDB_CONTROL_SEC_DESC_PROPAGATION_OID);
    1419      652611 :         if (sd_propagation_control == NULL) {
    1420           0 :                 return ldb_module_operr(module);
    1421             :         }
    1422             : 
    1423      652611 :         ret = dsdb_request_add_controls(sub_req,
    1424             :                                         DSDB_FLAG_AS_SYSTEM |
    1425             :                                         DSDB_SEARCH_SHOW_RECYCLED);
    1426      652611 :         if (ret != LDB_SUCCESS) {
    1427           0 :                 return ldb_module_operr(module);
    1428             :         }
    1429             : 
    1430      652611 :         ret = descriptor_modify(module, sub_req);
    1431      652611 :         if (ret == LDB_SUCCESS) {
    1432      652611 :                 ret = ldb_wait(sub_req->handle, LDB_WAIT_ALL);
    1433             :         }
    1434      652611 :         if (ret != LDB_SUCCESS) {
    1435           0 :                 ldb_asprintf_errstring(ldb_module_get_ctx(module),
    1436             :                                        "descriptor_modify on %s failed: %s",
    1437             :                                        ldb_dn_get_linearized(msg->dn),
    1438             :                                        ldb_errstring(ldb_module_get_ctx(module)));
    1439           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    1440             :         }
    1441             : 
    1442      652611 :         if (sd_propagation_control->critical != 0) {
    1443      529594 :                 if (c == NULL) {
    1444             :                         /*
    1445             :                          * If we don't have a
    1446             :                          * descriptor_changes structure
    1447             :                          * we're done.
    1448             :                          */
    1449      259312 :                         *stop = true;
    1450      270282 :                 } else if (!c->force_children) {
    1451             :                         /*
    1452             :                          * If we don't need to
    1453             :                          * propagate to children,
    1454             :                          * we're done.
    1455             :                          */
    1456      225114 :                         *stop = true;
    1457             :                 }
    1458             :         }
    1459             : 
    1460      652611 :         if (c != NULL && !c->force_children) {
    1461             :                 /*
    1462             :                  * Remove the pending change,
    1463             :                  * we already done all required work,
    1464             :                  * there's no need to do it again.
    1465             :                  *
    1466             :                  * Note DLIST_REMOVE() is a noop
    1467             :                  * if the element is not part of
    1468             :                  * the list.
    1469             :                  */
    1470      231527 :                 DLIST_REMOVE(t->changes.list, c);
    1471             :         }
    1472             : 
    1473      652611 :         talloc_free(mod_res);
    1474             : 
    1475      652611 :         return LDB_SUCCESS;
    1476             : }
    1477             : 
    1478     4338093 : static int descriptor_sd_propagation_msg_sort(struct ldb_message **m1,
    1479             :                                               struct ldb_message **m2)
    1480             : {
    1481     4338093 :         struct ldb_dn *dn1 = (*m1)->dn;
    1482     4338093 :         struct ldb_dn *dn2 = (*m2)->dn;
    1483             : 
    1484             :         /*
    1485             :          * This sorts in tree order, parents first
    1486             :          */
    1487     4338093 :         return ldb_dn_compare(dn2, dn1);
    1488             : }
    1489             : 
    1490      288724 : static int descriptor_sd_propagation_recursive(struct ldb_module *module,
    1491             :                                                struct descriptor_changes *change)
    1492             : {
    1493      275371 :         struct descriptor_data *descriptor_private =
    1494      288724 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1495             :                 struct descriptor_data);
    1496      288724 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1497      288724 :         struct ldb_result *guid_res = NULL;
    1498      288724 :         struct ldb_result *res = NULL;
    1499             :         unsigned int i;
    1500      288724 :         const char * const no_attrs[] = { "@__NONE__", NULL };
    1501      288724 :         struct ldb_dn *stopped_dn = NULL;
    1502             :         struct GUID_txt_buf guid_buf;
    1503             :         int ret;
    1504      288724 :         bool stop = false;
    1505             : 
    1506      288724 :         t->changes.num_processed += 1;
    1507             : 
    1508             :         /*
    1509             :          * First confirm this object has children, or exists
    1510             :          * (depending on change->force_self)
    1511             :          * 
    1512             :          * LDB_SCOPE_SUBTREE searches are expensive.
    1513             :          *
    1514             :          * We know this is safe against a rename race as we are in the
    1515             :          * prepare_commit(), so must be in a transaction.
    1516             :          */
    1517             : 
    1518             :         /* Find the DN by GUID, as this is stable under rename */
    1519      288724 :         ret = dsdb_module_search(module,
    1520             :                                  change,
    1521             :                                  &guid_res,
    1522             :                                  change->nc_root,
    1523             :                                  LDB_SCOPE_SUBTREE,
    1524             :                                  no_attrs,
    1525             :                                  DSDB_FLAG_NEXT_MODULE |
    1526             :                                  DSDB_FLAG_AS_SYSTEM |
    1527             :                                  DSDB_SEARCH_SHOW_DELETED |
    1528             :                                  DSDB_SEARCH_SHOW_RECYCLED |
    1529             :                                  DSDB_SEARCH_SHOW_EXTENDED_DN,
    1530             :                                  NULL, /* parent_req */
    1531             :                                  "(objectGUID=%s)",
    1532      288724 :                                  GUID_buf_string(&change->guid,
    1533             :                                                  &guid_buf));
    1534             : 
    1535      288724 :         if (ret != LDB_SUCCESS) {
    1536           0 :                 return ret;
    1537             :         }
    1538             : 
    1539      288724 :         if (guid_res->count != 1) {
    1540             :                 /*
    1541             :                  * We were just given this GUID during the same
    1542             :                  * transaction, if it is missing this is a big
    1543             :                  * problem.
    1544             :                  *
    1545             :                  * Cleanup of tombstones does not trigger this module
    1546             :                  * as it just does a delete.
    1547             :                  */
    1548           0 :                 ldb_asprintf_errstring(ldb_module_get_ctx(module),
    1549             :                                        "failed to find GUID %s under %s "
    1550             :                                        "for transaction-end SD inheritance: %d results",
    1551           0 :                                        GUID_buf_string(&change->guid,
    1552             :                                                        &guid_buf),
    1553             :                                        ldb_dn_get_linearized(change->nc_root),
    1554           0 :                                        guid_res->count);
    1555           0 :                 return LDB_ERR_OPERATIONS_ERROR;
    1556             :         }
    1557             : 
    1558             :         /*
    1559             :          * OK, so there was a parent, are there children?  Note: that
    1560             :          * this time we do not search for deleted/recycled objects
    1561             :          */
    1562      288724 :         ret = dsdb_module_search(module,
    1563             :                                  change,
    1564             :                                  &res,
    1565      288724 :                                  guid_res->msgs[0]->dn,
    1566             :                                  LDB_SCOPE_ONELEVEL,
    1567             :                                  no_attrs,
    1568             :                                  DSDB_FLAG_NEXT_MODULE |
    1569             :                                  DSDB_FLAG_AS_SYSTEM,
    1570             :                                  NULL, /* parent_req */
    1571             :                                  "(objectClass=*)");
    1572      288724 :         if (ret != LDB_SUCCESS) {
    1573             :                 /*
    1574             :                  * LDB_ERR_NO_SUCH_OBJECT, say if the DN was a deleted
    1575             :                  * object, is ignored by the caller
    1576             :                  */
    1577           0 :                 return ret;
    1578             :         }
    1579             : 
    1580      288724 :         if (res->count == 0 && !change->force_self) {
    1581             :                 /* All done, no children */
    1582       20208 :                 TALLOC_FREE(res);
    1583       20208 :                 return LDB_SUCCESS;
    1584             :         }
    1585             : 
    1586             :         /*
    1587             :          * First, if we are in force_self mode (eg renamed under new
    1588             :          * parent) then apply the SD to the top object
    1589             :          */
    1590      268516 :         if (change->force_self) {
    1591      260586 :                 ret = descriptor_sd_propagation_object(module,
    1592      260586 :                                                        guid_res->msgs[0],
    1593             :                                                        &stop);
    1594      260586 :                 if (ret != LDB_SUCCESS) {
    1595           0 :                         TALLOC_FREE(guid_res);
    1596           0 :                         return ret;
    1597             :                 }
    1598             : 
    1599      260586 :                 if (stop == true && !change->force_children) {
    1600             :                         /* There was no change, nothing more to do */
    1601      217524 :                         TALLOC_FREE(guid_res);
    1602      217524 :                         return LDB_SUCCESS;
    1603             :                 }
    1604             : 
    1605       43062 :                 if (res->count == 0) {
    1606             :                         /* All done! */
    1607       41343 :                         TALLOC_FREE(guid_res);
    1608       41343 :                         return LDB_SUCCESS;
    1609             :                 }
    1610             :         }
    1611             : 
    1612             :         /*
    1613             :          * Look for children
    1614             :          *
    1615             :          * Note: that we do not search for deleted/recycled objects
    1616             :          */
    1617        9649 :         ret = dsdb_module_search(module,
    1618             :                                  change,
    1619             :                                  &res,
    1620        9649 :                                  guid_res->msgs[0]->dn,
    1621             :                                  LDB_SCOPE_SUBTREE,
    1622             :                                  no_attrs,
    1623             :                                  DSDB_FLAG_NEXT_MODULE |
    1624             :                                  DSDB_FLAG_AS_SYSTEM |
    1625             :                                  DSDB_SEARCH_SHOW_EXTENDED_DN,
    1626             :                                  NULL, /* parent_req */
    1627             :                                  "(objectClass=*)");
    1628        9649 :         if (ret != LDB_SUCCESS) {
    1629           0 :                 return ret;
    1630             :         }
    1631             : 
    1632        9649 :         TYPESAFE_QSORT(res->msgs, res->count,
    1633             :                        descriptor_sd_propagation_msg_sort);
    1634             : 
    1635             :         /* We start from 1, the top object has been done */
    1636      527279 :         for (i = 1; i < res->count; i++) {
    1637             :                 /*
    1638             :                  * ldb_dn_compare_base() does not match for NULL but
    1639             :                  * this is clearer
    1640             :                  */
    1641      517630 :                 if (stopped_dn != NULL) {
    1642      361592 :                         ret = ldb_dn_compare_base(stopped_dn,
    1643      361592 :                                                   res->msgs[i]->dn);
    1644             :                         /*
    1645             :                          * Skip further processing of this
    1646             :                          * sub-subtree
    1647             :                          */
    1648      361592 :                         if (ret == 0) {
    1649        9558 :                                 continue;
    1650             :                         }
    1651             :                 }
    1652      508072 :                 ret = descriptor_sd_propagation_object(module,
    1653      508072 :                                                        res->msgs[i],
    1654             :                                                        &stop);
    1655      508072 :                 if (ret != LDB_SUCCESS) {
    1656           0 :                         return ret;
    1657             :                 }
    1658             : 
    1659      508072 :                 if (stop) {
    1660             :                         /*
    1661             :                          * If this child didn't change, then nothing
    1662             :                          * under it needs to change
    1663             :                          *
    1664             :                          * res has been sorted into tree order so the
    1665             :                          * next few entries can be skipped
    1666             :                          */
    1667      346378 :                         stopped_dn = res->msgs[i]->dn;
    1668             :                 }
    1669             :         }
    1670             : 
    1671        9649 :         TALLOC_FREE(res);
    1672        9649 :         return LDB_SUCCESS;
    1673             : }
    1674             : 
    1675      244076 : static int descriptor_start_transaction(struct ldb_module *module)
    1676             : {
    1677      187428 :         struct descriptor_data *descriptor_private =
    1678      244076 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1679             :                 struct descriptor_data);
    1680      244076 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1681             : 
    1682      244076 :         if (t->mem != NULL) {
    1683           0 :                 return ldb_module_operr(module);
    1684             :         }
    1685             : 
    1686      244076 :         *t = (struct descriptor_transaction) { .mem = NULL, };
    1687      244076 :         t->mem = talloc_new(descriptor_private);
    1688      244076 :         if (t->mem == NULL) {
    1689           0 :                 return ldb_module_oom(module);
    1690             :         }
    1691      244076 :         t->changes.map = db_open_rbt(t->mem);
    1692      244076 :         if (t->changes.map == NULL) {
    1693           0 :                 TALLOC_FREE(t->mem);
    1694           0 :                 *t = (struct descriptor_transaction) { .mem = NULL, };
    1695           0 :                 return ldb_module_oom(module);
    1696             :         }
    1697      244076 :         t->objects.map = db_open_rbt(t->mem);
    1698      244076 :         if (t->objects.map == NULL) {
    1699           0 :                 TALLOC_FREE(t->mem);
    1700           0 :                 *t = (struct descriptor_transaction) { .mem = NULL, };
    1701           0 :                 return ldb_module_oom(module);
    1702             :         }
    1703             : 
    1704      244076 :         return ldb_next_start_trans(module);
    1705             : }
    1706             : 
    1707      212234 : static int descriptor_prepare_commit(struct ldb_module *module)
    1708             : {
    1709      167039 :         struct descriptor_data *descriptor_private =
    1710      212234 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1711             :                 struct descriptor_data);
    1712      212234 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1713      212234 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
    1714             :         struct descriptor_changes *c, *n;
    1715             :         int ret;
    1716             : 
    1717      212234 :         DBG_NOTICE("changes: num_registrations=%zu\n",
    1718             :                    t->changes.num_registrations);
    1719      212234 :         DBG_NOTICE("changes: num_registered=%zu\n",
    1720             :                    t->changes.num_registered);
    1721             : 
    1722             :         /*
    1723             :          * The security descriptor propagation
    1724             :          * needs to apply the inheritance from
    1725             :          * an object to itself and/or all it's
    1726             :          * children.
    1727             :          *
    1728             :          * In the initial replication during
    1729             :          * a join, we have every object in our
    1730             :          * list.
    1731             :          *
    1732             :          * In order to avoid useless work it's
    1733             :          * better to start with toplevel objects and
    1734             :          * move down to the leaf object from there.
    1735             :          *
    1736             :          * So if the parent_guid is also in our list,
    1737             :          * we better move the object behind its parent.
    1738             :          *
    1739             :          * It allows that the recursive processing of
    1740             :          * the parent already does the work needed
    1741             :          * for the child.
    1742             :          *
    1743             :          * If we have a list for this directory tree:
    1744             :          *
    1745             :          *  A
    1746             :          *    -> B
    1747             :          *        -> C
    1748             :          *            -> D
    1749             :          *                -> E
    1750             :          *
    1751             :          * The initial list would have the order D, E, B, A, C
    1752             :          *
    1753             :          * By still processing from the front, we ensure that,
    1754             :          * when D is found to be below C, that E follows because
    1755             :          * we keep peeling items off the front for checking and
    1756             :          * move them behind their parent.
    1757             :          *
    1758             :          * So we would go:
    1759             :          *
    1760             :          * E B A C D
    1761             :          *
    1762             :          * B A C D E
    1763             :          *
    1764             :          * A B C D E
    1765             :          */
    1766      509697 :         for (c = t->changes.list; c; c = n) {
    1767      297463 :                 struct descriptor_changes *pc = NULL;
    1768      297463 :                 n = c->next;
    1769             : 
    1770      297463 :                 if (c->sort_count >= t->changes.num_registered) {
    1771             :                         /*
    1772             :                          * This should never happen, but it's
    1773             :                          * a sanity check in order to avoid
    1774             :                          * endless loops. Just stop sorting.
    1775             :                          */
    1776           0 :                         break;
    1777             :                 }
    1778             : 
    1779             :                 /*
    1780             :                  * Check if we have the parent also in the list.
    1781             :                  */
    1782      297463 :                 if (!GUID_all_zero((const void*)&c->parent_guid)) {
    1783             :                         TDB_DATA pkey;
    1784             :                         NTSTATUS status;
    1785             : 
    1786      295973 :                         pkey = make_tdb_data((const void*)&c->parent_guid,
    1787             :                                              sizeof(c->parent_guid));
    1788             : 
    1789      295973 :                         status = dbwrap_parse_record(t->changes.map, pkey,
    1790             :                                                      descriptor_changes_parser, &pc);
    1791      295973 :                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    1792       31933 :                                 pc = NULL;
    1793       31933 :                                 status = NT_STATUS_OK;
    1794             :                         }
    1795      295973 :                         if (!NT_STATUS_IS_OK(status)) {
    1796           0 :                                 ldb_debug(ldb, LDB_DEBUG_FATAL,
    1797             :                                           "dbwrap_parse_record() - %s\n",
    1798             :                                           nt_errstr(status));
    1799           0 :                                 return ldb_module_operr(module);
    1800             :                         }
    1801             :                 }
    1802             : 
    1803      297463 :                 if (pc == NULL) {
    1804             :                         /*
    1805             :                          * There is no parent in the list
    1806             :                          */
    1807       33423 :                         t->changes.num_toplevel += 1;
    1808       33423 :                         continue;
    1809             :                 }
    1810             : 
    1811             :                 /*
    1812             :                  * Move the child after the parent
    1813             :                  *
    1814             :                  * Note that we do that multiple times
    1815             :                  * in case the parent already moved itself.
    1816             :                  *
    1817             :                  * See the comment above the loop.
    1818             :                  */
    1819      264040 :                 DLIST_REMOVE(t->changes.list, c);
    1820      264040 :                 DLIST_ADD_AFTER(t->changes.list, c, pc);
    1821             : 
    1822             :                 /*
    1823             :                  * Remember how often we moved the object
    1824             :                  * in order to avoid endless loops.
    1825             :                  */
    1826      264040 :                 c->sort_count += 1;
    1827             :         }
    1828             : 
    1829      212234 :         DBG_NOTICE("changes: num_toplevel=%zu\n", t->changes.num_toplevel);
    1830             : 
    1831      667997 :         while (t->changes.list != NULL) {
    1832      288724 :                 c = t->changes.list;
    1833             : 
    1834      288724 :                 DLIST_REMOVE(t->changes.list, c);
    1835             : 
    1836             :                 /*
    1837             :                  * Note that descriptor_sd_propagation_recursive()
    1838             :                  * may also remove other elements of the list,
    1839             :                  * so we can't use a next pointer
    1840             :                  */
    1841      288724 :                 ret = descriptor_sd_propagation_recursive(module, c);
    1842      288724 :                 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    1843           0 :                         continue;
    1844             :                 }
    1845      288724 :                 if (ret != LDB_SUCCESS) {
    1846           0 :                         return ret;
    1847             :                 }
    1848             :         }
    1849             : 
    1850      212234 :         DBG_NOTICE("changes: num_processed=%zu\n", t->changes.num_processed);
    1851      212234 :         DBG_NOTICE("objects: num_processed=%zu\n", t->objects.num_processed);
    1852      212234 :         DBG_NOTICE("objects: num_skipped=%zu\n", t->objects.num_skipped);
    1853             : 
    1854      212234 :         return ldb_next_prepare_commit(module);
    1855             : }
    1856             : 
    1857      212231 : static int descriptor_end_transaction(struct ldb_module *module)
    1858             : {
    1859      167036 :         struct descriptor_data *descriptor_private =
    1860      212231 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1861             :                 struct descriptor_data);
    1862      212231 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1863             : 
    1864      212231 :         TALLOC_FREE(t->mem);
    1865      212231 :         *t = (struct descriptor_transaction) { .mem = NULL, };
    1866             : 
    1867      212231 :         return ldb_next_end_trans(module);
    1868             : }
    1869             : 
    1870       31844 : static int descriptor_del_transaction(struct ldb_module *module)
    1871             : {
    1872       20391 :         struct descriptor_data *descriptor_private =
    1873       31844 :                 talloc_get_type_abort(ldb_module_get_private(module),
    1874             :                 struct descriptor_data);
    1875       31844 :         struct descriptor_transaction *t = &descriptor_private->transaction;
    1876             : 
    1877       31844 :         TALLOC_FREE(t->mem);
    1878       31844 :         *t = (struct descriptor_transaction) { .mem = NULL, };
    1879             : 
    1880       31844 :         return ldb_next_del_trans(module);
    1881             : }
    1882             : 
    1883             : static const struct ldb_module_ops ldb_descriptor_module_ops = {
    1884             :         .name              = "descriptor",
    1885             :         .search            = descriptor_search,
    1886             :         .add               = descriptor_add,
    1887             :         .modify            = descriptor_modify,
    1888             :         .rename            = descriptor_rename,
    1889             :         .init_context      = descriptor_init,
    1890             :         .extended          = descriptor_extended,
    1891             :         .start_transaction = descriptor_start_transaction,
    1892             :         .prepare_commit    = descriptor_prepare_commit,
    1893             :         .end_transaction   = descriptor_end_transaction,
    1894             :         .del_transaction   = descriptor_del_transaction,
    1895             : };
    1896             : 
    1897        4310 : int ldb_descriptor_module_init(const char *version)
    1898             : {
    1899        4310 :         LDB_MODULE_CHECK_VERSION(version);
    1900        4310 :         return ldb_register_module(&ldb_descriptor_module_ops);
    1901             : }

Generated by: LCOV version 1.13