(root)/
Linux-PAM-1.5.3/
modules/
pam_faildelay/
pam_faildelay.c
       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  
      62  #include "config.h"
      63  
      64  #include <errno.h>
      65  #include <ctype.h>
      66  #include <stdio.h>
      67  #include <limits.h>
      68  #include <unistd.h>
      69  #include <syslog.h>
      70  #include <string.h>
      71  #include <stdlib.h>
      72  
      73  #include <security/pam_modules.h>
      74  #include <security/pam_ext.h>
      75  #include <security/pam_modutil.h>
      76  
      77  #define LOGIN_DEFS "/etc/login.defs"
      78  
      79  /* --- authentication management functions (only) --- */
      80  
      81  int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
      82  			int argc, const char **argv)
      83  {
      84      int i, debug_flag = 0;
      85      long int delay = -1;
      86  
      87      /* step through arguments */
      88      for (i = 0; i < argc; i++) {
      89  	if (sscanf(argv[i], "delay=%ld", &delay) == 1) {
      90  	  /* sscanf did already everything necessary */
      91  	} else if (strcmp (argv[i], "debug") == 0)
      92  	  debug_flag = 1;
      93  	else
      94  	  pam_syslog (pamh, LOG_ERR, "unknown option; %s", argv[i]);
      95      }
      96  
      97      if (delay == -1)
      98        {
      99  	char *endptr;
     100  	char *val = pam_modutil_search_key (pamh, LOGIN_DEFS, "FAIL_DELAY");
     101  	const char *val_orig = val;
     102  
     103  	if (val == NULL)
     104  	  return PAM_IGNORE;
     105  
     106  	errno = 0;
     107  	delay = strtol (val, &endptr, 10) & 0777;
     108  	if (((delay == 0) && (val_orig == endptr)) ||
     109  	    ((delay == LONG_MIN || delay == LONG_MAX) && (errno == ERANGE)))
     110  	  {
     111  	    pam_syslog (pamh, LOG_ERR, "FAIL_DELAY=%s in %s not valid",
     112  			val, LOGIN_DEFS);
     113  	    free (val);
     114  	    return PAM_IGNORE;
     115  	  }
     116  
     117  	free (val);
     118  	/* delay is in seconds, convert to microseconds. */
     119  	delay *= 1000000;
     120        }
     121  
     122      if (debug_flag)
     123        pam_syslog (pamh, LOG_DEBUG, "setting fail delay to %ld", delay);
     124  
     125      i = pam_fail_delay(pamh, delay);
     126      if (i == PAM_SUCCESS)
     127        return PAM_IGNORE;
     128      else
     129        return i;
     130  }
     131  
     132  int pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
     133  		   int argc UNUSED, const char **argv UNUSED)
     134  {
     135      return PAM_IGNORE;
     136  }
     137  
     138  /* end of module definition */