[Fedora-directory-commits] ldapserver/ldap/servers/slapd libglobs.c, 1.6, 1.7 libslapd.def, 1.14, 1.15 modify.c, 1.7, 1.8 proto-slap.h, 1.15, 1.16 pw.c, 1.8, 1.9 slap.h, 1.9, 1.10

Nathan Kinder (nkinder) fedora-directory-commits at redhat.com
Wed Jan 25 16:51:47 UTC 2006


Author: nkinder

Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv19454

Modified Files:
	libglobs.c libslapd.def modify.c proto-slap.h pw.c slap.h 
Log Message:
178867 - Enhanced password syntax checking


Index: libglobs.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/libglobs.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- libglobs.c	19 Apr 2005 22:07:36 -0000	1.6
+++ libglobs.c	25 Jan 2006 16:51:39 -0000	1.7
@@ -277,6 +277,33 @@
 	{CONFIG_PW_MINLENGTH_ATTRIBUTE, config_set_pw_minlength,
 		NULL, 0,
 		(void**)&global_slapdFrontendConfig.pw_policy.pw_minlength, CONFIG_INT, NULL},
+	{CONFIG_PW_MINDIGITS_ATTRIBUTE, config_set_pw_mindigits,
+		NULL, 0,
+		(void**)&global_slapdFrontendConfig.pw_policy.pw_mindigits, CONFIG_INT, NULL},
+	{CONFIG_PW_MINALPHAS_ATTRIBUTE, config_set_pw_minalphas,
+		NULL, 0,
+		(void**)&global_slapdFrontendConfig.pw_policy.pw_minalphas, CONFIG_INT, NULL},
+	{CONFIG_PW_MINUPPERS_ATTRIBUTE, config_set_pw_minuppers,
+		NULL, 0,
+                (void**)&global_slapdFrontendConfig.pw_policy.pw_minuppers, CONFIG_INT, NULL},
+	{CONFIG_PW_MINLOWERS_ATTRIBUTE, config_set_pw_minlowers,
+		NULL, 0,
+		(void**)&global_slapdFrontendConfig.pw_policy.pw_minlowers, CONFIG_INT, NULL},
+        {CONFIG_PW_MINSPECIALS_ATTRIBUTE, config_set_pw_minspecials,
+                NULL, 0,
+                (void**)&global_slapdFrontendConfig.pw_policy.pw_minspecials, CONFIG_INT, NULL},
+	{CONFIG_PW_MIN8BIT_ATTRIBUTE, config_set_pw_min8bit,
+		NULL, 0,
+		(void**)&global_slapdFrontendConfig.pw_policy.pw_min8bit, CONFIG_INT, NULL},
+	{CONFIG_PW_MAXREPEATS_ATTRIBUTE, config_set_pw_maxrepeats,
+		NULL, 0,
+		(void**)&global_slapdFrontendConfig.pw_policy.pw_maxrepeats, CONFIG_INT, NULL},
+        {CONFIG_PW_MINCATEGORIES_ATTRIBUTE, config_set_pw_mincategories,
+                NULL, 0,
+                (void**)&global_slapdFrontendConfig.pw_policy.pw_mincategories, CONFIG_INT, NULL},
+	{CONFIG_PW_MINTOKENLENGTH_ATTRIBUTE, config_set_pw_mintokenlength,
+		NULL, 0,
+		(void**)&global_slapdFrontendConfig.pw_policy.pw_mintokenlength, CONFIG_INT, NULL},
 	{CONFIG_ERRORLOG_ATTRIBUTE, config_set_errorlog,
 		NULL, 0,
 		(void**)&global_slapdFrontendConfig.errorlog, CONFIG_STRING_OR_EMPTY, NULL},
@@ -751,7 +778,16 @@
   cfg->pw_policy.pw_must_change = LDAP_OFF;
   cfg->pw_policy.pw_syntax = LDAP_OFF;
   cfg->pw_policy.pw_exp = LDAP_OFF;
-  cfg->pw_policy.pw_minlength = 6;
+  cfg->pw_policy.pw_minlength = 8;
+  cfg->pw_policy.pw_mindigits = 0;
+  cfg->pw_policy.pw_minalphas = 0;
+  cfg->pw_policy.pw_minuppers = 0;
+  cfg->pw_policy.pw_minlowers = 0;
+  cfg->pw_policy.pw_minspecials = 0;
+  cfg->pw_policy.pw_min8bit = 0;
+  cfg->pw_policy.pw_maxrepeats = 0;
+  cfg->pw_policy.pw_mincategories = 3;
+  cfg->pw_policy.pw_mintokenlength = 3;
   cfg->pw_policy.pw_maxage = 8640000; /* 100 days     */
   cfg->pw_policy.pw_minage = 0;
   cfg->pw_policy.pw_warning = 86400; /* 1 day        */
@@ -1340,6 +1376,276 @@
 }
 
 int
+config_set_pw_mindigits( const char *attrname, char *value, char *errorbuf, int apply ) {
+  int retVal = LDAP_SUCCESS, minDigits = 0;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+        return LDAP_OPERATIONS_ERROR;
+  }
+
+  minDigits = atoi(value);
+  if ( minDigits < 0 || minDigits > 64 ) {
+        PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+                          "password minimum number of digits \"%s\" is invalid. "
+                          "The minimum number of digits must range from 0 to 64.",
+                          value );
+        retVal = LDAP_OPERATIONS_ERROR;
+        return retVal;
+  }
+
+  if ( apply ) {
+        CFG_LOCK_WRITE(slapdFrontendConfig);
+
+        slapdFrontendConfig->pw_policy.pw_mindigits = minDigits;
+
+        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+  }
+
+  return retVal;
+}
+
+int
+config_set_pw_minalphas( const char *attrname, char *value, char *errorbuf, int apply ) {
+  int retVal = LDAP_SUCCESS, minAlphas = 0;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+        return LDAP_OPERATIONS_ERROR;
+  }
+
+  minAlphas = atoi(value);
+  if ( minAlphas < 0 || minAlphas > 64 ) {
+        PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+                          "password minimum number of alphas \"%s\" is invalid. "
+                          "The minimum number of alphas must range from 0 to 64.",
+                          value );
+        retVal = LDAP_OPERATIONS_ERROR;
+        return retVal;
+  }
+
+  if ( apply ) {
+        CFG_LOCK_WRITE(slapdFrontendConfig);
+
+        slapdFrontendConfig->pw_policy.pw_minalphas = minAlphas;
+
+        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+  }
+
+  return retVal;
+}
+
+int
+config_set_pw_minuppers( const char *attrname, char *value, char *errorbuf, int apply ) {
+  int retVal = LDAP_SUCCESS, minUppers = 0;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+        return LDAP_OPERATIONS_ERROR;
+  }
+
+  minUppers = atoi(value);
+  if ( minUppers < 0 || minUppers > 64 ) {
+        PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+                          "password minimum number of uppercase characters \"%s\" is invalid. "
+                          "The minimum number of uppercase characters must range from 0 to 64.",
+                          value );
+        retVal = LDAP_OPERATIONS_ERROR;
+        return retVal;
+  }
+
+  if ( apply ) {
+        CFG_LOCK_WRITE(slapdFrontendConfig);
+
+        slapdFrontendConfig->pw_policy.pw_minuppers = minUppers;
+
+        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+  }
+
+  return retVal;
+}
+
+int
+config_set_pw_minlowers( const char *attrname, char *value, char *errorbuf, int apply ) {
+  int retVal = LDAP_SUCCESS, minLowers = 0;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+        return LDAP_OPERATIONS_ERROR;
+  }
+
+  minLowers = atoi(value);
+  if ( minLowers < 0 || minLowers > 64 ) {
+        PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+                          "password minimum number of lowercase characters \"%s\" is invalid. "
+                          "The minimum number of lowercase characters must range from 0 to 64.",
+                          value );
+        retVal = LDAP_OPERATIONS_ERROR;
+        return retVal;
+  }
+
+  if ( apply ) {
+        CFG_LOCK_WRITE(slapdFrontendConfig);
+
+        slapdFrontendConfig->pw_policy.pw_minlowers = minLowers;
+
+        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+  }
+
+  return retVal;
+}
+
+int
+config_set_pw_minspecials( const char *attrname, char *value, char *errorbuf, int apply ) {
+  int retVal = LDAP_SUCCESS, minSpecials = 0;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+        return LDAP_OPERATIONS_ERROR;
+  }
+
+  minSpecials = atoi(value);
+  if ( minSpecials < 0 || minSpecials > 64 ) {
+        PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+                          "password minimum number of special characters \"%s\" is invalid. "
+                          "The minimum number of special characters must range from 0 to 64.",
+                          value );
+        retVal = LDAP_OPERATIONS_ERROR;
+        return retVal;
+  }
+
+  if ( apply ) {
+        CFG_LOCK_WRITE(slapdFrontendConfig);
+
+        slapdFrontendConfig->pw_policy.pw_minspecials = minSpecials;
+
+        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+  }
+
+  return retVal;
+}
+
+int
+config_set_pw_min8bit( const char *attrname, char *value, char *errorbuf, int apply ) {
+  int retVal = LDAP_SUCCESS, min8bit = 0;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+        return LDAP_OPERATIONS_ERROR;
+  }
+
+  min8bit = atoi(value);
+  if ( min8bit < 0 || min8bit > 64 ) {
+        PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+                          "password minimum number of 8-bit characters \"%s\" is invalid. "
+                          "The minimum number of 8-bit characters must range from 0 to 64.",
+                          value );
+        retVal = LDAP_OPERATIONS_ERROR;
+        return retVal;
+  }
+
+  if ( apply ) {
+        CFG_LOCK_WRITE(slapdFrontendConfig);
+
+        slapdFrontendConfig->pw_policy.pw_min8bit = min8bit;
+
+        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+  }
+
+  return retVal;
+}
+
+int
+config_set_pw_maxrepeats( const char *attrname, char *value, char *errorbuf, int apply ) {
+  int retVal = LDAP_SUCCESS, maxRepeats = 0;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+        return LDAP_OPERATIONS_ERROR;
+  }
+
+  maxRepeats = atoi(value);
+  if ( maxRepeats < 0 || maxRepeats > 64 ) {
+        PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+                          "password maximum number of repeated characters \"%s\" is invalid. "
+                          "The maximum number of repeated characters must range from 0 to 64.",
+                          value );
+        retVal = LDAP_OPERATIONS_ERROR;
+        return retVal;
+  }
+
+  if ( apply ) {
+        CFG_LOCK_WRITE(slapdFrontendConfig);
+
+        slapdFrontendConfig->pw_policy.pw_maxrepeats = maxRepeats;
+
+        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+  }
+
+  return retVal;
+}
+
+int
+config_set_pw_mincategories( const char *attrname, char *value, char *errorbuf, int apply ) {
+  int retVal = LDAP_SUCCESS, minCategories = 0;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+        return LDAP_OPERATIONS_ERROR;
+  }
+
+  minCategories = atoi(value);
+  if ( minCategories < 1 || minCategories > 5 ) {
+        PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+                          "password minimum number of categories \"%s\" is invalid. "
+                          "The minimum number of categories must range from 1 to 5.",
+                          value );
+        retVal = LDAP_OPERATIONS_ERROR;
+        return retVal;
+  }
+
+  if ( apply ) {
+        CFG_LOCK_WRITE(slapdFrontendConfig);
+
+        slapdFrontendConfig->pw_policy.pw_mincategories = minCategories;
+
+        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+  }
+
+  return retVal;
+}
+
+int
+config_set_pw_mintokenlength( const char *attrname, char *value, char *errorbuf, int apply ) {
+  int retVal = LDAP_SUCCESS, minTokenLength = 0;
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+  if ( config_value_is_null( attrname, value, errorbuf, 0 )) {
+        return LDAP_OPERATIONS_ERROR;
+  }
+
+  minTokenLength = atoi(value);
+  if ( minTokenLength < 1 || minTokenLength > 64 ) {
+        PR_snprintf ( errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+                          "password minimum token length \"%s\" is invalid. "
+                          "The minimum token length must range from 1 to 64.",
+                          value );
+        retVal = LDAP_OPERATIONS_ERROR;
+        return retVal;
+  }
+
+  if ( apply ) {
+        CFG_LOCK_WRITE(slapdFrontendConfig);
+
+        slapdFrontendConfig->pw_policy.pw_mintokenlength = minTokenLength;
+
+        CFG_UNLOCK_WRITE(slapdFrontendConfig);
+  }
+
+  return retVal;
+}
+
+int
 config_set_pw_maxfailure( const char *attrname, char *value, char *errorbuf, int apply ) {
   int retVal = LDAP_SUCCESS, maxFailure = 0;
   slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -2793,6 +3099,114 @@
   return retVal;
 }
 
+int
+config_get_pw_mindigits() {
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapdFrontendConfig->pw_policy.pw_mindigits;
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
+int
+config_get_pw_minalphas() {
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapdFrontendConfig->pw_policy.pw_minalphas;
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
+int
+config_get_pw_minuppers() {
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapdFrontendConfig->pw_policy.pw_minuppers;
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
+int
+config_get_pw_minlowers() {
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapdFrontendConfig->pw_policy.pw_minlowers;
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
+int
+config_get_pw_minspecials() {
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapdFrontendConfig->pw_policy.pw_minspecials;
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
+int
+config_get_pw_min8bit() {
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapdFrontendConfig->pw_policy.pw_min8bit;
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
+int
+config_get_pw_maxrepeats() {
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapdFrontendConfig->pw_policy.pw_maxrepeats;
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
+int
+config_get_pw_mincategories() {
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapdFrontendConfig->pw_policy.pw_mincategories;
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
+int
+config_get_pw_mintokenlength() {
+  slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+  int retVal;
+
+  CFG_LOCK_READ(slapdFrontendConfig);
+  retVal = slapdFrontendConfig->pw_policy.pw_mintokenlength;
+  CFG_UNLOCK_READ(slapdFrontendConfig);
+
+  return retVal;
+}
+
 int 
 config_get_pw_maxfailure() {
   slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();


Index: libslapd.def
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/libslapd.def,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- libslapd.def	29 Oct 2005 02:28:07 -0000	1.14
+++ libslapd.def	25 Jan 2006 16:51:39 -0000	1.15
@@ -1179,3 +1179,22 @@
 	sasl_map_done @1179
 	slapd_SECITEM_FreeItem @1180
 	slapi_op_type_to_string @1181
+; password syntax functions
+        config_set_pw_mindigits @1190
+        config_set_pw_minalphas @1191
+        config_set_pw_minuppers @1192
+        config_set_pw_minlowers @1193
+        config_set_pw_minspecials @1194
+	config_set_pw_min8bit @1195
+        config_set_pw_maxrepeats @1196
+	config_set_pw_mincategories @1197
+	config_set_pw_mintokenlength @1198
+        config_get_pw_mindigits @1199
+        config_get_pw_minalphas @1200
+        config_get_pw_minuppers @1201
+        config_get_pw_minlowers @1202
+        config_get_pw_minspecials @1203
+	config_get_pw_min8bit @1204
+        config_get_pw_maxrepeats @1205
+	config_get_pw_mincategories @1206
+	config_get_pw_mintokenlength @1207


Index: modify.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/modify.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- modify.c	19 Apr 2005 22:07:36 -0000	1.7
+++ modify.c	25 Jan 2006 16:51:39 -0000	1.8
@@ -65,7 +65,7 @@
 static int modify_internal_pb (Slapi_PBlock *pb);
 static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw);
 static void remove_mod (Slapi_Mods *smods, const char *type, Slapi_Mods *smod_unhashed);
-static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old_pw);
+static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_Mods *smods);
 
 #ifdef LDAP_DEBUG
 static const char*
@@ -279,7 +279,7 @@
 				 strcasecmp( mod->mod_type, SLAPI_USERPWD_ATTR ) == 0 ) {
 				/* assumes controls have already been decoded and placed
 				   in the pblock */
-				pw_change = op_shared_allow_pw_change (pb, mod, &old_pw);
+				pw_change = op_shared_allow_pw_change (pb, mod, &old_pw, &smods);
 				if (pw_change == -1) {
 					goto free_and_return;
 				}
@@ -432,7 +432,8 @@
     int             opresult = 0;
 	LDAPMod         **normalized_mods = NULL;
 	LDAPMod	        **mods;
-	LDAPMod			**mod;
+	LDAPMod	        **mod;
+	Slapi_Mods      smods;
 	int				pw_change = 0;
 	char			*old_pw = NULL;
 
@@ -469,7 +470,8 @@
 	{
 		if ((*mod)->mod_bvalues != NULL && strcasecmp((*mod)->mod_type, SLAPI_USERPWD_ATTR) == 0)
 		{
-			pw_change = op_shared_allow_pw_change (pb, *mod, &old_pw);
+			slapi_mods_init_passin(&smods, mods);
+			pw_change = op_shared_allow_pw_change (pb, *mod, &old_pw, &smods);
 			if (pw_change == -1)
 			{
 				/* The internal result code will already have been set by op_shared_allow_pw_change() */
@@ -865,7 +867,7 @@
 	}
 }
 
-static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old_pw)
+static int op_shared_allow_pw_change (Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_Mods *smods)
 {
 	int isroot, internal_op, repl_op, pwresponse_req = 0;
 	char *dn;
@@ -953,7 +955,7 @@
 	/* check password syntax; remember the old password;
 	   error sent directly from check_pw_syntax function */
 	valuearray_init_bervalarray(mod->mod_bvalues, &values);
-	switch (check_pw_syntax (pb, &sdn, values, old_pw, NULL, 1)) 
+	switch (check_pw_syntax_ext (pb, &sdn, values, old_pw, NULL, 1, smods)) 
 	{
 		case 0: /* success */
 				rc = 1;


Index: proto-slap.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/proto-slap.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- proto-slap.h	12 Jan 2006 00:28:57 -0000	1.15
+++ proto-slap.h	25 Jan 2006 16:51:39 -0000	1.16
@@ -268,6 +268,15 @@
 int config_set_pwpolicy_local(const char *attrname,  char *value, char *errorbuf, int apply );
 int config_set_pw_syntax(const char *attrname,  char *value, char *errorbuf, int apply );
 int config_set_pw_minlength(const char *attrname,  char *value, char *errorbuf, int apply );
+int config_set_pw_mindigits(const char *attrname,  char *value, char *errorbuf, int apply );
+int config_set_pw_minalphas(const char *attrname,  char *value, char *errorbuf, int apply );
+int config_set_pw_minuppers(const char *attrname,  char *value, char *errorbuf, int apply );
+int config_set_pw_minlowers(const char *attrname,  char *value, char *errorbuf, int apply );
+int config_set_pw_minspecials(const char *attrname,  char *value, char *errorbuf, int apply );
+int config_set_pw_min8bit(const char *attrname,  char *value, char *errorbuf, int apply );
+int config_set_pw_maxrepeats(const char *attrname,  char *value, char *errorbuf, int apply );
+int config_set_pw_mincategories(const char *attrname,  char *value, char *errorbuf, int apply );
+int config_set_pw_mintokenlength(const char *attrname,  char *value, char *errorbuf, int apply );
 int config_set_pw_exp(const char *attrname,  char *value, char *errorbuf, int apply );
 int config_set_pw_maxage(const char *attrname,  char *value, char *errorbuf, int apply );
 int config_set_pw_minage(const char *attrname,  char *value, char *errorbuf, int apply );
@@ -322,6 +331,15 @@
 int config_get_pw_must_change();
 int config_get_pw_syntax();
 int config_get_pw_minlength();
+int config_get_pw_mindigits();
+int config_get_pw_minalphas();
+int config_get_pw_minuppers();
+int config_get_pw_minlowers();
+int config_get_pw_minspecials();
+int config_get_pw_min8bit();
+int config_get_pw_maxrepeats();
+int config_get_pw_mincategories();
+int config_get_pw_mintokenlength();
 int config_get_pw_maxfailure();
 int config_get_pw_inhistory();
 long config_get_pw_lockduration();
@@ -694,6 +712,8 @@
 int update_pw_info( Slapi_PBlock *pb , char *old_pw );
 int check_pw_syntax( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, 
 	char **old_pw, Slapi_Entry *e, int mod_op );
+int check_pw_syntax_ext( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals,
+	char **old_pw, Slapi_Entry *e, int mod_op, Slapi_Mods *smods );
 int check_account_lock( Slapi_PBlock *pb, Slapi_Entry * bind_target_entry, int pwresponse_req);
 int check_pw_minage( Slapi_PBlock *pb, const Slapi_DN *sdn, struct berval **vals) ;
 void add_password_attrs( Slapi_PBlock *pb, Operation *op, Slapi_Entry *e );


Index: pw.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/pw.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- pw.c	19 Apr 2005 22:07:36 -0000	1.8
+++ pw.c	25 Jan 2006 16:51:39 -0000	1.9
@@ -62,7 +62,8 @@
 
 static int pw_in_history(Slapi_Value **history_vals, const Slapi_Value *pw_val);
 static int update_pw_history( Slapi_PBlock *pb, char *dn, char *old_pw );
-static int check_trivial_words (Slapi_PBlock *, Slapi_Entry *, Slapi_Value **, char *attrtype );
+static int check_trivial_words (Slapi_PBlock *, Slapi_Entry *, Slapi_Value **,
+		char *attrtype, int toklen, Slapi_Mods *smods );
 static int pw_boolean_str2value (const char *str);
 /* static LDAPMod* pw_malloc_mod (char* name, char* value, int mod_op); */
 
@@ -715,19 +716,39 @@
 check_pw_syntax ( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals, 
 			char **old_pw, Slapi_Entry *e, int mod_op)
 {
+	return ( check_pw_syntax_ext(pb, sdn, vals, old_pw, e, mod_op, NULL) );
+}
+
+int
+check_pw_syntax_ext ( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals,
+			char **old_pw, Slapi_Entry *e, int mod_op, Slapi_Mods *smods)
+{
    	Slapi_Attr* 	attr;
-	int 			i, pwresponse_req = 0;
+	int 		i, pwresponse_req = 0;
 	char *dn= (char*)slapi_sdn_get_ndn(sdn); /* jcm - Had to cast away const */
+	char *pwd = NULL;
+	char *p = NULL;
 	passwdPolicy *pwpolicy = NULL;
 
 	pwpolicy = new_passwdPolicy(pb, dn);
 	slapi_pblock_get ( pb, SLAPI_PWPOLICY, &pwresponse_req );
 
 	if ( pwpolicy->pw_syntax == 1 ) {
-		/* check for the minimum password lenght */	
 		for ( i = 0; vals[ i ] != NULL; ++i ) {
-			if ( pwpolicy->pw_minlength
-				> (int)slapi_value_get_length(vals[ i ]) ) { /* jcm: had to cast unsigned int to signed int */
+			int num_digits = 0;
+			int num_alphas = 0;
+			int num_uppers = 0;
+			int num_lowers = 0;
+			int num_specials = 0;
+			int num_8bit = 0;
+			int num_repeated = 0;
+			int max_repeated = 0;
+			int num_categories = 0;
+
+			/* check for the minimum password length */
+			if ( pwpolicy->pw_minlength >
+				ldap_utf8characters((char *)slapi_value_get_string( vals[i] )) )
+			{
 				if ( pwresponse_req == 1 ) {
 					slapi_pwpolicy_make_response_control ( pb, -1, -1,
 							LDAP_PWPOLICY_PWDTOOSHORT );
@@ -738,10 +759,95 @@
 				delete_passwdPolicy(&pwpolicy);
 				return ( 1 );
 			}
+
+			/* check character types */
+			pwd = (char *)slapi_value_get_string( vals[i] );
+			p = pwd;
+			/*
+			pwdlen = slapi_value_get_length( vals[i] );
+			for ( j = 0; j < pwdlen; j++ ) {
+			*/
+			while ( p && *p )
+			{
+				if ( ldap_utf8isdigit( p ) ) {
+					num_digits++;
+				} else if ( ldap_utf8isalpha( p ) ) {
+					num_alphas++;
+					if ( slapi_utf8isLower( p ) ) {
+						num_lowers++;
+					} else {
+						num_uppers++;
+					}
+				} else {
+					/* check if this is an 8-bit char */
+					if ( *p & 128 ) {
+						num_8bit++;
+					} else {
+						num_specials++;
+					}
+				}
+
+				/* check for repeating characters. If this is the
+				   first char of the password, no need to check */
+				if ( pwd != p ) {
+					int len = ldap_utf8len( p );
+					char *prev_p = ldap_utf8prev( p );
+
+					if ( len == ldap_utf8len( prev_p ) )
+					{
+						if ( memcmp( p, prev_p, len ) == 0 )
+                                        	{
+							num_repeated++;
+							if ( max_repeated < num_repeated ) {
+								max_repeated = num_repeated;
+							}
+						} else {
+							num_repeated = 0;
+						}
+					} else {
+						num_repeated = 0;
+					}
+				}
+
+				p = ldap_utf8next( p );
+			}
+
+			/* tally up the number of character categories */
+			if ( num_digits > 0 )
+				++num_categories;
+			if ( num_uppers > 0 )
+				++num_categories;
+			if ( num_lowers > 0 )
+				++num_categories;
+			if ( num_specials > 0 )
+				++num_categories;
+			if ( num_8bit > 0 )
+				++num_categories;
+
+			/* check for character based syntax limits */
+			if ( ( pwpolicy->pw_mindigits > num_digits ) ||
+				( pwpolicy->pw_minalphas > num_alphas ) ||
+				( pwpolicy->pw_minuppers > num_uppers ) ||
+				( pwpolicy->pw_minlowers > num_lowers ) ||
+				( pwpolicy->pw_minspecials > num_specials ) ||
+				( pwpolicy->pw_min8bit > num_8bit ) ||
+				( (pwpolicy->pw_maxrepeats != 0) && (pwpolicy->pw_maxrepeats < (max_repeated + 1)) ) ||
+				( pwpolicy->pw_mincategories > num_categories ) )
+			{
+                                if ( pwresponse_req == 1 ) {
+                                        slapi_pwpolicy_make_response_control ( pb, -1, -1,
+                                                        LDAP_PWPOLICY_INVALIDPWDSYNTAX );
+                                }
+                                pw_send_ldap_result ( pb,
+                                        LDAP_CONSTRAINT_VIOLATION, NULL,
+                                        "invalid password syntax", 0, NULL );
+                                delete_passwdPolicy(&pwpolicy);
+                                return ( 1 );
+			}
 		}
 	}
 
-	/* get the entry and check for the password history and syntax if this 	   is called by a modify operation */
+	/* get the entry and check for the password history if this is called by a modify operation */
 	if ( mod_op ) { 
 		/* retrieve the entry */
 		e = get_entry ( pb, dn );
@@ -808,19 +914,24 @@
 				*old_pw = NULL;
 			}
 		}
+	}
 
-		if ( pwpolicy->pw_syntax == 1 ) {
-			/* check for trivial words */
-			if ( check_trivial_words ( pb, e, vals, "uid" ) == 1 ||
-			   check_trivial_words ( pb, e, vals, "cn" ) == 1 ||
-			   check_trivial_words ( pb, e, vals, "sn" ) == 1 ||
-			   check_trivial_words ( pb, e, vals, "givenname" ) == 1 ||
-			   check_trivial_words ( pb, e, vals, "ou" ) == 1 ||
-			   check_trivial_words ( pb, e, vals, "mail" ) == 1) {
-			   slapi_entry_free( e ); 
-			   delete_passwdPolicy(&pwpolicy);
-			   return 1;
+	/* check for trivial words if syntax checking is enabled */
+	if ( pwpolicy->pw_syntax == 1 ) {
+		/* e is null if this is an add operation*/
+		if ( check_trivial_words ( pb, e, vals, "uid", pwpolicy->pw_mintokenlength, smods ) == 1 ||
+			check_trivial_words ( pb, e, vals, "cn", pwpolicy->pw_mintokenlength, smods ) == 1 ||
+			check_trivial_words ( pb, e, vals, "sn", pwpolicy->pw_mintokenlength, smods ) == 1 ||
+			check_trivial_words ( pb, e, vals, "givenname", pwpolicy->pw_mintokenlength, smods ) == 1 ||
+			check_trivial_words ( pb, e, vals, "ou", pwpolicy->pw_mintokenlength, smods ) == 1 ||
+			check_trivial_words ( pb, e, vals, "mail", pwpolicy->pw_mintokenlength, smods ) == 1)
+		{
+			if ( mod_op ) {
+				slapi_entry_free( e );
 			}
+
+			delete_passwdPolicy(&pwpolicy);
+			return 1;
 		}
 	}
 
@@ -1122,33 +1233,91 @@
 }
 
 static int
-check_trivial_words (Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Value **vals, char *attrtype  )
+check_trivial_words (Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Value **vals, char *attrtype,
+	int toklen, Slapi_Mods *smods )
 {
-	Slapi_Attr 	*attr;
-	int     i, pwresponse_req = 0;
+	Slapi_Attr     *attr = NULL;
+	Slapi_Mod      *smodp = NULL, *smod = NULL;
+	Slapi_ValueSet *vs = NULL;
+	Slapi_Value    *valp = NULL;
+	struct berval  *bvp = NULL;
+	int            i, pwresponse_req = 0;
+
+	vs = slapi_valueset_new();
 
 	slapi_pblock_get ( pb, SLAPI_PWPOLICY, &pwresponse_req );
-	attr = attrlist_find(e->e_attrs, attrtype);
-	if (attr && !valueset_isempty(&attr->a_present_values))
+
+        /* Get a list of present values for attrtype in the existing entry, if there is one */
+	if (e != NULL )
 	{
-		Slapi_Value **va= attr_get_present_values(attr);
-		for ( i = 0; va[i] != NULL; i++ )
+		if ( (attr = attrlist_find(e->e_attrs, attrtype)) &&
+			(!valueset_isempty(&attr->a_present_values)) )
 		{
-			if( strcasecmp( slapi_value_get_string(va[i]),  slapi_value_get_string(vals[0])) == 0) /* JCM Innards */
+			/* Add present values to valueset */
+			slapi_attr_get_valueset( attr, &vs );
+		}
+	}
+
+	/* Get a list of new values for attrtype from the operation */
+	if ( (smod = slapi_mod_new()) && smods )
+	{
+		for (smodp = slapi_mods_get_first_smod(smods, smod);
+			smodp != NULL; smodp = slapi_mods_get_next_smod(smods, smod) )
+		{
+			/* Operation has new values for attrtype */
+			if ( PL_strcasecmp(attrtype, slapi_mod_get_type(smodp)) == 0 )
 			{
-				if ( pwresponse_req == 1 ) {
+				/* iterate through smodp values and add them if they don't exist */
+				for ( bvp = slapi_mod_get_first_value( smodp );  bvp != NULL;
+					bvp = slapi_mod_get_next_value( smodp ) )
+				{
+					/* Add new value to valueset */
+					valp = slapi_value_new_berval( bvp );
+                                        slapi_valueset_add_value_ext( vs, valp, SLAPI_VALUE_FLAG_PASSIN );
+					valp = NULL;
+				}
+			}
+		}
+		/* Free smod */
+        	slapi_mod_free(&smod);
+		smod = NULL;
+		smodp = NULL;
+	}
+
+	/* If valueset isn't empty, we need to check if the password contains the values */
+	if ( slapi_valueset_count(vs) != 0 )
+	{
+		for ( i = slapi_valueset_first_value( vs, &valp);
+			(i != -1) && (valp != NULL);
+			i = slapi_valueset_next_value( vs, i, &valp) )
+		{
+			/* If the value is smaller than the max token length,
+			 * we don't need to check the password */
+			if ( ldap_utf8characters(slapi_value_get_string( valp )) < toklen )
+				continue;
+
+			/* See if the password contains the value */
+			if ( PL_strcasestr( slapi_value_get_string( vals[0] ),
+				slapi_value_get_string( valp ) ) )
+			{
+				if ( pwresponse_req == 1 )
+				{
 					slapi_pwpolicy_make_response_control ( pb, -1, -1,
 						LDAP_PWPOLICY_INVALIDPWDSYNTAX );
 				}
 				pw_send_ldap_result ( pb, 
 					LDAP_CONSTRAINT_VIOLATION, NULL,
-					"Password failed triviality check."
-					" Please choose a different password.", 
-					0, NULL );
-              	return ( 1 );
+					"invalid password syntax", 0, NULL );
+
+				/* Free valueset */
+				slapi_valueset_free( vs );
+				return ( 1 );
 			}
-        }
+		}
 	}
+
+	/* Free valueset */
+	slapi_valueset_free( vs );
 	return ( 0 );
 }
 
@@ -1361,6 +1530,60 @@
 						}
 					}
 					else
+                                        if (!strcasecmp(attr_name, "passwordmindigits")) {
+                                                if ((sval = attr_get_present_values(attr))) {
+                                                        pwdpolicy->pw_mindigits = slapi_value_get_int(*sval);
+                                                }
+                                        }
+					else
+					if (!strcasecmp(attr_name, "passwordminalphas")) {
+                                                if ((sval = attr_get_present_values(attr))) {
+                                                        pwdpolicy->pw_minalphas = slapi_value_get_int(*sval);
+                                                }
+                                        }
+					else
+                                        if (!strcasecmp(attr_name, "passwordminuppers")) {
+                                                if ((sval = attr_get_present_values(attr))) {
+                                                        pwdpolicy->pw_minuppers = slapi_value_get_int(*sval);
+                                                }
+                                        }
+					else
+                                        if (!strcasecmp(attr_name, "passwordminlowers")) {
+                                                if ((sval = attr_get_present_values(attr))) {
+                                                        pwdpolicy->pw_minlowers = slapi_value_get_int(*sval);
+                                                }
+                                        }
+                                        else
+                                        if (!strcasecmp(attr_name, "passwordminspecials")) {
+                                                if ((sval = attr_get_present_values(attr))) {
+                                                        pwdpolicy->pw_minspecials = slapi_value_get_int(*sval);
+                                                }
+                                        }
+					else
+					if (!strcasecmp(attr_name, "passwordmin8bit")) {
+						if ((sval = attr_get_present_values(attr))) {
+							pwdpolicy->pw_min8bit = slapi_value_get_int(*sval);
+						}
+					}
+					else
+					if (!strcasecmp(attr_name, "passwordmaxrepeats")) {
+                                                if ((sval = attr_get_present_values(attr))) {
+                                                        pwdpolicy->pw_maxrepeats = slapi_value_get_int(*sval);
+                                                }
+                                        }
+                                        else
+                                        if (!strcasecmp(attr_name, "passwordmincategories")) {
+                                                if ((sval = attr_get_present_values(attr))) {
+                                                        pwdpolicy->pw_mincategories = slapi_value_get_int(*sval);
+                                                }
+                                        }
+                                        else
+                                        if (!strcasecmp(attr_name, "passwordmintokenlength")) {
+                                                if ((sval = attr_get_present_values(attr))) {
+                                                        pwdpolicy->pw_mintokenlength = slapi_value_get_int(*sval);
+                                                }
+                                        }
+					else
 					if (!strcasecmp(attr_name, "passwordexp")) {
 						if ((sval = attr_get_present_values(attr))) {
 							pwdpolicy->pw_exp = 


Index: slap.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slap.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- slap.h	19 Apr 2005 22:07:37 -0000	1.9
+++ slap.h	25 Jan 2006 16:51:39 -0000	1.10
@@ -1661,6 +1661,15 @@
 #define CONFIG_PW_MUSTCHANGE_ATTRIBUTE "passwordMustChange"
 #define CONFIG_PW_SYNTAX_ATTRIBUTE "passwordCheckSyntax"
 #define CONFIG_PW_MINLENGTH_ATTRIBUTE "passwordMinLength"
+#define CONFIG_PW_MINDIGITS_ATTRIBUTE "passwordMinDigits"
+#define CONFIG_PW_MINALPHAS_ATTRIBUTE "passwordMinAlphas"
+#define CONFIG_PW_MINUPPERS_ATTRIBUTE "passwordMinUppers"
+#define CONFIG_PW_MINLOWERS_ATTRIBUTE "passwordMinLowers"
+#define CONFIG_PW_MINSPECIALS_ATTRIBUTE "passwordMinSpecials"
+#define CONFIG_PW_MIN8BIT_ATTRIBUTE "passwordMin8Bit"
+#define CONFIG_PW_MAXREPEATS_ATTRIBUTE "passwordMaxRepeats"
+#define CONFIG_PW_MINCATEGORIES_ATTRIBUTE "passwordMinCategories"
+#define CONFIG_PW_MINTOKENLENGTH_ATTRIBUTE "passwordMinTokenLength"
 #define CONFIG_PW_EXP_ATTRIBUTE "passwordExp"
 #define CONFIG_PW_MAXAGE_ATTRIBUTE "passwordMaxAge"
 #define CONFIG_PW_MINAGE_ATTRIBUTE "passwordMinAge"
@@ -1715,6 +1724,15 @@
   int pw_must_change;   /* 1 - indicates that users must change pwd upon reset */
   int pw_syntax;
   int pw_minlength;
+  int pw_mindigits;
+  int pw_minalphas;
+  int pw_minuppers;
+  int pw_minlowers;
+  int pw_minspecials;
+  int pw_min8bit;
+  int pw_maxrepeats;
+  int pw_mincategories;
+  int pw_mintokenlength;
   int pw_exp;
   long pw_maxage;
   long pw_minage;




More information about the Fedora-directory-commits mailing list