|
|
dc8c34 |
From ed46c6207742d6660a3034504f098d909b20cc71 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
dc8c34 |
Date: Mon, 20 Jan 2014 14:36:43 -0500
|
|
|
dc8c34 |
Subject: [PATCH 155/225] Ticket 47678 - modify-delete userpassword
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Description: Needed to backport ticket 394 to 1.2.11. Had to remove the password
|
|
|
dc8c34 |
extension code from the original patch.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/47678
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed by: nhosoi(Thanks!)
|
|
|
dc8c34 |
(cherry picked from commit a3b6e22cec1fb8cb5c55e8b848bec4a60f924849)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/slapd/modify.c | 168 +++++++++++++++++++++++++++++++++++---
|
|
|
dc8c34 |
ldap/servers/slapd/slapi-plugin.h | 11 ---
|
|
|
dc8c34 |
2 files changed, 158 insertions(+), 21 deletions(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
|
|
|
dc8c34 |
index 5e52f26..9db10c5 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/modify.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/modify.c
|
|
|
dc8c34 |
@@ -80,6 +80,7 @@ static void remove_mod (Slapi_Mods *smods, const char *type, Slapi_Mods *smod_un
|
|
|
dc8c34 |
#endif
|
|
|
dc8c34 |
static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_Mods *smods);
|
|
|
dc8c34 |
static int hash_rootpw (LDAPMod **mods);
|
|
|
dc8c34 |
+static int valuearray_init_bervalarray_unhashed_only(struct berval **bvals, Slapi_Value ***cvals);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
#ifdef LDAP_DEBUG
|
|
|
dc8c34 |
static const char*
|
|
|
dc8c34 |
@@ -833,19 +834,134 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw)
|
|
|
dc8c34 |
if (strcasecmp (pw_mod->mod_type, SLAPI_USERPWD_ATTR) != 0)
|
|
|
dc8c34 |
continue;
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if (LDAP_MOD_DELETE == pw_mod->mod_op) {
|
|
|
dc8c34 |
+ if ( SLAPI_IS_MOD_DELETE(pw_mod->mod_op) ) {
|
|
|
dc8c34 |
Slapi_Attr *a = NULL;
|
|
|
dc8c34 |
- /* delete pseudo password attribute if it exists in the entry */
|
|
|
dc8c34 |
- if (!slapi_entry_attr_find(e, unhashed_pw_attr, &a)) {
|
|
|
dc8c34 |
- slapi_mods_add_mod_values(&smods, pw_mod->mod_op,
|
|
|
dc8c34 |
- unhashed_pw_attr, va);
|
|
|
dc8c34 |
+ struct pw_scheme *pwsp = NULL;
|
|
|
dc8c34 |
+ int remove_unhashed_pw = 1;
|
|
|
dc8c34 |
+ char *valpwd = NULL;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /* if there are mod values, we need to delete a specific userpassword */
|
|
|
dc8c34 |
+ for ( i = 0; pw_mod->mod_bvalues != NULL && pw_mod->mod_bvalues[i] != NULL; i++ ) {
|
|
|
dc8c34 |
+ char *password = slapi_ch_strdup(pw_mod->mod_bvalues[i]->bv_val);
|
|
|
dc8c34 |
+ pwsp = pw_val2scheme( password, &valpwd, 1 );
|
|
|
dc8c34 |
+ if(strcmp(pwsp->pws_name, "CLEAR") == 0){
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * CLEAR password
|
|
|
dc8c34 |
+ *
|
|
|
dc8c34 |
+ * Ok, so now we to check the entry's userpassword values.
|
|
|
dc8c34 |
+ * First, find out the password encoding of the entry's pw.
|
|
|
dc8c34 |
+ * Then compare our clear text password to the encoded userpassword
|
|
|
dc8c34 |
+ * using the proper scheme. If we have a match, we know which
|
|
|
dc8c34 |
+ * userpassword value to delete.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ Slapi_Attr *pw = NULL;
|
|
|
dc8c34 |
+ struct berval bval, *bv[2];
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if(slapi_entry_attr_find(e, SLAPI_USERPWD_ATTR, &pw) == 0 && pw){
|
|
|
dc8c34 |
+ struct pw_scheme *pass_scheme = NULL;
|
|
|
dc8c34 |
+ Slapi_Value **present_values = NULL;
|
|
|
dc8c34 |
+ char *pval = NULL;
|
|
|
dc8c34 |
+ int ii;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ present_values = attr_get_present_values(pw);
|
|
|
dc8c34 |
+ for(ii = 0; present_values && present_values[ii]; ii++){
|
|
|
dc8c34 |
+ const char *userpwd = slapi_value_get_string(present_values[ii]);
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ pass_scheme = pw_val2scheme( (char *)userpwd, &pval, 1 );
|
|
|
dc8c34 |
+ if(strcmp(pass_scheme->pws_name,"CLEAR")){
|
|
|
dc8c34 |
+ /* its encoded, so compare it */
|
|
|
dc8c34 |
+ if((*(pass_scheme->pws_cmp))( valpwd, pval ) == 0 ){
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Match, replace the mod value with the encoded password
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ slapi_ch_free_string(&pw_mod->mod_bvalues[i]->bv_val);
|
|
|
dc8c34 |
+ pw_mod->mod_bvalues[i]->bv_val = strdup(userpwd);
|
|
|
dc8c34 |
+ pw_mod->mod_bvalues[i]->bv_len = strlen(userpwd);
|
|
|
dc8c34 |
+ free_pw_scheme( pass_scheme );
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ /* userpassword is already clear text, nothing to do */
|
|
|
dc8c34 |
+ free_pw_scheme( pass_scheme );
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ free_pw_scheme( pass_scheme );
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Finally, delete the unhashed userpassword
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ bval.bv_val = password;
|
|
|
dc8c34 |
+ bval.bv_len = strlen(password);
|
|
|
dc8c34 |
+ bv[0] = &bval;
|
|
|
dc8c34 |
+ bv[1] = NULL;
|
|
|
dc8c34 |
+ valuearray_init_bervalarray(bv, &va);
|
|
|
dc8c34 |
+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
|
|
|
dc8c34 |
+ valuearray_free(&va);
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Password is encoded, try and find a matching unhashed_password to delete
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ char **vals;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Grab the current unhashed passwords from the entry.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ vals = slapi_entry_attr_get_charray(e, unhashed_pw_attr);
|
|
|
dc8c34 |
+ if(vals){
|
|
|
dc8c34 |
+ int ii;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ for(ii = 0; vals && vals[ii]; ii++){
|
|
|
dc8c34 |
+ char *unhashed_pwd = vals[ii];
|
|
|
dc8c34 |
+ struct pw_scheme *unhashed_pwsp = NULL;
|
|
|
dc8c34 |
+ struct berval bval, *bv[2];
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /* prepare the value to delete from the list of unhashed userpasswords */
|
|
|
dc8c34 |
+ bval.bv_val = unhashed_pwd;
|
|
|
dc8c34 |
+ bval.bv_len = strlen(unhashed_pwd);
|
|
|
dc8c34 |
+ bv[0] = &bval;
|
|
|
dc8c34 |
+ bv[1] = NULL;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * Compare the clear text unhashed password, to the encoded password
|
|
|
dc8c34 |
+ * provided by the client.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ unhashed_pwsp = pw_val2scheme( unhashed_pwd, NULL, 1 );
|
|
|
dc8c34 |
+ if(strcmp(unhashed_pwsp->pws_name, "CLEAR") == 0){
|
|
|
dc8c34 |
+ if((*(pwsp->pws_cmp))(unhashed_pwd , valpwd) == 0 ){
|
|
|
dc8c34 |
+ /* match, add the delete mod for this particular unhashed userpassword */
|
|
|
dc8c34 |
+ valuearray_init_bervalarray(bv, &va);
|
|
|
dc8c34 |
+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
|
|
|
dc8c34 |
+ valuearray_free(&va);
|
|
|
dc8c34 |
+ free_pw_scheme( unhashed_pwsp );
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * We have a hashed unhashed_userpassword! We must delete it.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ valuearray_init_bervalarray(bv, &va);
|
|
|
dc8c34 |
+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
|
|
|
dc8c34 |
+ valuearray_free(&va);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ free_pw_scheme( unhashed_pwsp );
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ remove_unhashed_pw = 0; /* mark that we already removed the unhashed userpassword */
|
|
|
dc8c34 |
+ slapi_ch_free_string(&password);
|
|
|
dc8c34 |
+ free_pw_scheme( pwsp );
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (remove_unhashed_pw && !slapi_entry_attr_find(e, unhashed_pw_attr, &a)){
|
|
|
dc8c34 |
+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op,unhashed_pw_attr, va);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
- /* add pseudo password attribute */
|
|
|
dc8c34 |
- valuearray_init_bervalarray(pw_mod->mod_bvalues, &va);
|
|
|
dc8c34 |
- slapi_mods_add_mod_values(&smods, pw_mod->mod_op,
|
|
|
dc8c34 |
- unhashed_pw_attr, va);
|
|
|
dc8c34 |
- valuearray_free(&va);
|
|
|
dc8c34 |
+ /* add pseudo password attribute - only if it's value is clear text */
|
|
|
dc8c34 |
+ valuearray_init_bervalarray_unhashed_only(pw_mod->mod_bvalues, &va);
|
|
|
dc8c34 |
+ if(va){
|
|
|
dc8c34 |
+ slapi_mods_add_mod_values(&smods, pw_mod->mod_op, unhashed_pw_attr, va);
|
|
|
dc8c34 |
+ valuearray_free(&va);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* Init new value array for hashed value */
|
|
|
dc8c34 |
@@ -1301,3 +1417,35 @@ hash_rootpw (LDAPMod **mods)
|
|
|
dc8c34 |
return 0;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+/*
|
|
|
dc8c34 |
+ * Only add password mods that are in clear text. The console likes to send two mods:
|
|
|
dc8c34 |
+ * - Already encoded password
|
|
|
dc8c34 |
+ * - Clear text password
|
|
|
dc8c34 |
+ *
|
|
|
dc8c34 |
+ * We don't want to add the encoded value to the unhashed_userpassword attr
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+static int
|
|
|
dc8c34 |
+valuearray_init_bervalarray_unhashed_only(struct berval **bvals, Slapi_Value ***cvals)
|
|
|
dc8c34 |
+{
|
|
|
dc8c34 |
+ int n;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ for(n = 0; bvals != NULL && bvals[n] != NULL; n++);
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ if(n == 0){
|
|
|
dc8c34 |
+ *cvals = NULL;
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ struct pw_scheme *pwsp = NULL;
|
|
|
dc8c34 |
+ int i,p;
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+ *cvals = (Slapi_Value **) slapi_ch_malloc((n + 1) * sizeof(Slapi_Value *));
|
|
|
dc8c34 |
+ for(i = 0, p = 0; i < n; i++){
|
|
|
dc8c34 |
+ pwsp = pw_val2scheme( bvals[i]->bv_val, NULL, 1 );
|
|
|
dc8c34 |
+ if(strcmp(pwsp->pws_name, "CLEAR") == 0){
|
|
|
dc8c34 |
+ (*cvals)[p++] = slapi_value_new_berval(bvals[i]);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ free_pw_scheme( pwsp );
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ (*cvals)[p] = NULL;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ return n;
|
|
|
dc8c34 |
+}
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
|
|
dc8c34 |
index eeac43e..58feaf3 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/slapi-plugin.h
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/slapi-plugin.h
|
|
|
dc8c34 |
@@ -7227,17 +7227,6 @@ void slapi_set_plugin_open_rootdn_bind(Slapi_PBlock *pb);
|
|
|
dc8c34 |
#define SLAPI_EXT_SET_REPLACE 1
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/**
|
|
|
dc8c34 |
- * Get entry extension
|
|
|
dc8c34 |
- *
|
|
|
dc8c34 |
- * \param entry is the entry to retrieve the extension from
|
|
|
dc8c34 |
- * \param vals is the array of (Slapi_Value *), which directly refers the extension. Caller must duplicate it to use it for other than referring.
|
|
|
dc8c34 |
- *
|
|
|
dc8c34 |
- * \return LDAP_SUCCESS if successful.
|
|
|
dc8c34 |
- * \return non-zero otherwise.
|
|
|
dc8c34 |
- */
|
|
|
dc8c34 |
-int slapi_pw_get_entry_ext(Slapi_Entry *entry, Slapi_Value ***vals);
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
-/**
|
|
|
dc8c34 |
* Set entry extension
|
|
|
dc8c34 |
*
|
|
|
dc8c34 |
* \param entry is the entry to set the extension to
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.8.1.4
|
|
|
dc8c34 |
|