From 7292aa0923a530ded9af0116ffe9bdc8213355e6 Mon Sep 17 00:00:00 2001
From: HAMANO Tsukasa <hamano@osstech.co.jp>
Date: Fri, 30 Sep 2016 21:26:59 -0500
Subject: [PATCH] ITS#8349 - Fix ppolicy behavior when pwdInHistory is changed

---
 servers/slapd/overlays/ppolicy.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c
index ff1ad4f419..48215c6686 100644
--- a/servers/slapd/overlays/ppolicy.c
+++ b/servers/slapd/overlays/ppolicy.c
@@ -1622,7 +1622,7 @@ ppolicy_modify( Operation *op, SlapReply *rs )
 	slap_overinst		*on = (slap_overinst *)op->o_bd->bd_info;
 	pp_info			*pi = on->on_bi.bi_private;
 	int			i, rc, mod_pw_only, pwmod, pwmop = -1, deladd,
-				hsize = 0;
+				hsize = 0, hskip;
 	PassPolicy		pp;
 	Modifications		*mods = NULL, *modtail = NULL,
 				*ml, *delmod, *addmod;
@@ -2041,7 +2041,10 @@ ppolicy_modify( Operation *op, SlapReply *rs )
 			pErr = PP_passwordInHistory;
 			goto return_results;
 		}
-	
+
+		/* We need this when reduce pwdInHistory */
+		hskip = hsize - pp.pwdInHistory;
+
 		/*
 		 * Iterate through the password history, and fail on any
 		 * password matches.
@@ -2050,6 +2053,10 @@ ppolicy_modify( Operation *op, SlapReply *rs )
 		at.a_vals = cr;
 		cr[1].bv_val = NULL;
 		for(p=tl; p; p=p->next) {
+			if(hskip > 0){
+				hskip--;
+				continue;
+			}
 			cr[0] = p->pw;
 			/* FIXME: no access checking? */
 			rc = slap_passwd_check( op, NULL, &at, bv, &txt );
@@ -2158,7 +2165,19 @@ do_modify:
 			modtail = mods;
 		}
 
-		if (!got_history && pp.pwdInHistory > 0) {
+		/* Delete all pwdInHistory attribute */
+		if (!got_history && pp.pwdInHistory == 0 &&
+            attr_find(e->e_attrs, ad_pwdHistory )){
+			mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 );
+			mods->sml_op = LDAP_MOD_DELETE;
+			mods->sml_flags = SLAP_MOD_INTERNAL;
+			mods->sml_desc = ad_pwdHistory;
+			mods->sml_next = NULL;
+			modtail->sml_next = mods;
+			modtail = mods;
+		}
+
+		if (!got_history && pp.pwdInHistory > 0){
 			if (hsize >= pp.pwdInHistory) {
 				/*
 				 * We use the >= operator, since we are going to add
-- 
GitLab