Browse Source

Resolves: 207893
Summary: Check if passwords are already hashed before sync'ing with AD.

Nathan Kinder 18 years ago
parent
commit
20a4d4d200

+ 62 - 2
ldap/servers/plugins/replication/windows_protocol_util.c

@@ -1375,7 +1375,37 @@ windows_create_remote_entry(Private_Repl_Protocol *prp,Slapi_Entry *original_ent
 
 
 				slapi_valueset_first_value(vs,&value);
 				slapi_valueset_first_value(vs,&value);
 				password_value = slapi_value_get_string(value);
 				password_value = slapi_value_get_string(value);
-				*password = slapi_ch_strdup(password_value);
+				/* We need to check if the first character of password_value is an 
+				 * opening brace since strstr will simply return it's first argument
+				 * if it is an empty string. */
+				if (password_value && (*password_value == '{')) {
+					if (strchr( password_value, '}' )) {
+						/* A storage scheme is present.  Check if it's the
+						 * clear storage scheme. */
+						if ((strlen(password_value) >= PASSWD_CLEAR_PREFIX_LEN + 1) &&
+						    (strncasecmp(password_value, PASSWD_CLEAR_PREFIX, PASSWD_CLEAR_PREFIX_LEN) == 0)) {
+							/* This password is in clear text.  Strip off the clear prefix
+							 * and sync it. */
+							*password = slapi_ch_strdup(password_value + PASSWD_CLEAR_PREFIX_LEN);
+						} else {
+							/* This password is stored in a non-cleartext format.
+							 * We can only sync cleartext passwords. */
+							slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+								"%s: windows_create_remote_entry: "
+								"Password is already hashed.  Not syncing.\n",
+								agmt_get_long_name(prp->agmt));
+						}
+					} else {
+						/* This password doesn't have a storage prefix but
+						 * just happens to start with the '{' character.  We'll
+						 * assume that it's just a cleartext password without
+						 * the proper storage prefix. */
+						*password = slapi_ch_strdup(password_value);
+					}
+				} else {
+					/* This password has no storage prefix, or the password is empty */
+					*password = slapi_ch_strdup(password_value);
+				}
 			}
 			}
 
 
 		}
 		}
@@ -1554,7 +1584,37 @@ windows_map_mods_for_replay(Private_Repl_Protocol *prp,LDAPMod **original_mods,
 				{
 				{
 					char *password_value = NULL;
 					char *password_value = NULL;
 					password_value = mod->mod_bvalues[0]->bv_val;
 					password_value = mod->mod_bvalues[0]->bv_val;
-					*password = slapi_ch_strdup(password_value);
+					/* We need to check if the first character of password_value is an 
+					 * opening brace since strstr will simply return it's first argument
+					 * if it is an empty string. */
+					if (password_value && (*password_value == '{')) {
+						if (strchr( password_value, '}' )) {
+							/* A storage scheme is present.  Check if it's the
+							 * clear storage scheme. */
+							if ((strlen(password_value) >= PASSWD_CLEAR_PREFIX_LEN + 1) &&
+							     (strncasecmp(password_value, PASSWD_CLEAR_PREFIX, PASSWD_CLEAR_PREFIX_LEN) == 0)) {
+								/* This password is in clear text.  Strip off the clear prefix
+								 * and sync it. */
+								*password = slapi_ch_strdup(password_value + PASSWD_CLEAR_PREFIX_LEN);
+							} else {
+								/* This password is stored in a non-cleartext format.
+								 * We can only sync cleartext passwords. */
+								slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+									"%s: windows_create_remote_entry: "
+									"Password is already hashed.  Not syncing.\n",
+									agmt_get_long_name(prp->agmt));
+							}
+						} else {
+							/* This password doesn't have a storage prefix but
+							 * just happens to start with the '{' character.  We'll
+							 * assume that it's just a cleartext password without
+							 * the proper storage prefix. */
+							*password = slapi_ch_strdup(password_value);
+						}
+					} else {
+						/* This password has no storage prefix, or the password is empty */
+						*password = slapi_ch_strdup(password_value);
+					}
 				}
 				}
 			}
 			}
 		}
 		}

+ 3 - 1
ldap/servers/plugins/replication/windowsrepl.h

@@ -99,4 +99,6 @@ void windows_conn_set_agmt_changed(Repl_Connection *conn);
 #define FAKE_STREET_ATTR_NAME "in#place#of#streetaddress"
 #define FAKE_STREET_ATTR_NAME "in#place#of#streetaddress"
 /* Used to work around contrained attribute legth for initials on AD */
 /* Used to work around contrained attribute legth for initials on AD */
 #define AD_INITIALS_LENGTH 6
 #define AD_INITIALS_LENGTH 6
-
+/* Used to check for pre-hashed passwords when syncing */
+#define PASSWD_CLEAR_PREFIX "{clear}"
+#define PASSWD_CLEAR_PREFIX_LEN 7