LCOV - code coverage report
Current view: top level - lib/ldb/modules - rdn_name.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 179 289 61.9 %
Date: 2024-04-21 15:09:00 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             :    ldb database library
       3             : 
       4             :    Copyright (C) Andrew Bartlett 2005-2009
       5             :    Copyright (C) Simo Sorce 2006-2008
       6             : 
       7             :      ** NOTE! The following LGPL license applies to the ldb
       8             :      ** library. This does NOT imply that all of Samba is released
       9             :      ** under the LGPL
      10             : 
      11             :    This library is free software; you can redistribute it and/or
      12             :    modify it under the terms of the GNU Lesser General Public
      13             :    License as published by the Free Software Foundation; either
      14             :    version 3 of the License, or (at your option) any later version.
      15             : 
      16             :    This library is distributed in the hope that it will be useful,
      17             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      19             :    Lesser General Public License for more details.
      20             : 
      21             :    You should have received a copy of the GNU Lesser General Public
      22             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : /*
      26             :  *  Name: rdn_name
      27             :  *
      28             :  *  Component: ldb rdn name module
      29             :  *
      30             :  *  Description: keep a consistent name attribute on objects manpulations
      31             :  *
      32             :  *  Author: Andrew Bartlett
      33             :  *
      34             :  *  Modifications:
      35             :  *    - made the module async
      36             :  *      Simo Sorce Mar 2006
      37             :  */
      38             : 
      39             : #include "replace.h"
      40             : #include "system/filesys.h"
      41             : #include "system/time.h"
      42             : #include "ldb_module.h"
      43             : 
      44             : struct rename_context {
      45             :         struct ldb_module *module;
      46             :         struct ldb_request *req;
      47             : 
      48             :         struct ldb_reply *ares;
      49             : };
      50             : 
      51      654233 : static int rdn_name_add_callback(struct ldb_request *req,
      52             :                                  struct ldb_reply *ares)
      53             : {
      54       84505 :         struct rename_context *ac;
      55             : 
      56      654233 :         ac = talloc_get_type(req->context, struct rename_context);
      57             : 
      58      654233 :         if (!ares) {
      59           0 :                 return ldb_module_done(ac->req, NULL, NULL,
      60             :                                         LDB_ERR_OPERATIONS_ERROR);
      61             :         }
      62             : 
      63      654233 :         if (ares->type == LDB_REPLY_REFERRAL) {
      64           0 :                 return ldb_module_send_referral(ac->req, ares->referral);
      65             :         }
      66             : 
      67      654233 :         if (ares->error != LDB_SUCCESS) {
      68         362 :                 return ldb_module_done(ac->req, ares->controls,
      69             :                                         ares->response, ares->error);
      70             :         }
      71             : 
      72      653871 :         if (ares->type != LDB_REPLY_DONE) {
      73           0 :                 return ldb_module_done(ac->req, NULL, NULL,
      74             :                                         LDB_ERR_OPERATIONS_ERROR);
      75             :         }
      76             : 
      77      653871 :         return ldb_module_done(ac->req, ares->controls,
      78             :                                         ares->response, LDB_SUCCESS);
      79             : }
      80             : 
      81      661911 : static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
      82             : {
      83       84730 :         struct ldb_context *ldb;
      84       84730 :         struct ldb_request *down_req;
      85       84730 :         struct rename_context *ac;
      86       84730 :         struct ldb_message *msg;
      87       84730 :         struct ldb_message_element *attribute;
      88       84730 :         const struct ldb_schema_attribute *a;
      89       84730 :         const char *rdn_name;
      90       84730 :         const struct ldb_val *rdn_val_p;
      91       84730 :         struct ldb_val rdn_val;
      92       84730 :         unsigned int i;
      93       84730 :         int ret;
      94             : 
      95      661911 :         ldb = ldb_module_get_ctx(module);
      96             : 
      97             :         /* do not manipulate our control entries */
      98      661911 :         if (ldb_dn_is_special(req->op.add.message->dn)) {
      99        7677 :                 return ldb_next_request(module, req);
     100             :         }
     101             : 
     102      654234 :         ac = talloc_zero(req, struct rename_context);
     103      654234 :         if (ac == NULL) {
     104           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     105             :         }
     106             : 
     107      654234 :         ac->module = module;
     108      654234 :         ac->req = req;
     109             : 
     110      654234 :         msg = ldb_msg_copy_shallow(req, req->op.add.message);
     111      654234 :         if (msg == NULL) {
     112           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     113             :         }
     114             : 
     115      654234 :         rdn_name = ldb_dn_get_rdn_name(msg->dn);
     116      654234 :         if (rdn_name == NULL) {
     117           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     118             :         }
     119             : 
     120      654234 :         rdn_val_p = ldb_dn_get_rdn_val(msg->dn);
     121      654234 :         if (rdn_val_p == NULL) {
     122           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     123             :         }
     124      654234 :         if (rdn_val_p->length == 0) {
     125           0 :                 ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!",
     126           0 :                                        ldb_dn_get_linearized(req->op.add.message->dn));
     127           0 :                 return LDB_ERR_INVALID_DN_SYNTAX;
     128             :         }
     129      654234 :         rdn_val = ldb_val_dup(msg, rdn_val_p);
     130             : 
     131             :         /* Perhaps someone above us tried to set this? Then ignore it */
     132      654234 :         ldb_msg_remove_attr(msg, "name");
     133             : 
     134      654234 :         ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL);
     135      654234 :         if (ret != LDB_SUCCESS) {
     136           0 :                 return ret;
     137             :         }
     138             : 
     139      654234 :         a = ldb_schema_attribute_by_name(ldb, rdn_name);
     140      654234 :         if (a == NULL) {
     141           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     142             :         }
     143             : 
     144      654234 :         attribute = ldb_msg_find_element(msg, rdn_name);
     145      654234 :         if (!attribute) {
     146             :                 /* add entry with normalised RDN information if possible */
     147      421618 :                 if (a->name != NULL && strcmp(a->name, "*") != 0) {
     148      421617 :                         ret = ldb_msg_add_value(msg, a->name, &rdn_val, NULL);
     149             :                 } else {
     150           1 :                         ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL);
     151             :                 }
     152      421618 :                 if (ret != LDB_SUCCESS) {
     153           0 :                         return ret;
     154             :                 }
     155             :         } else {
     156             :                 /* normalise attribute name if possible */
     157      232616 :                 if (a->name != NULL && strcmp(a->name, "*") != 0) {
     158      232613 :                         attribute->name = a->name;
     159             :                 }
     160             :                 /* normalise attribute value */
     161      232619 :                 for (i = 0; i < attribute->num_values; i++) {
     162       39197 :                         bool matched;
     163      232618 :                         if (a->syntax->operator_fn) {
     164           0 :                                 ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a,
     165           0 :                                                              &rdn_val, &attribute->values[i], &matched);
     166           0 :                                 if (ret != LDB_SUCCESS) return ret;
     167             :                         } else {
     168      465236 :                                 matched = (a->syntax->comparison_fn(ldb, msg,
     169      232618 :                                                                     &rdn_val, &attribute->values[i]) == 0);
     170             :                         }
     171      232618 :                         if (matched) {
     172             :                                 /* overwrite so it matches in case */
     173      232615 :                                 attribute->values[i] = rdn_val;
     174      232615 :                                 break;
     175             :                         }
     176             :                 }
     177      232616 :                 if (i == attribute->num_values) {
     178           1 :                         char *rdn_errstring = talloc_asprintf(ac,
     179             :                                 "RDN mismatch on %s: %s (%.*s) should match one of:",
     180             :                                 ldb_dn_get_linearized(msg->dn), rdn_name,
     181           1 :                                 (int)rdn_val.length, (const char *)rdn_val.data);
     182           2 :                         for (i = 0; i < attribute->num_values; i++) {
     183           1 :                                 talloc_asprintf_addbuf(
     184             :                                         &rdn_errstring, " (%.*s)",
     185           1 :                                         (int)attribute->values[i].length,
     186           1 :                                         (const char *)attribute->values[i].data);
     187             :                         }
     188           1 :                         ldb_set_errstring(ldb, rdn_errstring);
     189             :                         /* Match AD's error here */
     190           1 :                         return LDB_ERR_INVALID_DN_SYNTAX;
     191             :                 }
     192             :         }
     193             : 
     194      654233 :         ret = ldb_build_add_req(&down_req, ldb, req,
     195             :                                 msg,
     196             :                                 req->controls,
     197             :                                 ac, rdn_name_add_callback,
     198             :                                 req);
     199      654233 :         if (ret != LDB_SUCCESS) {
     200           0 :                 return ret;
     201             :         }
     202             : 
     203      654233 :         talloc_steal(down_req, msg);
     204             : 
     205             :         /* go on with the call chain */
     206      654233 :         return ldb_next_request(module, down_req);
     207             : }
     208             : 
     209        1563 : static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
     210             : {
     211          18 :         struct rename_context *ac;
     212             : 
     213        1563 :         ac = talloc_get_type(req->context, struct rename_context);
     214             : 
     215        1563 :         if (!ares) {
     216           0 :                 return ldb_module_done(ac->req, NULL, NULL,
     217             :                                         LDB_ERR_OPERATIONS_ERROR);
     218             :         }
     219             : 
     220        1563 :         if (ares->type == LDB_REPLY_REFERRAL) {
     221           0 :                 return ldb_module_send_referral(ac->req, ares->referral);
     222             :         }
     223             : 
     224        1563 :         if (ares->error != LDB_SUCCESS) {
     225           0 :                 return ldb_module_done(ac->req, ares->controls,
     226             :                                         ares->response, ares->error);
     227             :         }
     228             : 
     229             :         /* the only supported reply right now is a LDB_REPLY_DONE */
     230        1563 :         if (ares->type != LDB_REPLY_DONE) {
     231           0 :                 return ldb_module_done(ac->req, NULL, NULL,
     232             :                                         LDB_ERR_OPERATIONS_ERROR);
     233             :         }
     234             : 
     235             :         /* send saved controls eventually */
     236        1563 :         return ldb_module_done(ac->req, ac->ares->controls,
     237        1563 :                                 ac->ares->response, LDB_SUCCESS);
     238             : }
     239             : 
     240        1636 : static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
     241             : {
     242          22 :         struct ldb_context *ldb;
     243          22 :         struct rename_context *ac;
     244          22 :         struct ldb_request *mod_req;
     245          22 :         const char *rdn_name;
     246        1636 :         const struct ldb_schema_attribute *a = NULL;
     247          22 :         const struct ldb_val *rdn_val_p;
     248          22 :         struct ldb_val rdn_val;
     249          22 :         struct ldb_message *msg;
     250          22 :         int ret;
     251             : 
     252        1636 :         ac = talloc_get_type(req->context, struct rename_context);
     253        1636 :         ldb = ldb_module_get_ctx(ac->module);
     254             : 
     255        1636 :         if (!ares) {
     256           0 :                 goto error;
     257             :         }
     258             : 
     259        1636 :         if (ares->type == LDB_REPLY_REFERRAL) {
     260           0 :                 return ldb_module_send_referral(ac->req, ares->referral);
     261             :         }
     262             : 
     263        1636 :         if (ares->error != LDB_SUCCESS) {
     264          72 :                 return ldb_module_done(ac->req, ares->controls,
     265             :                                         ares->response, ares->error);
     266             :         }
     267             : 
     268             :         /* the only supported reply right now is a LDB_REPLY_DONE */
     269        1564 :         if (ares->type != LDB_REPLY_DONE) {
     270           0 :                 goto error;
     271             :         }
     272             : 
     273             :         /* save reply for caller */
     274        1564 :         ac->ares = talloc_steal(ac, ares);
     275             : 
     276        1564 :         msg = ldb_msg_new(ac);
     277        1564 :         if (msg == NULL) {
     278           0 :                 goto error;
     279             :         }
     280        1564 :         msg->dn = ldb_dn_copy(msg, ac->req->op.rename.newdn);
     281        1564 :         if (msg->dn == NULL) {
     282           0 :                 goto error;
     283             :         }
     284             : 
     285        1564 :         rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn);
     286        1564 :         if (rdn_name == NULL) {
     287           0 :                 goto error;
     288             :         }
     289             : 
     290        1564 :         a = ldb_schema_attribute_by_name(ldb, rdn_name);
     291        1564 :         if (a == NULL) {
     292           0 :                 goto error;
     293             :         }
     294             : 
     295        1564 :         if (a->name != NULL && strcmp(a->name, "*") != 0) {
     296        1564 :                 rdn_name = a->name;
     297             :         }
     298             : 
     299        1564 :         rdn_val_p = ldb_dn_get_rdn_val(msg->dn);
     300        1564 :         if (rdn_val_p == NULL) {
     301           0 :                 goto error;
     302             :         }
     303        1564 :         if (rdn_val_p->length == 0) {
     304           1 :                 ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!",
     305             :                                        ldb_dn_get_linearized(req->op.rename.olddn));
     306           1 :                 return ldb_module_done(ac->req, NULL, NULL,
     307             :                                        LDB_ERR_NAMING_VIOLATION);
     308             :         }
     309        1563 :         rdn_val = ldb_val_dup(msg, rdn_val_p);
     310             : 
     311        1563 :         if (ldb_msg_append_value(msg, rdn_name, &rdn_val, LDB_FLAG_MOD_REPLACE) != 0) {
     312           0 :                 goto error;
     313             :         }
     314        1563 :         if (ldb_msg_append_value(msg, "name", &rdn_val, LDB_FLAG_MOD_REPLACE) != 0) {
     315           0 :                 goto error;
     316             :         }
     317             : 
     318        1563 :         ret = ldb_build_mod_req(&mod_req, ldb,
     319             :                                 ac, msg, NULL,
     320             :                                 ac, rdn_modify_callback,
     321             :                                 req);
     322        1563 :         if (ret != LDB_SUCCESS) {
     323           0 :                 return ldb_module_done(ac->req, NULL, NULL, ret);
     324             :         }
     325        1563 :         talloc_steal(mod_req, msg);
     326             : 
     327             :         /* go on with the call chain */
     328        1563 :         return ldb_next_request(ac->module, mod_req);
     329             : 
     330           0 : error:
     331           0 :         return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
     332             : }
     333             : 
     334        1636 : static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req)
     335             : {
     336          22 :         struct ldb_context *ldb;
     337          22 :         struct rename_context *ac;
     338          22 :         struct ldb_request *down_req;
     339          22 :         int ret;
     340             : 
     341        1636 :         ldb = ldb_module_get_ctx(module);
     342             : 
     343             :         /* do not manipulate our control entries */
     344        1636 :         if (ldb_dn_is_special(req->op.rename.newdn)) {
     345           0 :                 return ldb_next_request(module, req);
     346             :         }
     347             : 
     348        1636 :         ac = talloc_zero(req, struct rename_context);
     349        1636 :         if (ac == NULL) {
     350           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     351             :         }
     352             : 
     353        1636 :         ac->module = module;
     354        1636 :         ac->req = req;
     355             : 
     356        1636 :         ret = ldb_build_rename_req(&down_req,
     357             :                                    ldb,
     358             :                                    ac,
     359             :                                    req->op.rename.olddn,
     360             :                                    req->op.rename.newdn,
     361             :                                    req->controls,
     362             :                                    ac,
     363             :                                    rdn_rename_callback,
     364             :                                    req);
     365             : 
     366        1636 :         if (ret != LDB_SUCCESS) {
     367           0 :                 return ret;
     368             :         }
     369             : 
     370             :         /* rename first, modify "name" if rename is ok */
     371        1636 :         return ldb_next_request(module, down_req);
     372             : }
     373             : 
     374           0 : static int rdn_recalculate_callback(struct ldb_request *req, struct ldb_reply *ares)
     375             : {
     376           0 :         struct ldb_request *up_req = talloc_get_type(req->context, struct ldb_request);
     377             : 
     378           0 :         talloc_steal(up_req, req);
     379           0 :         return up_req->callback(up_req, ares);
     380             : }
     381             : 
     382      644144 : static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req)
     383             : {
     384       27872 :         struct ldb_context *ldb;
     385       27872 :         const struct ldb_val *rdn_val_p;
     386      644144 :         struct ldb_message_element *e = NULL;
     387      644144 :         struct ldb_control *recalculate_rdn_control = NULL;
     388             : 
     389      644144 :         ldb = ldb_module_get_ctx(module);
     390             : 
     391             :         /* do not manipulate our control entries */
     392      644144 :         if (ldb_dn_is_special(req->op.mod.message->dn)) {
     393         739 :                 return ldb_next_request(module, req);
     394             :         }
     395             : 
     396      643405 :         recalculate_rdn_control = ldb_request_get_control(req,
     397             :                                         LDB_CONTROL_RECALCULATE_RDN_OID);
     398      643405 :         if (recalculate_rdn_control != NULL) {
     399           0 :                 struct ldb_message *msg = NULL;
     400           0 :                 const char *rdn_name = NULL;
     401           0 :                 struct ldb_val rdn_val;
     402           0 :                 const struct ldb_schema_attribute *a = NULL;
     403           0 :                 struct ldb_request *mod_req = NULL;
     404           0 :                 int ret;
     405           0 :                 struct ldb_message_element *rdn_del = NULL;
     406           0 :                 struct ldb_message_element *name_del = NULL;
     407             : 
     408           0 :                 recalculate_rdn_control->critical = false;
     409             : 
     410           0 :                 msg = ldb_msg_copy_shallow(req, req->op.mod.message);
     411           0 :                 if (msg == NULL) {
     412           0 :                         return ldb_module_oom(module);
     413             :                 }
     414             : 
     415             :                 /*
     416             :                  * The caller must pass a dummy 'name' attribute
     417             :                  * in order to bypass some high level checks.
     418             :                  *
     419             :                  * We just remove it and check nothing is left.
     420             :                  */
     421           0 :                 ldb_msg_remove_attr(msg, "name");
     422             : 
     423           0 :                 if (msg->num_elements != 0) {
     424           0 :                         return ldb_module_operr(module);
     425             :                 }
     426             : 
     427           0 :                 rdn_name = ldb_dn_get_rdn_name(msg->dn);
     428           0 :                 if (rdn_name == NULL) {
     429           0 :                         return ldb_module_oom(module);
     430             :                 }
     431             : 
     432           0 :                 a = ldb_schema_attribute_by_name(ldb, rdn_name);
     433           0 :                 if (a == NULL) {
     434           0 :                         return ldb_module_operr(module);
     435             :                 }
     436             : 
     437           0 :                 if (a->name != NULL && strcmp(a->name, "*") != 0) {
     438           0 :                         rdn_name = a->name;
     439             :                 }
     440             : 
     441           0 :                 rdn_val_p = ldb_dn_get_rdn_val(msg->dn);
     442           0 :                 if (rdn_val_p == NULL) {
     443           0 :                         return ldb_module_oom(module);
     444             :                 }
     445           0 :                 rdn_val = ldb_val_dup(msg, rdn_val_p);
     446           0 :                 if (rdn_val.length == 0) {
     447           0 :                         return ldb_module_oom(module);
     448             :                 }
     449             : 
     450             :                 /*
     451             :                  * This is a bit tricky:
     452             :                  *
     453             :                  * We want _DELETE elements (as "rdn_del" and "name_del" without
     454             :                  * values) first, followed by _ADD (with the real names)
     455             :                  * elements (with values). Then we fix up the "rdn_del" and
     456             :                  * "name_del" attributes.
     457             :                  */
     458             : 
     459           0 :                 ret = ldb_msg_add_empty(msg, "rdn_del", LDB_FLAG_MOD_DELETE, NULL);
     460           0 :                 if (ret != 0) {
     461           0 :                         return ldb_module_oom(module);
     462             :                 }
     463           0 :                 ret = ldb_msg_append_value(msg, rdn_name, &rdn_val, LDB_FLAG_MOD_ADD);
     464           0 :                 if (ret != 0) {
     465           0 :                         return ldb_module_oom(module);
     466             :                 }
     467             : 
     468           0 :                 ret = ldb_msg_add_empty(msg, "name_del", LDB_FLAG_MOD_DELETE, NULL);
     469           0 :                 if (ret != 0) {
     470           0 :                         return ldb_module_oom(module);
     471             :                 }
     472           0 :                 ret = ldb_msg_append_value(msg, "name", &rdn_val, LDB_FLAG_MOD_ADD);
     473           0 :                 if (ret != 0) {
     474           0 :                         return ldb_module_oom(module);
     475             :                 }
     476             : 
     477           0 :                 rdn_del = ldb_msg_find_element(msg, "rdn_del");
     478           0 :                 if (rdn_del == NULL) {
     479           0 :                         return ldb_module_operr(module);
     480             :                 }
     481           0 :                 rdn_del->name = talloc_strdup(msg->elements, rdn_name);
     482           0 :                 if (rdn_del->name == NULL) {
     483           0 :                         return ldb_module_oom(module);
     484             :                 }
     485           0 :                 name_del = ldb_msg_find_element(msg, "name_del");
     486           0 :                 if (name_del == NULL) {
     487           0 :                         return ldb_module_operr(module);
     488             :                 }
     489           0 :                 name_del->name = talloc_strdup(msg->elements, "name");
     490           0 :                 if (name_del->name == NULL) {
     491           0 :                         return ldb_module_oom(module);
     492             :                 }
     493             : 
     494           0 :                 ret = ldb_build_mod_req(&mod_req, ldb,
     495             :                                         req, msg, NULL,
     496             :                                         req, rdn_recalculate_callback,
     497             :                                         req);
     498           0 :                 if (ret != LDB_SUCCESS) {
     499           0 :                         return ldb_module_done(req, NULL, NULL, ret);
     500             :                 }
     501           0 :                 talloc_steal(mod_req, msg);
     502             : 
     503           0 :                 ret = ldb_request_add_control(mod_req,
     504             :                                               LDB_CONTROL_RECALCULATE_RDN_OID,
     505             :                                               false, NULL);
     506           0 :                 if (ret != LDB_SUCCESS) {
     507           0 :                         return ldb_module_done(req, NULL, NULL, ret);
     508             :                 }
     509           0 :                 ret = ldb_request_add_control(mod_req,
     510             :                                               LDB_CONTROL_PERMISSIVE_MODIFY_OID,
     511             :                                               false, NULL);
     512           0 :                 if (ret != LDB_SUCCESS) {
     513           0 :                         return ldb_module_done(req, NULL, NULL, ret);
     514             :                 }
     515             : 
     516             :                 /* go on with the call chain */
     517           0 :                 return ldb_next_request(module, mod_req);
     518             :         }
     519             : 
     520      643405 :         rdn_val_p = ldb_dn_get_rdn_val(req->op.mod.message->dn);
     521      643405 :         if (rdn_val_p == NULL) {
     522           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     523             :         }
     524      643405 :         if (rdn_val_p->length == 0) {
     525           0 :                 ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!",
     526           0 :                                        ldb_dn_get_linearized(req->op.mod.message->dn));
     527           0 :                 return LDB_ERR_INVALID_DN_SYNTAX;
     528             :         }
     529             : 
     530      643405 :         e = ldb_msg_find_element(req->op.mod.message, "distinguishedName");
     531      643405 :         if (e != NULL) {
     532           3 :                 ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead",
     533           3 :                                        ldb_dn_get_linearized(req->op.mod.message->dn));
     534           3 :                 if (LDB_FLAG_MOD_TYPE(e->flags) == LDB_FLAG_MOD_REPLACE) {
     535           1 :                         return LDB_ERR_CONSTRAINT_VIOLATION;
     536             :                 } else {
     537           2 :                         return LDB_ERR_UNWILLING_TO_PERFORM;
     538             :                 }
     539             :         }
     540             : 
     541      643402 :         if (ldb_msg_find_element(req->op.mod.message, "name")) {
     542           1 :                 ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead",
     543           1 :                                        ldb_dn_get_linearized(req->op.mod.message->dn));
     544           1 :                 return LDB_ERR_NOT_ALLOWED_ON_RDN;
     545             :         }
     546             : 
     547      643401 :         if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) {
     548           1 :                 ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead",
     549           1 :                                        ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn));
     550           1 :                 return LDB_ERR_NOT_ALLOWED_ON_RDN;
     551             :         }
     552             : 
     553             :         /* All OK, they kept their fingers out of the special attributes */
     554      643400 :         return ldb_next_request(module, req);
     555             : }
     556             : 
     557    39468031 : static int rdn_name_search(struct ldb_module *module, struct ldb_request *req)
     558             : {
     559     2238386 :         struct ldb_context *ldb;
     560     2238386 :         const char *rdn_name;
     561     2238386 :         const struct ldb_val *rdn_val_p;
     562             : 
     563    39468031 :         ldb = ldb_module_get_ctx(module);
     564             : 
     565             :         /* do not manipulate our control entries */
     566    39468031 :         if (ldb_dn_is_special(req->op.search.base)) {
     567     1329404 :                 return ldb_next_request(module, req);
     568             :         }
     569             : 
     570    38138627 :         rdn_name = ldb_dn_get_rdn_name(req->op.search.base);
     571    38138627 :         rdn_val_p = ldb_dn_get_rdn_val(req->op.search.base);
     572    38138627 :         if ((rdn_name != NULL) && (rdn_val_p == NULL)) {
     573           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     574             :         }
     575    38138627 :         if ((rdn_val_p != NULL) && (rdn_val_p->length == 0)) {
     576           9 :                 ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!",
     577             :                                        ldb_dn_get_linearized(req->op.search.base));
     578           9 :                 return LDB_ERR_INVALID_DN_SYNTAX;
     579             :         }
     580             : 
     581    38138618 :         return ldb_next_request(module, req);
     582             : }
     583             : 
     584             : static const struct ldb_module_ops ldb_rdn_name_module_ops = {
     585             :         .name              = "rdn_name",
     586             :         .add               = rdn_name_add,
     587             :         .modify            = rdn_name_modify,
     588             :         .rename            = rdn_name_rename,
     589             :         .search            = rdn_name_search
     590             : };
     591             : 
     592        6091 : int ldb_rdn_name_init(const char *version)
     593             : {
     594        6091 :         LDB_MODULE_CHECK_VERSION(version);
     595        6091 :         return ldb_register_module(&ldb_rdn_name_module_ops);
     596             : }

Generated by: LCOV version 1.14