src/com
by Richard Allen Megginson
src/com/netscape/management/admserv/panel/LoggingConfigPanel.java | 71 ++++++++--
src/com/netscape/management/admserv/panel/panel.properties | 3
2 files changed, 59 insertions(+), 15 deletions(-)
New commits:
commit 8a5bb4c58ab983c52d471de232053608d8e174bb
Author: Endi S. Dewata <edewata(a)redhat.com>
Date: Fri Apr 23 19:13:04 2010 -0500
Bug 368481 - Unable to change Admin Server log paths in Console
https://bugzilla.redhat.com/show_bug.cgi?id=368481
Resolves: bug 368481
Bug Description: Unable to change Admin Server log paths in Console
Fix Description: The console has been modified to split the log full
path into the path of the log directory and the file name. They will
be shown in separate text fields. Only the file name will be editable.
When the user saves the changes, the directory path will be combined
with the file name, then submitted to the server as a full path.
Reviewed by: rmeggins (and pushed by)
diff --git a/src/com/netscape/management/admserv/panel/LoggingConfigPanel.java b/src/com/netscape/management/admserv/panel/LoggingConfigPanel.java
index 7699a38..e9a5422 100644
--- a/src/com/netscape/management/admserv/panel/LoggingConfigPanel.java
+++ b/src/com/netscape/management/admserv/panel/LoggingConfigPanel.java
@@ -38,11 +38,12 @@ public class LoggingConfigPanel extends PluginConfigPanel {
IConfigDataModel _configData;
static ResourceSet _resource;
- static String _i18nLogFile, _i18nErrorLogGroupbox,
+ static String _i18nLogPath, _i18nLogFile, _i18nErrorLogGroupbox,
_i18nAccessLogGroupbox;
static {
_resource = new ResourceSet("com.netscape.management.admserv.panel.panel");
+ _i18nLogPath = _resource.getString("logging","LogPath");
_i18nLogFile = _resource.getString("logging","LogFile");
_i18nAccessLogGroupbox = _resource.getString("logging","AccessLogGroupbox");
_i18nErrorLogGroupbox = _resource.getString("logging","ErrorLogGroupbox");
@@ -54,6 +55,9 @@ public class LoggingConfigPanel extends PluginConfigPanel {
SuiConstants.SEPARATED_COMPONENT_SPACE;
public static final int rghtColInset = SuiConstants.COMPONENT_SPACE;
+ JLabel _lblAccessPath, _lblErrorPath;
+ JTextField _txtAccessPath, _txtErrorPath;
+
JLabel _lblAccessFile, _lblErrorFile;
JTextField _txtAccessFile, _txtErrorFile;
@@ -111,21 +115,36 @@ public class LoggingConfigPanel extends PluginConfigPanel {
}
public void setPanelContent(IConfigDataModel data) {
+System.out.println("LoggingConfigPanel.setPanelContent: data: "+data.getClass().getName());
String value;
value = (String) data.getAttribute(AttrNames.CONFIG_ACCESSLOG);
- _txtAccessFile.setText(value == null ? "" : value);
+ if (value == null) {
+ _txtAccessPath.setText("");
+ _txtAccessFile.setText("");
+ } else {
+ int i = value.lastIndexOf('/');
+ _txtAccessPath.setText(value.substring(0, i));
+ _txtAccessFile.setText(value.substring(i+1));
+ }
value = (String) data.getAttribute(AttrNames.CONFIG_ERRORLOG);
- _txtErrorFile.setText(value == null ? "" : value);
+ if (value == null) {
+ _txtErrorPath.setText("");
+ _txtErrorFile.setText("");
+ } else {
+ int i = value.lastIndexOf('/');
+ _txtErrorPath.setText(value.substring(0, i));
+ _txtErrorFile.setText(value.substring(i+1));
+ }
}
public void getPanelContent(IConfigDataModel data)
throws ValidationException {
try {
data.setAttribute(AttrNames.CONFIG_ACCESSLOG,
- _txtAccessFile.getText());
+ _txtAccessPath.getText()+"/"+_txtAccessFile.getText());
data.setAttribute(AttrNames.CONFIG_ERRORLOG,
- _txtErrorFile.getText());
+ _txtErrorPath.getText()+"/"+_txtErrorFile.getText());
} catch (ValidationException e) {
throw e;
}
@@ -141,48 +160,72 @@ public class LoggingConfigPanel extends PluginConfigPanel {
p.setLayout(gbl = new GridBagLayout());
+ _lblAccessPath = new JLabel(_i18nLogPath);
+ _txtAccessPath = new SingleByteTextField(16);
_lblAccessFile = new JLabel(_i18nLogFile);
_txtAccessFile = new SingleByteTextField(16); // 324429
+ _txtAccessPath.setEditable(false);
+
//gbc.setInsets(0,leftColInset,0,0);
gbc.setGrid(0, 0, 1, 1);
gbc.setSpace(1.0, 0.0, GBC.WEST, //anchor
GBC.HORIZONTAL); //fill
- p.add(createLogGroup(_i18nAccessLogGroupbox, _lblAccessFile,
- _txtAccessFile), gbc);
+ p.add(createLogGroup(_i18nAccessLogGroupbox,
+ _lblAccessPath, _txtAccessPath,
+ _lblAccessFile, _txtAccessFile), gbc);
+ _lblErrorPath = new JLabel(_i18nLogPath);
+ _txtErrorPath = new SingleByteTextField(16);
_lblErrorFile = new JLabel(_i18nLogFile);
_txtErrorFile = new SingleByteTextField(16); // 324429
+ _txtErrorPath.setEditable(false);
+
//gbc.setInsets(0,leftColInset,0,0);
gbc.setGrid(0, 1, 1, 1);
gbc.setSpace(1.0, 0.0, GBC.WEST, //anchor
GBC.HORIZONTAL); //fill
- p.add(createLogGroup(_i18nErrorLogGroupbox, _lblErrorFile,
- _txtErrorFile), gbc);
+ p.add(createLogGroup(_i18nErrorLogGroupbox,
+ _lblErrorPath, _txtErrorPath,
+ _lblErrorFile, _txtErrorFile), gbc);
return p;
}
- private JPanel createLogGroup(String groupTitle, JLabel lbl,
- JTextField txt) {
+ private JPanel createLogGroup(String groupTitle,
+ JLabel lblPath, JTextField txtPath,
+ JLabel lblFile, JTextField txtFile) {
GridBagLayout gbl;
GBC gbc = new GBC();
JPanel group = new JPanel(gbl = new GridBagLayout());
group.setBorder(BaseConfigPanel.createGroupBorder(groupTitle));
- lbl.setFont(BaseConfigPanel.getLabelFont());
+ lblPath.setFont(BaseConfigPanel.getLabelFont());
gbc.setInsets(0, 0, 0, 0);
gbc.setGrid(0, 0, 1, 1);
gbc.setSpace(0.0, 0.0, GBC.WEST, //anchor
GBC.NONE); //fill
- group.add(lbl, gbc);
+ group.add(lblPath, gbc);
gbc.setInsets(0, rghtColInset, 0, 0);
gbc.setGrid(1, 0, 1, 1);
gbc.setSpace(1.0, 0.0, GBC.WEST, // anchor
GBC.HORIZONTAL); //fill
- group.add(txt, gbc);
+ group.add(txtPath, gbc);
+
+ lblFile.setFont(BaseConfigPanel.getLabelFont());
+ gbc.setInsets(0, 0, 0, 0);
+ gbc.setGrid(0, 1, 1, 1);
+ gbc.setSpace(0.0, 0.0, GBC.WEST, //anchor
+ GBC.NONE); //fill
+ group.add(lblFile, gbc);
+
+ gbc.setInsets(0, rghtColInset, 0, 0);
+ gbc.setGrid(1, 1, 1, 1);
+ gbc.setSpace(1.0, 0.0, GBC.WEST, // anchor
+ GBC.HORIZONTAL); //fill
+ group.add(txtFile, gbc);
return group;
}
diff --git a/src/com/netscape/management/admserv/panel/panel.properties b/src/com/netscape/management/admserv/panel/panel.properties
index d8e7fda..bfdb482 100644
--- a/src/com/netscape/management/admserv/panel/panel.properties
+++ b/src/com/netscape/management/admserv/panel/panel.properties
@@ -188,7 +188,8 @@ network-MsgEnterServerUID=Please enter server UID
#
# Logging panel
#
-logging-LogFile=Log File:
+logging-LogPath=Path:
+logging-LogFile=File Name:
logging-AccessLogGroupbox=Access Log
logging-ErrorLogGroupbox=Error Log
13 years, 11 months
admserv/cgi-src40
by Richard Allen Megginson
admserv/cgi-src40/config.c | 46 ++++++++++++++++++++++++++-------------------
1 file changed, 27 insertions(+), 19 deletions(-)
New commits:
commit 2d2a225b0a435e7f3199c4656ea2078b02cc6573
Author: Endi S. Dewata <edewata(a)redhat.com>
Date: Fri Apr 23 18:59:56 2010 -0500
Bug 368481 - Unable to change Admin Server log paths in Console
https://bugzilla.redhat.com/show_bug.cgi?id=368481
Resolves: bug 368481
Bug Description: Unable to change Admin Server log paths in Console
Fix Description: The console assumes that the attribute values read from
and written to the server will follow the same format, so the config.c
has been modified to accept the full path instead of just the file name.
The path will be validated to ensure that it is inside the server log
dir (ADMSERV_LOG_DIR). The return code of validate_logfile() has been
changed such that 0 indicates no error has occured.
Reviewed by: rmeggins (and pushed)
diff --git a/admserv/cgi-src40/config.c b/admserv/cgi-src40/config.c
index 886752f..8e04f88 100644
--- a/admserv/cgi-src40/config.c
+++ b/admserv/cgi-src40/config.c
@@ -541,7 +541,7 @@ int main(int argc, char *argv[])
/* Check if access log file is being changed */
if (strcasecmp(nameptr,"configuration.nsaccesslog") == 0) {
int rc = validate_logfile(logdir, valptr);
- if (rc == 2) {
+ if (rc == 1) {
/* report error */
psetDelete(pset);
if (i18nResource)
@@ -552,7 +552,7 @@ int main(int argc, char *argv[])
else PR_snprintf(error_info, sizeof(error_info), "%s log file name must be a valid file name and must not include the path. [%s] is invalid.",
"Access", nameptr);
rpt_err(APP_ERROR, error_info, NULL, NULL);
- } else if (rc == 0) {
+ } else if (rc == 2) {
/* report error */
psetDelete(pset);
if (i18nResource)
@@ -565,8 +565,8 @@ int main(int argc, char *argv[])
rpt_err(APP_ERROR, error_info, NULL, NULL);
}
else {
- char *pathline = PR_smprintf("%s/%s %s", logdir, valptr, "common");
- err = update_conf("console.conf", "CustomLog", pathline);
+ char *pathline = PR_smprintf("%s %s", valptr, "common");
+ err = update_conf("console.conf", "CustomLog", pathline);
PR_smprintf_free(pathline);
}
}
@@ -574,7 +574,7 @@ int main(int argc, char *argv[])
/* Check if error log file is being changed */
if (strcasecmp(nameptr,"configuration.nserrorlog") == 0) {
int rc = validate_logfile(logdir, valptr);
- if (rc == 2) {
+ if (rc == 1) {
/* report error */
psetDelete(pset);
if (i18nResource)
@@ -585,7 +585,7 @@ int main(int argc, char *argv[])
else PR_snprintf(error_info, sizeof(error_info), "%s log file name must be a valid file name and must not include the path. [%s] is invalid.",
"Error", nameptr);
rpt_err(APP_ERROR, error_info, NULL, NULL);
- } else if (rc == 0) {
+ } else if (rc == 2) {
/* report error */
psetDelete(pset);
if (i18nResource)
@@ -598,8 +598,7 @@ int main(int argc, char *argv[])
rpt_err(APP_ERROR, error_info, NULL, NULL);
}
else {
- char *newpath = PR_smprintf("%s/%s", logdir, valptr);
- err = update_conf("console.conf", "ErrorLog", newpath);
+ err = update_conf("console.conf", "ErrorLog", valptr);
}
}
@@ -1068,21 +1067,30 @@ static int validate_addr(char* ip) {
*/
static int validate_logfile(char *logdir, char *name) {
FILE *f;
- char *fullname;
+ char *filename;
+ int n;
- if (!name || !*name ||
- !util_is_valid_path_string(name)) {
- return 2; /* error */
+ if (!name || !*name) {
+ return 1; /* invalid path */
}
- fullname = PR_smprintf("%s/%s", logdir, name);
+ n = strlen(logdir);
- f = fopen(fullname, "a+");
- PR_smprintf_free(fullname);
- if (f != NULL) {
- fclose(f);
- return 1; /* ok*/
+ if (strncmp(logdir, name, n)) {
+ return 1; /* invalid path */
}
- return 0; /* error */
+ filename = &name[n+1];
+
+ if (!util_is_valid_path_string(filename)) {
+ return 1; /* invalid path */
+ }
+
+ f = fopen(name, "a+");
+ if (!f) {
+ return 2; /* can't open file */
+ }
+
+ fclose(f);
+ return 0; /* ok */
}
13 years, 11 months
Branch 'Directory_Server_8_2_Branch' - admserv/cgi-src40
by Richard Allen Megginson
admserv/cgi-src40/config.c | 46 ++++++++++++++++++++++++++-------------------
1 file changed, 27 insertions(+), 19 deletions(-)
New commits:
commit 05d5cf22730ba621fbc2b91f402787bb0f90a4c2
Author: Endi S. Dewata <edewata(a)redhat.com>
Date: Fri Apr 23 18:59:56 2010 -0500
Bug 368481 - Unable to change Admin Server log paths in Console
https://bugzilla.redhat.com/show_bug.cgi?id=368481
Resolves: bug 368481
Bug Description: Unable to change Admin Server log paths in Console
Fix Description: The console assumes that the attribute values read from
and written to the server will follow the same format, so the config.c
has been modified to accept the full path instead of just the file name.
The path will be validated to ensure that it is inside the server log
dir (ADMSERV_LOG_DIR). The return code of validate_logfile() has been
changed such that 0 indicates no error has occured.
Reviewed by: rmeggins (and pushed)
(cherry picked from commit 2d2a225b0a435e7f3199c4656ea2078b02cc6573)
diff --git a/admserv/cgi-src40/config.c b/admserv/cgi-src40/config.c
index 886752f..8e04f88 100644
--- a/admserv/cgi-src40/config.c
+++ b/admserv/cgi-src40/config.c
@@ -541,7 +541,7 @@ int main(int argc, char *argv[])
/* Check if access log file is being changed */
if (strcasecmp(nameptr,"configuration.nsaccesslog") == 0) {
int rc = validate_logfile(logdir, valptr);
- if (rc == 2) {
+ if (rc == 1) {
/* report error */
psetDelete(pset);
if (i18nResource)
@@ -552,7 +552,7 @@ int main(int argc, char *argv[])
else PR_snprintf(error_info, sizeof(error_info), "%s log file name must be a valid file name and must not include the path. [%s] is invalid.",
"Access", nameptr);
rpt_err(APP_ERROR, error_info, NULL, NULL);
- } else if (rc == 0) {
+ } else if (rc == 2) {
/* report error */
psetDelete(pset);
if (i18nResource)
@@ -565,8 +565,8 @@ int main(int argc, char *argv[])
rpt_err(APP_ERROR, error_info, NULL, NULL);
}
else {
- char *pathline = PR_smprintf("%s/%s %s", logdir, valptr, "common");
- err = update_conf("console.conf", "CustomLog", pathline);
+ char *pathline = PR_smprintf("%s %s", valptr, "common");
+ err = update_conf("console.conf", "CustomLog", pathline);
PR_smprintf_free(pathline);
}
}
@@ -574,7 +574,7 @@ int main(int argc, char *argv[])
/* Check if error log file is being changed */
if (strcasecmp(nameptr,"configuration.nserrorlog") == 0) {
int rc = validate_logfile(logdir, valptr);
- if (rc == 2) {
+ if (rc == 1) {
/* report error */
psetDelete(pset);
if (i18nResource)
@@ -585,7 +585,7 @@ int main(int argc, char *argv[])
else PR_snprintf(error_info, sizeof(error_info), "%s log file name must be a valid file name and must not include the path. [%s] is invalid.",
"Error", nameptr);
rpt_err(APP_ERROR, error_info, NULL, NULL);
- } else if (rc == 0) {
+ } else if (rc == 2) {
/* report error */
psetDelete(pset);
if (i18nResource)
@@ -598,8 +598,7 @@ int main(int argc, char *argv[])
rpt_err(APP_ERROR, error_info, NULL, NULL);
}
else {
- char *newpath = PR_smprintf("%s/%s", logdir, valptr);
- err = update_conf("console.conf", "ErrorLog", newpath);
+ err = update_conf("console.conf", "ErrorLog", valptr);
}
}
@@ -1068,21 +1067,30 @@ static int validate_addr(char* ip) {
*/
static int validate_logfile(char *logdir, char *name) {
FILE *f;
- char *fullname;
+ char *filename;
+ int n;
- if (!name || !*name ||
- !util_is_valid_path_string(name)) {
- return 2; /* error */
+ if (!name || !*name) {
+ return 1; /* invalid path */
}
- fullname = PR_smprintf("%s/%s", logdir, name);
+ n = strlen(logdir);
- f = fopen(fullname, "a+");
- PR_smprintf_free(fullname);
- if (f != NULL) {
- fclose(f);
- return 1; /* ok*/
+ if (strncmp(logdir, name, n)) {
+ return 1; /* invalid path */
}
- return 0; /* error */
+ filename = &name[n+1];
+
+ if (!util_is_valid_path_string(filename)) {
+ return 1; /* invalid path */
+ }
+
+ f = fopen(name, "a+");
+ if (!f) {
+ return 2; /* can't open file */
+ }
+
+ fclose(f);
+ return 0; /* ok */
}
13 years, 11 months
Branch 'Directory_Server_8_2_Branch' - ldap/admin
by Richard Allen Megginson
ldap/admin/src/scripts/DSCreate.pm.in | 3 +++
ldap/admin/src/scripts/DSDialogs.pm | 4 ++--
ldap/admin/src/scripts/setup-ds.res.in | 2 ++
3 files changed, 7 insertions(+), 2 deletions(-)
New commits:
commit 6fa876657c99509d770876b7c7c25dbebc8ebe53
Author: Endi S. Dewata <edewata(a)redhat.com>
Date: Fri Apr 16 11:26:32 2010 -0500
Bug 542570 - Directory Server port number is not validated in the beginning.
https://bugzilla.redhat.com/show_bug.cgi?id=542570
Resolves: bug 542570
Bug Description: Directory Server port number is not validated in the beginning.
Fix Description: The code has been modified to validate the port value from the
beginning of the string to the end to ensure that it only contains digits and to
generate the appropriate error message.
Reviewed by: rmeggins (and pushed)
(cherry picked from commit a7b2cdc8c3ee5fcc23155d791cafc48f554008f2)
diff --git a/ldap/admin/src/scripts/DSCreate.pm.in b/ldap/admin/src/scripts/DSCreate.pm.in
index e04f1cd..86a8b0f 100644
--- a/ldap/admin/src/scripts/DSCreate.pm.in
+++ b/ldap/admin/src/scripts/DSCreate.pm.in
@@ -82,6 +82,9 @@ sub checkPort {
}
}
+ if ($inf->{slapd}->{ServerPort} !~ /^\d+$/) {
+ return ('error_port_invalid', $inf->{slapd}->{ServerPort});
+ }
if (!portAvailable($inf->{slapd}->{ServerPort})) {
return ('error_port_available', $inf->{slapd}->{ServerPort}, $!);
}
diff --git a/ldap/admin/src/scripts/DSDialogs.pm b/ldap/admin/src/scripts/DSDialogs.pm
index 6583ff9..60bc115 100644
--- a/ldap/admin/src/scripts/DSDialogs.pm
+++ b/ldap/admin/src/scripts/DSDialogs.pm
@@ -64,8 +64,8 @@ my $dsport = new Dialog (
my $self = shift;
my $ans = shift;
my $res = $DialogManager::SAME;
- if ($ans !~ /\d+/) {
- $self->{manager}->alert("dialog_dsport_error", $ans);
+ if ($ans !~ /^\d+$/) {
+ $self->{manager}->alert("dialog_dsport_invalid", $ans);
} elsif (!portAvailable($ans)) {
$self->{manager}->alert("dialog_dsport_error", $ans);
} else {
diff --git a/ldap/admin/src/scripts/setup-ds.res.in b/ldap/admin/src/scripts/setup-ds.res.in
index b18a2ae..b0d88c2 100644
--- a/ldap/admin/src/scripts/setup-ds.res.in
+++ b/ldap/admin/src/scripts/setup-ds.res.in
@@ -55,6 +55,7 @@ dialog_ssgroup_no_user = The system user '%s' does not belong to the group '%s'.
dialog_dsport_text = The standard directory server network port number is 389. However, if\nyou are not logged as the superuser, or port 389 is in use, the\ndefault value will be a random unused port number greater than 1024.\nIf you want to use port 389, make sure that you are logged in as the\nsuperuser, that port 389 is not in use.\n\n
dialog_dsport_prompt = Directory server network port
dialog_dsport_error = The port %s is in use or not available. Please choose another port.\n\n
+dialog_dsport_invalid = The port %s is not a valid port. Please choose a valid port.\n\n
# ----------- DS server ID Dialog Resource ----------------
dialog_dsserverid_text = Each instance of a directory server requires a unique identifier.\nThis identifier is used to name the various\ninstance specific files and directories in the file system,\nas well as for other uses as a server instance identifier.\n\n
@@ -103,6 +104,7 @@ error_adding_entry = Error adding entry '%s'. Error: %s\n
error_updating_entry = Error updating entry '%s'. Error: %s\n
error_invalid_param = The parameter '%s' has an invalid value '%s'.\n
+error_port_invalid = The port %s is not a valid port. Please choose a valid port.\n
error_port_available = The port number '%s' is not available for use. This may be due to an\
invalid port number, or the port already being in use by another\
program, or low port restriction. Please choose another value for\
13 years, 11 months
2 commits - ldap/admin ldap/servers
by Richard Allen Megginson
ldap/admin/src/scripts/DSCreate.pm.in | 3 +
ldap/admin/src/scripts/DSDialogs.pm | 4 -
ldap/admin/src/scripts/setup-ds.res.in | 2
ldap/servers/slapd/plugin.c | 82 +++++++++++++++++++++++++++------
ldap/servers/slapd/slap.h | 8 ++-
5 files changed, 81 insertions(+), 18 deletions(-)
New commits:
commit 1d7f7f52485922e9fa992de0e74ede1d44b81097
Author: Endi S. Dewata <edewata(a)redhat.com>
Date: Sat Apr 17 00:08:35 2010 -0500
Bug 145181 - Plugin target/bind subtrees only take 1 value.
https://bugzilla.redhat.com/show_bug.cgi?id=145181
Resolves: bug 145181
Bug Description: Plugin target/bind subtrees only take 1 value.
Fix Description: New attributes nsslapd-exclude-targetSubtree and
nsslapd-exclude-bindSubtree have been added to specify excluded subtrees.
The set_plugin_config_from_entry() has been modified to read multiple
subtrees. The plugin_invoke_plugin_sdn() and plugin_allow_internal_op()
have been modified to check for excluded subtrees.
Reviewed by: rmeggins (and pushed)
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 84dbcfe..658fcf4 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -1726,6 +1726,8 @@ set_plugin_config_from_entry(
{
struct pluginconfig *config = &plugin->plg_conf;
char *value = 0;
+ char **values = 0;
+ int i = 0;
int status = 0;
PRBool target_seen = PR_FALSE;
PRBool bind_seen = PR_FALSE;
@@ -1782,39 +1784,73 @@ set_plugin_config_from_entry(
slapi_ch_free((void**)&value);
}
- if ((value = slapi_entry_attr_get_charptr(plugin_entry,
- ATTR_PLUGIN_TARGET_SUBTREE)) != NULL)
+ values = slapi_entry_attr_get_charray(plugin_entry,
+ ATTR_PLUGIN_TARGET_SUBTREE);
+ for (i=0; values && values[i]; i++)
{
- if (plugin_set_subtree_config(&(config->plgc_target_subtrees), value))
+ if (plugin_set_subtree_config(&(config->plgc_target_subtrees), values[i]))
{
LDAPDebug(LDAP_DEBUG_PLUGIN, "Error: invalid value %s for attribute %s "
- "from entry %s\n", value, ATTR_PLUGIN_TARGET_SUBTREE,
+ "from entry %s\n", values[i], ATTR_PLUGIN_TARGET_SUBTREE,
slapi_entry_get_dn_const(plugin_entry));
status = 1;
+ break;
}
else
{
target_seen = PR_TRUE;
}
- slapi_ch_free((void**)&value);
}
+ slapi_ch_array_free(values);
- if ((value = slapi_entry_attr_get_charptr(plugin_entry,
- ATTR_PLUGIN_BIND_SUBTREE)) != NULL)
+ values = slapi_entry_attr_get_charray(plugin_entry,
+ ATTR_PLUGIN_EXCLUDE_TARGET_SUBTREE);
+ for (i=0; values && values[i]; i++)
+ {
+ if (plugin_set_subtree_config(&(config->plgc_excluded_target_subtrees), values[i]))
+ {
+ LDAPDebug(LDAP_DEBUG_PLUGIN, "Error: invalid value %s for attribute %s "
+ "from entry %s\n", values[i], ATTR_PLUGIN_EXCLUDE_TARGET_SUBTREE,
+ slapi_entry_get_dn_const(plugin_entry));
+ status = 1;
+ break;
+ }
+ }
+ slapi_ch_array_free(values);
+
+ values = slapi_entry_attr_get_charray(plugin_entry,
+ ATTR_PLUGIN_BIND_SUBTREE);
+ for (i=0; values && values[i]; i++)
{
- if (plugin_set_subtree_config(&(config->plgc_bind_subtrees), value))
+ if (plugin_set_subtree_config(&(config->plgc_bind_subtrees), values[i]))
{
LDAPDebug(LDAP_DEBUG_PLUGIN, "Error: invalid value %s for attribute %s "
- "from entry %s\n", value, ATTR_PLUGIN_BIND_SUBTREE,
+ "from entry %s\n", values[i], ATTR_PLUGIN_BIND_SUBTREE,
slapi_entry_get_dn_const(plugin_entry));
status = 1;
+ break;
}
else
{
bind_seen = PR_TRUE;
}
- slapi_ch_free((void**)&value);
}
+ slapi_ch_array_free(values);
+
+ values = slapi_entry_attr_get_charray(plugin_entry,
+ ATTR_PLUGIN_EXCLUDE_BIND_SUBTREE);
+ for (i=0; values && values[i]; i++)
+ {
+ if (plugin_set_subtree_config(&(config->plgc_excluded_bind_subtrees), values[i]))
+ {
+ LDAPDebug(LDAP_DEBUG_PLUGIN, "Error: invalid value %s for attribute %s "
+ "from entry %s\n", values[i], ATTR_PLUGIN_EXCLUDE_BIND_SUBTREE,
+ slapi_entry_get_dn_const(plugin_entry));
+ status = 1;
+ break;
+ }
+ }
+ slapi_ch_array_free(values);
/* set target subtree default - allow access to all data */
if (!target_seen)
@@ -2274,7 +2310,9 @@ plugin_config_init (struct pluginconfig *config)
PR_ASSERT (config);
ptd_init (&config->plgc_target_subtrees);
+ ptd_init (&config->plgc_excluded_target_subtrees);
ptd_init (&config->plgc_bind_subtrees);
+ ptd_init (&config->plgc_excluded_bind_subtrees);
config->plgc_schema_check = PLGC_ON;
config->plgc_invoke_for_replop = PLGC_ON;
/* currently, we leave it up to plugin, but don't actually tell plugins that they can choose.
@@ -2319,7 +2357,9 @@ plugin_config_cleanup (struct pluginconfig *config)
PR_ASSERT (config);
ptd_cleanup (&config->plgc_target_subtrees);
+ ptd_cleanup (&config->plgc_excluded_target_subtrees);
ptd_cleanup (&config->plgc_bind_subtrees);
+ ptd_cleanup (&config->plgc_excluded_bind_subtrees);
}
#if 0
@@ -2380,13 +2420,13 @@ PRBool
plugin_invoke_plugin_sdn (struct slapdplugin *plugin, int operation, Slapi_PBlock *pb, Slapi_DN *target_spec)
{
PluginTargetData *ptd;
+ PluginTargetData *excludedPtd;
struct pluginconfig *config;
Slapi_Backend *be;
int isroot;
PRBool islocal;
PRBool bindop;
unsigned long op;
- PRBool rc;
int method = -1;
PR_ASSERT (plugin);
@@ -2453,15 +2493,19 @@ plugin_invoke_plugin_sdn (struct slapdplugin *plugin, int operation, Slapi_PBloc
if (bindop)
{
ptd = &(config->plgc_bind_subtrees);
+ excludedPtd = &(config->plgc_excluded_bind_subtrees);
}
else
{
ptd = &(config->plgc_target_subtrees);
+ excludedPtd = &(config->plgc_excluded_target_subtrees);
}
- rc = plugin_matches_operation (target_spec, ptd, bindop, isroot, islocal, method);
+ if (plugin_matches_operation (target_spec, excludedPtd, bindop, isroot, islocal, method) == PR_TRUE) {
+ return PR_FALSE;
+ }
- return rc;
+ return plugin_matches_operation (target_spec, ptd, bindop, isroot, islocal, method);
}
/* this interface is exposed to be used by internal operations.
@@ -2528,6 +2572,9 @@ PRBool plugin_allow_internal_op (Slapi_DN *target_spec, struct slapdplugin *plug
Slapi_Backend *be;
int islocal;
+ if (plugin_is_global (&config->plgc_excluded_target_subtrees))
+ return PR_FALSE;
+
if (plugin_is_global (&config->plgc_target_subtrees))
return PR_TRUE;
@@ -2545,7 +2592,14 @@ PRBool plugin_allow_internal_op (Slapi_DN *target_spec, struct slapdplugin *plug
} else {
islocal = be != defbackend_get_backend();
}
- /* SIMPLE auth method sends us through original code path in plugin_mathches_operation */
+
+ /* SIMPLE auth method sends us through original code path in plugin_mathches_operation */
+
+ if (plugin_matches_operation (target_spec, &config->plgc_excluded_target_subtrees,
+ PR_FALSE, PR_FALSE, islocal, LDAP_AUTH_SIMPLE) == PR_TRUE) {
+ return PR_FALSE;
+ }
+
return plugin_matches_operation (target_spec, &config->plgc_target_subtrees,
PR_FALSE, PR_FALSE, islocal, LDAP_AUTH_SIMPLE);
}
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index aa5a88b..ba550c7 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -707,7 +707,9 @@ struct matchingRuleList {
#define ATTR_PLUGIN_LOG_ACCESS "nsslapd-logAccess"
#define ATTR_PLUGIN_LOG_AUDIT "nsslapd-logAudit"
#define ATTR_PLUGIN_TARGET_SUBTREE "nsslapd-targetSubtree"
+#define ATTR_PLUGIN_EXCLUDE_TARGET_SUBTREE "nsslapd-exclude-targetSubtree"
#define ATTR_PLUGIN_BIND_SUBTREE "nsslapd-bindSubtree"
+#define ATTR_PLUGIN_EXCLUDE_BIND_SUBTREE "nsslapd-exclude-bindSubtree"
#define ATTR_PLUGIN_INVOKE_FOR_REPLOP "nsslapd-invokeForReplOp"
#define ATTR_PLUGIN_LOAD_NOW "nsslapd-pluginLoadNow"
#define ATTR_PLUGIN_LOAD_GLOBAL "nsslapd-pluginLoadGlobal"
@@ -752,8 +754,10 @@ typedef struct target_data
}PluginTargetData;
struct pluginconfig{
- PluginTargetData plgc_target_subtrees; /* list of subtrees accessible by the plugin */
- PluginTargetData plgc_bind_subtrees; /* the list of subtrees for which plugin in invoked during bind operation */
+ PluginTargetData plgc_target_subtrees; /* list of subtrees accessible by the plugin */
+ PluginTargetData plgc_excluded_target_subtrees; /* list of subtrees inaccessible by the plugin */
+ PluginTargetData plgc_bind_subtrees; /* the list of subtrees for which plugin is invoked during bind operation */
+ PluginTargetData plgc_excluded_bind_subtrees; /* the list of subtrees for which plugin is not invoked during bind operation */
PRBool plgc_schema_check; /* inidcates whether schema check is performed during internal op */
PRBool plgc_log_change; /* indicates whether changes are logged during internal op */
PRBool plgc_log_access; /* indicates whether internal op is recorded in access log */
commit a7b2cdc8c3ee5fcc23155d791cafc48f554008f2
Author: Endi S. Dewata <edewata(a)redhat.com>
Date: Fri Apr 16 11:26:32 2010 -0500
Bug 542570 - Directory Server port number is not validated in the beginning.
https://bugzilla.redhat.com/show_bug.cgi?id=542570
Resolves: bug 542570
Bug Description: Directory Server port number is not validated in the beginning.
Fix Description: The code has been modified to validate the port value from the
beginning of the string to the end to ensure that it only contains digits and to
generate the appropriate error message.
Reviewed by: rmeggins (and pushed)
diff --git a/ldap/admin/src/scripts/DSCreate.pm.in b/ldap/admin/src/scripts/DSCreate.pm.in
index dcd55af..a156f10 100644
--- a/ldap/admin/src/scripts/DSCreate.pm.in
+++ b/ldap/admin/src/scripts/DSCreate.pm.in
@@ -82,6 +82,9 @@ sub checkPort {
}
}
+ if ($inf->{slapd}->{ServerPort} !~ /^\d+$/) {
+ return ('error_port_invalid', $inf->{slapd}->{ServerPort});
+ }
if (!portAvailable($inf->{slapd}->{ServerPort})) {
return ('error_port_available', $inf->{slapd}->{ServerPort}, $!);
}
diff --git a/ldap/admin/src/scripts/DSDialogs.pm b/ldap/admin/src/scripts/DSDialogs.pm
index 6583ff9..60bc115 100644
--- a/ldap/admin/src/scripts/DSDialogs.pm
+++ b/ldap/admin/src/scripts/DSDialogs.pm
@@ -64,8 +64,8 @@ my $dsport = new Dialog (
my $self = shift;
my $ans = shift;
my $res = $DialogManager::SAME;
- if ($ans !~ /\d+/) {
- $self->{manager}->alert("dialog_dsport_error", $ans);
+ if ($ans !~ /^\d+$/) {
+ $self->{manager}->alert("dialog_dsport_invalid", $ans);
} elsif (!portAvailable($ans)) {
$self->{manager}->alert("dialog_dsport_error", $ans);
} else {
diff --git a/ldap/admin/src/scripts/setup-ds.res.in b/ldap/admin/src/scripts/setup-ds.res.in
index af9080d..ca7b6e7 100644
--- a/ldap/admin/src/scripts/setup-ds.res.in
+++ b/ldap/admin/src/scripts/setup-ds.res.in
@@ -55,6 +55,7 @@ dialog_ssgroup_no_user = The system user '%s' does not belong to the group '%s'.
dialog_dsport_text = The standard directory server network port number is 389. However, if\nyou are not logged as the superuser, or port 389 is in use, the\ndefault value will be a random unused port number greater than 1024.\nIf you want to use port 389, make sure that you are logged in as the\nsuperuser, that port 389 is not in use.\n\n
dialog_dsport_prompt = Directory server network port
dialog_dsport_error = The port %s is in use or not available. Please choose another port.\n\n
+dialog_dsport_invalid = The port %s is not a valid port. Please choose a valid port.\n\n
# ----------- DS server ID Dialog Resource ----------------
dialog_dsserverid_text = Each instance of a directory server requires a unique identifier.\nThis identifier is used to name the various\ninstance specific files and directories in the file system,\nas well as for other uses as a server instance identifier.\n\n
@@ -103,6 +104,7 @@ error_adding_entry = Error adding entry '%s'. Error: %s\n
error_updating_entry = Error updating entry '%s'. Error: %s\n
error_invalid_param = The parameter '%s' has an invalid value '%s'.\n
+error_port_invalid = The port %s is not a valid port. Please choose a valid port.\n
error_port_available = The port number '%s' is not available for use. This may be due to an\
invalid port number, or the port already being in use by another\
program, or low port restriction. Please choose another value for\
13 years, 11 months
ldap/admin ldap/schema ldap/servers
by Noriko Hosoi
ldap/admin/src/scripts/Migration.pm.in | 2
ldap/admin/src/scripts/Setup.pm.in | 2
ldap/schema/01core389.ldif | 2
ldap/schema/02common.ldif | 3
ldap/schema/30ns-common.ldif | 4
ldap/servers/plugins/acl/acl.c | 56 -
ldap/servers/plugins/acl/acl.h | 7
ldap/servers/plugins/acl/acl_ext.c | 2
ldap/servers/plugins/acl/aclanom.c | 1
ldap/servers/plugins/acl/acleffectiverights.c | 47
ldap/servers/plugins/acl/acllas.c | 201 +++-
ldap/servers/plugins/acl/aclparse.c | 386 ++++---
ldap/servers/plugins/acl/aclproxy.c | 17
ldap/servers/plugins/acl/aclutil.c | 66 +
ldap/servers/plugins/chainingdb/cb_config.c | 10
ldap/servers/plugins/chainingdb/cb_init.c | 4
ldap/servers/plugins/chainingdb/cb_instance.c | 8
ldap/servers/plugins/cos/cos_cache.c | 127 ++
ldap/servers/plugins/dna/dna.c | 53 -
ldap/servers/plugins/linkedattrs/fixup_task.c | 4
ldap/servers/plugins/mep/mep.c | 4
ldap/servers/plugins/pwdstorage/smd5_pwd.c | 4
ldap/servers/plugins/referint/referint.c | 37
ldap/servers/plugins/replication/legacy_consumer.c | 1
ldap/servers/plugins/replication/repl5.h | 2
ldap/servers/plugins/replication/repl5_agmt.c | 19
ldap/servers/plugins/replication/repl5_agmtlist.c | 3
ldap/servers/plugins/replication/repl5_protocol.c | 1
ldap/servers/plugins/replication/repl5_replica.c | 27
ldap/servers/plugins/replication/repl5_replica_config.c | 1
ldap/servers/plugins/replication/repl_init.c | 1
ldap/servers/plugins/retrocl/retrocl.c | 1
ldap/servers/plugins/retrocl/retrocl_create.c | 13
ldap/servers/plugins/syntaxes/string.c | 166 ++-
ldap/servers/plugins/syntaxes/syntax.h | 1
ldap/servers/plugins/syntaxes/validate.c | 12
ldap/servers/plugins/syntaxes/value.c | 90 +
ldap/servers/plugins/usn/usn_cleanup.c | 11
ldap/servers/slapd/add.c | 53 -
ldap/servers/slapd/attrlist.c | 6
ldap/servers/slapd/attrsyntax.c | 17
ldap/servers/slapd/auth.c | 50 -
ldap/servers/slapd/back-ldbm/import-threads.c | 1
ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c | 19
ldap/servers/slapd/back-ldbm/ldbm_config.c | 90 +
ldap/servers/slapd/back-ldbm/ldbm_index_config.c | 50 -
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 167 ++-
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 7
ldap/servers/slapd/back-ldbm/ldbm_search.c | 1
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 1
ldap/servers/slapd/back-ldbm/misc.c | 4
ldap/servers/slapd/back-ldbm/nextid.c | 2
ldap/servers/slapd/back-ldbm/vlv.c | 78 +
ldap/servers/slapd/backend.c | 28
ldap/servers/slapd/backend_manager.c | 6
ldap/servers/slapd/bind.c | 34
ldap/servers/slapd/compare.c | 31
ldap/servers/slapd/delete.c | 31
ldap/servers/slapd/dn.c | 791 ++++++++++++++--
ldap/servers/slapd/entry.c | 254 ++++-
ldap/servers/slapd/entrywsi.c | 9
ldap/servers/slapd/extendop.c | 37
ldap/servers/slapd/fedse.c | 1
ldap/servers/slapd/libglobs.c | 11
ldap/servers/slapd/main.c | 4
ldap/servers/slapd/mapping_tree.c | 89 +
ldap/servers/slapd/modify.c | 35
ldap/servers/slapd/modrdn.c | 108 ++
ldap/servers/slapd/modutil.c | 30
ldap/servers/slapd/passwd_extop.c | 35
ldap/servers/slapd/plugin.c | 26
ldap/servers/slapd/plugin_syntax.c | 2
ldap/servers/slapd/search.c | 35
ldap/servers/slapd/slap.h | 4
ldap/servers/slapd/slapi-plugin.h | 67 +
ldap/servers/slapd/slapi-private.h | 2
ldap/servers/slapd/snmp_collator.c | 3
ldap/servers/slapd/task.c | 50 -
ldap/servers/slapd/tools/dbscan.c | 2
ldap/servers/slapd/tools/ldclt/ldclt.h | 1
ldap/servers/slapd/util.c | 98 +
ldap/servers/slapd/value.c | 26
ldap/servers/slapd/valueset.c | 14
83 files changed, 3023 insertions(+), 783 deletions(-)
New commits:
commit 78c50664d6421cc5d0836bb03820680dc2cb7acf
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Mon Apr 26 11:03:52 2010 -0700
Update to New DN Format
Fix Description:
. adding slapi_dn_normalize_ext and its siblings to normalize/validate
invalid DNs; deprecating slapi_dn_normalize and its siblings. (dn.c)
. replacing slapi_dn_normalize with new corresponding functions.
. normalizing hardcoded DNs (e.g., removing spaces around ',')
. setting correct DN syntax to nsslapd-suffix, nsslapd-ldapiautodnsuffix,
costemplatedn, nsslapd-changelogsuffix, nsBaseDN, nsBindDN
. if nsslapd-dn-validate-strict is enabled, incoming DN is examined and
rejected if it is invalid. Once approved, the DN is normalized.
. fixing compiler warnings and typos.
See also:
http://directory.fedoraproject.org/wiki/Upgrade_to_New_DN_Format
Related bugs:
Bug 199923 - subtree search fails to find items under a db containing special
characters
Bug 567968 - subtree/user level password policy created using 389-ds-console
doesn't work.
Bug 570107 - The import of LDIFs with base-64 encoded DNs fails, modrdn with
non-ASCII new rdn incorrect
Bug 570962 - ns-inactivate.pl does not work
Bug 572785 - DN syntax: old style of DN <type>="<DN>",<the_rest> is not
correctly normalized
Bug 573060 - DN normalizer: ESC HEX HEX is not normalized
Bug 574167 - An escaped space at the end of the RDN value is not handled
correctly
diff --git a/ldap/admin/src/scripts/Migration.pm.in b/ldap/admin/src/scripts/Migration.pm.in
index 44613a8..1942c8b 100644
--- a/ldap/admin/src/scripts/Migration.pm.in
+++ b/ldap/admin/src/scripts/Migration.pm.in
@@ -125,7 +125,7 @@ You can supply default .inf data in this format:
e.g.
General.FullMachineName=foo.example.com
or
- "slapd.Suffix=dc=example, dc=com"
+ "slapd.Suffix=dc=example,dc=com"
Values passed in this manner will override values in an .inf file
given with the -f argument.
diff --git a/ldap/admin/src/scripts/Setup.pm.in b/ldap/admin/src/scripts/Setup.pm.in
index 021a99c..52300db 100644
--- a/ldap/admin/src/scripts/Setup.pm.in
+++ b/ldap/admin/src/scripts/Setup.pm.in
@@ -110,7 +110,7 @@ You can supply default .inf data in this format:
e.g.
General.FullMachineName=foo.example.com
or
- "slapd.Suffix=dc=example, dc=com"
+ "slapd.Suffix=dc=example,dc=com"
Values passed in this manner will override values in an .inf file given with the -f argument.
EOF
}
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index af445e7..96e70a8 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -122,6 +122,8 @@ attributeTypes: ( nsSSLSupportedCiphers-oid NAME 'nsSSLSupportedCiphers' DESC 'N
attributeTypes: ( nsSSLToken-oid NAME 'nsSSLToken' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSLPersonalitySSL-oid NAME 'nsSSLPersonalitySSL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSLActivation-oid NAME 'nsSSLActivation' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2091 NAME 'nsslapd-suffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2092 NAME 'nsslapd-ldapiautodnsuffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
#
# objectclasses
#
diff --git a/ldap/schema/02common.ldif b/ldap/schema/02common.ldif
index 7ea5594..5269d3b 100644
--- a/ldap/schema/02common.ldif
+++ b/ldap/schema/02common.ldif
@@ -110,7 +110,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.223 NAME ( 'passwordResetFailureCount' '
attributeTypes: ( 2.16.840.1.113730.3.1.550 NAME 'cosAttribute' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.551 NAME 'cosspecifier' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.552 NAME 'costargettree' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.553 NAME 'costemplatedn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.553 NAME 'costemplatedn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.35 NAME 'changeLog' DESC 'the distinguished name of the entry which contains the set of entries comprising this servers changelog' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Changelog Internet Draft' )
attributeTypes: ( 2.16.840.1.113730.3.1.200 NAME 'changeLogMaximumAge' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.201 NAME 'changeLogMaximumSize' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
@@ -144,6 +144,7 @@ attributeTypes: ( 1.3.6.1.1.4 NAME 'vendorName' EQUALITY 1.3.6.1.4.1.1466.109.11
attributeTypes: ( 1.3.6.1.1.5 NAME 'vendorVersion' EQUALITY 1.3.6.1.4.1.1466.109.114.1 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation X-ORIGIN 'RFC 3045' )
attributeTypes: ( 2.16.840.1.113730.3.1.3023 NAME 'nsViewFilter' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2063 NAME 'nsEncryptionAlgorithm' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2093 NAME 'nsslapd-changelogsuffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
#
# objectclasses:
#
diff --git a/ldap/schema/30ns-common.ldif b/ldap/schema/30ns-common.ldif
index a6b109d..cee5a07 100644
--- a/ldap/schema/30ns-common.ldif
+++ b/ldap/schema/30ns-common.ldif
@@ -42,8 +42,8 @@
#
dn: cn=schema
attributeTypes: ( nsServerID-oid NAME 'nsServerID' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
-attributeTypes: ( nsBaseDN-oid NAME 'nsBaseDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
-attributeTypes: ( nsBindDN-oid NAME 'nsBindDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
+attributeTypes: ( nsBaseDN-oid NAME 'nsBaseDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
+attributeTypes: ( nsBindDN-oid NAME 'nsBindDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
attributeTypes: ( nsBindPassword-oid NAME 'nsBindPassword' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsServerPort-oid NAME 'nsServerPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsServerAddress-oid NAME 'nsServerAddress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index aa22d56..715ad1e 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -358,8 +358,8 @@ acl_access_allowed(
if (oid && ((strcasecmp(oid, DN_SYNTAX_OID) == 0) ||
(strcasecmp(oid, NAMEANDOPTIONALUID_SYNTAX_OID) == 0))) {
/* should use slapi_sdn_compare() but that'a an extra malloc/free */
- char *dn_val_to_write = slapi_dn_normalize(slapi_ch_strdup(val->bv_val));
- if ( aclpb->aclpb_authorization_sdn &&
+ char *dn_val_to_write = slapi_create_dn_string("%s", val->bv_val);
+ if ( dn_val_to_write && aclpb->aclpb_authorization_sdn &&
slapi_utf8casecmp((ACLUCHP)dn_val_to_write, (ACLUCHP)
slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn)) == 0) {
access |= SLAPI_ACL_SELF;
@@ -754,9 +754,10 @@ static void print_access_control_summary( char *source, int ret_val, char *clien
if ( aclpb->aclpb_authorization_sdn != NULL ) {
- proxy_user = (char *)(aclpb->aclpb_authorization_sdn->ndn ?
- aclpb->aclpb_authorization_sdn->ndn:
- null_user);
+ proxy_user =
+ (char *)(slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn)?
+ slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn):
+ null_user);
slapi_log_error(loglevel, plugin_name,
"conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)"
@@ -1764,8 +1765,7 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
if (parent_DN == NULL) {
new_DN = new_RDN;
} else {
- new_DN = slapi_ch_smprintf("%s,%s", new_RDN, parent_DN);
- slapi_dn_normalize (new_DN);
+ new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
}
/* Change the acls */
@@ -2028,8 +2028,7 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
** We have a single ACI which we need to find if it applies to
** the resource or not.
*/
- if ((aci->aci_type & ACI_TARGET_DN) &&
- (aclpb->aclpb_curr_entry_sdn)) {
+ if ((aci->aci_type & ACI_TARGET_DN) && (aclpb->aclpb_curr_entry_sdn)) {
char *avaType;
struct berval *avaValue;
@@ -2246,10 +2245,10 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
*
*/
- if ((aclpb->aclpb_access & SLAPI_ACL_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS )||
- (aclpb->aclpb_access & SLAPI_ACL_DELETE &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS ) ) {
+ if (((aclpb->aclpb_access & SLAPI_ACL_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) )||
+ ((aclpb->aclpb_access & SLAPI_ACL_DELETE) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS) ) ) {
Targetattrfilter **attrFilterArray;
@@ -2367,10 +2366,10 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
goto acl__resource_match_aci_EXIT;
}
- } else if ( (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) ||
- (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS ) ) {
+ } else if ( ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) ||
+ ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)) ) {
/*
@@ -2381,28 +2380,28 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
* match that filter.
*
*
- */
+ */
Targetattrfilter **attrFilterArray = NULL;
Targetattrfilter *attrFilter;
int found = 0;
- if (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) {
+ if ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) {
- attrFilterArray = aci->targetAttrAddFilters;
+ attrFilterArray = aci->targetAttrAddFilters;
- } else if (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS) {
+ } else if ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)) {
- attrFilterArray = aci->targetAttrDelFilters;
+ attrFilterArray = aci->targetAttrDelFilters;
}
/*
* Scan this filter list for an applicable filter.
- */
+ */
found = 0;
num_attrs = 0;
@@ -2435,7 +2434,7 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
attr_matched= acl__test_filter(aclpb->aclpb_filter_test_entry,
attrFilter->filter,
1 /* Do filter sense evaluation below */
- );
+ );
slapi_entry_free( aclpb->aclpb_filter_test_entry );
}
@@ -2452,8 +2451,6 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
*/
attr_matched_in_targetattrfilters = 1;
-
-
}
} /* targetvaluefilters */
@@ -3233,9 +3230,6 @@ acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
realval = tmp;
}
- slapi_dn_normalize (realval);
-
-
/* What we have built is a regular pattaren expression.
** Now we will compile the pattern and compare wth the string to
** see if the input string matches with the patteren or not.
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index 36bdd43..3f4b4e6 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -119,7 +119,11 @@ static char* const aci_targetattr = "targetattr";
static char* const aci_targetattrfilters = "targattrfilters";
static char* const aci_targetfilter = "targetfilter";
+static char* const LDAP_URL_prefix_core = "ldap://";
+static char* const LDAPS_URL_prefix_core = "ldaps://";
+
static char* const LDAP_URL_prefix = "ldap:///";
+static char* const LDAPS_URL_prefix = "ldaps:///";
static char* const access_str_compare = "compare";
static char* const access_str_search = "search";
@@ -827,7 +831,7 @@ int acl_skip_access_check ( Slapi_PBlock *pb, Slapi_Entry *e );
int aclext_alloc_lockarray ();
-int aclutil_str_appened(char **str1, const char *str2);
+int aclutil_str_append(char **str1, const char *str2);
void aclutil_print_err (int rv , const Slapi_DN *sdn,
const struct berval* val, char **errbuf);
void aclutil_print_aci (aci_t *aci_item, char *type);
@@ -911,6 +915,7 @@ acl_replace_str(char * s, char *substr, char* replace_with);
int acl_strstr(char * s, char *substr);
int aclutil_evaluate_macro( char * rule, lasInfo *lasinfo,
acl_eval_types evalType );
+int aclutil_str_append_ext(char **dest, size_t *dlen, const char *src, size_t slen);
/* acl hash table functions */
void acl_ht_add_and_freeOld(acl_ht_t * acl_ht, PLHashNumber key,char *value);
diff --git a/ldap/servers/plugins/acl/acl_ext.c b/ldap/servers/plugins/acl/acl_ext.c
index 5e1d360..d9494ec 100644
--- a/ldap/servers/plugins/acl/acl_ext.c
+++ b/ldap/servers/plugins/acl/acl_ext.c
@@ -791,7 +791,7 @@ acl__done_aclpb ( struct acl_pblock *aclpb )
*/
/* Nothing needs to be cleaned up in this case */
- if ( !aclpb->aclpb_state & ACLPB_INITIALIZED)
+ if (!(aclpb->aclpb_state & ACLPB_INITIALIZED))
return;
/* Check the state */
diff --git a/ldap/servers/plugins/acl/aclanom.c b/ldap/servers/plugins/acl/aclanom.c
index 773dad2..b1d15ca 100644
--- a/ldap/servers/plugins/acl/aclanom.c
+++ b/ldap/servers/plugins/acl/aclanom.c
@@ -205,6 +205,7 @@ aclanom_gen_anomProfile (acl_lock_flag_t lock_flag)
/* see if this is a monitor acl */
if (( strcasecmp ( dn, "cn=monitor") == 0 ) ||
+ /* cn=monitor,cn=ldbm: No such object */
( strcasecmp ( dn, "cn=monitor,cn=ldbm") == 0 )) {
aci = acllist_get_next_aci ( NULL, aci, &cookie);
continue;
diff --git a/ldap/servers/plugins/acl/acleffectiverights.c b/ldap/servers/plugins/acl/acleffectiverights.c
index 9afac07..acf856c 100644
--- a/ldap/servers/plugins/acl/acleffectiverights.c
+++ b/ldap/servers/plugins/acl/acleffectiverights.c
@@ -170,7 +170,7 @@ _ger_g_permission_granted (
goto bailout;
}
- aclutil_str_appened ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
+ aclutil_str_append ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
slapi_log_error (SLAPI_LOG_ACL, plugin_name,
"_ger_g_permission_granted: %s\n", *errbuf);
rc = LDAP_INSUFFICIENT_ACCESS;
@@ -195,7 +195,10 @@ _ger_parse_control (
LDAPControl **requestcontrols;
struct berval *subjectber;
BerElement *ber;
- int subjectndnlen = 0;
+ size_t subjectndnlen = 0;
+ char *orig = NULL;
+ char *normed = NULL;
+ int rc = 0;
if (NULL == subjectndn)
{
@@ -215,7 +218,7 @@ _ger_parse_control (
if ( subjectber == NULL || subjectber->bv_val == NULL ||
subjectber->bv_len == 0 )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: missing subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: missing subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
return LDAP_INVALID_SYNTAX;
}
@@ -227,23 +230,23 @@ _ger_parse_control (
* or base64 encoding string. Hence users using -J option in
* ldapsearch don't have to do BER encoding for the subject.
*/
- *subjectndn = slapi_ch_malloc ( subjectber->bv_len + 1 );
- strncpy ( *subjectndn, subjectber->bv_val, subjectber->bv_len );
- *(*subjectndn + subjectber->bv_len) = '\0';
+ orig = slapi_ch_malloc ( subjectber->bv_len + 1 );
+ strncpy ( orig, subjectber->bv_val, subjectber->bv_len );
+ *(orig + subjectber->bv_len) = '\0';
}
else
{
ber = ber_init (subjectber);
if ( ber == NULL )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: ber_init failed for the subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: ber_init failed for the subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
return LDAP_OPERATIONS_ERROR;
}
/* "a" means to allocate storage as needed for octet string */
- if ( ber_scanf (ber, "a", subjectndn) == LBER_ERROR )
+ if ( ber_scanf (ber, "a", orig) == LBER_ERROR )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: invalid ber tag in the subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: invalid ber tag in the subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
ber_free ( ber, 1 );
return LDAP_INVALID_SYNTAX;
@@ -256,18 +259,32 @@ _ger_parse_control (
* (see section 9 of RFC 2829) only. It also only supports the "dnAuthzId"
* flavor, which looks like "dn:<DN>" where null <DN> is for anonymous.
*/
- subjectndnlen = strlen(*subjectndn);
- if ( NULL == *subjectndn || subjectndnlen < 3 ||
- strncasecmp ( "dn:", *subjectndn, 3 ) != 0 )
+ subjectndnlen = strlen(orig);
+ if ( NULL == orig || subjectndnlen < 3 || strncasecmp ( "dn:", orig, 3 ) != 0 )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
+ aclutil_str_append ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
+ slapi_ch_free_string(&orig);
return LDAP_INVALID_SYNTAX;
}
/* memmove is safe for overlapping copy */
- memmove ( *subjectndn, *subjectndn + 3, subjectndnlen - 2);/* 1 for '\0' */
- slapi_dn_normalize ( *subjectndn );
+ rc = slapi_dn_normalize_ext(orig + 3, 0, &normed, &subjectndnlen);
+ if (rc < 0) {
+ aclutil_str_append ( errbuf, "get-effective-rights: failed to normalize dn: ");
+ aclutil_str_append ( errbuf, orig);
+ slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
+ slapi_ch_free_string(&orig);
+ return LDAP_INVALID_SYNTAX;
+ }
+ if (rc == 0) { /* orig+3 is passed in; not terminated */
+ *(normed + subjectndnlen) = '\0';
+ *subjectndn = slapi_ch_strdup(normed);
+ slapi_ch_free_string(&orig);
+ } else {
+ slapi_ch_free_string(&orig);
+ *subjectndn = normed;
+ }
return LDAP_SUCCESS;
}
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
index 9a57d7c..9fbd25b 100644
--- a/ldap/servers/plugins/acl/acllas.c
+++ b/ldap/servers/plugins/acl/acllas.c
@@ -480,6 +480,7 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
int rc;
short len;
const size_t LDAP_URL_prefix_len = strlen(LDAP_URL_prefix);
+ const size_t LDAPS_URL_prefix_len = strlen(LDAPS_URL_prefix);
lasInfo lasinfo;
int got_undefined = 0;
@@ -530,15 +531,15 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
** userdn = "ldap:///DN1 || ldap:///DN2"
*/
-
/* The DN is now "ldap:///DN"
** remove the "ldap:///" part
*/
- if (strncasecmp (user, LDAP_URL_prefix,
- LDAP_URL_prefix_len) == 0) {
+ if (strncasecmp (user, LDAP_URL_prefix, LDAP_URL_prefix_len) == 0) {
s_user = user;
user += LDAP_URL_prefix_len;
-
+ } else if (strncasecmp (user, LDAPS_URL_prefix, LDAPS_URL_prefix_len) == 0) {
+ s_user = user;
+ user += LDAPS_URL_prefix_len;
} else {
char ebuf[ BUFSIZ ];
slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
@@ -677,8 +678,19 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
slapi_filter_free(f,1);
} else {
/* Must be a simple dn then */
- if (slapi_utf8casecmp((ACLUCHP)lasinfo.clientDn,
- (ACLUCHP)slapi_dn_normalize(user)) == 0) {
+ char *normed = NULL;
+ size_t dnlen = 0;
+ rc = slapi_dn_normalize_ext(user, 0, &normed, &dnlen);
+ if (rc == 0) { /* user passed in; not terminated */
+ *(normed + dnlen) = '\0';
+ } else if (rc < 0) { /* normalization failed, user the original */
+ normed = user;
+ }
+ rc = slapi_utf8casecmp((ACLUCHP)lasinfo.clientDn, (ACLUCHP)normed);
+ if (normed != user) {
+ slapi_ch_free_string(&normed);
+ }
+ if (0 == rc) {
matched = ACL_TRUE;
break;
}
@@ -1274,8 +1286,14 @@ DS_LASUserDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
while ( j != -1 ) {
attrVal = slapi_value_get_berval ( sval );
/* Here if atleast 1 value matches then we are done.*/
- val = slapi_dn_normalize (
- slapi_ch_strdup( attrVal->bv_val));
+ val = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == val) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASUserDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ slapi_ch_free ( (void**) &s_attrName);
+ return LAS_EVAL_FAIL;
+ }
if (slapi_utf8casecmp((ACLUCHP)val, (ACLUCHP)lasinfo.clientDn ) == 0) {
char ebuf [ BUFSIZ ];
@@ -2380,7 +2398,13 @@ acllas__handle_group_entry (Slapi_Entry* e, void *callback_data)
while ( i != -1 ) {
struct member_info *groupMember = NULL;
attrVal = slapi_value_get_berval ( sval );
- n_dn = slapi_dn_normalize ( slapi_ch_strdup( attrVal->bv_val ));
+ n_dn = slapi_create_dn_string( attrVal->bv_val );
+ if (NULL == n_dn) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__handle_group_entry: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
n = ++info->lu_idx;
if (n < 0) {
slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
@@ -2433,7 +2457,14 @@ acllas__handle_group_entry (Slapi_Entry* e, void *callback_data)
*/
if (strncasecmp( attrVal->bv_val, "ldap://",7) == 0 ||
strncasecmp( attrVal->bv_val, "ldaps://",8) == 0) {
- savURL = memberURL = slapi_ch_strdup ( attrVal->bv_val);
+ savURL = memberURL =
+ slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == savURL) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__handle_group_entry: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
slapi_log_error( SLAPI_LOG_ACL, plugin_name,
"ACL Group Eval:MemberURL:%s\n", memberURL);
info->result = acllas__client_match_URL (
@@ -2656,8 +2687,13 @@ DS_LASGroupDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
attr_i= slapi_attr_first_value ( attr,&sval );
while ( attr_i != -1 ) {
attrVal = slapi_value_get_berval ( sval );
- n_groupdn = slapi_dn_normalize(
- slapi_ch_strdup( attrVal->bv_val));
+ n_groupdn = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_groupdn) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASGroupDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
matched = acllas__user_ismember_of_group (
lasinfo.aclpb, n_groupdn, lasinfo.clientDn,
ACLLAS_CACHE_MEMBER_GROUPS,
@@ -2855,6 +2891,7 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
char *curMemberDn;
int Done = 0;
int ngr, tt;
+ char *normed = NULL;
/* Add the scope to the list of scopes */
if (aclpb->aclpb_numof_bases >= (aclpb->aclpb_grpsearchbase_size-1)) {
@@ -2866,9 +2903,15 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
sizeof (char *));
aclpb->aclpb_grpsearchbase_size += ACLPB_INCR_BASES;
}
- aclpb->aclpb_grpsearchbase[aclpb->aclpb_numof_bases++] =
- slapi_dn_normalize(slapi_ch_strdup(base));
-
+ normed = slapi_create_dn_string("%s", base);
+ if (NULL == normed) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__eval_memberGroupDnAttr: Invalid syntax: %s\n",
+ base );
+ slapi_ch_free ( (void **)&s_str );
+ return ACL_FALSE;
+ }
+ aclpb->aclpb_grpsearchbase[aclpb->aclpb_numof_bases++] = normed;
/* Set up info to do a search */
attrs[0] = type_member;
attrs[1] = type_uniquemember;
@@ -2991,8 +3034,14 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
while ( k != -1 ) {
char *n_attrval;
attrVal = slapi_value_get_berval ( sval );
- n_attrval = slapi_ch_strdup( attrVal->bv_val);
- n_attrval = slapi_dn_normalize (n_attrval);
+ n_attrval = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_attrval) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__eval_memberGroupDnAttr: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ slapi_ch_free ( (void **)&s_str );
+ return ACL_FALSE;
+ }
/* We support: The attribute value can be a USER or a GROUP.
** Let's compare with the client, thi might be just an user. If it is not
@@ -3147,7 +3196,13 @@ acllas__verify_client (Slapi_Entry* e, void *callback_data)
i = slapi_attr_first_value ( attr,&sval );
while ( i != -1 ) {
attrVal = slapi_value_get_berval ( sval );
- val = slapi_dn_normalize(slapi_ch_strdup(attrVal->bv_val));
+ val = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == val) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__verify_client: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
if (slapi_utf8casecmp((ACLUCHP)val, (ACLUCHP)info->clientdn ) == 0) {
info->result = 1;
@@ -3235,7 +3290,12 @@ acllas__get_members (Slapi_Entry* e, void *callback_data)
i = slapi_attr_first_value ( attr,&sval );
while ( i != -1 ) {
attrVal =slapi_value_get_berval ( sval );
- info->member[i] = slapi_dn_normalize ( slapi_ch_strdup(attrVal->bv_val));
+ info->member[i] = slapi_create_dn_string ("%s", attrVal->bv_val);
+ if (NULL == info->member[i]) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__get_members: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ }
i = slapi_attr_next_value ( attr, i, &sval );
}
return 0;
@@ -3426,7 +3486,17 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
LDAPURLDesc *ludp;
int rc;
Slapi_Filter *f = NULL;
-
+ char *rawdn = NULL;
+ char *dn = NULL;
+ size_t dnlen = 0;
+ char *p = NULL;
+ char *normed = NULL;
+ /* ldap(s)://host:port/suffix?attrs?scope?filter */
+ const size_t LDAP_URL_prefix_len = strlen(LDAP_URL_prefix_core);
+ const size_t LDAPS_URL_prefix_len = strlen(LDAPS_URL_prefix_core);
+ size_t prefix_len = 0;
+ char Q = '?';
+ char *hostport = NULL;
/* Get the client's entry if we don't have already */
if ( aclpb && ( NULL == aclpb->aclpb_client_entry )) {
@@ -3459,23 +3529,83 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
}
if ( NULL == aclpb->aclpb_client_entry ) {
- slapi_log_error ( SLAPI_LOG_ACL, plugin_name,
- "DS_LASUserAttrEval: Unable to get client's entry\n");
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: Unable to get client's entry\n");
return ACL_FALSE;
}
- if (( rc = ldap_url_parse( url, &ludp)) != 0 ) {
+ /* DN potion of URL must be normalized before calling ldap_url_parse.
+ * lud_dn is pointing at the middle of lud_string.
+ * lud_dn won't be freed in ldap_free_urldesc.
+ */
+ /* remove the "ldap{s}:///" part */
+ if (strncasecmp (url, LDAP_URL_prefix, LDAP_URL_prefix_len) == 0) {
+ prefix_len = LDAP_URL_prefix_len;
+ } else if (strncasecmp (url, LDAPS_URL_prefix, LDAPS_URL_prefix_len) == 0) {
+ prefix_len = LDAPS_URL_prefix_len;
+ } else {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: url %s does not include ldap prefix: %s\n", url);
+ return ACL_FALSE;
+ }
+ rawdn = url + prefix_len; /* ldap(s)://host:port/... or ldap(s):///... */
+ /* rawdn at ^ or ^ */
+ /* let rawdn point the suffix */
+ if ('/' == *(rawdn+1)) { /* ldap(s):/// */
+ rawdn += 2;
+ hostport = "/";
+ } else {
+ char *tmpp = rawdn;
+ rawdn = strchr(tmpp, '/');
+ size_t hostport_len = 0;
+ if (NULL == rawdn) {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: url %s does not include correct ldap prefix: %s\n", url);
+ return ACL_FALSE;
+ }
+ hostport_len = ++rawdn - tmpp; /* ldap(s)://host:port/... */
+ /* <--------> */
+ hostport = (char *)slapi_ch_malloc(hostport_len + 1);
+ memcpy(hostport, tmpp, hostport_len);
+ *(hostport+hostport_len) = '\0';
+ }
+ p = strchr(rawdn, Q);
+ if (p) {
+ /* url has scope and/or filter: ldap(s):///suffix?attr?scope?filter */
+ *p = '\0';
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__client_match_URL: Invalid syntax: %s\n", url);
+ return ACL_FALSE;
+ } else if (rc == 0) { /* url is passed in and not terminated with NULL*/
+ *(dn + dnlen) = '\0';
+ }
+ if (p) {
+ *p = Q;
+ }
+ normed = slapi_ch_smprintf("%s%s%s%s",
+ (prefix_len==LDAP_URL_prefix_len)?
+ LDAP_URL_prefix_core:LDAPS_URL_prefix_core,
+ hostport, dn, p?p:"");
+ if (rc > 0) {
+ /* dn was allocated in slapi_dn_normalize_ext */
+ slapi_ch_free_string(&dn);
+ }
+ if ('/' != *hostport) {
+ slapi_ch_free_string(&hostport);
+ }
+ rc = ldap_url_parse(normed, &ludp);
+ slapi_ch_free_string(&normed);
+ if (rc) {
return ACL_FALSE;
-
}
if ( ( NULL == ludp->lud_dn) || ( NULL == ludp->lud_filter) ) {
ldap_free_urldesc( ludp );
return ACL_FALSE;
}
- /* Normalize in place the dn */
- slapi_dn_normalize ( ludp->lud_dn );
-
/* Check the scope */
if ( ludp->lud_scope == LDAP_SCOPE_SUBTREE ) {
if (!slapi_dn_issuffix(n_clientdn, ludp->lud_dn)) {
@@ -3777,8 +3907,13 @@ DS_LASRoleDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
Slapi_DN *roleDN;
attrVal = slapi_value_get_berval ( sval );
- n_attrval = slapi_ch_strdup( attrVal->bv_val);
- n_attrval = slapi_dn_normalize (n_attrval);
+ n_attrval = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_attrval) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASRoleDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return LAS_EVAL_FAIL;
+ }
roleDN = slapi_sdn_new_dn_byval(n_attrval);
/* We support: The attribute value can be a USER or a GROUP.
@@ -3831,14 +3966,12 @@ DS_LASRoleDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
* returns: ACL_TRUE for matched,
* ACL_FALSE for matched.
* ACL_DONT_KNOW otherwise.
- *
- *
-*/
+ */
int
aclutil_evaluate_macro( char * rule, lasInfo *lasinfo,
- acl_eval_types evalType ) {
-
+ acl_eval_types evalType )
+{
int matched = 0;
aci_t *aci;
char *matched_val = NULL;
diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
index 8d4a21a..0c8d0fa 100644
--- a/ldap/servers/plugins/acl/aclparse.c
+++ b/ldap/servers/plugins/acl/aclparse.c
@@ -50,7 +50,6 @@ static int __aclp__sanity_check_acltxt(aci_t *aci_item, char *str);
static char * __aclp__normalize_acltxt (aci_t *aci_item, char *str);
static char * __aclp__getNextLASRule(aci_t *aci_item, char *str,
char **endOfCurrRule);
-static char * __aclp__dn_normalize( char *dn , char *end);
static int __aclp__get_aci_right ( char *str);
static int __aclp__init_targetattr (aci_t *aci, char *attr_val);
static int __acl__init_targetattrfilters( aci_t *aci_item, char *str);
@@ -239,10 +238,10 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
/*
- * The targetattrfilters bit looks like this:
- * (targetattrfilters="add= attr1:F1 && attr2:F2 ... && attrn:Fn,
- * del= attr1:F1 && attr2:F2... && attrn:Fn")
- */
+ * The targetattrfilters bit looks like this:
+ * (targetattrfilters="add= attr1:F1 && attr2:F2 ... && attrn:Fn,
+ * del= attr1:F1 && attr2:F2... && attrn:Fn")
+ */
if ( 0 != (rv= __acl__init_targetattrfilters(
aci_item, str))) {
return rv;
@@ -256,15 +255,14 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
}
/* Get individual components of the targetattr.
* (targetattr = "cn || u* || phone ||tel:add:(tel=1234)
- * || sn:del:(gn=5678)")
- * If it contains a value filter, the type will also be
- * ACI_TARGET_VALUE_ATTR.
- */
- if ( 0 != (rv= __aclp__init_targetattr(
- aci_item, str))) {
+ * || sn:del:(gn=5678)")
+ * If it contains a value filter, the type will also be
+ * ACI_TARGET_VALUE_ATTR.
+ */
+ if (0 != (rv = __aclp__init_targetattr(aci_item, str))) {
return rv;
}
- } else if (strncmp(str, aci_targetfilter,tfilterlen ) == 0) {
+ } else if (strncmp(str, aci_targetfilter,tfilterlen ) == 0) {
if ( aci_item->targetFilter)
return ACL_SYNTAX_ERR;
@@ -311,8 +309,8 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
} else if (strncmp(str, aci_targetdn, targetdnlen) == 0) {
char *tstr = NULL;
- const size_t LDAP_URL_prefix_len = strlen (LDAP_URL_prefix);
- char *tt;
+ size_t LDAP_URL_prefix_len = 0;
+ size_t tmplen = 0;
type = ACI_TARGET_DN;
/* Keep a copy of the target attr */
if (aci_item->target) {
@@ -322,30 +320,40 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
type |= ACI_TARGET_NOT;
strncpy(s, " ", 1);
}
-
- /* Convert it to lower as slapi_dn_normalize() does not */
- for (tt = str; *tt; tt++) *tt = TOLOWER ( *tt );
-
if ( (s = strchr( str, '=' )) != NULL ) {
value = s + 1;
- slapi_dn_normalize(value);
+ __acl_strip_leading_space(&value);
len = strlen ( value );
- if (*value == '"' && value[len-1] == '"'){
+ /* strip double quotes */
+ if (*value == '"' && value[len-1] == '"') {
value[len-1] = '\0';
value++;
}
__acl_strip_leading_space(&value);
- } else {
+ } else {
return ( ACL_SYNTAX_ERR );
}
-
- if ( strncasecmp ( value, LDAP_URL_prefix , LDAP_URL_prefix_len) )
+ if (0 ==
+ strncasecmp(value, LDAP_URL_prefix, strlen(LDAP_URL_prefix))) {
+ LDAP_URL_prefix_len = strlen(LDAP_URL_prefix);
+ } else if (0 == strncasecmp(value, LDAPS_URL_prefix,
+ strlen(LDAPS_URL_prefix))) {
+ LDAP_URL_prefix_len = strlen(LDAPS_URL_prefix);
+ } else {
return ( ACL_SYNTAX_ERR );
+ }
value += LDAP_URL_prefix_len;
- len = strlen ( value );
- tstr = (char *) slapi_ch_malloc ( targetdnlen + len + 4 );
- sprintf ( tstr, "(target=%s)", value);
+ rv = slapi_dn_normalize_case_ext(value, 0, &tmpstr, &tmplen);
+ if (rv < 0) {
+ return ACL_SYNTAX_ERR;
+ } else if (rv == 0) { /* value passed in; not null terminated */
+ *(tmpstr + tmplen) = '\0';
+ }
+ tstr = slapi_ch_smprintf("(target=%s)", tmpstr);
+ if (rv > 0) {
+ slapi_ch_free_string(&tmpstr);
+ }
if ( (rv = acl_check_for_target_macro( aci_item, value)) == -1) {
slapi_ch_free ( (void **) &tstr );
return(ACL_SYNTAX_ERR);
@@ -356,7 +364,7 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
/* it's a normal target with no macros inside */
f = slapi_str2filter ( tstr );
}
- slapi_ch_free ( (void **) &tstr );
+ slapi_ch_free_string ( &tstr );
} else {
/* did start with a 't' but was not a recognsied keyword */
return(ACL_SYNTAX_ERR);
@@ -492,20 +500,86 @@ __aclp__sanity_check_acltxt (aci_t *aci_item, char *str)
slapi_log_error(SLAPI_LOG_ACL, plugin_name, "Normalized String:%s\n", newstr);
/* check for acl syntax error */
- if ((handle = (ACLListHandle_t *) ACL_ParseString(&errp,
- newstr)) == NULL) {
+ if ((handle = (ACLListHandle_t *) ACL_ParseString(&errp, newstr)) == NULL) {
acl_print_acllib_err(&errp, str);
- slapi_ch_free ( (void **) &newstr );
+ slapi_ch_free_string(&newstr);
return ACL_SYNTAX_ERR;
} else {
/* get the rights and the aci type */
aci_item->aci_handle = handle;
nserrDispose(&errp);
- slapi_ch_free ( (void **) &newstr );
+ slapi_ch_free_string(&newstr);
return 0;
}
}
+
+/*
+ * If the src includes "ldap(s):///<dn>", normalize <dn> and copy
+ * the string starting from start to *dest.
+ * If isstrict is non-zero, if ldap(s):/// is not included in the src
+ * string, it returns an error (-1).
+ * If isstrict is zero, the string is copied as is.
+ *
+ * return value: 0 or positive: success
+ * negative: failure
+ */
+int
+__aclp__copy_normalized_str (char *src, char *endsrc, char *start,
+ char **dest, size_t *destlen, int isstrict)
+{
+ char *p = NULL;
+ int rc = -1;
+ char *dn = NULL;
+ size_t dnlen = 0;
+
+ p = PL_strnstr(src, LDAP_URL_prefix, endsrc - src);
+ if (p) {
+ p += strlen(LDAP_URL_prefix);
+ } else {
+ p = PL_strnstr(src, LDAPS_URL_prefix, endsrc - src);
+ if (p) {
+ p += strlen(LDAPS_URL_prefix);
+ }
+ }
+
+ if (isstrict && ((NULL == p) || 0 == strlen(p))) {
+ return rc; /* error */
+ }
+
+ rc = 0;
+ if (p && strlen(p) > 0) {
+ size_t len = 0;
+ /* strip the string starting from ? */
+ char *q = PL_strnchr(p, '?', endsrc - p);
+ if (q) {
+ len = q - p;
+ } else {
+ len = endsrc - p;
+ }
+ /* Normalize the value of userdn and append it to ret_str */
+ rc = slapi_dn_normalize_ext(p, len, &dn, &dnlen);
+ if (rc < 0) {
+ return rc;
+ }
+ /* append up to ldap(s):/// */
+ aclutil_str_append_ext(dest, destlen, start, p - start);
+ /* append the DN part */
+ aclutil_str_append_ext(dest, destlen, dn, dnlen);
+ if (rc > 0) { /* if rc == 0, p is passed in */
+ slapi_ch_free_string(&dn);
+ }
+ if (q) {
+ /* append the rest from '?' */
+ aclutil_str_append_ext(dest, destlen, q, endsrc - q);
+ }
+ } else {
+ aclutil_str_append_ext(dest, destlen, start, endsrc - start);
+ }
+
+ return rc;
+}
+
/******************************************************************************
*
* acl__normalize_acltxt
@@ -534,23 +608,25 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
char *s, *p;
char *end;
char *aclstr, *s_aclstr;
+ char *prevend = NULL;
char *ret_str = NULL;
+ size_t retstr_len = 0;
int len;
- char *ptr, *aclName;
+ char *aclName;
char *nextACE;
char *tmp_str = NULL;
char *acestr = NULL;
char *s_acestr = NULL;
int aci_rights_val = 0; /* bug 389975 */
+ int rc = 0;
/* make a copy first */
s_aclstr = aclstr = slapi_ch_strdup ( str );
/* The rules are like this version 3.0; acl "xyz"; rule1; rule2; */
s = strchr (aclstr, ';');
- if ( NULL == s) {
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (NULL == s) {
+ goto error;
}
aclstr = ++s;
@@ -564,9 +640,8 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
aclName = s+3;
s = strchr (aclstr, ';');
- if ( NULL == s) {
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (NULL == s) {
+ goto error;
}
aclstr = s;
@@ -576,8 +651,10 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
/* Here aclName is the acl description string */
aci_item->aclName = slapi_ch_strdup ( aclName );
- aclutil_str_appened (&ret_str, s_aclstr);
- aclutil_str_appened (&ret_str, ";");
+ retstr_len = strlen(str) * 3;
+ ret_str = (char *)slapi_ch_calloc(sizeof(char), retstr_len);
+ aclutil_str_append_ext (&ret_str, &retstr_len, s_aclstr, strlen(s_aclstr));
+ aclutil_str_append_ext (&ret_str, &retstr_len, ";", 1);
/* start with the string */
acestr = aclstr;
@@ -586,37 +663,34 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
* Here acestr is something like:
*
* " allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP";)"
- *
- *
- */
+ */
normalize_nextACERule:
/* now we are in the rule part */
tmp_str = acestr;
s = strchr (tmp_str, ';');
- if ( s == NULL) {
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (s == NULL) {
+ goto error;
}
+
nextACE = s;
LDAP_UTF8INC(nextACE);
*s = '\0';
- /* acestr now will hold copy of the ACE. Also add
+ /* acestr now will hold copy of the ACE. Also add
** some more space in case we need to add "absolute"
- ** for deny rule. We will never need more 2 times
- ** the len.
+ ** for deny rule. We will never need more 3 times
+ ** the len (even if all the chars are escaped).
*/
__acl_strip_leading_space(&tmp_str);
len = strlen (tmp_str);
- s_acestr = acestr = slapi_ch_calloc ( 1, 2 * len);
+ s_acestr = acestr = slapi_ch_calloc (1, 3 * len);
/*
* Now it's something like:
* allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP";
- */
+ */
if (strncasecmp(tmp_str, "allow", 5) == 0) {
memcpy(acestr, tmp_str, len);
tmp_str += 5;
@@ -624,6 +698,14 @@ normalize_nextACERule:
aci_rights_val = __aclp__get_aci_right (tmp_str);/* bug 389975 */
aci_item->aci_type |= ACI_HAS_ALLOW_RULE;
+ s = strchr(acestr, ')');
+ if (NULL == s) {
+ /* wrong syntax */
+ goto error;
+ }
+ /* add "allow(rights...)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len, acestr, s - acestr + 1);
+ prevend = s + 1;
} else if (strncasecmp(tmp_str, "deny", 4) == 0) {
char *d_rule ="deny absolute";
/* Then we have to add "absolute" to the deny rule
@@ -652,6 +734,15 @@ normalize_nextACERule:
len = strlen ( d_rule );
memcpy (acestr, d_rule, len );
memcpy (acestr+len, tmp_str, strlen (tmp_str) );
+
+ s = strchr(acestr, ')');
+ if (NULL == s) {
+ /* wrong syntax */
+ goto error;
+ }
+ /* add "deny(rights...)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len, acestr, s - acestr + 1);
+ prevend = s + 1;
} else {
/* wrong syntax */
aci_rights_val = -1 ;
@@ -659,32 +750,32 @@ normalize_nextACERule:
if (aci_rights_val == -1 )
{
/* wrong syntax */
- slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_acestr );
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ goto error;
} else
- aci_item->aci_access |= aci_rights_val;
+ aci_item->aci_access |= aci_rights_val;
-
- /* Normalize all the DNs in the userdn rule */
-
+ /* Normalize all the DNs in the userdn, groupdn, roledn rules */
/*
*
* Here acestr starts like this:
- * " allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP"
- */
-
+ * " allow (all) groupdn = "ldap:///cn=Domain Administrators,o=$dn.o,o=ISP"
+ */
s = __aclp__getNextLASRule(aci_item, acestr, &end);
while ( s ) {
- if ( 0 == strncmp ( s, DS_LAS_USERDNATTR, 10) ||
- ( 0 == strncmp ( s, DS_LAS_USERATTR, 8))) {
+ if ( (0 == strncmp(s, DS_LAS_USERDNATTR, 10)) ||
+ (0 == strncmp(s, DS_LAS_USERATTR, 8)) ) {
/*
** For userdnattr/userattr rule, the resources changes and hence
** we cannot cache the result. See above for more comments.
*/
aci_item->aci_elevel = ACI_ELEVEL_USERDNATTR;
- } else if ( 0== strncmp ( s, DS_LAS_USERDN, 6)) {
+
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 0);
+ if (rc < 0) {
+ goto error;
+ }
+ } else if ( 0 == strncmp ( s, DS_LAS_USERDN, 6)) {
p = strstr ( s, "=");
p--;
if ( strncmp (p, "!=", 2) == 0)
@@ -699,22 +790,12 @@ normalize_nextACERule:
* which would ensure that acl info is not cached from
* one resource entry to the next. (bug 558519)
*/
- p = strstr ( p, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8; /* for ldap:/// */
- if( __aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
-
+
/* we have a rule like userdn = "ldap:///blah". s points to blah now.
** let's find if we have a SELF rule like userdn = "ldap:///self".
** Since the resource changes on entry basis, we can't cache the
@@ -750,6 +831,12 @@ normalize_nextACERule:
aci_item->aci_elevel = ACI_ELEVEL_GROUPDNATTR;
}
aci_item->aci_ruleType |= ACI_GROUPDNATTR_RULE;
+
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 0);
+ if (rc < 0) {
+ goto error;
+ }
} else if ( 0 == strncmp ( s, DS_LAS_GROUPDN, 7)) {
p = strstr ( s, "=");
@@ -757,21 +844,12 @@ normalize_nextACERule:
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_GROUPDN;
- p = strstr ( s, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8;
- if (__aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
+
/* check for param rules */
__aclp_chk_paramRules ( aci_item, p, end );
@@ -786,21 +864,12 @@ normalize_nextACERule:
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_ROLEDN;
- p = strstr ( s, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8;
- if (__aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
+
/* check for param rules */
__aclp_chk_paramRules ( aci_item, p, end );
@@ -808,40 +877,47 @@ normalize_nextACERule:
if ( aci_item->aci_elevel > ACI_ELEVEL_GROUPDN )
aci_item->aci_elevel = ACI_ELEVEL_GROUPDN;*/
aci_item->aci_ruleType |= ACI_ROLEDN_RULE;
+ } else {
+ /* adding the string no need to be processed
+ * (e.g., dns="lab.example.com)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len,
+ prevend, end - prevend);
}
+ prevend = end;
s = ++end;
s = __aclp__getNextLASRule(aci_item, s, &end);
- }/* while */
+ if (NULL == s) {
+ /* adding the rest of the string, e.g. '\"' */
+ aclutil_str_append_ext(&ret_str, &retstr_len,
+ prevend, strlen(prevend));
+ }
+ } /* while */
- /* get the head of the string */
- acestr = s_acestr;
- len = strlen( acestr);
- ptr = acestr +len-1;
- while (*ptr && *ptr != '\"' && *ptr != ')' ) *ptr-- = ' ';
- ptr++;
- *ptr = ';';
-
- aclutil_str_appened (&ret_str, acestr);
- if (s_acestr) {
- slapi_ch_free ( (void **) &s_acestr );
- }
- s_acestr = NULL;
+ slapi_ch_free_string (&s_acestr);
+ __acl_strip_trailing_space(ret_str);
+ aclutil_str_append_ext(&ret_str, &retstr_len, ";", 1);
if (nextACE) {
s = strstr (nextACE, "allow");
if (s == NULL) s = strstr (nextACE, "deny");
if (s == NULL) {
if (nextACE && *nextACE != '\0')
- aclutil_str_appened (&ret_str, nextACE);
- slapi_ch_free ( (void **) &s_aclstr );
+ aclutil_str_append (&ret_str, nextACE);
+ slapi_ch_free_string (&s_aclstr);
return (ret_str);
}
acestr = nextACE;
goto normalize_nextACERule;
}
- slapi_ch_free ( (void **) &s_aclstr );
+ slapi_ch_free_string (&s_aclstr);
return (ret_str);
+
+error:
+ slapi_ch_free_string (&ret_str);
+ slapi_ch_free_string (&s_aclstr);
+ slapi_ch_free_string (&s_acestr);
+ return NULL;
}
/*
*
@@ -857,7 +933,7 @@ __aclp__getNextLASRule (aci_t *aci_item, char *original_str , char **endOfCurrRu
{
char *newstr, *word, *next, *start, *end;
char *ruleStart = NULL;
- int len, ruleLen;
+ int len, ruleLen = 0;
int in_dn_expr = 0;
*endOfCurrRule = NULL;
@@ -1029,43 +1105,7 @@ __aclp__getNextLASRule (aci_t *aci_item, char *original_str , char **endOfCurrRu
return ( ruleStart );
}
-/******************************************************************************
-*
-* __aclp__dn_normalize
-*
-* Normalize the DN INPLACE. This routine is similar to slapi_dn_normalize()
-* except various small stuff at the end.
-* Normalize until the "end" and not to the end of string.
-*
-******************************************************************************/
-static char *
-__aclp__dn_normalize( char *dn , char *end)
-{
- char *d;
-
- if ((end - dn) < 0) {
- return(NULL);
- }
- d = slapi_dn_normalize_to_end ( dn, end );
-
- /* Do I have the quotes already */
- if (*d != '\"' ) {
- /*
- ** We are taking care of this situation
- ** " ") ". We need to remove the space
- ** infront and tack it after the quote like this.
- ** "" ) ".
- */
-
- *d = '\"';
- d++;
- while (*d && *d != '\"') *d++ = ' ';
- *d = ' ';
- }
-
- return( dn );
-}
/***************************************************************************
* acl__get_aci_right
*
@@ -1263,6 +1303,7 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
}
while (str != 0 && *str != 0) {
+ int lenstr = 0;
__acl_strip_leading_space(&str);
@@ -1292,23 +1333,28 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
attr = (Targetattr *) slapi_ch_malloc (sizeof (Targetattr));
memset (attr, 0, sizeof(Targetattr));
- if (strchr(str, '*')) {
-
+ /* strip double quotes */
+ lenstr = strlen(str);
+ if (*str == '"' && *(str + lenstr - 1) == '"') {
+ *(str + lenstr - 1) = '\0';
+ str++;
+ }
+ if (strchr(str, '*')) {
+
/* It contains a * so it's something like * or cn* */
if (strcmp(str, "*" ) != 0) {
char line[100];
char *lineptr = &line[0];
char *newline = NULL;
- int lenstr = 0;
struct slapi_filter *f = NULL;
- if ((lenstr = strlen(str)) > 91) { /* 100 - 8 for "(attr =%s)" */
- newline = slapi_ch_malloc(lenstr + 9);
+ if (lenstr > 92) { /* 100 - 8 for "(attr=%s)\0" */
+ newline = slapi_ch_malloc(lenstr + 8);
lineptr = newline;
}
attr->attr_type = ACL_ATTR_FILTER;
- sprintf (lineptr, "(attr =%s)", str);
+ sprintf (lineptr, "(attr=%s)", str);
f = slapi_str2filter (lineptr);
if (f == NULL) {
@@ -1320,7 +1366,7 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
if (newline) slapi_ch_free((void **) &newline);
} else {
- attr->attr_type = ACL_ATTR_STAR;
+ attr->attr_type = ACL_ATTR_STAR;
attr->u.attr_str = slapi_ch_strdup (str);
}
diff --git a/ldap/servers/plugins/acl/aclproxy.c b/ldap/servers/plugins/acl/aclproxy.c
index d40f543..9b28489 100644
--- a/ldap/servers/plugins/acl/aclproxy.c
+++ b/ldap/servers/plugins/acl/aclproxy.c
@@ -87,7 +87,9 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
LDAPProxyAuth *spec = NULL;
BerElement *ber = NULL;
char *errstring = "unable to parse proxied authorization control";
-
+ int rc = 0;
+ char *normed = NULL;
+ size_t dnlen = 0;
BEGIN
ber_tag_t tag;
@@ -132,11 +134,20 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
errstring = "proxied authorization id must be a DN (dn:...)";
break;
}
- strcpy( spec->auth_dn, spec->auth_dn + 3 );
+ /* memmove is safe for overlapping copy */
+ memmove ( spec->auth_dn, spec->auth_dn + 3, strlen(spec->auth_dn) - 2);/* 1 for '\0' */
}
- slapi_dn_normalize(spec->auth_dn);
lderr = LDAP_SUCCESS; /* got it! */
+ rc = slapi_dn_normalize_ext(spec->auth_dn, 0, &normed, &dnlen);
+ if (rc < 0) {
+ lderr = LDAP_INVALID_SYNTAX;
+ } else if (rc == 0) { /* spec->auth_dn is passed in; not terminated */
+ *(normed + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&spec->auth_dn);
+ spec->auth_dn = normed;
+ }
END
/* Cleanup */
diff --git a/ldap/servers/plugins/acl/aclutil.c b/ldap/servers/plugins/acl/aclutil.c
index 4aebd47..c0b8f57 100644
--- a/ldap/servers/plugins/acl/aclutil.c
+++ b/ldap/servers/plugins/acl/aclutil.c
@@ -65,7 +65,7 @@ static PRIntn acl_ht_display_entry(PLHashEntry *he, PRIntn i, void *arg);
/* UTILITY FUNCTIONS */
/***************************************************************************/
int
-aclutil_str_appened(char **str1, const char *str2)
+aclutil_str_append(char **str1, const char *str2)
{
int new_len;
@@ -87,6 +87,43 @@ aclutil_str_appened(char **str1, const char *str2)
return(0);
}
+/*
+ * dlen: the length of the buffer *dest (not the string length in *dest)
+ */
+int
+aclutil_str_append_ext(char **dest, size_t *dlen, const char *src, size_t slen)
+{
+ char *ptr = NULL;
+ int rc = 0;
+
+ if ( dest == NULL || src == NULL ) {
+ return rc;
+ }
+
+ if (0 == slen) {
+ slen = strlen(src);
+ }
+ if (*dest && dlen > 0) {
+ size_t dest_strlen = strlen(*dest);
+ size_t new_len = dest_strlen + slen + 1;
+ if (new_len > *dlen) {
+ *dest = (char *)slapi_ch_realloc(*dest, new_len);
+ *dlen = new_len;
+ ptr = *dest + dest_strlen;
+ } else {
+ ptr = *dest + dest_strlen;
+ }
+ } else {
+ *dlen = slen + 1;
+ *dest = (char *)slapi_ch_malloc(*dlen);
+ ptr = *dest;
+ }
+ memcpy(ptr, src, slen);
+ *(ptr + slen) = '\0';
+
+ return rc;
+}
+
/***************************************************************************/
/* Print routines */
/***************************************************************************/
@@ -104,9 +141,14 @@ acl_print_acllib_err (NSErr_t *errp , char * str)
aclErrorFmt(errp, msgbuf, ACLUTIL_ACLLIB_MSGBUF_LEN, 1);
msgbuf[ACLUTIL_ACLLIB_MSGBUF_LEN-1] = '\0';
- if (msgbuf)
- slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)(%s)\n",
- msgbuf, str ? str: "NULL");
+ if (strlen(msgbuf) > 0) {
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)(%s)\n",
+ msgbuf, str ? str: "NULL");
+ } else {
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)\n",
+ str ? str: "NULL");
+ }
+
}
void
aclutil_print_aci (aci_t *aci_item, char *type)
@@ -240,7 +282,7 @@ aclutil_print_err (int rv , const Slapi_DN *sdn, const struct berval* val,
if (errbuf) {
/* If a buffer is provided, then copy the error */
- aclutil_str_appened(errbuf, lineptr );
+ aclutil_str_append(errbuf, lineptr );
}
slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "%s", lineptr);
@@ -436,7 +478,7 @@ acl_gen_err_msg(int access, char *edn, char *attr, char **errbuf)
line = PR_smprintf(
"Insufficient 'delete' privilege to delete the entry '%s'.\n",edn);
}
- aclutil_str_appened(errbuf, line );
+ aclutil_str_append(errbuf, line );
if (line) {
PR_smprintf_free(line);
@@ -540,7 +582,7 @@ aclutil_expand_paramString ( char *str, Slapi_Entry *e )
goto cleanup;
}
*p = '\0';
- aclutil_str_appened ( &buf,a_dns[i]);
+ aclutil_str_append ( &buf,a_dns[i]);
if ( type == 1 ) {
/* xyz = $dn.o */
@@ -573,15 +615,15 @@ aclutil_expand_paramString ( char *str, Slapi_Entry *e )
kk= slapi_attr_next_value( attr, kk, &sval );
if ( kk != -1 ) /* can't handle multiple --error */
goto cleanup;
+ attrValue = slapi_value_get_berval ( t_sval );
+ attrVal = attrValue->bv_val;
}
- attrValue = slapi_value_get_berval ( t_sval );
- attrVal = attrValue->bv_val;
}
} else {
attrVal = a_dns[i];
}
- aclutil_str_appened ( &buf, attrVal);
- aclutil_str_appened ( &buf, ",");
+ aclutil_str_append ( &buf, attrVal);
+ aclutil_str_append ( &buf, ",");
}
rc = 0; /* everything is okay*/
/* remove the last comma */
@@ -607,7 +649,7 @@ __aclutil_extract_dn_component ( char **e_dns, int position, char *attrName )
int i, matched, len;
char *s;
- int matchedPosition;
+ int matchedPosition = 0;
len = strlen ( attrName );
diff --git a/ldap/servers/plugins/chainingdb/cb_config.c b/ldap/servers/plugins/chainingdb/cb_config.c
index 1dab846..5659353 100644
--- a/ldap/servers/plugins/chainingdb/cb_config.c
+++ b/ldap/servers/plugins/chainingdb/cb_config.c
@@ -63,24 +63,28 @@ int cb_config_add_dse_entries(cb_backend *cb, char **entries, char *string1, cha
Slapi_PBlock *util_pb = NULL;
int res, rc = 0;
char entry_string[CB_BUFSIZE];
+ char *dn = NULL;
for(x = 0; strlen(entries[x]) > 0; x++) {
util_pb = slapi_pblock_new();
PR_snprintf(entry_string, sizeof(entry_string), entries[x], string1, string2, string3);
e = slapi_str2entry(entry_string, 0);
+ dn = slapi_ch_strdup(slapi_entry_get_dn(e)); /* for err msg */
slapi_add_entry_internal_set_pb(util_pb, e, NULL, cb->identity, 0);
slapi_add_internal_pb(util_pb);
slapi_pblock_get(util_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
if ( LDAP_SUCCESS != res && LDAP_ALREADY_EXISTS != res ) {
char ebuf[ BUFSIZ ];
- slapi_log_error(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
+ slapi_log_error(SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
"Unable to add config entry (%s) to the DSE: %s\n",
- escape_string(slapi_entry_get_dn(e), ebuf),
+ escape_string(dn, ebuf),
ldap_err2string(res));
rc = res;
slapi_pblock_destroy(util_pb);
+ slapi_ch_free_string(&dn);
break;
}
+ slapi_ch_free_string(&dn);
slapi_pblock_destroy(util_pb);
}
return rc;
@@ -161,7 +165,7 @@ int cb_config_load_dse_info(Slapi_PBlock * pb) {
/* Get the default instance value entry if it exists */
/* else create it */
-
+ /* This dn is already normalized */
PR_snprintf(defaultDn,sizeof(defaultDn),"cn=default instance config,%s",cb->pluginDN);
default_pb = slapi_pblock_new();
diff --git a/ldap/servers/plugins/chainingdb/cb_init.c b/ldap/servers/plugins/chainingdb/cb_init.c
index 21a54d5..3b4f7a0 100644
--- a/ldap/servers/plugins/chainingdb/cb_init.c
+++ b/ldap/servers/plugins/chainingdb/cb_init.c
@@ -82,7 +82,9 @@ chaining_back_init( Slapi_PBlock *pb )
/* Initialize misc. fields */
cb->config.rwl_config_lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "chaining_db");
- rc = slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, (void *) cb );
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, (void *) cb );
+
+ /* These DNs are already normalized */
cb->pluginDN=slapi_ch_smprintf("cn=%s,%s",CB_PLUGIN_NAME,PLUGIN_BASE_DN);
cb->configDN=slapi_ch_smprintf("cn=config,%s",cb->pluginDN);
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c
index 1c08bd9..73d5e01 100644
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
@@ -153,10 +153,10 @@ cb_dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
static char *cb_skeleton_entries[] =
{
- "dn:cn=monitor, cn=%s, cn=%s, cn=plugins, cn=config\n"
- "objectclass:top\n"
- "objectclass:extensibleObject\n"
- "cn:monitor\n",
+ "dn: cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config\n"
+ "objectclass: top\n"
+ "objectclass: extensibleObject\n"
+ "cn: monitor\n",
""
};
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
index a14e48c..b5aace6 100644
--- a/ldap/servers/plugins/cos/cos_cache.c
+++ b/ldap/servers/plugins/cos/cos_cache.c
@@ -69,6 +69,8 @@
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
+
#include "portable.h"
#include "slapi-plugin.h"
@@ -324,6 +326,8 @@ static int cos_cache_vattr_compare(vattr_sp_handle *handle, vattr_context *c, Sl
static int cos_cache_vattr_types(vattr_sp_handle *handle,Slapi_Entry *e,vattr_type_list_context *type_context,int flags);
static int cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Slapi_Entry *e, char *type, Slapi_ValueSet **out_attr, Slapi_Value *test_this, int *result, int *ops);
+static int hexchar2int( char c );
+
/*
compares s2 to s1 starting from end of string until the beginning of either
matches result in the s2 value being clipped from s1 with a NULL char
@@ -904,14 +908,29 @@ static int cos_dn_defs_cb (Slapi_Entry* e, void *callback_data) {
{
/* get the parent of the definition */
- char *parent = slapi_dn_parent(pDn->val);
- slapi_dn_normalize( parent );
+ char *parent = NULL;
+ size_t plen = 0;
+ int rc = 0;
+ char *orig = slapi_dn_parent(pDn->val);
+ rc = slapi_dn_normalize_ext(orig,
+ 0, &parent, &plen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_build_definition_list: failed to normalize parent dn %s. Adding the pre normalized dn.\n", orig, 0, 0);
+ parent = orig;
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(parent + plen) = '\0';
+ }
cos_cache_add_attrval(&pCosTargetTree, parent);
if(!pCosTemplateDn)
cos_cache_add_attrval(&pCosTemplateDn, parent);
- slapi_ch_free((void**)&parent);
+ if (orig != parent) {
+ slapi_ch_free_string(&orig);
+ }
+ slapi_ch_free_string(&parent);
}
slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL);
@@ -1916,16 +1935,33 @@ static int cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAt
theTemp = (cosTemplates*) slapi_ch_malloc(sizeof(cosTemplates));
if(theTemp)
{
- char *grade = (char*)slapi_ch_malloc(strlen(dn->val)+1);
+ char *grade = NULL;
int grade_index = 0;
int index = 0;
+ int lastindex = 0;
int template_default = 0;
-
- slapi_dn_normalize(dn->val);
+ char *dnval = NULL;
+ size_t dnlen = 0;
+ int rc = 0;
+
+ rc = slapi_dn_normalize_ext(dn->val, 0, &dnval, &dnlen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_add_tmpl: failed to normalize dn %s. "
+ "Processing the pre normalized dn.\n", dn->val, 0, 0);
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(dnval + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&dn->val);
+ dn->val = dnval;
+ }
+ grade = (char*)slapi_ch_malloc(strlen(dn->val)+1);
/* extract the cos grade */
while(dn->val[index] != '=' && dn->val[index] != '\0')
index++;
+ lastindex = strlen(dn->val) - 1;
if(dn->val[index] == '=')
{
@@ -1945,7 +1981,29 @@ static int cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAt
}
else
{
- if(dn->val[index] != '\\') /* skip escape chars */
+ if(dn->val[index] == '\\')
+ {
+ if ((index+2 <= lastindex) && isxdigit(dn->val[index+1]) &&
+ isxdigit(dn->val[index+2])) {
+ /* Convert ESC HEX HEX to a real char */
+ int n = hexchar2int(dn->val[index+1]);
+ int n2 = hexchar2int(dn->val[index+2]);
+ n = (n << 4) + n2;
+ if (n == 0) { /* don't change \00 */
+ grade[grade_index] = dn->val[index++]; /* '\\' */
+ grade_index++;
+ grade[grade_index] = dn->val[index++]; /* 0 */
+ grade_index++;
+ grade[grade_index] = dn->val[index]; /* 0 */
+ grade_index++;
+ } else {
+ grade[grade_index] = n;
+ index += 2;
+ grade_index++;
+ }
+ } /* else: skip escape chars */
+ }
+ else
{
grade[grade_index] = dn->val[index];
grade_index++;
@@ -2329,8 +2387,24 @@ static int cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Sl
/* is this entry a child of the target tree(s)? */
do
{
- if(pTargetTree)
- slapi_dn_normalize( pTargetTree->val );
+ if(pTargetTree) {
+ int rc = 0;
+ char *tval = NULL;
+ size_t tlen = 0;
+ rc = slapi_dn_normalize_ext(pTargetTree->val, 0, &tval, &tlen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_query_attr: failed to normalize dn %s. "
+ "Processing the pre normalized dn.\n",
+ pTargetTree->val, 0, 0);
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(tval + tlen) = '\0';
+ } else {
+ slapi_ch_free_string(&pTargetTree->val);
+ pTargetTree->val = tval;
+ }
+ }
if( pTargetTree->val == 0 ||
slapi_dn_issuffix(pDn, pTargetTree->val) != 0 ||
@@ -2800,7 +2874,23 @@ static int cos_cache_index_all(cosCache *pCache)
while(pAttrVal)
{
- slapi_dn_normalize(pAttrVal->val);
+ int rc = 0;
+ char *dnval = NULL;
+ size_t dnlen = 0;
+ rc = slapi_dn_normalize_ext(pAttrVal->val, 0,
+ &dnval, &dnlen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_index_all: failed to normalize dn %s. "
+ "Processing the pre normalized dn.\n",
+ pAttrVal->val, 0, 0);
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(dnval + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&pAttrVal->val);
+ pAttrVal->val = dnval;
+ }
pCache->ppTemplateList[tmpindex] = pAttrVal->val;
tmpindex++;
@@ -3519,3 +3609,20 @@ static int cos_cache_entry_is_cos_related( Slapi_Entry *e) {
}
return(rc);
}
+
+/* copied from dn.c */
+static int
+hexchar2int( char c )
+{
+ if ( '0' <= c && c <= '9' ) {
+ return( c - '0' );
+ }
+ if ( 'a' <= c && c <= 'f' ) {
+ return( c - 'a' + 10 );
+ }
+ if ( 'A' <= c && c <= 'F' ) {
+ return( c - 'A' + 10 );
+ }
+ return( -1 );
+}
+
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index b8922d9..94c4ab3 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -680,7 +680,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
}
entry = (struct configEntry *)
- slapi_ch_calloc(1, sizeof(struct configEntry));
+ slapi_ch_calloc(1, sizeof(struct configEntry));
if (NULL == entry) {
ret = DNA_FAILURE;
goto bail;
@@ -787,7 +787,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
if (value) {
/* TODO - Allow multiple scope settings for a single range. This may
* make ordering the scopes tough when we put them in the clist. */
- entry->scope = slapi_dn_normalize(value);
+ entry->scope = value;
} else {
slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
"dna_parse_config_entry: The %s config "
@@ -817,6 +817,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
if (value) {
Slapi_Entry *shared_e = NULL;
Slapi_DN *sdn = NULL;
+ char *normdn = NULL;
sdn = slapi_sdn_new_dn_byref(value);
@@ -840,15 +841,29 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
shared_e = NULL;
}
- entry->shared_cfg_base = slapi_ch_strdup(value);
- slapi_dn_normalize(entry->shared_cfg_base);
+ normdn = slapi_create_dn_string("%s", value);
+ if (NULL == normdn) {
+ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
+ "dna_parse_config_entry: failed to normalize dn: "
+ "%s\n", value);
+ ret = DNA_FAILURE;
+ goto bail;
+ }
+ entry->shared_cfg_base = normdn;
/* We prepend the host & port of this instance as a
* multi-part RDN for the shared config entry. */
- entry->shared_cfg_dn = slapi_ch_smprintf("%s=%s+%s=%s,%s", DNA_HOSTNAME,
- hostname, DNA_PORTNUM, portnum, value);
- slapi_ch_free_string(&value);
- slapi_dn_normalize(entry->shared_cfg_dn);
+ normdn = slapi_create_dn_string("%s=%s+%s=%s,%s", DNA_HOSTNAME,
+ hostname, DNA_PORTNUM, portnum, normdn);
+ if (NULL == normdn) {
+ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
+ "dna_parse_config_entry: failed to create dn: "
+ "%s=%s+%s=%s,%s", DNA_HOSTNAME,
+ hostname, DNA_PORTNUM, portnum, value);
+ ret = DNA_FAILURE;
+ goto bail;
+ }
+ entry->shared_cfg_dn = normdn;
slapi_log_error(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM,
"----------> %s [%s]\n", DNA_SHARED_CFG_DN,
@@ -1680,8 +1695,6 @@ static char *dna_get_dn(Slapi_PBlock * pb)
goto bail;
}
-/* slapi_dn_normalize( dn );
-*/
bail:
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"<-- dna_get_dn\n");
@@ -2310,7 +2323,14 @@ static int dna_is_replica_bind_dn(char *range_dn, char *bind_dn)
* the shared config. We need to see what the configured
* replica bind DN is. */
if (be_suffix) {
- replica_dn = slapi_ch_smprintf("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", be_suffix);
+ /* This function converts the old DN style to the new one. */
+ replica_dn = slapi_create_dn_string("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", be_suffix);
+ if (NULL == replica_dn) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
+ "dna_is_replica_bind_dn: failed to create "
+ "replica dn for %s\n", be_suffix);
+ return 1;
+ }
replica_sdn = slapi_sdn_new_dn_passin(replica_dn);
attrs[0] = DNA_REPL_BIND_DN;
@@ -2370,8 +2390,15 @@ static int dna_get_replica_bind_creds(char *range_dn, struct dnaServer *server,
/* Fetch the replication agreement entry */
if (be_suffix) {
- replica_dn = slapi_ch_smprintf("cn=replica,cn=\"%s\",cn=mapping tree,cn=config",
- be_suffix);
+ /* This function converts the old DN style to the new one. */
+ replica_dn = slapi_create_dn_string("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", be_suffix);
+ if (NULL == replica_dn) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
+ "dna_get_replica_bind_creds: failed to create "
+ "replica dn for %s\n", be_suffix);
+ ret = LDAP_PARAM_ERROR;
+ goto bail;
+ }
filter = slapi_ch_smprintf("(&(nsds5ReplicaHost=%s)(|(" DNA_REPL_PORT "=%u)"
"(" DNA_REPL_PORT "=%u)))",
diff --git a/ldap/servers/plugins/linkedattrs/fixup_task.c b/ldap/servers/plugins/linkedattrs/fixup_task.c
index 50d35d0..d550570 100644
--- a/ldap/servers/plugins/linkedattrs/fixup_task.c
+++ b/ldap/servers/plugins/linkedattrs/fixup_task.c
@@ -80,9 +80,9 @@ linked_attrs_fixup_task_add(Slapi_PBlock *pb, Slapi_Entry *e,
goto out;
}
- if (linkdn) {
+ if (linkdn) {
mytaskdata->linkdn = slapi_dn_normalize(slapi_ch_strdup(linkdn));
- }
+ }
/* allocate new task now */
task = slapi_new_task(slapi_entry_get_ndn(e));
diff --git a/ldap/servers/plugins/mep/mep.c b/ldap/servers/plugins/mep/mep.c
index e9d64fe..ba14203 100644
--- a/ldap/servers/plugins/mep/mep.c
+++ b/ldap/servers/plugins/mep/mep.c
@@ -88,7 +88,6 @@ static int mep_modrdn_pre_op(Slapi_PBlock *pb);
static int mep_load_config();
static void mep_delete_config();
static int mep_parse_config_entry(Slapi_Entry * e, int apply);
-static void mep_insert_config_index(struct configEntry *entry);
static void mep_free_config_entry(struct configEntry ** entry);
/*
@@ -949,7 +948,6 @@ mep_create_managed_entry(struct configEntry *config, Slapi_Entry *origin)
Slapi_Entry *template = NULL;
char *rdn_type = NULL;
char **vals = NULL;
- char *p = NULL;
char *type = NULL;
char *value = NULL;
int vlen = 0;
@@ -1055,7 +1053,7 @@ mep_create_managed_entry(struct configEntry *config, Slapi_Entry *origin)
/* Create the DN using the mapped RDN value
* and the base specified in the config. */
- dn = slapi_ch_smprintf("%s=%s,%s", rdn_type, rdn_val, config->managed_base);
+ dn = slapi_create_dn_string("%s=%s,%s", rdn_type, rdn_val, config->managed_base);
slapi_ch_free_string(&rdn_val);
diff --git a/ldap/servers/plugins/pwdstorage/smd5_pwd.c b/ldap/servers/plugins/pwdstorage/smd5_pwd.c
index 65c6b2a..cef3ee3 100644
--- a/ldap/servers/plugins/pwdstorage/smd5_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/smd5_pwd.c
@@ -89,7 +89,7 @@ smd5_pw_cmp( const char *userpwd, const char *dbpwd )
memset( quick_dbhash, 0, sizeof(quick_dbhash) );
}
- hashresult = PL_Base64Decode( dbpwd, 0, (char *)dbhash );
+ hashresult = PL_Base64Decode( dbpwd, 0, dbhash );
if (NULL == hashresult) {
slapi_log_error( SLAPI_LOG_PLUGIN, SALTED_MD5_SUBSYSTEM_NAME,
"smd5_pw_cmp: userPassword \"%s\" is the wrong length "
@@ -139,7 +139,7 @@ smd5_pw_enc( const char *pwd )
memset( hash_out, 0, sizeof(hash_out) );
/* generate a new random salt */
- slapi_rand_array( salt, MD5_DEFAULT_SALT_LENGTH );
+ slapi_rand_array( (void *)salt, MD5_DEFAULT_SALT_LENGTH );
saltval.bv_val = (void*)salt;
saltval.bv_len = MD5_DEFAULT_SALT_LENGTH;
diff --git a/ldap/servers/plugins/referint/referint.c b/ldap/servers/plugins/referint/referint.c
index b459a7a..0f1598d 100644
--- a/ldap/servers/plugins/referint/referint.c
+++ b/ldap/servers/plugins/referint/referint.c
@@ -385,6 +385,7 @@ _update_one_per_mod(const char *entryDN, /* DN of the searched entry */
/* no need to free superior */
superior = slapi_dn_find_parent(origDN);
}
+ /* newRDN and superior are already normalized. */
newDN = slapi_ch_smprintf("%s,%s", newRDN, superior);
/*
* Compare the modified dn with the value of
@@ -409,9 +410,19 @@ _update_one_per_mod(const char *entryDN, /* DN of the searched entry */
nval != -1;
nval = slapi_attr_next_value(attr, nval, &v)) {
char *p = NULL;
+ size_t dnlen = 0;
/* DN syntax, which should be a string */
sval = slapi_ch_strdup(slapi_value_get_string(v));
- slapi_dn_normalize_case(sval);
+ rc = slapi_dn_normalize_case_ext(sval, 0, &p, &dnlen);
+ if (rc == 0) { /* sval is passed in; not terminated */
+ *(p + dnlen) = '\0';
+ sval = p;
+ } else if (rc > 0) {
+ slapi_ch_free_string(&sval);
+ sval = p;
+ }
+ /* else: (rc < 0) Ignore the DN normalization error for now. */
+
p = PL_strstr(sval, norm_origDN);
if (p == sval) {
/* (case 1) */
@@ -448,6 +459,7 @@ _update_one_per_mod(const char *entryDN, /* DN of the searched entry */
bak = *p;
*p = '\0';
+ /* newRDN and superior are already normalized. */
newvalue = slapi_ch_smprintf("%s%s", sval, newDN);
*p = bak;
values_add[0]=newvalue;
@@ -579,9 +591,19 @@ _update_all_per_mod(const char *entryDN, /* DN of the searched entry */
nval != -1;
nval = slapi_attr_next_value(attr, nval, &v)) {
char *p = NULL;
+ size_t dnlen = 0;
/* DN syntax, which should be a string */
sval = slapi_ch_strdup(slapi_value_get_string(v));
- slapi_dn_normalize_case(sval);
+ rc = slapi_dn_normalize_case_ext(sval, 0, &p, &dnlen);
+ if (rc == 0) { /* sval is passed in; not terminated */
+ *(p + dnlen) = '\0';
+ sval = p;
+ } else if (rc > 0) {
+ slapi_ch_free_string(&sval);
+ sval = p;
+ }
+ /* else: (rc < 0) Ignore the DN normalization error for now. */
+
p = PL_strstr(sval, norm_origDN);
if (p == sval) {
/* (case 1) */
@@ -632,6 +654,7 @@ update_integrity(char **argv, char *origDN,
int i, j;
const char *search_base = NULL;
char *norm_origDN = NULL;
+ size_t dnlen = 0;
int rc;
if ( argv == NULL ) {
@@ -644,8 +667,14 @@ update_integrity(char **argv, char *origDN,
/* for now, just putting attributes to keep integrity on in conf file,
until resolve the other timing mode issue */
- norm_origDN = slapi_ch_strdup(origDN);
- slapi_dn_normalize_case(norm_origDN);
+ rc = slapi_dn_normalize_case_ext(origDN, 0, &norm_origDN, &dnlen);
+ if (rc == 0) { /* origDN is passed in; not terminated */
+ *(norm_origDN + dnlen) = '\0';
+ norm_origDN = slapi_ch_strdup(norm_origDN);
+ } else if (rc < 0) {
+ /* Ignore the DN normalization error for now. */
+ norm_origDN = slapi_ch_strdup(origDN);
+ }
search_result_pb = slapi_pblock_new();
diff --git a/ldap/servers/plugins/replication/legacy_consumer.c b/ldap/servers/plugins/replication/legacy_consumer.c
index 9774527..8a47e80 100644
--- a/ldap/servers/plugins/replication/legacy_consumer.c
+++ b/ldap/servers/plugins/replication/legacy_consumer.c
@@ -83,6 +83,7 @@ static void legacy_consumer_encode_pw (Slapi_Entry *e);
static void set_legacy_purl (Slapi_PBlock *pb, const char *purl);
static int get_legacy_referral (Slapi_Entry *e, char **referral, char **state);
+/* LEGACY_CONSUMER_CONFIG_DN is no need to be normalized. */
#define LEGACY_CONSUMER_CONFIG_DN "cn=legacy consumer," REPL_CONFIG_TOP
#define LEGACY_CONSUMER_FILTER "(objectclass=*)"
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index c6859dd..6be21ce 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -319,8 +319,8 @@ char **agmt_validate_replicated_attributes(Repl_Agmt *ra);
void* agmt_get_priv (const Repl_Agmt *agmt);
void agmt_set_priv (Repl_Agmt *agmt, void* priv);
-
int get_agmt_agreement_type ( Repl_Agmt *agmt);
+int agmt_has_protocol(Repl_Agmt *agmt);
typedef struct replica Replica;
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 13db1ac..f60da02 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2216,13 +2216,21 @@ agmt_get_consumer_rid ( Repl_Agmt *agmt, void *conn )
{
if ( agmt->consumerRID <= 0 ) {
- char mapping_tree_node[512];
+ char *mapping_tree_node = NULL;
struct berval **bvals = NULL;
- PR_snprintf ( mapping_tree_node,
- sizeof (mapping_tree_node),
- "cn=replica,cn=\"%s\",cn=mapping tree,cn=config",
- slapi_sdn_get_dn (agmt->replarea) );
+
+ /* This function converts the old style DN to the new one. */
+ mapping_tree_node =
+ slapi_create_dn_string("cn=replica,cn=\"%s\",cn=mapping tree,cn=config",
+ slapi_sdn_get_dn (agmt->replarea) );
+ if (NULL == mapping_tree_node) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "agmt_get_consumer_rid: failed to normalize "
+ "replica dn for %s\n",
+ slapi_sdn_get_dn (agmt->replarea));
+ agmt->consumerRID = 0;
+ }
conn_read_entry_attribute ( conn, mapping_tree_node, "nsDS5ReplicaID", &bvals );
if ( NULL != bvals && NULL != bvals[0] ) {
char *ridstr = slapi_ch_malloc( bvals[0]->bv_len + 1 );
@@ -2232,6 +2240,7 @@ agmt_get_consumer_rid ( Repl_Agmt *agmt, void *conn )
slapi_ch_free ( (void**) &ridstr );
ber_bvecfree ( bvals );
}
+ slapi_ch_free_string(&mapping_tree_node);
}
return agmt->consumerRID;
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
index 510757b..f9aa610 100644
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
@@ -50,7 +50,8 @@
#include "repl5.h"
#include <plstr.h>
-#define AGMT_CONFIG_BASE "cn=mapping tree, cn=config"
+/* normalized DN */
+#define AGMT_CONFIG_BASE "cn=mapping tree,cn=config"
#define CONFIG_FILTER "(objectclass=nsds5replicationagreement)"
#define WINDOWS_CONFIG_FILTER "(objectclass=nsdsWindowsreplicationagreement)"
#define GLOBAL_CONFIG_FILTER "(|" CONFIG_FILTER WINDOWS_CONFIG_FILTER " )"
diff --git a/ldap/servers/plugins/replication/repl5_protocol.c b/ldap/servers/plugins/replication/repl5_protocol.c
index 31f6072..b1ff730 100644
--- a/ldap/servers/plugins/replication/repl5_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_protocol.c
@@ -173,7 +173,6 @@ void
prot_free(Repl_Protocol **rpp)
{
Repl_Protocol *rp = NULL;
- PRIntervalTime interval;
if (rpp == NULL || *rpp == NULL) return;
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index f669900..0d2f195 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1528,6 +1528,12 @@ _replica_get_config_entry (const Slapi_DN *root)
Slapi_PBlock *pb = NULL;
dn = _replica_get_config_dn (root);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "_replica_get_config_entry: failed to get the config dn for %s\n",
+ slapi_sdn_get_dn (root));
+ return NULL;
+ }
pb = slapi_pblock_new ();
slapi_search_internal_set_pb (pb, dn, LDAP_SCOPE_BASE, "objectclass=*", NULL, 0, NULL,
@@ -1839,8 +1845,9 @@ _replica_get_config_dn (const Slapi_DN *root)
PR_ASSERT (root);
- dn = slapi_ch_smprintf("%s,cn=\"%s\",%s", REPLICA_RDN, slapi_sdn_get_dn (root), mp_base);
-
+ /* This function converts the old style DN to the new style. */
+ dn = slapi_create_dn_string("%s,cn=\"%s\",%s",
+ REPLICA_RDN, slapi_sdn_get_dn (root), mp_base);
return dn;
}
@@ -2162,6 +2169,13 @@ _replica_update_state (time_t when, void *arg)
r->repl_csn_assigned = PR_FALSE;
dn = _replica_get_config_dn (r->repl_root);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "_replica_update_state: failed to get the config dn for %s\n",
+ slapi_sdn_get_dn (r->repl_root));
+ PR_Unlock(r->repl_lock);
+ goto done;
+ }
pb = slapi_pblock_new();
mods[0] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod);
@@ -3057,6 +3071,14 @@ replica_replace_ruv_tombstone(Replica *r)
ruv_last_modified_to_smod ((RUV*)object_get_data(r->repl_ruv), &smod_last_modified);
dn = _replica_get_config_dn (r->repl_root);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "replica_replace_ruv_tombstone: "
+ "failed to get the config dn for %s\n",
+ slapi_sdn_get_dn (r->repl_root));
+ PR_Unlock(r->repl_lock);
+ goto bail;
+ }
mods[0] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod);
mods[1] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod_last_modified);
@@ -3090,6 +3112,7 @@ replica_replace_ruv_tombstone(Replica *r)
slapi_ch_free ((void**)&dn);
slapi_pblock_destroy (pb);
+bail:
slapi_mod_done (&smod);
slapi_mod_done (&smod_last_modified);
}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index af5b6cd..80b5361 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -47,6 +47,7 @@
#include "repl5.h"
#include "cl5_api.h"
+/* CONFIG_BASE: no need to optimize */
#define CONFIG_BASE "cn=mapping tree,cn=config"
#define CONFIG_FILTER "(objectclass=nsDS5Replica)"
#define TASK_ATTR "nsds5Task"
diff --git a/ldap/servers/plugins/replication/repl_init.c b/ldap/servers/plugins/replication/repl_init.c
index 5c89759..7a7c32c 100644
--- a/ldap/servers/plugins/replication/repl_init.c
+++ b/ldap/servers/plugins/replication/repl_init.c
@@ -207,6 +207,7 @@ legacy_entry_init( Slapi_PBlock *pb )
static int
create_config_top()
{
+ /* DN part of this entry_string: no need to be optimized. */
char *entry_string = slapi_ch_strdup("dn: cn=replication,cn=config\nobjectclass: top\nobjectclass: extensibleobject\ncn: replication\n");
Slapi_PBlock *pb = slapi_pblock_new();
Slapi_Entry *e = slapi_str2entry(entry_string, 0);
diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c
index 556dede..aedd616 100644
--- a/ldap/servers/plugins/retrocl/retrocl.c
+++ b/ldap/servers/plugins/retrocl/retrocl.c
@@ -266,6 +266,7 @@ char *retrocl_get_config_str(const char *attrt)
int rc = 0;
char *dn;
+ /* RETROCL_PLUGIN_DN is no need to be normalized. */
dn = RETROCL_PLUGIN_DN;
pb = slapi_pblock_new();
diff --git a/ldap/servers/plugins/retrocl/retrocl_create.c b/ldap/servers/plugins/retrocl/retrocl_create.c
index 88974b7..1ffdaae 100644
--- a/ldap/servers/plugins/retrocl/retrocl_create.c
+++ b/ldap/servers/plugins/retrocl/retrocl_create.c
@@ -77,6 +77,7 @@ static int retrocl_create_be(const char *bedir)
vals[1] = NULL;
e = slapi_entry_alloc();
+ /* RETROCL_LDBM_DN is no need to be normalized. */
slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_LDBM_DN));
/* Set the objectclass attribute */
@@ -142,6 +143,7 @@ static int retrocl_create_be(const char *bedir)
/* we need the changenumber indexed */
e = slapi_entry_alloc();
+ /* RETROCL_INDEX_DN is no need to be normalized. */
slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_INDEX_DN));
/* Set the objectclass attribute */
@@ -210,6 +212,7 @@ int retrocl_create_config(void)
struct berval *vals[2];
struct berval val;
int rc;
+ char *mappingtree_dn = NULL;
vals[0] = &val;
vals[1] = NULL;
@@ -219,7 +222,15 @@ int retrocl_create_config(void)
* in the errors file when the referenced backend does not exist.
*/
e = slapi_entry_alloc();
- slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_MAPPINGTREE_DN));
+ /* This function converts the old DN style to the new one. */
+ mappingtree_dn = slapi_create_dn_string("%s", RETROCL_MAPPINGTREE_DN);
+ if (NULL == mappingtree_dn) {
+ slapi_log_error (SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME,
+ "retrocl_create_config: failed to normalize "
+ "mappingtree dn %s\n", RETROCL_MAPPINGTREE_DN);
+ return LDAP_PARAM_ERROR;
+ }
+ slapi_entry_set_dn(e, mappingtree_dn); /* mappingtree_dn is consumed */
/* Set the objectclass attribute */
val.bv_val = "top";
diff --git a/ldap/servers/plugins/syntaxes/string.c b/ldap/servers/plugins/syntaxes/string.c
index 9b33833..21ff5d1 100644
--- a/ldap/servers/plugins/syntaxes/string.c
+++ b/ldap/servers/plugins/syntaxes/string.c
@@ -63,6 +63,7 @@ string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax,
{
int i, rc;
struct berval bvfilter_norm;
+ char *alt = NULL;
if(retVal) {
*retVal = NULL;
@@ -74,7 +75,12 @@ string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax,
bvfilter_norm.bv_val = slapi_ch_malloc( bvfilter->bv_len + 1 );
SAFEMEMCPY( bvfilter_norm.bv_val, bvfilter->bv_val, bvfilter->bv_len );
bvfilter_norm.bv_val[bvfilter->bv_len] = '\0';
- value_normalize( bvfilter_norm.bv_val, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( bvfilter_norm.bv_val, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&bvfilter_norm.bv_val);
+ bvfilter_norm.bv_val = alt;
+ }
bvfilter_norm.bv_len = strlen(bvfilter_norm.bv_val);
for ( i = 0; (bvals != NULL) && (bvals[i] != NULL); i++ ) {
@@ -211,6 +217,7 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
Operation *op = NULL;
Slapi_Regex *re = NULL;
const char *re_result = NULL;
+ char *alt = NULL;
LDAPDebug( LDAP_DEBUG_FILTER, "=> string_filter_sub\n",
0, 0, 0 );
@@ -260,27 +267,45 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
}
if ( initial != NULL ) {
- value_normalize( initial, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( initial, syntax, 1, &alt );
*p++ = '^';
- filter_strcpy_special_ext( p, initial, FILTER_STRCPY_ESCAPE_RECHARS );
+ if (alt) {
+ filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS );
+ slapi_ch_free_string(&alt);
+ } else {
+ filter_strcpy_special_ext( p, initial, FILTER_STRCPY_ESCAPE_RECHARS );
+ }
p = strchr( p, '\0' );
}
if ( any != NULL ) {
for ( i = 0; any[i] != NULL; i++ ) {
- value_normalize( any[i], syntax, 0 /* DO NOT trim leading blanks */ );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( any[i], syntax, 0, &alt );
/* ".*" + value */
*p++ = '.';
*p++ = '*';
- filter_strcpy_special_ext( p, any[i], FILTER_STRCPY_ESCAPE_RECHARS );
+ if (alt) {
+ filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS );
+ slapi_ch_free_string(&alt);
+ } else {
+ filter_strcpy_special_ext( p, any[i], FILTER_STRCPY_ESCAPE_RECHARS );
+ }
p = strchr( p, '\0' );
}
}
if ( final != NULL ) {
- value_normalize( final, syntax, 0 /* DO NOT trim leading blanks */ );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( final, syntax, 0, &alt );
/* ".*" + value */
*p++ = '.';
*p++ = '*';
- filter_strcpy_special_ext( p, final, FILTER_STRCPY_ESCAPE_RECHARS );
+ if (alt) {
+ filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS );
+ slapi_ch_free_string(&alt);
+ } else {
+ filter_strcpy_special_ext( p, final, FILTER_STRCPY_ESCAPE_RECHARS );
+ }
strcat( p, "$" );
}
@@ -327,9 +352,15 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
strcpy( tmpbuf, bvp->bv_val );
realval = tmpbuf;
}
- value_normalize( realval, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( realval, syntax, 1, &alt );
- tmprc = slapi_re_exec( re, realval, time_up );
+ if (alt) {
+ tmprc = slapi_re_exec( re, alt, time_up );
+ slapi_ch_free_string(&alt);
+ } else {
+ tmprc = slapi_re_exec( re, realval, time_up );
+ }
LDAPDebug( LDAP_DEBUG_TRACE, "re_exec (%s) %i\n",
escape_string( realval, ebuf ), tmprc, 0 );
@@ -359,6 +390,7 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
Slapi_Value **nbvals, **nbvlp;
Slapi_Value **bvlp;
char *w, *c, *p;
+ char *alt = NULL;
if (NULL == ivals) {
return 1;
@@ -380,9 +412,16 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
{
c = slapi_ch_strdup(slapi_value_get_string(*bvlp));
/* if the NORMALIZED flag is set, skip normalizing */
- if (!(slapi_value_get_flags(*bvlp) & SLAPI_ATTR_FLAG_NORMALIZED))
- value_normalize( c, syntax, 1 /* trim leading blanks */ );
- *nbvlp = slapi_value_new_string_passin(c);
+ if (!(slapi_value_get_flags(*bvlp) & SLAPI_ATTR_FLAG_NORMALIZED)) {
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( c, syntax, 1, &alt );
+ }
+ if (alt) {
+ slapi_ch_free_string(&c);
+ *nbvlp = slapi_value_new_string_passin(alt);
+ } else {
+ *nbvlp = slapi_value_new_string_passin(c);
+ }
}
*ivals = nbvals;
break;
@@ -470,14 +509,16 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
for ( bvlp = bvals; bvlp && *bvlp; bvlp++ ) {
/*
* Note: this calculation may err on the high side,
- * because value_normalize(), which is called below
+ * because value_normalize_ext(), which is called below
* before we actually create the substring keys, may
- * reduce the length of the value in some cases. For
- * example, spaces are removed when space insensitive
- * strings are normalized. But it's okay for nsubs to
- * be too big. Since the ivals array is NULL terminated,
- * the only downside is that we allocate more space than
- * we really need.
+ * reduce the length of the value in some cases or
+ * increase the length in other cases. For example,
+ * spaces are removed when space insensitive strings
+ * are normalized. Or if the value includes '\"' (2 bytes),
+ * it's normalized to '\22' (3 bytes). But it's okay
+ * for nsubs to be too big. Since the ivals array is
+ * NULL terminated, the only downside is that we
+ * allocate more space than we really need.
*/
nsubs += slapi_value_get_length(*bvlp) - substrlens[INDEX_SUBSTRMIDDLE] + 3;
}
@@ -489,8 +530,14 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
bvdup= slapi_value_new();
for ( bvlp = bvals; bvlp && *bvlp; bvlp++ ) {
c = slapi_ch_strdup(slapi_value_get_string(*bvlp));
- value_normalize( c, syntax, 1 /* trim leading blanks */ );
- slapi_value_set_string_passin(bvdup, c);
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( c, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&c);
+ slapi_value_set_string_passin(bvdup, alt);
+ } else {
+ slapi_value_set_string_passin(bvdup, c);
+ }
bvp = slapi_value_get_berval(bvdup);
@@ -554,6 +601,7 @@ string_assertion2keys_ava(
size_t len;
char *w, *c;
Slapi_Value *tmpval=NULL;
+ char *alt = NULL;
switch ( ftype ) {
case LDAP_FILTER_EQUALITY_FAST:
@@ -565,13 +613,23 @@ string_assertion2keys_ava(
}
memcpy(tmpval->bv.bv_val,slapi_value_get_string(val),len);
tmpval->bv.bv_val[len]='\0';
- value_normalize(tmpval->bv.bv_val, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext(tmpval->bv.bv_val, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&tmpval->bv.bv_val);
+ tmpval->bv.bv_val = alt;
+ }
tmpval->bv.bv_len=strlen(tmpval->bv.bv_val);
break;
case LDAP_FILTER_EQUALITY:
(*ivals) = (Slapi_Value **) slapi_ch_malloc( 2 * sizeof(Slapi_Value *) );
(*ivals)[0] = slapi_value_dup( val );
- value_normalize( (*ivals)[0]->bv.bv_val, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( (*ivals)[0]->bv.bv_val, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&(*ivals)[0]->bv.bv_val);
+ (*ivals)[0]->bv.bv_val = alt;
+ }
(*ivals)[0]->bv.bv_len = strlen( (*ivals)[0]->bv.bv_val );
(*ivals)[1] = NULL;
break;
@@ -628,6 +686,10 @@ string_assertion2keys_sub(
int localsublens[3] = {SUBBEGIN, SUBMIDDLE, SUBEND};/* default values */
int maxsublen;
char *comp_buf = NULL;
+ char *altinit = NULL;
+ char **altany = NULL;
+ char *altfinal = NULL;
+ int anysize = 0;
slapi_pblock_get(pb, SLAPI_SYNTAX_SUBSTRLENS, &substrlens);
@@ -650,13 +712,17 @@ string_assertion2keys_sub(
* First figure out how many keys we will return. The answer is based
* on the length of each assertion value. Since normalization may
* reduce the length (such as when spaces are removed from space
- * insensitive strings), we call value_normalize() before checking
+ * insensitive strings), we call value_normalize_ext() before checking
* the length.
*/
nsubs = 0;
if ( initial != NULL ) {
- value_normalize( initial, syntax, 0 /* do not trim leading blanks */ );
- initiallen = strlen( initial );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( initial, syntax, 0, &altinit );
+ if (NULL == altinit) {
+ altinit = initial;
+ }
+ initiallen = strlen( altinit );
if ( initiallen > substrlens[INDEX_SUBSTRBEGIN] - 2 ) {
nsubs += 1; /* for the initial begin string key */
/* the rest of the sub keys are "any" keys for this case */
@@ -664,19 +730,31 @@ string_assertion2keys_sub(
nsubs += initiallen - substrlens[INDEX_SUBSTRMIDDLE] + 1;
}
} else {
- initial = NULL; /* save some work later */
+ altinit = NULL; /* save some work later */
}
}
for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
- value_normalize( any[i], syntax, 0 /* do not trim leading blanks */ );
- len = strlen( any[i] );
+ anysize++;
+ }
+ altany = (char **)slapi_ch_calloc(anysize + 1, sizeof(char *));
+ for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( any[i], syntax, 0, &altany[i] );
+ if (NULL == altany[i]) {
+ altany[i] = any[i];
+ }
+ len = strlen( altany[i] );
if ( len >= substrlens[INDEX_SUBSTRMIDDLE] ) {
nsubs += len - substrlens[INDEX_SUBSTRMIDDLE] + 1;
}
}
if ( final != NULL ) {
- value_normalize( final, syntax, 0 /* do not trim leading blanks */ );
- finallen = strlen( final );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( final, syntax, 0, &altfinal );
+ if (NULL == altfinal) {
+ altfinal = final;
+ }
+ finallen = strlen( altfinal );
if ( finallen > substrlens[INDEX_SUBSTREND] - 2 ) {
nsubs += 1; /* for the final end string key */
/* the rest of the sub keys are "any" keys for this case */
@@ -684,7 +762,7 @@ string_assertion2keys_sub(
nsubs += finallen - substrlens[INDEX_SUBSTRMIDDLE] + 1;
}
} else {
- final = NULL; /* save some work later */
+ altfinal = NULL; /* save some work later */
}
}
if ( nsubs == 0 ) { /* no keys to return */
@@ -703,21 +781,31 @@ string_assertion2keys_sub(
nsubs = 0;
comp_buf = (char *)slapi_ch_malloc(maxsublen + 1);
- if ( initial != NULL ) {
- substring_comp_keys( ivals, &nsubs, initial, initiallen, '^', syntax,
+ if ( altinit != NULL ) {
+ substring_comp_keys( ivals, &nsubs, altinit, initiallen, '^', syntax,
comp_buf, substrlens );
+ if (altinit != initial) {
+ slapi_ch_free_string(&altinit);
+ }
}
- for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
- len = strlen( any[i] );
+ for ( i = 0; altany != NULL && altany[i] != NULL; i++ ) {
+ len = strlen( altany[i] );
if ( len < substrlens[INDEX_SUBSTRMIDDLE] ) {
continue;
}
- substring_comp_keys( ivals, &nsubs, any[i], len, 0, syntax,
+ substring_comp_keys( ivals, &nsubs, altany[i], len, 0, syntax,
comp_buf, substrlens );
+ if (altany[i] != any[i]) {
+ slapi_ch_free_string(&altany[i]);
+ }
}
- if ( final != NULL ) {
- substring_comp_keys( ivals, &nsubs, final, finallen, '$', syntax,
+ slapi_ch_free((void **)&altany);
+ if ( altfinal != NULL ) {
+ substring_comp_keys( ivals, &nsubs, altfinal, finallen, '$', syntax,
comp_buf, substrlens );
+ if (altfinal != final) {
+ slapi_ch_free_string(&final);
+ }
}
(*ivals)[nsubs] = NULL;
slapi_ch_free_string(&comp_buf);
diff --git a/ldap/servers/plugins/syntaxes/syntax.h b/ldap/servers/plugins/syntaxes/syntax.h
index ec3d5f0..64942ec 100644
--- a/ldap/servers/plugins/syntaxes/syntax.h
+++ b/ldap/servers/plugins/syntaxes/syntax.h
@@ -113,6 +113,7 @@ int string_assertion2keys_ava(Slapi_PBlock *pb,Slapi_Value *val,Slapi_Value ***i
int string_assertion2keys_sub(Slapi_PBlock *pb,char *initial,char **any,char *final,Slapi_Value ***ivals,int syntax);
int value_cmp(struct berval *v1,struct berval *v2,int syntax,int normalize);
void value_normalize(char *s,int syntax,int trim_leading_blanks);
+void value_normalize_ext(char *s,int syntax,int trim_leading_blanks, char **alt);
char *first_word( char *s );
char *next_word( char *s );
diff --git a/ldap/servers/plugins/syntaxes/validate.c b/ldap/servers/plugins/syntaxes/validate.c
index aab6d9c..989137b 100644
--- a/ldap/servers/plugins/syntaxes/validate.c
+++ b/ldap/servers/plugins/syntaxes/validate.c
@@ -362,7 +362,6 @@ int distinguishedname_validate(
{
int rc = 0; /* Assume value is valid */
char *val_copy = NULL;
- int strict = 0;
const char *p = begin;
const char *last = NULL;
@@ -377,17 +376,6 @@ int distinguishedname_validate(
* attributeValue = string / hexstring
*/
- /* Check if we should be performing strict validation. */
- strict = config_get_dn_validate_strict();
- if (!strict) {
- /* Create a normalized copy of the value to use
- * for validation. The original value will be
- * stored in the backend unmodified. */
- val_copy = PL_strndup(begin, end - begin + 1);
- p = val_copy;
- end = slapi_dn_normalize_to_end(val_copy, NULL) - 1;
- }
-
/* Validate one RDN at a time in a loop. */
while (p <= end) {
if ((rc = rdn_validate(p, end, &last)) != 0) {
diff --git a/ldap/servers/plugins/syntaxes/value.c b/ldap/servers/plugins/syntaxes/value.c
index f127b6b..9b048f3 100644
--- a/ldap/servers/plugins/syntaxes/value.c
+++ b/ldap/servers/plugins/syntaxes/value.c
@@ -86,23 +86,40 @@ utf8isspace_fast( char* s )
** Also note that this deviates from rfc 4517 INTEGER syntax, but we must
** support legacy clients for the time being
*/
+/*
+ * alt stores the normalized value in case the normalized value is longer
+ * than the original value. It may happen the value is DN.
+ */
void
-value_normalize(
+value_normalize_ext(
char *s,
int syntax,
- int trim_spaces
+ int trim_spaces,
+ char **alt
)
{
char *head = s;
char *d;
int prevspace, curspace;
+ if (NULL == alt) {
+ return;
+ }
+ *alt = NULL;
+
if ( ! (syntax & SYNTAX_CIS) && ! (syntax & SYNTAX_CES) ) {
return;
}
if ( syntax & SYNTAX_DN ) {
- (void) slapi_dn_normalize_case( s );
+ char *dest = NULL;
+ size_t dlen = 0;
+ int rc = slapi_dn_normalize_case_ext(s, 0, &dest, &dlen);
+ if (rc > 0) {
+ *alt = dest;
+ } else if (rc == 0) { /* normalized in line; not terminated */
+ *(dest + dlen) = '\0';
+ }
return;
}
@@ -203,6 +220,16 @@ value_normalize(
}
}
+void
+value_normalize(
+ char *s,
+ int syntax,
+ int trim_spaces
+)
+{
+ /* deprecated */
+}
+
int
value_cmp(
struct berval *v1,
@@ -220,6 +247,7 @@ value_cmp(
int free_v1 = 0;
int free_v2 = 0;
int v1sign = 1, v2sign = 1; /* default to positive */
+ char *alt = NULL;
/* This code used to call malloc up to four times in the copying
* of attributes to be normalized. Now we attempt to keep everything
@@ -233,13 +261,35 @@ value_cmp(
bvcopy1.bv_val = &little_buffer[buffer_offset];
bvcopy1.bv_val[v1->bv_len] = '\0';
v1 = &bvcopy1;
- buffer_space-= v1->bv_len+1;
- buffer_offset+= v1->bv_len+1;
} else {
v1 = ber_bvdup( v1 );
free_v1 = 1;
}
- value_normalize( v1->bv_val, syntax, 1 /* trim leading blanks */ );
+ value_normalize_ext( v1->bv_val, syntax,
+ 1 /* trim leading blanks */, &alt );
+ if (alt) {
+ if (free_v1) {
+ slapi_ch_free_string(&v1->bv_val);
+ v1->bv_val = alt;
+ v1->bv_len = strlen(alt);
+ } else {
+ if (strlen(alt) < buffer_space) {
+ v1->bv_len = strlen(alt);
+ /* Copying to little_buffer */
+ SAFEMEMCPY(v1->bv_val, alt, v1->bv_len);
+ *(v1->bv_val + v1->bv_len) = '\0';
+ } else {
+ free_v1 = 1;
+ v1 = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+ v1->bv_val = alt;
+ v1->bv_len = strlen(alt);
+ }
+ }
+ }
+ if (!free_v1) {
+ buffer_space -= v1->bv_len + 1;
+ buffer_offset += v1->bv_len + 1;
+ }
}
if ( normalize & 2 ) {
/* Do we have space in the little buffer ? */
@@ -249,13 +299,35 @@ value_cmp(
bvcopy2.bv_val = &little_buffer[buffer_offset];
bvcopy2.bv_val[v2->bv_len] = '\0';
v2 = &bvcopy2;
- buffer_space-= v2->bv_len+1;
- buffer_offset+= v2->bv_len+1;
} else {
v2 = ber_bvdup( v2 );
free_v2 = 1;
}
- value_normalize( v2->bv_val, syntax, 1 /* trim leading blanks */ );
+ value_normalize_ext( v2->bv_val, syntax,
+ 1 /* trim leading blanks */, &alt );
+ if (alt) {
+ if (free_v2) {
+ slapi_ch_free_string(&v2->bv_val);
+ v2->bv_val = alt;
+ v2->bv_len = strlen(alt);
+ } else {
+ if (strlen(alt) < buffer_space) {
+ v2->bv_len = strlen(alt);
+ /* Copying to little_buffer */
+ SAFEMEMCPY(v2->bv_val, alt, v2->bv_len);
+ *(v2->bv_val + v2->bv_len) = '\0';
+ } else {
+ free_v2 = 1;
+ v2 = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+ v2->bv_val = alt;
+ v2->bv_len = strlen(alt);
+ }
+ }
+ }
+ if (!free_v2) {
+ buffer_space -= v2->bv_len + 1;
+ buffer_offset += v2->bv_len + 1;
+ }
}
if (syntax & SYNTAX_INT) {
diff --git a/ldap/servers/plugins/usn/usn_cleanup.c b/ldap/servers/plugins/usn/usn_cleanup.c
index bf13073..1c92a5a 100644
--- a/ldap/servers/plugins/usn/usn_cleanup.c
+++ b/ldap/servers/plugins/usn/usn_cleanup.c
@@ -194,8 +194,15 @@ _usn_cleanup_is_mmr_enabled(const char *suffix)
char *base_dn = NULL;
int rc = 0; /* disabled, by default */
- base_dn = slapi_ch_smprintf("cn=replica,cn=\"%s\",%s",
- suffix, MAPPING_TREE_BASE_DN);
+ /* This function converts the old style DN to the new one */
+ base_dn = slapi_create_dn_string("cn=replica,cn=\"%s\",%s",
+ suffix, MAPPING_TREE_BASE_DN);
+ if (NULL == base_dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM,
+ "_usn_cleanup_is_mmr_enabled: failed to normalize "
+ "mappingtree dn for %s\n", suffix);
+ return 1;
+ }
search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, base_dn, LDAP_SCOPE_ONELEVEL,
"objectclass=nsDS5ReplicationAgreement",
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index 1a1f867..0e7d5c8 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -115,20 +115,47 @@ do_add( Slapi_PBlock *pb )
*/
/* get the name */
{
- char *dn = NULL;
- if ( ber_scanf( ber, "{a", &dn ) == LBER_ERROR ) {
- slapi_ch_free_string(&dn);
- LDAPDebug( LDAP_DEBUG_ANY,
- "ber_scanf failed (op=Add; params=DN)\n", 0, 0, 0 );
+ char *rawdn = NULL;
+ char *dn = NULL;
+ size_t dnlen = 0;
+ if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR ) {
+ slapi_ch_free_string(&rawdn);
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "ber_scanf failed (op=Add; params=DN)\n", 0, 0, 0 );
op_shared_log_error_access (pb, "ADD", "???", "decoding error");
- send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
- "decoding error", 0, NULL );
- return;
- }
- e = slapi_entry_alloc();
- slapi_entry_init(e,dn,NULL); /* Responsibility for DN is passed to the Entry. */
- }
- LDAPDebug( LDAP_DEBUG_ARGS, " do_add: dn (%s)\n", slapi_entry_get_dn_const(e), 0, 0 );
+ send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
+ "decoding error", 0, NULL );
+ return;
+ }
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ } else if (rc > 0) {
+ slapi_ch_free_string(&rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
+ e = slapi_entry_alloc();
+ slapi_entry_init(e,dn,NULL); /* Responsibility for DN is passed to the Entry. */
+ }
+ LDAPDebug( LDAP_DEBUG_ARGS, " do_add: dn (%s)\n", slapi_entry_get_dn_const(e), 0, 0 );
/* get the attrs */
for ( tag = ber_first_element( ber, &len, &last );
diff --git a/ldap/servers/slapd/attrlist.c b/ldap/servers/slapd/attrlist.c
index b200472..9c32990 100644
--- a/ldap/servers/slapd/attrlist.c
+++ b/ldap/servers/slapd/attrlist.c
@@ -289,6 +289,9 @@ int attrlist_replace(Slapi_Attr **alist, const char *type, struct berval **vals)
} else {
attrlist_find_or_create(alist, type, &a);
valuearray_init_bervalarray(vals, &values);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ valuearray_normalize_value(values);
+ }
rc = attr_replace(*a, values);
}
return rc;
@@ -312,6 +315,9 @@ int attrlist_replace_with_flags(Slapi_Attr **alist, const char *type, struct ber
} else {
attrlist_find_or_create(alist, type, &a);
valuearray_init_bervalarray_with_flags(vals, &values, flags);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ valuearray_normalize_value(values);
+ }
rc = attr_replace(*a, values);
}
return rc;
diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c
index 698c1cd..65f3bb0 100644
--- a/ldap/servers/slapd/attrsyntax.c
+++ b/ldap/servers/slapd/attrsyntax.c
@@ -819,6 +819,23 @@ slapi_attr_get_syntax_oid_copy( const Slapi_Attr *a, char **oidp )
}
}
+int
+slapi_attr_is_dn_syntax_attr(Slapi_Attr *attr)
+{
+ char *syntaxoid = NULL;
+ int dn_syntax = 0; /* not DN, by default */
+
+ if (attr->a_plugin) { /* If not set, there is no way to get the info */
+ slapi_attr_get_syntax_oid_copy(attr, &syntaxoid);
+ if (syntaxoid) {
+ dn_syntax = ((0 == strcmp(syntaxoid, NAMEANDOPTIONALUID_SYNTAX_OID))
+ || (0 == strcmp(syntaxoid, DN_SYNTAX_OID)));
+ slapi_ch_free_string(&syntaxoid);
+ }
+ }
+ return dn_syntax;
+}
+
#ifdef ATTR_LDAP_DEBUG
PRIntn
diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c
index 3a500eb..e483f6e 100644
--- a/ldap/servers/slapd/auth.c
+++ b/ldap/servers/slapd/auth.c
@@ -75,15 +75,33 @@ slapu_msgfree( LDAP* ld, LDAPMessage* msg )
}
static int LDAP_CALL LDAP_CALLBACK
-slapu_search_s( LDAP* ld, const char* baseDN, int scope, const char* filter,
+slapu_search_s( LDAP* ld, const char* rawbaseDN, int scope, const char* filter,
char** attrs, int attrsonly, LDAPMessage** result )
{
int err = LDAP_NO_SUCH_OBJECT;
- Slapi_PBlock* pb;
+ Slapi_PBlock* pb = NULL;
LDAPControl **ctrls;
+ char *baseDN = slapi_ch_strdup(rawbaseDN);
+ char *normDN = NULL;
+ size_t dnlen = 0;
+
+ err = slapi_dn_normalize_ext(baseDN, 0, &normDN, &dnlen);
+ if (err < 0) {
+ err = LDAP_INVALID_DN_SYNTAX;
+ LDAPDebug (LDAP_DEBUG_TRACE, "<= slapu_search_s %i\n", err, 0, 0);
+ return err;
+ } else if (err == 0) { /* baseDN is passed in; not terminated */
+ *(normDN + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&baseDN);
+ baseDN = normDN;
+ }
if (ld != internal_ld) {
- return ldap_search_ext_s (ld, baseDN, scope, filter, attrs, attrsonly, NULL, NULL, NULL, -1, result);
+ err = ldap_search_ext_s(ld, baseDN, scope, filter, attrs, attrsonly,
+ NULL, NULL, NULL, -1, result);
+ slapi_ch_free_string(&baseDN);
+ return err;
}
LDAPDebug (LDAP_DEBUG_TRACE, "=> slapu_search_s (\"%s\", %i, %s)\n",
baseDN, scope, filter);
@@ -120,6 +138,7 @@ slapu_search_s( LDAP* ld, const char* baseDN, int scope, const char* filter,
LDAPDebug (LDAP_DEBUG_ANY, "slapi_search_internal (\"%s\", %i, %s) NULL\n",
escape_string( (char*)baseDN, ebuf ), scope, escape_string( (char*)filter, fbuf ));
}
+ slapi_ch_free_string(&baseDN);
*result = (LDAPMessage*)pb;
LDAPDebug (LDAP_DEBUG_TRACE, "<= slapu_search_s %i\n", err, 0, 0);
return err;
@@ -486,8 +505,8 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
if (err == LDAPU_SUCCESS && chain) {
LDAPMessage* entry = slapu_first_entry (internal_ld, chain);
if (entry) {
+ /* clientDN is duplicated in slapu_get_dn */
clientDN = slapu_get_dn (internal_ld, entry);
- if (clientDN) slapi_dn_normalize (clientDN);
} else {
extraErrorMsg = "no entry";
@@ -507,12 +526,27 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
if (clientDN != NULL) {
char ebuf[ BUFSIZ ];
- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL client bound as %s\n",
- conn->c_connid, escape_string( clientDN, ebuf ));
+ int rc = 0;
+ char *normedDN = NULL;
+ size_t dnlen = 0;
+
+ rc = slapi_dn_normalize_ext(clientDN, 0, &normedDN, &dnlen);
+ if (rc < 0) {
+ /* ignoring the normalization error, use the pre normalized DN */
+ } else if (rc == 0) { /* clientDN is passed in; not terminated */
+ *(normedDN + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&clientDN);
+ clientDN = normedDN;
+ }
+ slapi_log_access (LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " SSL client bound as %s\n",
+ conn->c_connid, escape_string( clientDN, ebuf ));
} else if (clientCert != NULL) {
slapi_log_access (LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL failed to map client certificate to LDAP DN (%s)\n",
- conn->c_connid, extraErrorMsg );
+ "conn=%" NSPRIu64 " SSL failed to map client "
+ "certificate to LDAP DN (%s)\n",
+ conn->c_connid, extraErrorMsg );
}
/*
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
index 6cc1b66..264eb90 100644
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
@@ -533,6 +533,7 @@ import_producer(void *param)
FREE(estr);
continue;
}
+ /* get_value_from_string decodes base64 if it is encoded. */
rc = get_value_from_string((const char *)estr, "dn", &dn);
if (rc) {
import_log_notice(job, "WARNING: skipping bad LDIF entry (dn "
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
index 6717674..6600f00 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
@@ -142,13 +142,25 @@ attrcrypt_keymgmt_get_key(ldbm_instance *li, attrcrypt_cipher_state *acs, SECKEY
{
int ret = 0;
Slapi_Entry *entry = NULL;
- char *dn_template = "cn=%s,cn=encrypted attribute keys,cn=%s,cn=ldbm database,cn=plugins,cn=config";
+ char *dn_template = "cn=%s,cn=encrypted attribute keys,cn=%s,cn=%s,cn=plugins,cn=config";
char *instance_name = li->inst_name;
- char *dn_string = NULL;
Slapi_Attr *keyattr = NULL;
+ char *dn_string = NULL;
LDAPDebug(LDAP_DEBUG_TRACE,"-> attrcrypt_keymgmt_get_key\n", 0, 0, 0);
- dn_string = slapi_ch_smprintf(dn_template, acs->ace->cipher_display_name, instance_name);
+ dn_string = slapi_create_dn_string(dn_template,
+ acs->ace->cipher_display_name, instance_name,
+ li->inst_li->li_plugin->plg_name);
+ if (NULL == dn_string) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "attrcrypt_keymgmt_get_key: "
+ "failed create attrcrypt key dn for plugin %s, "
+ "instance %s, cypher %s\n",
+ li->inst_li->li_plugin->plg_name,
+ li->inst_name, acs->ace->cipher_display_name);
+ ret = -1;
+ goto bail;
+ }
/* Fetch the entry */
getConfigEntry(dn_string, &entry);
/* Did we find the entry ? */
@@ -170,6 +182,7 @@ attrcrypt_keymgmt_get_key(ldbm_instance *li, attrcrypt_cipher_state *acs, SECKEY
} else {
ret = -2; /* Means: we didn't find the entry (which happens if the key has never been generated) */
}
+bail:
slapi_ch_free_string(&dn_string);
LDAPDebug(LDAP_DEBUG_TRACE,"<- attrcrypt_keymgmt_get_key\n", 0, 0, 0);
return ret;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
index 60c3928..ecef74b 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
@@ -1047,7 +1047,7 @@ static int ldbm_config_entryrdn_switch_set(void *arg, void *value,
if (apply) {
entryrdn_set_switch((int)((uintptr_t)value));
}
- return LDAP_SUCCESS;
+ return LDAP_SUCCESS;
}
static void *ldbm_config_entryrdn_noancestorid_get(void *arg)
@@ -1061,7 +1061,7 @@ static int ldbm_config_entryrdn_noancestorid_set(void *arg, void *value,
if (apply) {
entryrdn_set_noancestorid((int)((uintptr_t)value));
}
- return LDAP_SUCCESS;
+ return LDAP_SUCCESS;
}
static void *ldbm_config_legacy_errcode_get(void *arg)
@@ -1296,11 +1296,17 @@ void
ldbm_config_read_instance_entries(struct ldbminfo *li, const char *backend_type)
{
Slapi_PBlock *tmp_pb;
- char basedn[BUFSIZ];
Slapi_Entry **entries = NULL;
+ char *basedn = NULL;
/* Construct the base dn of the subtree that holds the instance entries. */
- PR_snprintf(basedn, BUFSIZ, "cn=%s, cn=plugins, cn=config", backend_type);
+ basedn = slapi_create_dn_string("cn=%s,cn=plugins,cn=config", backend_type);
+ if (NULL == basedn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_read_instance_entries: "
+ "failed create backend dn for %s\n", backend_type);
+ return;
+ }
/* Do a search of the subtree containing the instance entries */
tmp_pb = slapi_pblock_new();
@@ -1327,29 +1333,38 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
{
Slapi_PBlock *search_pb;
Slapi_Entry **entries = NULL;
- int res;
- char dn[BUFSIZ];
+ char *dn = NULL;
+ int rval = 0;
/* We try to read the entry
* cn=config, cn=ldbm database, cn=plugins, cn=config. If the entry is
* there, then we process the config information it stores.
*/
- PR_snprintf(dn, BUFSIZ, "cn=config, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=config,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create config dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, dn, LDAP_SCOPE_BASE,
"objectclass=*", NULL, 0, NULL, NULL, li->li_identity, 0);
slapi_search_internal_pb (search_pb);
- slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rval);
- if (LDAP_NO_SUCH_OBJECT == res) {
+ if (LDAP_NO_SUCH_OBJECT == rval) {
/* Add skeleten dse entries for the ldbm plugin */
ldbm_config_add_dse_entries(li, ldbm_skeleton_entries,
li->li_plugin->plg_name, NULL, NULL, 0);
- } else if (res != LDAP_SUCCESS) {
+ } else if (rval != LDAP_SUCCESS) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the ldbm config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
} else {
/* Need to parse the configuration information for the ldbm
* plugin that is held in the DSE. */
@@ -1358,12 +1373,14 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
if (NULL == entries || entries[0] == NULL) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the ldbm config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
if (0 != parse_ldbm_config_entry(li, entries[0], ldbm_config)) {
LDAPDebug(LDAP_DEBUG_ANY, "Error parsing the ldbm config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
}
@@ -1377,8 +1394,6 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
ldbm_config_read_instance_entries(li, li->li_plugin->plg_name);
/* setup the dse callback functions for the ldbm backend config entry */
- PR_snprintf(dn, BUFSIZ, "cn=config, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_config_search_entry_callback,
(void *) li);
@@ -1388,24 +1403,52 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
slapi_config_register_callback(DSE_OPERATION_WRITE, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_config_search_entry_callback,
(void *) li);
+ slapi_ch_free_string(&dn);
/* setup the dse callback functions for the ldbm backend monitor entry */
- PR_snprintf(dn, BUFSIZ, "cn=monitor, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=monitor,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create monitor dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_monitor_search,
(void *)li);
+ slapi_ch_free_string(&dn);
/* And the ldbm backend database monitor entry */
- PR_snprintf(dn, BUFSIZ, "cn=database, cn=monitor, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=database,cn=monitor,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create monitor database dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_dbmonitor_search,
(void *)li);
+ slapi_ch_free_string(&dn);
/* setup the dse callback functions for the ldbm backend instance
* entries */
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=plugins, cn=config", li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create plugin dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsBackendInstance)",
ldbm_instance_add_instance_entry_callback, (void *) li);
@@ -1418,8 +1461,9 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsBackendInstance)",
ldbm_instance_post_delete_instance_entry_callback, (void *) li);
-
- return 0;
+bail:
+ slapi_ch_free_string(&dn);
+ return rval;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
index 9dc0f98..503c0fc 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
@@ -622,6 +622,7 @@ int ldbm_instance_config_add_index_entry(
char tmpIndexesStr[256];
char tmpMatchingRulesStr[1024];
struct ldbminfo *li = inst->inst_li;
+ char *dn = NULL;
if ((argc < 2) || (NULL == argv) || (NULL == argv[0]) ||
(NULL == argv[1])) {
@@ -642,31 +643,42 @@ int ldbm_instance_config_add_index_entry(
{
if('\0' == attrs[i][0]) continue;
basetype = slapi_attr_basetype(attrs[i], NULL, 0);
+ dn = slapi_create_dn_string("cn=%s,cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ basetype, inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_add_index_entry: "
+ "failed create index dn with type %s for plugin %s, "
+ "instance %s\n",
+ basetype, inst->inst_li->li_plugin->plg_name,
+ inst->inst_name);
+ return -1;
+ }
eBuf = PR_smprintf(
- "dn: cn=%s, cn=index, cn=%s, cn=%s, cn=plugins, cn=config\n"
- "objectclass:top\n"
- "objectclass:nsIndex\n"
- "cn:%s\n"
- "nsSystemIndex:%s\n",
- basetype, inst->inst_name, li->li_plugin->plg_name,
- basetype,
+ "dn: %s\n"
+ "objectclass: top\n"
+ "objectclass: nsIndex\n"
+ "cn: %s\n"
+ "nsSystemIndex: %s\n",
+ dn, basetype,
(ldbm_attribute_always_indexed(basetype)?"true":"false"));
+ slapi_ch_free_string(&dn);
for(j=0; indexes[j] != NULL; j++)
{
- eBuf = PR_sprintf_append(eBuf, "nsIndexType:%s\n", indexes[j]);
+ eBuf = PR_sprintf_append(eBuf, "nsIndexType:%s\n", indexes[j]);
}
if((argc>2)&&(argv[2]))
{
for(j=0; matchingRules[j] != NULL; j++)
{
- eBuf = PR_sprintf_append(eBuf, "nsMatchingRule:%s\n", matchingRules[j]);
+ eBuf = PR_sprintf_append(eBuf, "nsMatchingRule:%s\n", matchingRules[j]);
}
}
ldbm_config_add_dse_entry(li, eBuf, flags);
- if (eBuf) {
- PR_smprintf_free(eBuf);
- }
+ if (eBuf) {
+ PR_smprintf_free(eBuf);
+ }
slapi_ch_free((void**)&basetype);
}
@@ -722,10 +734,10 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
Slapi_Value *sval = NULL;
const struct berval *attrValue;
char *argv[ 8 ];
- char basedn[BUFSIZ];
char tmpBuf[MAX_TMPBUF];
char tmpBuf2[MAX_TMPBUF];
int argc;
+ char *basedn = NULL;
struct ldbminfo *li;
@@ -742,8 +754,15 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
strcpy(tmpBuf,"");
/* Construct the base dn of the subtree that holds the default user indexes. */
- PR_snprintf(basedn, BUFSIZ, "cn=default indexes, cn=config, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ basedn = slapi_create_dn_string("cn=default indexes,cn=config,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_instance_create_default_user_indexes: "
+ "failed create default index dn for plugin %s\n",
+ inst->inst_li->li_plugin->plg_name);
+ return -1;
+ }
/* Do a search of the subtree containing the index entries */
aPb = slapi_pblock_new();
@@ -821,5 +840,6 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
slapi_free_search_results_internal(aPb);
slapi_pblock_destroy(aPb);
+ slapi_ch_free_string(&basedn);
return 0;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
index f20836b..a6b1166 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
@@ -336,13 +336,20 @@ read_instance_index_entries(ldbm_instance *inst)
{
Slapi_PBlock *tmp_pb;
int scope = LDAP_SCOPE_SUBTREE;
- char basedn[BUFSIZ];
const char *searchfilter = "(objectclass=nsIndex)";
+ char *basedn = NULL;
/* Construct the base dn of the subtree that holds the index entries
* for this instance. */
- PR_snprintf(basedn, BUFSIZ, "cn=index, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ basedn = slapi_create_dn_string("cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "read_instance_index_entries: "
+ "failed create index dn for plugin %s, instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ return 1;
+ }
/* Set up a tmp callback that will handle the init for each index entry */
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
@@ -361,6 +368,7 @@ read_instance_index_entries(ldbm_instance *inst)
slapi_free_search_results_internal(tmp_pb);
slapi_pblock_destroy(tmp_pb);
+ slapi_ch_free_string(&basedn);
return 0;
}
@@ -372,13 +380,21 @@ read_instance_attrcrypt_entries(ldbm_instance *inst)
{
Slapi_PBlock *tmp_pb;
int scope = LDAP_SCOPE_SUBTREE;
- char basedn[BUFSIZ];
const char *searchfilter = ldbm_instance_attrcrypt_filter;
+ char *basedn = NULL;
/* Construct the base dn of the subtree that holds the index entries
* for this instance. */
- PR_snprintf(basedn, BUFSIZ, "cn=encrypted attributes, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ basedn = slapi_create_dn_string("cn=encrypted attributes,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "read_instance_attrcrypt_entries: "
+ "failed create encrypted attributes dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ return 1;
+ }
/* Set up a tmp callback that will handle the init for each index entry */
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
@@ -397,6 +413,7 @@ read_instance_attrcrypt_entries(ldbm_instance *inst)
slapi_free_search_results_internal(tmp_pb);
slapi_pblock_destroy(tmp_pb);
+ slapi_ch_free_string(&basedn);
return 0;
}
@@ -427,10 +444,11 @@ parse_ldbm_instance_config_entry(ldbm_instance *inst, Slapi_Entry *e, config_inf
Slapi_DN suffix;
slapi_attr_first_value(attr, &sval);
+
bval = (struct berval *) slapi_value_get_berval(sval);
slapi_sdn_init_dn_byref(&suffix, bval->bv_val);
if (!slapi_be_issuffix(inst->inst_be, &suffix)) {
- be_addsuffix(inst->inst_be, &suffix);
+ be_addsuffix(inst->inst_be, &suffix);
}
slapi_sdn_done(&suffix);
continue;
@@ -477,25 +495,34 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
struct ldbminfo *li = inst->inst_li;
Slapi_PBlock *search_pb;
Slapi_Entry **entries = NULL;
- int res;
- char dn[BUFSIZ];
+ char *dn = NULL;
+ int rval = 0;
/* We try to read the entry
* cn=instance_name, cn=ldbm database, cn=plugins, cn=config. If the
* entry is there, then we process the config information it stores.
*/
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create instance dn %s for plugin %s\n",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, dn, LDAP_SCOPE_BASE,
"objectclass=*", NULL, 0, NULL, NULL,
li->li_identity, 0);
slapi_search_internal_pb (search_pb);
- slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rval);
- if (res != LDAP_SUCCESS) {
+ if (rval != LDAP_SUCCESS) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the config DSE\n", 0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
} else {
/* Need to parse the configuration information for the ldbm
* plugin that is held in the DSE. */
@@ -504,13 +531,15 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
if ((!entries) || (!entries[0])) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
if (0 != parse_ldbm_instance_config_entry(inst, entries[0],
ldbm_instance_config)) {
LDAPDebug(LDAP_DEBUG_ANY, "Error parsing the config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
}
@@ -527,8 +556,6 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
inst->inst_name, 0);
/* setup the dse callback functions for the ldbm instance config entry */
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)",
ldbm_instance_search_config_entry_callback, (void *) inst);
@@ -543,9 +570,20 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
ldbm_instance_deny_config, (void *)inst);
/* delete is handled by a callback set in ldbm_config.c */
+ slapi_ch_free_string(&dn);
+
/* don't forget the monitor! */
- PR_snprintf(dn, BUFSIZ, "cn=monitor, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create monitor instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rval = 1;
+ goto bail;
+ }
/* make callback on search; deny add/modify/delete */
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_monitor_instance_search,
@@ -557,10 +595,20 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_instance_deny_config,
(void *)inst);
/* delete is okay */
+ slapi_ch_free_string(&dn);
/* Callbacks to handle indexes */
- PR_snprintf(dn, BUFSIZ, "cn=index, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create index instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_add_callback, (void *) inst);
@@ -570,10 +618,20 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_modify_callback, (void *) inst);
+ slapi_ch_free_string(&dn);
/* Callbacks to handle attribute encryption */
- PR_snprintf(dn, BUFSIZ, "cn=encrypted attributes, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=encrypted attributes,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create encrypted attribute instance dn "
+ "for plugin %s, instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, ldbm_instance_attrcrypt_filter,
ldbm_instance_attrcrypt_config_add_callback, (void *) inst);
@@ -583,8 +641,10 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, ldbm_instance_attrcrypt_filter,
ldbm_instance_attrcrypt_config_modify_callback, (void *) inst);
-
- return 0;
+ rval = 0;
+bail:
+ slapi_ch_free_string(&dn);
+ return rval;
}
/*
@@ -880,11 +940,19 @@ ldbm_instance_add_instance_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryBe
static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
{
struct ldbminfo *li = inst->inst_li;
- char dn[BUFSIZ];
+ char *dn = NULL;
/* tear down callbacks for the instance config entry */
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)",
ldbm_instance_search_config_entry_callback);
@@ -897,20 +965,38 @@ static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)",
ldbm_instance_deny_config);
+ slapi_ch_free_string(&dn);
/* now the cn=monitor entry */
- PR_snprintf(dn, BUFSIZ, "cn=monitor, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create monitor instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_monitor_instance_search);
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=*)", ldbm_instance_deny_config);
slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_instance_deny_config);
+ slapi_ch_free_string(&dn);
/* now the cn=index entries */
- PR_snprintf(dn, BUFSIZ, "cn=index, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create index dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_add_callback);
@@ -920,10 +1006,19 @@ static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_modify_callback);
+ slapi_ch_free_string(&dn);
/* now the cn=encrypted attributes entries */
- PR_snprintf(dn, BUFSIZ, "cn=encrypted attributes, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=encrypted attributes,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create encrypted attributes dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, ldbm_instance_attrcrypt_filter,
ldbm_instance_attrcrypt_config_add_callback);
@@ -935,6 +1030,8 @@ static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
ldbm_instance_attrcrypt_config_modify_callback);
vlv_remove_callbacks(inst);
+bail:
+ slapi_ch_free_string(&dn);
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 6d0a440..d30a3b9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -277,13 +277,6 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
/* find and lock the entry we are about to modify */
done_with_pblock_entry(pb,SLAPI_MODRDN_TARGET_ENTRY); /* Could be through this multiple times */
slapi_pblock_get (pb, SLAPI_TARGET_ADDRESS, &old_addr);
- ldap_result_code = slapi_dn_syntax_check(pb, old_addr->dn, 1);
- if (ldap_result_code)
- {
- ldap_result_code = LDAP_INVALID_DN_SYNTAX;
- slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
- goto error_return;
- }
ldap_result_code= get_copy_of_entry(pb, old_addr, &txn, SLAPI_MODRDN_TARGET_ENTRY, !is_replicated_operation);
if(ldap_result_code==LDAP_OPERATIONS_ERROR ||
ldap_result_code==LDAP_INVALID_DN_SYNTAX)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index 2ca6ad4..db1bd92 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -242,6 +242,7 @@ ldbm_back_search( Slapi_PBlock *pb )
dummyAttrs[0] = dummyAttr;
+ /* This dn is normalized. */
PR_snprintf(dn,sizeof(dn),"dn: oid=%s,cn=features,cn=config",LDAP_CONTROL_VLVREQUEST);
feature= slapi_str2entry(dn,0);
r= plugin_call_acl_plugin (pb, feature, dummyAttrs, NULL, SLAPI_ACL_READ, ACLPLUGIN_ACCESS_DEFAULT, NULL);
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index b913d68..60b72db 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -619,6 +619,7 @@ int ldbm_back_ldif2ldbm( Slapi_PBlock *pb )
if (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) {
/* initialize UniqueID generator - must be done once backends are started
and event queue is initialized but before plugins are started */
+ /* This dn is normalize. */
Slapi_DN *sdn = slapi_sdn_new_dn_byval ("cn=uniqueid generator,cn=config");
int rc = uniqueIDGenInit (NULL, sdn, 0 /* use single thread mode */);
slapi_sdn_free (&sdn);
diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c
index 802370b..759e37f 100644
--- a/ldap/servers/slapd/back-ldbm/misc.c
+++ b/ldap/servers/slapd/back-ldbm/misc.c
@@ -143,7 +143,7 @@ compute_entry_tombstone_dn(const char *entrydn, const char *uniqueid)
PR_ASSERT(NULL != entrydn);
PR_ASSERT(NULL != uniqueid);
- tombstone_dn = slapi_ch_smprintf("%s=%s, %s",
+ tombstone_dn = slapi_ch_smprintf("%s=%s,%s",
SLAPI_ATTR_UNIQUEID,
uniqueid,
entrydn);
@@ -158,7 +158,7 @@ compute_entry_tombstone_rdn(const char *entryrdn, const char *uniqueid)
PR_ASSERT(NULL != entryrdn);
PR_ASSERT(NULL != uniqueid);
- tombstone_rdn = slapi_ch_smprintf("%s=%s, %s",
+ tombstone_rdn = slapi_ch_smprintf("%s=%s,%s",
SLAPI_ATTR_UNIQUEID,
uniqueid,
entryrdn);
diff --git a/ldap/servers/slapd/back-ldbm/nextid.c b/ldap/servers/slapd/back-ldbm/nextid.c
index 6e8f631..02d381b 100644
--- a/ldap/servers/slapd/back-ldbm/nextid.c
+++ b/ldap/servers/slapd/back-ldbm/nextid.c
@@ -214,7 +214,7 @@ get_ids_from_disk(backend *be)
void id_internal_to_stored(ID i,char *b)
{
if ( sizeof(ID) > 4 ) {
- memset (b+4, 0, sizeof(ID)-4);
+ (void)memset (b+4, 0, sizeof(ID)-4);
}
b[0] = (char)(i >> 24);
diff --git a/ldap/servers/slapd/back-ldbm/vlv.c b/ldap/servers/slapd/back-ldbm/vlv.c
index 2402017..2f2cb48 100644
--- a/ldap/servers/slapd/back-ldbm/vlv.c
+++ b/ldap/servers/slapd/back-ldbm/vlv.c
@@ -339,7 +339,7 @@ vlv_init(ldbm_instance *inst)
/* The FE DSE *must* be initialised before we get here */
int return_value= LDAP_SUCCESS;
int scope= LDAP_SCOPE_SUBTREE;
- char *basedn, buf[512];
+ char *basedn = NULL;
const char *searchfilter = "(objectclass=vlvsearch)";
const char *indexfilter = "(objectclass=vlvindex)";
backend *be= inst->inst_be;
@@ -368,9 +368,15 @@ vlv_init(ldbm_instance *inst)
if (inst == NULL) {
basedn = NULL;
} else {
- PR_snprintf(buf, sizeof(buf), "cn=%s,cn=%s,cn=plugins,cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
- basedn = buf;
+ basedn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "vlv_init: failed to create vlv dn for plugin %s, instance %s\n",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ return_value = LDAP_PARAM_ERROR;
+ return return_value;
+ }
}
/* Find the VLV Search Entries */
@@ -405,6 +411,7 @@ vlv_init(ldbm_instance *inst)
slapi_config_register_callback(SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_DeleteIndexEntry,(void*)inst);
slapi_config_register_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,searchfilter,vlv_ModifyRDNSearchEntry,(void*)inst);
slapi_config_register_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_ModifyRDNIndexEntry,(void*)inst);
+ slapi_ch_free_string(&basedn);
}
return return_value;
@@ -417,16 +424,22 @@ vlv_remove_callbacks(ldbm_instance *inst) {
int return_value= LDAP_SUCCESS;
int scope= LDAP_SCOPE_SUBTREE;
- char *basedn, buf[512];
+ char *basedn = NULL;
const char *searchfilter = "(objectclass=vlvsearch)";
const char *indexfilter = "(objectclass=vlvindex)";
if (inst == NULL) {
basedn = NULL;
} else {
- PR_snprintf(buf, sizeof(buf), "cn=%s,cn=%s,cn=plugins,cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
- basedn = buf;
+ basedn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "vlv_remove_callbacks: failed to create vlv dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ return_value = LDAP_PARAM_ERROR;
+ }
}
if(basedn!=NULL)
{
@@ -439,8 +452,9 @@ vlv_remove_callbacks(ldbm_instance *inst) {
slapi_config_remove_callback(SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_DeleteIndexEntry);
slapi_config_remove_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,searchfilter,vlv_ModifyRDNSearchEntry);
slapi_config_remove_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_ModifyRDNIndexEntry);
+ slapi_ch_free_string(&basedn);
}
- return return_value;
+ return return_value;
}
/* Find an enabled index which matches this description. */
@@ -1980,17 +1994,13 @@ char *create_vlv_search_tag(const char* dn) {
/* Builds strings from Slapi_DN similar console GUI. Uses those dns to
delete vlvsearch's if they match. New write lock.
*/
-
-#define LDBM_PLUGIN_ROOT ", cn=ldbm database, cn=plugins, cn=config"
-#define TAG "cn=by MCC "
-
int vlv_delete_search_entry(Slapi_PBlock *pb, Slapi_Entry* e, ldbm_instance *inst)
{
int rc=0;
Slapi_PBlock *tmppb;
Slapi_DN *newdn;
struct vlvSearch* p=NULL;
- char *buf, *buf2, *tag1, *tag2;
+ char *base1 = NULL, *base2 = NULL, *tag1 = NULL, *tag2 = NULL;
const char *dn= slapi_sdn_get_dn(&e->e_sdn);
backend *be= NULL;
if (NULL == inst) {
@@ -2007,8 +2017,18 @@ int vlv_delete_search_entry(Slapi_PBlock *pb, Slapi_Entry* e, ldbm_instance *ins
return LDAP_OPERATIONS_ERROR;
}
tag1=create_vlv_search_tag(dn);
- buf=slapi_ch_smprintf("%s%s%s%s%s","cn=MCC ",tag1,", cn=",inst->inst_name,LDBM_PLUGIN_ROOT);
- newdn=slapi_sdn_new_dn_byval(buf);
+ base1 = slapi_create_dn_string("cn=MCC %s,cn=%s,cn=%s,cn=plugins,cn=config",
+ tag1, inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == base1) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "vlv_delete_search_entry: "
+ "failed to craete vlv search entry dn (rdn: cn=MCC %s) for "
+ "plugin %s, instance %s\n",
+ tag1, inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rc = LDAP_PARAM_ERROR;
+ goto bail;
+ }
+ newdn = slapi_sdn_new_dn_byval(base1);
/* vlvSearchList is modified; need Wlock */
PR_RWLock_Wlock(be->vlvSearchList_lock);
p = vlvSearch_finddn((struct vlvSearch *)be->vlvSearchList, newdn);
@@ -2016,37 +2036,49 @@ int vlv_delete_search_entry(Slapi_PBlock *pb, Slapi_Entry* e, ldbm_instance *ins
{
LDAPDebug( LDAP_DEBUG_ANY, "Deleted Virtual List View Search (%s).\n", p->vlv_name, 0, 0);
tag2=create_vlv_search_tag(dn);
- buf2=slapi_ch_smprintf("%s%s,%s",TAG,tag2,buf);
+ base2 = slapi_create_dn_string("cn=by MCC %s,%s", tag2, base1);
+ if (NULL == base2) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "vlv_delete_search_entry: failed to create "
+ "vlv search entry dn (rdn: cn=by MCC %s) for "
+ "plugin %s, instance %s\n",
+ tag2, inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rc = LDAP_PARAM_ERROR;
+ slapi_ch_free((void **)&tag2);
+ PR_RWLock_Unlock(be->vlvSearchList_lock);
+ goto bail;
+ }
vlvSearch_removefromlist((struct vlvSearch **)&be->vlvSearchList,p->vlv_dn);
/* This line release lock to prevent recursive deadlock caused by slapi_internal_delete calling vlvDeleteSearchEntry */
PR_RWLock_Unlock(be->vlvSearchList_lock);
vlvSearch_delete(&p);
tmppb = slapi_pblock_new();
- slapi_delete_internal_set_pb(tmppb, buf2, NULL, NULL,
+ slapi_delete_internal_set_pb(tmppb, base2, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
slapi_delete_internal_pb(tmppb);
slapi_pblock_get (tmppb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
if(rc != LDAP_SUCCESS) {
- LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", buf2, 0, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", base2, 0, 0);
}
pblock_done(tmppb);
pblock_init(tmppb);
- slapi_delete_internal_set_pb(tmppb, buf, NULL, NULL,
+ slapi_delete_internal_set_pb(tmppb, base1, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
slapi_delete_internal_pb(tmppb);
slapi_pblock_get (tmppb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
if(rc != LDAP_SUCCESS) {
- LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", buf, 0, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", base1, 0, 0);
}
slapi_pblock_destroy(tmppb);
slapi_ch_free((void **)&tag2);
- slapi_ch_free((void **)&buf2);
+ slapi_ch_free((void **)&base2);
} else {
PR_RWLock_Unlock(be->vlvSearchList_lock);
}
+bail:
instance_set_not_busy(inst);
slapi_ch_free((void **)&tag1);
- slapi_ch_free((void **)&buf);
+ slapi_ch_free((void **)&base1);
slapi_sdn_free(&newdn);
return rc;
}
diff --git a/ldap/servers/slapd/backend.c b/ldap/servers/slapd/backend.c
index 4b2d928..8784866 100644
--- a/ldap/servers/slapd/backend.c
+++ b/ldap/servers/slapd/backend.c
@@ -47,18 +47,32 @@
void
be_init( Slapi_Backend *be, const char *type, const char *name, int isprivate, int logchanges, int sizelimit, int timelimit )
{
- char text[128];
slapdFrontendConfig_t *fecfg;
be->be_suffix = NULL;
be->be_suffixlock= PR_NewLock();
be->be_suffixcount= 0;
/* e.g. dn: cn=config,cn=NetscapeRoot,cn=ldbm database,cn=plugins,cn=config */
- PR_snprintf(text, sizeof(text),"cn=%s,cn=%s,cn=plugins,cn=config", name, type);
- be->be_basedn= slapi_ch_strdup(slapi_dn_normalize(text));
- PR_snprintf(text, sizeof(text), "cn=config,cn=%s,cn=%s,cn=plugins,cn=config", name, type);
- be->be_configdn= slapi_ch_strdup(slapi_dn_normalize(text));
- PR_snprintf(text, sizeof(text), "cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config", name, type);
- be->be_monitordn= slapi_ch_strdup(slapi_dn_normalize(text));
+ be->be_basedn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ name, type);
+ if (NULL == be->be_basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "be_init: failed create instance dn for plugin %s, "
+ "instance %s\n", type, name);
+ }
+ be->be_configdn = slapi_create_dn_string("cn=config,cn=%s,cn=%s,cn=plugins,cn=config",
+ name, type);
+ if (NULL == be->be_configdn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "be_init: failed create instance config dn for "
+ "plugin %s, instance %s\n", type, name);
+ }
+ be->be_monitordn = slapi_create_dn_string("cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config",
+ name, type);
+ if (NULL == be->be_configdn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "be_init: failed create instance monitor dn for "
+ "plugin %s, instance %s\n", type, name);
+ }
be->be_sizelimit = sizelimit;
be->be_timelimit = timelimit;
/* maximum group nesting level before giving up */
diff --git a/ldap/servers/slapd/backend_manager.c b/ldap/servers/slapd/backend_manager.c
index 1818437..6456f29 100644
--- a/ldap/servers/slapd/backend_manager.c
+++ b/ldap/servers/slapd/backend_manager.c
@@ -423,12 +423,6 @@ be_nbackends_public()
}
/* backend instance management */
-/* JCM - These are hardcoded for the LDBM database */
-#define LDBM_CLASS_PREFIX "cn=ldbm database,cn=plugins,cn=config"
-#define LDBM_CONFIG_ENTRY "cn=config,cn=ldbm database,cn=plugins,cn=config"
-#define INSTANCE_ATTR "nsslapd-instance"
-#define SUFFIX_ATTR "nsslapd-suffix"
-#define CACHE_ATTR "nsslapd-cachememsize"
void
slapi_be_Rlock(Slapi_Backend * be)
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index f0bdbae..626494b 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -123,6 +123,7 @@ do_bind( Slapi_PBlock *pb )
ber_int_t version = -1;
int auth_response_requested = 0;
int pw_response_requested = 0;
+ char *rawdn = NULL;
char *dn = NULL, *saslmech = NULL;
struct berval cred = {0};
Slapi_Backend *be = NULL;
@@ -136,6 +137,7 @@ do_bind( Slapi_PBlock *pb )
int auto_bind = 0;
int minssf = 0;
char *test_bind_dn = NULL;
+ size_t dnlen = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
@@ -159,7 +161,7 @@ do_bind( Slapi_PBlock *pb )
* }
*/
- rc = ber_scanf( ber, "{iat", &version, &dn, &method );
+ rc = ber_scanf( ber, "{iat", &version, &rawdn, &method );
if ( rc == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Bind; params=Version,DN,Method)\n",
@@ -167,11 +169,37 @@ do_bind( Slapi_PBlock *pb )
log_bind_access (pb, "???", method, version, saslmech, "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"decoding error", 0, NULL );
- slapi_ch_free_string(&dn);
+ slapi_ch_free_string(&rawdn);
return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "BIND", rawdn?rawdn:"",
+ "strict: invalid bind dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid bind dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "BIND", rawdn?rawdn:"",
+ "invalid bind dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid bind dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ } else if (rc > 0) { /* if rc == 0, rawdn is passed in */
+ slapi_ch_free_string(&rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
- slapi_sdn_init_dn_passin(&sdn,dn);
+ slapi_sdn_init_dn_passin(&sdn, dn);
LDAPDebug( LDAP_DEBUG_TRACE, "BIND dn=\"%s\" method=%d version=%d\n",
dn, method, version );
diff --git a/ldap/servers/slapd/compare.c b/ldap/servers/slapd/compare.c
index 5a0256b..578d826 100644
--- a/ldap/servers/slapd/compare.c
+++ b/ldap/servers/slapd/compare.c
@@ -65,7 +65,9 @@ void
do_compare( Slapi_PBlock *pb )
{
BerElement *ber = pb->pb_op->o_ber;
+ char *rawdn = NULL;
char *dn = NULL;
+ size_t len = 0;
struct ava ava = {0};
Slapi_Backend *be = NULL;
int err;
@@ -94,15 +96,40 @@ do_compare( Slapi_PBlock *pb )
* }
*/
- if ( ber_scanf( ber, "{a{ao}}", &dn, &ava.ava_type,
+ if ( ber_scanf( ber, "{a{ao}}", &rawdn, &ava.ava_type,
&ava.ava_value ) == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Compare; params=DN,Type,Value)\n",
0, 0, 0 );
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
- NULL );
+ NULL );
goto free_and_return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "CMP",
+ rawdn?rawdn:"", "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawdn, 0, &dn, &len);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "CMP", rawdn?rawdn:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ } else if (err > 0) { /* if rc == 0, rawdn is passed in */
+ slapi_ch_free((void **) &rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + len) = '\0';
+ }
/*
* in LDAPv3 there can be optional control extensions on
* the end of an LDAPMessage. we need to read them in and
diff --git a/ldap/servers/slapd/delete.c b/ldap/servers/slapd/delete.c
index c17b669..3a80eeb 100644
--- a/ldap/servers/slapd/delete.c
+++ b/ldap/servers/slapd/delete.c
@@ -71,8 +71,10 @@ do_delete( Slapi_PBlock *pb )
{
Slapi_Operation *operation;
BerElement *ber;
+ char *rawdn = NULL;
char *dn = NULL;
- int err;
+ size_t dnlen = 0;
+ int err = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_delete\n", 0, 0, 0 );
@@ -88,7 +90,7 @@ do_delete( Slapi_PBlock *pb )
* DelRequest := DistinguishedName
*/
- if ( ber_scanf( pb->pb_op->o_ber, "a", &dn ) == LBER_ERROR ) {
+ if ( ber_scanf( pb->pb_op->o_ber, "a", &rawdn ) == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Delete; params=DN)\n", 0, 0, 0 );
op_shared_log_error_access (pb, "DEL", "???", "decoding error");
@@ -96,6 +98,31 @@ do_delete( Slapi_PBlock *pb )
NULL );
goto free_and_return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "DEL", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ goto free_and_return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "DEL", "???", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ goto free_and_return;
+ } else if (err > 0) { /* if err == 0, rawdn is passed in */
+ slapi_ch_free_string(&rawdn);
+ } else { /* err == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
/*
* in LDAPv3 there can be optional control extensions on
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index f9c2258..743aa36 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -57,9 +57,9 @@
static void add_rdn_av( char *avstart, char *avend, int *rdn_av_countp,
struct berval **rdn_avsp, struct berval *avstack );
static void reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp );
-static void sort_rdn_avs( struct berval *avs, int count );
+static void sort_rdn_avs( struct berval *avs, int count, int escape );
static int rdn_av_cmp( struct berval *av1, struct berval *av2 );
-static void rdn_av_swap( struct berval *av1, struct berval *av2 );
+static void rdn_av_swap( struct berval *av1, struct berval *av2, int escape );
int
@@ -77,24 +77,53 @@ hexchar2int( char c )
return( -1 );
}
+#define ISBLANK(c) ((c) == ' ')
+#define ISSPACE(c) (ISBLANK(c) || ((c) == '\n') || ((c) == '\r')) /* XXX 518524 */
+
+#define ISEQUAL(c) ((c) == '=')
+#define ISEQUALSTR(s) \
+ ((*(s) == '3') && ((*((s)+1) == 'd') || (*((s)+1) == 'D')))
+
+#define ISPLUS(c) ((c) == '+')
+#define ISPLUSSTR(s) \
+ ((*(s) == '2') && ((*((s)+1) == 'b') || (*((s)+1) == 'B')))
+
+#define ISESCAPE(c) ((c) == '\\')
+#define ISQUOTE(c) ((c) == '"')
+
#define DNSEPARATOR(c) (((c) == ',') || ((c) == ';'))
-#define SEPARATOR(c) (((c) == ',') || ((c) == ';') || ((c) == '+'))
-#define SPACE(c) (((c) == ' ') || ((c) == '\n')) /* XXX 518524 */
-#define NEEDSESCAPE(c) (((c) == '\\') || ((c) == '"') || ((c) == '+') || \
- ((c) == ',') || ((c) == ';') || ((c) == '<') || ((c) == '>') || ((c) == '='))
-#define LEADNEEDSESCAPE(c) (((c) == ' ') || ((c) == '#') || NEEDSESCAPE(c))
-#if 0 /* not used */
-#define ONLYTRAILNEEDSESCAPE(c) ((c) == ' ')
-#define TRAILNEEDSESCAPE(c) (ONLYTRAILNEEDSESCAPE(c) || NEEDSESCAPE(c))
-#endif
-#define B4TYPE 0
-#define INTYPE 1
-#define B4EQUAL 2
-#define B4VALUE 3
-#define INVALUE 4
-#define INQUOTEDVALUE 5
-#define B4SEPARATOR 6
-#define INVALUE1ST 7
+#define DNSEPARATORSTR(s) \
+ (((*(s) == '2') && ((*((s)+1) == 'c') || (*((s)+1) == 'C'))) || \
+ ((*(s) == '3') && ((*((s)+1) == 'b') || (*((s)+1) == 'B'))))
+
+#define SEPARATOR(c) (DNSEPARATOR(c) || ISPLUS(c))
+#define SEPARATORSTR(s) (DNSEPARATORSTR(s) || ISPLUSSTR(s))
+
+#define NEEDSESCAPE(c) (ISESCAPE(c) || ISQUOTE(c) || SEPARATOR(c) || \
+ ((c) == '<') || ((c) == '>') || ISEQUAL(c))
+#define NEEDSESCAPESTR(s) \
+ (((*(s) == '2') && ((*((s)+1) == '2') || \
+ (*((s)+1) == 'b') || (*((s)+1) == 'B') || \
+ (*((s)+1) == 'c') || (*((s)+1) == 'C'))) || \
+ ((*(s) == '3') && (((*((s)+1) >= 'b') && (*((s)+1) < 'f')) || \
+ ((*((s)+1) >= 'B') && (*((s)+1) < 'F')))) || \
+ ((*(s) == '5') && ((*((s)+1) == 'c') || (*((s)+1) == 'C'))))
+
+#define LEADNEEDSESCAPE(c) (ISBLANK(c) || ((c) == '#') || NEEDSESCAPE(c))
+#define LEADNEEDSESCAPESTR(s) (NEEDSESCAPESTR(s) || \
+ ((*(s) == '2') && (*((s)+1) == '3')))
+
+#define ISCLOSEBRACKET(c) (((c) == ')') || ((c) == ']'))
+
+#define B4TYPE 0
+#define INTYPE 1
+#define B4EQUAL 2
+#define B4VALUE 3
+#define INVALUE 4
+#define INQUOTEDVALUE 5
+#define B4SEPARATOR 6
+#define INVALUE1ST 7
+#define INQUOTEDVALUE1ST 8
#define SLAPI_DNNORM_INITIAL_RDN_AVS 10
#define SLAPI_DNNORM_SMALL_RDN_AV 512
@@ -137,13 +166,13 @@ hexchar2int( char c )
*
* This function does not support UTF-8 multi-byte encoding for attribute
* values, in particular it does not support UTF-8 whitespace. First the
- * SPACE macro above is limited, but also its frequent use of '-1' indexing
+ * ISSPACE macro above is limited, but also its frequent use of '-1' indexing
* into a char[] may hit the middle of a multi-byte UTF-8 whitespace character
* encoding (518524).
*/
char *
-substr_dn_normalize( char *dn, char *end )
+substr_dn_normalize_orig( char *dn, char *end )
{
/* \xx is changed to \c.
* \c is changed to c, unless this would change its meaning.
@@ -166,7 +195,7 @@ substr_dn_normalize( char *dn, char *end )
for ( d = s = dn; s != end; s++ ) {
switch ( state ) {
case B4TYPE:
- if ( ! SPACE( *s ) ) {
+ if ( ! ISSPACE( *s ) ) {
state = INTYPE;
typestart = d;
*d++ = *s;
@@ -176,7 +205,7 @@ substr_dn_normalize( char *dn, char *end )
if ( *s == '=' ) {
state = B4VALUE;
*d++ = *s;
- } else if ( SPACE( *s ) ) {
+ } else if ( ISSPACE( *s ) ) {
state = B4EQUAL;
} else {
*d++ = *s;
@@ -186,13 +215,13 @@ substr_dn_normalize( char *dn, char *end )
if ( *s == '=' ) {
state = B4VALUE;
*d++ = *s;
- } else if ( ! SPACE( *s ) ) {
+ } else if ( ! ISSPACE( *s ) ) {
/* not a valid dn - but what can we do here? */
*d++ = *s;
}
break;
case B4VALUE:
- if ( *s == '"' || ! SPACE( *s ) ) {
+ if ( *s == '"' || ! ISSPACE( *s ) ) {
value_separator = NULL;
value = d;
state = ( *s == '"' ) ? INQUOTEDVALUE : INVALUE1ST;
@@ -223,7 +252,7 @@ substr_dn_normalize( char *dn, char *end )
* be if it does at the end of the RDN value */
/* e.g., ou=ABC \ ,o=XYZ --> ou=ABC \ ,o=XYZ */
if ( lastesc ) {
- while ( SPACE( *(d - 1) ) && d > lastesc ) {
+ while ( ISSPACE( *(d - 1) ) && d > lastesc ) {
d--;
}
if ( d == lastesc ) {
@@ -231,7 +260,7 @@ substr_dn_normalize( char *dn, char *end )
*d++ = ' '; /* escaped trailing space */
}
} else {
- while ( SPACE( *(d - 1) ) ) {
+ while ( ISSPACE( *(d - 1) ) ) {
d--;
}
}
@@ -281,7 +310,7 @@ substr_dn_normalize( char *dn, char *end )
}
if ( *s != '+' ) { /* at end of this RDN */
if ( rdn_av_count > 1 ) {
- sort_rdn_avs( rdn_avs, rdn_av_count );
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
}
if ( rdn_av_count > 0 ) {
reset_rdn_avs( &rdn_avs, &rdn_av_count );
@@ -304,7 +333,7 @@ substr_dn_normalize( char *dn, char *end )
} else if ( *s == '"' ) {
state = B4SEPARATOR;
if ( value_separator == dn /* 2 or more separators */
- || SPACE( value[1] ) || SPACE( d[-1] ) ) {
+ || ISSPACE( value[1] ) || ISSPACE( d[-1] ) ) {
*d++ = *s;
} else {
/* convert to non-quoted value: */
@@ -338,7 +367,7 @@ substr_dn_normalize( char *dn, char *end )
}
if ( *s != '+' ) { /* at end of this RDN */
if ( rdn_av_count > 1 ) {
- sort_rdn_avs( rdn_avs, rdn_av_count );
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
}
if ( rdn_av_count > 0 ) {
reset_rdn_avs( &rdn_avs, &rdn_av_count );
@@ -397,7 +426,7 @@ substr_dn_normalize( char *dn, char *end )
&rdn_avs, initial_rdn_av_stack );
}
if ( rdn_av_count > 1 ) {
- sort_rdn_avs( rdn_avs, rdn_av_count );
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
}
if ( rdn_av_count > 0 ) {
reset_rdn_avs( &rdn_avs, &rdn_av_count );
@@ -408,7 +437,540 @@ substr_dn_normalize( char *dn, char *end )
return( d );
}
+char *
+substr_dn_normalize( char *dn, char *end )
+{
+ /* no op */
+ return end;
+}
+
+/*
+ * 1) Escaped NEEDSESCAPE chars (e.g., ',', '<', '=', etc.) are converted to
+ * ESC HEX HEX (e.g., \2C, \3C, \3D, etc.)
+ * Input could be a string in double quotes
+ * (= old DN format: dn: cn="x=x,y=y",... --> dn: cn=x\3Dx\2Cy\3Dy,...) or
+ * an escaped string
+ * (= new DN format dn: cn=x\=x\,y\=y,... -> dn: cn=x\3Dx\2Cy\3Dy,...)
+ *
+ * 2) All the other ESC HEX HEX are converted to the real characters.
+ *
+ * 3) Spaces around separator ',', ';', and '+' are removed.
+ *
+ * Input:
+ * src: src DN
+ * src_len: length of src; 0 is acceptable if src is NULL terminated.
+ * Output:
+ * dest: address of the converted string; NULL terminated
+ * (could store src address if no need to convert)
+ * dest_len: length of dest
+ *
+ * Return values:
+ * 0: nothing was done; dest is identical to src (src is passed in).
+ * 1: successfully escaped; dest is different from src. src needs to be freed.
+ * -1: failed; dest is NULL; invalid DN
+ */
+int
+slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
+{
+ int rc = -1;
+ int state = B4TYPE;
+ char *s = NULL; /* work pointer for src */
+ char *d = NULL; /* work pointer for dest */
+ char *ends = NULL;
+ char *endd = NULL;
+ char *typestart = NULL;
+ char *subtypestart = NULL; /* used for the nested DN */
+ char *lastesc = NULL;
+ int rdn_av_count = 0;
+ struct berval *rdn_avs = NULL;
+ struct berval initial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
+ int chkblank = 0;
+
+ if (NULL == dest) {
+ goto bail;
+ }
+ if (NULL == src) {
+ *dest = NULL;
+ *dest_len = 0;
+ goto bail;
+ }
+ if (0 == src_len) {
+ src_len = strlen(src);
+ }
+ s = PL_strnchr(src, '\\', src_len);
+ if (s) {
+ *dest_len = src_len * 3;
+ *dest = slapi_ch_malloc(*dest_len); /* max length */
+ rc = 1;
+ } else {
+ s = PL_strnchr(src, '"', src_len);
+ if (s) {
+ *dest_len = src_len * 3;
+ *dest = slapi_ch_malloc(*dest_len); /* max length */
+ rc = 1;
+ } else {
+ *dest_len = src_len;
+ *dest = src; /* just removing spaces around separators */
+ rc = 0;
+ }
+ }
+
+ ends = src + src_len;
+ endd = *dest + *dest_len;
+ for (s = src, d = *dest; s < ends && d < endd; ) {
+ switch (state) {
+ case B4TYPE: /* before type; cn=... */
+ /* ^ */
+ if (ISSPACE(*s)) {
+ s++; /* skip leading spaces */
+ } else {
+ state = INTYPE;
+ typestart = d;
+ *d++ = *s++;
+ }
+ break;
+ case INTYPE: /* in type; cn=... */
+ /* ^ */
+ if (ISEQUAL(*s)) {
+ state = B4VALUE;
+ *d++ = *s++;
+ } else if (ISCLOSEBRACKET(*s)) { /* special care for ACL macro */
+ state = INVALUE; /* skip a trailing space */
+ *d++ = *s++;
+ } else if (ISSPACE(*s)) {
+ state = B4EQUAL; /* skip a trailing space */
+ } else {
+ *d++ = *s++;
+ }
+ break;
+ case B4EQUAL: /* before equal; cn =... */
+ /* ^ */
+ if (ISEQUAL(*s)) {
+ state = B4VALUE;
+ *d++ = *s++;
+ } else if (ISSPACE(*s)) {
+ s++; /* skip trailing spaces */
+ } else {
+ /* type includes spaces; not a valid dn */
+ rc = -1;
+ goto bail;
+ }
+ break;
+ case B4VALUE: /* before value; cn= ABC */
+ /* ^ */
+ if (ISSPACE(*s)) {
+ s++;
+ } else {
+ if (ISQUOTE(*s)) {
+ s++; /* start with the first char in quotes */
+ state = INQUOTEDVALUE1ST;
+ } else {
+ state = INVALUE1ST;
+ }
+ lastesc = NULL;
+ /* process *s in INVALUE or INQUOTEDVALUE */
+ }
+ break;
+ case INVALUE1ST: /* 1st char in value; cn=ABC */
+ /* ^ */
+ if (ISSPACE(*s)) { /* skip leading spaces */
+ s++;
+ continue;
+ } else if (SEPARATOR(*s)) {
+ /* 1st char in value is separator; invalid dn */
+ rc = -1;
+ goto bail;
+ } /* otherwise, go through */
+ case INVALUE: /* in value; cn=ABC */
+ /* ^ */
+ if (ISESCAPE(*s)) {
+ if (s + 1 >= ends) {
+ /* DN ends with '\'; invalid dn */
+ rc = -1;
+ goto bail;
+ }
+ if (((state == INVALUE1ST) && LEADNEEDSESCAPE(*(s+1))) ||
+ ((state == INVALUE) && NEEDSESCAPE(*(s+1)))) {
+ if (d + 2 >= endd) {
+ /* Not enough space for dest; this never happens! */
+ rc = -1;
+ goto bail;
+ } else {
+ if (ISEQUAL(*(s+1))) {
+ if (NULL == subtypestart) {
+ /* e.g., cn=a\=b\,c\=d */
+ /* ^ */
+ *d = '\0';
+ subtypestart = strrchr(*dest, '=');
+ if (subtypestart) {
+ /* pointing 'a' in the above example */
+ subtypestart++;
+ }
+ /* else
+ * No equal for the nested DN looking value.
+ * Just through it.
+ */
+ }
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATOR(*(s+1))) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ if (chkblank && ISESCAPE(*(d-1)) && ISBLANK(*d)) {
+ /* last space is escaped "cn=A\ ,ou=..." */
+ /* ^ */
+ PR_snprintf(d, 3, "%X", *d); /* hexpair */
+ d += 2;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (subtypestart &&
+ (ISPLUS(*(s+1)) || rdn_av_count > 0)) {
+ add_rdn_av(subtypestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUS(*(s+1))) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 1 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ subtypestart = NULL;
+ }
+ }
+ }
+ /* dn: cn=x\=x\,... -> dn: cn=x\3Dx\2C,... */
+ *d++ = *s++; /* '\\' */
+ PR_snprintf(d, 3, "%X", *s); /* hexpair */
+ d += 2;
+ if (ISPLUS(*s) && PL_strnstr(s, "\\=", ends - s)) {
+ /* next type start of multi values */
+ subtypestart = d;
+ }
+ if (SEPARATOR(*s) || ISEQUAL(*s)) {
+ while (ISSPACE(*(s+1)))
+ s++; /* remove leading spaces */
+ s++;
+ } else {
+ s++;
+ }
+ }
+ } else if (((state == INVALUE1ST) && (s+2 < ends) &&
+ LEADNEEDSESCAPESTR(s+1)) ||
+ ((state == INVALUE) && (s+2 < ends) &&
+ NEEDSESCAPESTR(s+1))) {
+ if (ISEQUALSTR(s+1)) {
+ if (NULL == subtypestart) {
+ /* e.g., cn=a\3Db\2Cc\3Dd */
+ /* ^ */
+ *d = '\0';
+ subtypestart = strrchr(*dest, '=');
+ if (subtypestart) {
+ /* pointing 'a' in the above example */
+ subtypestart++;
+ }
+ /* else
+ * No equal for the nested DN looking value.
+ * Just through it.
+ */
+ }
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATORSTR(s+1)) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ if (chkblank && ISESCAPE(*(d-1)) && ISBLANK(*d)) {
+ /* last space is escaped "cn=A\ ,ou=..." */
+ /* ^ */
+ PR_snprintf(d, 3, "%X", *d); /* hexpair */
+ d += 2;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (subtypestart &&
+ (ISPLUSSTR(s+1) || rdn_av_count > 0)) {
+ add_rdn_av(subtypestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUSSTR(s+1)) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 1 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ }
+ }
+ }
+ *d++ = *s++; /* '\\' */
+ *d++ = *s++; /* HEX */
+ *d++ = *s++; /* HEX */
+ if (ISPLUSSTR(s-2) && PL_strnstr(s, "\\=", ends - s)) {
+ /* next type start of multi values */
+ subtypestart = d;
+ }
+ if (SEPARATORSTR(s-2) || ISEQUALSTR(s-2)) {
+ while (ISSPACE(*s)) /* remove leading spaces */
+ s++;
+ }
+ } else if (s + 2 < ends &&
+ isxdigit(*(s+1)) && isxdigit(*(s+2))) {
+ /* esc hexpair ==> real character */
+ int n = hexchar2int(*(s+1));
+ int n2 = hexchar2int(*(s+2));
+ n = (n << 4) + n2;
+ if (n == 0) { /* don't change \00 */
+ *d++ = *++s;
+ *d++ = *++s;
+ } else {
+ *d++ = n;
+ s += 3;
+ }
+ } else {
+ /* ignore an escape for now */
+ lastesc = d; /* position of the previous escape */
+ s++;
+ }
+ } else if (SEPARATOR(*s)) { /* cn=ABC , ... */
+ /* ^ */
+ /* handling a trailing escaped space */
+ /* assuming a space is the only an extra character which
+ * is not escaped if it appears in the middle, but should
+ * be if it does at the end of the RDN value */
+ /* e.g., ou=ABC \ ,o=XYZ --> ou=ABC \ ,o=XYZ */
+ if (lastesc) {
+ while (ISSPACE(*(d-1)) && d > lastesc ) {
+ d--;
+ }
+ if (d == lastesc) {
+ /* esc hexpair of space: \20 */
+ *d++ = '\\';
+ *d++ = '2';
+ *d++ = '0';
+ }
+ } else {
+ while (ISSPACE(*(d-1))) {
+ d--;
+ }
+ }
+ state = B4SEPARATOR;
+ break;
+ } else { /* else if (SEPARATOR(*s)) */
+ *d++ = *s++;
+ }
+ if (state == INVALUE1ST) {
+ state = INVALUE;
+ }
+ break;
+ case INQUOTEDVALUE1ST:
+ if (ISSPACE(*s) && (s+1 < ends && ISSPACE(*(s+1)))) {
+ /* skip leading spaces but need to leave one */
+ s++;
+ continue;
+ }
+ subtypestart = d; /* prepare for '+' in the quoted value, if any */
+ case INQUOTEDVALUE:
+ if (ISQUOTE(*s)) {
+ if (ISESCAPE(*(d-1))) { /* the quote is escaped */
+ PR_snprintf(d, 3, "%X", *(s++)); /* hexpair */
+ } else { /* end of INQUOTEVALUE */
+ while (ISSPACE(*(d-1))) { /* eliminate trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ /* We have to keep the last ' ' of a value in quotes.
+ * The same idea as the escaped last space:
+ * "cn=A,ou=B " */
+ /* ^ */
+ if (chkblank && ISBLANK(*d)) {
+ PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
+ d += 3;
+ chkblank = 0;
+ }
+ state = B4SEPARATOR;
+ s++;
+ }
+ } else if (((state == INQUOTEDVALUE1ST) && LEADNEEDSESCAPE(*s)) ||
+ (state == INQUOTEDVALUE && NEEDSESCAPE(*s))) {
+ if (d + 2 >= endd) {
+ /* Not enough space for dest; this never happens! */
+ rc = -1;
+ goto bail;
+ } else {
+ if (ISEQUAL(*s)) {
+ while (ISSPACE(*(d-1))) { /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATOR(*s)) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) { /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ /* We have to keep the last ' ' of a value in quotes.
+ * The same idea as the escaped last space:
+ * "cn=A\ ,ou=..." */
+ /* ^ */
+ if (chkblank && ISBLANK(*d)) {
+ PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
+ d += 3;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (ISPLUS(*s) || rdn_av_count > 0) {
+ add_rdn_av(subtypestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUS(*s)) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 1 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ subtypestart = NULL;
+ }
+ }
+ }
+
+ /* dn: cn="x=x,..",... -> dn: cn=x\3Dx\2C,... */
+ *d++ = '\\';
+ PR_snprintf(d, 3, "%X", *s); /* hexpair */
+ d += 2;
+ if (ISPLUS(*s++)) {
+ subtypestart = d; /* next type start of multi values */
+ }
+ if (SEPARATOR(*(s-1)) || ISEQUAL(*(s-1))) {
+ while (ISSPACE(*s)) /* remove leading spaces */
+ s++;
+ }
+ }
+ } else {
+ *d++ = *s++;
+ }
+ if (state == INQUOTEDVALUE1ST) {
+ state = INQUOTEDVALUE;
+ }
+ break;
+ case B4SEPARATOR:
+ if (SEPARATOR(*s)) {
+ state = B4TYPE;
+
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (ISPLUS(*s) || rdn_av_count > 0) {
+ add_rdn_av(typestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUS(*s)) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ }
+ }
+
+ *d++ = (ISPLUS(*s++)) ? '+' : ',';
+ } else {
+ s++;
+ }
+ break;
+ default:
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "slapi_dn_normalize - unknown state %d\n", state, 0, 0 );
+ break;
+ }
+ }
+
+ /*
+ * Track and sort attribute values within multivalued RDNs.
+ */
+ /* We may still be in an unexpected state, such as B4TYPE if
+ * we encountered something odd like a '+' at the end of the
+ * rdn. If this is the case, we don't want to add this bogus
+ * rdn to our list to sort. We should only be in the INVALUE
+ * or B4SEPARATOR state if we have a valid rdn component to
+ * be added. */
+ if ((rdn_av_count > 0) && ((state == INVALUE1ST) ||
+ (state == INVALUE) || (state == B4SEPARATOR))) {
+ add_rdn_av(typestart, d, &rdn_av_count, &rdn_avs, initial_rdn_av_stack);
+ }
+ if ( rdn_av_count > 1 ) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
+ }
+ if ( rdn_av_count > 0 ) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ }
+ /* Trim trailing spaces */
+ while (d > *dest && ISBLANK(*(d-1))) {
+ --d; /* XXX 518524 */
+ }
+ *dest_len = d - *dest;
+bail:
+ if (rc < 0) {
+ if (*dest != src) {
+ slapi_ch_free_string(dest);
+ } else {
+ *dest = NULL;
+ }
+ *dest_len = 0;
+ } else if (rc > 0) {
+ /* We terminate the str with NULL only when we allocate the str */
+ *d = '\0';
+ }
+ return rc;
+}
+
+char *
+slapi_create_dn_string(const char *fmt, ...)
+{
+ char *src = NULL;
+ char *dest = NULL;
+ size_t dest_len = 0;
+ va_list ap;
+ int rc = 0;
+
+ if (NULL == fmt) {
+ return NULL;
+ }
+
+ va_start(ap, fmt);
+ src = PR_vsmprintf(fmt, ap);
+ va_end(ap);
+ rc = slapi_dn_normalize_ext(src, strlen(src), &dest, &dest_len);
+ if (rc < 0) {
+ slapi_ch_free_string(&src);
+ return NULL;
+ } else if (rc == 0) { /* src is passed in. */
+ *(dest + dest_len) = '\0';
+ } else {
+ slapi_ch_free_string(&src);
+ }
+ return dest;
+}
/*
* Append previous AV to the attribute value array if multivalued RDN.
@@ -418,21 +980,22 @@ substr_dn_normalize( char *dn, char *end )
*/
static void
add_rdn_av( char *avstart, char *avend, int *rdn_av_countp,
- struct berval **rdn_avsp, struct berval *avstack )
+ struct berval **rdn_avsp, struct berval *avstack )
{
if ( *rdn_av_countp == 0 ) {
- *rdn_avsp = avstack;
+ *rdn_avsp = avstack;
} else if ( *rdn_av_countp == SLAPI_DNNORM_INITIAL_RDN_AVS ) {
- struct berval *tmpavs;
+ struct berval *tmpavs;
- tmpavs = (struct berval *)slapi_ch_calloc(
- SLAPI_DNNORM_INITIAL_RDN_AVS * 2, sizeof( struct berval ));
- memcpy( tmpavs, *rdn_avsp,
- SLAPI_DNNORM_INITIAL_RDN_AVS * sizeof( struct berval ));
- *rdn_avsp = tmpavs;
+ tmpavs = (struct berval *)slapi_ch_calloc(
+ SLAPI_DNNORM_INITIAL_RDN_AVS * 2, sizeof( struct berval ));
+ memcpy( tmpavs, *rdn_avsp,
+ SLAPI_DNNORM_INITIAL_RDN_AVS * sizeof( struct berval ));
+ *rdn_avsp = tmpavs;
} else if (( *rdn_av_countp % SLAPI_DNNORM_INITIAL_RDN_AVS ) == 0 ) {
- *rdn_avsp = (struct berval *)slapi_ch_realloc( (char *)*rdn_avsp,
- (*rdn_av_countp + SLAPI_DNNORM_INITIAL_RDN_AVS)*sizeof(struct berval) );
+ *rdn_avsp = (struct berval *)slapi_ch_realloc( (char *)*rdn_avsp,
+ (*rdn_av_countp +
+ SLAPI_DNNORM_INITIAL_RDN_AVS)*sizeof(struct berval) );
}
/*
@@ -453,7 +1016,7 @@ static void
reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp )
{
if ( *rdn_av_countp > SLAPI_DNNORM_INITIAL_RDN_AVS ) {
- slapi_ch_free( (void **)rdn_avsp );
+ slapi_ch_free( (void **)rdn_avsp );
}
*rdn_avsp = NULL;
*rdn_av_countp = 0;
@@ -471,9 +1034,9 @@ reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp )
* Also note that the bv_val's in the "avas" array are not zero-terminated.
*/
static void
-sort_rdn_avs( struct berval *avs, int count )
+sort_rdn_avs( struct berval *avs, int count, int escape )
{
- int i, j, swaps;
+ int i, j, swaps;
/*
* Since we expect there to be a small number of AVs, we use a
@@ -481,16 +1044,16 @@ sort_rdn_avs( struct berval *avs, int count )
* adjacent values anyway.
*/
for ( i = 0; i < count - 1; ++i ) {
- swaps = 0;
- for ( j = 0; j < count - 1; ++j ) {
- if ( rdn_av_cmp( &avs[j], &avs[j+1] ) > 0 ) {
- rdn_av_swap( &avs[j], &avs[j+1] );
- ++swaps;
- }
- }
- if ( swaps == 0 ) {
- break; /* stop early if no swaps made during the last pass */
- }
+ swaps = 0;
+ for ( j = 0; j < count - 1; ++j ) {
+ if ( rdn_av_cmp( &avs[j], &avs[j+1] ) > 0 ) {
+ rdn_av_swap( &avs[j], &avs[j+1], escape );
+ ++swaps;
+ }
+ }
+ if ( swaps == 0 ) {
+ break; /* stop early if no swaps made during the last pass */
+ }
}
}
@@ -501,15 +1064,15 @@ sort_rdn_avs( struct berval *avs, int count )
static int
rdn_av_cmp( struct berval *av1, struct berval *av2 )
{
- int rc;
+ int rc;
rc = strncasecmp( av1->bv_val, av2->bv_val,
- ( av1->bv_len < av2->bv_len ) ? av1->bv_len : av2->bv_len );
+ ( av1->bv_len < av2->bv_len ) ? av1->bv_len : av2->bv_len );
if ( rc == 0 ) {
- return( av1->bv_len - av2->bv_len ); /* longer is greater */
+ return( av1->bv_len - av2->bv_len ); /* longer is greater */
} else {
- return( rc );
+ return( rc );
}
}
@@ -519,12 +1082,12 @@ rdn_av_cmp( struct berval *av1, struct berval *av2 )
* Avoid allocating any heap memory for reasonably small AVs.
*/
static void
-rdn_av_swap( struct berval *av1, struct berval *av2 )
+rdn_av_swap( struct berval *av1, struct berval *av2, int escape )
{
- char *buf1, *buf2;
- char stackbuf1[ SLAPI_DNNORM_SMALL_RDN_AV ];
- char stackbuf2[ SLAPI_DNNORM_SMALL_RDN_AV ];
- int len1, len2;
+ char *buf1, *buf2;
+ char stackbuf1[ SLAPI_DNNORM_SMALL_RDN_AV ];
+ char stackbuf2[ SLAPI_DNNORM_SMALL_RDN_AV ];
+ int len1, len2;
/*
* Copy the two avs into temporary buffers. We use stack-based buffers
@@ -532,16 +1095,16 @@ rdn_av_swap( struct berval *av1, struct berval *av2 )
* large values.
*/
if (( len1 = av1->bv_len ) <= SLAPI_DNNORM_SMALL_RDN_AV ) {
- buf1 = stackbuf1;
+ buf1 = stackbuf1;
} else {
- buf1 = slapi_ch_malloc( len1 );
+ buf1 = slapi_ch_malloc( len1 );
}
memcpy( buf1, av1->bv_val, len1 );
if (( len2 = av2->bv_len ) <= SLAPI_DNNORM_SMALL_RDN_AV ) {
- buf2 = stackbuf2;
+ buf2 = stackbuf2;
} else {
- buf2 = slapi_ch_malloc( len2 );
+ buf2 = slapi_ch_malloc( len2 );
}
memcpy( buf2, av2->bv_val, len2 );
@@ -556,7 +1119,13 @@ rdn_av_swap( struct berval *av1, struct berval *av2 )
* Also reset av2 pointer and length.
*/
av2->bv_val = av1->bv_val + len2;
- *(av2->bv_val)++ = '+';
+ if (escape) {
+ *(av2->bv_val)++ = '\\';
+ PR_snprintf(av2->bv_val, 3, "%X", '+'); /* hexpair */
+ av2->bv_val += 2;
+ } else {
+ *(av2->bv_val)++ = '+';
+ }
memcpy( av2->bv_val, buf1, len1 );
av2->bv_len = len1;
@@ -564,19 +1133,19 @@ rdn_av_swap( struct berval *av1, struct berval *av2 )
* Clean up.
*/
if ( len1 > SLAPI_DNNORM_SMALL_RDN_AV ) {
- slapi_ch_free( (void **)&buf1 );
+ slapi_ch_free( (void **)&buf1 );
}
if ( len2 > SLAPI_DNNORM_SMALL_RDN_AV ) {
- slapi_ch_free( (void **)&buf2 );
+ slapi_ch_free( (void **)&buf2 );
}
}
/*
+ * DEPRECATED: this function does nothing.
* slapi_dn_normalize - put dn into a canonical format. the dn is
* normalized in place, as well as returned.
*/
-
char *
slapi_dn_normalize( char *dn )
{
@@ -586,7 +1155,10 @@ slapi_dn_normalize( char *dn )
return dn;
}
-/* Note that this routine normalizes to the end and doesn't null terminate */
+/*
+ * DEPRECATED: this function does nothing.
+ * Note that this routine normalizes to the end and doesn't null terminate
+ */
char *
slapi_dn_normalize_to_end( char *dn , char *end)
{
@@ -600,13 +1172,28 @@ slapi_dn_normalize_to_end( char *dn , char *end)
char *
slapi_dn_ignore_case( char *dn )
{
- unsigned char *s, *d;
+ unsigned char *s = NULL, *d = NULL;
+ int ssz, dsz;
+ /* normalize case (including UTF-8 multi-byte chars) */
+ for ( s = d = (unsigned char *)dn; s && *s; s += ssz, d += dsz ) {
+ slapi_utf8ToLower( s, d, &ssz, &dsz );
+ }
+ if (d) {
+ *d = '\0'; /* utf8ToLower result may be shorter than the original */
+ }
+ return( dn );
+}
+
+char *
+dn_ignore_case_to_end( char *dn, char *end )
+{
+ unsigned char *s = NULL, *d = NULL;
int ssz, dsz;
/* normalize case (including UTF-8 multi-byte chars) */
- for ( s = d = (unsigned char *)dn; *s; s += ssz, d += dsz ) {
- slapi_utf8ToLower( s, d, &ssz, &dsz );
+ for (s = d = (unsigned char *)dn; s && s < (unsigned char *)end && *s;
+ s += ssz, d += dsz) {
+ slapi_utf8ToLower( s, d, &ssz, &dsz );
}
- *d = '\0'; /* utf8ToLower result may be shorter than the original */
return( dn );
}
@@ -626,6 +1213,47 @@ slapi_dn_normalize_case( char *dn )
return( slapi_dn_ignore_case( dn ));
}
+int
+slapi_dn_normalize_case_ext(char *src, size_t src_len,
+ char **dest, size_t *dest_len)
+{
+ int rc = slapi_dn_normalize_ext(src, src_len, dest, dest_len);
+
+ if (rc >= 0) {
+ dn_ignore_case_to_end(*dest, *dest + *dest_len);
+ }
+ return rc;
+}
+
+char *
+slapi_create_dn_string_case(const char *fmt, ...)
+{
+ char *src = NULL;
+ char *dest = NULL;
+ size_t dest_len = 0;
+ va_list ap;
+ int rc = 0;
+
+ if (NULL == fmt) {
+ return NULL;
+ }
+
+ va_start(ap, fmt);
+ src = PR_vsmprintf(fmt, ap);
+ va_end(ap);
+
+ rc = slapi_dn_normalize_ext(src, strlen(src), &dest, &dest_len);
+ if (rc < 0) {
+ slapi_ch_free_string(&src);
+ } else if (rc == 0) { /* src is passed in. */
+ *(dest + dest_len) = '\0';
+ } else {
+ slapi_ch_free_string(&src);
+ }
+
+ return slapi_dn_ignore_case(dest);
+}
+
/*
* slapi_dn_beparent - return a copy of the dn of dn's parent,
* NULL if the DN is a suffix of the backend.
@@ -1129,10 +1757,7 @@ slapi_sdn_set_rdn(Slapi_DN *sdn, const Slapi_RDN *rdn)
{
/* NewDN= NewRDN + OldParent */
char *parentdn= slapi_dn_parent(sdn->dn);
- char *newdn= slapi_ch_malloc(strlen(rawrdn)+1+strlen(parentdn)+1);
- strcpy( newdn, rawrdn );
- strcat( newdn, "," );
- strcat( newdn, parentdn );
+ char *newdn = slapi_ch_smprintf("%s,%s", rawrdn, parentdn);
slapi_ch_free((void**)&parentdn);
slapi_sdn_set_dn_passin(sdn,newdn);
}
@@ -1264,10 +1889,10 @@ slapi_sdn_get_ndn(const Slapi_DN *sdn)
if(sdn->dn!=NULL)
{
char *p= slapi_ch_strdup(sdn->dn);
- Slapi_DN *ncsdn= (Slapi_DN*)sdn; /* non-const Slapi_DN */
- slapi_dn_normalize_case(p);
+ Slapi_DN *ncsdn= (Slapi_DN*)sdn; /* non-const Slapi_DN */
+ slapi_dn_ignore_case(p); /* dn is normalized; just ignore case */
ncsdn->ndn= p;
- ncsdn->ndn_len=strlen(p);
+ ncsdn->ndn_len=strlen(p);
ncsdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_NDN);
PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_created);
PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_exist);
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
index 3816d42..0a8c40d 100644
--- a/ldap/servers/slapd/entry.c
+++ b/ldap/servers/slapd/entry.c
@@ -150,9 +150,9 @@ str2entry_state_information_from_type(char *s,CSNSet **csnset,CSN **attributedel
}
}
-/* dn is not consumed. Caller needs to free it. */
+/* rawdn is not consumed. Caller needs to free it. */
static Slapi_Entry *
-str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
+str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
{
Slapi_Entry *e;
char *next, *ptype=NULL;
@@ -163,6 +163,11 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
CSN *attributedeletioncsn= NULL; /* Moved to this level so that the JCM csn_free call below gets useful */
CSNSet *valuecsnset= NULL; /* Moved to this level so that the JCM csn_free call below gets useful */
CSN *maxcsn = NULL;
+ char *normdn = NULL;
+ int strict = 0;
+
+ /* Check if we should be performing strict validation. */
+ strict = config_get_dn_validate_strict();
/*
* In string format, an entry looks like either of these:
@@ -267,13 +272,41 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
a = NULL;
}
- if ( dn ) {
- if ( NULL == slapi_entry_get_dn_const( e )) {
- slapi_entry_set_dn( e, slapi_ch_strdup( dn ));
+ if ( rawdn ) {
+ if ( NULL == slapi_entry_get_dn_const( e )) {
+ normdn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == normdn) {
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
+ "str2entry_fast: Invalid DN: %s\n", rawdn);
+ slapi_entry_free( e );
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ return NULL;
+ }
+ /* normdn is consumed in e */
+ slapi_entry_set_dn(e, normdn);
}
- if ( NULL == slapi_entry_get_rdn_const( e )) {
- slapi_entry_set_rdn( e, (char *)dn );
+ if ( NULL == slapi_entry_get_rdn_const( e )) {
+ if (normdn) {
+ /* normdn is just referred in slapi_entry_set_rdn. */
+ slapi_entry_set_rdn(e, normdn);
+ } else {
+ normdn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == normdn) {
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
+ "str2entry_fast: Invalid DN: %s\n", rawdn);
+ slapi_entry_free( e );
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ return NULL;
+ }
+ /* normdn is just referred in slapi_entry_set_rdn. */
+ slapi_entry_set_rdn(e, normdn);
+ slapi_ch_free_string(&normdn);
+ }
}
+ rawdn = NULL; /* Set once in the loop.
+ This won't affect the caller's passed address. */
}
if ( strcasecmp( type, "dn" ) == 0 ) {
if ( slapi_entry_get_dn_const(e)!=NULL ) {
@@ -288,11 +321,22 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
if (freetype) slapi_ch_free_string(&type);
continue;
}
- slapi_entry_set_dn(e,slapi_ch_strdup( valuecharptr ));
+ normdn = slapi_create_dn_string("%s", valuecharptr);
+ if (NULL == normdn) {
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
+ "str2entry_fast: Invalid DN: %s\n", valuecharptr);
+ slapi_entry_free( e );
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ return NULL;
+ }
+ /* normdn is consumed in e */
+ slapi_entry_set_dn(e, normdn);
+
/* the memory below was not allocated by the slapi_ch_ functions */
if (retmalloc) slapi_ch_free_string(&valuecharptr);
if (freetype) slapi_ch_free_string(&type);
- continue;
+ continue;
}
if ( strcasecmp( type, "rdn" ) == 0 ) {
@@ -302,7 +346,7 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
/* the memory below was not allocated by the slapi_ch_ functions */
if (retmalloc) slapi_ch_free_string(&valuecharptr);
if (freetype) slapi_ch_free_string(&type);
- continue;
+ continue;
}
@@ -310,8 +354,9 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
if ( strcasecmp (type, SLAPI_ATTR_UNIQUEID) == 0 ){
if (e->e_uniqueid != NULL){
- LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: entry has multiple "
- "uniqueids %s and %s (second ignored)\n",
+ LDAPDebug (LDAP_DEBUG_TRACE,
+ "str2entry_fast: entry has multiple uniqueids %s "
+ "and %s (second ignored)\n",
e->e_uniqueid, valuecharptr, 0);
}else{
/* name2asi will be locked in slapi_entry_set_uniqueid */
@@ -333,12 +378,7 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
}
{
- Slapi_Value *value= value_new(NULL,CSN_TYPE_NONE,NULL);
- slapi_value_set( value, valuecharptr, valuelen );
- /* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free_string(&valuecharptr);
- value->v_csnset= valuecsnset;
- valuecsnset= NULL;
+ Slapi_Value *value = NULL;
if(a==NULL)
{
switch(attr_state)
@@ -368,9 +408,51 @@ str2entry_fast( const char *dn, char *s, int flags, int read_stateinfo )
continue;
/* break; ??? */
}
-
+ }
+ /* moved the value setting code here to check Slapi_Attr 'a'
+ * to retrieve the attribute syntax info */
+ value = value_new(NULL, CSN_TYPE_NONE, NULL);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ int rc = 0;
+ char *dn_aval = NULL;
+ size_t dnlen = 0;
+ if (strict) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(NULL, valuecharptr, 1);
+ if (rc) { /* syntax check failed */
+ LDAPDebug2Args(LDAP_DEBUG_TRACE,
+ "str2entry_fast: strict: Invalid DN value: %s: %s\n",
+ type, valuecharptr);
+ slapi_entry_free( e );
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ return NULL;
+ }
+ }
+ rc = slapi_dn_normalize_ext(valuecharptr, 0, &dn_aval, &dnlen);
+ if (rc < 0) {
+ /* Give up normalizing the attribute value */
+ LDAPDebug2Args(LDAP_DEBUG_TRACE,
+ "str2entry_fast: Invalid DN value: %s: %s\n",
+ type, valuecharptr);
+ dn_aval = valuecharptr;
+ dnlen = valuelen;
+ }
+ slapi_value_set(value, dn_aval, dnlen);
+ if (rc > 0) { /* if rc == 0, valuecharptr is passed in */
+ slapi_ch_free_string(&dn_aval);
+ } else if (rc == 0) { /* rc == 0; valuecharptr is passed in;
+ not null terminated */
+ *(dn_aval + dnlen) = '\0';
+ }
+ } else {
+ slapi_value_set(value, valuecharptr, valuelen);
}
if (freetype) slapi_ch_free_string(&type); /* don't need type anymore */
+ /* the memory below was not allocated by the slapi_ch_ functions */
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ value->v_csnset = valuecsnset;
+ valuecsnset = NULL;
{
const CSN *distinguishedcsn= csnset_get_csn_of_type(value->v_csnset,CSN_TYPE_VALUE_DISTINGUISHED);
if(distinguishedcsn!=NULL)
@@ -601,7 +683,7 @@ entry_attrs_find(entry_attrs *ea,char *type)
/* dn is not consumed. Caller needs to free it. */
static Slapi_Entry *
-str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
+str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
{
Slapi_Entry *e;
str2entry_attr stack_attrs[STR2ENTRY_SMALL_BUFFER_SIZE];
@@ -625,6 +707,11 @@ str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
( 0 != ( flags & SLAPI_STR2ENTRY_REMOVEDUPVALS ));
Slapi_Value *value = 0;
CSN *maxcsn= NULL;
+ char *normdn = NULL;
+ int strict = 0;
+
+ /* Check if we should be performing strict validation. */
+ strict = config_get_dn_validate_strict();
LDAPDebug( LDAP_DEBUG_TRACE, "=> str2entry_dupcheck\n", 0, 0, 0 );
@@ -688,16 +775,44 @@ str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
csnset_free(&valuecsnset);
}
- if ( dn ) {
- if ( NULL == slapi_entry_get_dn_const(e) ) {
- slapi_entry_set_dn( e, slapi_ch_strdup( dn ));
+ if ( rawdn ) {
+ if ( NULL == slapi_entry_get_dn_const(e) ) {
+ normdn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == normdn) {
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
+ "str2entry_dupcheck: Invalid DN: %s\n", rawdn);
+ slapi_entry_free( e );
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ return NULL;
+ }
+ /* normdn is consumed in e */
+ slapi_entry_set_dn(e, normdn);
}
- if ( NULL == slapi_entry_get_rdn_const(e) ) {
- slapi_entry_set_rdn( e, (char *)dn );
+ if ( NULL == slapi_entry_get_rdn_const(e) ) {
+ if (normdn) {
+ /* normdn is just referred in slapi_entry_set_rdn. */
+ slapi_entry_set_rdn(e, normdn);
+ } else {
+ normdn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == normdn) {
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
+ "str2entry_fast: Invalid DN: %s\n", rawdn);
+ slapi_entry_free( e );
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ return NULL;
+ }
+ /* normdn is just referred in slapi_entry_set_rdn. */
+ slapi_entry_set_rdn(e, normdn);
+ slapi_ch_free_string(&normdn);
+ }
}
+ rawdn = NULL; /* Set once in the loop.
+ This won't affect the caller's passed address. */
}
if ( strcasecmp( type, "dn" ) == 0 ) {
- if ( slapi_entry_get_dn_const(e)!=NULL ) {
+ if ( slapi_entry_get_dn_const(e)!=NULL ) {
char ebuf[ BUFSIZ ];
LDAPDebug( LDAP_DEBUG_TRACE,
"str2entry_dupcheck: entry has multiple dns \"%s\" "
@@ -708,8 +823,18 @@ str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
if (retmalloc) slapi_ch_free_string(&valuecharptr);
if (freetype) slapi_ch_free_string(&type);
continue;
- }
- slapi_entry_set_dn(e,slapi_ch_strdup( valuecharptr ));
+ }
+ normdn = slapi_create_dn_string("%s", valuecharptr);
+ if (NULL == normdn) {
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
+ "str2entry_dupcheck: Invalid DN: %s\n", valuecharptr);
+ slapi_entry_free( e ); e = NULL;
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ goto free_and_return;
+ }
+ /* normdn is consumed in e */
+ slapi_entry_set_dn(e, normdn);
/* the memory below was not allocated by the slapi_ch_ functions */
if (retmalloc) slapi_ch_free_string(&valuecharptr);
if (freetype) slapi_ch_free_string(&type);
@@ -730,8 +855,9 @@ str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
if ( strcasecmp (type, SLAPI_ATTR_UNIQUEID) == 0 ){
if (e->e_uniqueid != NULL){
- LDAPDebug (LDAP_DEBUG_ANY, "str2entry_dupcheck: entry has multiple "
- "uniqueids %s and %s (second ignored)\n",
+ LDAPDebug (LDAP_DEBUG_TRACE,
+ "str2entry_dupcheck: entry has multiple uniqueids %s "
+ "and %s (second ignored)\n",
e->e_uniqueid, valuecharptr, 0);
}else{
slapi_entry_set_uniqueid (e, slapi_ch_strdup(valuecharptr));
@@ -853,10 +979,44 @@ str2entry_dupcheck( const char *dn, char *s, int flags, int read_stateinfo )
nattrs++;
}
- if (freetype) slapi_ch_free_string(&type);
sa = prev_attr; /* For readability */
- value= value_new(NULL,CSN_TYPE_NONE,NULL);
- slapi_value_set( value, valuecharptr, valuelen );
+ value= value_new(NULL, CSN_TYPE_NONE, NULL);
+ if (slapi_attr_is_dn_syntax_attr(&(sa->sa_attr))) {
+ char *dn_aval = NULL;
+ size_t dnlen = 0;
+ if (strict) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(NULL, valuecharptr, 1);
+ if (rc) { /* syntax check failed */
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "str2entry_dupcheck: strict: Invalid DN value: %s: %s\n",
+ type, valuecharptr);
+ slapi_entry_free( e ); e = NULL;
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ goto free_and_return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(valuecharptr, 0, &dn_aval, &dnlen);
+ if (rc < 0) {
+ /* Give up normalizing the attribute value */
+ LDAPDebug2Args(LDAP_DEBUG_TRACE,
+ "str2entry_dupcheck: Invalid DN value: %s: %s\n",
+ type, valuecharptr);
+ dn_aval = valuecharptr;
+ dnlen = valuelen;
+ }
+ slapi_value_set(value, dn_aval, dnlen);
+ if (rc > 0) { /* if rc == 0, valuecharptr is passed in */
+ slapi_ch_free_string(&dn_aval);
+ } else if (rc == 0) { /* rc == 0; valuecharptr is passed in;
+ not null terminated */
+ *(dn_aval + dnlen) = '\0';
+ }
+ } else {
+ slapi_value_set(value, valuecharptr, valuelen);
+ }
+ if (freetype) slapi_ch_free_string(&type);
/* the memory below was not allocated by the slapi_ch_ functions */
if (retmalloc) slapi_ch_free_string(&valuecharptr);
value->v_csnset= valuecsnset;
@@ -1166,6 +1326,7 @@ slapi_str2entry( char *s, int flags )
/*
* string s does not include dn.
+ * NOTE: the first arg "dn" should have been normalized before passing.
*/
Slapi_Entry *
slapi_str2entry_ext( const char *dn, char *s, int flags )
@@ -1190,15 +1351,15 @@ slapi_str2entry_ext( const char *dn, char *s, int flags )
*/
if ( 0 != ( flags & SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF ) ||
0 != ( flags & ~SLAPI_STRENTRY_FLAGS_HANDLED_BY_STR2ENTRY_FAST ))
- {
+ {
e= str2entry_dupcheck( dn, s, flags, read_stateinfo );
- }
- else
- {
+ }
+ else
+ {
e= str2entry_fast( dn, s, flags, read_stateinfo );
- }
- if (!e)
- return e; /* e == NULL */
+ }
+ if (!e)
+ return e; /* e == NULL */
if ( flags & SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES )
{
@@ -1770,8 +1931,12 @@ static size_t slapi_dn_size(Slapi_DN *sdn)
if (sdn == NULL) return 0;
- if (sdn->dn) size += strlen(sdn->dn) + 1;
- if (sdn->ndn) size *= 2;
+ if (slapi_sdn_get_dn(sdn)) {
+ size += strlen(slapi_sdn_get_dn(sdn)) + 1;
+ }
+ if (slapi_sdn_get_ndn(sdn)) {
+ size += strlen(slapi_sdn_get_ndn(sdn)) + 1;
+ }
return size;
}
@@ -2922,7 +3087,7 @@ entry_apply_mod( Slapi_Entry *e, const LDAPMod *mod )
case LDAP_MOD_ADD:
LDAPDebug( LDAP_DEBUG_ARGS, " add: %s\n", mod->mod_type, 0, 0 );
if(sawsubentry) e->e_flags |= SLAPI_ENTRY_LDAPSUBENTRY;
- err = slapi_entry_add_values( e, mod->mod_type, mod->mod_bvalues );
+ err = slapi_entry_add_values( e, mod->mod_type, mod->mod_bvalues );
break;
case LDAP_MOD_DELETE:
@@ -2980,6 +3145,9 @@ slapi_entry_add_values_sv(Slapi_Entry *e,
Slapi_Attr **a= NULL;
Slapi_Attr **alist= &e->e_attrs;
attrlist_find_or_create(alist, type, &a);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ valuearray_normalize_value(vals);
+ }
rc= attr_add_valuearray(*a,vals,slapi_entry_get_dn_const(e));
}
return( rc );
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
index 6b51ef1..01c160c 100644
--- a/ldap/servers/slapd/entrywsi.c
+++ b/ldap/servers/slapd/entrywsi.c
@@ -450,6 +450,10 @@ entry_add_present_values_wsi(Slapi_Entry *e, const char *type, struct berval **b
}
a_flags_orig = a->a_flags;
a->a_flags |= flags;
+ /* Check if the type of the to-be-added values has DN syntax or not. */
+ if (slapi_attr_is_dn_syntax_attr(a)) {
+ valuearray_normalize_value(valuestoadd);
+ }
if(urp)
{
/*
@@ -566,6 +570,11 @@ entry_delete_present_values_wsi(Slapi_Entry *e, const char *type, struct berval
/* delete some specific values */
Slapi_Value **valuestodelete= NULL;
valuearray_init_bervalarray(vals,&valuestodelete); /* JCM SLOW FUNCTION */
+ /* Check if the type of the to-be-deleted values has DN syntax
+ * or not. */
+ if (slapi_attr_is_dn_syntax_attr(a)) {
+ valuearray_normalize_value(valuestodelete);
+ }
if(urp)
{
Slapi_Value **valuesupdated= NULL;
diff --git a/ldap/servers/slapd/extendop.c b/ldap/servers/slapd/extendop.c
index 003c2ab..a521cb7 100644
--- a/ldap/servers/slapd/extendop.c
+++ b/ldap/servers/slapd/extendop.c
@@ -53,7 +53,9 @@ static const char *extended_op_oid2string( const char *oid );
static void extop_handle_import_start(Slapi_PBlock *pb, char *extoid,
struct berval *extval)
{
- char *suffix;
+ char *orig = NULL;
+ char *suffix = NULL;
+ size_t dnlen = 0;
Slapi_DN *sdn = NULL;
Slapi_Backend *be = NULL;
struct berval bv;
@@ -66,10 +68,34 @@ static void extop_handle_import_start(Slapi_PBlock *pb, char *extoid,
"no data supplied", 0, NULL);
return;
}
- suffix = slapi_ch_malloc(extval->bv_len+1);
- strncpy(suffix, extval->bv_val, extval->bv_len);
- suffix[extval->bv_len] = 0;
-
+ orig = slapi_ch_malloc(extval->bv_len+1);
+ strncpy(orig, extval->bv_val, extval->bv_len);
+ orig[extval->bv_len] = 0;
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ ret = slapi_dn_syntax_check(pb, orig, 1);
+ if (ret) { /* syntax check failed */
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "extop_handle_import_start: strict: invalid suffix\n",
+ orig);
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
+ "invalid suffix", 0, NULL);
+ return;
+ }
+ }
+ ret = slapi_dn_normalize_ext(orig, 0, &suffix, &dnlen);
+ if (ret < 0) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "extop_handle_import_start: invalid suffix\n", orig);
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
+ "invalid suffix", 0, NULL);
+ return;
+ } else if (ret > 0) {
+ slapi_ch_free_string(&orig);
+ } else { /* ret == 0; orig is passed in; not null terminated */
+ *(suffix + dnlen) = '\0';
+ }
sdn = slapi_sdn_new_dn_byval(suffix);
if (!sdn) {
LDAPDebug(LDAP_DEBUG_ANY,
@@ -109,6 +135,7 @@ static void extop_handle_import_start(Slapi_PBlock *pb, char *extoid,
/* slapi_str2entry modify its dn parameter so we must copy
* this string each time we call it !
*/
+ /* This dn is no need to be normalized. */
PR_snprintf(dn, sizeof(dn), "dn: oid=%s,cn=features,cn=config",
EXTOP_BULK_IMPORT_START_OID);
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
index 0439007..642b6af 100644
--- a/ldap/servers/slapd/fedse.c
+++ b/ldap/servers/slapd/fedse.c
@@ -76,6 +76,7 @@
extern char ** getSupportedCiphers();
+/* Note: These DNs are no need to be normalized */
static const char *internal_entries[] =
{
"dn:\n"
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index dbeae65..b8e26d1 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -870,7 +870,8 @@ FrontendConfig_init () {
cfg->ldapi_map_entries = LDAP_OFF;
cfg->ldapi_uidnumber_type = slapi_ch_strdup("uidNumber");
cfg->ldapi_gidnumber_type = slapi_ch_strdup("gidNumber");
- cfg->ldapi_search_base_dn = slapi_ch_strdup("dc=example, dc=com");
+ /* These DNs are no need to be normalized. */
+ cfg->ldapi_search_base_dn = slapi_ch_strdup("dc=example,dc=com");
#if defined(ENABLE_AUTO_DN_SUFFIX)
cfg->ldapi_auto_dn_suffix = slapi_ch_strdup("cn=peercred,cn=external,cn=auth");
#endif
@@ -4884,18 +4885,18 @@ config_set_instancedir(const char *attrname, char *value, char *errorbuf, int ap
{
int retVal = LDAP_SUCCESS;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
-
+
if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
return LDAP_OPERATIONS_ERROR;
}
-
+
if (!apply) {
return retVal;
}
-
+
CFG_LOCK_WRITE(slapdFrontendConfig);
/* We don't want to allow users to modify instance dir.
- * Set it once when the server starts. */
+ * Set it once when the server starts. */
if (NULL == slapdFrontendConfig->instancedir) {
slapdFrontendConfig->instancedir = slapi_ch_strdup(value);
}
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index 5023dcd..3772a75 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -1107,6 +1107,7 @@ main( int argc, char **argv)
/* initialize UniqueID generator - must be done once backends are started
and event queue is initialized but before plugins are started */
+ /* Note: This DN is no need to be normalized. */
sdn = slapi_sdn_new_dn_byval ("cn=uniqueid generator,cn=config");
rc = uniqueIDGenInit (NULL, sdn, slapd_exemode == SLAPD_EXEMODE_SLAPD);
slapi_sdn_free (&sdn);
@@ -1908,6 +1909,7 @@ lookup_instance_name_by_suffix(char *suffix,
if (query == NULL)
goto done;
+ /* Note: This DN is no need to be normalized. */
slapi_search_internal_set_pb(pb, "cn=mapping tree,cn=config",
LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
@@ -1928,6 +1930,7 @@ lookup_instance_name_by_suffix(char *suffix,
query = slapi_ch_smprintf("(&(objectclass=nsmappingtree)(|(cn=*%s\")(cn=*%s)))", suffixp, suffixp);
if (query == NULL)
goto done;
+ /* Note: This DN is no need to be normalized. */
slapi_search_internal_set_pb(pb, "cn=mapping tree,cn=config",
LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
@@ -2015,6 +2018,7 @@ static struct slapdplugin *lookup_plugin_by_instance_name(const char *name)
return NULL;
}
+ /* Note: This DN is no need to be normalized. */
slapi_search_internal_set_pb(pb, "cn=plugins,cn=config",
LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index 645618c..7503929 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -133,6 +133,7 @@ static int extension_type = -1; /* type returned from the factory */
/* Need to add a modifier flag to the state - such as round robin */
+/* Note: This DN is no need to be normalized. */
#define MAPPING_TREE_BASE_DN "cn=mapping tree,cn=config"
#define MAPPING_TREE_PARENT_ATTRIBUTE "nsslapd-parent-suffix"
@@ -365,24 +366,30 @@ static Slapi_DN *
get_parent_from_entry(Slapi_Entry * entry)
{
Slapi_Attr *attr = NULL;
- char * parent;
+ char *origparent = NULL;
+ char *parent = NULL;
Slapi_Value *val = NULL;
- Slapi_DN *parent_sdn;
+ Slapi_DN *parent_sdn = NULL;
if (slapi_entry_attr_find(entry, MAPPING_TREE_PARENT_ATTRIBUTE, &attr))
return NULL;
slapi_attr_first_value(attr, &val);
- parent = slapi_ch_strdup(slapi_value_get_string(val));
- if(parent[0]=='\"')
- {
- parent[strlen(parent) - 1] = '\0';
- parent_sdn = slapi_sdn_new_dn_byval(parent+1);
+ origparent = parent = slapi_ch_strdup(slapi_value_get_string(val));
+ if (parent) {
+ if(*parent == '"') {
+ char *ptr = NULL;
+ parent++; /* skipping the starting '"' */
+ ptr = PL_strnrchr(parent, '"', strlen(parent));
+ if (ptr) {
+ *ptr = '\0';
+ }
+ }
+ parent_sdn =
+ slapi_sdn_new_dn_passin(slapi_create_dn_string("%s", parent));
+ slapi_ch_free_string(&origparent);
}
- else
- parent_sdn = slapi_sdn_new_dn_byval(parent);
- slapi_ch_free((void **) &parent);
return parent_sdn;
}
@@ -393,9 +400,10 @@ static Slapi_DN *
get_subtree_from_entry(Slapi_Entry * entry)
{
Slapi_Attr *attr = NULL;
- char * cn;
+ char *origcn = NULL;
+ char *cn = NULL;
Slapi_Value *val = NULL;
- Slapi_DN *subtree;
+ Slapi_DN *subtree = NULL;
if (slapi_entry_attr_find(entry, "cn", &attr))
return NULL;
@@ -415,15 +423,19 @@ get_subtree_from_entry(Slapi_Entry * entry)
/* GB : I think removing the first and last " in the cn value
* is the right stuff to do
*/
- cn = slapi_ch_strdup(slapi_value_get_string(val));
- if(cn[0]=='\"')
- {
- cn[strlen(cn) - 1] = '\0';
- subtree = slapi_sdn_new_dn_byval(cn+1);
+ origcn = cn = slapi_ch_strdup(slapi_value_get_string(val));
+ if (cn) {
+ if(*cn == '"') {
+ char *ptr = NULL;
+ cn++; /* skipping the starting '"' */
+ ptr = PL_strnrchr(cn, '"', strlen(cn));
+ if (ptr) {
+ *ptr = '\0';
+ }
+ }
+ subtree = slapi_sdn_new_dn_passin(slapi_create_dn_string("%s", cn));
+ slapi_ch_free_string(&origcn);
}
- else
- subtree = slapi_sdn_new_dn_byval(cn);
- slapi_ch_free((void **) &cn);
return subtree;
}
@@ -2790,7 +2802,7 @@ get_mapping_tree_node_by_name(mapping_tree_node * node, char * be_name)
char*
slapi_get_mapping_tree_node_configdn (const Slapi_DN *root)
{
- char *dn;
+ char *dn = NULL;
if(mapping_tree_freed){
/* shutdown detected */
@@ -2799,7 +2811,16 @@ slapi_get_mapping_tree_node_configdn (const Slapi_DN *root)
if (root == NULL)
return NULL;
- dn = slapi_ch_smprintf("cn=\"%s\",%s", slapi_sdn_get_dn(root), MAPPING_TREE_BASE_DN);
+ /* This function converts the old DN style to the new one. */
+ dn = slapi_create_dn_string("cn=\"%s\",%s",
+ slapi_sdn_get_dn(root), MAPPING_TREE_BASE_DN);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "slapi_get_mapping_tree_node_configdn: "
+ "failed to crate mapping tree dn for %s\n",
+ slapi_sdn_get_dn(root));
+ return NULL;
+ }
return dn;
}
@@ -3114,7 +3135,7 @@ slapi_mtn_set_referral(const Slapi_DN *sdn, char ** referral)
}
slapi_mods_done(&smods);
- slapi_ch_free((void **) &node_dn);
+ slapi_ch_free_string(&node_dn);
return rc;
}
@@ -3135,13 +3156,13 @@ slapi_mtn_set_state(const Slapi_DN *sdn, char *state)
char * node_dn;
char * value;
- node_dn = slapi_get_mapping_tree_node_configdn(sdn);
- if(!node_dn){
- /* shutdown has been detected */
+ if (NULL == state) {
return LDAP_OPERATIONS_ERROR;
}
- if (NULL == state) {
+ node_dn = slapi_get_mapping_tree_node_configdn(sdn);
+ if(!node_dn){
+ /* shutdown has been detected */
return LDAP_OPERATIONS_ERROR;
}
@@ -3150,9 +3171,7 @@ slapi_mtn_set_state(const Slapi_DN *sdn, char *state)
if ( strcasecmp(value, state) == 0 )
{
/* Same state, don't change anything */
- slapi_ch_free((void **) &value);
- slapi_ch_free((void **) &node_dn);
- return rc;
+ goto bail;
}
}
@@ -3168,10 +3187,10 @@ slapi_mtn_set_state(const Slapi_DN *sdn, char *state)
slapi_pblock_get (&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
slapi_mods_done(&smods);
- slapi_ch_free((void **) &node_dn);
pblock_done(&pb);
- slapi_ch_free((void **) &value);
-
+bail:
+ slapi_ch_free_string(&value);
+ slapi_ch_free_string(&node_dn);
return rc;
}
@@ -3265,7 +3284,7 @@ slapi_mtn_get_referral(const Slapi_DN *sdn)
slapi_attr_free(&attr);
}
- slapi_ch_free((void **) &node_dn);
+ slapi_ch_free_string(&node_dn);
return referral;
}
@@ -3301,7 +3320,7 @@ slapi_mtn_get_state(const Slapi_DN *sdn)
slapi_attr_free(&attr);
}
- slapi_ch_free((void **) &node_dn);
+ slapi_ch_free_string(&node_dn);
return state;
}
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index 40646b2..027bbef 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -166,16 +166,43 @@ do_modify( Slapi_PBlock *pb )
*/
{
- if ( ber_scanf( ber, "{a", &dn ) == LBER_ERROR )
+ char *rawdn = NULL;
+ size_t dnlen = 0;
+ int rc = 0;
+ if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR )
{
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Modify; params=DN)\n", 0, 0, 0 );
op_shared_log_error_access (pb, "MOD", "???", "decoding error");
- send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
- NULL );
- slapi_ch_free_string(&dn);
+ send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL );
+ slapi_ch_free_string(&rawdn);
return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "MOD", "???", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ } else if (rc > 0) { /* if rc == 0, rawdn is passed in */
+ slapi_ch_free_string(&rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
}
LDAPDebug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", dn, 0, 0 );
diff --git a/ldap/servers/slapd/modrdn.c b/ldap/servers/slapd/modrdn.c
index b70377a..6951fb0 100644
--- a/ldap/servers/slapd/modrdn.c
+++ b/ldap/servers/slapd/modrdn.c
@@ -72,10 +72,13 @@ do_modrdn( Slapi_PBlock *pb )
{
Slapi_Operation *operation;
BerElement *ber;
+ char *rawdn = NULL, *rawnewsuperior = NULL;
char *dn = NULL, *newsuperior = NULL;
+ char *rawnewrdn = NULL;
char *newrdn = NULL;
int err = 0, deloldrdn = 0;
ber_len_t len = 0;
+ size_t dnlen = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 );
@@ -96,7 +99,7 @@ do_modrdn( Slapi_PBlock *pb )
* }
*/
- if ( ber_scanf( ber, "{aab", &dn, &newrdn, &deloldrdn )
+ if ( ber_scanf( ber, "{aab", &rawdn, &rawnewrdn, &deloldrdn )
== LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=ModRDN; params=DN,newRDN,deleteOldRDN)\n",
@@ -109,25 +112,116 @@ do_modrdn( Slapi_PBlock *pb )
}
if ( ber_peek_tag( ber, &len ) == LDAP_TAG_NEWSUPERIOR ) {
+ /* This "len" is not used... */
if ( pb->pb_conn->c_ldapversion < LDAP_VERSION3 ) {
LDAPDebug( LDAP_DEBUG_ANY,
"got newSuperior in LDAPv2 modrdn op\n", 0, 0, 0 );
- op_shared_log_error_access (pb, "MODRDN", dn, "decoding error");
+ op_shared_log_error_access (pb, "MODRDN",
+ rawdn?rawdn:"", "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"received newSuperior in LDAPv2 modrdn", 0, NULL );
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
goto free_and_return;
}
- if ( ber_scanf( ber, "a", &newsuperior ) == LBER_ERROR ) {
+ if ( ber_scanf( ber, "a", &rawnewsuperior ) == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=ModRDN; params=newSuperior)\n",
0, 0, 0 );
- op_shared_log_error_access (pb, "MODRDN", dn, "decoding error");
+ op_shared_log_error_access (pb, "MODRDN", rawdn, "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"unable to decode newSuperior parameter", 0, NULL );
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
goto free_and_return;
}
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MODRDN", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ }
+ /* check that the new rdn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawnewrdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MODRDN", rawnewrdn?rawnewrdn:"",
+ "strict: invalid new rdn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new rdn", 0, NULL);
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "MODRDN", rawdn?rawdn:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ } else if (err > 0) {
+ slapi_ch_free((void **) &rawdn);
+ } else { /* err == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
+ err = slapi_dn_normalize_ext(rawnewrdn, 0, &newrdn, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "MODRDN", rawnewrdn?rawnewrdn:"",
+ "invalid new rdn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new rdn", 0, NULL);
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ } else if (err > 0) {
+ slapi_ch_free((void **) &rawnewrdn);
+ } else { /* err == 0; rawnewdn is passed in; not null terminated */
+ *(newrdn + dnlen) = '\0';
+ }
+ if (rawnewsuperior) {
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawnewsuperior, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MODRDN",
+ rawnewsuperior?rawnewsuperior:"",
+ "strict: invalid new superior");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new superior", 0, NULL);
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawnewsuperior, 0, &newsuperior, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "MODRDN",
+ rawnewsuperior?rawnewsuperior:"",
+ "invalid new superior");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new superior", 0, NULL);
+ slapi_ch_free_string( &rawnewsuperior);
+ goto free_and_return;
+ } else if (err > 0) {
+ slapi_ch_free((void **) &rawnewsuperior);
+ } else { /* err == 0; rawnewsuperior is passed in; not terminated */
+ *(newsuperior + dnlen) = '\0';
+ }
+ }
+
/*
* in LDAPv3 there can be optional control extensions on
* the end of an LDAPMessage. we need to read them in and
@@ -153,9 +247,9 @@ do_modrdn( Slapi_PBlock *pb )
return;
free_and_return:
- slapi_ch_free((void **) &dn );
- slapi_ch_free((void **) &newrdn );
- slapi_ch_free((void **) &newsuperior );
+ slapi_ch_free_string( &dn );
+ slapi_ch_free_string( &newrdn );
+ slapi_ch_free_string( &newsuperior );
return;
}
diff --git a/ldap/servers/slapd/modutil.c b/ldap/servers/slapd/modutil.c
index 9c5949d..82147c6 100644
--- a/ldap/servers/slapd/modutil.c
+++ b/ldap/servers/slapd/modutil.c
@@ -188,11 +188,37 @@ void
slapi_mods_insert_at(Slapi_Mods *smods, LDAPMod *mod, int pos)
{
int i;
- slapi_mods_add_one_element(smods);
- for( i=smods->num_mods-1; i>=pos; i--)
+ Slapi_Attr a = {0};
+
+ if (NULL == mod) {
+ return;
+ }
+ slapi_mods_add_one_element(smods);
+ for( i=smods->num_mods-1; i>=pos; i--)
{
smods->mods[i+1]= smods->mods[i];
}
+ slapi_attr_init(&a, mod->mod_type);
+ /* Check if the type of the to-be-added values has DN syntax or not. */
+ if (slapi_attr_is_dn_syntax_attr(&a)) {
+ int rc = 0;
+ struct berval **mbvp = NULL;
+ char *normed = NULL;
+ size_t len = 0;
+ for (mbvp = mod->mod_bvalues; mbvp && *mbvp; mbvp++) {
+ rc = slapi_dn_normalize_ext((*mbvp)->bv_val, (*mbvp)->bv_len,
+ &normed, &len);
+ if (rc > 0) {
+ slapi_ch_free((void **)&((*mbvp)->bv_val));
+ } else if (rc == 0) {
+ /* original is passed in; not null terminated */
+ *(normed + len) = '\0';
+ }
+ (*mbvp)->bv_val = normed;
+ (*mbvp)->bv_len = len;
+ }
+ }
+ attr_done(&a);
smods->mods[pos]= mod;
smods->num_mods++;
smods->mods[smods->num_mods]= NULL;
diff --git a/ldap/servers/slapd/passwd_extop.c b/ldap/servers/slapd/passwd_extop.c
index 14341f9..ff2e19f 100644
--- a/ldap/servers/slapd/passwd_extop.c
+++ b/ldap/servers/slapd/passwd_extop.c
@@ -455,7 +455,9 @@ passwd_modify_extop( Slapi_PBlock *pb )
char *oid = NULL;
char *bindDN = NULL;
char *authmethod = NULL;
+ char *rawdn = NULL;
char *dn = NULL;
+ size_t dnlen = 0;
char *otdn = NULL;
char *oldPasswd = NULL;
char *newPasswd = NULL;
@@ -561,16 +563,43 @@ passwd_modify_extop( Slapi_PBlock *pb )
/* identify userID field by tags */
if (tag == LDAP_EXTOP_PASSMOD_TAG_USERID )
{
- if ( ber_scanf( ber, "a", &dn) == LBER_ERROR )
+ int rc = 0;
+ if ( ber_scanf( ber, "a", &rawdn) == LBER_ERROR )
{
- slapi_ch_free_string(&dn);
+ slapi_ch_free_string(&rawdn);
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed :{\n", 0, 0, 0 );
errMesg = "ber_scanf failed at userID parse.\n";
rc = LDAP_PROTOCOL_ERROR;
goto free_and_return;
}
-
+
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "EXT", rawdn?rawdn:"",
+ "strict: invalid target dn");
+ errMesg = "invalid target dn.\n";
+ slapi_ch_free_string(&rawdn);
+ rc = LDAP_INVALID_SYNTAX;
+ goto free_and_return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "EXT", rawdn?rawdn:"",
+ "invalid target dn");
+ slapi_ch_free_string(&rawdn);
+ errMesg = "invalid target dn.\n";
+ rc = LDAP_INVALID_SYNTAX;
+ goto free_and_return;
+ } else if (rc == 0) { /* rawdn is passed in, not terminated */
+ *(dn + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&rawdn);
+ }
tag = ber_peek_tag( ber, &len);
}
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 133f60e..84dbcfe 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -268,8 +268,15 @@ slapi_register_plugin_ext(
{
int ii = 0;
int rc = 0;
- Slapi_Entry *e = slapi_entry_alloc();
- char *dn = slapi_ch_smprintf("cn=%s, %s", name, PLUGIN_BASE_DN);
+ Slapi_Entry *e = NULL;
+ char *dn = slapi_create_dn_string("cn=%s,%s", name, PLUGIN_BASE_DN);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, NULL,
+ "slapi_register_plugin_ext: "
+ "failed to create plugin dn (plugin name: %s)\n", name);
+ return 1;
+ }
+ e = slapi_entry_alloc();
/* this function consumes dn */
slapi_entry_init(e, dn, NULL);
@@ -2461,7 +2468,7 @@ plugin_invoke_plugin_sdn (struct slapdplugin *plugin, int operation, Slapi_PBloc
*/
char* plugin_get_dn (const struct slapdplugin *plugin)
{
- char *plugindn;
+ char *plugindn = NULL;
char *pattern = "cn=%s," PLUGIN_BASE_DN;
if (plugin == NULL) /* old plugin that does not pass identity - use default */
@@ -2470,8 +2477,13 @@ char* plugin_get_dn (const struct slapdplugin *plugin)
if (plugin->plg_name == NULL)
return NULL;
- plugindn = slapi_ch_smprintf(pattern, plugin->plg_name);
-
+ plugindn = slapi_create_dn_string(pattern, plugin->plg_name);
+ if (NULL == plugindn) {
+ slapi_log_error(SLAPI_LOG_FATAL, NULL,
+ "plugin_get_dn: failed to create plugin dn "
+ "(plugin name: %s)\n", plugin->plg_name);
+ return NULL;
+ }
return plugindn;
}
@@ -2965,7 +2977,7 @@ slapi_set_plugin_default_config(const char *type, Slapi_Value *value)
/* cn=plugin default config,cn=config */
pblock_init(&pb);
slapi_search_internal_set_pb(&pb,
- SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */
+ SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN (normalized) */
LDAP_SCOPE_BASE,
"(objectclass=*)",
search_attrs, /* Attrs */
@@ -3069,7 +3081,7 @@ slapi_get_plugin_default_config(char *type, Slapi_ValueSet **valueset)
/* cn=plugin default config,cn=config */
pblock_init(&pb);
slapi_search_internal_set_pb(&pb,
- SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */
+ SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN (normalized) */
LDAP_SCOPE_BASE,
"(objectclass=*)",
search_attrs, /* Attrs */
diff --git a/ldap/servers/slapd/plugin_syntax.c b/ldap/servers/slapd/plugin_syntax.c
index 384692d..5018326 100644
--- a/ldap/servers/slapd/plugin_syntax.c
+++ b/ldap/servers/slapd/plugin_syntax.c
@@ -334,7 +334,7 @@ slapi_dn_syntax_check(
}
/* See if we need to set the error text in the pblock. */
- if (errp != &errtext[0]) {
+ if (pb && errp != &errtext[0]) {
/* SLAPI_PB_RESULT_TEXT duplicates the text in slapi_pblock_set */
slapi_pblock_set( pb, SLAPI_PB_RESULT_TEXT, errtext );
}
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
index fc3000c..2909a17 100644
--- a/ldap/servers/slapd/search.c
+++ b/ldap/servers/slapd/search.c
@@ -68,6 +68,7 @@ do_search( Slapi_PBlock *pb )
BerElement *ber;
int i, err, attrsonly;
ber_int_t scope, deref, sizelimit, timelimit;
+ char *rawbase = NULL;
char *base = NULL, *fstr = NULL;
struct slapi_filter *filter = NULL;
char **attrs = NULL;
@@ -80,6 +81,8 @@ do_search( Slapi_PBlock *pb )
int rc = -1;
char *original_base = 0;
char *new_base = 0;
+ size_t baselen = 0;
+ int strict = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_search\n", 0, 0, 0 );
@@ -114,13 +117,41 @@ do_search( Slapi_PBlock *pb )
*/
/* baseObject, scope, derefAliases, sizelimit, timelimit, attrsOnly */
- if ( ber_scanf( ber, "{aiiiib", &base, &scope, &deref, &sizelimit, &timelimit, &attrsonly ) == LBER_ERROR ){
- slapi_ch_free((void**)&base );
+ if ( ber_scanf( ber, "{aiiiib", &rawbase, &scope, &deref, &sizelimit, &timelimit, &attrsonly ) == LBER_ERROR ){
+ slapi_ch_free((void**)&rawbase );
log_search_access (pb, "???", -1, "???", "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL );
return;
}
+ /* Check if we should be performing strict validation. */
+ strict = config_get_dn_validate_strict();
+ if (strict) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawbase, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "SRCH",
+ rawbase?rawbase:"", "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawbase);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawbase, 0, &base, &baselen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "SRCH",
+ rawbase?rawbase:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawbase);
+ return;
+ } else if (rc > 0) { /* if rc == 0, rawbase is passed in */
+ slapi_ch_free((void **) &rawbase);
+ } else { /* rc == 0; rawbase is passed in; not null terminated */
+ *(base + baselen) = '\0';
+ }
+
/*
* ignore negative time and size limits since they make no sense
*/
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 140158a..aa5a88b 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -575,9 +575,9 @@ typedef int (*SyntaxEnumFunc)(char **names, Slapi_PluginDesc *plugindesc,
struct slapi_dn
{
unsigned char flag;
- const char *dn; /* DN */
+ const char *dn; /* DN [normalized] */
const char *ndn; /* Case Normalised DN */
- int ndn_len; /* normalize dn len */
+ int ndn_len; /* normalized dn length */
};
/*
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index f7683b5..2922a52 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -3025,28 +3025,74 @@ int slapi_rdn_partial_dup(Slapi_RDN *from, Slapi_RDN **to, int idx);
* utility routines for dealing with DNs
*/
/**
- * Normalizes a DN.
+ * Does nothing. (DEPRECATED)
*
* \param dn The DN to normalize.
* \return The normalized DN.
- * \deprecated Use slapi_sdn_get_ndn() instead.
+ * \deprecated Use slapi_dn_normalized_ext.
*/
char *slapi_dn_normalize( char *dn );
/**
- * Normalizes a portion of a DN value.
+ * Does nothing. (DEPRECATED)
*
* \param dn The DN value to normalize.
* \param end Pointer to the end of what will be normalized from the DN
* value in \c dn. If this parameter is \c NULL, the DN value
* will be wholly normalized.
- * \return A pointer to the end of the DN that has been normalized.
- * \warning This function does not null-terminate the string. Use this
- * function only if you know what you are doing.
+ * \return The normalized DN.
+ * \deprecated Use slapi_dn_normalized_ext.
*/
char *slapi_dn_normalize_to_end( char *dn, char *end );
/**
+ * Normalizes a DN.
+ *
+ * \param src The DN to normalize.
+ * \param src_len The length of src DN to normalize. If 0 is given, strlen(src) is used.
+ * \param dest The normalized DN.
+ * \param dest The length of the normalized DN dest.
+ * \return \c 0 if successful. The dest DN is normalized in line. Caller must not free dest.
+ * \return \c 1 if successful. The dest DN is allocated. Caller must free dest.
+ * \return \c -1 if an error occurs (for example, if the src DN cannot be normalized)
+ */
+int slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len);
+
+/**
+ * Normalizes a DN (in lower-case characters).
+ *
+ * \param src The DN to normalize.
+ * \param src_len The length of src DN to normalize. If 0 is given, strlen(src) is used internally.
+ * \param dest The normalized DN with the cases lowered.
+ * \param dest_len The length of the normalized DN dest.
+ * \return \c 0 if successful. The dest DN is normalized in line. Caller must not free dest. The string is NOT NULL terminated.
+ * \return \c 1 if successful. The dest DN is allocated. Caller must free dest.
+ * \return \c -1 if an error occurs (for example, if src DN cannot be normalized)
+ */
+int slapi_dn_normalize_case_ext(char *src, size_t src_len, char **dest, size_t *dest_len);
+
+/**
+ * Generate a valid DN string.
+ *
+ * \param fmt The format used to generate a DN string.
+ * \param ... The arguments to generate a DN string.
+ * \return A pointer to the generated DN. The
+ * \return NULL if failed.
+ * \note When a DN needs to be internally created, this function is supposed to be called. This function allocates the enough memory for the normalized DN and returns it filled with the normalized DN.
+ */
+char *slapi_create_dn_string(const char *fmt, ...);
+
+/**
+ * Generates a valid DN string (in lower-case characters).
+ *
+ * \param fmt The format used to generate a DN string.
+ * \param ... The arguments to generate a DN string.
+ * \return A pointer to the generated DN.
+ * \return NULL if failed.
+ */
+char *slapi_create_dn_string_case(const char *fmt, ...);
+
+/**
* Converts a DN to lowercase.
*
* \param dn The DN to convert.
@@ -3332,6 +3378,15 @@ int slapi_attr_get_oid_copy( const Slapi_Attr *attr, char **oidp );
int slapi_attr_get_syntax_oid_copy( const Slapi_Attr *a, char **oidp );
/**
+ * Checks if the attribute uses a DN syntax or not.
+ *
+ * \param attr The attribute to be checked.
+ * \return \c non 0 if the attribute uses a DN syntax.
+ * \return \c 0 if the attribute does not use a DN syntax.
+ */
+int slapi_attr_is_dn_syntax_attr(Slapi_Attr *attr);
+
+/**
* Get the flags associated with a particular attribute.
*
* Valid flags are:
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 84c3eb1..382cded 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -364,6 +364,7 @@ const CSN *value_get_csn( const Slapi_Value *value, CSNType t );
const CSNSet *value_get_csnset ( const Slapi_Value *value);
Slapi_Value *value_remove_csn( Slapi_Value *value, CSNType t);
int value_contains_csn( const Slapi_Value *value, CSN *csn);
+int value_normalize_value(Slapi_Value *value);
/* dn.c */
/* this functions should only be used for dns allocated on the stack */
@@ -820,6 +821,7 @@ void valuearray_add_value_fast(Slapi_Value ***vals, Slapi_Value *addval, int nva
void valuearray_add_valuearray( Slapi_Value ***vals, Slapi_Value **addvals, PRUint32 flags );
void valuearray_add_valuearray_fast( Slapi_Value ***vals, Slapi_Value **addvals, int nvals, int naddvals, int *maxvals, int exact, int passin );
int valuearray_find(const Slapi_Attr *a, Slapi_Value **va, const Slapi_Value *v);
+int valuearray_normalize_value(Slapi_Value **vals);
/******************************************************************************
diff --git a/ldap/servers/slapd/snmp_collator.c b/ldap/servers/slapd/snmp_collator.c
index 9beb878..9c485de 100644
--- a/ldap/servers/slapd/snmp_collator.c
+++ b/ldap/servers/slapd/snmp_collator.c
@@ -873,7 +873,8 @@ loadConfigStats() {
static Slapi_Entry *
getConfigEntry( Slapi_Entry **e ) {
Slapi_DN sdn;
-
+
+ /* SNMP_CONFIG_DN: no need to be normalized */
slapi_sdn_init_dn_byref( &sdn, SNMP_CONFIG_DN );
slapi_search_internal_get_entry( &sdn, NULL, e,
plugin_get_default_component_id());
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 733618f..a7fe789 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -60,13 +60,13 @@ static int shutting_down = 0;
/***********************************
* Private Defines
***********************************/
-#define TASK_BASE_DN "cn=tasks, cn=config"
-#define TASK_IMPORT_DN "cn=import, cn=tasks, cn=config"
-#define TASK_EXPORT_DN "cn=export, cn=tasks, cn=config"
-#define TASK_BACKUP_DN "cn=backup, cn=tasks, cn=config"
-#define TASK_RESTORE_DN "cn=restore, cn=tasks, cn=config"
-#define TASK_INDEX_DN "cn=index, cn=tasks, cn=config"
-#define TASK_UPGRADEDB_DN "cn=upgradedb, cn=tasks, cn=config"
+#define TASK_BASE_DN "cn=tasks,cn=config"
+#define TASK_IMPORT_DN "cn=import,cn=tasks,cn=config"
+#define TASK_EXPORT_DN "cn=export,cn=tasks,cn=config"
+#define TASK_BACKUP_DN "cn=backup,cn=tasks,cn=config"
+#define TASK_RESTORE_DN "cn=restore,cn=tasks,cn=config"
+#define TASK_INDEX_DN "cn=index,cn=tasks,cn=config"
+#define TASK_UPGRADEDB_DN "cn=upgradedb,cn=tasks,cn=config"
#define TASK_LOG_NAME "nsTaskLog"
#define TASK_STATUS_NAME "nsTaskStatus"
@@ -403,9 +403,12 @@ int slapi_task_register_handler(const char *name, dseCallbackFn func)
int ret = -1;
int x;
- dn = slapi_ch_smprintf("cn=%s, %s", name, TASK_BASE_DN);
- if (dn == NULL) {
- goto out;
+ dn = slapi_create_dn_string("cn=%s,%s", name, TASK_BASE_DN);
+ if (NULL == dn) {
+ LDAPDebug1Arg( LDAP_DEBUG_ANY,
+ "slapi_task_register_handler: "
+ "failed to create task dn for %s\n", name);
+ return ret;
}
pb = slapi_pblock_new();
@@ -458,9 +461,7 @@ int slapi_task_register_handler(const char *name, dseCallbackFn func)
ret = 0;
out:
- if (dn) {
- slapi_ch_free((void **)&dn);
- }
+ slapi_ch_free_string(&dn);
if (pb) {
slapi_pblock_destroy(pb);
}
@@ -487,18 +488,27 @@ void slapi_task_set_cancel_fn(Slapi_Task *task, TaskCallbackFn func)
***********************************/
/* create a new task, fill in DN, and setup modify callback */
static Slapi_Task *
-new_task(const char *dn)
+new_task(const char *rawdn)
{
- Slapi_Task *task = (Slapi_Task *)slapi_ch_calloc(1, sizeof(Slapi_Task));
+ Slapi_Task *task = NULL;
+ char *dn = NULL;
+
+ if (rawdn == NULL) {
+ return NULL;
+ }
- if (task == NULL)
+ dn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "new_task failed: invalid task dn: %s\n", rawdn);
return NULL;
+ }
+ task = (Slapi_Task *)slapi_ch_calloc(1, sizeof(Slapi_Task));
PR_Lock(global_task_lock);
task->next = global_task_list;
global_task_list = task;
PR_Unlock(global_task_lock);
-
- task->task_dn = slapi_ch_strdup(dn);
+ task->task_dn = dn;
task->task_state = SLAPI_TASK_SETUP;
task->task_flags = SLAPI_TASK_RUNNING_AS_TASK;
task->destructor = NULL;
@@ -511,8 +521,8 @@ new_task(const char *dn)
/* don't add entries under this one */
#if 0
/* don't know why, but this doesn't work. it makes the current add
- * * operation fail. :(
- * */
+ * operation fail. :(
+ */
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=*)", task_deny, NULL);
#endif
diff --git a/ldap/servers/slapd/tools/dbscan.c b/ldap/servers/slapd/tools/dbscan.c
index ad22b42..320f5ed 100644
--- a/ldap/servers/slapd/tools/dbscan.c
+++ b/ldap/servers/slapd/tools/dbscan.c
@@ -434,7 +434,7 @@ static ID id_stored_to_internal(char* b)
static void id_internal_to_stored(ID i,char *b)
{
if ( sizeof(ID) > 4 ) {
- memset (b+4, 0, sizeof(ID)-4);
+ (void)memset (b+4, 0, sizeof(ID)-4);
}
b[0] = (char)(i >> 24);
diff --git a/ldap/servers/slapd/tools/ldclt/ldclt.h b/ldap/servers/slapd/tools/ldclt/ldclt.h
index c8ead2c..48c398b 100644
--- a/ldap/servers/slapd/tools/ldclt/ldclt.h
+++ b/ldap/servers/slapd/tools/ldclt/ldclt.h
@@ -741,6 +741,7 @@ extern char *dnFromMessage (thread_context *tttctx, LDAPMessage *res);
extern int doAddEntry (thread_context *tttctx);
extern int doAttrReplace (thread_context *tttctx); /*JLS 21-11-00*/
extern int doAttrFileReplace (thread_context *tttctx);
+
extern int doBindOnly (thread_context *tttctx); /*JLS 04-05-01*/
extern int doDeleteEntry (thread_context *tttctx);
extern int doExactSearch (thread_context *tttctx);
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
index d26b0b9..8987e63 100644
--- a/ldap/servers/slapd/util.c
+++ b/ldap/servers/slapd/util.c
@@ -335,8 +335,9 @@ int slapi_entry2mods (const Slapi_Entry *e, char **dn, LDAPMod ***attrs)
*
* normalize_mods2bvals
*
-*
-*
+* Return value: normalized mods
+* The values/bvals are all duplicated in this function since
+* the normalized mods are freed with ldap_mods_free by the caller.
*
*******************************************************************************/
@@ -360,6 +361,18 @@ normalize_mods2bvals(const LDAPMod **mods)
for (w = 0; mods[w] != NULL; w++)
{
+ Slapi_Attr a = {0};
+ slapi_attr_init(&a, mods[w]->mod_type);
+ int is_dn_syntax = 0;
+ struct berval **normmbvp = NULL;
+
+ /* Check if the type of the to-be-added values has DN syntax
+ * or not. */
+ if (slapi_attr_is_dn_syntax_attr(&a)) {
+ is_dn_syntax = 1;
+ }
+ attr_done(&a);
+
/* copy each mod into a normalized modbvalue */
normalized_mods[w] = (LDAPMod *) slapi_ch_calloc(1, sizeof(LDAPMod));
normalized_mods[w]->mod_op = mods[w]->mod_op | LDAP_MOD_BVALUES;
@@ -397,32 +410,79 @@ normalize_mods2bvals(const LDAPMod **mods)
if (mods[w]->mod_op & LDAP_MOD_BVALUES)
{
- for (x = 0; mods[w]->mod_bvalues != NULL &&
- mods[w]->mod_bvalues[x] != NULL; x++)
+ struct berval **mbvp = NULL;
+
+ for (mbvp = mods[w]->mod_bvalues,
+ normmbvp = normalized_mods[w]->mod_bvalues;
+ mbvp && *mbvp; mbvp++, normmbvp++)
{
- normalized_mods[w]->mod_bvalues[x] = ber_bvdup(mods[w]->mod_bvalues[x]);
+ if (is_dn_syntax) {
+ int rc = 0;
+ char *normed = NULL;
+ size_t dnlen = 0;
+
+ rc = slapi_dn_normalize_ext((*mbvp)->bv_val,
+ (*mbvp)->bv_len,
+ &normed, &dnlen);
+ if (rc < 0) { /* normalization failed; use the original */
+ *normmbvp = ber_bvdup(*mbvp);
+ } else if (rc == 0) { /* if rc == 0, value is passed in */
+ *(normed + dnlen) = '\0';
+ *normmbvp = ber_bvdup(*mbvp);
+ } else {
+ (*normmbvp)->bv_val = normed;
+ (*normmbvp)->bv_len = dnlen;
+ }
+ } else {
+ *normmbvp = ber_bvdup(*mbvp);
+ }
}
} else {
- for (x = 0; mods[w]->mod_values != NULL &&
- mods[w]->mod_values[x] != NULL; x++)
+ char **mvp = NULL;
+
+ for (mvp = mods[w]->mod_values,
+ normmbvp = normalized_mods[w]->mod_bvalues;
+ mvp && *mvp; mvp++, normmbvp++)
{
- normalized_mods[w]->mod_bvalues[ x ] = (struct berval *)
- slapi_ch_calloc(1, sizeof(struct berval));
-
- vlen = strlen(mods[w]->mod_values[x]);
- normalized_mods[w]->mod_bvalues[ x ]->bv_val =
- slapi_ch_calloc(vlen + 1, sizeof(char));
- memcpy(normalized_mods[w]->mod_bvalues[ x ]->bv_val,
- mods[w]->mod_values[x], vlen);
- normalized_mods[w]->mod_bvalues[ x ]->bv_val[vlen] = '\0';
- normalized_mods[w]->mod_bvalues[ x ]->bv_len = vlen;
+ *normmbvp =
+ (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+
+ vlen = strlen(*mvp);
+
+ if (is_dn_syntax) {
+ int rc = 0;
+ char *normed = NULL;
+ size_t dnlen = 0;
+ rc = slapi_dn_normalize_ext(*mvp, vlen,
+ &normed, &dnlen);
+ if (rc < 0) { /* normalization failed; use the original */
+ (*normmbvp)->bv_val = slapi_ch_malloc(vlen + 1);
+ memcpy((*normmbvp)->bv_val, *mvp, vlen);
+ (*normmbvp)->bv_val[vlen] = '\0';
+ (*normmbvp)->bv_len = vlen;
+ } else if (rc == 0) { /* if rc == 0, value is passed in */
+ *(normed + dnlen) = '\0';
+ (*normmbvp)->bv_val = slapi_ch_strdup(normed);
+ (*normmbvp)->bv_len = dnlen;
+ } else {
+ (*normmbvp)->bv_val = normed;
+ (*normmbvp)->bv_len = dnlen;
+ }
+ } else {
+ (*normmbvp)->bv_val = slapi_ch_malloc(vlen + 1);
+ memcpy((*normmbvp)->bv_val, *mvp, vlen);
+ (*normmbvp)->bv_val[vlen] = '\0';
+ (*normmbvp)->bv_len = vlen;
+ }
}
}
+ PR_ASSERT(normmbvp - normalized_mods[w]->mod_bvalues <= num_values);
+
/* don't forget to null terminate it */
- if (num_values > 0)
+ if (num_values > 0)
{
- normalized_mods[w]->mod_bvalues[ x ] = NULL;
+ *normmbvp = NULL;
}
}
diff --git a/ldap/servers/slapd/value.c b/ldap/servers/slapd/value.c
index 72f94b9..c0cf66e 100644
--- a/ldap/servers/slapd/value.c
+++ b/ldap/servers/slapd/value.c
@@ -551,3 +551,29 @@ value_dump( const Slapi_Value *value, const char *text)
}
#endif
+int
+value_normalize_value(Slapi_Value *value)
+{
+ char *normval = NULL;
+ size_t len = 0;
+ int rc = 0;
+
+ if (NULL == value) {
+ return 0;
+ }
+
+ rc = slapi_dn_normalize_ext(value->bv.bv_val, value->bv.bv_len,
+ &normval, &len);
+ if (rc < 0) {
+ return 1;
+ } else if (rc > 0) { /* if rc == 0, the original value is passed in */
+ slapi_ch_free_string(&value->bv.bv_val);
+ } else { /* rc == 0; original is passed in; not null terminated */
+ /* since bvalue, no need to terminate with null, tho */
+ *(normval + len) = '\0';
+ }
+ value->bv.bv_val = normval;
+ value->bv.bv_len = len;
+
+ return 0;
+}
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
index d6909ac..22ffb4a 100644
--- a/ldap/servers/slapd/valueset.c
+++ b/ldap/servers/slapd/valueset.c
@@ -1437,3 +1437,17 @@ valueset_update_csn_for_valuearray(Slapi_ValueSet *vs, const Slapi_Attr *a, Slap
*valuesupdated= vaf_valuesupdated.va;
}
}
+
+int
+valuearray_normalize_value(Slapi_Value **vals)
+{
+ int rc = 0;
+ Slapi_Value **vp = NULL;
+
+ for (vp = vals; vp && *vp; vp++) {
+ rc |= value_normalize_value(*vp);
+ }
+
+ return rc;
+}
+
13 years, 11 months
Branch 'Directory_Server_8_2_Branch' - ldap/admin ldap/schema ldap/servers
by Noriko Hosoi
ldap/admin/src/scripts/Migration.pm.in | 2
ldap/admin/src/scripts/Setup.pm.in | 2
ldap/schema/01common.ldif | 3
ldap/schema/30ns-common.ldif | 9
ldap/servers/plugins/acl/acl.c | 56 -
ldap/servers/plugins/acl/acl.h | 7
ldap/servers/plugins/acl/acl_ext.c | 6
ldap/servers/plugins/acl/aclanom.c | 3
ldap/servers/plugins/acl/acleffectiverights.c | 47
ldap/servers/plugins/acl/acllas.c | 202 +++
ldap/servers/plugins/acl/aclparse.c | 386 ++++---
ldap/servers/plugins/acl/aclproxy.c | 17
ldap/servers/plugins/acl/aclutil.c | 66 +
ldap/servers/plugins/chainingdb/cb_config.c | 10
ldap/servers/plugins/chainingdb/cb_init.c | 4
ldap/servers/plugins/chainingdb/cb_instance.c | 8
ldap/servers/plugins/cos/cos_cache.c | 127 ++
ldap/servers/plugins/dna/dna.c | 57 -
ldap/servers/plugins/pwdstorage/smd5_pwd.c | 7
ldap/servers/plugins/replication/legacy_consumer.c | 1
ldap/servers/plugins/replication/repl5.h | 2
ldap/servers/plugins/replication/repl5_agmt.c | 19
ldap/servers/plugins/replication/repl5_agmtlist.c | 3
ldap/servers/plugins/replication/repl5_protocol.c | 1
ldap/servers/plugins/replication/repl5_replica.c | 27
ldap/servers/plugins/replication/repl5_replica_config.c | 1
ldap/servers/plugins/replication/repl_init.c | 1
ldap/servers/plugins/retrocl/retrocl.c | 1
ldap/servers/plugins/retrocl/retrocl.h | 2
ldap/servers/plugins/retrocl/retrocl_create.c | 3
ldap/servers/plugins/syntaxes/string.c | 166 ++-
ldap/servers/plugins/syntaxes/syntax.h | 1
ldap/servers/plugins/syntaxes/validate.c | 12
ldap/servers/plugins/syntaxes/value.c | 90 +
ldap/servers/plugins/usn/usn_cleanup.c | 11
ldap/servers/slapd/add.c | 53 -
ldap/servers/slapd/attrlist.c | 6
ldap/servers/slapd/attrsyntax.c | 17
ldap/servers/slapd/auth.c | 50
ldap/servers/slapd/back-ldbm/cache.c | 4
ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c | 48
ldap/servers/slapd/back-ldbm/ldbm_config.c | 86 +
ldap/servers/slapd/back-ldbm/ldbm_index_config.c | 50
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c | 167 ++-
ldap/servers/slapd/back-ldbm/ldbm_search.c | 1
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 1
ldap/servers/slapd/back-ldbm/misc.c | 2
ldap/servers/slapd/back-ldbm/nextid.c | 2
ldap/servers/slapd/back-ldbm/vlv.c | 78 +
ldap/servers/slapd/backend.c | 28
ldap/servers/slapd/backend_manager.c | 6
ldap/servers/slapd/bind.c | 34
ldap/servers/slapd/compare.c | 31
ldap/servers/slapd/delete.c | 31
ldap/servers/slapd/dn.c | 829 ++++++++++++++--
ldap/servers/slapd/entry.c | 175 ++-
ldap/servers/slapd/entrywsi.c | 9
ldap/servers/slapd/extendop.c | 37
ldap/servers/slapd/fedse.c | 1
ldap/servers/slapd/libglobs.c | 7
ldap/servers/slapd/main.c | 4
ldap/servers/slapd/mapping_tree.c | 89 +
ldap/servers/slapd/modify.c | 35
ldap/servers/slapd/modrdn.c | 112 +-
ldap/servers/slapd/modutil.c | 30
ldap/servers/slapd/passwd_extop.c | 35
ldap/servers/slapd/plugin.c | 28
ldap/servers/slapd/plugin_syntax.c | 2
ldap/servers/slapd/pw.c | 1
ldap/servers/slapd/search.c | 33
ldap/servers/slapd/slap.h | 4
ldap/servers/slapd/slapi-plugin.h | 67 +
ldap/servers/slapd/slapi-private.h | 2
ldap/servers/slapd/snmp_collator.c | 3
ldap/servers/slapd/task.c | 50
ldap/servers/slapd/tools/dbscan.c | 2
ldap/servers/slapd/tools/ldclt/ldclt.h | 2
ldap/servers/slapd/util.c | 98 +
ldap/servers/slapd/value.c | 26
ldap/servers/slapd/valueset.c | 14
80 files changed, 2952 insertions(+), 798 deletions(-)
New commits:
commit 7fd0ad8923a6789650911bb7752deda324afde4c
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Mon Apr 26 11:02:12 2010 -0700
Update to New DN Format
Fix Description:
. adding slapi_dn_normalize_ext and its siblings to normalize/validate
invalid DNs; deprecating slapi_dn_normalize and its siblings. (dn.c)
. replacing slapi_dn_normalize with new corresponding functions.
. normalizing hardcoded DNs (e.g., removing spaces around ',')
. setting correct DN syntax to nsslapd-suffix, nsslapd-ldapiautodnsuffix,
costemplatedn, nsslapd-changelogsuffix, nsBaseDN, nsBindDN
. if nsslapd-dn-validate-strict is enabled, incoming DN is examined and
rejected if it is invalid. Once approved, the DN is normalized.
. fixing compiler warnings and typos.
See also:
http://directory.fedoraproject.org/wiki/Upgrade_to_New_DN_Format
Related bugs:
Bug 199923 - subtree search fails to find items under a db containing special
characters
Bug 567968 - subtree/user level password policy created using 389-ds-console
doesn't work.
Bug 570107 - The import of LDIFs with base-64 encoded DNs fails, modrdn with
non-ASCII new rdn incorrect
Bug 570962 - ns-inactivate.pl does not work
Bug 572785 - DN syntax: old style of DN <type>="<DN>",<the_rest> is not
correctly normalized
Bug 573060 - DN normalizer: ESC HEX HEX is not normalized
Bug 574167 - An escaped space at the end of the RDN value is not handled
correctly
diff --git a/ldap/admin/src/scripts/Migration.pm.in b/ldap/admin/src/scripts/Migration.pm.in
index 44613a8..1942c8b 100644
--- a/ldap/admin/src/scripts/Migration.pm.in
+++ b/ldap/admin/src/scripts/Migration.pm.in
@@ -125,7 +125,7 @@ You can supply default .inf data in this format:
e.g.
General.FullMachineName=foo.example.com
or
- "slapd.Suffix=dc=example, dc=com"
+ "slapd.Suffix=dc=example,dc=com"
Values passed in this manner will override values in an .inf file
given with the -f argument.
diff --git a/ldap/admin/src/scripts/Setup.pm.in b/ldap/admin/src/scripts/Setup.pm.in
index 021a99c..52300db 100644
--- a/ldap/admin/src/scripts/Setup.pm.in
+++ b/ldap/admin/src/scripts/Setup.pm.in
@@ -110,7 +110,7 @@ You can supply default .inf data in this format:
e.g.
General.FullMachineName=foo.example.com
or
- "slapd.Suffix=dc=example, dc=com"
+ "slapd.Suffix=dc=example,dc=com"
Values passed in this manner will override values in an .inf file given with the -f argument.
EOF
}
diff --git a/ldap/schema/01common.ldif b/ldap/schema/01common.ldif
index 01e0727..e6779e1 100644
--- a/ldap/schema/01common.ldif
+++ b/ldap/schema/01common.ldif
@@ -188,7 +188,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.241 NAME 'displayName' DESC 'inetOrgPers
attributeTypes: ( 2.16.840.1.113730.3.1.550 NAME 'cosAttribute' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.551 NAME 'cosspecifier' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.552 NAME 'costargettree' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
-attributeTypes: ( 2.16.840.1.113730.3.1.553 NAME 'costemplatedn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.553 NAME 'costemplatedn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.35 NAME 'changeLog' DESC 'the distinguished name of the entry which contains the set of entries comprising this servers changelog' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Changelog Internet Draft' )
attributeTypes: ( 2.16.840.1.113730.3.1.200 NAME 'changeLogMaximumAge' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.201 NAME 'changeLogMaximumSize' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape Directory Server' )
@@ -226,6 +226,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2063 NAME 'nsEncryptionAlgorithm' DESC '
attributeTypes: ( 2.16.840.1.113730.3.1.2064 NAME 'nsSaslMapRegexString' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2065 NAME 'nsSaslMapBaseDNTemplate' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2066 NAME 'nsSaslMapFilterTemplate' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2093 NAME 'nsslapd-changelogsuffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
#
# objectclasses:
#
diff --git a/ldap/schema/30ns-common.ldif b/ldap/schema/30ns-common.ldif
index ea48c66..01bd7d8 100644
--- a/ldap/schema/30ns-common.ldif
+++ b/ldap/schema/30ns-common.ldif
@@ -42,8 +42,8 @@
#
dn: cn=schema
attributeTypes: ( nsServerID-oid NAME 'nsServerID' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
-attributeTypes: ( nsBaseDN-oid NAME 'nsBaseDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
-attributeTypes: ( nsBindDN-oid NAME 'nsBindDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
+attributeTypes: ( nsBaseDN-oid NAME 'nsBaseDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
+attributeTypes: ( nsBindDN-oid NAME 'nsBindDN' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
attributeTypes: ( nsBindPassword-oid NAME 'nsBindPassword' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsServerPort-oid NAME 'nsServerPort' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsServerAddress-oid NAME 'nsServerAddress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
@@ -95,6 +95,11 @@ attributeTypes: ( nsExecRef-oid NAME 'nsExecRef' DESC 'Netscape defined attribut
attributeTypes: ( nsLogSuppress-oid NAME 'nsLogSuppress' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsJarfilename-oid NAME 'nsJarfilename' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsClassname-oid NAME 'nsClassname' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2091 NAME 'nsslapd-suffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2092 NAME 'nsslapd-ldapiautodnsuffix' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape' )
+ #
+ # objectclasses
+ #
objectClasses: ( nsAdminDomain-oid NAME 'nsAdminDomain' DESC 'Netscape defined objectclass' SUP organizationalUnit MAY ( nsAdminDomainName ) X-ORIGIN 'Netscape' )
objectClasses: ( nsHost-oid NAME 'nsHost' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( serverHostName $ description $ l $ nsHostLocation $ nsHardwarePlatform $ nsOsVersion ) X-ORIGIN 'Netscape' )
objectClasses: ( nsAdminGroup-oid NAME 'nsAdminGroup' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsAdminGroupName $ description $ nsConfigRoot $ nsAdminSIEDN ) X-ORIGIN 'Netscape' )
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index df2f4e4..8b0e7fa 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -355,8 +355,8 @@ acl_access_allowed(
if (oid && ((strcasecmp(oid, DN_SYNTAX_OID) == 0) ||
(strcasecmp(oid, NAMEANDOPTIONALUID_SYNTAX_OID) == 0))) {
/* should use slapi_sdn_compare() but that'a an extra malloc/free */
- char *dn_val_to_write = slapi_dn_normalize(slapi_ch_strdup(val->bv_val));
- if ( aclpb->aclpb_authorization_sdn &&
+ char *dn_val_to_write = slapi_create_dn_string("%s", val->bv_val);
+ if ( dn_val_to_write && aclpb->aclpb_authorization_sdn &&
slapi_utf8casecmp((ACLUCHP)dn_val_to_write, (ACLUCHP)
slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn)) == 0) {
access |= SLAPI_ACL_SELF;
@@ -751,9 +751,10 @@ static void print_access_control_summary( char *source, int ret_val, char *clien
if ( aclpb->aclpb_authorization_sdn != NULL ) {
- proxy_user = (char *)(aclpb->aclpb_authorization_sdn->ndn ?
- aclpb->aclpb_authorization_sdn->ndn:
- null_user);
+ proxy_user =
+ (char *)(slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn)?
+ slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn):
+ null_user);
slapi_log_error(loglevel, plugin_name,
"conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)"
@@ -1761,8 +1762,7 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
if (parent_DN == NULL) {
new_DN = new_RDN;
} else {
- new_DN = slapi_ch_smprintf("%s,%s", new_RDN, parent_DN);
- slapi_dn_normalize (new_DN);
+ new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
}
/* Change the acls */
@@ -2025,8 +2025,7 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
** We have a single ACI which we need to find if it applies to
** the resource or not.
*/
- if ((aci->aci_type & ACI_TARGET_DN) &&
- (aclpb->aclpb_curr_entry_sdn)) {
+ if ((aci->aci_type & ACI_TARGET_DN) && (aclpb->aclpb_curr_entry_sdn)) {
char *avaType;
struct berval *avaValue;
@@ -2243,10 +2242,10 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
*
*/
- if ((aclpb->aclpb_access & SLAPI_ACL_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS )||
- (aclpb->aclpb_access & SLAPI_ACL_DELETE &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS ) ) {
+ if (((aclpb->aclpb_access & SLAPI_ACL_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) )||
+ ((aclpb->aclpb_access & SLAPI_ACL_DELETE) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS) ) ) {
Targetattrfilter **attrFilterArray;
@@ -2364,10 +2363,10 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
goto acl__resource_match_aci_EXIT;
}
- } else if ( (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) ||
- (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS ) ) {
+ } else if ( ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) ||
+ ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)) ) {
/*
@@ -2378,28 +2377,28 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
* match that filter.
*
*
- */
+ */
Targetattrfilter **attrFilterArray = NULL;
Targetattrfilter *attrFilter;
int found = 0;
- if (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD &&
- aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS) {
+ if ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_ADD) &&
+ (aci->aci_type & ACI_TARGET_ATTR_ADD_FILTERS)) {
- attrFilterArray = aci->targetAttrAddFilters;
+ attrFilterArray = aci->targetAttrAddFilters;
- } else if (aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL &&
- aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS) {
+ } else if ((aclpb->aclpb_access & ACLPB_SLAPI_ACL_WRITE_DEL) &&
+ (aci->aci_type & ACI_TARGET_ATTR_DEL_FILTERS)) {
- attrFilterArray = aci->targetAttrDelFilters;
+ attrFilterArray = aci->targetAttrDelFilters;
}
/*
* Scan this filter list for an applicable filter.
- */
+ */
found = 0;
num_attrs = 0;
@@ -2432,7 +2431,7 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
attr_matched= acl__test_filter(aclpb->aclpb_filter_test_entry,
attrFilter->filter,
1 /* Do filter sense evaluation below */
- );
+ );
slapi_entry_free( aclpb->aclpb_filter_test_entry );
}
@@ -2449,8 +2448,6 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
*/
attr_matched_in_targetattrfilters = 1;
-
-
}
} /* targetvaluefilters */
@@ -3230,9 +3227,6 @@ acl_match_substring ( Slapi_Filter *f, char *str, int exact_match)
realval = tmp;
}
- slapi_dn_normalize (realval);
-
-
/* What we have built is a regular pattaren expression.
** Now we will compile the pattern and compare wth the string to
** see if the input string matches with the patteren or not.
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index d8bc507..cbfde48 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -119,7 +119,11 @@ static char* const aci_targetattr = "targetattr";
static char* const aci_targetattrfilters = "targattrfilters";
static char* const aci_targetfilter = "targetfilter";
+static char* const LDAP_URL_prefix_core = "ldap://";
+static char* const LDAPS_URL_prefix_core = "ldaps://";
+
static char* const LDAP_URL_prefix = "ldap:///";
+static char* const LDAPS_URL_prefix = "ldaps:///";
static char* const access_str_compare = "compare";
static char* const access_str_search = "search";
@@ -827,7 +831,7 @@ int acl_skip_access_check ( Slapi_PBlock *pb, Slapi_Entry *e );
int aclext_alloc_lockarray ();
-int aclutil_str_appened(char **str1, const char *str2);
+int aclutil_str_append(char **str1, const char *str2);
void aclutil_print_err (int rv , const Slapi_DN *sdn,
const struct berval* val, char **errbuf);
void aclutil_print_aci (aci_t *aci_item, char *type);
@@ -911,6 +915,7 @@ acl_replace_str(char * s, char *substr, char* replace_with);
int acl_strstr(char * s, char *substr);
int aclutil_evaluate_macro( char * rule, lasInfo *lasinfo,
acl_eval_types evalType );
+int aclutil_str_append_ext(char **dest, size_t *dlen, const char *src, size_t slen);
/* acl hash table functions */
void acl_ht_add_and_freeOld(acl_ht_t * acl_ht, PLHashNumber key,char *value);
diff --git a/ldap/servers/plugins/acl/acl_ext.c b/ldap/servers/plugins/acl/acl_ext.c
index d400c9c..d9494ec 100644
--- a/ldap/servers/plugins/acl/acl_ext.c
+++ b/ldap/servers/plugins/acl/acl_ext.c
@@ -653,7 +653,7 @@ acl_init_aclpb ( Slapi_PBlock *pb , Acl_PBlock *aclpb, const char *dn, int copy_
char *authType;
void *conn;
int op_type;
- int ssf = 0;
+ intptr_t ssf = 0;
if ( NULL == aclpb ) {
@@ -695,7 +695,7 @@ acl_init_aclpb ( Slapi_PBlock *pb , Acl_PBlock *aclpb, const char *dn, int copy_
return;
}
slapi_pblock_get ( pb, SLAPI_OPERATION_SSF, &ssf);
- if (PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_SSF, ssf, 0) < 0) {
+ if (PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_SSF, (const void *)ssf, 0) < 0) {
slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
"Unable to set the SSF in the Plist\n");
return;
@@ -791,7 +791,7 @@ acl__done_aclpb ( struct acl_pblock *aclpb )
*/
/* Nothing needs to be cleaned up in this case */
- if ( !aclpb->aclpb_state & ACLPB_INITIALIZED)
+ if (!(aclpb->aclpb_state & ACLPB_INITIALIZED))
return;
/* Check the state */
diff --git a/ldap/servers/plugins/acl/aclanom.c b/ldap/servers/plugins/acl/aclanom.c
index 773dad2..16b7ad9 100644
--- a/ldap/servers/plugins/acl/aclanom.c
+++ b/ldap/servers/plugins/acl/aclanom.c
@@ -205,7 +205,8 @@ aclanom_gen_anomProfile (acl_lock_flag_t lock_flag)
/* see if this is a monitor acl */
if (( strcasecmp ( dn, "cn=monitor") == 0 ) ||
- ( strcasecmp ( dn, "cn=monitor,cn=ldbm") == 0 )) {
+ ( strncasecmp ( dn, "cn=monitor,cn=ldbm",
+ strlen("cn=monitor,cn=ldbm")) == 0 )) {
aci = acllist_get_next_aci ( NULL, aci, &cookie);
continue;
} else {
diff --git a/ldap/servers/plugins/acl/acleffectiverights.c b/ldap/servers/plugins/acl/acleffectiverights.c
index 9afac07..acf856c 100644
--- a/ldap/servers/plugins/acl/acleffectiverights.c
+++ b/ldap/servers/plugins/acl/acleffectiverights.c
@@ -170,7 +170,7 @@ _ger_g_permission_granted (
goto bailout;
}
- aclutil_str_appened ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
+ aclutil_str_append ( errbuf, "get-effective-rights: requestor has no g permission on the entry" );
slapi_log_error (SLAPI_LOG_ACL, plugin_name,
"_ger_g_permission_granted: %s\n", *errbuf);
rc = LDAP_INSUFFICIENT_ACCESS;
@@ -195,7 +195,10 @@ _ger_parse_control (
LDAPControl **requestcontrols;
struct berval *subjectber;
BerElement *ber;
- int subjectndnlen = 0;
+ size_t subjectndnlen = 0;
+ char *orig = NULL;
+ char *normed = NULL;
+ int rc = 0;
if (NULL == subjectndn)
{
@@ -215,7 +218,7 @@ _ger_parse_control (
if ( subjectber == NULL || subjectber->bv_val == NULL ||
subjectber->bv_len == 0 )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: missing subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: missing subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
return LDAP_INVALID_SYNTAX;
}
@@ -227,23 +230,23 @@ _ger_parse_control (
* or base64 encoding string. Hence users using -J option in
* ldapsearch don't have to do BER encoding for the subject.
*/
- *subjectndn = slapi_ch_malloc ( subjectber->bv_len + 1 );
- strncpy ( *subjectndn, subjectber->bv_val, subjectber->bv_len );
- *(*subjectndn + subjectber->bv_len) = '\0';
+ orig = slapi_ch_malloc ( subjectber->bv_len + 1 );
+ strncpy ( orig, subjectber->bv_val, subjectber->bv_len );
+ *(orig + subjectber->bv_len) = '\0';
}
else
{
ber = ber_init (subjectber);
if ( ber == NULL )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: ber_init failed for the subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: ber_init failed for the subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
return LDAP_OPERATIONS_ERROR;
}
/* "a" means to allocate storage as needed for octet string */
- if ( ber_scanf (ber, "a", subjectndn) == LBER_ERROR )
+ if ( ber_scanf (ber, "a", orig) == LBER_ERROR )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: invalid ber tag in the subject" );
+ aclutil_str_append ( errbuf, "get-effective-rights: invalid ber tag in the subject" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
ber_free ( ber, 1 );
return LDAP_INVALID_SYNTAX;
@@ -256,18 +259,32 @@ _ger_parse_control (
* (see section 9 of RFC 2829) only. It also only supports the "dnAuthzId"
* flavor, which looks like "dn:<DN>" where null <DN> is for anonymous.
*/
- subjectndnlen = strlen(*subjectndn);
- if ( NULL == *subjectndn || subjectndnlen < 3 ||
- strncasecmp ( "dn:", *subjectndn, 3 ) != 0 )
+ subjectndnlen = strlen(orig);
+ if ( NULL == orig || subjectndnlen < 3 || strncasecmp ( "dn:", orig, 3 ) != 0 )
{
- aclutil_str_appened ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
+ aclutil_str_append ( errbuf, "get-effective-rights: subject is not dnAuthzId" );
slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
+ slapi_ch_free_string(&orig);
return LDAP_INVALID_SYNTAX;
}
/* memmove is safe for overlapping copy */
- memmove ( *subjectndn, *subjectndn + 3, subjectndnlen - 2);/* 1 for '\0' */
- slapi_dn_normalize ( *subjectndn );
+ rc = slapi_dn_normalize_ext(orig + 3, 0, &normed, &subjectndnlen);
+ if (rc < 0) {
+ aclutil_str_append ( errbuf, "get-effective-rights: failed to normalize dn: ");
+ aclutil_str_append ( errbuf, orig);
+ slapi_log_error (SLAPI_LOG_FATAL, plugin_name, "%s\n", *errbuf );
+ slapi_ch_free_string(&orig);
+ return LDAP_INVALID_SYNTAX;
+ }
+ if (rc == 0) { /* orig+3 is passed in; not terminated */
+ *(normed + subjectndnlen) = '\0';
+ *subjectndn = slapi_ch_strdup(normed);
+ slapi_ch_free_string(&orig);
+ } else {
+ slapi_ch_free_string(&orig);
+ *subjectndn = normed;
+ }
return LDAP_SUCCESS;
}
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
index 53620e4..9fbd25b 100644
--- a/ldap/servers/plugins/acl/acllas.c
+++ b/ldap/servers/plugins/acl/acllas.c
@@ -480,6 +480,7 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
int rc;
short len;
const size_t LDAP_URL_prefix_len = strlen(LDAP_URL_prefix);
+ const size_t LDAPS_URL_prefix_len = strlen(LDAPS_URL_prefix);
lasInfo lasinfo;
int got_undefined = 0;
@@ -530,15 +531,15 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
** userdn = "ldap:///DN1 || ldap:///DN2"
*/
-
/* The DN is now "ldap:///DN"
** remove the "ldap:///" part
*/
- if (strncasecmp (user, LDAP_URL_prefix,
- LDAP_URL_prefix_len) == 0) {
+ if (strncasecmp (user, LDAP_URL_prefix, LDAP_URL_prefix_len) == 0) {
s_user = user;
user += LDAP_URL_prefix_len;
-
+ } else if (strncasecmp (user, LDAPS_URL_prefix, LDAPS_URL_prefix_len) == 0) {
+ s_user = user;
+ user += LDAPS_URL_prefix_len;
} else {
char ebuf[ BUFSIZ ];
slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
@@ -677,8 +678,19 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
slapi_filter_free(f,1);
} else {
/* Must be a simple dn then */
- if (slapi_utf8casecmp((ACLUCHP)lasinfo.clientDn,
- (ACLUCHP)slapi_dn_normalize(user)) == 0) {
+ char *normed = NULL;
+ size_t dnlen = 0;
+ rc = slapi_dn_normalize_ext(user, 0, &normed, &dnlen);
+ if (rc == 0) { /* user passed in; not terminated */
+ *(normed + dnlen) = '\0';
+ } else if (rc < 0) { /* normalization failed, user the original */
+ normed = user;
+ }
+ rc = slapi_utf8casecmp((ACLUCHP)lasinfo.clientDn, (ACLUCHP)normed);
+ if (normed != user) {
+ slapi_ch_free_string(&normed);
+ }
+ if (0 == rc) {
matched = ACL_TRUE;
break;
}
@@ -1274,8 +1286,14 @@ DS_LASUserDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
while ( j != -1 ) {
attrVal = slapi_value_get_berval ( sval );
/* Here if atleast 1 value matches then we are done.*/
- val = slapi_dn_normalize (
- slapi_ch_strdup( attrVal->bv_val));
+ val = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == val) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASUserDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ slapi_ch_free ( (void**) &s_attrName);
+ return LAS_EVAL_FAIL;
+ }
if (slapi_utf8casecmp((ACLUCHP)val, (ACLUCHP)lasinfo.clientDn ) == 0) {
char ebuf [ BUFSIZ ];
@@ -1711,7 +1729,6 @@ DS_LASSSFEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
char *ptr;
int len;
int rc;
- char *s = NULL;
lasInfo lasinfo;
int aclssf;
@@ -2381,7 +2398,13 @@ acllas__handle_group_entry (Slapi_Entry* e, void *callback_data)
while ( i != -1 ) {
struct member_info *groupMember = NULL;
attrVal = slapi_value_get_berval ( sval );
- n_dn = slapi_dn_normalize ( slapi_ch_strdup( attrVal->bv_val ));
+ n_dn = slapi_create_dn_string( attrVal->bv_val );
+ if (NULL == n_dn) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__handle_group_entry: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
n = ++info->lu_idx;
if (n < 0) {
slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
@@ -2434,7 +2457,14 @@ acllas__handle_group_entry (Slapi_Entry* e, void *callback_data)
*/
if (strncasecmp( attrVal->bv_val, "ldap://",7) == 0 ||
strncasecmp( attrVal->bv_val, "ldaps://",8) == 0) {
- savURL = memberURL = slapi_ch_strdup ( attrVal->bv_val);
+ savURL = memberURL =
+ slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == savURL) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__handle_group_entry: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
slapi_log_error( SLAPI_LOG_ACL, plugin_name,
"ACL Group Eval:MemberURL:%s\n", memberURL);
info->result = acllas__client_match_URL (
@@ -2657,8 +2687,13 @@ DS_LASGroupDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
attr_i= slapi_attr_first_value ( attr,&sval );
while ( attr_i != -1 ) {
attrVal = slapi_value_get_berval ( sval );
- n_groupdn = slapi_dn_normalize(
- slapi_ch_strdup( attrVal->bv_val));
+ n_groupdn = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_groupdn) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASGroupDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
matched = acllas__user_ismember_of_group (
lasinfo.aclpb, n_groupdn, lasinfo.clientDn,
ACLLAS_CACHE_MEMBER_GROUPS,
@@ -2856,6 +2891,7 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
char *curMemberDn;
int Done = 0;
int ngr, tt;
+ char *normed = NULL;
/* Add the scope to the list of scopes */
if (aclpb->aclpb_numof_bases >= (aclpb->aclpb_grpsearchbase_size-1)) {
@@ -2867,9 +2903,15 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
sizeof (char *));
aclpb->aclpb_grpsearchbase_size += ACLPB_INCR_BASES;
}
- aclpb->aclpb_grpsearchbase[aclpb->aclpb_numof_bases++] =
- slapi_dn_normalize(slapi_ch_strdup(base));
-
+ normed = slapi_create_dn_string("%s", base);
+ if (NULL == normed) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__eval_memberGroupDnAttr: Invalid syntax: %s\n",
+ base );
+ slapi_ch_free ( (void **)&s_str );
+ return ACL_FALSE;
+ }
+ aclpb->aclpb_grpsearchbase[aclpb->aclpb_numof_bases++] = normed;
/* Set up info to do a search */
attrs[0] = type_member;
attrs[1] = type_uniquemember;
@@ -2992,8 +3034,14 @@ acllas__eval_memberGroupDnAttr (char *attrName, Slapi_Entry *e,
while ( k != -1 ) {
char *n_attrval;
attrVal = slapi_value_get_berval ( sval );
- n_attrval = slapi_ch_strdup( attrVal->bv_val);
- n_attrval = slapi_dn_normalize (n_attrval);
+ n_attrval = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_attrval) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__eval_memberGroupDnAttr: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ slapi_ch_free ( (void **)&s_str );
+ return ACL_FALSE;
+ }
/* We support: The attribute value can be a USER or a GROUP.
** Let's compare with the client, thi might be just an user. If it is not
@@ -3148,7 +3196,13 @@ acllas__verify_client (Slapi_Entry* e, void *callback_data)
i = slapi_attr_first_value ( attr,&sval );
while ( i != -1 ) {
attrVal = slapi_value_get_berval ( sval );
- val = slapi_dn_normalize(slapi_ch_strdup(attrVal->bv_val));
+ val = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == val) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__verify_client: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return 0;
+ }
if (slapi_utf8casecmp((ACLUCHP)val, (ACLUCHP)info->clientdn ) == 0) {
info->result = 1;
@@ -3236,7 +3290,12 @@ acllas__get_members (Slapi_Entry* e, void *callback_data)
i = slapi_attr_first_value ( attr,&sval );
while ( i != -1 ) {
attrVal =slapi_value_get_berval ( sval );
- info->member[i] = slapi_dn_normalize ( slapi_ch_strdup(attrVal->bv_val));
+ info->member[i] = slapi_create_dn_string ("%s", attrVal->bv_val);
+ if (NULL == info->member[i]) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__get_members: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ }
i = slapi_attr_next_value ( attr, i, &sval );
}
return 0;
@@ -3427,7 +3486,17 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
LDAPURLDesc *ludp;
int rc;
Slapi_Filter *f = NULL;
-
+ char *rawdn = NULL;
+ char *dn = NULL;
+ size_t dnlen = 0;
+ char *p = NULL;
+ char *normed = NULL;
+ /* ldap(s)://host:port/suffix?attrs?scope?filter */
+ const size_t LDAP_URL_prefix_len = strlen(LDAP_URL_prefix_core);
+ const size_t LDAPS_URL_prefix_len = strlen(LDAPS_URL_prefix_core);
+ size_t prefix_len = 0;
+ char Q = '?';
+ char *hostport = NULL;
/* Get the client's entry if we don't have already */
if ( aclpb && ( NULL == aclpb->aclpb_client_entry )) {
@@ -3460,23 +3529,83 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
}
if ( NULL == aclpb->aclpb_client_entry ) {
- slapi_log_error ( SLAPI_LOG_ACL, plugin_name,
- "DS_LASUserAttrEval: Unable to get client's entry\n");
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: Unable to get client's entry\n");
return ACL_FALSE;
}
- if (( rc = ldap_url_parse( url, &ludp)) != 0 ) {
+ /* DN potion of URL must be normalized before calling ldap_url_parse.
+ * lud_dn is pointing at the middle of lud_string.
+ * lud_dn won't be freed in ldap_free_urldesc.
+ */
+ /* remove the "ldap{s}:///" part */
+ if (strncasecmp (url, LDAP_URL_prefix, LDAP_URL_prefix_len) == 0) {
+ prefix_len = LDAP_URL_prefix_len;
+ } else if (strncasecmp (url, LDAPS_URL_prefix, LDAPS_URL_prefix_len) == 0) {
+ prefix_len = LDAPS_URL_prefix_len;
+ } else {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: url %s does not include ldap prefix: %s\n", url);
+ return ACL_FALSE;
+ }
+ rawdn = url + prefix_len; /* ldap(s)://host:port/... or ldap(s):///... */
+ /* rawdn at ^ or ^ */
+ /* let rawdn point the suffix */
+ if ('/' == *(rawdn+1)) { /* ldap(s):/// */
+ rawdn += 2;
+ hostport = "/";
+ } else {
+ char *tmpp = rawdn;
+ rawdn = strchr(tmpp, '/');
+ size_t hostport_len = 0;
+ if (NULL == rawdn) {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acllas__client_match_URL: url %s does not include correct ldap prefix: %s\n", url);
+ return ACL_FALSE;
+ }
+ hostport_len = ++rawdn - tmpp; /* ldap(s)://host:port/... */
+ /* <--------> */
+ hostport = (char *)slapi_ch_malloc(hostport_len + 1);
+ memcpy(hostport, tmpp, hostport_len);
+ *(hostport+hostport_len) = '\0';
+ }
+ p = strchr(rawdn, Q);
+ if (p) {
+ /* url has scope and/or filter: ldap(s):///suffix?attr?scope?filter */
+ *p = '\0';
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "acllas__client_match_URL: Invalid syntax: %s\n", url);
+ return ACL_FALSE;
+ } else if (rc == 0) { /* url is passed in and not terminated with NULL*/
+ *(dn + dnlen) = '\0';
+ }
+ if (p) {
+ *p = Q;
+ }
+ normed = slapi_ch_smprintf("%s%s%s%s",
+ (prefix_len==LDAP_URL_prefix_len)?
+ LDAP_URL_prefix_core:LDAPS_URL_prefix_core,
+ hostport, dn, p?p:"");
+ if (rc > 0) {
+ /* dn was allocated in slapi_dn_normalize_ext */
+ slapi_ch_free_string(&dn);
+ }
+ if ('/' != *hostport) {
+ slapi_ch_free_string(&hostport);
+ }
+ rc = ldap_url_parse(normed, &ludp);
+ slapi_ch_free_string(&normed);
+ if (rc) {
return ACL_FALSE;
-
}
if ( ( NULL == ludp->lud_dn) || ( NULL == ludp->lud_filter) ) {
ldap_free_urldesc( ludp );
return ACL_FALSE;
}
- /* Normalize in place the dn */
- slapi_dn_normalize ( ludp->lud_dn );
-
/* Check the scope */
if ( ludp->lud_scope == LDAP_SCOPE_SUBTREE ) {
if (!slapi_dn_issuffix(n_clientdn, ludp->lud_dn)) {
@@ -3778,8 +3907,13 @@ DS_LASRoleDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
Slapi_DN *roleDN;
attrVal = slapi_value_get_berval ( sval );
- n_attrval = slapi_ch_strdup( attrVal->bv_val);
- n_attrval = slapi_dn_normalize (n_attrval);
+ n_attrval = slapi_create_dn_string("%s", attrVal->bv_val);
+ if (NULL == n_attrval) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name,
+ "DS_LASRoleDnAttrEval: Invalid syntax: %s\n",
+ attrVal->bv_val );
+ return LAS_EVAL_FAIL;
+ }
roleDN = slapi_sdn_new_dn_byval(n_attrval);
/* We support: The attribute value can be a USER or a GROUP.
@@ -3832,14 +3966,12 @@ DS_LASRoleDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
* returns: ACL_TRUE for matched,
* ACL_FALSE for matched.
* ACL_DONT_KNOW otherwise.
- *
- *
-*/
+ */
int
aclutil_evaluate_macro( char * rule, lasInfo *lasinfo,
- acl_eval_types evalType ) {
-
+ acl_eval_types evalType )
+{
int matched = 0;
aci_t *aci;
char *matched_val = NULL;
diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
index 8d4a21a..0c8d0fa 100644
--- a/ldap/servers/plugins/acl/aclparse.c
+++ b/ldap/servers/plugins/acl/aclparse.c
@@ -50,7 +50,6 @@ static int __aclp__sanity_check_acltxt(aci_t *aci_item, char *str);
static char * __aclp__normalize_acltxt (aci_t *aci_item, char *str);
static char * __aclp__getNextLASRule(aci_t *aci_item, char *str,
char **endOfCurrRule);
-static char * __aclp__dn_normalize( char *dn , char *end);
static int __aclp__get_aci_right ( char *str);
static int __aclp__init_targetattr (aci_t *aci, char *attr_val);
static int __acl__init_targetattrfilters( aci_t *aci_item, char *str);
@@ -239,10 +238,10 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
/*
- * The targetattrfilters bit looks like this:
- * (targetattrfilters="add= attr1:F1 && attr2:F2 ... && attrn:Fn,
- * del= attr1:F1 && attr2:F2... && attrn:Fn")
- */
+ * The targetattrfilters bit looks like this:
+ * (targetattrfilters="add= attr1:F1 && attr2:F2 ... && attrn:Fn,
+ * del= attr1:F1 && attr2:F2... && attrn:Fn")
+ */
if ( 0 != (rv= __acl__init_targetattrfilters(
aci_item, str))) {
return rv;
@@ -256,15 +255,14 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
}
/* Get individual components of the targetattr.
* (targetattr = "cn || u* || phone ||tel:add:(tel=1234)
- * || sn:del:(gn=5678)")
- * If it contains a value filter, the type will also be
- * ACI_TARGET_VALUE_ATTR.
- */
- if ( 0 != (rv= __aclp__init_targetattr(
- aci_item, str))) {
+ * || sn:del:(gn=5678)")
+ * If it contains a value filter, the type will also be
+ * ACI_TARGET_VALUE_ATTR.
+ */
+ if (0 != (rv = __aclp__init_targetattr(aci_item, str))) {
return rv;
}
- } else if (strncmp(str, aci_targetfilter,tfilterlen ) == 0) {
+ } else if (strncmp(str, aci_targetfilter,tfilterlen ) == 0) {
if ( aci_item->targetFilter)
return ACL_SYNTAX_ERR;
@@ -311,8 +309,8 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
} else if (strncmp(str, aci_targetdn, targetdnlen) == 0) {
char *tstr = NULL;
- const size_t LDAP_URL_prefix_len = strlen (LDAP_URL_prefix);
- char *tt;
+ size_t LDAP_URL_prefix_len = 0;
+ size_t tmplen = 0;
type = ACI_TARGET_DN;
/* Keep a copy of the target attr */
if (aci_item->target) {
@@ -322,30 +320,40 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
type |= ACI_TARGET_NOT;
strncpy(s, " ", 1);
}
-
- /* Convert it to lower as slapi_dn_normalize() does not */
- for (tt = str; *tt; tt++) *tt = TOLOWER ( *tt );
-
if ( (s = strchr( str, '=' )) != NULL ) {
value = s + 1;
- slapi_dn_normalize(value);
+ __acl_strip_leading_space(&value);
len = strlen ( value );
- if (*value == '"' && value[len-1] == '"'){
+ /* strip double quotes */
+ if (*value == '"' && value[len-1] == '"') {
value[len-1] = '\0';
value++;
}
__acl_strip_leading_space(&value);
- } else {
+ } else {
return ( ACL_SYNTAX_ERR );
}
-
- if ( strncasecmp ( value, LDAP_URL_prefix , LDAP_URL_prefix_len) )
+ if (0 ==
+ strncasecmp(value, LDAP_URL_prefix, strlen(LDAP_URL_prefix))) {
+ LDAP_URL_prefix_len = strlen(LDAP_URL_prefix);
+ } else if (0 == strncasecmp(value, LDAPS_URL_prefix,
+ strlen(LDAPS_URL_prefix))) {
+ LDAP_URL_prefix_len = strlen(LDAPS_URL_prefix);
+ } else {
return ( ACL_SYNTAX_ERR );
+ }
value += LDAP_URL_prefix_len;
- len = strlen ( value );
- tstr = (char *) slapi_ch_malloc ( targetdnlen + len + 4 );
- sprintf ( tstr, "(target=%s)", value);
+ rv = slapi_dn_normalize_case_ext(value, 0, &tmpstr, &tmplen);
+ if (rv < 0) {
+ return ACL_SYNTAX_ERR;
+ } else if (rv == 0) { /* value passed in; not null terminated */
+ *(tmpstr + tmplen) = '\0';
+ }
+ tstr = slapi_ch_smprintf("(target=%s)", tmpstr);
+ if (rv > 0) {
+ slapi_ch_free_string(&tmpstr);
+ }
if ( (rv = acl_check_for_target_macro( aci_item, value)) == -1) {
slapi_ch_free ( (void **) &tstr );
return(ACL_SYNTAX_ERR);
@@ -356,7 +364,7 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
/* it's a normal target with no macros inside */
f = slapi_str2filter ( tstr );
}
- slapi_ch_free ( (void **) &tstr );
+ slapi_ch_free_string ( &tstr );
} else {
/* did start with a 't' but was not a recognsied keyword */
return(ACL_SYNTAX_ERR);
@@ -492,20 +500,86 @@ __aclp__sanity_check_acltxt (aci_t *aci_item, char *str)
slapi_log_error(SLAPI_LOG_ACL, plugin_name, "Normalized String:%s\n", newstr);
/* check for acl syntax error */
- if ((handle = (ACLListHandle_t *) ACL_ParseString(&errp,
- newstr)) == NULL) {
+ if ((handle = (ACLListHandle_t *) ACL_ParseString(&errp, newstr)) == NULL) {
acl_print_acllib_err(&errp, str);
- slapi_ch_free ( (void **) &newstr );
+ slapi_ch_free_string(&newstr);
return ACL_SYNTAX_ERR;
} else {
/* get the rights and the aci type */
aci_item->aci_handle = handle;
nserrDispose(&errp);
- slapi_ch_free ( (void **) &newstr );
+ slapi_ch_free_string(&newstr);
return 0;
}
}
+
+/*
+ * If the src includes "ldap(s):///<dn>", normalize <dn> and copy
+ * the string starting from start to *dest.
+ * If isstrict is non-zero, if ldap(s):/// is not included in the src
+ * string, it returns an error (-1).
+ * If isstrict is zero, the string is copied as is.
+ *
+ * return value: 0 or positive: success
+ * negative: failure
+ */
+int
+__aclp__copy_normalized_str (char *src, char *endsrc, char *start,
+ char **dest, size_t *destlen, int isstrict)
+{
+ char *p = NULL;
+ int rc = -1;
+ char *dn = NULL;
+ size_t dnlen = 0;
+
+ p = PL_strnstr(src, LDAP_URL_prefix, endsrc - src);
+ if (p) {
+ p += strlen(LDAP_URL_prefix);
+ } else {
+ p = PL_strnstr(src, LDAPS_URL_prefix, endsrc - src);
+ if (p) {
+ p += strlen(LDAPS_URL_prefix);
+ }
+ }
+
+ if (isstrict && ((NULL == p) || 0 == strlen(p))) {
+ return rc; /* error */
+ }
+
+ rc = 0;
+ if (p && strlen(p) > 0) {
+ size_t len = 0;
+ /* strip the string starting from ? */
+ char *q = PL_strnchr(p, '?', endsrc - p);
+ if (q) {
+ len = q - p;
+ } else {
+ len = endsrc - p;
+ }
+ /* Normalize the value of userdn and append it to ret_str */
+ rc = slapi_dn_normalize_ext(p, len, &dn, &dnlen);
+ if (rc < 0) {
+ return rc;
+ }
+ /* append up to ldap(s):/// */
+ aclutil_str_append_ext(dest, destlen, start, p - start);
+ /* append the DN part */
+ aclutil_str_append_ext(dest, destlen, dn, dnlen);
+ if (rc > 0) { /* if rc == 0, p is passed in */
+ slapi_ch_free_string(&dn);
+ }
+ if (q) {
+ /* append the rest from '?' */
+ aclutil_str_append_ext(dest, destlen, q, endsrc - q);
+ }
+ } else {
+ aclutil_str_append_ext(dest, destlen, start, endsrc - start);
+ }
+
+ return rc;
+}
+
/******************************************************************************
*
* acl__normalize_acltxt
@@ -534,23 +608,25 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
char *s, *p;
char *end;
char *aclstr, *s_aclstr;
+ char *prevend = NULL;
char *ret_str = NULL;
+ size_t retstr_len = 0;
int len;
- char *ptr, *aclName;
+ char *aclName;
char *nextACE;
char *tmp_str = NULL;
char *acestr = NULL;
char *s_acestr = NULL;
int aci_rights_val = 0; /* bug 389975 */
+ int rc = 0;
/* make a copy first */
s_aclstr = aclstr = slapi_ch_strdup ( str );
/* The rules are like this version 3.0; acl "xyz"; rule1; rule2; */
s = strchr (aclstr, ';');
- if ( NULL == s) {
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (NULL == s) {
+ goto error;
}
aclstr = ++s;
@@ -564,9 +640,8 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
aclName = s+3;
s = strchr (aclstr, ';');
- if ( NULL == s) {
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (NULL == s) {
+ goto error;
}
aclstr = s;
@@ -576,8 +651,10 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
/* Here aclName is the acl description string */
aci_item->aclName = slapi_ch_strdup ( aclName );
- aclutil_str_appened (&ret_str, s_aclstr);
- aclutil_str_appened (&ret_str, ";");
+ retstr_len = strlen(str) * 3;
+ ret_str = (char *)slapi_ch_calloc(sizeof(char), retstr_len);
+ aclutil_str_append_ext (&ret_str, &retstr_len, s_aclstr, strlen(s_aclstr));
+ aclutil_str_append_ext (&ret_str, &retstr_len, ";", 1);
/* start with the string */
acestr = aclstr;
@@ -586,37 +663,34 @@ __aclp__normalize_acltxt ( aci_t * aci_item, char * str )
* Here acestr is something like:
*
* " allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP";)"
- *
- *
- */
+ */
normalize_nextACERule:
/* now we are in the rule part */
tmp_str = acestr;
s = strchr (tmp_str, ';');
- if ( s == NULL) {
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ if (s == NULL) {
+ goto error;
}
+
nextACE = s;
LDAP_UTF8INC(nextACE);
*s = '\0';
- /* acestr now will hold copy of the ACE. Also add
+ /* acestr now will hold copy of the ACE. Also add
** some more space in case we need to add "absolute"
- ** for deny rule. We will never need more 2 times
- ** the len.
+ ** for deny rule. We will never need more 3 times
+ ** the len (even if all the chars are escaped).
*/
__acl_strip_leading_space(&tmp_str);
len = strlen (tmp_str);
- s_acestr = acestr = slapi_ch_calloc ( 1, 2 * len);
+ s_acestr = acestr = slapi_ch_calloc (1, 3 * len);
/*
* Now it's something like:
* allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP";
- */
+ */
if (strncasecmp(tmp_str, "allow", 5) == 0) {
memcpy(acestr, tmp_str, len);
tmp_str += 5;
@@ -624,6 +698,14 @@ normalize_nextACERule:
aci_rights_val = __aclp__get_aci_right (tmp_str);/* bug 389975 */
aci_item->aci_type |= ACI_HAS_ALLOW_RULE;
+ s = strchr(acestr, ')');
+ if (NULL == s) {
+ /* wrong syntax */
+ goto error;
+ }
+ /* add "allow(rights...)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len, acestr, s - acestr + 1);
+ prevend = s + 1;
} else if (strncasecmp(tmp_str, "deny", 4) == 0) {
char *d_rule ="deny absolute";
/* Then we have to add "absolute" to the deny rule
@@ -652,6 +734,15 @@ normalize_nextACERule:
len = strlen ( d_rule );
memcpy (acestr, d_rule, len );
memcpy (acestr+len, tmp_str, strlen (tmp_str) );
+
+ s = strchr(acestr, ')');
+ if (NULL == s) {
+ /* wrong syntax */
+ goto error;
+ }
+ /* add "deny(rights...)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len, acestr, s - acestr + 1);
+ prevend = s + 1;
} else {
/* wrong syntax */
aci_rights_val = -1 ;
@@ -659,32 +750,32 @@ normalize_nextACERule:
if (aci_rights_val == -1 )
{
/* wrong syntax */
- slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_acestr );
- slapi_ch_free ( (void **) &s_aclstr );
- return NULL;
+ goto error;
} else
- aci_item->aci_access |= aci_rights_val;
+ aci_item->aci_access |= aci_rights_val;
-
- /* Normalize all the DNs in the userdn rule */
-
+ /* Normalize all the DNs in the userdn, groupdn, roledn rules */
/*
*
* Here acestr starts like this:
- * " allow (all) groupdn = "ldap:///cn=Domain Administrators, o=$dn.o, o=ISP"
- */
-
+ * " allow (all) groupdn = "ldap:///cn=Domain Administrators,o=$dn.o,o=ISP"
+ */
s = __aclp__getNextLASRule(aci_item, acestr, &end);
while ( s ) {
- if ( 0 == strncmp ( s, DS_LAS_USERDNATTR, 10) ||
- ( 0 == strncmp ( s, DS_LAS_USERATTR, 8))) {
+ if ( (0 == strncmp(s, DS_LAS_USERDNATTR, 10)) ||
+ (0 == strncmp(s, DS_LAS_USERATTR, 8)) ) {
/*
** For userdnattr/userattr rule, the resources changes and hence
** we cannot cache the result. See above for more comments.
*/
aci_item->aci_elevel = ACI_ELEVEL_USERDNATTR;
- } else if ( 0== strncmp ( s, DS_LAS_USERDN, 6)) {
+
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 0);
+ if (rc < 0) {
+ goto error;
+ }
+ } else if ( 0 == strncmp ( s, DS_LAS_USERDN, 6)) {
p = strstr ( s, "=");
p--;
if ( strncmp (p, "!=", 2) == 0)
@@ -699,22 +790,12 @@ normalize_nextACERule:
* which would ensure that acl info is not cached from
* one resource entry to the next. (bug 558519)
*/
- p = strstr ( p, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8; /* for ldap:/// */
- if( __aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
-
+
/* we have a rule like userdn = "ldap:///blah". s points to blah now.
** let's find if we have a SELF rule like userdn = "ldap:///self".
** Since the resource changes on entry basis, we can't cache the
@@ -750,6 +831,12 @@ normalize_nextACERule:
aci_item->aci_elevel = ACI_ELEVEL_GROUPDNATTR;
}
aci_item->aci_ruleType |= ACI_GROUPDNATTR_RULE;
+
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 0);
+ if (rc < 0) {
+ goto error;
+ }
} else if ( 0 == strncmp ( s, DS_LAS_GROUPDN, 7)) {
p = strstr ( s, "=");
@@ -757,21 +844,12 @@ normalize_nextACERule:
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_GROUPDN;
- p = strstr ( s, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8;
- if (__aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
+
/* check for param rules */
__aclp_chk_paramRules ( aci_item, p, end );
@@ -786,21 +864,12 @@ normalize_nextACERule:
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_ROLEDN;
- p = strstr ( s, "ldap");
- if (p == NULL) {
- /* must start with ldap */
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
- }
- p += 8;
- if (__aclp__dn_normalize (p, end) == NULL) {
- if (s_acestr) slapi_ch_free ( (void **) &s_acestr );
- if (ret_str) slapi_ch_free ( (void **) &ret_str );
- slapi_ch_free ( (void **) &s_aclstr );
- return (NULL);
+ rc = __aclp__copy_normalized_str(s, end, prevend,
+ &ret_str, &retstr_len, 1);
+ if (rc < 0) {
+ goto error;
}
+
/* check for param rules */
__aclp_chk_paramRules ( aci_item, p, end );
@@ -808,40 +877,47 @@ normalize_nextACERule:
if ( aci_item->aci_elevel > ACI_ELEVEL_GROUPDN )
aci_item->aci_elevel = ACI_ELEVEL_GROUPDN;*/
aci_item->aci_ruleType |= ACI_ROLEDN_RULE;
+ } else {
+ /* adding the string no need to be processed
+ * (e.g., dns="lab.example.com)" */
+ aclutil_str_append_ext(&ret_str, &retstr_len,
+ prevend, end - prevend);
}
+ prevend = end;
s = ++end;
s = __aclp__getNextLASRule(aci_item, s, &end);
- }/* while */
+ if (NULL == s) {
+ /* adding the rest of the string, e.g. '\"' */
+ aclutil_str_append_ext(&ret_str, &retstr_len,
+ prevend, strlen(prevend));
+ }
+ } /* while */
- /* get the head of the string */
- acestr = s_acestr;
- len = strlen( acestr);
- ptr = acestr +len-1;
- while (*ptr && *ptr != '\"' && *ptr != ')' ) *ptr-- = ' ';
- ptr++;
- *ptr = ';';
-
- aclutil_str_appened (&ret_str, acestr);
- if (s_acestr) {
- slapi_ch_free ( (void **) &s_acestr );
- }
- s_acestr = NULL;
+ slapi_ch_free_string (&s_acestr);
+ __acl_strip_trailing_space(ret_str);
+ aclutil_str_append_ext(&ret_str, &retstr_len, ";", 1);
if (nextACE) {
s = strstr (nextACE, "allow");
if (s == NULL) s = strstr (nextACE, "deny");
if (s == NULL) {
if (nextACE && *nextACE != '\0')
- aclutil_str_appened (&ret_str, nextACE);
- slapi_ch_free ( (void **) &s_aclstr );
+ aclutil_str_append (&ret_str, nextACE);
+ slapi_ch_free_string (&s_aclstr);
return (ret_str);
}
acestr = nextACE;
goto normalize_nextACERule;
}
- slapi_ch_free ( (void **) &s_aclstr );
+ slapi_ch_free_string (&s_aclstr);
return (ret_str);
+
+error:
+ slapi_ch_free_string (&ret_str);
+ slapi_ch_free_string (&s_aclstr);
+ slapi_ch_free_string (&s_acestr);
+ return NULL;
}
/*
*
@@ -857,7 +933,7 @@ __aclp__getNextLASRule (aci_t *aci_item, char *original_str , char **endOfCurrRu
{
char *newstr, *word, *next, *start, *end;
char *ruleStart = NULL;
- int len, ruleLen;
+ int len, ruleLen = 0;
int in_dn_expr = 0;
*endOfCurrRule = NULL;
@@ -1029,43 +1105,7 @@ __aclp__getNextLASRule (aci_t *aci_item, char *original_str , char **endOfCurrRu
return ( ruleStart );
}
-/******************************************************************************
-*
-* __aclp__dn_normalize
-*
-* Normalize the DN INPLACE. This routine is similar to slapi_dn_normalize()
-* except various small stuff at the end.
-* Normalize until the "end" and not to the end of string.
-*
-******************************************************************************/
-static char *
-__aclp__dn_normalize( char *dn , char *end)
-{
- char *d;
-
- if ((end - dn) < 0) {
- return(NULL);
- }
- d = slapi_dn_normalize_to_end ( dn, end );
-
- /* Do I have the quotes already */
- if (*d != '\"' ) {
- /*
- ** We are taking care of this situation
- ** " ") ". We need to remove the space
- ** infront and tack it after the quote like this.
- ** "" ) ".
- */
-
- *d = '\"';
- d++;
- while (*d && *d != '\"') *d++ = ' ';
- *d = ' ';
- }
-
- return( dn );
-}
/***************************************************************************
* acl__get_aci_right
*
@@ -1263,6 +1303,7 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
}
while (str != 0 && *str != 0) {
+ int lenstr = 0;
__acl_strip_leading_space(&str);
@@ -1292,23 +1333,28 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
attr = (Targetattr *) slapi_ch_malloc (sizeof (Targetattr));
memset (attr, 0, sizeof(Targetattr));
- if (strchr(str, '*')) {
-
+ /* strip double quotes */
+ lenstr = strlen(str);
+ if (*str == '"' && *(str + lenstr - 1) == '"') {
+ *(str + lenstr - 1) = '\0';
+ str++;
+ }
+ if (strchr(str, '*')) {
+
/* It contains a * so it's something like * or cn* */
if (strcmp(str, "*" ) != 0) {
char line[100];
char *lineptr = &line[0];
char *newline = NULL;
- int lenstr = 0;
struct slapi_filter *f = NULL;
- if ((lenstr = strlen(str)) > 91) { /* 100 - 8 for "(attr =%s)" */
- newline = slapi_ch_malloc(lenstr + 9);
+ if (lenstr > 92) { /* 100 - 8 for "(attr=%s)\0" */
+ newline = slapi_ch_malloc(lenstr + 8);
lineptr = newline;
}
attr->attr_type = ACL_ATTR_FILTER;
- sprintf (lineptr, "(attr =%s)", str);
+ sprintf (lineptr, "(attr=%s)", str);
f = slapi_str2filter (lineptr);
if (f == NULL) {
@@ -1320,7 +1366,7 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
if (newline) slapi_ch_free((void **) &newline);
} else {
- attr->attr_type = ACL_ATTR_STAR;
+ attr->attr_type = ACL_ATTR_STAR;
attr->u.attr_str = slapi_ch_strdup (str);
}
diff --git a/ldap/servers/plugins/acl/aclproxy.c b/ldap/servers/plugins/acl/aclproxy.c
index d40f543..9b28489 100644
--- a/ldap/servers/plugins/acl/aclproxy.c
+++ b/ldap/servers/plugins/acl/aclproxy.c
@@ -87,7 +87,9 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
LDAPProxyAuth *spec = NULL;
BerElement *ber = NULL;
char *errstring = "unable to parse proxied authorization control";
-
+ int rc = 0;
+ char *normed = NULL;
+ size_t dnlen = 0;
BEGIN
ber_tag_t tag;
@@ -132,11 +134,20 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
errstring = "proxied authorization id must be a DN (dn:...)";
break;
}
- strcpy( spec->auth_dn, spec->auth_dn + 3 );
+ /* memmove is safe for overlapping copy */
+ memmove ( spec->auth_dn, spec->auth_dn + 3, strlen(spec->auth_dn) - 2);/* 1 for '\0' */
}
- slapi_dn_normalize(spec->auth_dn);
lderr = LDAP_SUCCESS; /* got it! */
+ rc = slapi_dn_normalize_ext(spec->auth_dn, 0, &normed, &dnlen);
+ if (rc < 0) {
+ lderr = LDAP_INVALID_SYNTAX;
+ } else if (rc == 0) { /* spec->auth_dn is passed in; not terminated */
+ *(normed + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&spec->auth_dn);
+ spec->auth_dn = normed;
+ }
END
/* Cleanup */
diff --git a/ldap/servers/plugins/acl/aclutil.c b/ldap/servers/plugins/acl/aclutil.c
index 4aebd47..c0b8f57 100644
--- a/ldap/servers/plugins/acl/aclutil.c
+++ b/ldap/servers/plugins/acl/aclutil.c
@@ -65,7 +65,7 @@ static PRIntn acl_ht_display_entry(PLHashEntry *he, PRIntn i, void *arg);
/* UTILITY FUNCTIONS */
/***************************************************************************/
int
-aclutil_str_appened(char **str1, const char *str2)
+aclutil_str_append(char **str1, const char *str2)
{
int new_len;
@@ -87,6 +87,43 @@ aclutil_str_appened(char **str1, const char *str2)
return(0);
}
+/*
+ * dlen: the length of the buffer *dest (not the string length in *dest)
+ */
+int
+aclutil_str_append_ext(char **dest, size_t *dlen, const char *src, size_t slen)
+{
+ char *ptr = NULL;
+ int rc = 0;
+
+ if ( dest == NULL || src == NULL ) {
+ return rc;
+ }
+
+ if (0 == slen) {
+ slen = strlen(src);
+ }
+ if (*dest && dlen > 0) {
+ size_t dest_strlen = strlen(*dest);
+ size_t new_len = dest_strlen + slen + 1;
+ if (new_len > *dlen) {
+ *dest = (char *)slapi_ch_realloc(*dest, new_len);
+ *dlen = new_len;
+ ptr = *dest + dest_strlen;
+ } else {
+ ptr = *dest + dest_strlen;
+ }
+ } else {
+ *dlen = slen + 1;
+ *dest = (char *)slapi_ch_malloc(*dlen);
+ ptr = *dest;
+ }
+ memcpy(ptr, src, slen);
+ *(ptr + slen) = '\0';
+
+ return rc;
+}
+
/***************************************************************************/
/* Print routines */
/***************************************************************************/
@@ -104,9 +141,14 @@ acl_print_acllib_err (NSErr_t *errp , char * str)
aclErrorFmt(errp, msgbuf, ACLUTIL_ACLLIB_MSGBUF_LEN, 1);
msgbuf[ACLUTIL_ACLLIB_MSGBUF_LEN-1] = '\0';
- if (msgbuf)
- slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)(%s)\n",
- msgbuf, str ? str: "NULL");
+ if (strlen(msgbuf) > 0) {
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)(%s)\n",
+ msgbuf, str ? str: "NULL");
+ } else {
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,"ACL LIB ERR:(%s)\n",
+ str ? str: "NULL");
+ }
+
}
void
aclutil_print_aci (aci_t *aci_item, char *type)
@@ -240,7 +282,7 @@ aclutil_print_err (int rv , const Slapi_DN *sdn, const struct berval* val,
if (errbuf) {
/* If a buffer is provided, then copy the error */
- aclutil_str_appened(errbuf, lineptr );
+ aclutil_str_append(errbuf, lineptr );
}
slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "%s", lineptr);
@@ -436,7 +478,7 @@ acl_gen_err_msg(int access, char *edn, char *attr, char **errbuf)
line = PR_smprintf(
"Insufficient 'delete' privilege to delete the entry '%s'.\n",edn);
}
- aclutil_str_appened(errbuf, line );
+ aclutil_str_append(errbuf, line );
if (line) {
PR_smprintf_free(line);
@@ -540,7 +582,7 @@ aclutil_expand_paramString ( char *str, Slapi_Entry *e )
goto cleanup;
}
*p = '\0';
- aclutil_str_appened ( &buf,a_dns[i]);
+ aclutil_str_append ( &buf,a_dns[i]);
if ( type == 1 ) {
/* xyz = $dn.o */
@@ -573,15 +615,15 @@ aclutil_expand_paramString ( char *str, Slapi_Entry *e )
kk= slapi_attr_next_value( attr, kk, &sval );
if ( kk != -1 ) /* can't handle multiple --error */
goto cleanup;
+ attrValue = slapi_value_get_berval ( t_sval );
+ attrVal = attrValue->bv_val;
}
- attrValue = slapi_value_get_berval ( t_sval );
- attrVal = attrValue->bv_val;
}
} else {
attrVal = a_dns[i];
}
- aclutil_str_appened ( &buf, attrVal);
- aclutil_str_appened ( &buf, ",");
+ aclutil_str_append ( &buf, attrVal);
+ aclutil_str_append ( &buf, ",");
}
rc = 0; /* everything is okay*/
/* remove the last comma */
@@ -607,7 +649,7 @@ __aclutil_extract_dn_component ( char **e_dns, int position, char *attrName )
int i, matched, len;
char *s;
- int matchedPosition;
+ int matchedPosition = 0;
len = strlen ( attrName );
diff --git a/ldap/servers/plugins/chainingdb/cb_config.c b/ldap/servers/plugins/chainingdb/cb_config.c
index 1dab846..5659353 100644
--- a/ldap/servers/plugins/chainingdb/cb_config.c
+++ b/ldap/servers/plugins/chainingdb/cb_config.c
@@ -63,24 +63,28 @@ int cb_config_add_dse_entries(cb_backend *cb, char **entries, char *string1, cha
Slapi_PBlock *util_pb = NULL;
int res, rc = 0;
char entry_string[CB_BUFSIZE];
+ char *dn = NULL;
for(x = 0; strlen(entries[x]) > 0; x++) {
util_pb = slapi_pblock_new();
PR_snprintf(entry_string, sizeof(entry_string), entries[x], string1, string2, string3);
e = slapi_str2entry(entry_string, 0);
+ dn = slapi_ch_strdup(slapi_entry_get_dn(e)); /* for err msg */
slapi_add_entry_internal_set_pb(util_pb, e, NULL, cb->identity, 0);
slapi_add_internal_pb(util_pb);
slapi_pblock_get(util_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
if ( LDAP_SUCCESS != res && LDAP_ALREADY_EXISTS != res ) {
char ebuf[ BUFSIZ ];
- slapi_log_error(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
+ slapi_log_error(SLAPI_LOG_FATAL, CB_PLUGIN_SUBSYSTEM,
"Unable to add config entry (%s) to the DSE: %s\n",
- escape_string(slapi_entry_get_dn(e), ebuf),
+ escape_string(dn, ebuf),
ldap_err2string(res));
rc = res;
slapi_pblock_destroy(util_pb);
+ slapi_ch_free_string(&dn);
break;
}
+ slapi_ch_free_string(&dn);
slapi_pblock_destroy(util_pb);
}
return rc;
@@ -161,7 +165,7 @@ int cb_config_load_dse_info(Slapi_PBlock * pb) {
/* Get the default instance value entry if it exists */
/* else create it */
-
+ /* This dn is already normalized */
PR_snprintf(defaultDn,sizeof(defaultDn),"cn=default instance config,%s",cb->pluginDN);
default_pb = slapi_pblock_new();
diff --git a/ldap/servers/plugins/chainingdb/cb_init.c b/ldap/servers/plugins/chainingdb/cb_init.c
index 21a54d5..3b4f7a0 100644
--- a/ldap/servers/plugins/chainingdb/cb_init.c
+++ b/ldap/servers/plugins/chainingdb/cb_init.c
@@ -82,7 +82,9 @@ chaining_back_init( Slapi_PBlock *pb )
/* Initialize misc. fields */
cb->config.rwl_config_lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "chaining_db");
- rc = slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, (void *) cb );
+ rc = slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, (void *) cb );
+
+ /* These DNs are already normalized */
cb->pluginDN=slapi_ch_smprintf("cn=%s,%s",CB_PLUGIN_NAME,PLUGIN_BASE_DN);
cb->configDN=slapi_ch_smprintf("cn=config,%s",cb->pluginDN);
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c
index 1c08bd9..73d5e01 100644
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
@@ -153,10 +153,10 @@ cb_dont_allow_that(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e,
static char *cb_skeleton_entries[] =
{
- "dn:cn=monitor, cn=%s, cn=%s, cn=plugins, cn=config\n"
- "objectclass:top\n"
- "objectclass:extensibleObject\n"
- "cn:monitor\n",
+ "dn: cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config\n"
+ "objectclass: top\n"
+ "objectclass: extensibleObject\n"
+ "cn: monitor\n",
""
};
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
index a14e48c..496f749 100644
--- a/ldap/servers/plugins/cos/cos_cache.c
+++ b/ldap/servers/plugins/cos/cos_cache.c
@@ -69,6 +69,8 @@
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
+
#include "portable.h"
#include "slapi-plugin.h"
@@ -324,6 +326,8 @@ static int cos_cache_vattr_compare(vattr_sp_handle *handle, vattr_context *c, Sl
static int cos_cache_vattr_types(vattr_sp_handle *handle,Slapi_Entry *e,vattr_type_list_context *type_context,int flags);
static int cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Slapi_Entry *e, char *type, Slapi_ValueSet **out_attr, Slapi_Value *test_this, int *result, int *ops);
+static int hexchar2int( char c );
+
/*
compares s2 to s1 starting from end of string until the beginning of either
matches result in the s2 value being clipped from s1 with a NULL char
@@ -904,14 +908,29 @@ static int cos_dn_defs_cb (Slapi_Entry* e, void *callback_data) {
{
/* get the parent of the definition */
- char *parent = slapi_dn_parent(pDn->val);
- slapi_dn_normalize( parent );
+ char *parent = NULL;
+ size_t plen = 0;
+ int rc = 0;
+ char *orig = slapi_dn_parent(pDn->val);
+ rc = slapi_dn_normalize_ext(orig,
+ 0, &parent, &plen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_build_definition_list: failed to normalize parent dn %s. Adding the pre normalized dn.\n", orig, 0, 0);
+ parent = orig;
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(parent + plen) = '\0';
+ }
cos_cache_add_attrval(&pCosTargetTree, parent);
if(!pCosTemplateDn)
cos_cache_add_attrval(&pCosTemplateDn, parent);
- slapi_ch_free((void**)&parent);
+ if (orig != parent) {
+ slapi_ch_free_string(&orig);
+ }
+ slapi_ch_free_string(&parent);
}
slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL);
@@ -1916,16 +1935,33 @@ static int cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAt
theTemp = (cosTemplates*) slapi_ch_malloc(sizeof(cosTemplates));
if(theTemp)
{
- char *grade = (char*)slapi_ch_malloc(strlen(dn->val)+1);
+ char *grade = NULL;
int grade_index = 0;
int index = 0;
+ int lastindex = 0;
int template_default = 0;
-
- slapi_dn_normalize(dn->val);
+ char *dnval = NULL;
+ size_t dnlen = 0;
+ int rc = 0;
+
+ rc = slapi_dn_normalize_ext(dn->val, 0, &dnval, &dnlen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_add_tmpl: failed to normalize dn %s. "
+ "Processing the pre normalized dn.\n", dn->val, 0, 0);
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(dnval + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&dn->val);
+ dn->val = dnval;
+ }
+ grade = (char*)slapi_ch_malloc(strlen(dn->val)+1);
/* extract the cos grade */
while(dn->val[index] != '=' && dn->val[index] != '\0')
index++;
+ lastindex = strlen(dn->val) - 1;
if(dn->val[index] == '=')
{
@@ -1945,7 +1981,29 @@ static int cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAt
}
else
{
- if(dn->val[index] != '\\') /* skip escape chars */
+ if(dn->val[index] == '\\')
+ {
+ if ((index+2 <= lastindex) && isxdigit(dn->val[index+1]) &&
+ isxdigit(dn->val[index+2])) {
+ /* Convert ESC HEX HEX to a real char */
+ int n = hexchar2int(dn->val[index+1]);
+ int n2 = hexchar2int(dn->val[index+2]);
+ n = (n << 4) + n2;
+ if (n == 0) { /* don't change \00 */
+ grade[grade_index] = dn->val[index++]; /* '\\' */
+ grade_index++;
+ grade[grade_index] = dn->val[index++]; /* 0 */
+ grade_index++;
+ grade[grade_index] = dn->val[index]; /* 0 */
+ grade_index++;
+ } else {
+ grade[grade_index] = n;
+ index += 2;
+ grade_index++;
+ }
+ } /* else: skip escape chars */
+ }
+ else
{
grade[grade_index] = dn->val[index];
grade_index++;
@@ -2329,8 +2387,24 @@ static int cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Sl
/* is this entry a child of the target tree(s)? */
do
{
- if(pTargetTree)
- slapi_dn_normalize( pTargetTree->val );
+ if(pTargetTree) {
+ int rc = 0;
+ char *tval = NULL;
+ size_t tlen = 0;
+ rc = slapi_dn_normalize_ext(pTargetTree->val, 0, &tval, &tlen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_query_attr: failed to normalize dn %s. "
+ "Processing the pre normalized dn.\n",
+ pTargetTree->val, 0, 0);
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(tval + tlen) = '\0';
+ } else {
+ slapi_ch_free_string(&pTargetTree->val);
+ pTargetTree->val = tval;
+ }
+ }
if( pTargetTree->val == 0 ||
slapi_dn_issuffix(pDn, pTargetTree->val) != 0 ||
@@ -2800,7 +2874,23 @@ static int cos_cache_index_all(cosCache *pCache)
while(pAttrVal)
{
- slapi_dn_normalize(pAttrVal->val);
+ int rc = 0;
+ char *dnval = NULL;
+ size_t dnlen = 0;
+ rc = slapi_dn_normalize_ext(pAttrVal->val, 0,
+ &dnval, &dnlen);
+ if (rc < 0) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "cos_cache_index_all: failed to normalize dn %s. "
+ "Processing the pre normalized dn.\n",
+ pAttrVal->val, 0, 0);
+ } else if (rc == 0) {
+ /* passed in. not terminated */
+ *(dnval + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&pAttrVal->val);
+ pAttrVal->val = dnval;
+ }
pCache->ppTemplateList[tmpindex] = pAttrVal->val;
tmpindex++;
@@ -3519,3 +3609,20 @@ static int cos_cache_entry_is_cos_related( Slapi_Entry *e) {
}
return(rc);
}
+
+/* copied from dn.c */
+static int
+hexchar2int( char c )
+{
+ if ( '0' <= c && c <= '9' ) {
+ return( c - '0' );
+ }
+ if ( 'a' <= c && c <= 'f' ) {
+ return( c - 'a' + 10 );
+ }
+ if ( 'A' <= c && c <= 'F' ) {
+ return( c - 'A' + 10 );
+ }
+ return( -1 );
+}
+
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index 9b6e021..94c4ab3 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -680,7 +680,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
}
entry = (struct configEntry *)
- slapi_ch_calloc(1, sizeof(struct configEntry));
+ slapi_ch_calloc(1, sizeof(struct configEntry));
if (NULL == entry) {
ret = DNA_FAILURE;
goto bail;
@@ -787,7 +787,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
if (value) {
/* TODO - Allow multiple scope settings for a single range. This may
* make ordering the scopes tough when we put them in the clist. */
- entry->scope = slapi_dn_normalize(value);
+ entry->scope = value;
} else {
slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
"dna_parse_config_entry: The %s config "
@@ -817,6 +817,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
if (value) {
Slapi_Entry *shared_e = NULL;
Slapi_DN *sdn = NULL;
+ char *normdn = NULL;
sdn = slapi_sdn_new_dn_byref(value);
@@ -840,15 +841,29 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
shared_e = NULL;
}
- entry->shared_cfg_base = slapi_ch_strdup(value);
- slapi_dn_normalize(entry->shared_cfg_base);
+ normdn = slapi_create_dn_string("%s", value);
+ if (NULL == normdn) {
+ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
+ "dna_parse_config_entry: failed to normalize dn: "
+ "%s\n", value);
+ ret = DNA_FAILURE;
+ goto bail;
+ }
+ entry->shared_cfg_base = normdn;
/* We prepend the host & port of this instance as a
* multi-part RDN for the shared config entry. */
- entry->shared_cfg_dn = slapi_ch_smprintf("%s=%s+%s=%s,%s", DNA_HOSTNAME,
- hostname, DNA_PORTNUM, portnum, value);
- slapi_ch_free_string(&value);
- slapi_dn_normalize(entry->shared_cfg_dn);
+ normdn = slapi_create_dn_string("%s=%s+%s=%s,%s", DNA_HOSTNAME,
+ hostname, DNA_PORTNUM, portnum, normdn);
+ if (NULL == normdn) {
+ slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
+ "dna_parse_config_entry: failed to create dn: "
+ "%s=%s+%s=%s,%s", DNA_HOSTNAME,
+ hostname, DNA_PORTNUM, portnum, value);
+ ret = DNA_FAILURE;
+ goto bail;
+ }
+ entry->shared_cfg_dn = normdn;
slapi_log_error(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM,
"----------> %s [%s]\n", DNA_SHARED_CFG_DN,
@@ -860,7 +875,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
entry->threshold = strtoull(value, 0, 0);
slapi_log_error(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM,
- "----------> %s [%" NSPRIu64 "]\n", DNA_THRESHOLD, value);
+ "----------> %s [%s]\n", DNA_THRESHOLD, value);
slapi_ch_free_string(&value);
} else {
@@ -1680,8 +1695,6 @@ static char *dna_get_dn(Slapi_PBlock * pb)
goto bail;
}
-/* slapi_dn_normalize( dn );
-*/
bail:
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
"<-- dna_get_dn\n");
@@ -2310,7 +2323,14 @@ static int dna_is_replica_bind_dn(char *range_dn, char *bind_dn)
* the shared config. We need to see what the configured
* replica bind DN is. */
if (be_suffix) {
- replica_dn = slapi_ch_smprintf("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", be_suffix);
+ /* This function converts the old DN style to the new one. */
+ replica_dn = slapi_create_dn_string("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", be_suffix);
+ if (NULL == replica_dn) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
+ "dna_is_replica_bind_dn: failed to create "
+ "replica dn for %s\n", be_suffix);
+ return 1;
+ }
replica_sdn = slapi_sdn_new_dn_passin(replica_dn);
attrs[0] = DNA_REPL_BIND_DN;
@@ -2370,8 +2390,15 @@ static int dna_get_replica_bind_creds(char *range_dn, struct dnaServer *server,
/* Fetch the replication agreement entry */
if (be_suffix) {
- replica_dn = slapi_ch_smprintf("cn=replica,cn=\"%s\",cn=mapping tree,cn=config",
- be_suffix);
+ /* This function converts the old DN style to the new one. */
+ replica_dn = slapi_create_dn_string("cn=replica,cn=\"%s\",cn=mapping tree,cn=config", be_suffix);
+ if (NULL == replica_dn) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
+ "dna_get_replica_bind_creds: failed to create "
+ "replica dn for %s\n", be_suffix);
+ ret = LDAP_PARAM_ERROR;
+ goto bail;
+ }
filter = slapi_ch_smprintf("(&(nsds5ReplicaHost=%s)(|(" DNA_REPL_PORT "=%u)"
"(" DNA_REPL_PORT "=%u)))",
@@ -2654,7 +2681,7 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
generate = 1;
}
- slapi_ch_free_string(&value);
+ slapi_ch_free_string(&value);
} else {
/* check mods for magic value */
Slapi_Mod *next_mod = slapi_mod_new();
diff --git a/ldap/servers/plugins/pwdstorage/smd5_pwd.c b/ldap/servers/plugins/pwdstorage/smd5_pwd.c
index 6747a20..cef3ee3 100644
--- a/ldap/servers/plugins/pwdstorage/smd5_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/smd5_pwd.c
@@ -70,7 +70,6 @@ smd5_pw_cmp( const char *userpwd, const char *dbpwd )
unsigned char *dbhash = quick_dbhash;
struct berval salt;
char *hashresult = NULL;
- SECItem binary_item;
ctx = PK11_CreateDigestContext(SEC_OID_MD5);
if (ctx == NULL) {
@@ -84,7 +83,7 @@ smd5_pw_cmp( const char *userpwd, const char *dbpwd )
*/
hash_len = pwdstorage_base64_decode_len(dbpwd, 0);
if ( hash_len >= sizeof(quick_dbhash) ) { /* get more space: */
- dbhash = (char*) slapi_ch_calloc( hash_len + 1, sizeof(char) );
+ dbhash = (unsigned char*) slapi_ch_calloc( hash_len + 1, sizeof(char) );
if ( dbhash == NULL ) goto loser;
} else {
memset( quick_dbhash, 0, sizeof(quick_dbhash) );
@@ -125,7 +124,7 @@ smd5_pw_enc( const char *pwd )
unsigned int outLen;
unsigned char hash_out[MD5_LENGTH + MD5_DEFAULT_SALT_LENGTH];
unsigned char b2a_out[(MD5_LENGTH*2) + (MD5_MAX_SALT_LENGTH*2)]; /* conservative */
- char *salt = hash_out + MD5_LENGTH;
+ unsigned char *salt = hash_out + MD5_LENGTH;
struct berval saltval;
SECItem binary_item;
@@ -140,7 +139,7 @@ smd5_pw_enc( const char *pwd )
memset( hash_out, 0, sizeof(hash_out) );
/* generate a new random salt */
- slapi_rand_array( salt, MD5_DEFAULT_SALT_LENGTH );
+ slapi_rand_array( (void *)salt, MD5_DEFAULT_SALT_LENGTH );
saltval.bv_val = (void*)salt;
saltval.bv_len = MD5_DEFAULT_SALT_LENGTH;
diff --git a/ldap/servers/plugins/replication/legacy_consumer.c b/ldap/servers/plugins/replication/legacy_consumer.c
index 9774527..8a47e80 100644
--- a/ldap/servers/plugins/replication/legacy_consumer.c
+++ b/ldap/servers/plugins/replication/legacy_consumer.c
@@ -83,6 +83,7 @@ static void legacy_consumer_encode_pw (Slapi_Entry *e);
static void set_legacy_purl (Slapi_PBlock *pb, const char *purl);
static int get_legacy_referral (Slapi_Entry *e, char **referral, char **state);
+/* LEGACY_CONSUMER_CONFIG_DN is no need to be normalized. */
#define LEGACY_CONSUMER_CONFIG_DN "cn=legacy consumer," REPL_CONFIG_TOP
#define LEGACY_CONSUMER_FILTER "(objectclass=*)"
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index c6859dd..6be21ce 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -319,8 +319,8 @@ char **agmt_validate_replicated_attributes(Repl_Agmt *ra);
void* agmt_get_priv (const Repl_Agmt *agmt);
void agmt_set_priv (Repl_Agmt *agmt, void* priv);
-
int get_agmt_agreement_type ( Repl_Agmt *agmt);
+int agmt_has_protocol(Repl_Agmt *agmt);
typedef struct replica Replica;
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 13db1ac..f60da02 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2216,13 +2216,21 @@ agmt_get_consumer_rid ( Repl_Agmt *agmt, void *conn )
{
if ( agmt->consumerRID <= 0 ) {
- char mapping_tree_node[512];
+ char *mapping_tree_node = NULL;
struct berval **bvals = NULL;
- PR_snprintf ( mapping_tree_node,
- sizeof (mapping_tree_node),
- "cn=replica,cn=\"%s\",cn=mapping tree,cn=config",
- slapi_sdn_get_dn (agmt->replarea) );
+
+ /* This function converts the old style DN to the new one. */
+ mapping_tree_node =
+ slapi_create_dn_string("cn=replica,cn=\"%s\",cn=mapping tree,cn=config",
+ slapi_sdn_get_dn (agmt->replarea) );
+ if (NULL == mapping_tree_node) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "agmt_get_consumer_rid: failed to normalize "
+ "replica dn for %s\n",
+ slapi_sdn_get_dn (agmt->replarea));
+ agmt->consumerRID = 0;
+ }
conn_read_entry_attribute ( conn, mapping_tree_node, "nsDS5ReplicaID", &bvals );
if ( NULL != bvals && NULL != bvals[0] ) {
char *ridstr = slapi_ch_malloc( bvals[0]->bv_len + 1 );
@@ -2232,6 +2240,7 @@ agmt_get_consumer_rid ( Repl_Agmt *agmt, void *conn )
slapi_ch_free ( (void**) &ridstr );
ber_bvecfree ( bvals );
}
+ slapi_ch_free_string(&mapping_tree_node);
}
return agmt->consumerRID;
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
index 510757b..f9aa610 100644
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
@@ -50,7 +50,8 @@
#include "repl5.h"
#include <plstr.h>
-#define AGMT_CONFIG_BASE "cn=mapping tree, cn=config"
+/* normalized DN */
+#define AGMT_CONFIG_BASE "cn=mapping tree,cn=config"
#define CONFIG_FILTER "(objectclass=nsds5replicationagreement)"
#define WINDOWS_CONFIG_FILTER "(objectclass=nsdsWindowsreplicationagreement)"
#define GLOBAL_CONFIG_FILTER "(|" CONFIG_FILTER WINDOWS_CONFIG_FILTER " )"
diff --git a/ldap/servers/plugins/replication/repl5_protocol.c b/ldap/servers/plugins/replication/repl5_protocol.c
index 31f6072..b1ff730 100644
--- a/ldap/servers/plugins/replication/repl5_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_protocol.c
@@ -173,7 +173,6 @@ void
prot_free(Repl_Protocol **rpp)
{
Repl_Protocol *rp = NULL;
- PRIntervalTime interval;
if (rpp == NULL || *rpp == NULL) return;
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index f669900..0d2f195 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1528,6 +1528,12 @@ _replica_get_config_entry (const Slapi_DN *root)
Slapi_PBlock *pb = NULL;
dn = _replica_get_config_dn (root);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "_replica_get_config_entry: failed to get the config dn for %s\n",
+ slapi_sdn_get_dn (root));
+ return NULL;
+ }
pb = slapi_pblock_new ();
slapi_search_internal_set_pb (pb, dn, LDAP_SCOPE_BASE, "objectclass=*", NULL, 0, NULL,
@@ -1839,8 +1845,9 @@ _replica_get_config_dn (const Slapi_DN *root)
PR_ASSERT (root);
- dn = slapi_ch_smprintf("%s,cn=\"%s\",%s", REPLICA_RDN, slapi_sdn_get_dn (root), mp_base);
-
+ /* This function converts the old style DN to the new style. */
+ dn = slapi_create_dn_string("%s,cn=\"%s\",%s",
+ REPLICA_RDN, slapi_sdn_get_dn (root), mp_base);
return dn;
}
@@ -2162,6 +2169,13 @@ _replica_update_state (time_t when, void *arg)
r->repl_csn_assigned = PR_FALSE;
dn = _replica_get_config_dn (r->repl_root);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "_replica_update_state: failed to get the config dn for %s\n",
+ slapi_sdn_get_dn (r->repl_root));
+ PR_Unlock(r->repl_lock);
+ goto done;
+ }
pb = slapi_pblock_new();
mods[0] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod);
@@ -3057,6 +3071,14 @@ replica_replace_ruv_tombstone(Replica *r)
ruv_last_modified_to_smod ((RUV*)object_get_data(r->repl_ruv), &smod_last_modified);
dn = _replica_get_config_dn (r->repl_root);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name,
+ "replica_replace_ruv_tombstone: "
+ "failed to get the config dn for %s\n",
+ slapi_sdn_get_dn (r->repl_root));
+ PR_Unlock(r->repl_lock);
+ goto bail;
+ }
mods[0] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod);
mods[1] = (LDAPMod*)slapi_mod_get_ldapmod_byref(&smod_last_modified);
@@ -3090,6 +3112,7 @@ replica_replace_ruv_tombstone(Replica *r)
slapi_ch_free ((void**)&dn);
slapi_pblock_destroy (pb);
+bail:
slapi_mod_done (&smod);
slapi_mod_done (&smod_last_modified);
}
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index af5b6cd..1f52a72 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -47,6 +47,7 @@
#include "repl5.h"
#include "cl5_api.h"
+/* CONFIG_BASE: no need to normalize */
#define CONFIG_BASE "cn=mapping tree,cn=config"
#define CONFIG_FILTER "(objectclass=nsDS5Replica)"
#define TASK_ATTR "nsds5Task"
diff --git a/ldap/servers/plugins/replication/repl_init.c b/ldap/servers/plugins/replication/repl_init.c
index 5c89759..5ad17a7 100644
--- a/ldap/servers/plugins/replication/repl_init.c
+++ b/ldap/servers/plugins/replication/repl_init.c
@@ -207,6 +207,7 @@ legacy_entry_init( Slapi_PBlock *pb )
static int
create_config_top()
{
+ /* DN part of this entry_string: no need to be normalize. */
char *entry_string = slapi_ch_strdup("dn: cn=replication,cn=config\nobjectclass: top\nobjectclass: extensibleobject\ncn: replication\n");
Slapi_PBlock *pb = slapi_pblock_new();
Slapi_Entry *e = slapi_str2entry(entry_string, 0);
diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c
index d1a59ed..bb83651 100644
--- a/ldap/servers/plugins/retrocl/retrocl.c
+++ b/ldap/servers/plugins/retrocl/retrocl.c
@@ -263,6 +263,7 @@ char *retrocl_get_config_str(const char *attrt)
int rc = 0;
char *dn;
+ /* RETROCL_PLUGIN_DN is no need to be normalized. */
dn = RETROCL_PLUGIN_DN;
pb = slapi_pblock_new();
diff --git a/ldap/servers/plugins/retrocl/retrocl.h b/ldap/servers/plugins/retrocl/retrocl.h
index e7b65c6..4c67b5b 100644
--- a/ldap/servers/plugins/retrocl/retrocl.h
+++ b/ldap/servers/plugins/retrocl/retrocl.h
@@ -96,7 +96,7 @@ typedef struct _cnumRet {
#define CONFIG_CHANGELOG_DIRECTORY_ATTRIBUTE "nsslapd-changelogdir"
#define RETROCL_CHANGELOG_DN "cn=changelog"
-#define RETROCL_MAPPINGTREE_DN "cn=\"cn=changelog\",cn=mapping tree,cn=config"
+#define RETROCL_MAPPINGTREE_DN "cn=cn\3Dchangelog,cn=mapping tree,cn=config"
#define RETROCL_PLUGIN_DN "cn=Retro Changelog Plugin,cn=plugins,cn=config"
#define RETROCL_LDBM_DN "cn=changelog,cn=ldbm database,cn=plugins,cn=config"
#define RETROCL_INDEX_DN "cn=changenumber,cn=index,cn=changelog,cn=ldbm database,cn=plugins,cn=config"
diff --git a/ldap/servers/plugins/retrocl/retrocl_create.c b/ldap/servers/plugins/retrocl/retrocl_create.c
index 88974b7..bb6521e 100644
--- a/ldap/servers/plugins/retrocl/retrocl_create.c
+++ b/ldap/servers/plugins/retrocl/retrocl_create.c
@@ -77,6 +77,7 @@ static int retrocl_create_be(const char *bedir)
vals[1] = NULL;
e = slapi_entry_alloc();
+ /* RETROCL_LDBM_DN is no need to be normalized. */
slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_LDBM_DN));
/* Set the objectclass attribute */
@@ -142,6 +143,7 @@ static int retrocl_create_be(const char *bedir)
/* we need the changenumber indexed */
e = slapi_entry_alloc();
+ /* RETROCL_INDEX_DN is no need to be normalized. */
slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_INDEX_DN));
/* Set the objectclass attribute */
@@ -219,6 +221,7 @@ int retrocl_create_config(void)
* in the errors file when the referenced backend does not exist.
*/
e = slapi_entry_alloc();
+ /* RETROCL_MAPPINGTREE_DN is no need to be normalized. */
slapi_entry_set_dn(e,slapi_ch_strdup(RETROCL_MAPPINGTREE_DN));
/* Set the objectclass attribute */
diff --git a/ldap/servers/plugins/syntaxes/string.c b/ldap/servers/plugins/syntaxes/string.c
index 9b33833..fc4ca20 100644
--- a/ldap/servers/plugins/syntaxes/string.c
+++ b/ldap/servers/plugins/syntaxes/string.c
@@ -63,6 +63,7 @@ string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax,
{
int i, rc;
struct berval bvfilter_norm;
+ char *alt = NULL;
if(retVal) {
*retVal = NULL;
@@ -74,7 +75,12 @@ string_filter_ava( struct berval *bvfilter, Slapi_Value **bvals, int syntax,
bvfilter_norm.bv_val = slapi_ch_malloc( bvfilter->bv_len + 1 );
SAFEMEMCPY( bvfilter_norm.bv_val, bvfilter->bv_val, bvfilter->bv_len );
bvfilter_norm.bv_val[bvfilter->bv_len] = '\0';
- value_normalize( bvfilter_norm.bv_val, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( bvfilter_norm.bv_val, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&bvfilter_norm.bv_val);
+ bvfilter_norm.bv_val = alt;
+ }
bvfilter_norm.bv_len = strlen(bvfilter_norm.bv_val);
for ( i = 0; (bvals != NULL) && (bvals[i] != NULL); i++ ) {
@@ -211,6 +217,7 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
Operation *op = NULL;
Slapi_Regex *re = NULL;
const char *re_result = NULL;
+ char *alt = NULL;
LDAPDebug( LDAP_DEBUG_FILTER, "=> string_filter_sub\n",
0, 0, 0 );
@@ -260,27 +267,45 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
}
if ( initial != NULL ) {
- value_normalize( initial, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( initial, syntax, 1, &alt );
*p++ = '^';
- filter_strcpy_special_ext( p, initial, FILTER_STRCPY_ESCAPE_RECHARS );
+ if (alt) {
+ filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS );
+ slapi_ch_free_string(&alt);
+ } else {
+ filter_strcpy_special_ext( p, initial, FILTER_STRCPY_ESCAPE_RECHARS );
+ }
p = strchr( p, '\0' );
}
if ( any != NULL ) {
for ( i = 0; any[i] != NULL; i++ ) {
- value_normalize( any[i], syntax, 0 /* DO NOT trim leading blanks */ );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( any[i], syntax, 0, &alt );
/* ".*" + value */
*p++ = '.';
*p++ = '*';
- filter_strcpy_special_ext( p, any[i], FILTER_STRCPY_ESCAPE_RECHARS );
+ if (alt) {
+ filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS );
+ slapi_ch_free_string(&alt);
+ } else {
+ filter_strcpy_special_ext( p, any[i], FILTER_STRCPY_ESCAPE_RECHARS );
+ }
p = strchr( p, '\0' );
}
}
if ( final != NULL ) {
- value_normalize( final, syntax, 0 /* DO NOT trim leading blanks */ );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( final, syntax, 0, &alt );
/* ".*" + value */
*p++ = '.';
*p++ = '*';
- filter_strcpy_special_ext( p, final, FILTER_STRCPY_ESCAPE_RECHARS );
+ if (alt) {
+ filter_strcpy_special_ext( p, alt, FILTER_STRCPY_ESCAPE_RECHARS );
+ slapi_ch_free_string(&alt);
+ } else {
+ filter_strcpy_special_ext( p, final, FILTER_STRCPY_ESCAPE_RECHARS );
+ }
strcat( p, "$" );
}
@@ -327,9 +352,15 @@ string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
strcpy( tmpbuf, bvp->bv_val );
realval = tmpbuf;
}
- value_normalize( realval, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( realval, syntax, 1, &alt );
- tmprc = slapi_re_exec( re, realval, time_up );
+ if (alt) {
+ tmprc = slapi_re_exec( re, alt, time_up );
+ slapi_ch_free_string(&alt);
+ } else {
+ tmprc = slapi_re_exec( re, realval, time_up );
+ }
LDAPDebug( LDAP_DEBUG_TRACE, "re_exec (%s) %i\n",
escape_string( realval, ebuf ), tmprc, 0 );
@@ -359,6 +390,7 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
Slapi_Value **nbvals, **nbvlp;
Slapi_Value **bvlp;
char *w, *c, *p;
+ char *alt = NULL;
if (NULL == ivals) {
return 1;
@@ -380,9 +412,16 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
{
c = slapi_ch_strdup(slapi_value_get_string(*bvlp));
/* if the NORMALIZED flag is set, skip normalizing */
- if (!(slapi_value_get_flags(*bvlp) & SLAPI_ATTR_FLAG_NORMALIZED))
- value_normalize( c, syntax, 1 /* trim leading blanks */ );
- *nbvlp = slapi_value_new_string_passin(c);
+ if (!(slapi_value_get_flags(*bvlp) & SLAPI_ATTR_FLAG_NORMALIZED)) {
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( c, syntax, 1, &alt );
+ }
+ if (alt) {
+ slapi_ch_free_string(&c);
+ *nbvlp = slapi_value_new_string_passin(alt);
+ } else {
+ *nbvlp = slapi_value_new_string_passin(c);
+ }
}
*ivals = nbvals;
break;
@@ -470,14 +509,16 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
for ( bvlp = bvals; bvlp && *bvlp; bvlp++ ) {
/*
* Note: this calculation may err on the high side,
- * because value_normalize(), which is called below
+ * because value_normalize_ext(), which is called below
* before we actually create the substring keys, may
- * reduce the length of the value in some cases. For
- * example, spaces are removed when space insensitive
- * strings are normalized. But it's okay for nsubs to
- * be too big. Since the ivals array is NULL terminated,
- * the only downside is that we allocate more space than
- * we really need.
+ * reduce the length of the value in some cases or
+ * increase the length in other cases. For example,
+ * spaces are removed when space insensitive strings
+ * are normalized. Or if the value includes '\"' (2 bytes),
+ * it's normalized to '\22' (3 bytes). But it's okay
+ * for nsubs to be too big. Since the ivals array is
+ * NULL terminated, the only downside is that we
+ * allocate more space than we really need.
*/
nsubs += slapi_value_get_length(*bvlp) - substrlens[INDEX_SUBSTRMIDDLE] + 3;
}
@@ -489,8 +530,14 @@ string_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
bvdup= slapi_value_new();
for ( bvlp = bvals; bvlp && *bvlp; bvlp++ ) {
c = slapi_ch_strdup(slapi_value_get_string(*bvlp));
- value_normalize( c, syntax, 1 /* trim leading blanks */ );
- slapi_value_set_string_passin(bvdup, c);
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( c, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&c);
+ slapi_value_set_string_passin(bvdup, alt);
+ } else {
+ slapi_value_set_string_passin(bvdup, c);
+ }
bvp = slapi_value_get_berval(bvdup);
@@ -554,6 +601,7 @@ string_assertion2keys_ava(
size_t len;
char *w, *c;
Slapi_Value *tmpval=NULL;
+ char *alt = NULL;
switch ( ftype ) {
case LDAP_FILTER_EQUALITY_FAST:
@@ -565,13 +613,23 @@ string_assertion2keys_ava(
}
memcpy(tmpval->bv.bv_val,slapi_value_get_string(val),len);
tmpval->bv.bv_val[len]='\0';
- value_normalize(tmpval->bv.bv_val, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext(tmpval->bv.bv_val, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&tmpval->bv.bv_val);
+ tmpval->bv.bv_val = alt;
+ }
tmpval->bv.bv_len=strlen(tmpval->bv.bv_val);
break;
case LDAP_FILTER_EQUALITY:
(*ivals) = (Slapi_Value **) slapi_ch_malloc( 2 * sizeof(Slapi_Value *) );
(*ivals)[0] = slapi_value_dup( val );
- value_normalize( (*ivals)[0]->bv.bv_val, syntax, 1 /* trim leading blanks */ );
+ /* 3rd arg: 1 - trim leading blanks */
+ value_normalize_ext( (*ivals)[0]->bv.bv_val, syntax, 1, &alt );
+ if (alt) {
+ slapi_ch_free_string(&(*ivals)[0]->bv.bv_val);
+ (*ivals)[0]->bv.bv_val = alt;
+ }
(*ivals)[0]->bv.bv_len = strlen( (*ivals)[0]->bv.bv_val );
(*ivals)[1] = NULL;
break;
@@ -628,6 +686,10 @@ string_assertion2keys_sub(
int localsublens[3] = {SUBBEGIN, SUBMIDDLE, SUBEND};/* default values */
int maxsublen;
char *comp_buf = NULL;
+ char *altinit = NULL;
+ char **altany = NULL;
+ char *altfinal = NULL;
+ int anysize = 0;
slapi_pblock_get(pb, SLAPI_SYNTAX_SUBSTRLENS, &substrlens);
@@ -650,13 +712,17 @@ string_assertion2keys_sub(
* First figure out how many keys we will return. The answer is based
* on the length of each assertion value. Since normalization may
* reduce the length (such as when spaces are removed from space
- * insensitive strings), we call value_normalize() before checking
+ * insensitive strings), we call value_normalize_ext() before checking
* the length.
*/
nsubs = 0;
if ( initial != NULL ) {
- value_normalize( initial, syntax, 0 /* do not trim leading blanks */ );
- initiallen = strlen( initial );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( initial, syntax, 0, &altinit );
+ if (NULL == altinit) {
+ altinit = initial;
+ }
+ initiallen = strlen( altinit );
if ( initiallen > substrlens[INDEX_SUBSTRBEGIN] - 2 ) {
nsubs += 1; /* for the initial begin string key */
/* the rest of the sub keys are "any" keys for this case */
@@ -664,19 +730,31 @@ string_assertion2keys_sub(
nsubs += initiallen - substrlens[INDEX_SUBSTRMIDDLE] + 1;
}
} else {
- initial = NULL; /* save some work later */
+ altinit = NULL; /* save some work later */
}
}
for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
- value_normalize( any[i], syntax, 0 /* do not trim leading blanks */ );
- len = strlen( any[i] );
+ anysize++;
+ }
+ altany = (char **)slapi_ch_calloc(anysize + 1, sizeof(char *));
+ for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( any[i], syntax, 0, &altany[i] );
+ if (NULL == altany[i]) {
+ altany[i] = any[i];
+ }
+ len = strlen( altany[i] );
if ( len >= substrlens[INDEX_SUBSTRMIDDLE] ) {
nsubs += len - substrlens[INDEX_SUBSTRMIDDLE] + 1;
}
}
if ( final != NULL ) {
- value_normalize( final, syntax, 0 /* do not trim leading blanks */ );
- finallen = strlen( final );
+ /* 3rd arg: 0 - DO NOT trim leading blanks */
+ value_normalize_ext( final, syntax, 0, &altfinal );
+ if (NULL == altfinal) {
+ altfinal = final;
+ }
+ finallen = strlen( altfinal );
if ( finallen > substrlens[INDEX_SUBSTREND] - 2 ) {
nsubs += 1; /* for the final end string key */
/* the rest of the sub keys are "any" keys for this case */
@@ -684,7 +762,7 @@ string_assertion2keys_sub(
nsubs += finallen - substrlens[INDEX_SUBSTRMIDDLE] + 1;
}
} else {
- final = NULL; /* save some work later */
+ altfinal = NULL; /* save some work later */
}
}
if ( nsubs == 0 ) { /* no keys to return */
@@ -703,21 +781,31 @@ string_assertion2keys_sub(
nsubs = 0;
comp_buf = (char *)slapi_ch_malloc(maxsublen + 1);
- if ( initial != NULL ) {
- substring_comp_keys( ivals, &nsubs, initial, initiallen, '^', syntax,
+ if ( altinit != NULL ) {
+ substring_comp_keys( ivals, &nsubs, altinit, initiallen, '^', syntax,
comp_buf, substrlens );
+ if (altinit != initial) {
+ slapi_ch_free_string(&altinit);
+ }
}
- for ( i = 0; any != NULL && any[i] != NULL; i++ ) {
- len = strlen( any[i] );
+ for ( i = 0; altany != NULL && altany[i] != NULL; i++ ) {
+ len = strlen( altany[i] );
if ( len < substrlens[INDEX_SUBSTRMIDDLE] ) {
continue;
}
- substring_comp_keys( ivals, &nsubs, any[i], len, 0, syntax,
+ substring_comp_keys( ivals, &nsubs, altany[i], len, 0, syntax,
comp_buf, substrlens );
+ if (altany[i] != any[i]) {
+ slapi_ch_free_string(&altany[i]);
+ }
}
- if ( final != NULL ) {
- substring_comp_keys( ivals, &nsubs, final, finallen, '$', syntax,
+ slapi_ch_free((void **)&altany);
+ if ( altfinal != NULL ) {
+ substring_comp_keys( ivals, &nsubs, altfinal, finallen, '$', syntax,
comp_buf, substrlens );
+ if (altfinal != final) {
+ slapi_ch_free_string(&final);
+ }
}
(*ivals)[nsubs] = NULL;
slapi_ch_free_string(&comp_buf);
diff --git a/ldap/servers/plugins/syntaxes/syntax.h b/ldap/servers/plugins/syntaxes/syntax.h
index 4007028..bf416d6 100644
--- a/ldap/servers/plugins/syntaxes/syntax.h
+++ b/ldap/servers/plugins/syntaxes/syntax.h
@@ -117,6 +117,7 @@ int string_assertion2keys_ava(Slapi_PBlock *pb,Slapi_Value *val,Slapi_Value ***i
int string_assertion2keys_sub(Slapi_PBlock *pb,char *initial,char **any,char *final,Slapi_Value ***ivals,int syntax);
int value_cmp(struct berval *v1,struct berval *v2,int syntax,int normalize);
void value_normalize(char *s,int syntax,int trim_leading_blanks);
+void value_normalize_ext(char *s,int syntax,int trim_leading_blanks, char **alt);
char *first_word( char *s );
char *next_word( char *s );
diff --git a/ldap/servers/plugins/syntaxes/validate.c b/ldap/servers/plugins/syntaxes/validate.c
index aab6d9c..989137b 100644
--- a/ldap/servers/plugins/syntaxes/validate.c
+++ b/ldap/servers/plugins/syntaxes/validate.c
@@ -362,7 +362,6 @@ int distinguishedname_validate(
{
int rc = 0; /* Assume value is valid */
char *val_copy = NULL;
- int strict = 0;
const char *p = begin;
const char *last = NULL;
@@ -377,17 +376,6 @@ int distinguishedname_validate(
* attributeValue = string / hexstring
*/
- /* Check if we should be performing strict validation. */
- strict = config_get_dn_validate_strict();
- if (!strict) {
- /* Create a normalized copy of the value to use
- * for validation. The original value will be
- * stored in the backend unmodified. */
- val_copy = PL_strndup(begin, end - begin + 1);
- p = val_copy;
- end = slapi_dn_normalize_to_end(val_copy, NULL) - 1;
- }
-
/* Validate one RDN at a time in a loop. */
while (p <= end) {
if ((rc = rdn_validate(p, end, &last)) != 0) {
diff --git a/ldap/servers/plugins/syntaxes/value.c b/ldap/servers/plugins/syntaxes/value.c
index f127b6b..9b048f3 100644
--- a/ldap/servers/plugins/syntaxes/value.c
+++ b/ldap/servers/plugins/syntaxes/value.c
@@ -86,23 +86,40 @@ utf8isspace_fast( char* s )
** Also note that this deviates from rfc 4517 INTEGER syntax, but we must
** support legacy clients for the time being
*/
+/*
+ * alt stores the normalized value in case the normalized value is longer
+ * than the original value. It may happen the value is DN.
+ */
void
-value_normalize(
+value_normalize_ext(
char *s,
int syntax,
- int trim_spaces
+ int trim_spaces,
+ char **alt
)
{
char *head = s;
char *d;
int prevspace, curspace;
+ if (NULL == alt) {
+ return;
+ }
+ *alt = NULL;
+
if ( ! (syntax & SYNTAX_CIS) && ! (syntax & SYNTAX_CES) ) {
return;
}
if ( syntax & SYNTAX_DN ) {
- (void) slapi_dn_normalize_case( s );
+ char *dest = NULL;
+ size_t dlen = 0;
+ int rc = slapi_dn_normalize_case_ext(s, 0, &dest, &dlen);
+ if (rc > 0) {
+ *alt = dest;
+ } else if (rc == 0) { /* normalized in line; not terminated */
+ *(dest + dlen) = '\0';
+ }
return;
}
@@ -203,6 +220,16 @@ value_normalize(
}
}
+void
+value_normalize(
+ char *s,
+ int syntax,
+ int trim_spaces
+)
+{
+ /* deprecated */
+}
+
int
value_cmp(
struct berval *v1,
@@ -220,6 +247,7 @@ value_cmp(
int free_v1 = 0;
int free_v2 = 0;
int v1sign = 1, v2sign = 1; /* default to positive */
+ char *alt = NULL;
/* This code used to call malloc up to four times in the copying
* of attributes to be normalized. Now we attempt to keep everything
@@ -233,13 +261,35 @@ value_cmp(
bvcopy1.bv_val = &little_buffer[buffer_offset];
bvcopy1.bv_val[v1->bv_len] = '\0';
v1 = &bvcopy1;
- buffer_space-= v1->bv_len+1;
- buffer_offset+= v1->bv_len+1;
} else {
v1 = ber_bvdup( v1 );
free_v1 = 1;
}
- value_normalize( v1->bv_val, syntax, 1 /* trim leading blanks */ );
+ value_normalize_ext( v1->bv_val, syntax,
+ 1 /* trim leading blanks */, &alt );
+ if (alt) {
+ if (free_v1) {
+ slapi_ch_free_string(&v1->bv_val);
+ v1->bv_val = alt;
+ v1->bv_len = strlen(alt);
+ } else {
+ if (strlen(alt) < buffer_space) {
+ v1->bv_len = strlen(alt);
+ /* Copying to little_buffer */
+ SAFEMEMCPY(v1->bv_val, alt, v1->bv_len);
+ *(v1->bv_val + v1->bv_len) = '\0';
+ } else {
+ free_v1 = 1;
+ v1 = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+ v1->bv_val = alt;
+ v1->bv_len = strlen(alt);
+ }
+ }
+ }
+ if (!free_v1) {
+ buffer_space -= v1->bv_len + 1;
+ buffer_offset += v1->bv_len + 1;
+ }
}
if ( normalize & 2 ) {
/* Do we have space in the little buffer ? */
@@ -249,13 +299,35 @@ value_cmp(
bvcopy2.bv_val = &little_buffer[buffer_offset];
bvcopy2.bv_val[v2->bv_len] = '\0';
v2 = &bvcopy2;
- buffer_space-= v2->bv_len+1;
- buffer_offset+= v2->bv_len+1;
} else {
v2 = ber_bvdup( v2 );
free_v2 = 1;
}
- value_normalize( v2->bv_val, syntax, 1 /* trim leading blanks */ );
+ value_normalize_ext( v2->bv_val, syntax,
+ 1 /* trim leading blanks */, &alt );
+ if (alt) {
+ if (free_v2) {
+ slapi_ch_free_string(&v2->bv_val);
+ v2->bv_val = alt;
+ v2->bv_len = strlen(alt);
+ } else {
+ if (strlen(alt) < buffer_space) {
+ v2->bv_len = strlen(alt);
+ /* Copying to little_buffer */
+ SAFEMEMCPY(v2->bv_val, alt, v2->bv_len);
+ *(v2->bv_val + v2->bv_len) = '\0';
+ } else {
+ free_v2 = 1;
+ v2 = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+ v2->bv_val = alt;
+ v2->bv_len = strlen(alt);
+ }
+ }
+ }
+ if (!free_v2) {
+ buffer_space -= v2->bv_len + 1;
+ buffer_offset += v2->bv_len + 1;
+ }
}
if (syntax & SYNTAX_INT) {
diff --git a/ldap/servers/plugins/usn/usn_cleanup.c b/ldap/servers/plugins/usn/usn_cleanup.c
index bf13073..1c92a5a 100644
--- a/ldap/servers/plugins/usn/usn_cleanup.c
+++ b/ldap/servers/plugins/usn/usn_cleanup.c
@@ -194,8 +194,15 @@ _usn_cleanup_is_mmr_enabled(const char *suffix)
char *base_dn = NULL;
int rc = 0; /* disabled, by default */
- base_dn = slapi_ch_smprintf("cn=replica,cn=\"%s\",%s",
- suffix, MAPPING_TREE_BASE_DN);
+ /* This function converts the old style DN to the new one */
+ base_dn = slapi_create_dn_string("cn=replica,cn=\"%s\",%s",
+ suffix, MAPPING_TREE_BASE_DN);
+ if (NULL == base_dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM,
+ "_usn_cleanup_is_mmr_enabled: failed to normalize "
+ "mappingtree dn for %s\n", suffix);
+ return 1;
+ }
search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, base_dn, LDAP_SCOPE_ONELEVEL,
"objectclass=nsDS5ReplicationAgreement",
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index 1a1f867..0e7d5c8 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -115,20 +115,47 @@ do_add( Slapi_PBlock *pb )
*/
/* get the name */
{
- char *dn = NULL;
- if ( ber_scanf( ber, "{a", &dn ) == LBER_ERROR ) {
- slapi_ch_free_string(&dn);
- LDAPDebug( LDAP_DEBUG_ANY,
- "ber_scanf failed (op=Add; params=DN)\n", 0, 0, 0 );
+ char *rawdn = NULL;
+ char *dn = NULL;
+ size_t dnlen = 0;
+ if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR ) {
+ slapi_ch_free_string(&rawdn);
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "ber_scanf failed (op=Add; params=DN)\n", 0, 0, 0 );
op_shared_log_error_access (pb, "ADD", "???", "decoding error");
- send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
- "decoding error", 0, NULL );
- return;
- }
- e = slapi_entry_alloc();
- slapi_entry_init(e,dn,NULL); /* Responsibility for DN is passed to the Entry. */
- }
- LDAPDebug( LDAP_DEBUG_ARGS, " do_add: dn (%s)\n", slapi_entry_get_dn_const(e), 0, 0 );
+ send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
+ "decoding error", 0, NULL );
+ return;
+ }
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ } else if (rc > 0) {
+ slapi_ch_free_string(&rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
+ e = slapi_entry_alloc();
+ slapi_entry_init(e,dn,NULL); /* Responsibility for DN is passed to the Entry. */
+ }
+ LDAPDebug( LDAP_DEBUG_ARGS, " do_add: dn (%s)\n", slapi_entry_get_dn_const(e), 0, 0 );
/* get the attrs */
for ( tag = ber_first_element( ber, &len, &last );
diff --git a/ldap/servers/slapd/attrlist.c b/ldap/servers/slapd/attrlist.c
index b200472..9c32990 100644
--- a/ldap/servers/slapd/attrlist.c
+++ b/ldap/servers/slapd/attrlist.c
@@ -289,6 +289,9 @@ int attrlist_replace(Slapi_Attr **alist, const char *type, struct berval **vals)
} else {
attrlist_find_or_create(alist, type, &a);
valuearray_init_bervalarray(vals, &values);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ valuearray_normalize_value(values);
+ }
rc = attr_replace(*a, values);
}
return rc;
@@ -312,6 +315,9 @@ int attrlist_replace_with_flags(Slapi_Attr **alist, const char *type, struct ber
} else {
attrlist_find_or_create(alist, type, &a);
valuearray_init_bervalarray_with_flags(vals, &values, flags);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ valuearray_normalize_value(values);
+ }
rc = attr_replace(*a, values);
}
return rc;
diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c
index e88f4ba..2c5c1a6 100644
--- a/ldap/servers/slapd/attrsyntax.c
+++ b/ldap/servers/slapd/attrsyntax.c
@@ -771,6 +771,23 @@ slapi_attr_get_syntax_oid_copy( const Slapi_Attr *a, char **oidp )
}
}
+int
+slapi_attr_is_dn_syntax_attr(Slapi_Attr *attr)
+{
+ char *syntaxoid = NULL;
+ int dn_syntax = 0; /* not DN, by default */
+
+ if (attr->a_plugin) { /* If not set, there is no way to get the info */
+ slapi_attr_get_syntax_oid_copy(attr, &syntaxoid);
+ if (syntaxoid) {
+ dn_syntax = ((0 == strcmp(syntaxoid, NAMEANDOPTIONALUID_SYNTAX_OID))
+ || (0 == strcmp(syntaxoid, DN_SYNTAX_OID)));
+ slapi_ch_free_string(&syntaxoid);
+ }
+ }
+ return dn_syntax;
+}
+
#ifdef ATTR_LDAP_DEBUG
PRIntn
diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c
index 3a500eb..e483f6e 100644
--- a/ldap/servers/slapd/auth.c
+++ b/ldap/servers/slapd/auth.c
@@ -75,15 +75,33 @@ slapu_msgfree( LDAP* ld, LDAPMessage* msg )
}
static int LDAP_CALL LDAP_CALLBACK
-slapu_search_s( LDAP* ld, const char* baseDN, int scope, const char* filter,
+slapu_search_s( LDAP* ld, const char* rawbaseDN, int scope, const char* filter,
char** attrs, int attrsonly, LDAPMessage** result )
{
int err = LDAP_NO_SUCH_OBJECT;
- Slapi_PBlock* pb;
+ Slapi_PBlock* pb = NULL;
LDAPControl **ctrls;
+ char *baseDN = slapi_ch_strdup(rawbaseDN);
+ char *normDN = NULL;
+ size_t dnlen = 0;
+
+ err = slapi_dn_normalize_ext(baseDN, 0, &normDN, &dnlen);
+ if (err < 0) {
+ err = LDAP_INVALID_DN_SYNTAX;
+ LDAPDebug (LDAP_DEBUG_TRACE, "<= slapu_search_s %i\n", err, 0, 0);
+ return err;
+ } else if (err == 0) { /* baseDN is passed in; not terminated */
+ *(normDN + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&baseDN);
+ baseDN = normDN;
+ }
if (ld != internal_ld) {
- return ldap_search_ext_s (ld, baseDN, scope, filter, attrs, attrsonly, NULL, NULL, NULL, -1, result);
+ err = ldap_search_ext_s(ld, baseDN, scope, filter, attrs, attrsonly,
+ NULL, NULL, NULL, -1, result);
+ slapi_ch_free_string(&baseDN);
+ return err;
}
LDAPDebug (LDAP_DEBUG_TRACE, "=> slapu_search_s (\"%s\", %i, %s)\n",
baseDN, scope, filter);
@@ -120,6 +138,7 @@ slapu_search_s( LDAP* ld, const char* baseDN, int scope, const char* filter,
LDAPDebug (LDAP_DEBUG_ANY, "slapi_search_internal (\"%s\", %i, %s) NULL\n",
escape_string( (char*)baseDN, ebuf ), scope, escape_string( (char*)filter, fbuf ));
}
+ slapi_ch_free_string(&baseDN);
*result = (LDAPMessage*)pb;
LDAPDebug (LDAP_DEBUG_TRACE, "<= slapu_search_s %i\n", err, 0, 0);
return err;
@@ -486,8 +505,8 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
if (err == LDAPU_SUCCESS && chain) {
LDAPMessage* entry = slapu_first_entry (internal_ld, chain);
if (entry) {
+ /* clientDN is duplicated in slapu_get_dn */
clientDN = slapu_get_dn (internal_ld, entry);
- if (clientDN) slapi_dn_normalize (clientDN);
} else {
extraErrorMsg = "no entry";
@@ -507,12 +526,27 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
if (clientDN != NULL) {
char ebuf[ BUFSIZ ];
- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL client bound as %s\n",
- conn->c_connid, escape_string( clientDN, ebuf ));
+ int rc = 0;
+ char *normedDN = NULL;
+ size_t dnlen = 0;
+
+ rc = slapi_dn_normalize_ext(clientDN, 0, &normedDN, &dnlen);
+ if (rc < 0) {
+ /* ignoring the normalization error, use the pre normalized DN */
+ } else if (rc == 0) { /* clientDN is passed in; not terminated */
+ *(normedDN + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&clientDN);
+ clientDN = normedDN;
+ }
+ slapi_log_access (LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " SSL client bound as %s\n",
+ conn->c_connid, escape_string( clientDN, ebuf ));
} else if (clientCert != NULL) {
slapi_log_access (LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL failed to map client certificate to LDAP DN (%s)\n",
- conn->c_connid, extraErrorMsg );
+ "conn=%" NSPRIu64 " SSL failed to map client "
+ "certificate to LDAP DN (%s)\n",
+ conn->c_connid, extraErrorMsg );
}
/*
diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
index 84e935c..333cd73 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -649,8 +649,8 @@ void cache_debug_hash(struct cache *cache, char **out)
u_long slots;
int total_entries, max_entries_per_slot, *slot_stats;
int i, j;
- Hashtable *ht;
- char *name;
+ Hashtable *ht = NULL;
+ char *name = "";
PR_Lock(cache->c_mutex);
*out = (char *)slapi_ch_malloc(1024);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
index 4e2e6cb..c542891 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
@@ -142,13 +142,25 @@ attrcrypt_keymgmt_get_key(ldbm_instance *li, attrcrypt_cipher_state *acs, SECKEY
{
int ret = 0;
Slapi_Entry *entry = NULL;
- char *dn_template = "cn=%s,cn=encrypted attribute keys,cn=%s,cn=ldbm database,cn=plugins,cn=config";
+ char *dn_template = "cn=%s,cn=encrypted attribute keys,cn=%s,cn=%s,cn=plugins,cn=config";
char *instance_name = li->inst_name;
- char *dn_string = NULL;
Slapi_Attr *keyattr = NULL;
+ char *dn_string = NULL;
LDAPDebug(LDAP_DEBUG_TRACE,"-> attrcrypt_keymgmt_get_key\n", 0, 0, 0);
- dn_string = slapi_ch_smprintf(dn_template, acs->ace->cipher_display_name, instance_name);
+ dn_string = slapi_create_dn_string(dn_template,
+ acs->ace->cipher_display_name, instance_name,
+ li->inst_li->li_plugin->plg_name);
+ if (NULL == dn_string) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "attrcrypt_keymgmt_get_key: "
+ "failed create attrcrypt key dn for plugin %s, "
+ "instance %s, cypher %s\n",
+ li->inst_li->li_plugin->plg_name,
+ li->inst_name, acs->ace->cipher_display_name);
+ ret = -1;
+ goto bail;
+ }
/* Fetch the entry */
getConfigEntry(dn_string, &entry);
/* Did we find the entry ? */
@@ -170,6 +182,7 @@ attrcrypt_keymgmt_get_key(ldbm_instance *li, attrcrypt_cipher_state *acs, SECKEY
} else {
ret = -2; /* Means: we didn't find the entry (which happens if the key has never been generated) */
}
+bail:
slapi_ch_free_string(&dn_string);
LDAPDebug(LDAP_DEBUG_TRACE,"<- attrcrypt_keymgmt_get_key\n", 0, 0, 0);
return ret;
@@ -518,6 +531,20 @@ int attrcrypt_check_enable_cipher(attrcrypt_cipher_entry *ace)
return ret;
}
+int
+attrcrypt_cleanup(attrcrypt_cipher_state *acs)
+{
+ LDAPDebug(LDAP_DEBUG_TRACE,"-> attrcrypt_cleanup\n", 0, 0, 0);
+ if (acs->key) {
+ slapd_pk11_FreeSymKey(acs->key);
+ }
+ if (acs->slot) {
+ slapd_pk11_FreeSlot(acs->slot);
+ }
+ LDAPDebug(LDAP_DEBUG_TRACE,"<- attrcrypt_cleanup\n", 0, 0, 0);
+ return 0;
+}
+
/*
* This function cleans up the inst_attrcrypt_state_private in each backend
* instance.
@@ -525,7 +552,6 @@ int attrcrypt_check_enable_cipher(attrcrypt_cipher_entry *ace)
int
attrcrypt_cleanup_private(ldbm_instance *li)
{
- int i = 0;
attrcrypt_cipher_state **current = NULL;
LDAPDebug(LDAP_DEBUG_TRACE, "-> attrcrypt_cleanup_private\n", 0, 0, 0);
@@ -541,20 +567,6 @@ attrcrypt_cleanup_private(ldbm_instance *li)
return 0;
}
-int
-attrcrypt_cleanup(attrcrypt_cipher_state *acs)
-{
- LDAPDebug(LDAP_DEBUG_TRACE,"-> attrcrypt_cleanup\n", 0, 0, 0);
- if (acs->key) {
- slapd_pk11_FreeSymKey(acs->key);
- }
- if (acs->slot) {
- slapd_pk11_FreeSlot(acs->slot);
- }
- LDAPDebug(LDAP_DEBUG_TRACE,"<- attrcrypt_cleanup\n", 0, 0, 0);
- return 0;
-}
-
static attrcrypt_cipher_state *
attrcrypt_get_acs(backend *be, attrcrypt_private *priv)
{
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.c b/ldap/servers/slapd/back-ldbm/ldbm_config.c
index 5aa3669..0e2b390 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.c
@@ -1266,11 +1266,17 @@ void
ldbm_config_read_instance_entries(struct ldbminfo *li, const char *backend_type)
{
Slapi_PBlock *tmp_pb;
- char basedn[BUFSIZ];
Slapi_Entry **entries = NULL;
+ char *basedn = NULL;
/* Construct the base dn of the subtree that holds the instance entries. */
- PR_snprintf(basedn, BUFSIZ, "cn=%s, cn=plugins, cn=config", backend_type);
+ basedn = slapi_create_dn_string("cn=%s,cn=plugins,cn=config", backend_type);
+ if (NULL == basedn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_read_instance_entries: "
+ "failed create backend dn for %s\n", backend_type);
+ return;
+ }
/* Do a search of the subtree containing the instance entries */
tmp_pb = slapi_pblock_new();
@@ -1297,29 +1303,38 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
{
Slapi_PBlock *search_pb;
Slapi_Entry **entries = NULL;
- int res;
- char dn[BUFSIZ];
+ char *dn = NULL;
+ int rval = 0;
/* We try to read the entry
* cn=config, cn=ldbm database, cn=plugins, cn=config. If the entry is
* there, then we process the config information it stores.
*/
- PR_snprintf(dn, BUFSIZ, "cn=config, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=config,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create config dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, dn, LDAP_SCOPE_BASE,
"objectclass=*", NULL, 0, NULL, NULL, li->li_identity, 0);
slapi_search_internal_pb (search_pb);
- slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rval);
- if (LDAP_NO_SUCH_OBJECT == res) {
+ if (LDAP_NO_SUCH_OBJECT == rval) {
/* Add skeleten dse entries for the ldbm plugin */
ldbm_config_add_dse_entries(li, ldbm_skeleton_entries,
li->li_plugin->plg_name, NULL, NULL, 0);
- } else if (res != LDAP_SUCCESS) {
+ } else if (rval != LDAP_SUCCESS) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the ldbm config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
} else {
/* Need to parse the configuration information for the ldbm
* plugin that is held in the DSE. */
@@ -1328,12 +1343,14 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
if (NULL == entries || entries[0] == NULL) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the ldbm config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
if (0 != parse_ldbm_config_entry(li, entries[0], ldbm_config)) {
LDAPDebug(LDAP_DEBUG_ANY, "Error parsing the ldbm config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
}
@@ -1347,8 +1364,6 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
ldbm_config_read_instance_entries(li, li->li_plugin->plg_name);
/* setup the dse callback functions for the ldbm backend config entry */
- PR_snprintf(dn, BUFSIZ, "cn=config, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_config_search_entry_callback,
(void *) li);
@@ -1358,24 +1373,52 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
slapi_config_register_callback(DSE_OPERATION_WRITE, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_config_search_entry_callback,
(void *) li);
+ slapi_ch_free_string(&dn);
/* setup the dse callback functions for the ldbm backend monitor entry */
- PR_snprintf(dn, BUFSIZ, "cn=monitor, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=monitor,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create monitor dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_monitor_search,
(void *)li);
+ slapi_ch_free_string(&dn);
/* And the ldbm backend database monitor entry */
- PR_snprintf(dn, BUFSIZ, "cn=database, cn=monitor, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=database,cn=monitor,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create monitor database dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_dbmonitor_search,
(void *)li);
+ slapi_ch_free_string(&dn);
/* setup the dse callback functions for the ldbm backend instance
* entries */
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=plugins, cn=config", li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_config_load_dse_info: "
+ "failed create plugin dn for %s\n",
+ li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsBackendInstance)",
ldbm_instance_add_instance_entry_callback, (void *) li);
@@ -1388,8 +1431,9 @@ int ldbm_config_load_dse_info(struct ldbminfo *li)
slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsBackendInstance)",
ldbm_instance_post_delete_instance_entry_callback, (void *) li);
-
- return 0;
+bail:
+ slapi_ch_free_string(&dn);
+ return rval;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
index 7df0b89..46abe97 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
@@ -614,6 +614,7 @@ int ldbm_instance_config_add_index_entry(
char tmpIndexesStr[256];
char tmpMatchingRulesStr[1024];
struct ldbminfo *li = inst->inst_li;
+ char *dn = NULL;
if ((argc < 2) || (NULL == argv) || (NULL == argv[0]) ||
(NULL == argv[1])) {
@@ -634,31 +635,42 @@ int ldbm_instance_config_add_index_entry(
{
if('\0' == attrs[i][0]) continue;
basetype = slapi_attr_basetype(attrs[i], NULL, 0);
+ dn = slapi_create_dn_string("cn=%s,cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ basetype, inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_add_index_entry: "
+ "failed create index dn with type %s for plugin %s, "
+ "instance %s\n",
+ basetype, inst->inst_li->li_plugin->plg_name,
+ inst->inst_name);
+ return -1;
+ }
eBuf = PR_smprintf(
- "dn: cn=%s, cn=index, cn=%s, cn=%s, cn=plugins, cn=config\n"
- "objectclass:top\n"
- "objectclass:nsIndex\n"
- "cn:%s\n"
- "nsSystemIndex:%s\n",
- basetype, inst->inst_name, li->li_plugin->plg_name,
- basetype,
+ "dn: %s\n"
+ "objectclass: top\n"
+ "objectclass: nsIndex\n"
+ "cn: %s\n"
+ "nsSystemIndex: %s\n",
+ dn, basetype,
(ldbm_attribute_always_indexed(basetype)?"true":"false"));
+ slapi_ch_free_string(&dn);
for(j=0; indexes[j] != NULL; j++)
{
- eBuf = PR_sprintf_append(eBuf, "nsIndexType:%s\n", indexes[j]);
+ eBuf = PR_sprintf_append(eBuf, "nsIndexType:%s\n", indexes[j]);
}
if((argc>2)&&(argv[2]))
{
for(j=0; matchingRules[j] != NULL; j++)
{
- eBuf = PR_sprintf_append(eBuf, "nsMatchingRule:%s\n", matchingRules[j]);
+ eBuf = PR_sprintf_append(eBuf, "nsMatchingRule:%s\n", matchingRules[j]);
}
}
ldbm_config_add_dse_entry(li, eBuf, flags);
- if (eBuf) {
- PR_smprintf_free(eBuf);
- }
+ if (eBuf) {
+ PR_smprintf_free(eBuf);
+ }
slapi_ch_free((void**)&basetype);
}
@@ -714,10 +726,10 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
Slapi_Value *sval = NULL;
const struct berval *attrValue;
char *argv[ 8 ];
- char basedn[BUFSIZ];
char tmpBuf[MAX_TMPBUF];
char tmpBuf2[MAX_TMPBUF];
int argc;
+ char *basedn = NULL;
struct ldbminfo *li;
@@ -734,8 +746,15 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
strcpy(tmpBuf,"");
/* Construct the base dn of the subtree that holds the default user indexes. */
- PR_snprintf(basedn, BUFSIZ, "cn=default indexes, cn=config, cn=%s, cn=plugins, cn=config",
- li->li_plugin->plg_name);
+ basedn = slapi_create_dn_string("cn=default indexes,cn=config,cn=%s,cn=plugins,cn=config",
+ li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "ldbm_instance_create_default_user_indexes: "
+ "failed create default index dn for plugin %s\n",
+ inst->inst_li->li_plugin->plg_name);
+ return -1;
+ }
/* Do a search of the subtree containing the index entries */
aPb = slapi_pblock_new();
@@ -813,5 +832,6 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
slapi_free_search_results_internal(aPb);
slapi_pblock_destroy(aPb);
+ slapi_ch_free_string(&basedn);
return 0;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
index b4e4473..a826e3c 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c
@@ -311,13 +311,20 @@ read_instance_index_entries(ldbm_instance *inst)
{
Slapi_PBlock *tmp_pb;
int scope = LDAP_SCOPE_SUBTREE;
- char basedn[BUFSIZ];
const char *searchfilter = "(objectclass=nsIndex)";
+ char *basedn = NULL;
/* Construct the base dn of the subtree that holds the index entries
* for this instance. */
- PR_snprintf(basedn, BUFSIZ, "cn=index, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ basedn = slapi_create_dn_string("cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "read_instance_index_entries: "
+ "failed create index dn for plugin %s, instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ return 1;
+ }
/* Set up a tmp callback that will handle the init for each index entry */
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
@@ -336,6 +343,7 @@ read_instance_index_entries(ldbm_instance *inst)
slapi_free_search_results_internal(tmp_pb);
slapi_pblock_destroy(tmp_pb);
+ slapi_ch_free_string(&basedn);
return 0;
}
@@ -347,13 +355,21 @@ read_instance_attrcrypt_entries(ldbm_instance *inst)
{
Slapi_PBlock *tmp_pb;
int scope = LDAP_SCOPE_SUBTREE;
- char basedn[BUFSIZ];
const char *searchfilter = ldbm_instance_attrcrypt_filter;
+ char *basedn = NULL;
/* Construct the base dn of the subtree that holds the index entries
* for this instance. */
- PR_snprintf(basedn, BUFSIZ, "cn=encrypted attributes, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ basedn = slapi_create_dn_string("cn=encrypted attributes,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "read_instance_attrcrypt_entries: "
+ "failed create encrypted attributes dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ return 1;
+ }
/* Set up a tmp callback that will handle the init for each index entry */
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP,
@@ -372,6 +388,7 @@ read_instance_attrcrypt_entries(ldbm_instance *inst)
slapi_free_search_results_internal(tmp_pb);
slapi_pblock_destroy(tmp_pb);
+ slapi_ch_free_string(&basedn);
return 0;
}
@@ -402,10 +419,11 @@ parse_ldbm_instance_config_entry(ldbm_instance *inst, Slapi_Entry *e, config_inf
Slapi_DN suffix;
slapi_attr_first_value(attr, &sval);
+
bval = (struct berval *) slapi_value_get_berval(sval);
slapi_sdn_init_dn_byref(&suffix, bval->bv_val);
if (!slapi_be_issuffix(inst->inst_be, &suffix)) {
- be_addsuffix(inst->inst_be, &suffix);
+ be_addsuffix(inst->inst_be, &suffix);
}
slapi_sdn_done(&suffix);
continue;
@@ -452,25 +470,34 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
struct ldbminfo *li = inst->inst_li;
Slapi_PBlock *search_pb;
Slapi_Entry **entries = NULL;
- int res;
- char dn[BUFSIZ];
+ char *dn = NULL;
+ int rval = 0;
/* We try to read the entry
* cn=instance_name, cn=ldbm database, cn=plugins, cn=config. If the
* entry is there, then we process the config information it stores.
*/
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create instance dn %s for plugin %s\n",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ rval = 1;
+ goto bail;
+ }
search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, dn, LDAP_SCOPE_BASE,
"objectclass=*", NULL, 0, NULL, NULL,
li->li_identity, 0);
slapi_search_internal_pb (search_pb);
- slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rval);
- if (res != LDAP_SUCCESS) {
+ if (rval != LDAP_SUCCESS) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the config DSE\n", 0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
} else {
/* Need to parse the configuration information for the ldbm
* plugin that is held in the DSE. */
@@ -479,13 +506,15 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
if ((!entries) || (!entries[0])) {
LDAPDebug(LDAP_DEBUG_ANY, "Error accessing the config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
if (0 != parse_ldbm_instance_config_entry(inst, entries[0],
ldbm_instance_config)) {
LDAPDebug(LDAP_DEBUG_ANY, "Error parsing the config DSE\n",
0, 0, 0);
- return 1;
+ rval = 1;
+ goto bail;
}
}
@@ -502,8 +531,6 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
inst->inst_name, 0);
/* setup the dse callback functions for the ldbm instance config entry */
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)",
ldbm_instance_search_config_entry_callback, (void *) inst);
@@ -518,9 +545,20 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
ldbm_instance_deny_config, (void *)inst);
/* delete is handled by a callback set in ldbm_config.c */
+ slapi_ch_free_string(&dn);
+
/* don't forget the monitor! */
- PR_snprintf(dn, BUFSIZ, "cn=monitor, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create monitor instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rval = 1;
+ goto bail;
+ }
/* make callback on search; deny add/modify/delete */
slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_monitor_instance_search,
@@ -532,10 +570,20 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_instance_deny_config,
(void *)inst);
/* delete is okay */
+ slapi_ch_free_string(&dn);
/* Callbacks to handle indexes */
- PR_snprintf(dn, BUFSIZ, "cn=index, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create index instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_add_callback, (void *) inst);
@@ -545,10 +593,20 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_modify_callback, (void *) inst);
+ slapi_ch_free_string(&dn);
/* Callbacks to handle attribute encryption */
- PR_snprintf(dn, BUFSIZ, "cn=encrypted attributes, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=encrypted attributes,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_config_load_dse_info: "
+ "failed create encrypted attribute instance dn "
+ "for plugin %s, instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rval = 1;
+ goto bail;
+ }
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, ldbm_instance_attrcrypt_filter,
ldbm_instance_attrcrypt_config_add_callback, (void *) inst);
@@ -558,8 +616,10 @@ ldbm_instance_config_load_dse_info(ldbm_instance *inst)
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, ldbm_instance_attrcrypt_filter,
ldbm_instance_attrcrypt_config_modify_callback, (void *) inst);
-
- return 0;
+ rval = 0;
+bail:
+ slapi_ch_free_string(&dn);
+ return rval;
}
/*
@@ -855,11 +915,19 @@ ldbm_instance_add_instance_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryBe
static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
{
struct ldbminfo *li = inst->inst_li;
- char dn[BUFSIZ];
+ char *dn = NULL;
/* tear down callbacks for the instance config entry */
- PR_snprintf(dn, BUFSIZ, "cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)",
ldbm_instance_search_config_entry_callback);
@@ -872,20 +940,38 @@ static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)",
ldbm_instance_deny_config);
+ slapi_ch_free_string(&dn);
/* now the cn=monitor entry */
- PR_snprintf(dn, BUFSIZ, "cn=monitor, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create monitor instance dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_back_monitor_instance_search);
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=*)", ldbm_instance_deny_config);
slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_BASE, "(objectclass=*)", ldbm_instance_deny_config);
+ slapi_ch_free_string(&dn);
/* now the cn=index entries */
- PR_snprintf(dn, BUFSIZ, "cn=index, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create index dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_add_callback);
@@ -895,10 +981,19 @@ static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=nsIndex)",
ldbm_instance_index_config_modify_callback);
+ slapi_ch_free_string(&dn);
/* now the cn=encrypted attributes entries */
- PR_snprintf(dn, BUFSIZ, "cn=encrypted attributes, cn=%s, cn=%s, cn=plugins, cn=config",
- inst->inst_name, li->li_plugin->plg_name);
+ dn = slapi_create_dn_string("cn=encrypted attributes,cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, li->li_plugin->plg_name);
+ if (NULL == dn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "ldbm_instance_unregister_callbacks: "
+ "failed create encrypted attributes dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ goto bail;
+ }
slapi_config_remove_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, ldbm_instance_attrcrypt_filter,
ldbm_instance_attrcrypt_config_add_callback);
@@ -910,6 +1005,8 @@ static void ldbm_instance_unregister_callbacks(ldbm_instance *inst)
ldbm_instance_attrcrypt_config_modify_callback);
vlv_remove_callbacks(inst);
+bail:
+ slapi_ch_free_string(&dn);
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index ab6278c..c25935d 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -242,6 +242,7 @@ ldbm_back_search( Slapi_PBlock *pb )
dummyAttrs[0] = dummyAttr;
+ /* This dn is no need to be normalized. */
PR_snprintf(dn,sizeof(dn),"dn: oid=%s,cn=features,cn=config",LDAP_CONTROL_VLVREQUEST);
feature= slapi_str2entry(dn,0);
r= plugin_call_acl_plugin (pb, feature, dummyAttrs, NULL, SLAPI_ACL_READ, ACLPLUGIN_ACCESS_DEFAULT, NULL);
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index 423164c..4540c14 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -571,6 +571,7 @@ int ldbm_back_ldif2ldbm( Slapi_PBlock *pb )
if (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) {
/* initialize UniqueID generator - must be done once backends are started
and event queue is initialized but before plugins are started */
+ /* This dn is no need to be normalized. */
Slapi_DN *sdn = slapi_sdn_new_dn_byval ("cn=uniqueid generator,cn=config");
int rc = uniqueIDGenInit (NULL, sdn, 0 /* use single thread mode */);
slapi_sdn_free (&sdn);
diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c
index 8fcb81f..3762215 100644
--- a/ldap/servers/slapd/back-ldbm/misc.c
+++ b/ldap/servers/slapd/back-ldbm/misc.c
@@ -141,7 +141,7 @@ compute_entry_tombstone_dn(const char *entrydn, const char *uniqueid)
PR_ASSERT(NULL != entrydn);
PR_ASSERT(NULL != uniqueid);
- tombstone_dn = slapi_ch_smprintf("%s=%s, %s",
+ tombstone_dn = slapi_ch_smprintf("%s=%s,%s",
SLAPI_ATTR_UNIQUEID,
uniqueid,
entrydn);
diff --git a/ldap/servers/slapd/back-ldbm/nextid.c b/ldap/servers/slapd/back-ldbm/nextid.c
index 6e8f631..02d381b 100644
--- a/ldap/servers/slapd/back-ldbm/nextid.c
+++ b/ldap/servers/slapd/back-ldbm/nextid.c
@@ -214,7 +214,7 @@ get_ids_from_disk(backend *be)
void id_internal_to_stored(ID i,char *b)
{
if ( sizeof(ID) > 4 ) {
- memset (b+4, 0, sizeof(ID)-4);
+ (void)memset (b+4, 0, sizeof(ID)-4);
}
b[0] = (char)(i >> 24);
diff --git a/ldap/servers/slapd/back-ldbm/vlv.c b/ldap/servers/slapd/back-ldbm/vlv.c
index f0ce9e6..847d748 100644
--- a/ldap/servers/slapd/back-ldbm/vlv.c
+++ b/ldap/servers/slapd/back-ldbm/vlv.c
@@ -339,7 +339,7 @@ vlv_init(ldbm_instance *inst)
/* The FE DSE *must* be initialised before we get here */
int return_value= LDAP_SUCCESS;
int scope= LDAP_SCOPE_SUBTREE;
- char *basedn, buf[512];
+ char *basedn = NULL;
const char *searchfilter = "(objectclass=vlvsearch)";
const char *indexfilter = "(objectclass=vlvindex)";
backend *be= inst->inst_be;
@@ -368,9 +368,15 @@ vlv_init(ldbm_instance *inst)
if (inst == NULL) {
basedn = NULL;
} else {
- PR_snprintf(buf, sizeof(buf), "cn=%s,cn=%s,cn=plugins,cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
- basedn = buf;
+ basedn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "vlv_init: failed to create vlv dn for plugin %s, instance %s\n",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ return_value = LDAP_PARAM_ERROR;
+ return return_value;
+ }
}
/* Find the VLV Search Entries */
@@ -405,6 +411,7 @@ vlv_init(ldbm_instance *inst)
slapi_config_register_callback(SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_DeleteIndexEntry,(void*)inst);
slapi_config_register_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,searchfilter,vlv_ModifyRDNSearchEntry,(void*)inst);
slapi_config_register_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_ModifyRDNIndexEntry,(void*)inst);
+ slapi_ch_free_string(&basedn);
}
return return_value;
@@ -417,16 +424,22 @@ vlv_remove_callbacks(ldbm_instance *inst) {
int return_value= LDAP_SUCCESS;
int scope= LDAP_SCOPE_SUBTREE;
- char *basedn, buf[512];
+ char *basedn = NULL;
const char *searchfilter = "(objectclass=vlvsearch)";
const char *indexfilter = "(objectclass=vlvindex)";
if (inst == NULL) {
basedn = NULL;
} else {
- PR_snprintf(buf, sizeof(buf), "cn=%s,cn=%s,cn=plugins,cn=config",
- inst->inst_name, inst->inst_li->li_plugin->plg_name);
- basedn = buf;
+ basedn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "vlv_remove_callbacks: failed to create vlv dn for plugin %s, "
+ "instance %s\n",
+ inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ return_value = LDAP_PARAM_ERROR;
+ }
}
if(basedn!=NULL)
{
@@ -439,8 +452,9 @@ vlv_remove_callbacks(ldbm_instance *inst) {
slapi_config_remove_callback(SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_DeleteIndexEntry);
slapi_config_remove_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,searchfilter,vlv_ModifyRDNSearchEntry);
slapi_config_remove_callback(SLAPI_OPERATION_MODRDN,DSE_FLAG_PREOP,basedn,scope,indexfilter,vlv_ModifyRDNIndexEntry);
+ slapi_ch_free_string(&basedn);
}
- return return_value;
+ return return_value;
}
/* Find an enabled index which matches this description. */
@@ -1972,17 +1986,13 @@ char *create_vlv_search_tag(const char* dn) {
/* Builds strings from Slapi_DN similar console GUI. Uses those dns to
delete vlvsearch's if they match. New write lock.
*/
-
-#define LDBM_PLUGIN_ROOT ", cn=ldbm database, cn=plugins, cn=config"
-#define TAG "cn=by MCC "
-
int vlv_delete_search_entry(Slapi_PBlock *pb, Slapi_Entry* e, ldbm_instance *inst)
{
int rc=0;
Slapi_PBlock *tmppb;
Slapi_DN *newdn;
struct vlvSearch* p=NULL;
- char *buf, *buf2, *tag1, *tag2;
+ char *base1 = NULL, *base2 = NULL, *tag1 = NULL, *tag2 = NULL;
const char *dn= slapi_sdn_get_dn(&e->e_sdn);
backend *be= inst->inst_be;
@@ -1995,8 +2005,18 @@ int vlv_delete_search_entry(Slapi_PBlock *pb, Slapi_Entry* e, ldbm_instance *ins
return LDAP_OPERATIONS_ERROR;
}
tag1=create_vlv_search_tag(dn);
- buf=slapi_ch_smprintf("%s%s%s%s%s","cn=MCC ",tag1,", cn=",inst->inst_name,LDBM_PLUGIN_ROOT);
- newdn=slapi_sdn_new_dn_byval(buf);
+ base1 = slapi_create_dn_string("cn=MCC %s,cn=%s,cn=%s,cn=plugins,cn=config",
+ tag1, inst->inst_name, inst->inst_li->li_plugin->plg_name);
+ if (NULL == base1) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "vlv_delete_search_entry: "
+ "failed to craete vlv search entry dn (rdn: cn=MCC %s) for "
+ "plugin %s, instance %s\n",
+ tag1, inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rc = LDAP_PARAM_ERROR;
+ goto bail;
+ }
+ newdn = slapi_sdn_new_dn_byval(base1);
/* vlvSearchList is modified; need Wlock */
PR_RWLock_Wlock(be->vlvSearchList_lock);
p = vlvSearch_finddn((struct vlvSearch *)be->vlvSearchList, newdn);
@@ -2004,37 +2024,49 @@ int vlv_delete_search_entry(Slapi_PBlock *pb, Slapi_Entry* e, ldbm_instance *ins
{
LDAPDebug( LDAP_DEBUG_ANY, "Deleted Virtual List View Search (%s).\n", p->vlv_name, 0, 0);
tag2=create_vlv_search_tag(dn);
- buf2=slapi_ch_smprintf("%s%s,%s",TAG,tag2,buf);
+ base2 = slapi_create_dn_string("cn=by MCC %s,%s", tag2, base1);
+ if (NULL == base2) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "vlv_delete_search_entry: failed to create "
+ "vlv search entry dn (rdn: cn=by MCC %s) for "
+ "plugin %s, instance %s\n",
+ tag2, inst->inst_li->li_plugin->plg_name, inst->inst_name);
+ rc = LDAP_PARAM_ERROR;
+ slapi_ch_free((void **)&tag2);
+ PR_RWLock_Unlock(be->vlvSearchList_lock);
+ goto bail;
+ }
vlvSearch_removefromlist((struct vlvSearch **)&be->vlvSearchList,p->vlv_dn);
/* This line release lock to prevent recursive deadlock caused by slapi_internal_delete calling vlvDeleteSearchEntry */
PR_RWLock_Unlock(be->vlvSearchList_lock);
vlvSearch_delete(&p);
tmppb = slapi_pblock_new();
- slapi_delete_internal_set_pb(tmppb, buf2, NULL, NULL,
+ slapi_delete_internal_set_pb(tmppb, base2, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
slapi_delete_internal_pb(tmppb);
slapi_pblock_get (tmppb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
if(rc != LDAP_SUCCESS) {
- LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", buf2, 0, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", base2, 0, 0);
}
pblock_done(tmppb);
pblock_init(tmppb);
- slapi_delete_internal_set_pb(tmppb, buf, NULL, NULL,
+ slapi_delete_internal_set_pb(tmppb, base1, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
slapi_delete_internal_pb(tmppb);
slapi_pblock_get (tmppb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
if(rc != LDAP_SUCCESS) {
- LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", buf, 0, 0);
+ LDAPDebug(LDAP_DEBUG_ANY, "vlv_delete_search_entry:can't delete dse entry '%s'\n", base1, 0, 0);
}
slapi_pblock_destroy(tmppb);
slapi_ch_free((void **)&tag2);
- slapi_ch_free((void **)&buf2);
+ slapi_ch_free((void **)&base2);
} else {
PR_RWLock_Unlock(be->vlvSearchList_lock);
}
+bail:
instance_set_not_busy(inst);
slapi_ch_free((void **)&tag1);
- slapi_ch_free((void **)&buf);
+ slapi_ch_free((void **)&base1);
slapi_sdn_free(&newdn);
return rc;
}
diff --git a/ldap/servers/slapd/backend.c b/ldap/servers/slapd/backend.c
index bdf977c..fbb8fca 100644
--- a/ldap/servers/slapd/backend.c
+++ b/ldap/servers/slapd/backend.c
@@ -47,18 +47,32 @@
void
be_init( Slapi_Backend *be, const char *type, const char *name, int isprivate, int logchanges, int sizelimit, int timelimit )
{
- char text[128];
slapdFrontendConfig_t *fecfg;
be->be_suffix = NULL;
be->be_suffixlock= PR_NewLock();
be->be_suffixcount= 0;
/* e.g. dn: cn=config,cn=NetscapeRoot,cn=ldbm database,cn=plugins,cn=config */
- PR_snprintf(text, sizeof(text),"cn=%s,cn=%s,cn=plugins,cn=config", name, type);
- be->be_basedn= slapi_ch_strdup(slapi_dn_normalize(text));
- PR_snprintf(text, sizeof(text), "cn=config,cn=%s,cn=%s,cn=plugins,cn=config", name, type);
- be->be_configdn= slapi_ch_strdup(slapi_dn_normalize(text));
- PR_snprintf(text, sizeof(text), "cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config", name, type);
- be->be_monitordn= slapi_ch_strdup(slapi_dn_normalize(text));
+ be->be_basedn = slapi_create_dn_string("cn=%s,cn=%s,cn=plugins,cn=config",
+ name, type);
+ if (NULL == be->be_basedn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "be_init: failed create instance dn for plugin %s, "
+ "instance %s\n", type, name);
+ }
+ be->be_configdn = slapi_create_dn_string("cn=config,cn=%s,cn=%s,cn=plugins,cn=config",
+ name, type);
+ if (NULL == be->be_configdn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "be_init: failed create instance config dn for "
+ "plugin %s, instance %s\n", type, name);
+ }
+ be->be_monitordn = slapi_create_dn_string("cn=monitor,cn=%s,cn=%s,cn=plugins,cn=config",
+ name, type);
+ if (NULL == be->be_configdn) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "be_init: failed create instance monitor dn for "
+ "plugin %s, instance %s\n", type, name);
+ }
be->be_sizelimit = sizelimit;
be->be_timelimit = timelimit;
/* maximum group nesting level before giving up */
diff --git a/ldap/servers/slapd/backend_manager.c b/ldap/servers/slapd/backend_manager.c
index 1818437..6456f29 100644
--- a/ldap/servers/slapd/backend_manager.c
+++ b/ldap/servers/slapd/backend_manager.c
@@ -423,12 +423,6 @@ be_nbackends_public()
}
/* backend instance management */
-/* JCM - These are hardcoded for the LDBM database */
-#define LDBM_CLASS_PREFIX "cn=ldbm database,cn=plugins,cn=config"
-#define LDBM_CONFIG_ENTRY "cn=config,cn=ldbm database,cn=plugins,cn=config"
-#define INSTANCE_ATTR "nsslapd-instance"
-#define SUFFIX_ATTR "nsslapd-suffix"
-#define CACHE_ATTR "nsslapd-cachememsize"
void
slapi_be_Rlock(Slapi_Backend * be)
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index 4fe4a05..3e02e0c 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -123,6 +123,7 @@ do_bind( Slapi_PBlock *pb )
ber_int_t version = -1;
int auth_response_requested = 0;
int pw_response_requested = 0;
+ char *rawdn = NULL;
char *dn = NULL, *saslmech = NULL;
struct berval cred = {0};
Slapi_Backend *be = NULL;
@@ -136,6 +137,7 @@ do_bind( Slapi_PBlock *pb )
int auto_bind = 0;
int minssf = 0;
char *test_bind_dn = NULL;
+ size_t dnlen = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_bind\n", 0, 0, 0 );
@@ -159,7 +161,7 @@ do_bind( Slapi_PBlock *pb )
* }
*/
- rc = ber_scanf( ber, "{iat", &version, &dn, &method );
+ rc = ber_scanf( ber, "{iat", &version, &rawdn, &method );
if ( rc == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Bind; params=Version,DN,Method)\n",
@@ -167,11 +169,37 @@ do_bind( Slapi_PBlock *pb )
log_bind_access (pb, "???", method, version, saslmech, "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"decoding error", 0, NULL );
- slapi_ch_free_string(&dn);
+ slapi_ch_free_string(&rawdn);
return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "BIND", rawdn?rawdn:"",
+ "strict: invalid bind dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid bind dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "BIND", rawdn?rawdn:"",
+ "invalid bind dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid bind dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ return;
+ } else if (rc > 0) { /* if rc == 0, rawdn is passed in */
+ slapi_ch_free_string(&rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
- slapi_sdn_init_dn_passin(&sdn,dn);
+ slapi_sdn_init_dn_passin(&sdn, dn);
LDAPDebug( LDAP_DEBUG_TRACE, "BIND dn=\"%s\" method=%d version=%d\n",
dn, method, version );
diff --git a/ldap/servers/slapd/compare.c b/ldap/servers/slapd/compare.c
index 5a0256b..578d826 100644
--- a/ldap/servers/slapd/compare.c
+++ b/ldap/servers/slapd/compare.c
@@ -65,7 +65,9 @@ void
do_compare( Slapi_PBlock *pb )
{
BerElement *ber = pb->pb_op->o_ber;
+ char *rawdn = NULL;
char *dn = NULL;
+ size_t len = 0;
struct ava ava = {0};
Slapi_Backend *be = NULL;
int err;
@@ -94,15 +96,40 @@ do_compare( Slapi_PBlock *pb )
* }
*/
- if ( ber_scanf( ber, "{a{ao}}", &dn, &ava.ava_type,
+ if ( ber_scanf( ber, "{a{ao}}", &rawdn, &ava.ava_type,
&ava.ava_value ) == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Compare; params=DN,Type,Value)\n",
0, 0, 0 );
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
- NULL );
+ NULL );
goto free_and_return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "CMP",
+ rawdn?rawdn:"", "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawdn, 0, &dn, &len);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "CMP", rawdn?rawdn:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ } else if (err > 0) { /* if rc == 0, rawdn is passed in */
+ slapi_ch_free((void **) &rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + len) = '\0';
+ }
/*
* in LDAPv3 there can be optional control extensions on
* the end of an LDAPMessage. we need to read them in and
diff --git a/ldap/servers/slapd/delete.c b/ldap/servers/slapd/delete.c
index c17b669..3a80eeb 100644
--- a/ldap/servers/slapd/delete.c
+++ b/ldap/servers/slapd/delete.c
@@ -71,8 +71,10 @@ do_delete( Slapi_PBlock *pb )
{
Slapi_Operation *operation;
BerElement *ber;
+ char *rawdn = NULL;
char *dn = NULL;
- int err;
+ size_t dnlen = 0;
+ int err = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_delete\n", 0, 0, 0 );
@@ -88,7 +90,7 @@ do_delete( Slapi_PBlock *pb )
* DelRequest := DistinguishedName
*/
- if ( ber_scanf( pb->pb_op->o_ber, "a", &dn ) == LBER_ERROR ) {
+ if ( ber_scanf( pb->pb_op->o_ber, "a", &rawdn ) == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Delete; params=DN)\n", 0, 0, 0 );
op_shared_log_error_access (pb, "DEL", "???", "decoding error");
@@ -96,6 +98,31 @@ do_delete( Slapi_PBlock *pb )
NULL );
goto free_and_return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "DEL", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ goto free_and_return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "DEL", "???", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string(&rawdn);
+ goto free_and_return;
+ } else if (err > 0) { /* if err == 0, rawdn is passed in */
+ slapi_ch_free_string(&rawdn);
+ } else { /* err == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
/*
* in LDAPv3 there can be optional control extensions on
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 73eeda1..4a40369 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -57,9 +57,9 @@
static void add_rdn_av( char *avstart, char *avend, int *rdn_av_countp,
struct berval **rdn_avsp, struct berval *avstack );
static void reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp );
-static void sort_rdn_avs( struct berval *avs, int count );
+static void sort_rdn_avs( struct berval *avs, int count, int escape );
static int rdn_av_cmp( struct berval *av1, struct berval *av2 );
-static void rdn_av_swap( struct berval *av1, struct berval *av2 );
+static void rdn_av_swap( struct berval *av1, struct berval *av2, int escape );
int
@@ -77,24 +77,53 @@ hexchar2int( char c )
return( -1 );
}
+#define ISBLANK(c) ((c) == ' ')
+#define ISSPACE(c) (ISBLANK(c) || ((c) == '\n') || ((c) == '\r')) /* XXX 518524 */
+
+#define ISEQUAL(c) ((c) == '=')
+#define ISEQUALSTR(s) \
+ ((*(s) == '3') && ((*((s)+1) == 'd') || (*((s)+1) == 'D')))
+
+#define ISPLUS(c) ((c) == '+')
+#define ISPLUSSTR(s) \
+ ((*(s) == '2') && ((*((s)+1) == 'b') || (*((s)+1) == 'B')))
+
+#define ISESCAPE(c) ((c) == '\\')
+#define ISQUOTE(c) ((c) == '"')
+
#define DNSEPARATOR(c) (((c) == ',') || ((c) == ';'))
-#define SEPARATOR(c) (((c) == ',') || ((c) == ';') || ((c) == '+'))
-#define SPACE(c) (((c) == ' ') || ((c) == '\n')) /* XXX 518524 */
-#define NEEDSESCAPE(c) (((c) == '\\') || ((c) == '"') || ((c) == '+') || \
- ((c) == ',') || ((c) == ';') || ((c) == '<') || ((c) == '>') || ((c) == '='))
-#define LEADNEEDSESCAPE(c) (((c) == ' ') || ((c) == '#') || NEEDSESCAPE(c))
-#if 0 /* not used */
-#define ONLYTRAILNEEDSESCAPE(c) ((c) == ' ')
-#define TRAILNEEDSESCAPE(c) (ONLYTRAILNEEDSESCAPE(c) || NEEDSESCAPE(c))
-#endif
-#define B4TYPE 0
-#define INTYPE 1
-#define B4EQUAL 2
-#define B4VALUE 3
-#define INVALUE 4
-#define INQUOTEDVALUE 5
-#define B4SEPARATOR 6
-#define INVALUE1ST 7
+#define DNSEPARATORSTR(s) \
+ (((*(s) == '2') && ((*((s)+1) == 'c') || (*((s)+1) == 'C'))) || \
+ ((*(s) == '3') && ((*((s)+1) == 'b') || (*((s)+1) == 'B'))))
+
+#define SEPARATOR(c) (DNSEPARATOR(c) || ISPLUS(c))
+#define SEPARATORSTR(s) (DNSEPARATORSTR(s) || ISPLUSSTR(s))
+
+#define NEEDSESCAPE(c) (ISESCAPE(c) || ISQUOTE(c) || SEPARATOR(c) || \
+ ((c) == '<') || ((c) == '>') || ISEQUAL(c))
+#define NEEDSESCAPESTR(s) \
+ (((*(s) == '2') && ((*((s)+1) == '2') || \
+ (*((s)+1) == 'b') || (*((s)+1) == 'B') || \
+ (*((s)+1) == 'c') || (*((s)+1) == 'C'))) || \
+ ((*(s) == '3') && (((*((s)+1) >= 'b') && (*((s)+1) < 'f')) || \
+ ((*((s)+1) >= 'B') && (*((s)+1) < 'F')))) || \
+ ((*(s) == '5') && ((*((s)+1) == 'c') || (*((s)+1) == 'C'))))
+
+#define LEADNEEDSESCAPE(c) (ISBLANK(c) || ((c) == '#') || NEEDSESCAPE(c))
+#define LEADNEEDSESCAPESTR(s) (NEEDSESCAPESTR(s) || \
+ ((*(s) == '2') && (*((s)+1) == '3')))
+
+#define ISCLOSEBRACKET(c) (((c) == ')') || ((c) == ']'))
+
+#define B4TYPE 0
+#define INTYPE 1
+#define B4EQUAL 2
+#define B4VALUE 3
+#define INVALUE 4
+#define INQUOTEDVALUE 5
+#define B4SEPARATOR 6
+#define INVALUE1ST 7
+#define INQUOTEDVALUE1ST 8
#define SLAPI_DNNORM_INITIAL_RDN_AVS 10
#define SLAPI_DNNORM_SMALL_RDN_AV 512
@@ -137,13 +166,13 @@ hexchar2int( char c )
*
* This function does not support UTF-8 multi-byte encoding for attribute
* values, in particular it does not support UTF-8 whitespace. First the
- * SPACE macro above is limited, but also its frequent use of '-1' indexing
+ * ISSPACE macro above is limited, but also its frequent use of '-1' indexing
* into a char[] may hit the middle of a multi-byte UTF-8 whitespace character
* encoding (518524).
*/
char *
-substr_dn_normalize( char *dn, char *end )
+substr_dn_normalize_orig( char *dn, char *end )
{
/* \xx is changed to \c.
* \c is changed to c, unless this would change its meaning.
@@ -166,7 +195,7 @@ substr_dn_normalize( char *dn, char *end )
for ( d = s = dn; s != end; s++ ) {
switch ( state ) {
case B4TYPE:
- if ( ! SPACE( *s ) ) {
+ if ( ! ISSPACE( *s ) ) {
state = INTYPE;
typestart = d;
*d++ = *s;
@@ -176,7 +205,7 @@ substr_dn_normalize( char *dn, char *end )
if ( *s == '=' ) {
state = B4VALUE;
*d++ = *s;
- } else if ( SPACE( *s ) ) {
+ } else if ( ISSPACE( *s ) ) {
state = B4EQUAL;
} else {
*d++ = *s;
@@ -186,13 +215,13 @@ substr_dn_normalize( char *dn, char *end )
if ( *s == '=' ) {
state = B4VALUE;
*d++ = *s;
- } else if ( ! SPACE( *s ) ) {
+ } else if ( ! ISSPACE( *s ) ) {
/* not a valid dn - but what can we do here? */
*d++ = *s;
}
break;
case B4VALUE:
- if ( *s == '"' || ! SPACE( *s ) ) {
+ if ( *s == '"' || ! ISSPACE( *s ) ) {
value_separator = NULL;
value = d;
state = ( *s == '"' ) ? INQUOTEDVALUE : INVALUE1ST;
@@ -223,7 +252,7 @@ substr_dn_normalize( char *dn, char *end )
* be if it does at the end of the RDN value */
/* e.g., ou=ABC \ ,o=XYZ --> ou=ABC \ ,o=XYZ */
if ( lastesc ) {
- while ( SPACE( *(d - 1) ) && d > lastesc ) {
+ while ( ISSPACE( *(d - 1) ) && d > lastesc ) {
d--;
}
if ( d == lastesc ) {
@@ -231,7 +260,7 @@ substr_dn_normalize( char *dn, char *end )
*d++ = ' '; /* escaped trailing space */
}
} else {
- while ( SPACE( *(d - 1) ) ) {
+ while ( ISSPACE( *(d - 1) ) ) {
d--;
}
}
@@ -281,7 +310,7 @@ substr_dn_normalize( char *dn, char *end )
}
if ( *s != '+' ) { /* at end of this RDN */
if ( rdn_av_count > 1 ) {
- sort_rdn_avs( rdn_avs, rdn_av_count );
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
}
if ( rdn_av_count > 0 ) {
reset_rdn_avs( &rdn_avs, &rdn_av_count );
@@ -304,7 +333,7 @@ substr_dn_normalize( char *dn, char *end )
} else if ( *s == '"' ) {
state = B4SEPARATOR;
if ( value_separator == dn /* 2 or more separators */
- || SPACE( value[1] ) || SPACE( d[-1] ) ) {
+ || ISSPACE( value[1] ) || ISSPACE( d[-1] ) ) {
*d++ = *s;
} else {
/* convert to non-quoted value: */
@@ -338,7 +367,7 @@ substr_dn_normalize( char *dn, char *end )
}
if ( *s != '+' ) { /* at end of this RDN */
if ( rdn_av_count > 1 ) {
- sort_rdn_avs( rdn_avs, rdn_av_count );
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
}
if ( rdn_av_count > 0 ) {
reset_rdn_avs( &rdn_avs, &rdn_av_count );
@@ -397,7 +426,7 @@ substr_dn_normalize( char *dn, char *end )
&rdn_avs, initial_rdn_av_stack );
}
if ( rdn_av_count > 1 ) {
- sort_rdn_avs( rdn_avs, rdn_av_count );
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
}
if ( rdn_av_count > 0 ) {
reset_rdn_avs( &rdn_avs, &rdn_av_count );
@@ -408,7 +437,540 @@ substr_dn_normalize( char *dn, char *end )
return( d );
}
+char *
+substr_dn_normalize( char *dn, char *end )
+{
+ /* no op */
+ return end;
+}
+
+/*
+ * 1) Escaped NEEDSESCAPE chars (e.g., ',', '<', '=', etc.) are converted to
+ * ESC HEX HEX (e.g., \2C, \3C, \3D, etc.)
+ * Input could be a string in double quotes
+ * (= old DN format: dn: cn="x=x,y=y",... --> dn: cn=x\3Dx\2Cy\3Dy,...) or
+ * an escaped string
+ * (= new DN format dn: cn=x\=x\,y\=y,... -> dn: cn=x\3Dx\2Cy\3Dy,...)
+ *
+ * 2) All the other ESC HEX HEX are converted to the real characters.
+ *
+ * 3) Spaces around separator ',', ';', and '+' are removed.
+ *
+ * Input:
+ * src: src DN
+ * src_len: length of src; 0 is acceptable if src is NULL terminated.
+ * Output:
+ * dest: address of the converted string; NULL terminated
+ * (could store src address if no need to convert)
+ * dest_len: length of dest
+ *
+ * Return values:
+ * 0: nothing was done; dest is identical to src (src is passed in).
+ * 1: successfully escaped; dest is different from src. src needs to be freed.
+ * -1: failed; dest is NULL; invalid DN
+ */
+int
+slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
+{
+ int rc = -1;
+ int state = B4TYPE;
+ char *s = NULL; /* work pointer for src */
+ char *d = NULL; /* work pointer for dest */
+ char *ends = NULL;
+ char *endd = NULL;
+ char *typestart = NULL;
+ char *subtypestart = NULL; /* used for the nested DN */
+ char *lastesc = NULL;
+ int rdn_av_count = 0;
+ struct berval *rdn_avs = NULL;
+ struct berval initial_rdn_av_stack[ SLAPI_DNNORM_INITIAL_RDN_AVS ];
+ int chkblank = 0;
+
+ if (NULL == dest) {
+ goto bail;
+ }
+ if (NULL == src) {
+ *dest = NULL;
+ *dest_len = 0;
+ goto bail;
+ }
+ if (0 == src_len) {
+ src_len = strlen(src);
+ }
+ s = PL_strnchr(src, '\\', src_len);
+ if (s) {
+ *dest_len = src_len * 3;
+ *dest = slapi_ch_malloc(*dest_len); /* max length */
+ rc = 1;
+ } else {
+ s = PL_strnchr(src, '"', src_len);
+ if (s) {
+ *dest_len = src_len * 3;
+ *dest = slapi_ch_malloc(*dest_len); /* max length */
+ rc = 1;
+ } else {
+ *dest_len = src_len;
+ *dest = src; /* just removing spaces around separators */
+ rc = 0;
+ }
+ }
+
+ ends = src + src_len;
+ endd = *dest + *dest_len;
+ for (s = src, d = *dest; s < ends && d < endd; ) {
+ switch (state) {
+ case B4TYPE: /* before type; cn=... */
+ /* ^ */
+ if (ISSPACE(*s)) {
+ s++; /* skip leading spaces */
+ } else {
+ state = INTYPE;
+ typestart = d;
+ *d++ = *s++;
+ }
+ break;
+ case INTYPE: /* in type; cn=... */
+ /* ^ */
+ if (ISEQUAL(*s)) {
+ state = B4VALUE;
+ *d++ = *s++;
+ } else if (ISCLOSEBRACKET(*s)) { /* special care for ACL macro */
+ state = INVALUE; /* skip a trailing space */
+ *d++ = *s++;
+ } else if (ISSPACE(*s)) {
+ state = B4EQUAL; /* skip a trailing space */
+ } else {
+ *d++ = *s++;
+ }
+ break;
+ case B4EQUAL: /* before equal; cn =... */
+ /* ^ */
+ if (ISEQUAL(*s)) {
+ state = B4VALUE;
+ *d++ = *s++;
+ } else if (ISSPACE(*s)) {
+ s++; /* skip trailing spaces */
+ } else {
+ /* type includes spaces; not a valid dn */
+ rc = -1;
+ goto bail;
+ }
+ break;
+ case B4VALUE: /* before value; cn= ABC */
+ /* ^ */
+ if (ISSPACE(*s)) {
+ s++;
+ } else {
+ if (ISQUOTE(*s)) {
+ s++; /* start with the first char in quotes */
+ state = INQUOTEDVALUE1ST;
+ } else {
+ state = INVALUE1ST;
+ }
+ lastesc = NULL;
+ /* process *s in INVALUE or INQUOTEDVALUE */
+ }
+ break;
+ case INVALUE1ST: /* 1st char in value; cn=ABC */
+ /* ^ */
+ if (ISSPACE(*s)) { /* skip leading spaces */
+ s++;
+ continue;
+ } else if (SEPARATOR(*s)) {
+ /* 1st char in value is separator; invalid dn */
+ rc = -1;
+ goto bail;
+ } /* otherwise, go through */
+ case INVALUE: /* in value; cn=ABC */
+ /* ^ */
+ if (ISESCAPE(*s)) {
+ if (s + 1 >= ends) {
+ /* DN ends with '\'; invalid dn */
+ rc = -1;
+ goto bail;
+ }
+ if (((state == INVALUE1ST) && LEADNEEDSESCAPE(*(s+1))) ||
+ ((state == INVALUE) && NEEDSESCAPE(*(s+1)))) {
+ if (d + 2 >= endd) {
+ /* Not enough space for dest; this never happens! */
+ rc = -1;
+ goto bail;
+ } else {
+ if (ISEQUAL(*(s+1))) {
+ if (NULL == subtypestart) {
+ /* e.g., cn=a\=b\,c\=d */
+ /* ^ */
+ *d = '\0';
+ subtypestart = strrchr(*dest, '=');
+ if (subtypestart) {
+ /* pointing 'a' in the above example */
+ subtypestart++;
+ }
+ /* else
+ * No equal for the nested DN looking value.
+ * Just through it.
+ */
+ }
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATOR(*(s+1))) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ if (chkblank && ISESCAPE(*(d-1)) && ISBLANK(*d)) {
+ /* last space is escaped "cn=A\ ,ou=..." */
+ /* ^ */
+ PR_snprintf(d, 3, "%X", *d); /* hexpair */
+ d += 2;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (subtypestart &&
+ (ISPLUS(*(s+1)) || rdn_av_count > 0)) {
+ add_rdn_av(subtypestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUS(*(s+1))) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 1 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ subtypestart = NULL;
+ }
+ }
+ }
+ /* dn: cn=x\=x\,... -> dn: cn=x\3Dx\2C,... */
+ *d++ = *s++; /* '\\' */
+ PR_snprintf(d, 3, "%X", *s); /* hexpair */
+ d += 2;
+ if (ISPLUS(*s) && PL_strnstr(s, "\\=", ends - s)) {
+ /* next type start of multi values */
+ subtypestart = d;
+ }
+ if (SEPARATOR(*s) || ISEQUAL(*s)) {
+ while (ISSPACE(*(s+1)))
+ s++; /* remove leading spaces */
+ s++;
+ } else {
+ s++;
+ }
+ }
+ } else if (((state == INVALUE1ST) && (s+2 < ends) &&
+ LEADNEEDSESCAPESTR(s+1)) ||
+ ((state == INVALUE) && (s+2 < ends) &&
+ NEEDSESCAPESTR(s+1))) {
+ if (ISEQUALSTR(s+1)) {
+ if (NULL == subtypestart) {
+ /* e.g., cn=a\3Db\2Cc\3Dd */
+ /* ^ */
+ *d = '\0';
+ subtypestart = strrchr(*dest, '=');
+ if (subtypestart) {
+ /* pointing 'a' in the above example */
+ subtypestart++;
+ }
+ /* else
+ * No equal for the nested DN looking value.
+ * Just through it.
+ */
+ }
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATORSTR(s+1)) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) {
+ /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ if (chkblank && ISESCAPE(*(d-1)) && ISBLANK(*d)) {
+ /* last space is escaped "cn=A\ ,ou=..." */
+ /* ^ */
+ PR_snprintf(d, 3, "%X", *d); /* hexpair */
+ d += 2;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (subtypestart &&
+ (ISPLUSSTR(s+1) || rdn_av_count > 0)) {
+ add_rdn_av(subtypestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUSSTR(s+1)) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 1 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ }
+ }
+ }
+ *d++ = *s++; /* '\\' */
+ *d++ = *s++; /* HEX */
+ *d++ = *s++; /* HEX */
+ if (ISPLUSSTR(s-2) && PL_strnstr(s, "\\=", ends - s)) {
+ /* next type start of multi values */
+ subtypestart = d;
+ }
+ if (SEPARATORSTR(s-2) || ISEQUALSTR(s-2)) {
+ while (ISSPACE(*s)) /* remove leading spaces */
+ s++;
+ }
+ } else if (s + 2 < ends &&
+ isxdigit(*(s+1)) && isxdigit(*(s+2))) {
+ /* esc hexpair ==> real character */
+ int n = hexchar2int(*(s+1));
+ int n2 = hexchar2int(*(s+2));
+ n = (n << 4) + n2;
+ if (n == 0) { /* don't change \00 */
+ *d++ = *++s;
+ *d++ = *++s;
+ } else {
+ *d++ = n;
+ s += 3;
+ }
+ } else {
+ /* ignore an escape for now */
+ lastesc = d; /* position of the previous escape */
+ s++;
+ }
+ } else if (SEPARATOR(*s)) { /* cn=ABC , ... */
+ /* ^ */
+ /* handling a trailing escaped space */
+ /* assuming a space is the only an extra character which
+ * is not escaped if it appears in the middle, but should
+ * be if it does at the end of the RDN value */
+ /* e.g., ou=ABC \ ,o=XYZ --> ou=ABC \ ,o=XYZ */
+ if (lastesc) {
+ while (ISSPACE(*(d-1)) && d > lastesc ) {
+ d--;
+ }
+ if (d == lastesc) {
+ /* esc hexpair of space: \20 */
+ *d++ = '\\';
+ *d++ = '2';
+ *d++ = '0';
+ }
+ } else {
+ while (ISSPACE(*(d-1))) {
+ d--;
+ }
+ }
+ state = B4SEPARATOR;
+ break;
+ } else { /* else if (SEPARATOR(*s)) */
+ *d++ = *s++;
+ }
+ if (state == INVALUE1ST) {
+ state = INVALUE;
+ }
+ break;
+ case INQUOTEDVALUE1ST:
+ if (ISSPACE(*s) && (s+1 < ends && ISSPACE(*(s+1)))) {
+ /* skip leading spaces but need to leave one */
+ s++;
+ continue;
+ }
+ subtypestart = d; /* prepare for '+' in the quoted value, if any */
+ case INQUOTEDVALUE:
+ if (ISQUOTE(*s)) {
+ if (ISESCAPE(*(d-1))) { /* the quote is escaped */
+ PR_snprintf(d, 3, "%X", *(s++)); /* hexpair */
+ } else { /* end of INQUOTEVALUE */
+ while (ISSPACE(*(d-1))) { /* eliminate trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ /* We have to keep the last ' ' of a value in quotes.
+ * The same idea as the escaped last space:
+ * "cn=A,ou=B " */
+ /* ^ */
+ if (chkblank && ISBLANK(*d)) {
+ PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
+ d += 3;
+ chkblank = 0;
+ }
+ state = B4SEPARATOR;
+ s++;
+ }
+ } else if (((state == INQUOTEDVALUE1ST) && LEADNEEDSESCAPE(*s)) ||
+ (state == INQUOTEDVALUE && NEEDSESCAPE(*s))) {
+ if (d + 2 >= endd) {
+ /* Not enough space for dest; this never happens! */
+ rc = -1;
+ goto bail;
+ } else {
+ if (ISEQUAL(*s)) {
+ while (ISSPACE(*(d-1))) { /* remove trailing spaces */
+ d--;
+ }
+ } else if (SEPARATOR(*s)) {
+ /* separator is a subset of needsescape */
+ while (ISSPACE(*(d-1))) { /* remove trailing spaces */
+ d--;
+ chkblank = 1;
+ }
+ /* We have to keep the last ' ' of a value in quotes.
+ * The same idea as the escaped last space:
+ * "cn=A\ ,ou=..." */
+ /* ^ */
+ if (chkblank && ISBLANK(*d)) {
+ PR_snprintf(d, 4, "\\%X", *d); /* hexpair */
+ d += 3;
+ chkblank = 0;
+ }
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (ISPLUS(*s) || rdn_av_count > 0) {
+ add_rdn_av(subtypestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUS(*s)) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 1 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ subtypestart = NULL;
+ }
+ }
+ }
+
+ /* dn: cn="x=x,..",... -> dn: cn=x\3Dx\2C,... */
+ *d++ = '\\';
+ PR_snprintf(d, 3, "%X", *s); /* hexpair */
+ d += 2;
+ if (ISPLUS(*s++)) {
+ subtypestart = d; /* next type start of multi values */
+ }
+ if (SEPARATOR(*(s-1)) || ISEQUAL(*(s-1))) {
+ while (ISSPACE(*s)) /* remove leading spaces */
+ s++;
+ }
+ }
+ } else {
+ *d++ = *s++;
+ }
+ if (state == INQUOTEDVALUE1ST) {
+ state = INQUOTEDVALUE;
+ }
+ break;
+ case B4SEPARATOR:
+ if (SEPARATOR(*s)) {
+ state = B4TYPE;
+
+ /*
+ * Track and sort attribute values within
+ * multivalued RDNs.
+ */
+ if (ISPLUS(*s) || rdn_av_count > 0) {
+ add_rdn_av(typestart, d, &rdn_av_count,
+ &rdn_avs, initial_rdn_av_stack);
+ }
+ if (!ISPLUS(*s)) { /* at end of this RDN */
+ if (rdn_av_count > 1) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
+ }
+ if (rdn_av_count > 0) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ }
+ }
+
+ *d++ = (ISPLUS(*s++)) ? '+' : ',';
+ } else {
+ s++;
+ }
+ break;
+ default:
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "slapi_dn_normalize - unknown state %d\n", state, 0, 0 );
+ break;
+ }
+ }
+ /*
+ * Track and sort attribute values within multivalued RDNs.
+ */
+ /* We may still be in an unexpected state, such as B4TYPE if
+ * we encountered something odd like a '+' at the end of the
+ * rdn. If this is the case, we don't want to add this bogus
+ * rdn to our list to sort. We should only be in the INVALUE
+ * or B4SEPARATOR state if we have a valid rdn component to
+ * be added. */
+ if ((rdn_av_count > 0) && ((state == INVALUE1ST) ||
+ (state == INVALUE) || (state == B4SEPARATOR))) {
+ add_rdn_av(typestart, d, &rdn_av_count, &rdn_avs, initial_rdn_av_stack);
+ }
+ if ( rdn_av_count > 1 ) {
+ sort_rdn_avs( rdn_avs, rdn_av_count, 0 );
+ }
+ if ( rdn_av_count > 0 ) {
+ reset_rdn_avs( &rdn_avs, &rdn_av_count );
+ }
+ /* Trim trailing spaces */
+ while (d > *dest && ISBLANK(*(d-1))) {
+ --d; /* XXX 518524 */
+ }
+ *dest_len = d - *dest;
+bail:
+ if (rc < 0) {
+ if (*dest != src) {
+ slapi_ch_free_string(dest);
+ } else {
+ *dest = NULL;
+ }
+ *dest_len = 0;
+ } else if (rc > 0) {
+ /* We terminate the str with NULL only when we allocate the str */
+ *d = '\0';
+ }
+ return rc;
+}
+
+char *
+slapi_create_dn_string(const char *fmt, ...)
+{
+ char *src = NULL;
+ char *dest = NULL;
+ size_t dest_len = 0;
+ va_list ap;
+ int rc = 0;
+
+ if (NULL == fmt) {
+ return NULL;
+ }
+
+ va_start(ap, fmt);
+ src = PR_vsmprintf(fmt, ap);
+ va_end(ap);
+
+ rc = slapi_dn_normalize_ext(src, strlen(src), &dest, &dest_len);
+ if (rc < 0) {
+ slapi_ch_free_string(&src);
+ return NULL;
+ } else if (rc == 0) { /* src is passed in. */
+ *(dest + dest_len) = '\0';
+ } else {
+ slapi_ch_free_string(&src);
+ }
+ return dest;
+}
/*
* Append previous AV to the attribute value array if multivalued RDN.
@@ -418,21 +980,22 @@ substr_dn_normalize( char *dn, char *end )
*/
static void
add_rdn_av( char *avstart, char *avend, int *rdn_av_countp,
- struct berval **rdn_avsp, struct berval *avstack )
+ struct berval **rdn_avsp, struct berval *avstack )
{
if ( *rdn_av_countp == 0 ) {
- *rdn_avsp = avstack;
+ *rdn_avsp = avstack;
} else if ( *rdn_av_countp == SLAPI_DNNORM_INITIAL_RDN_AVS ) {
- struct berval *tmpavs;
+ struct berval *tmpavs;
- tmpavs = (struct berval *)slapi_ch_calloc(
- SLAPI_DNNORM_INITIAL_RDN_AVS * 2, sizeof( struct berval ));
- memcpy( tmpavs, *rdn_avsp,
- SLAPI_DNNORM_INITIAL_RDN_AVS * sizeof( struct berval ));
- *rdn_avsp = tmpavs;
+ tmpavs = (struct berval *)slapi_ch_calloc(
+ SLAPI_DNNORM_INITIAL_RDN_AVS * 2, sizeof( struct berval ));
+ memcpy( tmpavs, *rdn_avsp,
+ SLAPI_DNNORM_INITIAL_RDN_AVS * sizeof( struct berval ));
+ *rdn_avsp = tmpavs;
} else if (( *rdn_av_countp % SLAPI_DNNORM_INITIAL_RDN_AVS ) == 0 ) {
- *rdn_avsp = (struct berval *)slapi_ch_realloc( (char *)*rdn_avsp,
- (*rdn_av_countp + SLAPI_DNNORM_INITIAL_RDN_AVS)*sizeof(struct berval) );
+ *rdn_avsp = (struct berval *)slapi_ch_realloc( (char *)*rdn_avsp,
+ (*rdn_av_countp +
+ SLAPI_DNNORM_INITIAL_RDN_AVS)*sizeof(struct berval) );
}
/*
@@ -453,7 +1016,7 @@ static void
reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp )
{
if ( *rdn_av_countp > SLAPI_DNNORM_INITIAL_RDN_AVS ) {
- slapi_ch_free( (void **)rdn_avsp );
+ slapi_ch_free( (void **)rdn_avsp );
}
*rdn_avsp = NULL;
*rdn_av_countp = 0;
@@ -471,9 +1034,9 @@ reset_rdn_avs( struct berval **rdn_avsp, int *rdn_av_countp )
* Also note that the bv_val's in the "avas" array are not zero-terminated.
*/
static void
-sort_rdn_avs( struct berval *avs, int count )
+sort_rdn_avs( struct berval *avs, int count, int escape )
{
- int i, j, swaps;
+ int i, j, swaps;
/*
* Since we expect there to be a small number of AVs, we use a
@@ -481,16 +1044,16 @@ sort_rdn_avs( struct berval *avs, int count )
* adjacent values anyway.
*/
for ( i = 0; i < count - 1; ++i ) {
- swaps = 0;
- for ( j = 0; j < count - 1; ++j ) {
- if ( rdn_av_cmp( &avs[j], &avs[j+1] ) > 0 ) {
- rdn_av_swap( &avs[j], &avs[j+1] );
- ++swaps;
- }
- }
- if ( swaps == 0 ) {
- break; /* stop early if no swaps made during the last pass */
- }
+ swaps = 0;
+ for ( j = 0; j < count - 1; ++j ) {
+ if ( rdn_av_cmp( &avs[j], &avs[j+1] ) > 0 ) {
+ rdn_av_swap( &avs[j], &avs[j+1], escape );
+ ++swaps;
+ }
+ }
+ if ( swaps == 0 ) {
+ break; /* stop early if no swaps made during the last pass */
+ }
}
}
@@ -501,15 +1064,15 @@ sort_rdn_avs( struct berval *avs, int count )
static int
rdn_av_cmp( struct berval *av1, struct berval *av2 )
{
- int rc;
+ int rc;
rc = strncasecmp( av1->bv_val, av2->bv_val,
- ( av1->bv_len < av2->bv_len ) ? av1->bv_len : av2->bv_len );
+ ( av1->bv_len < av2->bv_len ) ? av1->bv_len : av2->bv_len );
if ( rc == 0 ) {
- return( av1->bv_len - av2->bv_len ); /* longer is greater */
+ return( av1->bv_len - av2->bv_len ); /* longer is greater */
} else {
- return( rc );
+ return( rc );
}
}
@@ -519,12 +1082,12 @@ rdn_av_cmp( struct berval *av1, struct berval *av2 )
* Avoid allocating any heap memory for reasonably small AVs.
*/
static void
-rdn_av_swap( struct berval *av1, struct berval *av2 )
+rdn_av_swap( struct berval *av1, struct berval *av2, int escape )
{
- char *buf1, *buf2;
- char stackbuf1[ SLAPI_DNNORM_SMALL_RDN_AV ];
- char stackbuf2[ SLAPI_DNNORM_SMALL_RDN_AV ];
- int len1, len2;
+ char *buf1, *buf2;
+ char stackbuf1[ SLAPI_DNNORM_SMALL_RDN_AV ];
+ char stackbuf2[ SLAPI_DNNORM_SMALL_RDN_AV ];
+ int len1, len2;
/*
* Copy the two avs into temporary buffers. We use stack-based buffers
@@ -532,16 +1095,16 @@ rdn_av_swap( struct berval *av1, struct berval *av2 )
* large values.
*/
if (( len1 = av1->bv_len ) <= SLAPI_DNNORM_SMALL_RDN_AV ) {
- buf1 = stackbuf1;
+ buf1 = stackbuf1;
} else {
- buf1 = slapi_ch_malloc( len1 );
+ buf1 = slapi_ch_malloc( len1 );
}
memcpy( buf1, av1->bv_val, len1 );
if (( len2 = av2->bv_len ) <= SLAPI_DNNORM_SMALL_RDN_AV ) {
- buf2 = stackbuf2;
+ buf2 = stackbuf2;
} else {
- buf2 = slapi_ch_malloc( len2 );
+ buf2 = slapi_ch_malloc( len2 );
}
memcpy( buf2, av2->bv_val, len2 );
@@ -556,7 +1119,13 @@ rdn_av_swap( struct berval *av1, struct berval *av2 )
* Also reset av2 pointer and length.
*/
av2->bv_val = av1->bv_val + len2;
- *(av2->bv_val)++ = '+';
+ if (escape) {
+ *(av2->bv_val)++ = '\\';
+ PR_snprintf(av2->bv_val, 3, "%X", '+'); /* hexpair */
+ av2->bv_val += 2;
+ } else {
+ *(av2->bv_val)++ = '+';
+ }
memcpy( av2->bv_val, buf1, len1 );
av2->bv_len = len1;
@@ -564,19 +1133,19 @@ rdn_av_swap( struct berval *av1, struct berval *av2 )
* Clean up.
*/
if ( len1 > SLAPI_DNNORM_SMALL_RDN_AV ) {
- slapi_ch_free( (void **)&buf1 );
+ slapi_ch_free( (void **)&buf1 );
}
if ( len2 > SLAPI_DNNORM_SMALL_RDN_AV ) {
- slapi_ch_free( (void **)&buf2 );
+ slapi_ch_free( (void **)&buf2 );
}
}
/*
+ * DEPRECATED: this function does nothing.
* slapi_dn_normalize - put dn into a canonical format. the dn is
* normalized in place, as well as returned.
*/
-
char *
slapi_dn_normalize( char *dn )
{
@@ -586,7 +1155,10 @@ slapi_dn_normalize( char *dn )
return dn;
}
-/* Note that this routine normalizes to the end and doesn't null terminate */
+/*
+ * DEPRECATED: this function does nothing.
+ * Note that this routine normalizes to the end and doesn't null terminate
+ */
char *
slapi_dn_normalize_to_end( char *dn , char *end)
{
@@ -600,13 +1172,28 @@ slapi_dn_normalize_to_end( char *dn , char *end)
char *
slapi_dn_ignore_case( char *dn )
{
- unsigned char *s, *d;
+ unsigned char *s = NULL, *d = NULL;
+ int ssz, dsz;
+ /* normalize case (including UTF-8 multi-byte chars) */
+ for ( s = d = (unsigned char *)dn; s && *s; s += ssz, d += dsz ) {
+ slapi_utf8ToLower( s, d, &ssz, &dsz );
+ }
+ if (d) {
+ *d = '\0'; /* utf8ToLower result may be shorter than the original */
+ }
+ return( dn );
+}
+
+char *
+dn_ignore_case_to_end( char *dn, char *end )
+{
+ unsigned char *s = NULL, *d = NULL;
int ssz, dsz;
/* normalize case (including UTF-8 multi-byte chars) */
- for ( s = d = (unsigned char *)dn; *s; s += ssz, d += dsz ) {
- slapi_utf8ToLower( s, d, &ssz, &dsz );
+ for (s = d = (unsigned char *)dn; s && s < (unsigned char *)end && *s;
+ s += ssz, d += dsz) {
+ slapi_utf8ToLower( s, d, &ssz, &dsz );
}
- *d = '\0'; /* utf8ToLower result may be shorter than the original */
return( dn );
}
@@ -626,6 +1213,47 @@ slapi_dn_normalize_case( char *dn )
return( slapi_dn_ignore_case( dn ));
}
+int
+slapi_dn_normalize_case_ext(char *src, size_t src_len,
+ char **dest, size_t *dest_len)
+{
+ int rc = slapi_dn_normalize_ext(src, src_len, dest, dest_len);
+
+ if (rc >= 0) {
+ dn_ignore_case_to_end(*dest, *dest + *dest_len);
+ }
+ return rc;
+}
+
+char *
+slapi_create_dn_string_case(const char *fmt, ...)
+{
+ char *src = NULL;
+ char *dest = NULL;
+ size_t dest_len = 0;
+ va_list ap;
+ int rc = 0;
+
+ if (NULL == fmt) {
+ return NULL;
+ }
+
+ va_start(ap, fmt);
+ src = PR_vsmprintf(fmt, ap);
+ va_end(ap);
+
+ rc = slapi_dn_normalize_ext(src, strlen(src), &dest, &dest_len);
+ if (rc < 0) {
+ slapi_ch_free_string(&src);
+ } else if (rc == 0) { /* src is passed in. */
+ *(dest + dest_len) = '\0';
+ } else {
+ slapi_ch_free_string(&src);
+ }
+
+ return slapi_dn_ignore_case(dest);
+}
+
/*
* slapi_dn_beparent - return a copy of the dn of dn's parent,
* NULL if the DN is a suffix of the backend.
@@ -952,7 +1580,7 @@ slapi_sdn_init_dn_byref(Slapi_DN *sdn,const char *dn)
{
slapi_sdn_init(sdn);
slapi_sdn_set_dn_byref(sdn,dn);
- return sdn;
+ return sdn;
}
Slapi_DN *
@@ -960,7 +1588,7 @@ slapi_sdn_init_dn_byval(Slapi_DN *sdn,const char *dn)
{
slapi_sdn_init(sdn);
slapi_sdn_set_dn_byval(sdn,dn);
- return sdn;
+ return sdn;
}
Slapi_DN *
@@ -968,23 +1596,23 @@ slapi_sdn_init_dn_passin(Slapi_DN *sdn,const char *dn)
{
slapi_sdn_init(sdn);
slapi_sdn_set_dn_passin(sdn,dn);
- return sdn;
+ return sdn;
}
/* use when dn is normalized previously */
Slapi_DN *
slapi_sdn_init_dn_ndn_byref(Slapi_DN *sdn,const char *dn) {
- slapi_sdn_init(sdn);
- slapi_sdn_set_dn_byref(sdn,dn);
- /* slapi_sdn_set_ndn_byref nulls out dn set in above statement */
- sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_NDN);
- sdn->ndn= dn;
- if(dn == NULL) {
- sdn->ndn_len=0;
- } else {
- sdn->ndn_len=strlen(dn);
- }
- return sdn;
+ slapi_sdn_init(sdn);
+ slapi_sdn_set_dn_byref(sdn,dn);
+ /* slapi_sdn_set_ndn_byref nulls out dn set in above statement */
+ sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_NDN);
+ sdn->ndn= dn;
+ if(dn == NULL) {
+ sdn->ndn_len=0;
+ } else {
+ sdn->ndn_len=strlen(dn);
+ }
+ return sdn;
}
Slapi_DN *
@@ -992,7 +1620,7 @@ slapi_sdn_init_ndn_byref(Slapi_DN *sdn,const char *dn)
{
slapi_sdn_init(sdn);
slapi_sdn_set_ndn_byref(sdn,dn);
- return sdn;
+ return sdn;
}
Slapi_DN *
@@ -1000,7 +1628,7 @@ slapi_sdn_init_ndn_byval(Slapi_DN *sdn,const char *dn)
{
slapi_sdn_init(sdn);
slapi_sdn_set_ndn_byval(sdn,dn);
- return sdn;
+ return sdn;
}
Slapi_DN *
@@ -1106,10 +1734,10 @@ slapi_sdn_set_ndn_byref(Slapi_DN *sdn, const char *ndn)
slapi_sdn_done(sdn);
sdn->flag= slapi_unsetbit_uchar(sdn->flag,FLAG_NDN);
sdn->ndn= ndn;
- if(ndn == NULL) {
- sdn->ndn_len=0;
+ if (ndn) {
+ sdn->ndn_len = strlen(ndn);
} else {
- sdn->ndn_len=strlen(ndn);
+ sdn->ndn_len = 0;
}
return sdn;
}
@@ -1129,10 +1757,7 @@ slapi_sdn_set_rdn(Slapi_DN *sdn, const Slapi_RDN *rdn)
{
/* NewDN= NewRDN + OldParent */
char *parentdn= slapi_dn_parent(sdn->dn);
- char *newdn= slapi_ch_malloc(strlen(rawrdn)+1+strlen(parentdn)+1);
- strcpy( newdn, rawrdn );
- strcat( newdn, "," );
- strcat( newdn, parentdn );
+ char *newdn = slapi_ch_smprintf("%s,%s", rawrdn, parentdn);
slapi_ch_free((void**)&parentdn);
slapi_sdn_set_dn_passin(sdn,newdn);
}
@@ -1264,10 +1889,10 @@ slapi_sdn_get_ndn(const Slapi_DN *sdn)
if(sdn->dn!=NULL)
{
char *p= slapi_ch_strdup(sdn->dn);
- Slapi_DN *ncsdn= (Slapi_DN*)sdn; /* non-const Slapi_DN */
- slapi_dn_normalize_case(p);
+ Slapi_DN *ncsdn= (Slapi_DN*)sdn; /* non-const Slapi_DN */
+ slapi_dn_ignore_case(p); /* dn is normalized; just ignore case */
ncsdn->ndn= p;
- ncsdn->ndn_len=strlen(p);
+ ncsdn->ndn_len=strlen(p);
ncsdn->flag= slapi_setbit_uchar(sdn->flag,FLAG_NDN);
PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_created);
PR_INCREMENT_COUNTER(slapi_sdn_counter_ndn_exist);
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
index 6405e30..17f4199 100644
--- a/ldap/servers/slapd/entry.c
+++ b/ldap/servers/slapd/entry.c
@@ -163,6 +163,11 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
CSN *attributedeletioncsn= NULL; /* Moved to this level so that the JCM csn_free call below gets useful */
CSNSet *valuecsnset= NULL; /* Moved to this level so that the JCM csn_free call below gets useful */
CSN *maxcsn = NULL;
+ char *normdn = NULL;
+ int strict = 0;
+
+ /* Check if we should be performing strict validation. */
+ strict = config_get_dn_validate_strict();
/*
* In string format, an entry looks like this:
@@ -265,16 +270,27 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
if ( slapi_entry_get_dn_const(e)!=NULL )
{
char ebuf[ BUFSIZ ];
- LDAPDebug( LDAP_DEBUG_ANY,
+ LDAPDebug( LDAP_DEBUG_TRACE,
"str2entry_fast: entry has multiple dns \"%s\" and \"%s\" (second ignored)\n",
escape_string( slapi_entry_get_dn_const(e), ebuf ),
escape_string( valuecharptr, ebuf ), 0 );
/* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free((void **) &valuecharptr);
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
if (freetype) slapi_ch_free_string(&type);
continue;
}
- slapi_entry_set_dn(e,slapi_ch_strdup( valuecharptr ));
+ normdn = slapi_create_dn_string("%s", valuecharptr);
+ if (NULL == normdn) {
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
+ "str2entry_fast: Invalid DN: %s\n", valuecharptr);
+ slapi_entry_free( e );
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ return NULL;
+ }
+ /* normdn is consumed in e */
+ slapi_entry_set_dn(e, normdn);
+
/* the memory below was not allocated by the slapi_ch_ functions */
if (retmalloc) slapi_ch_free_string(&valuecharptr);
if (freetype) slapi_ch_free_string(&type);
@@ -285,7 +301,7 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
if ( strcasecmp (type, SLAPI_ATTR_UNIQUEID) == 0 ){
if (e->e_uniqueid != NULL){
- LDAPDebug (LDAP_DEBUG_ANY, "str2entry_fast: entry has multiple "
+ LDAPDebug (LDAP_DEBUG_TRACE, "str2entry_fast: entry has multiple "
"uniqueids %s and %s (second ignored)\n",
e->e_uniqueid, valuecharptr, 0);
}else{
@@ -308,12 +324,7 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
}
{
- Slapi_Value *value= value_new(NULL,CSN_TYPE_NONE,NULL);
- slapi_value_set( value, valuecharptr, valuelen );
- /* the memory below was not allocated by the slapi_ch_ functions */
- if (retmalloc) slapi_ch_free_string(&valuecharptr);
- value->v_csnset= valuecsnset;
- valuecsnset= NULL;
+ Slapi_Value *value = NULL;
if(a==NULL)
{
switch(attr_state)
@@ -343,9 +354,51 @@ str2entry_fast( char *s, int flags, int read_stateinfo )
continue;
/* break; ??? */
}
-
+ }
+ /* moved the value setting code here to check Slapi_Attr 'a'
+ * to retrieve the attribute syntax info */
+ value = value_new(NULL, CSN_TYPE_NONE, NULL);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ int rc = 0;
+ char *dn_aval = NULL;
+ size_t dnlen = 0;
+ if (strict) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(NULL, valuecharptr, 1);
+ if (rc) { /* syntax check failed */
+ LDAPDebug2Args(LDAP_DEBUG_TRACE,
+ "str2entry_fast: strict: Invalid DN value: %s: %s\n",
+ type, valuecharptr);
+ slapi_entry_free( e );
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ return NULL;
+ }
+ }
+ rc = slapi_dn_normalize_ext(valuecharptr, 0, &dn_aval, &dnlen);
+ if (rc < 0) {
+ /* Give up normalizing the attribute value */
+ LDAPDebug2Args(LDAP_DEBUG_TRACE,
+ "str2entry_fast: Invalid DN value: %s: %s\n",
+ type, valuecharptr);
+ dn_aval = valuecharptr;
+ dnlen = valuelen;
+ }
+ slapi_value_set(value, dn_aval, dnlen);
+ if (rc > 0) { /* if rc == 0, valuecharptr is passed in */
+ slapi_ch_free_string(&dn_aval);
+ } else if (rc == 0) { /* rc == 0; valuecharptr is passed in;
+ not null terminated */
+ *(dn_aval + dnlen) = '\0';
+ }
+ } else {
+ slapi_value_set(value, valuecharptr, valuelen);
}
if (freetype) slapi_ch_free_string(&type); /* don't need type anymore */
+ /* the memory below was not allocated by the slapi_ch_ functions */
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ value->v_csnset = valuecsnset;
+ valuecsnset = NULL;
{
const CSN *distinguishedcsn= csnset_get_csn_of_type(value->v_csnset,CSN_TYPE_VALUE_DISTINGUISHED);
if(distinguishedcsn!=NULL)
@@ -444,6 +497,7 @@ typedef struct _str2entry_attr {
value_compare_fn_type sa_comparefn;
Avlnode *sa_vtree;
CSN *sa_attributedeletioncsn;
+ Slapi_Attr sa_attr;
} str2entry_attr;
static void
@@ -458,6 +512,7 @@ entry_attr_init(str2entry_attr *sa, const char *type, int state)
sa->sa_comparefn = NULL;
sa->sa_vtree= NULL;
sa->sa_attributedeletioncsn= NULL;
+ slapi_attr_init(&sa->sa_attr, type);
}
/*
@@ -599,6 +654,10 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
( 0 != ( flags & SLAPI_STR2ENTRY_REMOVEDUPVALS ));
Slapi_Value *value = 0;
CSN *maxcsn= NULL;
+ int strict = 0;
+
+ /* Check if we should be performing strict validation. */
+ strict = config_get_dn_validate_strict();
LDAPDebug( LDAP_DEBUG_TRACE, "=> str2entry_dupcheck\n", 0, 0, 0 );
@@ -630,7 +689,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( (retmalloc = ldif_parse_line( s, &type, &valuecharptr, &valuelen )) < 0 ) {
LDAPDebug( LDAP_DEBUG_TRACE,
- "<= slapi_str2entry NULL (parse_line)\n", 0, 0, 0 );
+ "<= str2entry_dupcheck NULL (parse_line)\n", 0, 0, 0 );
continue;
}
#if defined(USE_OPENLDAP)
@@ -663,10 +722,11 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
}
if ( strcasecmp( type, "dn" ) == 0 ) {
+ char *normdn = NULL;
if ( slapi_entry_get_dn_const(e)!=NULL ) {
char ebuf[ BUFSIZ ];
- LDAPDebug( LDAP_DEBUG_ANY,
- "slapi_str2entry: entry has multiple dns \"%s\" and \"%s\" (second ignored)\n",
+ LDAPDebug( LDAP_DEBUG_TRACE,
+ "str2entry_dupcheck: entry has multiple dns \"%s\" and \"%s\" (second ignored)\n",
escape_string( slapi_entry_get_dn_const(e), ebuf ),
escape_string( valuecharptr, ebuf ), 0 );
/* the memory below was not allocated by the slapi_ch_ functions */
@@ -674,7 +734,17 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if (freetype) slapi_ch_free_string(&type);
continue;
}
- slapi_entry_set_dn(e,slapi_ch_strdup( valuecharptr ));
+ normdn = slapi_create_dn_string("%s", valuecharptr);
+ if (NULL == normdn) {
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
+ "str2entry_dupcheck: Invalid DN: %s\n", valuecharptr);
+ slapi_entry_free( e ); e = NULL;
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ goto free_and_return;
+ }
+ /* normdn is consumed in e */
+ slapi_entry_set_dn(e, normdn);
/* the memory below was not allocated by the slapi_ch_ functions */
if (retmalloc) slapi_ch_free_string(&valuecharptr);
if (freetype) slapi_ch_free_string(&type);
@@ -685,7 +755,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( strcasecmp (type, SLAPI_ATTR_UNIQUEID) == 0 ){
if (e->e_uniqueid != NULL){
- LDAPDebug (LDAP_DEBUG_ANY, "slapi_str2entry: entry has multiple "
+ LDAPDebug (LDAP_DEBUG_TRACE, "str2entry_dupcheck: entry has multiple "
"uniqueids %s and %s (second ignored)\n",
e->e_uniqueid, valuecharptr, 0);
}else{
@@ -787,7 +857,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( slapi_attr_type2plugin( type,(void **)&(attrs[nattrs].sa_pi) ) != 0 )
{
LDAPDebug( LDAP_DEBUG_ANY,
- "<= slapi_str2entry NULL (slapi_attr_type2plugin)\n",
+ "<= str2entry_dupcheck NULL (slapi_attr_type2plugin)\n",
0, 0, 0 );
slapi_entry_free( e ); e = NULL;
if (retmalloc) slapi_ch_free_string(&valuecharptr);
@@ -818,10 +888,44 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
nattrs++;
}
- if (freetype) slapi_ch_free_string(&type);
sa = prev_attr; /* For readability */
- value= value_new(NULL,CSN_TYPE_NONE,NULL);
- slapi_value_set( value, valuecharptr, valuelen );
+ value= value_new(NULL, CSN_TYPE_NONE, NULL);
+ if (slapi_attr_is_dn_syntax_attr(&(sa->sa_attr))) {
+ char *dn_aval = NULL;
+ size_t dnlen = 0;
+ if (strict) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(NULL, valuecharptr, 1);
+ if (rc) { /* syntax check failed */
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "str2entry_dupcheck: strict: Invalid DN value: %s: %s\n",
+ type, valuecharptr);
+ slapi_entry_free( e ); e = NULL;
+ if (retmalloc) slapi_ch_free_string(&valuecharptr);
+ if (freetype) slapi_ch_free_string(&type);
+ goto free_and_return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(valuecharptr, 0, &dn_aval, &dnlen);
+ if (rc < 0) {
+ /* Give up normalizing the attribute value */
+ LDAPDebug2Args(LDAP_DEBUG_TRACE,
+ "str2entry_dupcheck: Invalid DN value: %s: %s\n",
+ type, valuecharptr);
+ dn_aval = valuecharptr;
+ dnlen = valuelen;
+ }
+ slapi_value_set(value, dn_aval, dnlen);
+ if (rc > 0) { /* if rc == 0, valuecharptr is passed in */
+ slapi_ch_free_string(&dn_aval);
+ } else if (rc == 0) { /* rc == 0; valuecharptr is passed in;
+ not null terminated */
+ *(dn_aval + dnlen) = '\0';
+ }
+ } else {
+ slapi_value_set(value, valuecharptr, valuelen);
+ }
+ if (freetype) slapi_ch_free_string(&type);
/* the memory below was not allocated by the slapi_ch_ functions */
if (retmalloc) slapi_ch_free_string(&valuecharptr);
value->v_csnset= valuecsnset;
@@ -911,7 +1015,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
else
{
/* Failure adding to value tree */
- LDAPDebug( LDAP_DEBUG_ANY, "slapi_str2entry: unexpected failure %d constructing value tree\n", rc, 0, 0 );
+ LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: unexpected failure %d constructing value tree\n", rc, 0, 0 );
slapi_entry_free( e ); e = NULL;
goto free_and_return;
}
@@ -924,7 +1028,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( slapi_entry_get_dn_const(e)==NULL )
{
if (!(SLAPI_STR2ENTRY_INCLUDE_VERSION_STR & flags))
- LDAPDebug( LDAP_DEBUG_ANY, "slapi_str2entry: entry has no dn\n",
+ LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: entry has no dn\n",
0, 0, 0 );
slapi_entry_free( e ); e = NULL;
goto free_and_return;
@@ -945,11 +1049,11 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( sa->sa_numdups > 0 )
{
if ( sa->sa_numdups > 1 ) {
- LDAPDebug( LDAP_DEBUG_ANY, "%d duplicate values for attribute "
+ LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: %d duplicate values for attribute "
"type %s detected in entry %s. Extra values ignored.\n",
sa->sa_numdups, sa->sa_type, slapi_entry_get_dn_const(e) );
} else {
- LDAPDebug( LDAP_DEBUG_ANY, "Duplicate value for attribute "
+ LDAPDebug( LDAP_DEBUG_ANY, "str2entry_dupcheck: Duplicate value for attribute "
"type %s detected in entry %s. Extra value ignored.\n",
sa->sa_type, slapi_entry_get_dn_const(e), 0 );
}
@@ -1014,7 +1118,7 @@ str2entry_dupcheck( char *s, int flags, int read_stateinfo )
if ( flags & SLAPI_STR2ENTRY_ADDRDNVALS ) {
if ( slapi_entry_add_rdn_values( e ) != LDAP_SUCCESS ) {
LDAPDebug( LDAP_DEBUG_TRACE,
- "slapi_str2entry: entry has badly formatted dn\n",
+ "str2entry_dupcheck: entry has badly formatted dn\n",
0, 0, 0 );
slapi_entry_free( e ); e = NULL;
goto free_and_return;
@@ -1033,6 +1137,7 @@ free_and_return:
valuearrayfast_done(&attrs[ i ].sa_present_values);
valuearrayfast_done(&attrs[ i ].sa_deleted_values);
valuetree_free( &attrs[ i ].sa_vtree );
+ attr_done( &attrs[ i ].sa_attr );
}
if (tree_attr_checking)
{
@@ -1555,8 +1660,12 @@ static size_t slapi_dn_size(Slapi_DN *sdn)
if (sdn == NULL) return 0;
- if (sdn->dn) size += strlen(sdn->dn) + 1;
- if (sdn->ndn) size *= 2;
+ if (slapi_sdn_get_dn(sdn)) {
+ size += strlen(slapi_sdn_get_dn(sdn)) + 1;
+ }
+ if (slapi_sdn_get_ndn(sdn)) {
+ size += strlen(slapi_sdn_get_ndn(sdn)) + 1;
+ }
return size;
}
@@ -2624,14 +2733,15 @@ slapi_entry_apply_mods( Slapi_Entry *e, LDAPMod **mods )
int
entry_apply_mods( Slapi_Entry *e, LDAPMod **mods )
{
- int err, j;
+ int err;
+ LDAPMod **mp = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "=> entry_apply_mods\n", 0, 0, 0 );
err = LDAP_SUCCESS;
- for ( j = 0; mods[j] != NULL; j++ )
+ for ( mp = mods; mp && *mp; mp++ )
{
- err= entry_apply_mod( e, mods[j] );
+ err= entry_apply_mod( e, *mp );
if ( err != LDAP_SUCCESS ) {
break;
}
@@ -2663,7 +2773,7 @@ entry_apply_mod( Slapi_Entry *e, const LDAPMod *mod )
case LDAP_MOD_ADD:
LDAPDebug( LDAP_DEBUG_ARGS, " add: %s\n", mod->mod_type, 0, 0 );
if(sawsubentry) e->e_flags |= SLAPI_ENTRY_LDAPSUBENTRY;
- err = slapi_entry_add_values( e, mod->mod_type, mod->mod_bvalues );
+ err = slapi_entry_add_values( e, mod->mod_type, mod->mod_bvalues );
break;
case LDAP_MOD_DELETE:
@@ -2721,6 +2831,9 @@ slapi_entry_add_values_sv(Slapi_Entry *e,
Slapi_Attr **a= NULL;
Slapi_Attr **alist= &e->e_attrs;
attrlist_find_or_create(alist, type, &a);
+ if (slapi_attr_is_dn_syntax_attr(*a)) {
+ valuearray_normalize_value(vals);
+ }
rc= attr_add_valuearray(*a,vals,slapi_entry_get_dn_const(e));
}
return( rc );
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
index 6b51ef1..01c160c 100644
--- a/ldap/servers/slapd/entrywsi.c
+++ b/ldap/servers/slapd/entrywsi.c
@@ -450,6 +450,10 @@ entry_add_present_values_wsi(Slapi_Entry *e, const char *type, struct berval **b
}
a_flags_orig = a->a_flags;
a->a_flags |= flags;
+ /* Check if the type of the to-be-added values has DN syntax or not. */
+ if (slapi_attr_is_dn_syntax_attr(a)) {
+ valuearray_normalize_value(valuestoadd);
+ }
if(urp)
{
/*
@@ -566,6 +570,11 @@ entry_delete_present_values_wsi(Slapi_Entry *e, const char *type, struct berval
/* delete some specific values */
Slapi_Value **valuestodelete= NULL;
valuearray_init_bervalarray(vals,&valuestodelete); /* JCM SLOW FUNCTION */
+ /* Check if the type of the to-be-deleted values has DN syntax
+ * or not. */
+ if (slapi_attr_is_dn_syntax_attr(a)) {
+ valuearray_normalize_value(valuestodelete);
+ }
if(urp)
{
Slapi_Value **valuesupdated= NULL;
diff --git a/ldap/servers/slapd/extendop.c b/ldap/servers/slapd/extendop.c
index 003c2ab..a521cb7 100644
--- a/ldap/servers/slapd/extendop.c
+++ b/ldap/servers/slapd/extendop.c
@@ -53,7 +53,9 @@ static const char *extended_op_oid2string( const char *oid );
static void extop_handle_import_start(Slapi_PBlock *pb, char *extoid,
struct berval *extval)
{
- char *suffix;
+ char *orig = NULL;
+ char *suffix = NULL;
+ size_t dnlen = 0;
Slapi_DN *sdn = NULL;
Slapi_Backend *be = NULL;
struct berval bv;
@@ -66,10 +68,34 @@ static void extop_handle_import_start(Slapi_PBlock *pb, char *extoid,
"no data supplied", 0, NULL);
return;
}
- suffix = slapi_ch_malloc(extval->bv_len+1);
- strncpy(suffix, extval->bv_val, extval->bv_len);
- suffix[extval->bv_len] = 0;
-
+ orig = slapi_ch_malloc(extval->bv_len+1);
+ strncpy(orig, extval->bv_val, extval->bv_len);
+ orig[extval->bv_len] = 0;
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ ret = slapi_dn_syntax_check(pb, orig, 1);
+ if (ret) { /* syntax check failed */
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "extop_handle_import_start: strict: invalid suffix\n",
+ orig);
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
+ "invalid suffix", 0, NULL);
+ return;
+ }
+ }
+ ret = slapi_dn_normalize_ext(orig, 0, &suffix, &dnlen);
+ if (ret < 0) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "extop_handle_import_start: invalid suffix\n", orig);
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
+ "invalid suffix", 0, NULL);
+ return;
+ } else if (ret > 0) {
+ slapi_ch_free_string(&orig);
+ } else { /* ret == 0; orig is passed in; not null terminated */
+ *(suffix + dnlen) = '\0';
+ }
sdn = slapi_sdn_new_dn_byval(suffix);
if (!sdn) {
LDAPDebug(LDAP_DEBUG_ANY,
@@ -109,6 +135,7 @@ static void extop_handle_import_start(Slapi_PBlock *pb, char *extoid,
/* slapi_str2entry modify its dn parameter so we must copy
* this string each time we call it !
*/
+ /* This dn is no need to be normalized. */
PR_snprintf(dn, sizeof(dn), "dn: oid=%s,cn=features,cn=config",
EXTOP_BULK_IMPORT_START_OID);
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
index 0439007..642b6af 100644
--- a/ldap/servers/slapd/fedse.c
+++ b/ldap/servers/slapd/fedse.c
@@ -76,6 +76,7 @@
extern char ** getSupportedCiphers();
+/* Note: These DNs are no need to be normalized */
static const char *internal_entries[] =
{
"dn:\n"
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 9295861..b8e26d1 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -870,7 +870,8 @@ FrontendConfig_init () {
cfg->ldapi_map_entries = LDAP_OFF;
cfg->ldapi_uidnumber_type = slapi_ch_strdup("uidNumber");
cfg->ldapi_gidnumber_type = slapi_ch_strdup("gidNumber");
- cfg->ldapi_search_base_dn = slapi_ch_strdup("dc=example, dc=com");
+ /* These DNs are no need to be normalized. */
+ cfg->ldapi_search_base_dn = slapi_ch_strdup("dc=example,dc=com");
#if defined(ENABLE_AUTO_DN_SUFFIX)
cfg->ldapi_auto_dn_suffix = slapi_ch_strdup("cn=peercred,cn=external,cn=auth");
#endif
@@ -5796,9 +5797,9 @@ config_set_entry(Slapi_Entry *e)
if (needs_free && value) { /* assumes memory allocated by slapi_ch_Xalloc */
if (CONFIG_CHARRAY == cgas->config_var_type) {
- charray_free(*((char ***)value));
+ charray_free((char **)*value);
} else if (CONFIG_SPECIAL_REFERRALLIST == cgas->config_var_type) {
- ber_bvecfree(*((struct berval ***)value));
+ ber_bvecfree((struct berval **)*value);
} else if ((CONFIG_CONSTANT_INT != cgas->config_var_type) && /* do not free constants */
(CONFIG_CONSTANT_STRING != cgas->config_var_type)) {
slapi_ch_free(value);
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
index f92c845..67be790 100644
--- a/ldap/servers/slapd/main.c
+++ b/ldap/servers/slapd/main.c
@@ -1107,6 +1107,7 @@ main( int argc, char **argv)
/* initialize UniqueID generator - must be done once backends are started
and event queue is initialized but before plugins are started */
+ /* Note: This DN is no need to be normalized. */
sdn = slapi_sdn_new_dn_byval ("cn=uniqueid generator,cn=config");
rc = uniqueIDGenInit (NULL, sdn, slapd_exemode == SLAPD_EXEMODE_SLAPD);
slapi_sdn_free (&sdn);
@@ -1906,6 +1907,7 @@ lookup_instance_name_by_suffix(char *suffix,
if (query == NULL)
goto done;
+ /* Note: This DN is no need to be normalized. */
slapi_search_internal_set_pb(pb, "cn=mapping tree,cn=config",
LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
@@ -1926,6 +1928,7 @@ lookup_instance_name_by_suffix(char *suffix,
query = slapi_ch_smprintf("(&(objectclass=nsmappingtree)(|(cn=*%s\")(cn=*%s)))", suffixp, suffixp);
if (query == NULL)
goto done;
+ /* Note: This DN is no need to be normalized. */
slapi_search_internal_set_pb(pb, "cn=mapping tree,cn=config",
LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
@@ -2013,6 +2016,7 @@ static struct slapdplugin *lookup_plugin_by_instance_name(const char *name)
return NULL;
}
+ /* Note: This DN is no need to be normalized. */
slapi_search_internal_set_pb(pb, "cn=plugins,cn=config",
LDAP_SCOPE_SUBTREE, query, NULL, 0, NULL, NULL,
(void *)plugin_get_default_component_id(), 0);
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index e9d5c3f..42ce610 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -133,6 +133,7 @@ static int extension_type = -1; /* type returned from the factory */
/* Need to add a modifier flag to the state - such as round robin */
+/* Note: This DN is no need to be normalized. */
#define MAPPING_TREE_BASE_DN "cn=mapping tree,cn=config"
#define MAPPING_TREE_PARENT_ATTRIBUTE "nsslapd-parent-suffix"
@@ -365,24 +366,30 @@ static Slapi_DN *
get_parent_from_entry(Slapi_Entry * entry)
{
Slapi_Attr *attr = NULL;
- char * parent;
+ char *origparent = NULL;
+ char *parent = NULL;
Slapi_Value *val = NULL;
- Slapi_DN *parent_sdn;
+ Slapi_DN *parent_sdn = NULL;
if (slapi_entry_attr_find(entry, MAPPING_TREE_PARENT_ATTRIBUTE, &attr))
return NULL;
slapi_attr_first_value(attr, &val);
- parent = slapi_ch_strdup(slapi_value_get_string(val));
- if(parent[0]=='\"')
- {
- parent[strlen(parent) - 1] = '\0';
- parent_sdn = slapi_sdn_new_dn_byval(parent+1);
+ origparent = parent = slapi_ch_strdup(slapi_value_get_string(val));
+ if (parent) {
+ if(*parent == '"') {
+ char *ptr = NULL;
+ parent++; /* skipping the starting '"' */
+ ptr = PL_strnrchr(parent, '"', strlen(parent));
+ if (ptr) {
+ *ptr = '\0';
+ }
+ }
+ parent_sdn =
+ slapi_sdn_new_dn_passin(slapi_create_dn_string("%s", parent));
+ slapi_ch_free_string(&origparent);
}
- else
- parent_sdn = slapi_sdn_new_dn_byval(parent);
- slapi_ch_free((void **) &parent);
return parent_sdn;
}
@@ -393,9 +400,10 @@ static Slapi_DN *
get_subtree_from_entry(Slapi_Entry * entry)
{
Slapi_Attr *attr = NULL;
- char * cn;
+ char *origcn = NULL;
+ char *cn = NULL;
Slapi_Value *val = NULL;
- Slapi_DN *subtree;
+ Slapi_DN *subtree = NULL;
if (slapi_entry_attr_find(entry, "cn", &attr))
return NULL;
@@ -415,15 +423,19 @@ get_subtree_from_entry(Slapi_Entry * entry)
/* GB : I think removing the first and last " in the cn value
* is the right stuff to do
*/
- cn = slapi_ch_strdup(slapi_value_get_string(val));
- if(cn[0]=='\"')
- {
- cn[strlen(cn) - 1] = '\0';
- subtree = slapi_sdn_new_dn_byval(cn+1);
+ origcn = cn = slapi_ch_strdup(slapi_value_get_string(val));
+ if (cn) {
+ if(*cn == '"') {
+ char *ptr = NULL;
+ cn++; /* skipping the starting '"' */
+ ptr = PL_strnrchr(cn, '"', strlen(cn));
+ if (ptr) {
+ *ptr = '\0';
+ }
+ }
+ subtree = slapi_sdn_new_dn_passin(slapi_create_dn_string("%s", cn));
+ slapi_ch_free_string(&origcn);
}
- else
- subtree = slapi_sdn_new_dn_byval(cn);
- slapi_ch_free((void **) &cn);
return subtree;
}
@@ -2747,7 +2759,7 @@ get_mapping_tree_node_by_name(mapping_tree_node * node, char * be_name)
char*
slapi_get_mapping_tree_node_configdn (const Slapi_DN *root)
{
- char *dn;
+ char *dn = NULL;
if(mapping_tree_freed){
/* shutdown detected */
@@ -2756,7 +2768,16 @@ slapi_get_mapping_tree_node_configdn (const Slapi_DN *root)
if (root == NULL)
return NULL;
- dn = slapi_ch_smprintf("cn=\"%s\",%s", slapi_sdn_get_dn(root), MAPPING_TREE_BASE_DN);
+ /* This function converts the old DN style to the new one. */
+ dn = slapi_create_dn_string("cn=\"%s\",%s",
+ slapi_sdn_get_dn(root), MAPPING_TREE_BASE_DN);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "slapi_get_mapping_tree_node_configdn: "
+ "failed to crate mapping tree dn for %s\n",
+ slapi_sdn_get_dn(root));
+ return NULL;
+ }
return dn;
}
@@ -3058,7 +3079,7 @@ slapi_mtn_set_referral(const Slapi_DN *sdn, char ** referral)
}
slapi_mods_done(&smods);
- slapi_ch_free((void **) &node_dn);
+ slapi_ch_free_string(&node_dn);
return rc;
}
@@ -3079,13 +3100,13 @@ slapi_mtn_set_state(const Slapi_DN *sdn, char *state)
char * node_dn;
char * value;
- node_dn = slapi_get_mapping_tree_node_configdn(sdn);
- if(!node_dn){
- /* shutdown has been detected */
+ if (NULL == state) {
return LDAP_OPERATIONS_ERROR;
}
- if (NULL == state) {
+ node_dn = slapi_get_mapping_tree_node_configdn(sdn);
+ if(!node_dn){
+ /* shutdown has been detected */
return LDAP_OPERATIONS_ERROR;
}
@@ -3094,9 +3115,7 @@ slapi_mtn_set_state(const Slapi_DN *sdn, char *state)
if ( strcasecmp(value, state) == 0 )
{
/* Same state, don't change anything */
- slapi_ch_free((void **) &value);
- slapi_ch_free((void **) &node_dn);
- return rc;
+ goto bail;
}
}
@@ -3112,10 +3131,10 @@ slapi_mtn_set_state(const Slapi_DN *sdn, char *state)
slapi_pblock_get (&pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
slapi_mods_done(&smods);
- slapi_ch_free((void **) &node_dn);
pblock_done(&pb);
- slapi_ch_free((void **) &value);
-
+bail:
+ slapi_ch_free_string(&value);
+ slapi_ch_free_string(&node_dn);
return rc;
}
@@ -3209,7 +3228,7 @@ slapi_mtn_get_referral(const Slapi_DN *sdn)
slapi_attr_free(&attr);
}
- slapi_ch_free((void **) &node_dn);
+ slapi_ch_free_string(&node_dn);
return referral;
}
@@ -3245,7 +3264,7 @@ slapi_mtn_get_state(const Slapi_DN *sdn)
slapi_attr_free(&attr);
}
- slapi_ch_free((void **) &node_dn);
+ slapi_ch_free_string(&node_dn);
return state;
}
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index 40646b2..027bbef 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -166,16 +166,43 @@ do_modify( Slapi_PBlock *pb )
*/
{
- if ( ber_scanf( ber, "{a", &dn ) == LBER_ERROR )
+ char *rawdn = NULL;
+ size_t dnlen = 0;
+ int rc = 0;
+ if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR )
{
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Modify; params=DN)\n", 0, 0, 0 );
op_shared_log_error_access (pb, "MOD", "???", "decoding error");
- send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
- NULL );
- slapi_ch_free_string(&dn);
+ send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL );
+ slapi_ch_free_string(&rawdn);
return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MOD", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "MOD", "???", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawdn);
+ return;
+ } else if (rc > 0) { /* if rc == 0, rawdn is passed in */
+ slapi_ch_free_string(&rawdn);
+ } else { /* rc == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
}
LDAPDebug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", dn, 0, 0 );
diff --git a/ldap/servers/slapd/modrdn.c b/ldap/servers/slapd/modrdn.c
index dc953f7..6951fb0 100644
--- a/ldap/servers/slapd/modrdn.c
+++ b/ldap/servers/slapd/modrdn.c
@@ -72,10 +72,13 @@ do_modrdn( Slapi_PBlock *pb )
{
Slapi_Operation *operation;
BerElement *ber;
+ char *rawdn = NULL, *rawnewsuperior = NULL;
char *dn = NULL, *newsuperior = NULL;
+ char *rawnewrdn = NULL;
char *newrdn = NULL;
int err = 0, deloldrdn = 0;
ber_len_t len = 0;
+ size_t dnlen = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 );
@@ -96,7 +99,7 @@ do_modrdn( Slapi_PBlock *pb )
* }
*/
- if ( ber_scanf( ber, "{aab", &dn, &newrdn, &deloldrdn )
+ if ( ber_scanf( ber, "{aab", &rawdn, &rawnewrdn, &deloldrdn )
== LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=ModRDN; params=DN,newRDN,deleteOldRDN)\n",
@@ -109,25 +112,116 @@ do_modrdn( Slapi_PBlock *pb )
}
if ( ber_peek_tag( ber, &len ) == LDAP_TAG_NEWSUPERIOR ) {
+ /* This "len" is not used... */
if ( pb->pb_conn->c_ldapversion < LDAP_VERSION3 ) {
LDAPDebug( LDAP_DEBUG_ANY,
"got newSuperior in LDAPv2 modrdn op\n", 0, 0, 0 );
- op_shared_log_error_access (pb, "MODRDN", dn, "decoding error");
+ op_shared_log_error_access (pb, "MODRDN",
+ rawdn?rawdn:"", "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"received newSuperior in LDAPv2 modrdn", 0, NULL );
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
goto free_and_return;
}
- if ( ber_scanf( ber, "a", &newsuperior ) == LBER_ERROR ) {
+ if ( ber_scanf( ber, "a", &rawnewsuperior ) == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=ModRDN; params=newSuperior)\n",
0, 0, 0 );
- op_shared_log_error_access (pb, "MODRDN", dn, "decoding error");
+ op_shared_log_error_access (pb, "MODRDN", rawdn, "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"unable to decode newSuperior parameter", 0, NULL );
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
goto free_and_return;
}
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MODRDN", rawdn?rawdn:"",
+ "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ }
+ /* check that the new rdn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawnewrdn, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MODRDN", rawnewrdn?rawnewrdn:"",
+ "strict: invalid new rdn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new rdn", 0, NULL);
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "MODRDN", rawdn?rawdn:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free_string( &rawdn );
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ } else if (err > 0) {
+ slapi_ch_free((void **) &rawdn);
+ } else { /* err == 0; rawdn is passed in; not null terminated */
+ *(dn + dnlen) = '\0';
+ }
+ err = slapi_dn_normalize_ext(rawnewrdn, 0, &newrdn, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "MODRDN", rawnewrdn?rawnewrdn:"",
+ "invalid new rdn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new rdn", 0, NULL);
+ slapi_ch_free_string( &rawnewrdn );
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ } else if (err > 0) {
+ slapi_ch_free((void **) &rawnewrdn);
+ } else { /* err == 0; rawnewdn is passed in; not null terminated */
+ *(newrdn + dnlen) = '\0';
+ }
+ if (rawnewsuperior) {
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ err = slapi_dn_syntax_check(pb, rawnewsuperior, 1);
+ if (err) { /* syntax check failed */
+ op_shared_log_error_access(pb, "MODRDN",
+ rawnewsuperior?rawnewsuperior:"",
+ "strict: invalid new superior");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new superior", 0, NULL);
+ slapi_ch_free_string( &rawnewsuperior );
+ goto free_and_return;
+ }
+ }
+ err = slapi_dn_normalize_ext(rawnewsuperior, 0, &newsuperior, &dnlen);
+ if (err < 0) {
+ op_shared_log_error_access(pb, "MODRDN",
+ rawnewsuperior?rawnewsuperior:"",
+ "invalid new superior");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid new superior", 0, NULL);
+ slapi_ch_free_string( &rawnewsuperior);
+ goto free_and_return;
+ } else if (err > 0) {
+ slapi_ch_free((void **) &rawnewsuperior);
+ } else { /* err == 0; rawnewsuperior is passed in; not terminated */
+ *(newsuperior + dnlen) = '\0';
+ }
+ }
+
/*
* in LDAPv3 there can be optional control extensions on
* the end of an LDAPMessage. we need to read them in and
@@ -153,9 +247,9 @@ do_modrdn( Slapi_PBlock *pb )
return;
free_and_return:
- slapi_ch_free((void **) &dn );
- slapi_ch_free((void **) &newrdn );
- slapi_ch_free((void **) &newsuperior );
+ slapi_ch_free_string( &dn );
+ slapi_ch_free_string( &newrdn );
+ slapi_ch_free_string( &newsuperior );
return;
}
@@ -383,7 +477,7 @@ op_shared_rename(Slapi_PBlock *pb, int passin_args)
(NULL == newrdn) ? "(null)" : newrdn);
} else {
slapi_log_error(SLAPI_LOG_ARGS, NULL,
- "conn=%" NSPRIu64 " op=%d MODRDN invalid new RDN (\"%s\")\n",
+ "conn=%s op=%d MODRDN invalid new RDN (\"%s\")\n",
LOG_INTERNAL_OP_CON_ID,
LOG_INTERNAL_OP_OP_ID,
(NULL == newrdn) ? "(null)" : newrdn);
@@ -415,7 +509,7 @@ op_shared_rename(Slapi_PBlock *pb, int passin_args)
(NULL == newsuperior) ? "(null)" : newsuperiorbuf);
} else {
slapi_log_error(SLAPI_LOG_ARGS, NULL,
- "conn=%" NSPRIu64 " op=%d MODRDN invalid new superior (\"%s\")",
+ "conn=%s op=%d MODRDN invalid new superior (\"%s\")",
LOG_INTERNAL_OP_CON_ID,
LOG_INTERNAL_OP_OP_ID,
(NULL == newsuperior) ? "(null)" : newsuperiorbuf);
diff --git a/ldap/servers/slapd/modutil.c b/ldap/servers/slapd/modutil.c
index deed1cc..51a2d2a 100644
--- a/ldap/servers/slapd/modutil.c
+++ b/ldap/servers/slapd/modutil.c
@@ -188,11 +188,37 @@ void
slapi_mods_insert_at(Slapi_Mods *smods, LDAPMod *mod, int pos)
{
int i;
- slapi_mods_add_one_element(smods);
- for( i=smods->num_mods-1; i>=pos; i--)
+ Slapi_Attr a = {0};
+
+ if (NULL == mod) {
+ return;
+ }
+ slapi_mods_add_one_element(smods);
+ for( i=smods->num_mods-1; i>=pos; i--)
{
smods->mods[i+1]= smods->mods[i];
}
+ slapi_attr_init(&a, mod->mod_type);
+ /* Check if the type of the to-be-added values has DN syntax or not. */
+ if (slapi_attr_is_dn_syntax_attr(&a)) {
+ int rc = 0;
+ struct berval **mbvp = NULL;
+ char *normed = NULL;
+ size_t len = 0;
+ for (mbvp = mod->mod_bvalues; mbvp && *mbvp; mbvp++) {
+ rc = slapi_dn_normalize_ext((*mbvp)->bv_val, (*mbvp)->bv_len,
+ &normed, &len);
+ if (rc > 0) {
+ slapi_ch_free((void **)&((*mbvp)->bv_val));
+ } else if (rc == 0) {
+ /* original is passed in; not null terminated */
+ *(normed + len) = '\0';
+ }
+ (*mbvp)->bv_val = normed;
+ (*mbvp)->bv_len = len;
+ }
+ }
+ attr_done(&a);
smods->mods[pos]= mod;
smods->num_mods++;
smods->mods[smods->num_mods]= NULL;
diff --git a/ldap/servers/slapd/passwd_extop.c b/ldap/servers/slapd/passwd_extop.c
index 14341f9..ff2e19f 100644
--- a/ldap/servers/slapd/passwd_extop.c
+++ b/ldap/servers/slapd/passwd_extop.c
@@ -455,7 +455,9 @@ passwd_modify_extop( Slapi_PBlock *pb )
char *oid = NULL;
char *bindDN = NULL;
char *authmethod = NULL;
+ char *rawdn = NULL;
char *dn = NULL;
+ size_t dnlen = 0;
char *otdn = NULL;
char *oldPasswd = NULL;
char *newPasswd = NULL;
@@ -561,16 +563,43 @@ passwd_modify_extop( Slapi_PBlock *pb )
/* identify userID field by tags */
if (tag == LDAP_EXTOP_PASSMOD_TAG_USERID )
{
- if ( ber_scanf( ber, "a", &dn) == LBER_ERROR )
+ int rc = 0;
+ if ( ber_scanf( ber, "a", &rawdn) == LBER_ERROR )
{
- slapi_ch_free_string(&dn);
+ slapi_ch_free_string(&rawdn);
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed :{\n", 0, 0, 0 );
errMesg = "ber_scanf failed at userID parse.\n";
rc = LDAP_PROTOCOL_ERROR;
goto free_and_return;
}
-
+
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawdn, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "EXT", rawdn?rawdn:"",
+ "strict: invalid target dn");
+ errMesg = "invalid target dn.\n";
+ slapi_ch_free_string(&rawdn);
+ rc = LDAP_INVALID_SYNTAX;
+ goto free_and_return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawdn, 0, &dn, &dnlen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "EXT", rawdn?rawdn:"",
+ "invalid target dn");
+ slapi_ch_free_string(&rawdn);
+ errMesg = "invalid target dn.\n";
+ rc = LDAP_INVALID_SYNTAX;
+ goto free_and_return;
+ } else if (rc == 0) { /* rawdn is passed in, not terminated */
+ *(dn + dnlen) = '\0';
+ } else {
+ slapi_ch_free_string(&rawdn);
+ }
tag = ber_peek_tag( ber, &len);
}
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 24f66b9..84dbcfe 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -268,8 +268,15 @@ slapi_register_plugin_ext(
{
int ii = 0;
int rc = 0;
- Slapi_Entry *e = slapi_entry_alloc();
- char *dn = slapi_ch_smprintf("cn=%s, %s", name, PLUGIN_BASE_DN);
+ Slapi_Entry *e = NULL;
+ char *dn = slapi_create_dn_string("cn=%s,%s", name, PLUGIN_BASE_DN);
+ if (NULL == dn) {
+ slapi_log_error(SLAPI_LOG_FATAL, NULL,
+ "slapi_register_plugin_ext: "
+ "failed to create plugin dn (plugin name: %s)\n", name);
+ return 1;
+ }
+ e = slapi_entry_alloc();
/* this function consumes dn */
slapi_entry_init(e, dn, NULL);
@@ -2461,7 +2468,7 @@ plugin_invoke_plugin_sdn (struct slapdplugin *plugin, int operation, Slapi_PBloc
*/
char* plugin_get_dn (const struct slapdplugin *plugin)
{
- char *plugindn;
+ char *plugindn = NULL;
char *pattern = "cn=%s," PLUGIN_BASE_DN;
if (plugin == NULL) /* old plugin that does not pass identity - use default */
@@ -2470,8 +2477,13 @@ char* plugin_get_dn (const struct slapdplugin *plugin)
if (plugin->plg_name == NULL)
return NULL;
- plugindn = slapi_ch_smprintf(pattern, plugin->plg_name);
-
+ plugindn = slapi_create_dn_string(pattern, plugin->plg_name);
+ if (NULL == plugindn) {
+ slapi_log_error(SLAPI_LOG_FATAL, NULL,
+ "plugin_get_dn: failed to create plugin dn "
+ "(plugin name: %s)\n", plugin->plg_name);
+ return NULL;
+ }
return plugindn;
}
@@ -2888,7 +2900,7 @@ void plugin_print_lists(void)
struct slapdplugin *tmp = NULL;
for (i = 0; i < PLUGIN_LIST_GLOBAL_MAX; i++) {
- if (list = get_plugin_list(i))
+ if ((list = get_plugin_list(i)))
{
slapi_log_error(SLAPI_LOG_PLUGIN, NULL,
"---- Plugin List (type %d) ----\n", i);
@@ -2965,7 +2977,7 @@ slapi_set_plugin_default_config(const char *type, Slapi_Value *value)
/* cn=plugin default config,cn=config */
pblock_init(&pb);
slapi_search_internal_set_pb(&pb,
- SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */
+ SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN (normalized) */
LDAP_SCOPE_BASE,
"(objectclass=*)",
search_attrs, /* Attrs */
@@ -3069,7 +3081,7 @@ slapi_get_plugin_default_config(char *type, Slapi_ValueSet **valueset)
/* cn=plugin default config,cn=config */
pblock_init(&pb);
slapi_search_internal_set_pb(&pb,
- SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN */
+ SLAPI_PLUGIN_DEFAULT_CONFIG, /* Base DN (normalized) */
LDAP_SCOPE_BASE,
"(objectclass=*)",
search_attrs, /* Attrs */
diff --git a/ldap/servers/slapd/plugin_syntax.c b/ldap/servers/slapd/plugin_syntax.c
index 5565d58..64cbe0d 100644
--- a/ldap/servers/slapd/plugin_syntax.c
+++ b/ldap/servers/slapd/plugin_syntax.c
@@ -323,7 +323,7 @@ slapi_dn_syntax_check(
}
/* See if we need to set the error text in the pblock. */
- if (errp != &errtext[0]) {
+ if (pb && (errp != &errtext[0])) {
/* SLAPI_PB_RESULT_TEXT duplicates the text in slapi_pblock_set */
slapi_pblock_set( pb, SLAPI_PB_RESULT_TEXT, errtext );
}
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
index 8f27aa6..f1e87a3 100644
--- a/ldap/servers/slapd/pw.c
+++ b/ldap/servers/slapd/pw.c
@@ -341,7 +341,6 @@ pw_encodevals_ext( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals )
{
int i;
passwdPolicy *pwpolicy=NULL;
- char *dn;
char *(*pws_enc) ( char *pwd ) = NULL;
if ( vals == NULL ) {
diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c
index fc3000c..9b80936 100644
--- a/ldap/servers/slapd/search.c
+++ b/ldap/servers/slapd/search.c
@@ -68,6 +68,7 @@ do_search( Slapi_PBlock *pb )
BerElement *ber;
int i, err, attrsonly;
ber_int_t scope, deref, sizelimit, timelimit;
+ char *rawbase = NULL;
char *base = NULL, *fstr = NULL;
struct slapi_filter *filter = NULL;
char **attrs = NULL;
@@ -80,6 +81,7 @@ do_search( Slapi_PBlock *pb )
int rc = -1;
char *original_base = 0;
char *new_base = 0;
+ size_t baselen = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_search\n", 0, 0, 0 );
@@ -114,13 +116,40 @@ do_search( Slapi_PBlock *pb )
*/
/* baseObject, scope, derefAliases, sizelimit, timelimit, attrsOnly */
- if ( ber_scanf( ber, "{aiiiib", &base, &scope, &deref, &sizelimit, &timelimit, &attrsonly ) == LBER_ERROR ){
- slapi_ch_free((void**)&base );
+ if ( ber_scanf( ber, "{aiiiib", &rawbase, &scope, &deref, &sizelimit, &timelimit, &attrsonly ) == LBER_ERROR ){
+ slapi_ch_free((void**)&rawbase );
log_search_access (pb, "???", -1, "???", "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL );
return;
}
+ /* Check if we should be performing strict validation. */
+ if (config_get_dn_validate_strict()) {
+ /* check that the dn is formatted correctly */
+ rc = slapi_dn_syntax_check(pb, rawbase, 1);
+ if (rc) { /* syntax check failed */
+ op_shared_log_error_access(pb, "SRCH",
+ rawbase?rawbase:"", "strict: invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawbase);
+ return;
+ }
+ }
+ rc = slapi_dn_normalize_ext(rawbase, 0, &base, &baselen);
+ if (rc < 0) {
+ op_shared_log_error_access(pb, "SRCH",
+ rawbase?rawbase:"", "invalid dn");
+ send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX,
+ NULL, "invalid dn", 0, NULL);
+ slapi_ch_free((void **) &rawbase);
+ return;
+ } else if (rc > 0) { /* if rc == 0, rawbase is passed in */
+ slapi_ch_free((void **) &rawbase);
+ } else { /* rc == 0; rawbase is passed in; not null terminated */
+ *(base + baselen) = '\0';
+ }
+
/*
* ignore negative time and size limits since they make no sense
*/
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 062d669..e590421 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -569,9 +569,9 @@ typedef int (*SyntaxEnumFunc)(char **names, Slapi_PluginDesc *plugindesc,
struct slapi_dn
{
unsigned char flag;
- const char *dn; /* DN */
+ const char *dn; /* DN [normalized] */
const char *ndn; /* Case Normalised DN */
- int ndn_len; /* normalize dn len */
+ int ndn_len; /* normalized dn length */
};
/*
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 883e966..039f7e5 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -2803,28 +2803,74 @@ Slapi_DN *slapi_sdn_add_rdn(Slapi_DN *sdn, const Slapi_RDN *rdn);
* utility routines for dealing with DNs
*/
/**
- * Normalizes a DN.
+ * Does nothing. (DEPRECATED)
*
* \param dn The DN to normalize.
* \return The normalized DN.
- * \deprecated Use slapi_sdn_get_ndn() instead.
+ * \deprecated Use slapi_dn_normalized_ext.
*/
char *slapi_dn_normalize( char *dn );
/**
- * Normalizes a portion of a DN value.
+ * Does nothing. (DEPRECATED)
*
* \param dn The DN value to normalize.
* \param end Pointer to the end of what will be normalized from the DN
* value in \c dn. If this parameter is \c NULL, the DN value
* will be wholly normalized.
- * \return A pointer to the end of the DN that has been normalized.
- * \warning This function does not null-terminate the string. Use this
- * function only if you know what you are doing.
+ * \return The normalized DN.
+ * \deprecated Use slapi_dn_normalized_ext.
*/
char *slapi_dn_normalize_to_end( char *dn, char *end );
/**
+ * Normalizes a DN.
+ *
+ * \param src The DN to normalize.
+ * \param src_len The length of src DN to normalize. If 0 is given, strlen(src) is used internally.
+ * \param dest The normalized DN.
+ * \param dest_len The length of the normalized DN dest.
+ * \return \c 0 if successful. The dest DN is normalized in line. Caller must not free dest in addition to src. The string is NOT NULL terminated.
+ * \return \c 1 if successful. The dest DN is allocated. Caller must free dest.
+ * \return \c -1 if an error occurs (for example, the src DN cannot be normalized)
+ */
+int slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len);
+
+/**
+ * Normalizes a DN (in lower-case characters).
+ *
+ * \param src The DN to normalize.
+ * \param src_len The length of src DN to normalize. If 0 is given, strlen(src) is used internally.
+ * \param dest The normalized DN with the cases lowered.
+ * \param dest The length of the normalized DN dest.
+ * \return \c 0 if successful. The dest DN is normalized in line. Caller must not free dest. The string is NOT NULL terminated.
+ * \return \c 1 if successful. The dest DN is allocated. Caller must free dest.
+ * \return \c -1 if an error occurs (for example, if src DN cannot be normalized)
+ */
+int slapi_dn_normalize_case_ext(char *src, size_t src_len, char **dest, size_t *dest_len);
+
+/**
+ * Generates a valid DN string.
+ *
+ * \param fmt The format used to generate a DN string.
+ * \param ... The arguments to generate a DN string.
+ * \return A pointer to the generated DN.
+ * \return NULL if failed.
+ * \note When a DN needs to be internally created, this function is supposed to be called. This function allocates the enough memory for the normalized DN and returns it filled with the normalized DN.
+ */
+char *slapi_create_dn_string(const char *fmt, ...);
+
+/**
+ * Generates a valid DN string (in lower-case characters).
+ *
+ * \param fmt The format used to generate a DN string.
+ * \param ... The arguments to generate a DN string.
+ * \return A pointer to the generated DN.
+ * \return NULL if failed.
+ */
+char *slapi_create_dn_string_case(const char *fmt, ...);
+
+/**
* Converts a DN to lowercase.
*
* \param dn The DN to convert.
@@ -3105,6 +3151,15 @@ int slapi_attr_get_oid_copy( const Slapi_Attr *attr, char **oidp );
int slapi_attr_get_syntax_oid_copy( const Slapi_Attr *a, char **oidp );
/**
+ * Checks if the attribute uses a DN syntax or not.
+ *
+ * \param attr The attribute to be checked.
+ * \return \c non 0 if the attribute uses a DN syntax.
+ * \return \c 0 if the attribute does not use a DN syntax.
+ */
+int slapi_attr_is_dn_syntax_attr(Slapi_Attr *attr);
+
+/**
* Get the flags associated with a particular attribute.
*
* Valid flags are:
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 0f32f00..bbe3b5e 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -364,6 +364,7 @@ const CSN *value_get_csn( const Slapi_Value *value, CSNType t );
const CSNSet *value_get_csnset ( const Slapi_Value *value);
Slapi_Value *value_remove_csn( Slapi_Value *value, CSNType t);
int value_contains_csn( const Slapi_Value *value, CSN *csn);
+int value_normalize_value(Slapi_Value *value);
/* dn.c */
/* this functions should only be used for dns allocated on the stack */
@@ -820,6 +821,7 @@ void valuearray_add_value_fast(Slapi_Value ***vals, Slapi_Value *addval, int nva
void valuearray_add_valuearray( Slapi_Value ***vals, Slapi_Value **addvals, PRUint32 flags );
void valuearray_add_valuearray_fast( Slapi_Value ***vals, Slapi_Value **addvals, int nvals, int naddvals, int *maxvals, int exact, int passin );
int valuearray_find(const Slapi_Attr *a, Slapi_Value **va, const Slapi_Value *v);
+int valuearray_normalize_value(Slapi_Value **vals);
/******************************************************************************
diff --git a/ldap/servers/slapd/snmp_collator.c b/ldap/servers/slapd/snmp_collator.c
index 9beb878..9c485de 100644
--- a/ldap/servers/slapd/snmp_collator.c
+++ b/ldap/servers/slapd/snmp_collator.c
@@ -873,7 +873,8 @@ loadConfigStats() {
static Slapi_Entry *
getConfigEntry( Slapi_Entry **e ) {
Slapi_DN sdn;
-
+
+ /* SNMP_CONFIG_DN: no need to be normalized */
slapi_sdn_init_dn_byref( &sdn, SNMP_CONFIG_DN );
slapi_search_internal_get_entry( &sdn, NULL, e,
plugin_get_default_component_id());
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
index 733618f..a7fe789 100644
--- a/ldap/servers/slapd/task.c
+++ b/ldap/servers/slapd/task.c
@@ -60,13 +60,13 @@ static int shutting_down = 0;
/***********************************
* Private Defines
***********************************/
-#define TASK_BASE_DN "cn=tasks, cn=config"
-#define TASK_IMPORT_DN "cn=import, cn=tasks, cn=config"
-#define TASK_EXPORT_DN "cn=export, cn=tasks, cn=config"
-#define TASK_BACKUP_DN "cn=backup, cn=tasks, cn=config"
-#define TASK_RESTORE_DN "cn=restore, cn=tasks, cn=config"
-#define TASK_INDEX_DN "cn=index, cn=tasks, cn=config"
-#define TASK_UPGRADEDB_DN "cn=upgradedb, cn=tasks, cn=config"
+#define TASK_BASE_DN "cn=tasks,cn=config"
+#define TASK_IMPORT_DN "cn=import,cn=tasks,cn=config"
+#define TASK_EXPORT_DN "cn=export,cn=tasks,cn=config"
+#define TASK_BACKUP_DN "cn=backup,cn=tasks,cn=config"
+#define TASK_RESTORE_DN "cn=restore,cn=tasks,cn=config"
+#define TASK_INDEX_DN "cn=index,cn=tasks,cn=config"
+#define TASK_UPGRADEDB_DN "cn=upgradedb,cn=tasks,cn=config"
#define TASK_LOG_NAME "nsTaskLog"
#define TASK_STATUS_NAME "nsTaskStatus"
@@ -403,9 +403,12 @@ int slapi_task_register_handler(const char *name, dseCallbackFn func)
int ret = -1;
int x;
- dn = slapi_ch_smprintf("cn=%s, %s", name, TASK_BASE_DN);
- if (dn == NULL) {
- goto out;
+ dn = slapi_create_dn_string("cn=%s,%s", name, TASK_BASE_DN);
+ if (NULL == dn) {
+ LDAPDebug1Arg( LDAP_DEBUG_ANY,
+ "slapi_task_register_handler: "
+ "failed to create task dn for %s\n", name);
+ return ret;
}
pb = slapi_pblock_new();
@@ -458,9 +461,7 @@ int slapi_task_register_handler(const char *name, dseCallbackFn func)
ret = 0;
out:
- if (dn) {
- slapi_ch_free((void **)&dn);
- }
+ slapi_ch_free_string(&dn);
if (pb) {
slapi_pblock_destroy(pb);
}
@@ -487,18 +488,27 @@ void slapi_task_set_cancel_fn(Slapi_Task *task, TaskCallbackFn func)
***********************************/
/* create a new task, fill in DN, and setup modify callback */
static Slapi_Task *
-new_task(const char *dn)
+new_task(const char *rawdn)
{
- Slapi_Task *task = (Slapi_Task *)slapi_ch_calloc(1, sizeof(Slapi_Task));
+ Slapi_Task *task = NULL;
+ char *dn = NULL;
+
+ if (rawdn == NULL) {
+ return NULL;
+ }
- if (task == NULL)
+ dn = slapi_create_dn_string("%s", rawdn);
+ if (NULL == dn) {
+ LDAPDebug1Arg(LDAP_DEBUG_ANY,
+ "new_task failed: invalid task dn: %s\n", rawdn);
return NULL;
+ }
+ task = (Slapi_Task *)slapi_ch_calloc(1, sizeof(Slapi_Task));
PR_Lock(global_task_lock);
task->next = global_task_list;
global_task_list = task;
PR_Unlock(global_task_lock);
-
- task->task_dn = slapi_ch_strdup(dn);
+ task->task_dn = dn;
task->task_state = SLAPI_TASK_SETUP;
task->task_flags = SLAPI_TASK_RUNNING_AS_TASK;
task->destructor = NULL;
@@ -511,8 +521,8 @@ new_task(const char *dn)
/* don't add entries under this one */
#if 0
/* don't know why, but this doesn't work. it makes the current add
- * * operation fail. :(
- * */
+ * operation fail. :(
+ */
slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn,
LDAP_SCOPE_SUBTREE, "(objectclass=*)", task_deny, NULL);
#endif
diff --git a/ldap/servers/slapd/tools/dbscan.c b/ldap/servers/slapd/tools/dbscan.c
index 8483231..99d44c6 100644
--- a/ldap/servers/slapd/tools/dbscan.c
+++ b/ldap/servers/slapd/tools/dbscan.c
@@ -409,7 +409,7 @@ static ID id_stored_to_internal(char* b)
static void id_internal_to_stored(ID i,char *b)
{
if ( sizeof(ID) > 4 ) {
- memset (b+4, 0, sizeof(ID)-4);
+ (void)memset (b+4, 0, sizeof(ID)-4);
}
b[0] = (char)(i >> 24);
diff --git a/ldap/servers/slapd/tools/ldclt/ldclt.h b/ldap/servers/slapd/tools/ldclt/ldclt.h
index e6c858a..48c398b 100644
--- a/ldap/servers/slapd/tools/ldclt/ldclt.h
+++ b/ldap/servers/slapd/tools/ldclt/ldclt.h
@@ -740,6 +740,8 @@ extern int connectToServer (thread_context *tttctx); /*JLS 14-03-01*/
extern char *dnFromMessage (thread_context *tttctx, LDAPMessage *res);
extern int doAddEntry (thread_context *tttctx);
extern int doAttrReplace (thread_context *tttctx); /*JLS 21-11-00*/
+extern int doAttrFileReplace (thread_context *tttctx);
+
extern int doBindOnly (thread_context *tttctx); /*JLS 04-05-01*/
extern int doDeleteEntry (thread_context *tttctx);
extern int doExactSearch (thread_context *tttctx);
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
index d26b0b9..8987e63 100644
--- a/ldap/servers/slapd/util.c
+++ b/ldap/servers/slapd/util.c
@@ -335,8 +335,9 @@ int slapi_entry2mods (const Slapi_Entry *e, char **dn, LDAPMod ***attrs)
*
* normalize_mods2bvals
*
-*
-*
+* Return value: normalized mods
+* The values/bvals are all duplicated in this function since
+* the normalized mods are freed with ldap_mods_free by the caller.
*
*******************************************************************************/
@@ -360,6 +361,18 @@ normalize_mods2bvals(const LDAPMod **mods)
for (w = 0; mods[w] != NULL; w++)
{
+ Slapi_Attr a = {0};
+ slapi_attr_init(&a, mods[w]->mod_type);
+ int is_dn_syntax = 0;
+ struct berval **normmbvp = NULL;
+
+ /* Check if the type of the to-be-added values has DN syntax
+ * or not. */
+ if (slapi_attr_is_dn_syntax_attr(&a)) {
+ is_dn_syntax = 1;
+ }
+ attr_done(&a);
+
/* copy each mod into a normalized modbvalue */
normalized_mods[w] = (LDAPMod *) slapi_ch_calloc(1, sizeof(LDAPMod));
normalized_mods[w]->mod_op = mods[w]->mod_op | LDAP_MOD_BVALUES;
@@ -397,32 +410,79 @@ normalize_mods2bvals(const LDAPMod **mods)
if (mods[w]->mod_op & LDAP_MOD_BVALUES)
{
- for (x = 0; mods[w]->mod_bvalues != NULL &&
- mods[w]->mod_bvalues[x] != NULL; x++)
+ struct berval **mbvp = NULL;
+
+ for (mbvp = mods[w]->mod_bvalues,
+ normmbvp = normalized_mods[w]->mod_bvalues;
+ mbvp && *mbvp; mbvp++, normmbvp++)
{
- normalized_mods[w]->mod_bvalues[x] = ber_bvdup(mods[w]->mod_bvalues[x]);
+ if (is_dn_syntax) {
+ int rc = 0;
+ char *normed = NULL;
+ size_t dnlen = 0;
+
+ rc = slapi_dn_normalize_ext((*mbvp)->bv_val,
+ (*mbvp)->bv_len,
+ &normed, &dnlen);
+ if (rc < 0) { /* normalization failed; use the original */
+ *normmbvp = ber_bvdup(*mbvp);
+ } else if (rc == 0) { /* if rc == 0, value is passed in */
+ *(normed + dnlen) = '\0';
+ *normmbvp = ber_bvdup(*mbvp);
+ } else {
+ (*normmbvp)->bv_val = normed;
+ (*normmbvp)->bv_len = dnlen;
+ }
+ } else {
+ *normmbvp = ber_bvdup(*mbvp);
+ }
}
} else {
- for (x = 0; mods[w]->mod_values != NULL &&
- mods[w]->mod_values[x] != NULL; x++)
+ char **mvp = NULL;
+
+ for (mvp = mods[w]->mod_values,
+ normmbvp = normalized_mods[w]->mod_bvalues;
+ mvp && *mvp; mvp++, normmbvp++)
{
- normalized_mods[w]->mod_bvalues[ x ] = (struct berval *)
- slapi_ch_calloc(1, sizeof(struct berval));
-
- vlen = strlen(mods[w]->mod_values[x]);
- normalized_mods[w]->mod_bvalues[ x ]->bv_val =
- slapi_ch_calloc(vlen + 1, sizeof(char));
- memcpy(normalized_mods[w]->mod_bvalues[ x ]->bv_val,
- mods[w]->mod_values[x], vlen);
- normalized_mods[w]->mod_bvalues[ x ]->bv_val[vlen] = '\0';
- normalized_mods[w]->mod_bvalues[ x ]->bv_len = vlen;
+ *normmbvp =
+ (struct berval *)slapi_ch_malloc(sizeof(struct berval));
+
+ vlen = strlen(*mvp);
+
+ if (is_dn_syntax) {
+ int rc = 0;
+ char *normed = NULL;
+ size_t dnlen = 0;
+ rc = slapi_dn_normalize_ext(*mvp, vlen,
+ &normed, &dnlen);
+ if (rc < 0) { /* normalization failed; use the original */
+ (*normmbvp)->bv_val = slapi_ch_malloc(vlen + 1);
+ memcpy((*normmbvp)->bv_val, *mvp, vlen);
+ (*normmbvp)->bv_val[vlen] = '\0';
+ (*normmbvp)->bv_len = vlen;
+ } else if (rc == 0) { /* if rc == 0, value is passed in */
+ *(normed + dnlen) = '\0';
+ (*normmbvp)->bv_val = slapi_ch_strdup(normed);
+ (*normmbvp)->bv_len = dnlen;
+ } else {
+ (*normmbvp)->bv_val = normed;
+ (*normmbvp)->bv_len = dnlen;
+ }
+ } else {
+ (*normmbvp)->bv_val = slapi_ch_malloc(vlen + 1);
+ memcpy((*normmbvp)->bv_val, *mvp, vlen);
+ (*normmbvp)->bv_val[vlen] = '\0';
+ (*normmbvp)->bv_len = vlen;
+ }
}
}
+ PR_ASSERT(normmbvp - normalized_mods[w]->mod_bvalues <= num_values);
+
/* don't forget to null terminate it */
- if (num_values > 0)
+ if (num_values > 0)
{
- normalized_mods[w]->mod_bvalues[ x ] = NULL;
+ *normmbvp = NULL;
}
}
diff --git a/ldap/servers/slapd/value.c b/ldap/servers/slapd/value.c
index 72f94b9..c0cf66e 100644
--- a/ldap/servers/slapd/value.c
+++ b/ldap/servers/slapd/value.c
@@ -551,3 +551,29 @@ value_dump( const Slapi_Value *value, const char *text)
}
#endif
+int
+value_normalize_value(Slapi_Value *value)
+{
+ char *normval = NULL;
+ size_t len = 0;
+ int rc = 0;
+
+ if (NULL == value) {
+ return 0;
+ }
+
+ rc = slapi_dn_normalize_ext(value->bv.bv_val, value->bv.bv_len,
+ &normval, &len);
+ if (rc < 0) {
+ return 1;
+ } else if (rc > 0) { /* if rc == 0, the original value is passed in */
+ slapi_ch_free_string(&value->bv.bv_val);
+ } else { /* rc == 0; original is passed in; not null terminated */
+ /* since bvalue, no need to terminate with null, tho */
+ *(normval + len) = '\0';
+ }
+ value->bv.bv_val = normval;
+ value->bv.bv_len = len;
+
+ return 0;
+}
diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
index 8aa33c5..4b0d30f 100644
--- a/ldap/servers/slapd/valueset.c
+++ b/ldap/servers/slapd/valueset.c
@@ -1438,3 +1438,17 @@ valueset_update_csn_for_valuearray(Slapi_ValueSet *vs, const Slapi_Attr *a, Slap
*valuesupdated= vaf_valuesupdated.va;
}
}
+
+int
+valuearray_normalize_value(Slapi_Value **vals)
+{
+ int rc = 0;
+ Slapi_Value **vp = NULL;
+
+ for (vp = vals; vp && *vp; vp++) {
+ rc |= value_normalize_value(*vp);
+ }
+
+ return rc;
+}
+
13 years, 11 months
ldap/servers
by Nathan Kinder
ldap/servers/slapd/tools/rsearch/searchthread.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 4754291972668c37559a8f68d75ac6f8c477efb8
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Fri Apr 23 11:32:36 2010 -0700
Fix rsearch usage of name files for random filters
The rsearch utility has an option (-i) that allows one to have a
file containing names to be used as a variable in search filters.
The way this is designed is that you would specify a partial filter
(such as "uid=") as the filter option and a random name from the
name file will be appended to the filter for each search operation.
Unfortunately, this option was broken. The format was missing
where we were creating the filter string, which caused the filter
option to be used as specified without appending a name from the
name file.
diff --git a/ldap/servers/slapd/tools/rsearch/searchthread.c b/ldap/servers/slapd/tools/rsearch/searchthread.c
index 38d5d59..c229d75 100644
--- a/ldap/servers/slapd/tools/rsearch/searchthread.c
+++ b/ldap/servers/slapd/tools/rsearch/searchthread.c
@@ -318,7 +318,7 @@ static int st_search(SearchThread *st)
sprintf(num, "%d", get_large_random_number() % numeric);
s = num;
}
- sprintf(filterBuffer, filter, s);
+ sprintf(filterBuffer, "%s%s", filter, s);
pFilter = filterBuffer;
} else {
pFilter = filter;
13 years, 11 months
ldap/admin Makefile.am Makefile.in
by Nathan Kinder
Makefile.am | 1 +
Makefile.in | 3 ++-
ldap/admin/src/scripts/10cleanupldapi.pl | 23 +++++++++++++++++++++++
3 files changed, 26 insertions(+), 1 deletion(-)
New commits:
commit b70739589cfaa7a8da3faffcc13465d521e7ad20
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Wed Apr 21 13:55:33 2010 -0700
Bug 584156 - Remove ldapi socket file during upgrade
The ldapi socket file is only removed when ns-slapd is started
since the server does not have permission to remove it at shutdown.
The causes issues when upgrading to a recetn version that has
SELinux policy since the newly confined ns-slapd daemon will not
be allowed to remove the old ldapi socket file since it doesn't
have a dirsrv specific label. To deal with this, I've added an
upgrade scriptlet that will remove the ldapi socket file. When
the newly confined ns-slapd starts up, it will create a new
socket file with the proper label.
diff --git a/Makefile.am b/Makefile.am
index 6cfbef8..9d1bee6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -407,6 +407,7 @@ dist_man_MANS = man/man1/dbscan.1 \
#------------------------
update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
ldap/admin/src/scripts/exampleupdate.ldif \
+ ldap/admin/src/scripts/10cleanupldapi.pl \
ldap/admin/src/scripts/10delautodnsuffix.pl \
ldap/admin/src/scripts/10fixrundir.pl \
ldap/admin/src/scripts/50addchainingsaslpwroles.ldif \
diff --git a/Makefile.in b/Makefile.in
index f7c82fb..4ecd1c5 100755
--- a/Makefile.in
+++ b/Makefile.in
@@ -1489,6 +1489,7 @@ dist_man_MANS = man/man1/dbscan.1 \
#------------------------
update_DATA = ldap/admin/src/scripts/exampleupdate.pl \
ldap/admin/src/scripts/exampleupdate.ldif \
+ ldap/admin/src/scripts/10cleanupldapi.pl \
ldap/admin/src/scripts/10delautodnsuffix.pl \
ldap/admin/src/scripts/10fixrundir.pl \
ldap/admin/src/scripts/50addchainingsaslpwroles.ldif \
@@ -9685,7 +9686,7 @@ distdir: $(DISTFILES)
|| exit 1; \
fi; \
done
- -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+ -find $(distdir) -type d ! -perm -755 -exec chmod a+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
diff --git a/ldap/admin/src/scripts/10cleanupldapi.pl b/ldap/admin/src/scripts/10cleanupldapi.pl
new file mode 100644
index 0000000..a09abe6
--- /dev/null
+++ b/ldap/admin/src/scripts/10cleanupldapi.pl
@@ -0,0 +1,23 @@
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::Utils qw(normalizeDN);
+use Mozilla::LDAP::API qw(:constant ldap_url_parse ldap_explode_dn);
+
+sub runinst {
+ my ($inf, $inst, $dseldif, $conn) = @_;
+
+ my @errs;
+ my $ldapifile;
+
+ # see if nsslapd-rundir is defined
+ my $ent = $conn->search("cn=config", "base", "(objectclass=*)");
+ if (!$ent) {
+ return ('error_finding_config_entry', 'cn=config', $conn->getErrorString());
+ }
+
+ $ldapifile = $ent->getValues('nsslapd-ldapifilepath');
+ if ($ldapifile) {
+ unlink($ldapifile);
+ }
+
+ return ();
+}
13 years, 11 months
ldap/servers
by Richard Allen Megginson
ldap/servers/plugins/dna/dna.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
New commits:
commit 288953655c3af087c82007d630cf8fb6558e9a9e
Author: Endi S. Dewata <edewata(a)redhat.com>
Date: Sun Apr 18 04:29:41 2010 -0500
Bug 584109 - Slapd crashes while parsing DNA configuration
https://bugzilla.redhat.com/show_bug.cgi?id=584109
Resolves: bug 584109
Bug Description: Slapd crashes while parsing DNA configuration
Fix Description: The dna_parse_config_entry() has been modified to duplicate
the shared_cfg_base value to avoid freeing the same memory location twice.
Reviewed by: rmeggins (and pushed by)
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index 0da8f07..b8922d9 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -840,7 +840,8 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
shared_e = NULL;
}
- entry->shared_cfg_base = slapi_dn_normalize(value);
+ entry->shared_cfg_base = slapi_ch_strdup(value);
+ slapi_dn_normalize(entry->shared_cfg_base);
/* We prepend the host & port of this instance as a
* multi-part RDN for the shared config entry. */
13 years, 11 months