Revert "Revert "oran-shell-release: release image for F""
[pti/rtp.git] / meta-starlingx / meta-stx-integ / recipes-support / openldap / files / 0022-ltb-project-openldap-ppolicy-check-password-1.1.patch
1 From 26002bd1d02d871e3c0526f3a0b7b99e25f3564c Mon Sep 17 00:00:00 2001
2 From: babak sarashki <babak.sarashki@windriver.com>
3 Date: Tue, 5 Nov 2019 18:02:38 -0800
4 Subject: [PATCH] ltb project openldap ppolicy check password 1.1
5
6 From stx 1901 openldap src RPM 2.4.44
7 Upstream at https://github.com/ltb-project/openldap-ppolicy-check-password.git
8 ---
9  .../INSTALL                                   |  31 ++
10  .../LICENSE                                   |  50 ++
11  .../Makefile                                  |  48 ++
12  .../README                                    | 146 ++++++
13  .../check_password.c                          | 447 ++++++++++++++++++
14  5 files changed, 722 insertions(+)
15  create mode 100644 ltb-project-openldap-ppolicy-check-password-1.1/INSTALL
16  create mode 100644 ltb-project-openldap-ppolicy-check-password-1.1/LICENSE
17  create mode 100644 ltb-project-openldap-ppolicy-check-password-1.1/Makefile
18  create mode 100644 ltb-project-openldap-ppolicy-check-password-1.1/README
19  create mode 100644 ltb-project-openldap-ppolicy-check-password-1.1/check_password.c
20
21 diff --git a/ltb-project-openldap-ppolicy-check-password-1.1/INSTALL b/ltb-project-openldap-ppolicy-check-password-1.1/INSTALL
22 new file mode 100644
23 index 0000000..eb2dab4
24 --- /dev/null
25 +++ b/ltb-project-openldap-ppolicy-check-password-1.1/INSTALL
26 @@ -0,0 +1,31 @@
27 +INSTALLATION
28 +============
29 +
30 +Build dependencies
31 +------------------
32 +cracklib header files (link with -lcrack). The Makefile does not look for
33 +cracklib; you may need to provide the paths manually.
34 +
35 +Build
36 +-----
37 +Use the provided Makefile to build the module.
38 +
39 +Copy the resulting check_password.so into the OpenLDAP modulepath.
40 +
41 +Or, change the installation path to match with the OpenLDAP module path in the
42 +Makefile and use 'make install'.
43 +
44 +
45 +USAGE
46 +=====
47 +Add objectClass 'pwdPolicyChecker' with an attribute
48 +
49 +   pwdCheckModule: check_password.so
50 +
51 +to a password policy entry.
52 +
53 +The module depends on a working cracklib installation including wordlist files.
54 +If the wordlist files are not readable, the cracklib check will be skipped
55 +silently. 
56 +
57 +But you can use this module without cracklib, just checks for syntatic checks.
58 diff --git a/ltb-project-openldap-ppolicy-check-password-1.1/LICENSE b/ltb-project-openldap-ppolicy-check-password-1.1/LICENSE
59 new file mode 100644
60 index 0000000..03f692b
61 --- /dev/null
62 +++ b/ltb-project-openldap-ppolicy-check-password-1.1/LICENSE
63 @@ -0,0 +1,50 @@
64 +OpenLDAP Public License
65 +
66 +The OpenLDAP Public License
67 +  Version 2.8.1, 25 November 2003
68 +
69 +Redistribution and use of this software and associated documentation
70 +("Software"), with or without modification, are permitted provided
71 +that the following conditions are met:
72 +
73 +1. Redistributions in source form must retain copyright statements
74 +   and notices,
75 +
76 +2. Redistributions in binary form must reproduce applicable copyright
77 +   statements and notices, this list of conditions, and the following
78 +   disclaimer in the documentation and/or other materials provided
79 +   with the distribution, and
80 +
81 +3. Redistributions must contain a verbatim copy of this document.
82 +
83 +The OpenLDAP Foundation may revise this license from time to time.
84 +Each revision is distinguished by a version number.  You may use
85 +this Software under terms of this license revision or under the
86 +terms of any subsequent revision of the license.
87 +
88 +THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS
89 +CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
90 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
91 +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT
92 +SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S)
93 +OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
94 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
95 +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96 +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
97 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
98 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
99 +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
100 +POSSIBILITY OF SUCH DAMAGE.
101 +
102 +The names of the authors and copyright holders must not be used in
103 +advertising or otherwise to promote the sale, use or other dealing
104 +in this Software without specific, written prior permission.  Title
105 +to copyright in this Software shall at all times remain with copyright
106 +holders.
107 +
108 +OpenLDAP is a registered trademark of the OpenLDAP Foundation.
109 +
110 +Copyright 1999-2003 The OpenLDAP Foundation, Redwood City,
111 +California, USA.  All rights reserved.  Permission to copy and
112 +distribute verbatim copies of this document is granted.
113 +
114 diff --git a/ltb-project-openldap-ppolicy-check-password-1.1/Makefile b/ltb-project-openldap-ppolicy-check-password-1.1/Makefile
115 new file mode 100644
116 index 0000000..91de40b
117 --- /dev/null
118 +++ b/ltb-project-openldap-ppolicy-check-password-1.1/Makefile
119 @@ -0,0 +1,48 @@
120 +# contrib/slapd-modules/check_password/Makefile
121 +# Copyright 2007 Michael Steinmann, Calivia. All Rights Reserved.
122 +# Updated by Pierre-Yves Bonnetain, B&A Consultants, 2008
123 +#
124 +
125 +CC=gcc
126 +
127 +# Where to look for the CrackLib dictionaries
128 +#
129 +CRACKLIB=/usr/share/cracklib/pw_dict
130 +
131 +# Path to the configuration file
132 +#
133 +CONFIG=/etc/openldap/check_password.conf
134 +
135 +CFLAGS+=-fpic                                                  \
136 +       -DHAVE_CRACKLIB -DCRACKLIB_DICTPATH="\"$(CRACKLIB)\""  \
137 +       -DCONFIG_FILE="\"$(CONFIG)\""                          \
138 +       -DDEBUG
139 +
140 +LDAP_LIB=-lldap_r -llber
141 +
142 +# Comment out this line if you do NOT want to use the cracklib.
143 +# You may have to add an -Ldirectory if the libcrak is not in a standard
144 +# location
145 +#
146 +CRACKLIB_LIB=-lcrack
147 +
148 +LIBS=$(LDAP_LIB) $(CRACKLIB_LIB)
149 +
150 +LIBDIR=/usr/lib/openldap/
151 +
152 +
153 +all:   check_password
154 +
155 +check_password.o:
156 +       $(CC) $(CFLAGS) -c $(LDAP_INC) check_password.c
157 +
158 +check_password: clean check_password.o
159 +       $(CC) $(LDFLAGS) -shared -o check_password.so check_password.o $(CRACKLIB_LIB)
160 +
161 +install: check_password
162 +       cp -f check_password.so ../../../usr/lib/openldap/modules/
163 +
164 +clean:
165 +       $(RM) check_password.o check_password.so check_password.lo
166 +       $(RM) -r .libs
167 +
168 diff --git a/ltb-project-openldap-ppolicy-check-password-1.1/README b/ltb-project-openldap-ppolicy-check-password-1.1/README
169 new file mode 100644
170 index 0000000..10191c2
171 --- /dev/null
172 +++ b/ltb-project-openldap-ppolicy-check-password-1.1/README
173 @@ -0,0 +1,146 @@
174 +
175 +check_password.c - OpenLDAP pwdChecker library
176 +
177 +2007-06-06 Michael Steinmann <msl@calivia.com>
178 +2008-01-30 Pierre-Yves Bonnetain <py.bonnetain@ba-cst.com>
179 +2009        Clement Oudot <clem.oudot@gmail.com> - LTB-project
180 +2009        Jerome HUET - LTB-project
181 +
182 +check_password.c is an OpenLDAP pwdPolicyChecker module used to check the
183 +strength and quality of user-provided passwords.
184 +
185 +This module is used as an extension of the OpenLDAP password policy controls,
186 +see slapo-ppolicy(5) section pwdCheckModule.
187 +
188 +check_password.c will run a number of checks on the passwords to ensure minimum
189 +strength and quality requirements are met. Passwords that do not meet these
190 +requirements are rejected.
191 +
192 +
193 +Password checks
194 +---------------
195 + - passwords shorter than 6 characters are rejected if cracklib is used (because
196 +   cracklib WILL reject them).
197 +
198 + - syntactic checks controls how many different character classes are used
199 +   (lower, upper, digit and punctuation characters). The minimum number of
200 +   classes is defined in a configuration file. You can set the minimum for each
201 +   class.
202 +
203 + - passwords are checked against cracklib if cracklib is enabled at compile
204 +   time. It can be disabled in configuration file.
205 +
206 +INSTALLATION
207 +------------
208 +Use the provided Makefile to build the module.
209 +
210 +Compilation constants :
211 +
212 +CONFIG_FILE : Path to the configuration file. 
213 +              Defaults to /etc/openldap/check_password.conf
214 +
215 +DEBUG : If defined, check_password will syslog() its actions.
216 +
217 +Build dependencies
218 +cracklib header files (link with -lcrack). The Makefile does not look for
219 +cracklib; you may need to provide the paths manually.
220 +
221 +Install into the slapd server module path.  Change the installation
222 +path to match with the OpenLDAP module path in the Makefile.
223 +
224 +The module may be defined with slapd.conf parameter "modulepath".
225 +
226 +USAGE
227 +-----
228 +To use this module you need to add objectClass pwdPolicyChecker with an 
229 +attribute 'pwdCheckModule: check_password.so' to a password policy entry.
230 +
231 +The module depends on a working cracklib installation including wordlist files.
232 +If the wordlist files are not readable, the cracklib check will be skipped
233 +silently.
234 +
235 +Note: pwdPolicyChecker modules are loaded on *every* password change operation.
236 +
237 +Configuration
238 +-------------
239 +The configuration file (/etc/openldap/check_password.conf by default) contains
240 +parameters for the module. If the file is not found, parameters are given their
241 +default value.
242 +
243 +The syntax of the file is :
244 +
245 +parameter value
246 +
247 +with spaces being delimiters. Parameter names ARE case sensitive (this may
248 +change in the future).
249 +
250 +Current parameters :
251 +
252 +-  useCracklib: integer. Default value: 1. Set it to 0 to disable cracklib verification.
253 +   It has no effect if cracklib is not included at compile time.
254 +
255 +-  minPoints: integer. Default value: 3. Minimum number of quality points a new
256 +   password must have to be accepted. One quality point is awarded for each character
257 +   class used in the password.
258 +
259 +- minUpper: integer. Defaut value: 0. Minimum upper characters expected.
260 +
261 +- minLower: integer. Defaut value: 0. Minimum lower characters expected.
262 +
263 +- minDigit: integer. Defaut value: 0. Minimum digit characters expected.
264 +
265 +- minPunct: integer. Defaut value: 0. Minimum punctuation characters expected.
266 +
267 +Logs
268 +----
269 +If a user password is rejected by an OpenLDAP pwdChecker module, the user will
270 +*not* get a detailed error message, this is by design.
271 +
272 +Typical user message from ldappasswd(5):
273 +  Result: Constraint violation (19)
274 +  Additional info: Password fails quality checking policy
275 +
276 +A more detailed message is written to the server log.
277 +
278 +Server log:
279 +  check_password_quality: module error: (check_password.so)
280 +  Password for dn=".." does not pass required number of strength checks (2 of 3)
281 +
282 +
283 +Caveats
284 +-------
285 +Runtime errors with this module (such as cracklib configuration problems) may
286 +bring down the slapd process.
287 +
288 +Use at your own risk.
289 +
290 +
291 +TODO
292 +----
293 +* use proper malloc function, see ITS#4998
294 +
295 +
296 +HISTORY
297 +-------
298 +* 2009-10-30 Clement OUDOT - LTB-project
299 +  Version 1.1
300 +   - Apply patch from Jerome HUET for minUpper/minLower/minDigit/minPunct
301 +
302 +* 2009-02-05 Clement Oudot <clem.oudot@gmail.com> - LINAGORA Group
303 +  Version 1.0.3
304 +  - Add useCracklib parameter in config file (with help of Pascal Pejac)
305 +  - Prefix log messages with "check_password: "
306 +  - Log what character type is found for quality checking
307 +
308 +* 2008-01-31 Pierre-Yves Bonnetain <py.bonnetain@ba-cst.com>
309 +  Version 1.0.2
310 +  - Several bug fixes.
311 +  - Add external config file
312 +
313 +* 2007-06-06 Michael Steinmann <msl@calivia.com>
314 +  Version 1.0.1
315 +  - add dn to error messages
316 +
317 +* 2007-06-02 Michael Steinmann <msl@calivia.com>
318 +  Version 1.0
319 +
320 diff --git a/ltb-project-openldap-ppolicy-check-password-1.1/check_password.c b/ltb-project-openldap-ppolicy-check-password-1.1/check_password.c
321 new file mode 100644
322 index 0000000..f4dd1cb
323 --- /dev/null
324 +++ b/ltb-project-openldap-ppolicy-check-password-1.1/check_password.c
325 @@ -0,0 +1,447 @@
326 +/*
327 + * check_password.c for OpenLDAP
328 + *
329 + * See LICENSE, README and INSTALL files
330 + */
331 +
332 +#include <string.h>
333 +#include <ctype.h>
334 +#include <portable.h>
335 +#include <slap.h>
336 +
337 +#ifdef HAVE_CRACKLIB
338 +#include <crack.h>
339 +#endif
340 +
341 +#if defined(DEBUG)
342 +#include <syslog.h>
343 +#endif
344 +
345 +#ifndef CRACKLIB_DICTPATH
346 +#define CRACKLIB_DICTPATH "/usr/share/cracklib/pw_dict"
347 +#endif
348 +
349 +#ifndef CONFIG_FILE
350 +#define CONFIG_FILE "/etc/openldap/check_password.conf"
351 +#endif
352 +
353 +#define DEFAULT_QUALITY  3
354 +#define DEFAULT_CRACKLIB 1
355 +#define MEMORY_MARGIN    50
356 +#define MEM_INIT_SZ      64
357 +#define FILENAME_MAXLEN  512
358 +
359 +#define PASSWORD_TOO_SHORT_SZ \
360 +       "Password for dn=\"%s\" is too short (%d/6)"
361 +#define PASSWORD_QUALITY_SZ \
362 +       "Password for dn=\"%s\" does not pass required number of strength checks for the required character sets (%d of %d)"
363 +#define BAD_PASSWORD_SZ \
364 +       "Bad password for dn=\"%s\" because %s"
365 +#define UNKNOWN_ERROR_SZ \
366 +       "An unknown error occurred, please see your systems administrator"
367 +
368 +typedef int (*validator) (char*);
369 +static int read_config_file ();
370 +static validator valid_word (char *);
371 +static int set_quality (char *);
372 +static int set_cracklib (char *);
373 +
374 +int check_password (char *pPasswd, char **ppErrStr, Entry *pEntry);
375 +
376 +struct config_entry {
377 +       char* key;
378 +       char* value;
379 +       char* def_value;
380 +} config_entries[] = { { "minPoints", NULL, "3"},
381 +                      { "useCracklib", NULL, "1"},
382 +                      { "minUpper", NULL, "0"},
383 +                      { "minLower", NULL, "0"},
384 +                      { "minDigit", NULL, "0"},
385 +                      { "minPunct", NULL, "0"},
386 +                      { NULL, NULL, NULL }};
387 +
388 +int get_config_entry_int(char* entry) {
389 +       struct config_entry* centry = config_entries;
390 +
391 +       int i = 0;
392 +       char* key = centry[i].key;
393 +       while (key != NULL) {
394 +               if ( strncmp(key, entry, strlen(key)) == 0 ) {
395 +                       if ( centry[i].value == NULL ) {
396 +                               return atoi(centry[i].def_value);
397 +                       }
398 +                       else {
399 +                               return atoi(centry[i].value);
400 +                       }
401 +               }
402 +               i++;
403 +               key = centry[i].key;
404 +       }
405 +
406 +       return -1;
407 +}
408 +
409 +void dealloc_config_entries() {
410 +       struct config_entry* centry = config_entries;
411 +
412 +       int i = 0;
413 +       while (centry[i].key != NULL) {
414 +               if ( centry[i].value != NULL ) {
415 +                       ber_memfree(centry[i].value);
416 +               }
417 +               i++;
418 +       }
419 +}
420 +
421 +char* chomp(char *s)
422 +{
423 +       char* t = ber_memalloc(strlen(s)+1);
424 +       strncpy (t,s,strlen(s)+1);
425 +
426 +       if ( t[strlen(t)-1] == '\n' ) {
427 +               t[strlen(t)-1] = '\0';
428 +       }
429 +
430 +       return t;
431 +}
432 +
433 +static int set_quality (char *value)
434 +{
435 +#if defined(DEBUG)
436 +       syslog(LOG_INFO, "check_password: Setting quality to [%s]", value);
437 +#endif
438 +
439 +       /* No need to require more quality than we can check for. */
440 +       if (!isdigit(*value) || (int) (value[0] - '0') > 4) return DEFAULT_QUALITY;
441 +       return (int) (value[0] - '0');
442 +
443 +}
444 +
445 +static int set_cracklib (char *value)
446 +{
447 +#if defined(DEBUG)
448 +       syslog(LOG_INFO, "check_password: Setting cracklib usage to [%s]", value);
449 +#endif
450 +
451 +
452 +       return (int) (value[0] - '0');
453 +
454 +}
455 +
456 +static int set_digit (char *value)
457 +{
458 +#if defined(DEBUG)
459 +       syslog(LOG_INFO, "check_password: Setting parameter to [%s]", value);
460 +#endif
461 +       if (!isdigit(*value) || (int) (value[0] - '0') > 9) return 0;
462 +       return (int) (value[0] - '0');
463 +}
464 +
465 +static validator valid_word (char *word)
466 +{
467 +       struct {
468 +               char * parameter;
469 +               validator dealer;
470 +       } list[] = { { "minPoints", set_quality },
471 +                    { "useCracklib", set_cracklib },
472 +                    { "minUpper", set_digit },
473 +                    { "minLower", set_digit },
474 +                    { "minDigit", set_digit },
475 +                    { "minPunct", set_digit },
476 +                    { NULL, NULL } };
477 +       int index = 0;
478 +
479 +#if defined(DEBUG)
480 +       syslog(LOG_DEBUG, "check_password: Validating parameter [%s]", word);
481 +#endif
482 +
483 +       while (list[index].parameter != NULL) {
484 +               if (strlen(word) == strlen(list[index].parameter) &&
485 +                   strcmp(list[index].parameter, word) == 0) {
486 +#if defined(DEBUG)
487 +                       syslog(LOG_DEBUG, "check_password: Parameter accepted.");
488 +#endif
489 +                       return list[index].dealer;
490 +               }
491 +               index++;
492 +       }
493 +
494 +#if defined(DEBUG)
495 +       syslog(LOG_DEBUG, "check_password: Parameter rejected.");
496 +#endif
497 +
498 +       return NULL;
499 +}
500 +
501 +static int read_config_file ()
502 +{
503 +       FILE * config;
504 +       char * line;
505 +       int returnValue =  -1;
506 +
507 +       line = ber_memcalloc(260, sizeof(char));
508 +
509 +       if ( line == NULL ) {
510 +               return returnValue;
511 +       }
512 +
513 +       if ( (config = fopen(CONFIG_FILE, "r")) == NULL) {
514 +#if defined(DEBUG)
515 +               syslog(LOG_ERR, "check_password: Opening file %s failed", CONFIG_FILE);
516 +#endif
517 +
518 +               ber_memfree(line);
519 +               return returnValue;
520 +       }
521 +
522 +       returnValue = 0;
523 +
524 +       while (fgets(line, 256, config) != NULL) {
525 +               char *start = line;
526 +               char *word, *value;
527 +               validator dealer;
528 +
529 +#if defined(DEBUG)
530 +               /* Debug traces to syslog. */
531 +               syslog(LOG_DEBUG, "check_password: Got line |%s|", line);
532 +#endif
533 +
534 +               while (isspace(*start) && isascii(*start)) start++;
535 +
536 +               /* If we've got punctuation, just skip the line. */
537 +               if ( ispunct(*start)) {
538 +#if defined(DEBUG)
539 +                       /* Debug traces to syslog. */
540 +                       syslog(LOG_DEBUG, "check_password: Skipped line |%s|", line);
541 +#endif
542 +                       continue;
543 +               }
544 +
545 +               if( isascii(*start)) {
546 +
547 +                       struct config_entry* centry = config_entries;
548 +                       int i = 0;
549 +                       char* keyWord = centry[i].key;
550 +                       if ((word = strtok(start, " \t")) && (value = strtok(NULL, " \t"))) {
551 +                               while ( keyWord != NULL ) {
552 +                                       if ((strncmp(keyWord,word,strlen(keyWord)) == 0) && (dealer = valid_word(word)) ) {
553 +
554 +#if defined(DEBUG)
555 +                                               syslog(LOG_DEBUG, "check_password: Word = %s, value = %s", word, value);
556 +#endif
557 +
558 +                                               centry[i].value = chomp(value);
559 +                                               break;
560 +                                       }
561 +                                       i++;
562 +                                       keyWord = centry[i].key;
563 +                               }
564 +                       }
565 +               }
566 +       }
567 +       fclose(config);
568 +       ber_memfree(line);
569 +
570 +       return returnValue;
571 +}
572 +
573 +static int realloc_error_message (char ** target, int curlen, int nextlen)
574 +{
575 +       if (curlen < nextlen + MEMORY_MARGIN) {
576 +#if defined(DEBUG)
577 +               syslog(LOG_WARNING, "check_password: Reallocating szErrStr from %d to %d",
578 +                      curlen, nextlen + MEMORY_MARGIN);
579 +#endif
580 +               ber_memfree(*target);
581 +               curlen = nextlen + MEMORY_MARGIN;
582 +               *target = (char *) ber_memalloc(curlen);
583 +       }
584 +
585 +       return curlen;
586 +}
587 +
588 +int
589 +check_password (char *pPasswd, char **ppErrStr, Entry *pEntry)
590 +{
591 +
592 +       char *szErrStr = (char *) ber_memalloc(MEM_INIT_SZ);
593 +       int  mem_len = MEM_INIT_SZ;
594 +
595 +       int nLen;
596 +       int nLower = 0;
597 +       int nUpper = 0;
598 +       int nDigit = 0;
599 +       int nPunct = 0;
600 +       int minLower = 0;
601 +       int minUpper = 0;
602 +       int minDigit = 0;
603 +       int minPunct = 0;
604 +       int nQuality = 0;
605 +       int i;
606 +
607 +       /* Set a sensible default to keep original behaviour. */
608 +       int minQuality = DEFAULT_QUALITY;
609 +       int useCracklib = DEFAULT_CRACKLIB;
610 +
611 +       /** bail out early as cracklib will reject passwords shorter
612 +        * than 6 characters
613 +        */
614 +
615 +       nLen = strlen (pPasswd);
616 +       if ( nLen < 6) {
617 +               mem_len = realloc_error_message(&szErrStr, mem_len,
618 +                                               strlen(PASSWORD_TOO_SHORT_SZ) +
619 +                                               strlen(pEntry->e_name.bv_val) + 1);
620 +               sprintf (szErrStr, PASSWORD_TOO_SHORT_SZ, pEntry->e_name.bv_val, nLen);
621 +               goto fail;
622 +       }
623 +
624 +       if (read_config_file() == -1) {
625 +               syslog(LOG_ERR, "Warning: Could not read values from config file %s. Using defaults.", CONFIG_FILE);
626 +       }
627 +
628 +       minQuality = get_config_entry_int("minPoints");
629 +       useCracklib = get_config_entry_int("useCracklib");
630 +       minUpper = get_config_entry_int("minUpper");
631 +       minLower = get_config_entry_int("minLower");
632 +       minDigit = get_config_entry_int("minDigit");
633 +       minPunct = get_config_entry_int("minPunct");
634 +
635 +       /** The password must have at least minQuality strength points with one
636 +        * point for the first occurrance of a lower, upper, digit and
637 +        * punctuation character
638 +        */
639 +
640 +       for ( i = 0; i < nLen; i++ ) {
641 +
642 +               if ( islower (pPasswd[i]) ) {
643 +                       minLower--;
644 +                       if ( !nLower && (minLower < 1)) {
645 +                               nLower = 1; nQuality++;
646 +#if defined(DEBUG)
647 +                               syslog(LOG_DEBUG, "check_password: Found lower character - quality raise %d", nQuality);
648 +#endif
649 +                       }
650 +                       continue;
651 +               }
652 +
653 +               if ( isupper (pPasswd[i]) ) {
654 +                       minUpper--;
655 +                       if ( !nUpper && (minUpper < 1)) {
656 +                               nUpper = 1; nQuality++;
657 +#if defined(DEBUG)
658 +                               syslog(LOG_DEBUG, "check_password: Found upper character - quality raise %d", nQuality);
659 +#endif
660 +                       }
661 +                       continue;
662 +               }
663 +
664 +               if ( isdigit (pPasswd[i]) ) {
665 +                       minDigit--;
666 +                       if ( !nDigit && (minDigit < 1)) {
667 +                               nDigit = 1; nQuality++;
668 +#if defined(DEBUG)
669 +                               syslog(LOG_DEBUG, "check_password: Found digit character - quality raise %d", nQuality);
670 +#endif
671 +                       }
672 +                       continue;
673 +               }
674 +
675 +               if ( ispunct (pPasswd[i]) ) {
676 +                       minPunct--;
677 +                       if ( !nPunct && (minPunct < 1)) {
678 +                               nPunct = 1; nQuality++;
679 +#if defined(DEBUG)
680 +                               syslog(LOG_DEBUG, "check_password: Found punctuation character - quality raise %d", nQuality);
681 +#endif
682 +                       }
683 +                       continue;
684 +               }
685 +       }
686 +
687 +       /*
688 +        * If you have a required field, then it should be required in the strength
689 +        * checks.
690 +        */
691 +
692 +       if (
693 +               (minLower > 0 ) ||
694 +               (minUpper > 0 ) ||
695 +               (minDigit > 0 ) ||
696 +               (minPunct > 0 ) ||
697 +               (nQuality < minQuality)
698 +               ) {
699 +               mem_len = realloc_error_message(&szErrStr, mem_len,
700 +                                               strlen(PASSWORD_QUALITY_SZ) +
701 +                                               strlen(pEntry->e_name.bv_val) + 2);
702 +               sprintf (szErrStr, PASSWORD_QUALITY_SZ, pEntry->e_name.bv_val,
703 +                        nQuality, minQuality);
704 +               goto fail;
705 +       }
706 +
707 +#ifdef HAVE_CRACKLIB
708 +
709 +       /** Check password with cracklib */
710 +
711 +       if ( useCracklib > 0 ) {
712 +               int   j = 0;
713 +               FILE* fp;
714 +               char  filename[FILENAME_MAXLEN];
715 +               char  const* ext[] = { "hwm", "pwd", "pwi" };
716 +               int   nErr = 0;
717 +
718 +               /**
719 +                * Silently fail when cracklib wordlist is not found
720 +                */
721 +
722 +               for ( j = 0; j < 3; j++ ) {
723 +
724 +                       snprintf (filename, FILENAME_MAXLEN - 1, "%s.%s", \
725 +                                 CRACKLIB_DICTPATH, ext[j]);
726 +
727 +                       if (( fp = fopen ( filename, "r")) == NULL ) {
728 +
729 +                               nErr = 1;
730 +                               break;
731 +
732 +                       } else {
733 +
734 +                               fclose (fp);
735 +
736 +                       }
737 +               }
738 +
739 +               char *r;
740 +               if ( nErr  == 0) {
741 +
742 +                       r = (char *) FascistCheck (pPasswd, CRACKLIB_DICTPATH);
743 +                       if ( r != NULL ) {
744 +                               mem_len = realloc_error_message(&szErrStr, mem_len,
745 +                                                               strlen(BAD_PASSWORD_SZ) +
746 +                                                               strlen(pEntry->e_name.bv_val) +
747 +                                                               strlen(r));
748 +                               sprintf (szErrStr, BAD_PASSWORD_SZ, pEntry->e_name.bv_val, r);
749 +                               goto fail;
750 +                       }
751 +               }
752 +       }
753 +
754 +       else {
755 +#if defined(DEBUG)
756 +               syslog(LOG_NOTICE, "check_password: Cracklib verification disabled by configuration");
757 +#endif
758 +       }
759 +
760 +#endif
761 +       dealloc_config_entries();
762 +       *ppErrStr = strdup ("");
763 +       ber_memfree(szErrStr);
764 +       return (LDAP_SUCCESS);
765 +
766 +fail:
767 +       dealloc_config_entries();
768 +       *ppErrStr = strdup (szErrStr);
769 +       ber_memfree(szErrStr);
770 +       return (EXIT_FAILURE);
771 +
772 +}
773 -- 
774 2.17.1
775