pam_faildelay.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * pam_faildelay module
  3. *
  4. * Allows an admin to set the delay on failure per-application.
  5. * Provides "auth" interface only.
  6. *
  7. * Use by putting something like this in the relevant pam config:
  8. * auth required pam_faildelay.so delay=[microseconds]
  9. *
  10. * eg:
  11. * auth required pam_faildelay.so delay=10000000
  12. * will set the delay on failure to 10 seconds.
  13. *
  14. * If no delay option was given, pam_faildelay.so will use the
  15. * FAIL_DELAY value of /etc/login.defs.
  16. *
  17. * Based on pam_rootok and parts of pam_unix both by Andrew Morgan
  18. * <morgan@linux.kernel.org>
  19. *
  20. * Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de>
  21. * - Rewrite to use extended PAM functions
  22. * - Add /etc/login.defs support
  23. *
  24. * Portions Copyright (c) 2005 Darren Tucker <dtucker at zip com au>.
  25. *
  26. * Redistribution and use in source and binary forms of, with
  27. * or without modification, are permitted provided that the following
  28. * conditions are met:
  29. *
  30. * 1. Redistributions of source code must retain any existing copyright
  31. * notice, and this entire permission notice in its entirety,
  32. * including the disclaimer of warranties.
  33. *
  34. * 2. Redistributions in binary form must reproduce all prior and current
  35. * copyright notices, this list of conditions, and the following
  36. * disclaimer in the documentation and/or other materials provided
  37. * with the distribution.
  38. *
  39. * 3. The name of any author may not be used to endorse or promote
  40. * products derived from this software without their specific prior
  41. * written permission.
  42. *
  43. * ALTERNATIVELY, this product may be distributed under the terms of the
  44. * GNU General Public License, in which case the provisions of the GNU
  45. * GPL are required INSTEAD OF the above restrictions. (This clause is
  46. * necessary due to a potential conflict between the GNU GPL and the
  47. * restrictions contained in a BSD-style copyright.)
  48. *
  49. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  50. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  51. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  52. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
  53. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  54. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  55. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  56. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  57. * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  58. * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  59. * DAMAGE.
  60. */
  61. #include "config.h"
  62. #include <errno.h>
  63. #include <ctype.h>
  64. #include <stdio.h>
  65. #include <limits.h>
  66. #include <unistd.h>
  67. #include <syslog.h>
  68. #include <string.h>
  69. #include <stdlib.h>
  70. #include <security/pam_modules.h>
  71. #include <security/pam_ext.h>
  72. #include <security/pam_modutil.h>
  73. #define LOGIN_DEFS "/etc/login.defs"
  74. /* --- authentication management functions (only) --- */
  75. int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
  76. int argc, const char **argv)
  77. {
  78. int i, debug_flag = 0;
  79. long int delay = -1;
  80. /* step through arguments */
  81. for (i = 0; i < argc; i++) {
  82. if (sscanf(argv[i], "delay=%ld", &delay) == 1) {
  83. /* sscanf did already everything necessary */
  84. } else if (strcmp (argv[i], "debug") == 0)
  85. debug_flag = 1;
  86. else
  87. pam_syslog (pamh, LOG_ERR, "unknown option; %s", argv[i]);
  88. }
  89. if (delay == -1)
  90. {
  91. char *endptr;
  92. char *val = pam_modutil_search_key (pamh, LOGIN_DEFS, "FAIL_DELAY");
  93. const char *val_orig = val;
  94. if (val == NULL)
  95. return PAM_IGNORE;
  96. errno = 0;
  97. delay = strtol (val, &endptr, 10) & 0777;
  98. if (((delay == 0) && (val_orig == endptr)) ||
  99. ((delay == LONG_MIN || delay == LONG_MAX) && (errno == ERANGE)))
  100. {
  101. pam_syslog (pamh, LOG_ERR, "FAIL_DELAY=%s in %s not valid",
  102. val, LOGIN_DEFS);
  103. free (val);
  104. return PAM_IGNORE;
  105. }
  106. free (val);
  107. /* delay is in seconds, convert to microseconds. */
  108. delay *= 1000000;
  109. }
  110. if (debug_flag)
  111. pam_syslog (pamh, LOG_DEBUG, "setting fail delay to %ld", delay);
  112. i = pam_fail_delay(pamh, delay);
  113. if (i == PAM_SUCCESS)
  114. return PAM_IGNORE;
  115. else
  116. return i;
  117. }
  118. int pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
  119. int argc UNUSED, const char **argv UNUSED)
  120. {
  121. return PAM_IGNORE;
  122. }
  123. /* end of module definition */