LCOV - code coverage report
Current view: top level - source4/dsdb/samdb/ldb_modules - new_partition.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 54 74 73.0 %
Date: 2024-04-21 15:09:00 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* 
       2             :    ldb database library
       3             : 
       4             :    Copyright (C) Simo Sorce  2004-2008
       5             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
       6             :    Copyright (C) Andrew Tridgell 2005
       7             :    Copyright (C) Stefan Metzmacher <metze@samba.org> 2007
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             :    
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             :    
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : /*
      24             :  *  Name: ldb
      25             :  *
      26             :  *  Component: ldb new partition module
      27             :  *
      28             :  *  Description: Handle the add of new partitions
      29             :  *
      30             :  *  Author: Andrew Bartlett
      31             :  */
      32             : 
      33             : #include "includes.h"
      34             : #include "ldb.h"
      35             : #include "ldb_module.h"
      36             : #include "librpc/gen_ndr/ndr_misc.h"
      37             : #include "dsdb/samdb/samdb.h"
      38             : #include "../libds/common/flags.h"
      39             : #include "dsdb/common/util.h"
      40             : 
      41             : struct np_context {
      42             :         struct ldb_module *module;
      43             :         struct ldb_request *req;
      44             :         struct ldb_request *search_req;
      45             :         struct ldb_request *part_add;
      46             : };
      47             : 
      48         979 : static int np_part_mod_callback(struct ldb_request *req, struct ldb_reply *ares)
      49             : {
      50         108 :         struct ldb_context *ldb;
      51         108 :         struct np_context *ac;
      52             : 
      53         979 :         ac = talloc_get_type(req->context, struct np_context);
      54         979 :         ldb = ldb_module_get_ctx(ac->module);
      55             : 
      56         979 :         if (!ares) {
      57           0 :                 return ldb_module_done(ac->req, NULL, NULL,
      58             :                                         LDB_ERR_OPERATIONS_ERROR);
      59             :         }
      60             : 
      61             :         /* We just want to update the @PARTITIONS record if the value does not exist */
      62         979 :         if (ares->error != LDB_SUCCESS && ares->error != LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
      63           0 :                 return ldb_module_done(ac->req, ares->controls,
      64             :                                         ares->response, ares->error);
      65             :         }
      66             : 
      67         979 :         if (ares->type != LDB_REPLY_DONE) {
      68           0 :                 ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type);
      69           0 :                 return ldb_module_done(ac->req, NULL, NULL,
      70             :                                         LDB_ERR_OPERATIONS_ERROR);
      71             :         }
      72             : 
      73         979 :         ldb_reset_err_string(ldb);
      74             : 
      75             :         /* Do the original add */
      76         979 :         return ldb_next_request(ac->module, ac->req);
      77             : }
      78             : 
      79         979 : static int np_part_search_callback(struct ldb_request *req, struct ldb_reply *ares)
      80             : {
      81         108 :         struct ldb_context *ldb;
      82         108 :         struct np_context *ac;
      83         108 :         struct dsdb_create_partition_exop *ex_op;
      84         108 :         int ret;
      85             : 
      86         979 :         ac = talloc_get_type(req->context, struct np_context);
      87         979 :         ldb = ldb_module_get_ctx(ac->module);
      88             : 
      89         979 :         if (!ares) {
      90           0 :                 return ldb_module_done(ac->req, NULL, NULL,
      91             :                                         LDB_ERR_OPERATIONS_ERROR);
      92             :         }
      93             : 
      94             :         /* If this already exists, we really don't want to create a
      95             :          * partition - it would allow a duplicate entry to be
      96             :          * created */
      97         979 :         if (ares->error != LDB_ERR_NO_SUCH_OBJECT) {
      98           0 :                 if (ares->error == LDB_SUCCESS) {
      99           0 :                         return ldb_module_done(ac->req, ares->controls,
     100             :                                                ares->response, LDB_ERR_ENTRY_ALREADY_EXISTS);
     101             :                 } else {
     102           0 :                         return ldb_module_done(ac->req, ares->controls,
     103             :                                                ares->response, ares->error);
     104             :                 }
     105             :         }
     106             : 
     107         979 :         if (ares->type != LDB_REPLY_DONE) {
     108           0 :                 ldb_set_errstring(ldb, "Invalid reply type - we must not get a result here!");
     109           0 :                 return ldb_module_done(ac->req, NULL, NULL,
     110             :                                         LDB_ERR_OPERATIONS_ERROR);
     111             :         }
     112             : 
     113         979 :         ldb_reset_err_string(ldb);
     114             : 
     115             :         /* Now that we know it does not exist, we can try and create the partition */
     116         979 :         ex_op = talloc(ac, struct dsdb_create_partition_exop);
     117         979 :         if (ex_op == NULL) {
     118           0 :                 return ldb_oom(ldb);
     119             :         }
     120             :         
     121         979 :         ex_op->new_dn = ac->req->op.add.message->dn;
     122             :         
     123         979 :         ret = ldb_build_extended_req(&ac->part_add, 
     124             :                                      ldb, ac, DSDB_EXTENDED_CREATE_PARTITION_OID, ex_op, 
     125             :                                      NULL, ac, np_part_mod_callback, req);
     126             : 
     127             :         /* if the parent was asking for a partial replica, then we
     128             :          * need the extended operation to also ask for a partial
     129             :          * replica */
     130         979 :         if (ldb_request_get_control(req, DSDB_CONTROL_PARTIAL_REPLICA)) {
     131           0 :                 ret = dsdb_request_add_controls(ac->part_add, DSDB_MODIFY_PARTIAL_REPLICA);
     132           0 :                 if (ret != LDB_SUCCESS) {
     133           0 :                         return ret;
     134             :                 }
     135             :         }
     136             : 
     137             :         
     138         979 :         LDB_REQ_SET_LOCATION(ac->part_add);
     139         979 :         if (ret != LDB_SUCCESS) {
     140           0 :                 return ret;
     141             :         }
     142             :         
     143         979 :         return ldb_next_request(ac->module, ac->part_add);
     144             : }
     145             : 
     146             : /* add_record: add instancetype attribute */
     147      924119 : static int new_partition_add(struct ldb_module *module, struct ldb_request *req)
     148             : {
     149       83787 :         struct ldb_context *ldb;
     150       83787 :         struct np_context *ac;
     151       83787 :         int ret;
     152             : 
     153      924119 :         ldb = ldb_module_get_ctx(module);
     154             : 
     155      924119 :         ldb_debug(ldb, LDB_DEBUG_TRACE, "new_partition_add\n");
     156             : 
     157             :         /* do not manipulate our control entries */
     158      924119 :         if (ldb_dn_is_special(req->op.add.message->dn)) {
     159        1517 :                 return ldb_next_request(module, req);
     160             :         }
     161             : 
     162      922602 :         if (ldb_msg_find_element(req->op.add.message, "instanceType")) {
     163             :                 /* This needs to be 'static' to ensure it does not move, and is not on the stack */
     164       83611 :                 static const char *no_attrs[] = { NULL };
     165      922602 :                 uint32_t instanceType = ldb_msg_find_attr_as_uint(req->op.add.message, "instanceType", 0);
     166             : 
     167      922602 :                 if (!(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
     168      921623 :                         return ldb_next_request(module, req);
     169             :                 }
     170             : 
     171         979 :                 if (ldb_msg_find_attr_as_bool(req->op.add.message, "isDeleted", false)) {
     172           0 :                         DEBUG(0,(__location__ ": Skipping deleted partition %s\n",
     173             :                                  ldb_dn_get_linearized(req->op.add.message->dn)));
     174           0 :                         return ldb_next_request(module, req);           
     175             :                 }
     176             : 
     177             :                 /* Create an @PARTITIONS record for this partition -
     178             :                  * by asking the partitions module to do so via an
     179             :                  * extended operation, after first checking if the
     180             :                  * record already exists */
     181         979 :                 ac = talloc(req, struct np_context);
     182         979 :                 if (ac == NULL) {
     183           0 :                         return ldb_oom(ldb);
     184             :                 }
     185         979 :                 ac->module = module;
     186         979 :                 ac->req = req;
     187             :                 
     188         979 :                 ret = ldb_build_search_req(&ac->search_req, ldb, ac, req->op.add.message->dn, 
     189             :                                            LDB_SCOPE_BASE, NULL, no_attrs, req->controls, ac, 
     190             :                                            np_part_search_callback,
     191             :                                            req);
     192         979 :                 LDB_REQ_SET_LOCATION(ac->search_req);
     193         979 :                 if (ret != LDB_SUCCESS) {
     194           0 :                         return ret;
     195             :                 }
     196             :                 
     197         979 :                 return ldb_next_request(module, ac->search_req);
     198             :         }
     199             : 
     200             :         /* go on with the call chain */
     201           0 :         return ldb_next_request(module, req);
     202             : }
     203             : 
     204             : static const struct ldb_module_ops ldb_new_partition_module_ops = {
     205             :         .name          = "new_partition",
     206             :         .add           = new_partition_add,
     207             : };
     208             : 
     209        6040 : int ldb_new_partition_module_init(const char *version)
     210             : {
     211        6040 :         LDB_MODULE_CHECK_VERSION(version);
     212        6040 :         return ldb_register_module(&ldb_new_partition_module_ops);
     213             : }

Generated by: LCOV version 1.14