{
    "mode": "info",
    "parameter": "pam_fail_delay",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/info/pam_fail_delay/json",
    "generated": "2026-07-05T01:33:53Z",
    "synopsis": "#include <security/pamappl.h>\nint pamfaildelay(pamhandlet *pamh, unsigned int usec);",
    "sections": {
        "NAME": {
            "content": "pamfaildelay - request a delay on failure\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "#include <security/pamappl.h>\n\nint pamfaildelay(pamhandlet *pamh, unsigned int usec);\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "The pamfaildelay function provides a mechanism by which an\napplication or module can suggest a minimum delay of usec\nmicro-seconds. The function keeps a record of the longest time\nrequested with this function. Should pamauthenticate(3) fail, the\nfailing return to the application is delayed by an amount of time\nrandomly distributed (by up to 50%) about this longest value.\n\nIndependent of success, the delay time is reset to its zero default\nvalue when the PAM service module returns control to the application.\nThe delay occurs after all authentication modules have been called, but\nbefore control is returned to the service application.\n\nWhen using this function the programmer should check if it is available\nwith:\n\n#ifdef HAVEPAMFAILDELAY\n....\n#endif /* HAVEPAMFAILDELAY */\n\nFor applications written with a single thread that are event driven in\nnature, generating this delay may be undesirable. Instead, the\napplication may want to register the delay in some other way. For\nexample, in a single threaded server that serves multiple\nauthentication requests from a single event loop, the application might\nwant to simply mark a given connection as blocked until an application\ntimer expires. For this reason the delay function can be changed with\nthe PAMFAILDELAY item. It can be queried and set with pamgetitem(3)\nand pamsetitem(3) respectively. The value used to set it should be a\nfunction pointer of the following prototype:\n\nvoid (*delayfn)(int retval, unsigned usecdelay, void *appdataptr);\n\nThe arguments being the retval return code of the module stack, the\nusecdelay micro-second delay that libpam is requesting and the\nappdataptr that the application has associated with the current pamh.\nThis last value was set by the application when it called pamstart(3)\nor explicitly with pamsetitem(3).\n\nNote that the PAMFAILDELAY item is set to NULL by default. This\nindicates that PAM should perform a random delay as described above\nwhen authentication fails and a delay has been suggested. If an\napplication does not want the PAM library to perform any delay on\nauthentication failure, then the application must define a custom delay\nfunction that executes no statements and set the PAMFAILDELAY item to\npoint to this function.\n",
            "subsections": []
        },
        "RATIONALE": {
            "content": "It is often possible to attack an authentication scheme by exploiting\nthe time it takes the scheme to deny access to an applicant user. In\ncases of short timeouts, it may prove possible to attempt a brute force\ndictionary attack -- with an automated process, the attacker tries all\npossible passwords to gain access to the system. In other cases, where\nindividual failures can take measurable amounts of time (indicating the\nnature of the failure), an attacker can obtain useful information about\nthe authentication process. These latter attacks make use of procedural\ndelays that constitute a covert channel of useful information.\n\nTo minimize the effectiveness of such attacks, it is desirable to\nintroduce a random delay in a failed authentication process. Preferable\nthis value should be set by the application or a special PAM module.\nStandard PAM modules should not modify the delay unconditional.\n",
            "subsections": []
        },
        "EXAMPLE": {
            "content": "For example, a login application may require a failure delay of roughly\n3 seconds. It will contain the following code:\n\npamfaildelay (pamh, 3000000 /* micro-seconds */ );\npamauthenticate (pamh, 0);\n\nif the modules do not request a delay, the failure delay will be\nbetween 1.5 and 4.5 seconds.\n\nHowever, the modules, invoked in the authentication process, may also\nrequest delays:\n\nmodule #1:    pamfaildelay (pamh, 2000000);\nmodule #2:    pamfaildelay (pamh, 4000000);\n\nin this case, it is the largest requested value that is used to compute\nthe actual failed delay: here between 2 and 6 seconds.\n",
            "subsections": []
        },
        "RETURN VALUES": {
            "content": "PAMSUCCESS\nDelay was successful adjusted.\n\nPAMSYSTEMERR\nA NULL pointer was submitted as PAM handle.\n",
            "subsections": []
        },
        "SEE ALSO": {
            "content": "pamstart(3), pamgetitem(3), pamstrerror(3)\n",
            "subsections": []
        },
        "STANDARDS": {
            "content": "The pamfaildelay function is an Linux-PAM extension.\n\nLinux-PAM Manual                  06/08/2020                 PAMFAILDELAY(3)",
            "subsections": []
        }
    },
    "summary": "pamfaildelay - request a delay on failure",
    "flags": [],
    "examples": [
        "For example, a login application may require a failure delay of roughly",
        "3 seconds. It will contain the following code:",
        "pamfaildelay (pamh, 3000000 /* micro-seconds */ );",
        "pamauthenticate (pamh, 0);",
        "if the modules do not request a delay, the failure delay will be",
        "between 1.5 and 4.5 seconds.",
        "However, the modules, invoked in the authentication process, may also",
        "request delays:",
        "module #1:    pamfaildelay (pamh, 2000000);",
        "module #2:    pamfaildelay (pamh, 4000000);",
        "in this case, it is the largest requested value that is used to compute",
        "the actual failed delay: here between 2 and 6 seconds."
    ],
    "see_also": [
        {
            "name": "pamstart",
            "section": "3",
            "url": "https://www.chedong.com/phpMan.php/man/pamstart/3/json"
        },
        {
            "name": "pamgetitem",
            "section": "3",
            "url": "https://www.chedong.com/phpMan.php/man/pamgetitem/3/json"
        },
        {
            "name": "pamstrerror",
            "section": "3",
            "url": "https://www.chedong.com/phpMan.php/man/pamstrerror/3/json"
        }
    ]
}