]> granicus.if.org Git - linux-pam/commitdiff
Do not crash when remember, minlen, or rounds options are used with wrong module...
authorTomas Mraz <tmraz@fedoraproject.org>
Wed, 15 Jun 2011 18:55:30 +0000 (20:55 +0200)
committerTomas Mraz <tmraz@fedoraproject.org>
Wed, 15 Jun 2011 18:55:30 +0000 (20:55 +0200)
ChangeLog
modules/pam_unix/support.c

index b3c499a5bfc10ff21122ce6935bd9952608ebbf8..fcc56e4d1c716fe4e5941d853a39ecd6acbb836a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,9 @@
        * modules/pam_pwhistory/pam_pwhistory.8.xml: Document the
        special meaning of remember=0.
 
+       * modules/pam_unix/support.c (_set_ctrl): Do not crash when remember,
+       minlen, or rounds options are used with wrong module type.
+
 2011-06-14  Thorsten Kukuk  <kukuk@thkukuk.de>
 
        * configure.in: Check for libtirpc by default.
index 0b8d4d64171e2bc26c04fd13e959cf8c99ba6014..cc350e584d1f8391196ae060c0473e1bf1ae58aa 100644 (file)
@@ -83,7 +83,7 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
        }
        /* now parse the arguments to this module */
 
-       while (argc-- > 0) {
+       for (; argc-- > 0; ++argv) {
                int j;
 
                D(("pam_unix arg: %s", *argv));
@@ -99,24 +99,37 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
                        pam_syslog(pamh, LOG_ERR,
                                 "unrecognized option [%s]", *argv);
                } else {
-                       ctrl &= unix_args[j].mask;      /* for turning things off */
-                       ctrl |= unix_args[j].flag;      /* for turning things on  */
-
                        /* special cases */
-                       if (remember != NULL && j == UNIX_REMEMBER_PASSWD) {
+                       if (j == UNIX_REMEMBER_PASSWD) {
+                               if (remember == NULL) {
+                                       pam_syslog(pamh, LOG_ERR,
+                                           "option remember not allowed for this module type");
+                                       continue;
+                               }
                                *remember = strtol(*argv + 9, NULL, 10);
                                if ((*remember == INT_MIN) || (*remember == INT_MAX))
                                        *remember = -1;
                                if (*remember > 400)
                                        *remember = 400;
-                       } else if (pass_min_len && j == UNIX_MIN_PASS_LEN) {
+                       } else if (j == UNIX_MIN_PASS_LEN) {
+                               if (pass_min_len == NULL) {
+                                       pam_syslog(pamh, LOG_ERR,
+                                           "option minlen not allowed for this module type");
+                                       continue;
+                               }
                                *pass_min_len = atoi(*argv + 7);
-                       }
-                       if (rounds != NULL && j == UNIX_ALGO_ROUNDS)
+                       } else if (j == UNIX_ALGO_ROUNDS) {
+                               if (rounds == NULL) {
+                                       pam_syslog(pamh, LOG_ERR,
+                                           "option rounds not allowed for this module type");
+                                       continue;
+                               }
                                *rounds = strtol(*argv + 7, NULL, 10);
-               }
+                       }
 
-               ++argv;         /* step to next argument */
+                       ctrl &= unix_args[j].mask;      /* for turning things off */
+                       ctrl |= unix_args[j].flag;      /* for turning things on  */
+               }
        }
 
        if (UNIX_DES_CRYPT(ctrl)
@@ -132,7 +145,7 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
        }
 
        /* Set default rounds for blowfish */
-       if (on(UNIX_BLOWFISH_PASS, ctrl) && off(UNIX_ALGO_ROUNDS, ctrl)) {
+       if (on(UNIX_BLOWFISH_PASS, ctrl) && off(UNIX_ALGO_ROUNDS, ctrl) && rounds != NULL) {
                *rounds = 5;
                set(UNIX_ALGO_ROUNDS, ctrl);
        }