From 9022d77690b7e932e7fddc9d4c354f52c9c8121f Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@redhat.com>
Date: Thu, 2 Apr 2015 11:49:46 -0700
Subject: [PATCH 309/319] Ticket #561 - disable writing unhashed#user#password
to changelog
Backported:
. commit c4bd52e2211c043087765f74df6cf6cd41b8f234
Ticket #561 - disable writing unhashed#user#password to changelog
. commit da3be3fbf497775f608d1289f72cfe427850f950
Fix optimization issue introduced with fix for ticket #561,
. commit 1d4f3ca2e931e6d930056aeb683256965503c5e1
Fixing a compiler warning introduced by Ticket #561
. commit 84b8bfd7d18a0613920dce36f1d3775d75e45a3e
Fix for CVE-2014-8112
Description:
Introducing a config parameter nsslapd-unhashed-pw-switch to cn=config.
The parameter takes 3 values:
on - unhashed password is stored in the entry extension
and logged in the changelog.
nolog - unhashed password is stored in the entry extension
but not logged in the changelog.
off - unhashed password is not stored in the entry extension.
https://fedorahosted.org/389/ticket/561
(cherry picked from commit bb565bd8e664a22aed754af092121d293d2fee5d)
---
ldap/servers/plugins/replication/cl5_api.c | 48 +++++++++++++----
ldap/servers/plugins/retrocl/retrocl_po.c | 6 +++
ldap/servers/slapd/add.c | 13 ++---
ldap/servers/slapd/libglobs.c | 84 +++++++++++++++++++++++++++++-
ldap/servers/slapd/modify.c | 45 +++++++++-------
ldap/servers/slapd/opshared.c | 35 +++++--------
ldap/servers/slapd/proto-slap.h | 2 +
ldap/servers/slapd/slap.h | 8 +--
ldap/servers/slapd/slapi-plugin.h | 8 +++
ldap/servers/slapd/slapi-private.h | 1 +
ldap/servers/slapd/util.c | 11 ++--
11 files changed, 194 insertions(+), 67 deletions(-)
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
index ae522a3..0618d9b 100644
--- a/ldap/servers/plugins/replication/cl5_api.c
+++ b/ldap/servers/plugins/replication/cl5_api.c
@@ -322,7 +322,7 @@ static int _cl5Str2OperationType (const char *str);
static void _cl5WriteString (const char *str, char **buff);
static void _cl5ReadString (char **str, char **buff);
static void _cl5WriteMods (LDAPMod **mods, char **buff);
-static void _cl5WriteMod (LDAPMod *mod, char **buff);
+static int _cl5WriteMod (LDAPMod *mod, char **buff);
static int _cl5ReadMods (LDAPMod ***mods, char **buff);
static int _cl5ReadMod (Slapi_Mod *mod, char **buff);
static int _cl5GetModsSize (LDAPMod **mods);
@@ -2474,7 +2474,7 @@ static void _cl5WriteMods (LDAPMod **mods, char **buff)
{
PRInt32 i;
char *mod_start;
- PRInt32 count;
+ PRInt32 count = 0;
if (mods == NULL)
return;
@@ -2483,30 +2483,49 @@ static void _cl5WriteMods (LDAPMod **mods, char **buff)
mod_start = (*buff) + sizeof (count);
/* write mods*/
- for (i=0; mods[i]; i++)
- {
- _cl5WriteMod (mods[i], &mod_start);
+ for (i = 0; mods[i]; i++) {
+ if (0 <= _cl5WriteMod (mods[i], &mod_start)) {
+ count++;
+ }
}
- count = PR_htonl(i);
+ count = PR_htonl(count);
memcpy (*buff, &count, sizeof (count));
(*buff) = mod_start;
}
-static void _cl5WriteMod (LDAPMod *mod, char **buff)
+/*
+ * return values:
+ * positive: no need to encrypt && succeeded to write a mod
+ * 0: succeeded to encrypt && write a mod
+ * netative: failed to encrypt && no write to the changelog
+ */
+static int
+_cl5WriteMod (LDAPMod *mod, char **buff)
{
+ char *orig_pos;
char *pos;
PRInt32 count;
struct berval *bv;
struct berval *encbv;
struct berval *bv_to_use;
Slapi_Mod smod;
- int rc = 0;
+ int rc = -1;
+
+ if (NULL == mod) {
+ return rc;
+ }
+ if (SLAPD_UNHASHED_PW_NOLOG == slapi_config_get_unhashed_pw_switch()) {
+ if (0 == strcasecmp(mod->mod_type, PSEUDO_ATTR_UNHASHEDUSERPASSWORD)) {
+ /* If nsslapd-unhashed-pw-switch == nolog, skip writing it to cl. */
+ return rc;
+ }
+ }
slapi_mod_init_byref(&smod, mod);
- pos = *buff;
+ orig_pos = pos = *buff;
/* write mod op */
*pos = (PRUint8)slapi_mod_get_operation (&smod);
pos ++;
@@ -2516,7 +2535,7 @@ static void _cl5WriteMod (LDAPMod *mod, char **buff)
/* write value count */
count = PR_htonl(slapi_mod_get_num_values(&smod));
memcpy (pos, &count, sizeof (count));
- pos += sizeof (PRInt32);
+ pos += sizeof (PRInt32);
bv = slapi_mod_get_first_value (&smod);
while (bv)
@@ -2536,6 +2555,8 @@ static void _cl5WriteMod (LDAPMod *mod, char **buff)
"_cl5WriteMod: encrypting \"%s: %s\" failed\n",
slapi_mod_get_type(&smod), bv->bv_val);
bv_to_use = NULL;
+ rc = -1;
+ break;
}
if (bv_to_use) {
_cl5WriteBerval (bv_to_use, &pos);
@@ -2544,9 +2565,14 @@ static void _cl5WriteMod (LDAPMod *mod, char **buff)
bv = slapi_mod_get_next_value (&smod);
}
- (*buff) = pos;
+ if (rc < 0) {
+ (*buff) = orig_pos;
+ } else {
+ (*buff) = pos;
+ }
slapi_mod_done (&smod);
+ return rc;
}
/* mods format:
diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c
index c3d1c41..3fdf887 100644
--- a/ldap/servers/plugins/retrocl/retrocl_po.c
+++ b/ldap/servers/plugins/retrocl/retrocl_po.c
@@ -101,6 +101,12 @@ static lenstr *make_changes_string(LDAPMod **ldm, const char **includeattrs)
continue;
}
}
+ if (SLAPD_UNHASHED_PW_NOLOG == slapi_config_get_unhashed_pw_switch()) {
+ if (0 == strcasecmp(ldm[ i ]->mod_type, PSEUDO_ATTR_UNHASHEDUSERPASSWORD)) {
+ /* If nsslapd-unhashed-pw-switch == nolog, skip writing it to cl. */
+ continue;
+ }
+ }
switch ( ldm[ i ]->mod_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_ADD:
addlenstr( l, "add: " );
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index f52f766..37060df 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -447,7 +447,6 @@ static void op_shared_add (Slapi_PBlock *pb)
int err;
int internal_op, repl_op, legacy_op, lastmod;
char *pwdtype = NULL;
- Slapi_Value **unhashed_password_vals = NULL;
Slapi_Attr *attr = NULL;
Slapi_Entry *referral;
char errorbuf[BUFSIZ];
@@ -545,6 +544,7 @@ static void op_shared_add (Slapi_PBlock *pb)
{
Slapi_Value **present_values;
present_values= attr_get_present_values(attr);
+ Slapi_Value **unhashed_password_vals = NULL;
/* Set the backend in the pblock. The slapi_access_allowed function
* needs this set to work properly. */
@@ -576,11 +576,13 @@ static void op_shared_add (Slapi_PBlock *pb)
add_password_attrs(pb, operation, e);
slapi_entry_attr_replace_sv(e, SLAPI_USERPWD_ATTR, vals);
valuearray_free(&vals);
-
- /* Add the unhashed password pseudo-attribute to the entry */
- pwdtype = slapi_attr_syntax_normalize(PSEUDO_ATTR_UNHASHEDUSERPASSWORD);
- slapi_entry_add_values_sv(e, pwdtype, unhashed_password_vals);
+ if (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch()) {
+ /* Add the unhashed password pseudo-attribute to the entry */
+ pwdtype = slapi_attr_syntax_normalize(PSEUDO_ATTR_UNHASHEDUSERPASSWORD);
+ slapi_entry_add_values_sv(e, pwdtype, unhashed_password_vals);
+ }
}
+ valuearray_free(&unhashed_password_vals);
}
/* look for multiple backend local credentials or replication local credentials */
@@ -751,7 +753,6 @@ done:
slapi_ch_free((void **)&operation->o_params.p.p_add.parentuniqueid);
slapi_entry_free(e);
slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
- valuearray_free(&unhashed_password_vals);
slapi_ch_free((void**)&pwdtype);
slapi_ch_free_string(&proxydn);
slapi_ch_free_string(&proxystr);
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 825dcee..dbb0fa8 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -121,7 +121,8 @@ typedef enum {
CONFIG_SPECIAL_ERRORLOGLEVEL, /* requires & with LDAP_DEBUG_ANY */
CONFIG_STRING_OR_EMPTY, /* use an empty string */
CONFIG_SPECIAL_ANON_ACCESS_SWITCH, /* maps strings to an enumeration */
- CONFIG_SPECIAL_VALIDATE_CERT_SWITCH /* maps strings to an enumeration */
+ CONFIG_SPECIAL_VALIDATE_CERT_SWITCH, /* maps strings to an enumeration */
+ CONFIG_SPECIAL_UNHASHED_PW_SWITCH /* unhashed pw: on/off/nolog */
} ConfigVarType;
static int config_set_onoff( const char *attrname, char *value,
@@ -269,6 +270,7 @@ int init_mempool_switch;
#define DEFAULT_SSLCLIENTAPTH "off"
#define DEFAULT_ALLOW_ANON_ACCESS "on"
#define DEFAULT_VALIDATE_CERT "warn"
+#define DEFAULT_UNHASHED_PW_SWITCH "on"
static int
isInt(ConfigVarType type)
@@ -1041,6 +1043,11 @@ static struct config_get_and_set {
NULL, 0,
(void**)&global_slapdFrontendConfig.ndn_cache_max_size,
CONFIG_INT, (ConfigGetFunc)config_get_ndn_cache_size},
+ {CONFIG_UNHASHED_PW_SWITCH_ATTRIBUTE, config_set_unhashed_pw_switch,
+ NULL, 0,
+ (void**)&global_slapdFrontendConfig.unhashed_pw_switch,
+ CONFIG_SPECIAL_UNHASHED_PW_SWITCH,
+ (ConfigGetFunc)config_get_unhashed_pw_switch}
#ifdef MEMPOOL_EXPERIMENTAL
,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch,
NULL, 0,
@@ -1459,6 +1466,7 @@ FrontendConfig_init () {
cfg->disk_grace_period = 60; /* 1 hour */
init_disk_logging_critical = cfg->disk_logging_critical = LDAP_OFF;
cfg->sasl_max_bufsize = SLAPD_DEFAULT_SASL_MAXBUFSIZE;
+ cfg->unhashed_pw_switch = SLAPD_UNHASHED_PW_ON;
init_listen_backlog_size = cfg->listen_backlog_size = DAEMON_LISTEN_SIZE;
init_ignore_time_skew = cfg->ignore_time_skew = LDAP_OFF;
@@ -6552,7 +6560,6 @@ config_get_allowed_to_delete_attrs(void)
return retVal;
}
-
int
config_set_allowed_to_delete_attrs( const char *attrname, char *value,
char *errorbuf, int apply )
@@ -6711,6 +6718,62 @@ config_initvalue_to_onoff(struct config_get_and_set *cgas, char *initvalbuf, siz
return retval;
}
+int
+config_set_unhashed_pw_switch(const char *attrname, char *value,
+ char *errorbuf, int apply)
+{
+ int retVal = LDAP_SUCCESS;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ if (config_value_is_null(attrname, value, errorbuf, 0)) {
+ return LDAP_OPERATIONS_ERROR;
+ }
+
+ if ((strcasecmp(value, "on") != 0) && (strcasecmp(value, "off") != 0) &&
+ (strcasecmp(value, "nolog") != 0)) {
+ PR_snprintf(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+ "%s: invalid value \"%s\". Valid values are \"on\", "
+ "\"off\", or \"nolog\".", attrname, value);
+ retVal = LDAP_OPERATIONS_ERROR;
+ }
+
+ if (!apply) {
+ /* we can return now if we aren't applying the changes */
+ return retVal;
+ }
+
+ CFG_LOCK_WRITE(slapdFrontendConfig);
+
+ if (strcasecmp(value, "on") == 0 ) {
+ slapdFrontendConfig->unhashed_pw_switch = SLAPD_UNHASHED_PW_ON;
+ } else if (strcasecmp(value, "off") == 0 ) {
+ slapdFrontendConfig->unhashed_pw_switch = SLAPD_UNHASHED_PW_OFF;
+ } else if (strcasecmp(value, "nolog") == 0) {
+ slapdFrontendConfig->unhashed_pw_switch = SLAPD_UNHASHED_PW_NOLOG;
+ }
+
+ CFG_UNLOCK_WRITE(slapdFrontendConfig);
+ return retVal;
+}
+
+int
+slapi_config_get_unhashed_pw_switch()
+{
+ return config_get_unhashed_pw_switch();
+}
+
+int
+config_get_unhashed_pw_switch()
+{
+ int retVal = 0;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ CFG_LOCK_READ(slapdFrontendConfig);
+ retVal = slapdFrontendConfig->unhashed_pw_switch;
+ CFG_UNLOCK_READ(slapdFrontendConfig);
+
+ return retVal;
+}
+
/*
* This function is intended to be used from the dse code modify callback. It
* is "optimized" for that case because it takes a berval** of values, which is
@@ -6931,6 +6994,23 @@ config_set_value(
slapi_entry_attr_set_charptr(e, cgas->attr_name, sval);
break;
+ case CONFIG_SPECIAL_UNHASHED_PW_SWITCH:
+ if (!value) {
+ slapi_entry_attr_set_charptr(e, cgas->attr_name, "on");
+ break;
+ }
+
+ if (*((int *)value) == SLAPD_UNHASHED_PW_OFF) {
+ sval = "off";
+ } else if (*((int *)value) == SLAPD_UNHASHED_PW_NOLOG) {
+ sval = "nolog";
+ } else {
+ sval = "on";
+ }
+ slapi_entry_attr_set_charptr(e, cgas->attr_name, sval);
+
+ break;
+
case CONFIG_SPECIAL_VALIDATE_CERT_SWITCH:
if (!value) {
slapi_entry_attr_set_charptr(e, cgas->attr_name, "off");
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index 9c6610f..c67ef14 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -894,13 +894,15 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw)
/*
* Finally, delete the unhashed userpassword
*/
- bval.bv_val = password;
- bval.bv_len = strlen(password);
- bv[0] = &bval;
- bv[1] = NULL;
- valuearray_init_bervalarray(bv, &va);
- slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
- valuearray_free(&va);
+ if (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch()) {
+ bval.bv_val = password;
+ bval.bv_len = strlen(password);
+ bv[0] = &bval;
+ bv[1] = NULL;
+ valuearray_init_bervalarray(bv, &va);
+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
+ valuearray_free(&va);
+ }
} else {
/*
* Password is encoded, try and find a matching unhashed_password to delete
@@ -924,28 +926,31 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw)
bval.bv_len = strlen(unhashed_pwd);
bv[0] = &bval;
bv[1] = NULL;
-
/*
* Compare the clear text unhashed password, to the encoded password
* provided by the client.
*/
- unhashed_pwsp = pw_val2scheme( unhashed_pwd, NULL, 1 );
+ unhashed_pwsp = pw_val2scheme( (char *)unhashed_pwd, NULL, 1 );
if(strcmp(unhashed_pwsp->pws_name, "CLEAR") == 0){
- if((*(pwsp->pws_cmp))(unhashed_pwd , valpwd) == 0 ){
+ if((*(pwsp->pws_cmp))((char *)unhashed_pwd , valpwd) == 0 ){
/* match, add the delete mod for this particular unhashed userpassword */
- valuearray_init_bervalarray(bv, &va);
- slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
- valuearray_free(&va);
- free_pw_scheme( unhashed_pwsp );
+ if (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch()) {
+ valuearray_init_bervalarray(bv, &va);
+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
+ valuearray_free(&va);
+ free_pw_scheme( unhashed_pwsp );
+ }
break;
}
} else {
/*
* We have a hashed unhashed_userpassword! We must delete it.
*/
- valuearray_init_bervalarray(bv, &va);
- slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
- valuearray_free(&va);
+ if (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch()) {
+ valuearray_init_bervalarray(bv, &va);
+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
+ valuearray_free(&va);
+ }
}
free_pw_scheme( unhashed_pwsp );
}
@@ -958,13 +963,13 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw)
if (remove_unhashed_pw && !slapi_entry_attr_find(e, unhashed_pw_attr, &a)){
slapi_mods_add_mod_values(&smods, pw_mod->mod_op,unhashed_pw_attr, va);
}
- } else {
- /* add pseudo password attribute - only if it's value is clear text */
+ } else if (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch()) {
+ /* add pseudo password attribute */
valuearray_init_bervalarray_unhashed_only(pw_mod->mod_bvalues, &va);
if(va && va[0]){
slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
}
- valuearray_free(&va);
+ valuearray_free(&va);
}
/* Init new value array for hashed value */
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
index a7367a7..bef19d1 100644
--- a/ldap/servers/slapd/opshared.c
+++ b/ldap/servers/slapd/opshared.c
@@ -52,10 +52,7 @@
static void compute_limits (Slapi_PBlock *pb);
/* attributes that no clients are allowed to add or modify */
-/* PSEUDO_ATTR_UNHASHEDUSERPASSWORD used to be in protected_attrs_all.
- * Now it's moved to back-ldbm/id2entry.c to share it among repl masters.
- * (bz 182507)*/
-static char *protected_attrs_all [] = { NULL };
+static char *protected_attrs_all [] = { PSEUDO_ATTR_UNHASHEDUSERPASSWORD, NULL };
static char *pwpolicy_lock_attrs_all [] = { "passwordRetryCount",
"retryCountResetTime",
"accountUnlockTime",
@@ -70,30 +67,26 @@ int op_shared_is_allowed_attr (const char *attr_name, int replicated_op)
int i;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
- /* check list of attributes that no client is allowed to specify */
- for (i = 0; protected_attrs_all[i]; i ++)
- {
- if (strcasecmp (attr_name, protected_attrs_all[i]) == 0)
- {
- /* this attribute is not allowed */
- return 0;
- }
- }
-
/* ONREPL - should allow backends to plugin here to specify
attributes that are not allowed */
- if (!replicated_op)
- {
- /*
- * check to see if attribute is marked as one clients can't modify
- */
+ if (!replicated_op) {
struct asyntaxinfo *asi;
int no_user_mod = 0;
+ /* check list of attributes that no client is allowed to specify */
+ for (i = 0; protected_attrs_all[i]; i ++) {
+ if (strcasecmp (attr_name, protected_attrs_all[i]) == 0) {
+ /* this attribute is not allowed */
+ return 0;
+ }
+ }
+ /*
+ * check to see if attribute is marked as one clients can't modify
+ */
asi = attr_syntax_get_by_name( attr_name, 0 );
if ( NULL != asi &&
- 0 != ( asi->asi_flags & SLAPI_ATTR_FLAG_NOUSERMOD ))
+ 0 != ( asi->asi_flags & SLAPI_ATTR_FLAG_NOUSERMOD ))
{
/* this attribute is not allowed */
no_user_mod = 1;
@@ -187,7 +180,7 @@ modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods)
/* anonymous bind */
bv.bv_val = "";
bv.bv_len = strlen(bv.bv_val);
- } else {
+ } else {
bv.bv_val = binddn;
bv.bv_len = strlen(bv.bv_val);
}
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index da9c925..c497c14 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -403,6 +403,7 @@ int config_set_malloc_mmap_threshold(const char *attrname, char *value, char *er
int config_set_ndn_cache_enabled(const char *attrname, char *value, char *errorbuf, int apply);
int config_set_ndn_cache_max_size(const char *attrname, char *value, char *errorbuf, int apply);
+int config_set_unhashed_pw_switch(const char *attrname, char *value, char *errorbuf, int apply);
#if !defined(_WIN32) && !defined(AIX)
@@ -572,6 +573,7 @@ int config_get_malloc_mmap_threshold();
int config_get_ndn_cache_count();
size_t config_get_ndn_cache_size();
int config_get_ndn_cache_enabled();
+int config_get_unhashed_pw_switch();
PLHashNumber hashNocaseString(const void *key);
PRIntn hashNocaseCompare(const void *v1, const void *v2);
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 70e8a51..c298033 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -306,9 +306,6 @@ typedef void (*VFPV)(); /* takes undefined arguments */
#define ATTR_NETSCAPEMDSUFFIX "netscapemdsuffix"
-/* Used to make unhashed passwords available to plugins. */
-#define PSEUDO_ATTR_UNHASHEDUSERPASSWORD "unhashed#user#password"
-
#define REFERRAL_REMOVE_CMD "remove"
/* Filenames for DSE storage */
@@ -339,6 +336,8 @@ typedef void (*VFPV)(); /* takes undefined arguments */
#define SLAPD_VALIDATE_CERT_ON 1
#define SLAPD_VALIDATE_CERT_WARN 2
+typedef int slapi_onoff_t;
+
struct subfilt {
char *sf_type;
char *sf_initial;
@@ -1891,6 +1890,7 @@ typedef struct _slapdEntryPoints {
#define CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE "nsslapd-errorlog-logging-enabled"
#define CONFIG_AUDITLOG_LOGGING_ENABLED_ATTRIBUTE "nsslapd-auditlog-logging-enabled"
#define CONFIG_AUDITLOG_LOGGING_HIDE_UNHASHED_PW "nsslapd-auditlog-logging-hide-unhashed-pw"
+#define CONFIG_UNHASHED_PW_SWITCH_ATTRIBUTE "nsslapd-unhashed-pw-switch"
#define CONFIG_ROOTDN_ATTRIBUTE "nsslapd-rootdn"
#define CONFIG_ROOTPW_ATTRIBUTE "nsslapd-rootpw"
#define CONFIG_ROOTPWSTORAGESCHEME_ATTRIBUTE "nsslapd-rootpwstoragescheme"
@@ -2277,7 +2277,7 @@ typedef struct _slapdFrontendConfig {
PRInt64 disk_threshold;
int disk_grace_period;
int disk_logging_critical;
-
+ slapi_onoff_t unhashed_pw_switch; /* switch to on/off/nolog unhashed pw */
int ignore_time_skew;
#if defined(LINUX)
int malloc_mxfast; /* mallopt M_MXFAST */
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index e02127d..5c737ad 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -7057,6 +7057,14 @@ char **slapi_str2charray_ext( char *str, char *brkstr, int allow_dups );
#endif
#endif
+/* Used to make unhashed passwords available to plugins. */
+#define PSEUDO_ATTR_UNHASHEDUSERPASSWORD "unhashed#user#password"
+
+/* Unhashed password */
+#define SLAPD_UNHASHED_PW_OFF 0
+#define SLAPD_UNHASHED_PW_ON 1
+#define SLAPD_UNHASHED_PW_NOLOG 2
+
/**
* Set given "type: value" to the plugin default config entry
* (cn=plugin default config,cn=config) unless the same "type: value" pair
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 18f0e94..9a4e339 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -816,6 +816,7 @@ int pw_rever_decode(char *cipher, char **plain, const char * attr_name);
/* config routines */
int slapi_config_get_readonly();
+int slapi_config_get_unhashed_pw_switch();
/*
* charray.c
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
index 7a753f8..8c0b7ee 100644
--- a/ldap/servers/slapd/util.c
+++ b/ldap/servers/slapd/util.c
@@ -325,13 +325,15 @@ int slapi_mods2entry (Slapi_Entry **e, const char *idn, LDAPMod **iattrs)
return rc;
}
-int slapi_entry2mods (const Slapi_Entry *e, char **dn, LDAPMod ***attrs)
+int
+slapi_entry2mods (const Slapi_Entry *e, char **dn, LDAPMod ***attrs)
{
Slapi_Mods smods;
Slapi_Attr *attr;
Slapi_Value **va;
char *type;
int rc;
+ int unhashed_pw_on = (SLAPD_UNHASHED_PW_ON == config_get_unhashed_pw_switch());
PR_ASSERT (e && attrs);
@@ -343,8 +345,11 @@ int slapi_entry2mods (const Slapi_Entry *e, char **dn, LDAPMod ***attrs)
while (rc == 0)
{
if ( NULL != ( va = attr_get_present_values( attr ))) {
- slapi_attr_get_type(attr, &type);
- slapi_mods_add_mod_values(&smods, LDAP_MOD_ADD, type, va );
+ slapi_attr_get_type(attr, &type);
+ if (unhashed_pw_on || strcasecmp(type, PSEUDO_ATTR_UNHASHEDUSERPASSWORD)) {
+ /* SLAPD_UNHASHED_PW_ON or type is not unhashed pw */
+ slapi_mods_add_mod_values(&smods, LDAP_MOD_ADD, type, va );
+ }
}
rc = slapi_entry_next_attr(e, attr, &attr);
}
--
1.9.3