Although we were properly checking that the user successfully
authenticated (either through a password bind or a GSSAPI bind) we were
not enforcing the requirement to provide us with the old password, and
this is better security hygiene.

Fixes: https://fedorahosted.org/freeipa/ticket/1814

Tested and works for me.

Properly requires old password for self password changes. Do not require
it for admin password changes.

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York
>From 99f4f55bf65391f52f2743d174f185dedad438e8 Mon Sep 17 00:00:00 2001
From: Simo Sorce <sso...@redhat.com>
Date: Fri, 16 Sep 2011 14:18:38 -0400
Subject: [PATCH 2/2] ipa-pwd-extop: Enforce old password checks

If a user is changing his own password, then require the old password to be
sent for validation purposes.
---
 .../ipa-pwd-extop/ipa_pwd_extop.c                  |   65 +++++++++++++++++++-
 1 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
index 9fdf17713228b6c7b1c1748c8d5167dacb232ec2..95ac68e9cfc8d7024048d8a9d2793044f01dd1aa 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c
@@ -283,7 +283,7 @@ parse_req_done:
 		dn = slapi_ch_strdup(bindDN);
 		LOG_TRACE("Missing userIdentity in request, "
                           "using the bind DN instead.\n");
-	 }
+	}
 
 	 if (slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET, dn )) {
 		LOG_FATAL("slapi_pblock_set failed!\n");
@@ -301,6 +301,69 @@ parse_req_done:
 		goto free_and_return;
 	 }
 
+    if (dn) {
+        Slapi_DN *bind_sdn;
+        Slapi_DN *target_sdn;
+
+        /* if the user changing the password is self, we must request the
+         * old password and verify it matches the current one before
+         * proceeding with the password change */
+        bind_sdn = slapi_sdn_new_dn_byref(bindDN);
+        target_sdn = slapi_sdn_new_dn_byref(dn);
+        if (!bind_sdn || !target_sdn) {
+            LOG_OOM();
+            rc = LDAP_OPERATIONS_ERROR;
+            goto free_and_return;
+        }
+        /* this one will normalize and compare, so difference in case will be
+         * correctly handled */
+        ret = slapi_sdn_compare(bind_sdn, target_sdn);
+        if (ret == 0) {
+            Slapi_Value *cpw[2] = { NULL, NULL };
+            Slapi_Value *pw;
+            char *cur_pw;
+
+            if (oldPasswd == NULL || *oldPasswd == '\0') {
+                LOG_FATAL("Old password was not provided!\n");
+                rc = LDAP_INVALID_CREDENTIALS;
+                goto free_and_return;
+            }
+
+            /* if the user is changing his own password we need to check that
+             * oldPasswd matches the current password */
+            cur_pw = slapi_entry_attr_get_charptr(targetEntry,
+                                                  "userPassword");
+            if (!cur_pw) {
+                LOG_FATAL("User has no current password?\n");
+                rc = LDAP_UNWILLING_TO_PERFORM;
+                goto free_and_return;
+            }
+
+            cpw[0] = slapi_value_new_string(cur_pw);
+            pw = slapi_value_new_string(oldPasswd);
+            if (!cpw[0] || !pw) {
+                LOG_OOM();
+                rc = LDAP_OPERATIONS_ERROR;
+                goto free_and_return;
+            }
+
+            ret = slapi_pw_find_sv(cpw, pw);
+
+            slapi_value_free(&cpw[0]);
+            slapi_value_free(&pw);
+
+            if (ret != 0) {
+                LOG_TRACE("Invalid password!\n");
+                rc = LDAP_INVALID_CREDENTIALS;
+                goto free_and_return;
+            }
+        }
+    } else {
+        LOG_TRACE("Undefined target DN!\n");
+        rc = LDAP_OPERATIONS_ERROR;
+        goto free_and_return;
+    }
+
 	 rc = ipapwd_entry_checks(pb, targetEntry,
 				&is_root, &is_krb, &is_smb,
 				SLAPI_USERPWD_ATTR, SLAPI_ACL_WRITE);
-- 
1.7.6.2

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to