From 9022d77690b7e932e7fddc9d4c354f52c9c8121f Mon Sep 17 00:00:00 2001 From: Noriko Hosoi 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