LCOV - code coverage report
Current view: top level - source4/dsdb/samdb/ldb_modules - samba_dsdb.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 216 269 80.3 %
Date: 2024-05-31 13:13:24 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             :    Samba4 module loading module
       3             : 
       4             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : /*
      21             :  *  Name: ldb
      22             :  *
      23             :  *  Component: Samba4 module loading module
      24             :  *
      25             :  *  Description: Implement a single 'module' in the ldb database,
      26             :  *  which loads the remaining modules based on 'choice of configuration' attributes
      27             :  *
      28             :  *  This is to avoid forcing a reprovision of the ldb databases when we change the internal structure of the code
      29             :  *
      30             :  *  Author: Andrew Bartlett
      31             :  */
      32             : 
      33             : #include "includes.h"
      34             : #include <ldb.h>
      35             : #include <ldb_errors.h>
      36             : #include <ldb_module.h>
      37             : #include "dsdb/samdb/ldb_modules/util.h"
      38             : #include "dsdb/samdb/samdb.h"
      39             : #include "librpc/ndr/libndr.h"
      40             : #include "auth/credentials/credentials.h"
      41             : #include "param/secrets.h"
      42             : #include "lib/ldb-samba/ldb_wrap.h"
      43             : 
      44      181595 : static int read_at_rootdse_record(struct ldb_context *ldb, struct ldb_module *module, TALLOC_CTX *mem_ctx,
      45             :                                   struct ldb_message **msg, struct ldb_request *parent)
      46             : {
      47        6078 :         int ret;
      48        6078 :         static const char *rootdse_attrs[] = { "defaultNamingContext", "configurationNamingContext", "schemaNamingContext", NULL };
      49        6078 :         struct ldb_result *rootdse_res;
      50        6078 :         struct ldb_dn *rootdse_dn;
      51      181595 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
      52      181595 :         if (!tmp_ctx) {
      53           0 :                 return ldb_oom(ldb);
      54             :         }
      55             : 
      56      181595 :         rootdse_dn = ldb_dn_new(tmp_ctx, ldb, "@ROOTDSE");
      57      181595 :         if (!rootdse_dn) {
      58           0 :                 talloc_free(tmp_ctx);
      59           0 :                 return ldb_oom(ldb);
      60             :         }
      61             : 
      62      181595 :         ret = dsdb_module_search_dn(module, tmp_ctx, &rootdse_res, rootdse_dn,
      63             :                                     rootdse_attrs, DSDB_FLAG_NEXT_MODULE, parent);
      64      181595 :         if (ret != LDB_SUCCESS) {
      65           6 :                 talloc_free(tmp_ctx);
      66           6 :                 return ret;
      67             :         }
      68             : 
      69      181589 :         talloc_steal(mem_ctx, rootdse_res->msgs);
      70      181589 :         *msg = rootdse_res->msgs[0];
      71             : 
      72      181589 :         talloc_free(tmp_ctx);
      73             : 
      74      181589 :         return ret;
      75             : }
      76             : 
      77      363178 : static int prepare_modules_line(struct ldb_context *ldb,
      78             :                                 TALLOC_CTX *mem_ctx,
      79             :                                 const struct ldb_message *rootdse_msg,
      80             :                                 struct ldb_message *msg, const char *backend_attr,
      81             :                                 const char *backend_mod, const char **backend_mod_list)
      82             : {
      83       12156 :         int ret;
      84       12156 :         const char **backend_full_list;
      85       12156 :         const char *backend_dn;
      86       12156 :         char *mod_list_string;
      87       12156 :         char *full_string;
      88      363178 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
      89      363178 :         if (!tmp_ctx) {
      90           0 :                 return ldb_oom(ldb);
      91             :         }
      92             : 
      93      363178 :         if (backend_attr) {
      94      181589 :                 backend_dn = ldb_msg_find_attr_as_string(rootdse_msg, backend_attr, NULL);
      95      181589 :                 if (!backend_dn) {
      96           0 :                         ldb_asprintf_errstring(ldb,
      97             :                                                "samba_dsdb_init: "
      98             :                                                "unable to read %s from %s:%s",
      99           0 :                                                backend_attr, ldb_dn_get_linearized(rootdse_msg->dn),
     100             :                                                ldb_errstring(ldb));
     101           0 :                         return LDB_ERR_CONSTRAINT_VIOLATION;
     102             :                 }
     103             :         } else {
     104      175511 :                 backend_dn = "*";
     105             :         }
     106             : 
     107      363178 :         if (backend_mod) {
     108      181589 :                 char **b = str_list_make_single(tmp_ctx, backend_mod);
     109      181589 :                 backend_full_list = discard_const_p(const char *, b);
     110             :         } else {
     111      181589 :                 char **b = str_list_make_empty(tmp_ctx);
     112      181589 :                 backend_full_list = discard_const_p(const char *, b);
     113             :         }
     114      363178 :         if (!backend_full_list) {
     115           0 :                 talloc_free(tmp_ctx);
     116           0 :                 return ldb_oom(ldb);
     117             :         }
     118             : 
     119      363178 :         backend_full_list = str_list_append_const(backend_full_list, backend_mod_list);
     120      363178 :         if (!backend_full_list) {
     121           0 :                 talloc_free(tmp_ctx);
     122           0 :                 return ldb_oom(ldb);
     123             :         }
     124             : 
     125      363178 :         mod_list_string = str_list_join(tmp_ctx, backend_full_list, ',');
     126             : 
     127             :         /* str_list_append allocates on NULL */
     128      363178 :         talloc_free(backend_full_list);
     129             : 
     130      363178 :         if (!mod_list_string) {
     131           0 :                 talloc_free(tmp_ctx);
     132           0 :                 return ldb_oom(ldb);
     133             :         }
     134             : 
     135      363178 :         full_string = talloc_asprintf(tmp_ctx, "%s:%s", backend_dn, mod_list_string);
     136      363178 :         ret = ldb_msg_add_steal_string(msg, "modules", full_string);
     137      363178 :         talloc_free(tmp_ctx);
     138      363178 :         return ret;
     139             : }
     140             : 
     141      181590 : static bool check_required_features(struct ldb_message_element *el)
     142             : {
     143      181590 :         if (el != NULL) {
     144        6000 :                 int k;
     145      167132 :                 DATA_BLOB esf = data_blob_string_const(
     146             :                         SAMBA_ENCRYPTED_SECRETS_FEATURE);
     147      167132 :                 DATA_BLOB lmdbl1 = data_blob_string_const(
     148             :                         SAMBA_LMDB_LEVEL_ONE_FEATURE);
     149      434500 :                 for (k = 0; k < el->num_values; k++) {
     150      355606 :                         if ((data_blob_cmp(&esf, &el->values[k]) != 0) &&
     151       94237 :                             (data_blob_cmp(&lmdbl1, &el->values[k]) != 0)) {
     152           1 :                                 return false;
     153             :                         }
     154             :                 }
     155             :         }
     156      175511 :         return true;
     157             : }
     158             : 
     159      181596 : static int samba_dsdb_init(struct ldb_module *module)
     160             : {
     161      181596 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     162        6079 :         int ret, lock_ret, len, i, j;
     163      181596 :         TALLOC_CTX *tmp_ctx = talloc_new(module);
     164        6079 :         struct ldb_result *res;
     165      181596 :         struct ldb_message *rootdse_msg = NULL, *partition_msg;
     166        6079 :         struct ldb_dn *samba_dsdb_dn, *partition_dn, *indexlist_dn;
     167        6079 :         struct ldb_module *backend_module, *module_chain;
     168        6079 :         const char **final_module_list, **reverse_module_list;
     169             :         /*
     170             :           Add modules to the list to activate them by default
     171             :           beware often order is important
     172             : 
     173             :           Some Known ordering constraints:
     174             :           - rootdse must be first, as it makes redirects from "" -> cn=rootdse
     175             :           - extended_dn_in must be before objectclass.c, as it resolves the DN
     176             :           - objectclass must be before password_hash and samldb since these LDB
     177             :             modules require the expanded "objectClass" list
     178             :           - objectclass must be before descriptor and acl, as both assume that
     179             :             objectClass values are sorted
     180             :           - objectclass_attrs must be behind operational in order to see all
     181             :             attributes (the operational module protects and therefore
     182             :             suppresses per default some important ones)
     183             :           - partition must be last
     184             :           - each partition has its own module list then
     185             : 
     186             :           The list is presented here as a set of declarations to show the
     187             :           stack visually - the code below then handles the creation of the list
     188             :           based on the parameters loaded from the database.
     189             :         */
     190        6079 :         static const char *modules_list1[] = {"resolve_oids",
     191             :                                              "rootdse",
     192             :                                              "dsdb_notification",
     193             :                                              "schema_load",
     194             :                                              "lazy_commit",
     195             :                                              "dirsync",
     196             :                                              "dsdb_paged_results",
     197             :                                              "vlv",
     198             :                                              "ranged_results",
     199             :                                              "anr",
     200             :                                              "server_sort",
     201             :                                              "asq",
     202             :                                              "extended_dn_store",
     203             :                                              NULL };
     204             :         /* extended_dn_in or extended_dn_in_openldap goes here */
     205        6079 :         static const char *modules_list1a[] = {"audit_log",
     206             :                                              "objectclass",
     207             :                                              "tombstone_reanimate",
     208             :                                              "descriptor",
     209             :                                              "acl",
     210             :                                              "aclread",
     211             :                                              "samldb",
     212             :                                              "password_hash",
     213             :                                              "instancetype",
     214             :                                              "objectclass_attrs",
     215             :                                              NULL };
     216             : 
     217        6079 :         const char **link_modules;
     218        6079 :         static const char *tdb_modules_list[] = {
     219             :                 "rdn_name",
     220             :                 "subtree_delete",
     221             :                 "repl_meta_data",
     222             :                 "group_audit_log",
     223             :                 "encrypted_secrets",
     224             :                 "operational",
     225             :                 "unique_object_sids",
     226             :                 "subtree_rename",
     227             :                 "linked_attributes",
     228             :                 NULL};
     229             : 
     230        6079 :         const char *extended_dn_module;
     231      181596 :         const char *extended_dn_module_ldb = "extended_dn_out_ldb";
     232      181596 :         const char *extended_dn_in_module = "extended_dn_in";
     233             : 
     234        6079 :         static const char *modules_list2[] = {"dns_notify",
     235             :                                               "show_deleted",
     236             :                                               "new_partition",
     237             :                                               "partition",
     238             :                                               NULL };
     239             : 
     240        6079 :         const char **backend_modules;
     241        6079 :         static const char *samba_dsdb_attrs[] = { SAMBA_COMPATIBLE_FEATURES_ATTR,
     242             :                                                   SAMBA_REQUIRED_FEATURES_ATTR, NULL };
     243        6079 :         static const char *indexlist_attrs[] = { SAMBA_FEATURES_SUPPORTED_FLAG, NULL };
     244             : 
     245      181596 :         const char *current_supportedFeatures[] = {SAMBA_SORTED_LINKS_FEATURE};
     246             : 
     247      181596 :         if (!tmp_ctx) {
     248           0 :                 return ldb_oom(ldb);
     249             :         }
     250             : 
     251      181596 :         ret = ldb_register_samba_handlers(ldb);
     252      181596 :         if (ret != LDB_SUCCESS) {
     253           0 :                 talloc_free(tmp_ctx);
     254           0 :                 return ret;
     255             :         }
     256             : 
     257      181596 :         samba_dsdb_dn = ldb_dn_new(tmp_ctx, ldb, "@SAMBA_DSDB");
     258      181596 :         if (!samba_dsdb_dn) {
     259           0 :                 talloc_free(tmp_ctx);
     260           0 :                 return ldb_oom(ldb);
     261             :         }
     262             : 
     263      181596 :         indexlist_dn = ldb_dn_new(tmp_ctx, ldb, "@INDEXLIST");
     264      181596 :         if (!samba_dsdb_dn) {
     265           0 :                 talloc_free(tmp_ctx);
     266           0 :                 return ldb_oom(ldb);
     267             :         }
     268             : 
     269      181596 :         partition_dn = ldb_dn_new(tmp_ctx, ldb, DSDB_PARTITION_DN);
     270      181596 :         if (!partition_dn) {
     271           0 :                 talloc_free(tmp_ctx);
     272           0 :                 return ldb_oom(ldb);
     273             :         }
     274             : 
     275             : #define CHECK_LDB_RET(check_ret)                                \
     276             :         do {                                                    \
     277             :                 if (check_ret != LDB_SUCCESS) {                 \
     278             :                         talloc_free(tmp_ctx);                   \
     279             :                         return check_ret;                       \
     280             :                 }                                               \
     281             :         } while (0)
     282             : 
     283      181596 :         ret = dsdb_module_search_dn(module, tmp_ctx, &res, samba_dsdb_dn,
     284             :                                     samba_dsdb_attrs, DSDB_FLAG_NEXT_MODULE, NULL);
     285      181596 :         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     286             :                 /* do nothing, a very old db being upgraded */
     287      181590 :         } else if (ret == LDB_SUCCESS) {
     288        6079 :                 struct ldb_message_element *requiredFeatures;
     289        6079 :                 struct ldb_message_element *old_compatibleFeatures;
     290             : 
     291      181590 :                 requiredFeatures = ldb_msg_find_element(res->msgs[0], SAMBA_REQUIRED_FEATURES_ATTR);
     292      181590 :                 if (!check_required_features(requiredFeatures)) {
     293           1 :                         ldb_set_errstring(
     294             :                                 ldb,
     295             :                                 "This Samba database was created with "
     296             :                                 "a newer Samba version and is marked "
     297             :                                 "with extra requiredFeatures in "
     298             :                                 "@SAMBA_DSDB. This database can not "
     299             :                                 "safely be read by this Samba version");
     300           1 :                         return LDB_ERR_OPERATIONS_ERROR;
     301             :                 }
     302             : 
     303      181589 :                 old_compatibleFeatures = ldb_msg_find_element(res->msgs[0],
     304             :                                                               SAMBA_COMPATIBLE_FEATURES_ATTR);
     305             : 
     306      181589 :                 if (old_compatibleFeatures) {
     307        5999 :                         struct ldb_message *features_msg;
     308        5999 :                         struct ldb_message_element *features_el;
     309      181281 :                         int samba_options_supported = 0;
     310      181281 :                         ret = dsdb_module_search_dn(module, tmp_ctx, &res,
     311             :                                                     indexlist_dn,
     312             :                                                     indexlist_attrs,
     313             :                                                     DSDB_FLAG_NEXT_MODULE, NULL);
     314      181281 :                         if (ret == LDB_SUCCESS) {
     315        5976 :                                 samba_options_supported
     316      181076 :                                         = ldb_msg_find_attr_as_int(res->msgs[0],
     317             :                                                                    SAMBA_FEATURES_SUPPORTED_FLAG,
     318             :                                                                    0);
     319             : 
     320         205 :                         } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     321             :                                 /*
     322             :                                  * If we don't have @INDEXLIST yet, then we
     323             :                                  * are so early in set-up that we know this is
     324             :                                  * a blank DB, so no need to wripe out old
     325             :                                  * features
     326             :                                  */
     327         205 :                                 samba_options_supported = 1;
     328             :                         }
     329             : 
     330      181281 :                         features_msg = ldb_msg_new(res);
     331      181281 :                         if (features_msg == NULL) {
     332           0 :                                 return ldb_module_operr(module);
     333             :                         }
     334      181281 :                         features_msg->dn = samba_dsdb_dn;
     335             : 
     336      181281 :                         ret = ldb_msg_add_empty(features_msg, SAMBA_COMPATIBLE_FEATURES_ATTR,
     337             :                                                 LDB_FLAG_MOD_DELETE, &features_el);
     338      181281 :                         if (ret != LDB_SUCCESS) {
     339           0 :                                 return ret;
     340             :                         }
     341             : 
     342      181281 :                         if (samba_options_supported == 1) {
     343      175282 :                                 for (i = 0;
     344      362563 :                                      old_compatibleFeatures && i < old_compatibleFeatures->num_values;
     345      181282 :                                      i++) {
     346      175282 :                                         for (j = 0;
     347      181283 :                                              j < ARRAY_SIZE(current_supportedFeatures); j++) {
     348      181282 :                                                 if (strcmp((char *)old_compatibleFeatures->values[i].data,
     349             :                                                            current_supportedFeatures[j]) == 0) {
     350      175282 :                                                         break;
     351             :                                                 }
     352             :                                         }
     353      181282 :                                         if (j == ARRAY_SIZE(current_supportedFeatures)) {
     354             :                                                 /*
     355             :                                                  * Add to list of features to remove
     356             :                                                  * (rather than all features)
     357             :                                                  */
     358           2 :                                                 ret = ldb_msg_add_value(features_msg, SAMBA_COMPATIBLE_FEATURES_ATTR,
     359           1 :                                                                         &old_compatibleFeatures->values[i],
     360             :                                                                         NULL);
     361           1 :                                                 if (ret != LDB_SUCCESS) {
     362           0 :                                                         return ret;
     363             :                                                 }
     364             :                                         }
     365             :                                 }
     366             : 
     367      181281 :                                 if (features_el->num_values > 0) {
     368             :                                         /* Delete by list */
     369           1 :                                         ret = ldb_next_start_trans(module);
     370           1 :                                         if (ret != LDB_SUCCESS) {
     371           0 :                                                 return ret;
     372             :                                         }
     373           1 :                                         ret = dsdb_module_modify(module, features_msg, DSDB_FLAG_NEXT_MODULE, NULL);
     374           1 :                                         if (ret != LDB_SUCCESS) {
     375           0 :                                                 ldb_next_del_trans(module);
     376           0 :                                                 return ret;
     377             :                                         }
     378           1 :                                         ret = ldb_next_end_trans(module);
     379           1 :                                         if (ret != LDB_SUCCESS) {
     380           0 :                                                 return ret;
     381             :                                         }
     382             :                                 }
     383             :                         } else {
     384             :                                 /* Delete all */
     385           0 :                                 ret = ldb_next_start_trans(module);
     386           0 :                                 if (ret != LDB_SUCCESS) {
     387           0 :                                         return ret;
     388             :                                 }
     389           0 :                                 ret = dsdb_module_modify(module, features_msg, DSDB_FLAG_NEXT_MODULE, NULL);
     390           0 :                                 if (ret != LDB_SUCCESS) {
     391           0 :                                         ldb_next_del_trans(module);
     392           0 :                                         return ret;
     393             :                                 }
     394           0 :                                 ret = ldb_next_end_trans(module);
     395           0 :                                 if (ret != LDB_SUCCESS) {
     396           0 :                                         return ret;
     397             :                                 }
     398             :                         }
     399             :                 }
     400             : 
     401             :         } else {
     402           0 :                 talloc_free(tmp_ctx);
     403           0 :                 return ret;
     404             :         }
     405             : 
     406      181595 :         backend_modules = NULL;
     407      181595 :         extended_dn_module = extended_dn_module_ldb;
     408      181595 :         link_modules = tdb_modules_list;
     409             : 
     410             : #define CHECK_MODULE_LIST \
     411             :         do {                                                    \
     412             :                 if (!final_module_list) {                       \
     413             :                         talloc_free(tmp_ctx);                   \
     414             :                         return ldb_oom(ldb);                    \
     415             :                 }                                               \
     416             :         } while (0)
     417             : 
     418      181595 :         final_module_list = str_list_copy_const(tmp_ctx, modules_list1);
     419      181595 :         CHECK_MODULE_LIST;
     420             : 
     421      181595 :         final_module_list = str_list_add_const(final_module_list, extended_dn_in_module);
     422      181595 :         CHECK_MODULE_LIST;
     423             : 
     424      181595 :         final_module_list = str_list_append_const(final_module_list, modules_list1a);
     425      181595 :         CHECK_MODULE_LIST;
     426             : 
     427      181595 :         final_module_list = str_list_append_const(final_module_list, link_modules);
     428      181595 :         CHECK_MODULE_LIST;
     429             : 
     430      181595 :         final_module_list = str_list_add_const(final_module_list, extended_dn_module);
     431      181595 :         CHECK_MODULE_LIST;
     432             : 
     433      181595 :         final_module_list = str_list_append_const(final_module_list, modules_list2);
     434      181595 :         CHECK_MODULE_LIST;
     435             : 
     436             : 
     437      181595 :         ret = read_at_rootdse_record(ldb, module, tmp_ctx, &rootdse_msg, NULL);
     438      181595 :         CHECK_LDB_RET(ret);
     439             : 
     440      181589 :         partition_msg = ldb_msg_new(tmp_ctx);
     441      181589 :         partition_msg->dn = ldb_dn_new(partition_msg, ldb, "@" DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME);
     442             : 
     443      181589 :         ret = prepare_modules_line(ldb, tmp_ctx,
     444             :                                    rootdse_msg,
     445             :                                    partition_msg, "schemaNamingContext",
     446             :                                    "schema_data", backend_modules);
     447      181589 :         CHECK_LDB_RET(ret);
     448             : 
     449      181589 :         ret = prepare_modules_line(ldb, tmp_ctx,
     450             :                                    rootdse_msg,
     451             :                                    partition_msg, NULL,
     452             :                                    NULL, backend_modules);
     453      181589 :         CHECK_LDB_RET(ret);
     454             : 
     455             :         /* This opaque is also used by the gMSA code to confirm that it has local DB access */
     456      181589 :         ret = ldb_set_opaque(ldb, DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME, partition_msg);
     457      181589 :         CHECK_LDB_RET(ret);
     458             : 
     459      181589 :         talloc_steal(ldb, partition_msg);
     460             : 
     461             :         /* Now prepare the module chain. Oddly, we must give it to
     462             :          * ldb_module_load_list in REVERSE */
     463     7088049 :         for (len = 0; final_module_list[len]; len++) { /* noop */};
     464             : 
     465      181589 :         reverse_module_list = talloc_array(tmp_ctx, const char *, len+1);
     466      181589 :         if (!reverse_module_list) {
     467           0 :                 talloc_free(tmp_ctx);
     468           0 :                 return ldb_oom(ldb);
     469             :         }
     470     7081971 :         for (i=0; i < len; i++) {
     471     6900382 :                 reverse_module_list[i] = final_module_list[(len - 1) - i];
     472             :         }
     473      181589 :         reverse_module_list[i] = NULL;
     474             : 
     475             :         /* The backend (at least until the partitions module
     476             :          * reconfigures things) is the next module in the currently
     477             :          * loaded chain */
     478      181589 :         backend_module = ldb_module_next(module);
     479      181589 :         ret = ldb_module_load_list(ldb, reverse_module_list, backend_module, &module_chain);
     480      181589 :         CHECK_LDB_RET(ret);
     481             : 
     482      181589 :         talloc_free(tmp_ctx);
     483             :         /* Set this as the 'next' module, so that we effectively append it to
     484             :          * module chain */
     485      181589 :         ldb_module_set_next(module, module_chain);
     486             : 
     487      181589 :         ret = ldb_next_read_lock(module);
     488      181589 :         if (ret != LDB_SUCCESS) {
     489           0 :                 return ret;
     490             :         }
     491             : 
     492      181589 :         ret = ldb_next_init(module);
     493             : 
     494      181589 :         lock_ret = ldb_next_read_unlock(module);
     495             : 
     496      181589 :         if (lock_ret != LDB_SUCCESS) {
     497           0 :                 return lock_ret;
     498             :         }
     499             : 
     500      175511 :         return ret;
     501             : }
     502             : 
     503             : static const struct ldb_module_ops ldb_samba_dsdb_module_ops = {
     504             :         .name              = "samba_dsdb",
     505             :         .init_context      = samba_dsdb_init,
     506             : };
     507             : 
     508          35 : static struct ldb_message *dsdb_flags_ignore_fixup(TALLOC_CTX *mem_ctx,
     509             :                                                 const struct ldb_message *_msg)
     510             : {
     511          35 :         struct ldb_message *msg = NULL;
     512          35 :         unsigned int i;
     513             : 
     514             :         /* we have to copy the message as the caller might have it as a const */
     515          35 :         msg = ldb_msg_copy_shallow(mem_ctx, _msg);
     516          35 :         if (msg == NULL) {
     517           0 :                 return NULL;
     518             :         }
     519             : 
     520         212 :         for (i=0; i < msg->num_elements;) {
     521         177 :                 struct ldb_message_element *e = &msg->elements[i];
     522             : 
     523         177 :                 if (!(e->flags & DSDB_FLAG_INTERNAL_FORCE_META_DATA)) {
     524         165 :                         i++;
     525         165 :                         continue;
     526             :                 }
     527             : 
     528          12 :                 e->flags &= ~DSDB_FLAG_INTERNAL_FORCE_META_DATA;
     529             : 
     530          12 :                 if (e->num_values != 0) {
     531           2 :                         i++;
     532           2 :                         continue;
     533             :                 }
     534             : 
     535          10 :                 ldb_msg_remove_element(msg, e);
     536             :         }
     537             : 
     538           0 :         return msg;
     539             : }
     540             : 
     541          16 : static int dsdb_flags_ignore_add(struct ldb_module *module, struct ldb_request *req)
     542             : {
     543          16 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     544          16 :         struct ldb_request *down_req = NULL;
     545          16 :         struct ldb_message *msg = NULL;
     546          16 :         int ret;
     547             : 
     548          16 :         msg = dsdb_flags_ignore_fixup(req, req->op.add.message);
     549          16 :         if (msg == NULL) {
     550           0 :                 return ldb_module_oom(module);
     551             :         }
     552             : 
     553          16 :         ret = ldb_build_add_req(&down_req, ldb, req,
     554             :                                 msg,
     555             :                                 req->controls,
     556             :                                 req, dsdb_next_callback,
     557             :                                 req);
     558          16 :         LDB_REQ_SET_LOCATION(down_req);
     559          16 :         if (ret != LDB_SUCCESS) {
     560           0 :                 return ret;
     561             :         }
     562             : 
     563             :         /* go on with the call chain */
     564          16 :         return ldb_next_request(module, down_req);
     565             : }
     566             : 
     567          19 : static int dsdb_flags_ignore_modify(struct ldb_module *module, struct ldb_request *req)
     568             : {
     569          19 :         struct ldb_context *ldb = ldb_module_get_ctx(module);
     570          19 :         struct ldb_request *down_req = NULL;
     571          19 :         struct ldb_message *msg = NULL;
     572          19 :         int ret;
     573             : 
     574          19 :         msg = dsdb_flags_ignore_fixup(req, req->op.mod.message);
     575          19 :         if (msg == NULL) {
     576           0 :                 return ldb_module_oom(module);
     577             :         }
     578             : 
     579          19 :         ret = ldb_build_mod_req(&down_req, ldb, req,
     580             :                                 msg,
     581             :                                 req->controls,
     582             :                                 req, dsdb_next_callback,
     583             :                                 req);
     584          19 :         LDB_REQ_SET_LOCATION(down_req);
     585          19 :         if (ret != LDB_SUCCESS) {
     586           0 :                 return ret;
     587             :         }
     588             : 
     589             :         /* go on with the call chain */
     590          19 :         return ldb_next_request(module, down_req);
     591             : }
     592             : 
     593             : static const struct ldb_module_ops ldb_dsdb_flags_ignore_module_ops = {
     594             :         .name   = "dsdb_flags_ignore",
     595             :         .add    = dsdb_flags_ignore_add,
     596             :         .modify = dsdb_flags_ignore_modify,
     597             : };
     598             : 
     599        6286 : int ldb_samba_dsdb_module_init(const char *version)
     600             : {
     601         445 :         int ret;
     602        6286 :         LDB_MODULE_CHECK_VERSION(version);
     603        6286 :         ret = ldb_register_module(&ldb_samba_dsdb_module_ops);
     604        6286 :         if (ret != LDB_SUCCESS) {
     605           0 :                 return ret;
     606             :         }
     607        6286 :         ret = ldb_register_module(&ldb_dsdb_flags_ignore_module_ops);
     608        6286 :         if (ret != LDB_SUCCESS) {
     609           0 :                 return ret;
     610             :         }
     611        5841 :         return LDB_SUCCESS;
     612             : }

Generated by: LCOV version 1.14