diff --git a/check-password-makefile.patch b/check-password-makefile.patch new file mode 100644 index 0000000..f39ba81 --- /dev/null +++ b/check-password-makefile.patch @@ -0,0 +1,41 @@ +--- a/Makefile 2009-10-31 18:59:06.000000000 +0100 ++++ b/Makefile 2014-12-17 09:42:37.586079225 +0100 +@@ -13,22 +13,11 @@ + # + CONFIG=/etc/openldap/check_password.conf + +-OPT=-g -O2 -Wall -fpic \ +- -DHAVE_CRACKLIB -DCRACKLIB_DICTPATH="\"$(CRACKLIB)\"" \ +- -DCONFIG_FILE="\"$(CONFIG)\"" \ ++CFLAGS+=-fpic \ ++ -DHAVE_CRACKLIB -DCRACKLIB_DICTPATH="\"$(CRACKLIB)\"" \ ++ -DCONFIG_FILE="\"$(CONFIG)\"" \ + -DDEBUG + +-# Where to find the OpenLDAP headers. +-# +-LDAP_INC=-I/home/pyb/tmp/openldap-2.3.39/include \ +- -I/home/pyb/tmp/openldap-2.3.39/servers/slapd +- +-# Where to find the CrackLib headers. +-# +-CRACK_INC= +- +-INCS=$(LDAP_INC) $(CRACK_INC) +- + LDAP_LIB=-lldap_r -llber + + # Comment out this line if you do NOT want to use the cracklib. +@@ -45,10 +34,10 @@ + all: check_password + + check_password.o: +- $(CC) $(OPT) -c $(INCS) check_password.c ++ $(CC) $(CFLAGS) -c $(LDAP_INC) check_password.c + + check_password: clean check_password.o +- $(CC) -shared -o check_password.so check_password.o $(CRACKLIB_LIB) ++ $(CC) $(LDFLAGS) -shared -o check_password.so check_password.o $(CRACKLIB_LIB) + + install: check_password + cp -f check_password.so ../../../usr/lib/openldap/modules/ diff --git a/check-password.patch b/check-password.patch new file mode 100644 index 0000000..7a79e95 --- /dev/null +++ b/check-password.patch @@ -0,0 +1,321 @@ +--- a/check_password.c 2009-10-31 18:59:06.000000000 +0100 ++++ b/check_password.c 2014-12-17 12:25:00.148900907 +0100 +@@ -10,7 +10,7 @@ + #include + + #ifdef HAVE_CRACKLIB +-#include "crack.h" ++#include + #endif + + #if defined(DEBUG) +@@ -34,18 +34,77 @@ + #define PASSWORD_TOO_SHORT_SZ \ + "Password for dn=\"%s\" is too short (%d/6)" + #define PASSWORD_QUALITY_SZ \ +- "Password for dn=\"%s\" does not pass required number of strength checks (%d of %d)" ++ "Password for dn=\"%s\" does not pass required number of strength checks for the required character sets (%d of %d)" + #define BAD_PASSWORD_SZ \ + "Bad password for dn=\"%s\" because %s" ++#define UNKNOWN_ERROR_SZ \ ++ "An unknown error occurred, please see your systems administrator" + + typedef int (*validator) (char*); +-static int read_config_file (char *); ++static int read_config_file (); + static validator valid_word (char *); + static int set_quality (char *); + static int set_cracklib (char *); + + int check_password (char *pPasswd, char **ppErrStr, Entry *pEntry); + ++struct config_entry { ++ char* key; ++ char* value; ++ char* def_value; ++} config_entries[] = { { "minPoints", NULL, "3"}, ++ { "useCracklib", NULL, "1"}, ++ { "minUpper", NULL, "0"}, ++ { "minLower", NULL, "0"}, ++ { "minDigit", NULL, "0"}, ++ { "minPunct", NULL, "0"}, ++ { NULL, NULL, NULL }}; ++ ++int get_config_entry_int(char* entry) { ++ struct config_entry* centry = config_entries; ++ ++ int i = 0; ++ char* key = centry[i].key; ++ while (key != NULL) { ++ if ( strncmp(key, entry, strlen(key)) == 0 ) { ++ if ( centry[i].value == NULL ) { ++ return atoi(centry[i].def_value); ++ } ++ else { ++ return atoi(centry[i].value); ++ } ++ } ++ i++; ++ key = centry[i].key; ++ } ++ ++ return -1; ++} ++ ++void dealloc_config_entries() { ++ struct config_entry* centry = config_entries; ++ ++ int i = 0; ++ while (centry[i].key != NULL) { ++ if ( centry[i].value != NULL ) { ++ ber_memfree(centry[i].value); ++ } ++ i++; ++ } ++} ++ ++char* chomp(char *s) ++{ ++ char* t = ber_memalloc(strlen(s)+1); ++ strncpy (t,s,strlen(s)+1); ++ ++ if ( t[strlen(t)-1] == '\n' ) { ++ t[strlen(t)-1] = '\0'; ++ } ++ ++ return t; ++} ++ + static int set_quality (char *value) + { + #if defined(DEBUG) +@@ -84,12 +143,12 @@ + char * parameter; + validator dealer; + } list[] = { { "minPoints", set_quality }, +- { "useCracklib", set_cracklib }, +- { "minUpper", set_digit }, +- { "minLower", set_digit }, +- { "minDigit", set_digit }, +- { "minPunct", set_digit }, +- { NULL, NULL } }; ++ { "useCracklib", set_cracklib }, ++ { "minUpper", set_digit }, ++ { "minLower", set_digit }, ++ { "minDigit", set_digit }, ++ { "minPunct", set_digit }, ++ { NULL, NULL } }; + int index = 0; + + #if defined(DEBUG) +@@ -98,7 +157,7 @@ + + while (list[index].parameter != NULL) { + if (strlen(word) == strlen(list[index].parameter) && +- strcmp(list[index].parameter, word) == 0) { ++ strcmp(list[index].parameter, word) == 0) { + #if defined(DEBUG) + syslog(LOG_NOTICE, "check_password: Parameter accepted."); + #endif +@@ -114,13 +173,15 @@ + return NULL; + } + +-static int read_config_file (char *keyWord) ++static int read_config_file () + { + FILE * config; + char * line; + int returnValue = -1; + +- if ((line = ber_memcalloc(260, sizeof(char))) == NULL) { ++ line = ber_memcalloc(260, sizeof(char)); ++ ++ if ( line == NULL ) { + return returnValue; + } + +@@ -133,6 +194,8 @@ + return returnValue; + } + ++ returnValue = 0; ++ + while (fgets(line, 256, config) != NULL) { + char *start = line; + char *word, *value; +@@ -145,23 +208,40 @@ + + while (isspace(*start) && isascii(*start)) start++; + +- if (! isascii(*start)) ++ /* If we've got punctuation, just skip the line. */ ++ if ( ispunct(*start)) { ++#if defined(DEBUG) ++ /* Debug traces to syslog. */ ++ syslog(LOG_NOTICE, "check_password: Skipped line |%s|", line); ++#endif + continue; ++ } + +- if ((word = strtok(start, " \t")) && (dealer = valid_word(word)) && (strcmp(keyWord,word)==0)) { +- if ((value = strtok(NULL, " \t")) == NULL) +- continue; ++ if( isascii(*start)) { ++ ++ struct config_entry* centry = config_entries; ++ int i = 0; ++ char* keyWord = centry[i].key; ++ if ((word = strtok(start, " \t")) && (value = strtok(NULL, " \t"))) { ++ while ( keyWord != NULL ) { ++ if ((strncmp(keyWord,word,strlen(keyWord)) == 0) && (dealer = valid_word(word)) ) { + + #if defined(DEBUG) +- syslog(LOG_NOTICE, "check_password: Word = %s, value = %s", word, value); ++ syslog(LOG_NOTICE, "check_password: Word = %s, value = %s", word, value); + #endif + +- returnValue = (*dealer)(value); ++ centry[i].value = chomp(value); ++ break; ++ } ++ i++; ++ keyWord = centry[i].key; ++ } ++ } + } + } +- + fclose(config); + ber_memfree(line); ++ + return returnValue; + } + +@@ -170,7 +250,7 @@ + if (curlen < nextlen + MEMORY_MARGIN) { + #if defined(DEBUG) + syslog(LOG_WARNING, "check_password: Reallocating szErrStr from %d to %d", +- curlen, nextlen + MEMORY_MARGIN); ++ curlen, nextlen + MEMORY_MARGIN); + #endif + ber_memfree(*target); + curlen = nextlen + MEMORY_MARGIN; +@@ -180,7 +260,7 @@ + return curlen; + } + +- int ++int + check_password (char *pPasswd, char **ppErrStr, Entry *pEntry) + { + +@@ -210,20 +290,22 @@ + nLen = strlen (pPasswd); + if ( nLen < 6) { + mem_len = realloc_error_message(&szErrStr, mem_len, +- strlen(PASSWORD_TOO_SHORT_SZ) + +- strlen(pEntry->e_name.bv_val) + 1); ++ strlen(PASSWORD_TOO_SHORT_SZ) + ++ strlen(pEntry->e_name.bv_val) + 1); + sprintf (szErrStr, PASSWORD_TOO_SHORT_SZ, pEntry->e_name.bv_val, nLen); + goto fail; + } + +- /* Read config file */ +- minQuality = read_config_file("minPoints"); ++ if (read_config_file() == -1) { ++ syslog(LOG_ERR, "Warning: Could not read values from config file %s. Using defaults.", CONFIG_FILE); ++ } + +- useCracklib = read_config_file("useCracklib"); +- minUpper = read_config_file("minUpper"); +- minLower = read_config_file("minLower"); +- minDigit = read_config_file("minDigit"); +- minPunct = read_config_file("minPunct"); ++ minQuality = get_config_entry_int("minPoints"); ++ useCracklib = get_config_entry_int("useCracklib"); ++ minUpper = get_config_entry_int("minUpper"); ++ minLower = get_config_entry_int("minLower"); ++ minDigit = get_config_entry_int("minDigit"); ++ minPunct = get_config_entry_int("minPunct"); + + /** The password must have at least minQuality strength points with one + * point for the first occurrance of a lower, upper, digit and +@@ -232,8 +314,6 @@ + + for ( i = 0; i < nLen; i++ ) { + +- if ( nQuality >= minQuality ) break; +- + if ( islower (pPasswd[i]) ) { + minLower--; + if ( !nLower && (minLower < 1)) { +@@ -279,12 +359,23 @@ + } + } + +- if ( nQuality < minQuality ) { ++ /* ++ * If you have a required field, then it should be required in the strength ++ * checks. ++ */ ++ ++ if ( ++ (minLower > 0 ) || ++ (minUpper > 0 ) || ++ (minDigit > 0 ) || ++ (minPunct > 0 ) || ++ (nQuality < minQuality) ++ ) { + mem_len = realloc_error_message(&szErrStr, mem_len, +- strlen(PASSWORD_QUALITY_SZ) + +- strlen(pEntry->e_name.bv_val) + 2); ++ strlen(PASSWORD_QUALITY_SZ) + ++ strlen(pEntry->e_name.bv_val) + 2); + sprintf (szErrStr, PASSWORD_QUALITY_SZ, pEntry->e_name.bv_val, +- nQuality, minQuality); ++ nQuality, minQuality); + goto fail; + } + +@@ -306,7 +397,7 @@ + for ( j = 0; j < 3; j++ ) { + + snprintf (filename, FILENAME_MAXLEN - 1, "%s.%s", \ +- CRACKLIB_DICTPATH, ext[j]); ++ CRACKLIB_DICTPATH, ext[j]); + + if (( fp = fopen ( filename, "r")) == NULL ) { + +@@ -326,9 +417,9 @@ + r = (char *) FascistCheck (pPasswd, CRACKLIB_DICTPATH); + if ( r != NULL ) { + mem_len = realloc_error_message(&szErrStr, mem_len, +- strlen(BAD_PASSWORD_SZ) + +- strlen(pEntry->e_name.bv_val) + +- strlen(r)); ++ strlen(BAD_PASSWORD_SZ) + ++ strlen(pEntry->e_name.bv_val) + ++ strlen(r)); + sprintf (szErrStr, BAD_PASSWORD_SZ, pEntry->e_name.bv_val, r); + goto fail; + } +@@ -342,15 +433,15 @@ + } + + #endif +- ++ dealloc_config_entries(); + *ppErrStr = strdup (""); + ber_memfree(szErrStr); + return (LDAP_SUCCESS); + + fail: ++ dealloc_config_entries(); + *ppErrStr = strdup (szErrStr); + ber_memfree(szErrStr); + return (EXIT_FAILURE); + + } +- diff --git a/openldap.spec b/openldap.spec index c96c27e..62123ff 100644 --- a/openldap.spec +++ b/openldap.spec @@ -49,6 +49,10 @@ Patch20: openldap-ldapi-sasl.patch # TLSv1 support, already included upstream Patch21: openldap-support-tlsv1-and-later.patch +# check-password module specific patches +Patch90: check-password-makefile.patch +Patch91: check-password.patch + # Fedora specific patches Patch100: openldap-autoconf-pkgconfig-nss.patch Patch102: openldap-fedora-systemd.patch @@ -181,6 +185,11 @@ done popd +pushd ltb-project-openldap-ppolicy-check-password-%{check_password_version} +%patch90 -p1 +%patch91 -p1 +popd + %build %ifarch s390 s390x @@ -578,6 +587,7 @@ exit 0 %changelog * Wed Dec 17 2014 Jan Synáček - 2.4.40-5 - harden the build +- improve check_password * Tue Dec 16 2014 Jan Synáček - 2.4.40-4 - remove openldap.pc