Author: nkinder
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv15940/ldap/servers/slapd
Modified Files:
passwd_extop.c pw.c
Log Message:
Resolves: 248924
Summary: Make password modify extended operation reset expired passwords.
Index: passwd_extop.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/passwd_extop.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- passwd_extop.c 15 Jan 2009 18:24:48 -0000 1.19
+++ passwd_extop.c 16 Jan 2009 05:26:42 -0000 1.20
@@ -143,8 +143,8 @@
/* Construct Mods pblock and perform the modify operation
* Sets result of operation in SLAPI_PLUGIN_INTOP_RESULT
*/
-static int passwd_apply_mods(const char *dn, Slapi_Mods *mods, LDAPControl
**req_controls,
- LDAPControl ***resp_controls)
+static int passwd_apply_mods(Slapi_PBlock *pb_orig, const char *dn, Slapi_Mods *mods,
+ LDAPControl **req_controls, LDAPControl ***resp_controls)
{
Slapi_PBlock pb;
LDAPControl **req_controls_copy = NULL;
@@ -168,7 +168,19 @@
pw_get_componentID(), /* PluginID */
0); /* Flags */
+ /* We copy the connection from the original pblock into the
+ * pblock we use for the internal modify operation. We do
+ * this to allow the password policy code to be able to tell
+ * that the password change was initiated by the user who
+ * sent the extended operation instead of always assuming
+ * that it was done by the root DN. */
+ pb.pb_conn = pb_orig->pb_conn;
+
ret =slapi_modify_internal_pb (&pb);
+
+ /* We now clean up the connection that we copied into the
+ * new pblock. We want to leave it untouched. */
+ pb.pb_conn = NULL;
slapi_pblock_get(&pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
@@ -195,8 +207,8 @@
/* Modify the userPassword attribute field of the entry */
-static int passwd_modify_userpassword(Slapi_Entry *targetEntry, const char *newPasswd,
- LDAPControl **req_controls, LDAPControl ***resp_controls)
+static int passwd_modify_userpassword(Slapi_PBlock *pb_orig, Slapi_Entry *targetEntry,
+ const char *newPasswd, LDAPControl **req_controls, LDAPControl ***resp_controls)
{
char *dn = NULL;
int ret = 0;
@@ -209,7 +221,7 @@
slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, SLAPI_USERPWD_ATTR, newPasswd);
- ret = passwd_apply_mods(dn, &smods, req_controls, resp_controls);
+ ret = passwd_apply_mods(pb_orig, dn, &smods, req_controls, resp_controls);
slapi_mods_done(&smods);
@@ -770,7 +782,7 @@
slapi_pblock_get(pb, SLAPI_REQCONTROLS, &req_controls);
/* Now we're ready to make actual password change */
- ret = passwd_modify_userpassword(targetEntry, newPasswd, req_controls,
&resp_controls);
+ ret = passwd_modify_userpassword(pb, targetEntry, newPasswd, req_controls,
&resp_controls);
/* Set the response controls if necessary. We want to do this now
* so it is set for both the success and failure cases. The pblock
Index: pw.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/pw.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- pw.c 24 Nov 2008 17:16:55 -0000 1.19
+++ pw.c 16 Jan 2009 05:26:42 -0000 1.20
@@ -160,6 +160,7 @@
/* Checks if the specified value is encoded.
Returns 1 if it is and 0 otherwise
*/
+/* NGK - Use this for checking if the password is hashed */
int slapi_is_encoded (char *value)
{
struct pw_scheme *is_hashed = NULL;
@@ -554,6 +555,11 @@
time_t cur_time;
char *dn;
passwdPolicy *pwpolicy = NULL;
+ int internal_op = 0;
+ Slapi_Operation *operation = NULL;
+
+ slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
+ internal_op = slapi_operation_is_flag_set(operation, SLAPI_OP_FLAG_INTERNAL);
cur_time = current_time();
slapi_pblock_get( pb, SLAPI_TARGET_DN, &dn );
@@ -588,12 +594,13 @@
/* Clear the passwordgraceusertime from the user entry */
slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "passwordgraceusertime",
"0");
- /* if the password is reset by root, mark it the first time logon */
-
- if ( pb->pb_requestor_isroot == 1 &&
- pwpolicy->pw_must_change){
+ /* If the password is reset by root, mark it the first time logon. If this is an
internal
+ * operation, we have a special case for the password modify extended operation where
+ * we stuff the actual user who initiated the password change in pb_conn. We check
+ * for this special case to ensure we reset the expiration date properly. */
+ if ((internal_op && pwpolicy->pw_must_change && (!pb->pb_conn ||
slapi_dn_isroot(pb->pb_conn->c_dn))) ||
+ (!internal_op && pwpolicy->pw_must_change &&
(pb->pb_requestor_isroot == 1))) {
pw_exp_date = NO_TIME;
-
} else if ( pwpolicy->pw_exp == 1 ) {
Slapi_Entry *pse = NULL;
@@ -757,6 +764,20 @@
int max_repeated = 0;
int num_categories = 0;
+ /* NGK - Check if password is already hashed and reject if so. */
+ /* NGK - Allow if root or if replication user */
+ if (slapi_is_encoded(slapi_value_get_string(vals[i]))) {
+ PR_snprintf( errormsg, BUFSIZ,
+ "invalid password syntax - pre-hashed passwords are not allowed");
+ if ( pwresponse_req == 1 ) {
+ slapi_pwpolicy_make_response_control ( pb, -1, -1,
+ LDAP_PWPOLICY_INVALIDPWDSYNTAX );
+ }
+ pw_send_ldap_result ( pb, LDAP_CONSTRAINT_VIOLATION, NULL, errormsg, 0, NULL );
+ delete_passwdPolicy(&pwpolicy);
+ return( 1 );
+ }
+
/* check for the minimum password length */
if ( pwpolicy->pw_minlength >
ldap_utf8characters((char *)slapi_value_get_string( vals[i] )) )