diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/back-sch.c | 82 |
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, |
