summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/back-sch.c82
1 files changed, 73 insertions, 9 deletions
diff --git a/src/back-sch.c b/src/back-sch.c
index ac6ff17..2e2d195 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -287,7 +287,8 @@ void
backend_set_entry(Slapi_PBlock *pb, Slapi_Entry *e,
struct backend_set_data *data)
{
- char *dn, *rdn, *ndn, *ldif, *plugin_id, *keys[2], *values[2], **ava;
+ const char *hexchars = "0123456789ABCDEF";
+ char *rdn, *ndn, *ldif, *plugin_id, *keys[2], *values[2], **ava, *p, *q;
char *attr, *val;
unsigned int rdn_len, value_len, *ava_lens;
const char *rdnstr;
@@ -317,21 +318,68 @@ backend_set_entry(Slapi_PBlock *pb, Slapi_Entry *e,
&data->common.ref_attr_list,
&data->common.inref_attr_list,
&rdn_len);
- if (rdn == NULL) {
- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id,
- "no RDN for %s, unsetting domain/map/id"
+ if ((rdn == NULL) || (strlen(rdn) == 0) || (strchr(rdn, '=') == NULL)) {
+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id,
+ "no RDN for %s, unsetting domain/map/id "
"\"%s\"/\"%s\"/(\"%s\")\n",
ndn, data->common.group, data->common.set, ndn);
map_data_unset_entry(data->common.state,
data->common.group, data->common.set, ndn);
+ return;
+ }
+ /* Assume attribute=value and hex-escape the whole value to build the
+ * new entry's RDN. The server functions will un-escape whatever they
+ * can when we build the resulting DN. */
+ q = malloc(strlen(rdn) * 3 + 1);
+ p = strchr(rdn, '=') + 1;
+ i = p - rdn;
+ memcpy(q, rdn, i);
+ while (*p != '\0') {
+ j = ((unsigned int) *p++) & 0xff;
+ q[i++] = '\\';
+ q[i++] = hexchars[(j & 0xf0) >> 4];
+ q[i++] = hexchars[j & 0xf];
+ }
+ q[i] = '\0';
+ srdn = slapi_rdn_new_dn(q);
+ free(q);
+ /* Now build the SDN. Check it for validity. */
+ sdn = slapi_sdn_add_rdn(slapi_sdn_dup(data->container_sdn), srdn);
+ slapi_rdn_free(&srdn);
+ if ((sdn == NULL) ||
+ (slapi_sdn_get_dn(sdn) == NULL) ||
+ (slapi_sdn_get_ndn(sdn) == NULL)) {
+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id,
+ "would generate an invalid DN (1), "
+ "unsetting domain/map/id "
+ "\"%s\"/\"%s\"/(\"%s\")\n",
+ data->common.group, data->common.set, ndn);
+ map_data_unset_entry(data->common.state,
+ data->common.group, data->common.set, ndn);
+ if (sdn != NULL) {
+ slapi_sdn_free(&sdn);
+ }
+ format_free_data(rdn);
+ return;
}
- /* Now build the entry itself, and set the DN first. */
+ /* Now build the entry itself. Set the DN first, and make sure it took
+ * the value. */
entry = slapi_entry_alloc();
- dn = slapi_dn_plus_rdn(slapi_sdn_get_ndn(data->container_sdn), rdn);
- sdn = slapi_sdn_new_dn_byval(dn);
slapi_entry_set_sdn(entry, sdn);
slapi_sdn_free(&sdn);
- slapi_ch_free((void **) &dn);
+ if ((slapi_entry_get_dn(entry) == NULL) ||
+ (slapi_entry_get_ndn(entry) == NULL)) {
+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id,
+ "would generate an invalid DN (2), "
+ "unsetting domain/map/id "
+ "\"%s\"/\"%s\"/(\"%s\")\n",
+ data->common.group, data->common.set, ndn);
+ map_data_unset_entry(data->common.state,
+ data->common.group, data->common.set, ndn);
+ slapi_entry_free(entry);
+ format_free_data(rdn);
+ return;
+ }
/* Set operational attributes here so that they can be overridden. */
backend_set_operational_attributes(entry, data->common.state,
time(NULL), 0);
@@ -457,8 +505,24 @@ backend_set_entry(Slapi_PBlock *pb, Slapi_Entry *e,
backend_entry_make_entry_data(e_dn, entry),
backend_entry_free_entry_data);
} else {
+ if (rdnstr == NULL) {
+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id,
+ "would generate an invalid RDN, "
+ "unsetting domain/map/id "
+ "\"%s\"/\"%s\"/(\"%s\")\n",
+ data->common.group, data->common.set,
+ ndn);
+ }
+ if (slapi_entry_get_ndn(entry) == NULL) {
+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id,
+ "would generate an invalid entry DN, "
+ "unsetting domain/map/id "
+ "\"%s\"/\"%s\"/(\"%s\")\n",
+ data->common.group, data->common.set,
+ ndn);
+ }
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id,
- "no value for %s, unsetting domain/map/id"
+ "no value for %s, unsetting domain/map/id "
"\"%s\"/\"%s\"/(\"%s\")\n",
ndn, data->common.group, data->common.set, ndn);
map_data_unset_entry(data->common.state,