Wrap the password change extop in a 389-ds transaction and ensure that administratively set passwords are always considered expired.

I also removed an extraneous init from the betxn conversion. This was causing an error to be raised in the 389-ds error logs.

rob
>From 58b247d25251402c2e2fa408e5a54f830c5c082f Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Wed, 5 Dec 2012 23:27:57 -0500
Subject: [PATCH] Password change in a transcation, ensure passwords are truly
 expired.

Wrap the password change extop in a transaction.

Fix the case where a password is reset and then immediately used. If done
fast enough then the KDC may not detect that the password is expired and
grant access using the expired password rather than prompting for a reset.

https://fedorahosted.org/freeipa/ticket/1064
---
 .../ipa-pwd-extop/ipa_pwd_extop.c                  | 31 +++++++++++++++++++---
 .../ipa-pwd-extop/ipapwd_common.c                  |  6 +++++
 .../ipa-pwd-extop/ipapwd_prepost.c                 |  1 -
 3 files changed, 34 insertions(+), 4 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 425b1c07d8e165231443dd36bfc5a59306f9f044..7fcf647f783db48fe903aa11148df3dcd87e9404 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
@@ -85,6 +85,7 @@ Slapi_PluginDesc ipapwd_plugin_desc = {
 };
 
 void *ipapwd_plugin_id;
+static int usetxn = 0;
 
 static int filter_keys(struct ipapwd_krbcfg *krbcfg,
                        struct ipapwd_keyset *kset)
@@ -158,6 +159,7 @@ static int ipapwd_chpwop(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
 	struct ipapwd_data pwdata;
 	int is_krb, is_smb, is_ipant;
     char *principal = NULL;
+	Slapi_PBlock *chpwop_pb = NULL;
 
 	/* Get the ber value of the extended operation */
 	slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value);
@@ -238,6 +240,22 @@ static int ipapwd_chpwop(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
 	}
 
 parse_req_done:
+
+	if (usetxn) {
+                Slapi_DN *sdn = slapi_sdn_new_dn_byref(dn);
+                Slapi_Backend *be = slapi_be_select(sdn);
+                slapi_sdn_free(&sdn);
+                if (be) {
+			chpwop_pb = slapi_pblock_new();
+			slapi_pblock_set(chpwop_pb, SLAPI_BACKEND, be);
+			rc = slapi_back_transaction_begin(chpwop_pb);
+			if (rc) {
+				LOG_FATAL("failed to start transaction\n");
+			}
+		} else {
+			LOG_FATAL("failed to get be backend from %s\n", dn);
+		}
+	}
 	/* Uncomment for debugging, otherwise we don't want to leak the
 	 * password values into the log... */
 	/* LDAPDebug( LDAP_DEBUG_ARGS, "passwd: dn (%s), oldPasswd (%s),
@@ -499,6 +517,14 @@ parse_req_done:
 
 	/* Free anything that we allocated above */
 free_and_return:
+	if (usetxn && chpwop_pb) {
+		if (rc) { /* fails */
+			slapi_back_transaction_abort(chpwop_pb);
+		} else {
+			slapi_back_transaction_commit(chpwop_pb);
+		}
+		slapi_pblock_destroy(chpwop_pb);
+	}
 	slapi_ch_free_string(&oldPasswd);
 	slapi_ch_free_string(&newPasswd);
 	/* Either this is the same pointer that we allocated and set above,
@@ -1271,12 +1297,11 @@ int ipapwd_init( Slapi_PBlock *pb )
 {
     int ret;
     Slapi_Entry *plugin_entry = NULL;
-    int is_betxn = 0;
 
     /* get args */
     if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
         plugin_entry) {
-            is_betxn = slapi_entry_attr_get_bool(plugin_entry,
+            usetxn = slapi_entry_attr_get_bool(plugin_entry,
                                                  "nsslapd-pluginbetxn");
     }
 
@@ -1310,7 +1335,7 @@ int ipapwd_init( Slapi_PBlock *pb )
         return -1;
     }
 
-    if (is_betxn) {
+    if (usetxn) {
         slapi_register_plugin("betxnpreoperation", 1,
                               "ipapwd_pre_init_betxn", ipapwd_pre_init_betxn,
                               "IPA pwd pre ops betxn", NULL,
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_common.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_common.c
index cac8bf45f3770e102c49735335066b7bc761dba2..bb1d96ade8c22bf60138a78957e409cf1b0de055 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_common.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_common.c
@@ -640,6 +640,12 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
          * force a password change on the next login.
          * But not if Directory Manager */
         if (data->changetype == IPA_CHANGETYPE_ADMIN) {
+            /* The expiration date needs to be older than the current time
+             * otherwise the KDC may not immediately register the password
+             * as expired. The last password change needs to match the
+             * password expiration otherwise minlife issues will arise.
+             */
+            data->timeNow -= 1;
             data->expireTime = data->timeNow;
         }
 
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c
index 0e4a63b493347f8c88efdaeac09cf7da92dfcd63..3b512a4744d3edddc52e224c11aaa93388d06b75 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c
@@ -1313,7 +1313,6 @@ int ipapwd_pre_init_betxn(Slapi_PBlock *pb)
 
     ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01);
     if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&ipapwd_plugin_desc);
-    if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_BIND_FN, (void *)ipapwd_pre_bind);
     if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN, (void *)ipapwd_pre_add);
     if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN, (void *)ipapwd_pre_mod);
 
-- 
1.8.0

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

Reply via email to