1f65b2180SDag-Erling Smørgrav /*- 237def36fSDag-Erling Smørgrav * Copyright (c) 2001,2003 Networks Associates Technology, Inc. 3f65b2180SDag-Erling Smørgrav * All rights reserved. 4f65b2180SDag-Erling Smørgrav * 5f65b2180SDag-Erling Smørgrav * This software was developed for the FreeBSD Project by ThinkSec AS and 6f65b2180SDag-Erling Smørgrav * NAI Labs, the Security Research Division of Network Associates, Inc. 7f65b2180SDag-Erling Smørgrav * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 8f65b2180SDag-Erling Smørgrav * DARPA CHATS research program. 9f65b2180SDag-Erling Smørgrav * 10f65b2180SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 11f65b2180SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 12f65b2180SDag-Erling Smørgrav * are met: 13f65b2180SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 14f65b2180SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 15f65b2180SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 16f65b2180SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 17f65b2180SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 18f65b2180SDag-Erling Smørgrav * 3. The name of the author may not be used to endorse or promote 19f65b2180SDag-Erling Smørgrav * products derived from this software without specific prior written 20f65b2180SDag-Erling Smørgrav * permission. 21f65b2180SDag-Erling Smørgrav * 22f65b2180SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23f65b2180SDag-Erling Smørgrav * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24f65b2180SDag-Erling Smørgrav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25f65b2180SDag-Erling Smørgrav * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26f65b2180SDag-Erling Smørgrav * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27f65b2180SDag-Erling Smørgrav * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28f65b2180SDag-Erling Smørgrav * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29f65b2180SDag-Erling Smørgrav * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30f65b2180SDag-Erling Smørgrav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31f65b2180SDag-Erling Smørgrav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32f65b2180SDag-Erling Smørgrav * SUCH DAMAGE. 33f65b2180SDag-Erling Smørgrav */ 34f65b2180SDag-Erling Smørgrav 35f65b2180SDag-Erling Smørgrav #include <sys/cdefs.h> 36f65b2180SDag-Erling Smørgrav __FBSDID("$FreeBSD$"); 37f65b2180SDag-Erling Smørgrav 38f65b2180SDag-Erling Smørgrav #include <sys/types.h> 39f65b2180SDag-Erling Smørgrav #include <sys/wait.h> 40f65b2180SDag-Erling Smørgrav 41f65b2180SDag-Erling Smørgrav #include <errno.h> 428bdb099aSEd Schouten #include <stdio.h> 43f65b2180SDag-Erling Smørgrav #include <stdlib.h> 44f65b2180SDag-Erling Smørgrav #include <string.h> 45f65b2180SDag-Erling Smørgrav #include <unistd.h> 46f65b2180SDag-Erling Smørgrav 47f65b2180SDag-Erling Smørgrav #include <security/pam_appl.h> 48f65b2180SDag-Erling Smørgrav #include <security/pam_modules.h> 49f65b2180SDag-Erling Smørgrav #include <security/openpam.h> 50f65b2180SDag-Erling Smørgrav 519d97c7eeSDag-Erling Smørgrav #define ENV_ITEM(n) { (n), #n } 529d97c7eeSDag-Erling Smørgrav static struct { 539d97c7eeSDag-Erling Smørgrav int item; 549d97c7eeSDag-Erling Smørgrav const char *name; 559d97c7eeSDag-Erling Smørgrav } env_items[] = { 569d97c7eeSDag-Erling Smørgrav ENV_ITEM(PAM_SERVICE), 579d97c7eeSDag-Erling Smørgrav ENV_ITEM(PAM_USER), 589d97c7eeSDag-Erling Smørgrav ENV_ITEM(PAM_TTY), 599d97c7eeSDag-Erling Smørgrav ENV_ITEM(PAM_RHOST), 609d97c7eeSDag-Erling Smørgrav ENV_ITEM(PAM_RUSER), 619d97c7eeSDag-Erling Smørgrav }; 629d97c7eeSDag-Erling Smørgrav 63*7e3d5c1fSJean-Sébastien Pédron #define PAM_RV_COUNT 24 64*7e3d5c1fSJean-Sébastien Pédron 65f65b2180SDag-Erling Smørgrav static int 66*7e3d5c1fSJean-Sébastien Pédron _pam_exec(pam_handle_t *pamh __unused, 67*7e3d5c1fSJean-Sébastien Pédron const char *func, int flags __unused, int argc, const char *argv[]) 68f65b2180SDag-Erling Smørgrav { 69*7e3d5c1fSJean-Sébastien Pédron int envlen, i, nitems, pam_err, status, return_prog_exit_status; 70*7e3d5c1fSJean-Sébastien Pédron int nitems_rv; 71*7e3d5c1fSJean-Sébastien Pédron char *env, **envlist, **tmp, *envstr; 721cede0c9SDag-Erling Smørgrav volatile int childerr; 73f65b2180SDag-Erling Smørgrav pid_t pid; 74f65b2180SDag-Erling Smørgrav 75f65b2180SDag-Erling Smørgrav /* 76f65b2180SDag-Erling Smørgrav * XXX For additional credit, divert child's stdin/stdout/stderr 77f65b2180SDag-Erling Smørgrav * to the conversation function. 78f65b2180SDag-Erling Smørgrav */ 799d97c7eeSDag-Erling Smørgrav 809d97c7eeSDag-Erling Smørgrav /* 81*7e3d5c1fSJean-Sébastien Pédron * Parse options: 82*7e3d5c1fSJean-Sébastien Pédron * return_prog_exit_status: 83*7e3d5c1fSJean-Sébastien Pédron * use the program exit status as the return code of pam_exec 84*7e3d5c1fSJean-Sébastien Pédron * --: 85*7e3d5c1fSJean-Sébastien Pédron * stop options parsing; what follows is the command to execute 86*7e3d5c1fSJean-Sébastien Pédron */ 87*7e3d5c1fSJean-Sébastien Pédron return_prog_exit_status = 0; 88*7e3d5c1fSJean-Sébastien Pédron for (i = 0; i < argc; ++i) { 89*7e3d5c1fSJean-Sébastien Pédron if (strcmp(argv[i], "return_prog_exit_status") == 0) { 90*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_DEBUG, 91*7e3d5c1fSJean-Sébastien Pédron "%s: Option \"return_prog_exit_status\" enabled", 92*7e3d5c1fSJean-Sébastien Pédron func); 93*7e3d5c1fSJean-Sébastien Pédron return_prog_exit_status = 1; 94*7e3d5c1fSJean-Sébastien Pédron } else { 95*7e3d5c1fSJean-Sébastien Pédron if (strcmp(argv[i], "--") == 0) { 96*7e3d5c1fSJean-Sébastien Pédron argc--; 97*7e3d5c1fSJean-Sébastien Pédron argv++; 98*7e3d5c1fSJean-Sébastien Pédron } 99*7e3d5c1fSJean-Sébastien Pédron 100*7e3d5c1fSJean-Sébastien Pédron break; 101*7e3d5c1fSJean-Sébastien Pédron } 102*7e3d5c1fSJean-Sébastien Pédron } 103*7e3d5c1fSJean-Sébastien Pédron 104*7e3d5c1fSJean-Sébastien Pédron argc -= i; 105*7e3d5c1fSJean-Sébastien Pédron argv += i; 106*7e3d5c1fSJean-Sébastien Pédron 107*7e3d5c1fSJean-Sébastien Pédron /* Check there's a program name left after parsing options. */ 108*7e3d5c1fSJean-Sébastien Pédron if (argc < 1) { 109*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s: No program specified: aborting", 110*7e3d5c1fSJean-Sébastien Pédron func); 111*7e3d5c1fSJean-Sébastien Pédron return (PAM_SERVICE_ERR); 112*7e3d5c1fSJean-Sébastien Pédron } 113*7e3d5c1fSJean-Sébastien Pédron 114*7e3d5c1fSJean-Sébastien Pédron /* 1159d97c7eeSDag-Erling Smørgrav * Set up the child's environment list. It consists of the PAM 116*7e3d5c1fSJean-Sébastien Pédron * environment, plus a few hand-picked PAM items, the pam_sm_* 117*7e3d5c1fSJean-Sébastien Pédron * function name calling it and, if return_prog_exit_status is 118*7e3d5c1fSJean-Sébastien Pédron * set, the valid return codes numerical values. 1199d97c7eeSDag-Erling Smørgrav */ 120a76a4d44SDag-Erling Smørgrav envlist = pam_getenvlist(pamh); 1219d97c7eeSDag-Erling Smørgrav for (envlen = 0; envlist[envlen] != NULL; ++envlen) 1229d97c7eeSDag-Erling Smørgrav /* nothing */ ; 1239d97c7eeSDag-Erling Smørgrav nitems = sizeof(env_items) / sizeof(*env_items); 124*7e3d5c1fSJean-Sébastien Pédron /* Count PAM return values put in the environment. */ 125*7e3d5c1fSJean-Sébastien Pédron nitems_rv = return_prog_exit_status ? PAM_RV_COUNT : 0; 126*7e3d5c1fSJean-Sébastien Pédron tmp = realloc(envlist, (envlen + nitems + 1 + nitems_rv + 1) * 127*7e3d5c1fSJean-Sébastien Pédron sizeof(*envlist)); 1289d97c7eeSDag-Erling Smørgrav if (tmp == NULL) { 1299d97c7eeSDag-Erling Smørgrav openpam_free_envlist(envlist); 1309d97c7eeSDag-Erling Smørgrav return (PAM_BUF_ERR); 1319d97c7eeSDag-Erling Smørgrav } 1329d97c7eeSDag-Erling Smørgrav envlist = tmp; 1339d97c7eeSDag-Erling Smørgrav for (i = 0; i < nitems; ++i) { 1349d97c7eeSDag-Erling Smørgrav const void *item; 1359d97c7eeSDag-Erling Smørgrav 1369d97c7eeSDag-Erling Smørgrav pam_err = pam_get_item(pamh, env_items[i].item, &item); 1379d97c7eeSDag-Erling Smørgrav if (pam_err != PAM_SUCCESS || item == NULL) 1389d97c7eeSDag-Erling Smørgrav continue; 1399d97c7eeSDag-Erling Smørgrav asprintf(&envstr, "%s=%s", env_items[i].name, item); 1409d97c7eeSDag-Erling Smørgrav if (envstr == NULL) { 1419d97c7eeSDag-Erling Smørgrav openpam_free_envlist(envlist); 1429d97c7eeSDag-Erling Smørgrav return (PAM_BUF_ERR); 1439d97c7eeSDag-Erling Smørgrav } 1449d97c7eeSDag-Erling Smørgrav envlist[envlen++] = envstr; 1459d97c7eeSDag-Erling Smørgrav envlist[envlen] = NULL; 1469d97c7eeSDag-Erling Smørgrav } 1479d97c7eeSDag-Erling Smørgrav 148*7e3d5c1fSJean-Sébastien Pédron /* Add the pam_sm_* function name to the environment. */ 149*7e3d5c1fSJean-Sébastien Pédron asprintf(&envstr, "PAM_SM_FUNC=%s", func); 150*7e3d5c1fSJean-Sébastien Pédron if (envstr == NULL) { 151*7e3d5c1fSJean-Sébastien Pédron openpam_free_envlist(envlist); 152*7e3d5c1fSJean-Sébastien Pédron return (PAM_BUF_ERR); 153*7e3d5c1fSJean-Sébastien Pédron } 154*7e3d5c1fSJean-Sébastien Pédron envlist[envlen++] = envstr; 155*7e3d5c1fSJean-Sébastien Pédron 156*7e3d5c1fSJean-Sébastien Pédron /* Add the PAM return values to the environment. */ 157*7e3d5c1fSJean-Sébastien Pédron if (return_prog_exit_status) { 158*7e3d5c1fSJean-Sébastien Pédron #define ADD_PAM_RV_TO_ENV(name) \ 159*7e3d5c1fSJean-Sébastien Pédron asprintf(&envstr, #name "=%d", name); \ 160*7e3d5c1fSJean-Sébastien Pédron if (envstr == NULL) { \ 161*7e3d5c1fSJean-Sébastien Pédron openpam_free_envlist(envlist); \ 162*7e3d5c1fSJean-Sébastien Pédron return (PAM_BUF_ERR); \ 163*7e3d5c1fSJean-Sébastien Pédron } \ 164*7e3d5c1fSJean-Sébastien Pédron envlist[envlen++] = envstr 165*7e3d5c1fSJean-Sébastien Pédron /* 166*7e3d5c1fSJean-Sébastien Pédron * CAUTION: When adding/removing an item in the list 167*7e3d5c1fSJean-Sébastien Pédron * below, be sure to update the value of PAM_RV_COUNT. 168*7e3d5c1fSJean-Sébastien Pédron */ 169*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_ABORT); 170*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_ACCT_EXPIRED); 171*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_AUTHINFO_UNAVAIL); 172*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_AUTHTOK_DISABLE_AGING); 173*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_AUTHTOK_ERR); 174*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_AUTHTOK_LOCK_BUSY); 175*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_AUTHTOK_RECOVERY_ERR); 176*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_AUTH_ERR); 177*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_BUF_ERR); 178*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_CONV_ERR); 179*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_CRED_ERR); 180*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_CRED_EXPIRED); 181*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_CRED_INSUFFICIENT); 182*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_CRED_UNAVAIL); 183*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_IGNORE); 184*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_MAXTRIES); 185*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_NEW_AUTHTOK_REQD); 186*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_PERM_DENIED); 187*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_SERVICE_ERR); 188*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_SESSION_ERR); 189*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_SUCCESS); 190*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_SYSTEM_ERR); 191*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_TRY_AGAIN); 192*7e3d5c1fSJean-Sébastien Pédron ADD_PAM_RV_TO_ENV(PAM_USER_UNKNOWN); 193*7e3d5c1fSJean-Sébastien Pédron } 194*7e3d5c1fSJean-Sébastien Pédron 195*7e3d5c1fSJean-Sébastien Pédron envlist[envlen] = NULL; 196*7e3d5c1fSJean-Sébastien Pédron 1979d97c7eeSDag-Erling Smørgrav /* 1989d97c7eeSDag-Erling Smørgrav * Fork and run the command. By using vfork() instead of fork(), 1999d97c7eeSDag-Erling Smørgrav * we can distinguish between an execve() failure and a non-zero 200*7e3d5c1fSJean-Sébastien Pédron * exit status from the command. 2019d97c7eeSDag-Erling Smørgrav */ 202f65b2180SDag-Erling Smørgrav childerr = 0; 203f65b2180SDag-Erling Smørgrav if ((pid = vfork()) == 0) { 2049d97c7eeSDag-Erling Smørgrav execve(argv[0], (char * const *)argv, (char * const *)envlist); 205f65b2180SDag-Erling Smørgrav childerr = errno; 206f65b2180SDag-Erling Smørgrav _exit(1); 207a76a4d44SDag-Erling Smørgrav } 2089d97c7eeSDag-Erling Smørgrav openpam_free_envlist(envlist); 209a76a4d44SDag-Erling Smørgrav if (pid == -1) { 210*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s: vfork(): %m", func); 211f65b2180SDag-Erling Smørgrav return (PAM_SYSTEM_ERR); 212f65b2180SDag-Erling Smørgrav } 213*7e3d5c1fSJean-Sébastien Pédron while (waitpid(pid, &status, 0) == -1) { 214*7e3d5c1fSJean-Sébastien Pédron if (errno == EINTR) 215*7e3d5c1fSJean-Sébastien Pédron continue; 216*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s: waitpid(): %m", func); 217f65b2180SDag-Erling Smørgrav return (PAM_SYSTEM_ERR); 218f65b2180SDag-Erling Smørgrav } 219f65b2180SDag-Erling Smørgrav if (childerr != 0) { 220*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s: execve(): %m", func); 221f65b2180SDag-Erling Smørgrav return (PAM_SYSTEM_ERR); 222f65b2180SDag-Erling Smørgrav } 223f65b2180SDag-Erling Smørgrav if (WIFSIGNALED(status)) { 224*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s: %s caught signal %d%s", 225*7e3d5c1fSJean-Sébastien Pédron func, argv[0], WTERMSIG(status), 226f65b2180SDag-Erling Smørgrav WCOREDUMP(status) ? " (core dumped)" : ""); 227*7e3d5c1fSJean-Sébastien Pédron return (PAM_SERVICE_ERR); 228f65b2180SDag-Erling Smørgrav } 229f65b2180SDag-Erling Smørgrav if (!WIFEXITED(status)) { 230*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s: unknown status 0x%x", 231*7e3d5c1fSJean-Sébastien Pédron func, status); 232*7e3d5c1fSJean-Sébastien Pédron return (PAM_SERVICE_ERR); 233f65b2180SDag-Erling Smørgrav } 234*7e3d5c1fSJean-Sébastien Pédron 235*7e3d5c1fSJean-Sébastien Pédron if (return_prog_exit_status) { 236*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_DEBUG, 237*7e3d5c1fSJean-Sébastien Pédron "%s: Use program exit status as return value: %d", 238*7e3d5c1fSJean-Sébastien Pédron func, WEXITSTATUS(status)); 239*7e3d5c1fSJean-Sébastien Pédron return (WEXITSTATUS(status)); 240*7e3d5c1fSJean-Sébastien Pédron } else { 241*7e3d5c1fSJean-Sébastien Pédron return (WEXITSTATUS(status) == 0 ? 242*7e3d5c1fSJean-Sébastien Pédron PAM_SUCCESS : PAM_PERM_DENIED); 243f65b2180SDag-Erling Smørgrav } 244f65b2180SDag-Erling Smørgrav } 245f65b2180SDag-Erling Smørgrav 246f65b2180SDag-Erling Smørgrav PAM_EXTERN int 247f65b2180SDag-Erling Smørgrav pam_sm_authenticate(pam_handle_t *pamh, int flags, 248f65b2180SDag-Erling Smørgrav int argc, const char *argv[]) 249f65b2180SDag-Erling Smørgrav { 250*7e3d5c1fSJean-Sébastien Pédron int ret; 251f65b2180SDag-Erling Smørgrav 252*7e3d5c1fSJean-Sébastien Pédron ret = _pam_exec(pamh, __func__, flags, argc, argv); 253*7e3d5c1fSJean-Sébastien Pédron 254*7e3d5c1fSJean-Sébastien Pédron /* 255*7e3d5c1fSJean-Sébastien Pédron * We must check that the program returned a valid code for this 256*7e3d5c1fSJean-Sébastien Pédron * function. 257*7e3d5c1fSJean-Sébastien Pédron */ 258*7e3d5c1fSJean-Sébastien Pédron switch (ret) { 259*7e3d5c1fSJean-Sébastien Pédron case PAM_SUCCESS: 260*7e3d5c1fSJean-Sébastien Pédron case PAM_ABORT: 261*7e3d5c1fSJean-Sébastien Pédron case PAM_AUTHINFO_UNAVAIL: 262*7e3d5c1fSJean-Sébastien Pédron case PAM_AUTH_ERR: 263*7e3d5c1fSJean-Sébastien Pédron case PAM_BUF_ERR: 264*7e3d5c1fSJean-Sébastien Pédron case PAM_CONV_ERR: 265*7e3d5c1fSJean-Sébastien Pédron case PAM_CRED_INSUFFICIENT: 266*7e3d5c1fSJean-Sébastien Pédron case PAM_IGNORE: 267*7e3d5c1fSJean-Sébastien Pédron case PAM_MAXTRIES: 268*7e3d5c1fSJean-Sébastien Pédron case PAM_PERM_DENIED: 269*7e3d5c1fSJean-Sébastien Pédron case PAM_SERVICE_ERR: 270*7e3d5c1fSJean-Sébastien Pédron case PAM_SYSTEM_ERR: 271*7e3d5c1fSJean-Sébastien Pédron case PAM_USER_UNKNOWN: 272*7e3d5c1fSJean-Sébastien Pédron break; 273*7e3d5c1fSJean-Sébastien Pédron default: 274*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s returned invalid code %d", 275*7e3d5c1fSJean-Sébastien Pédron argv[0], ret); 276*7e3d5c1fSJean-Sébastien Pédron ret = PAM_SERVICE_ERR; 277*7e3d5c1fSJean-Sébastien Pédron } 278*7e3d5c1fSJean-Sébastien Pédron 279*7e3d5c1fSJean-Sébastien Pédron return (ret); 280f65b2180SDag-Erling Smørgrav } 281f65b2180SDag-Erling Smørgrav 282f65b2180SDag-Erling Smørgrav PAM_EXTERN int 283f65b2180SDag-Erling Smørgrav pam_sm_setcred(pam_handle_t *pamh, int flags, 284f65b2180SDag-Erling Smørgrav int argc, const char *argv[]) 285f65b2180SDag-Erling Smørgrav { 286*7e3d5c1fSJean-Sébastien Pédron int ret; 287f65b2180SDag-Erling Smørgrav 288*7e3d5c1fSJean-Sébastien Pédron ret = _pam_exec(pamh, __func__, flags, argc, argv); 289*7e3d5c1fSJean-Sébastien Pédron 290*7e3d5c1fSJean-Sébastien Pédron /* 291*7e3d5c1fSJean-Sébastien Pédron * We must check that the program returned a valid code for this 292*7e3d5c1fSJean-Sébastien Pédron * function. 293*7e3d5c1fSJean-Sébastien Pédron */ 294*7e3d5c1fSJean-Sébastien Pédron switch (ret) { 295*7e3d5c1fSJean-Sébastien Pédron case PAM_SUCCESS: 296*7e3d5c1fSJean-Sébastien Pédron case PAM_ABORT: 297*7e3d5c1fSJean-Sébastien Pédron case PAM_BUF_ERR: 298*7e3d5c1fSJean-Sébastien Pédron case PAM_CONV_ERR: 299*7e3d5c1fSJean-Sébastien Pédron case PAM_CRED_ERR: 300*7e3d5c1fSJean-Sébastien Pédron case PAM_CRED_EXPIRED: 301*7e3d5c1fSJean-Sébastien Pédron case PAM_CRED_UNAVAIL: 302*7e3d5c1fSJean-Sébastien Pédron case PAM_IGNORE: 303*7e3d5c1fSJean-Sébastien Pédron case PAM_PERM_DENIED: 304*7e3d5c1fSJean-Sébastien Pédron case PAM_SERVICE_ERR: 305*7e3d5c1fSJean-Sébastien Pédron case PAM_SYSTEM_ERR: 306*7e3d5c1fSJean-Sébastien Pédron case PAM_USER_UNKNOWN: 307*7e3d5c1fSJean-Sébastien Pédron break; 308*7e3d5c1fSJean-Sébastien Pédron default: 309*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s returned invalid code %d", 310*7e3d5c1fSJean-Sébastien Pédron argv[0], ret); 311*7e3d5c1fSJean-Sébastien Pédron ret = PAM_SERVICE_ERR; 312*7e3d5c1fSJean-Sébastien Pédron } 313*7e3d5c1fSJean-Sébastien Pédron 314*7e3d5c1fSJean-Sébastien Pédron return (ret); 315f65b2180SDag-Erling Smørgrav } 316f65b2180SDag-Erling Smørgrav 317f65b2180SDag-Erling Smørgrav PAM_EXTERN int 318f65b2180SDag-Erling Smørgrav pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, 319f65b2180SDag-Erling Smørgrav int argc, const char *argv[]) 320f65b2180SDag-Erling Smørgrav { 321*7e3d5c1fSJean-Sébastien Pédron int ret; 322f65b2180SDag-Erling Smørgrav 323*7e3d5c1fSJean-Sébastien Pédron ret = _pam_exec(pamh, __func__, flags, argc, argv); 324*7e3d5c1fSJean-Sébastien Pédron 325*7e3d5c1fSJean-Sébastien Pédron /* 326*7e3d5c1fSJean-Sébastien Pédron * We must check that the program returned a valid code for this 327*7e3d5c1fSJean-Sébastien Pédron * function. 328*7e3d5c1fSJean-Sébastien Pédron */ 329*7e3d5c1fSJean-Sébastien Pédron switch (ret) { 330*7e3d5c1fSJean-Sébastien Pédron case PAM_SUCCESS: 331*7e3d5c1fSJean-Sébastien Pédron case PAM_ABORT: 332*7e3d5c1fSJean-Sébastien Pédron case PAM_ACCT_EXPIRED: 333*7e3d5c1fSJean-Sébastien Pédron case PAM_AUTH_ERR: 334*7e3d5c1fSJean-Sébastien Pédron case PAM_BUF_ERR: 335*7e3d5c1fSJean-Sébastien Pédron case PAM_CONV_ERR: 336*7e3d5c1fSJean-Sébastien Pédron case PAM_IGNORE: 337*7e3d5c1fSJean-Sébastien Pédron case PAM_NEW_AUTHTOK_REQD: 338*7e3d5c1fSJean-Sébastien Pédron case PAM_PERM_DENIED: 339*7e3d5c1fSJean-Sébastien Pédron case PAM_SERVICE_ERR: 340*7e3d5c1fSJean-Sébastien Pédron case PAM_SYSTEM_ERR: 341*7e3d5c1fSJean-Sébastien Pédron case PAM_USER_UNKNOWN: 342*7e3d5c1fSJean-Sébastien Pédron break; 343*7e3d5c1fSJean-Sébastien Pédron default: 344*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s returned invalid code %d", 345*7e3d5c1fSJean-Sébastien Pédron argv[0], ret); 346*7e3d5c1fSJean-Sébastien Pédron ret = PAM_SERVICE_ERR; 347*7e3d5c1fSJean-Sébastien Pédron } 348*7e3d5c1fSJean-Sébastien Pédron 349*7e3d5c1fSJean-Sébastien Pédron return (ret); 350f65b2180SDag-Erling Smørgrav } 351f65b2180SDag-Erling Smørgrav 352f65b2180SDag-Erling Smørgrav PAM_EXTERN int 353f65b2180SDag-Erling Smørgrav pam_sm_open_session(pam_handle_t *pamh, int flags, 354f65b2180SDag-Erling Smørgrav int argc, const char *argv[]) 355f65b2180SDag-Erling Smørgrav { 356*7e3d5c1fSJean-Sébastien Pédron int ret; 357f65b2180SDag-Erling Smørgrav 358*7e3d5c1fSJean-Sébastien Pédron ret = _pam_exec(pamh, __func__, flags, argc, argv); 359*7e3d5c1fSJean-Sébastien Pédron 360*7e3d5c1fSJean-Sébastien Pédron /* 361*7e3d5c1fSJean-Sébastien Pédron * We must check that the program returned a valid code for this 362*7e3d5c1fSJean-Sébastien Pédron * function. 363*7e3d5c1fSJean-Sébastien Pédron */ 364*7e3d5c1fSJean-Sébastien Pédron switch (ret) { 365*7e3d5c1fSJean-Sébastien Pédron case PAM_SUCCESS: 366*7e3d5c1fSJean-Sébastien Pédron case PAM_ABORT: 367*7e3d5c1fSJean-Sébastien Pédron case PAM_BUF_ERR: 368*7e3d5c1fSJean-Sébastien Pédron case PAM_CONV_ERR: 369*7e3d5c1fSJean-Sébastien Pédron case PAM_IGNORE: 370*7e3d5c1fSJean-Sébastien Pédron case PAM_PERM_DENIED: 371*7e3d5c1fSJean-Sébastien Pédron case PAM_SERVICE_ERR: 372*7e3d5c1fSJean-Sébastien Pédron case PAM_SESSION_ERR: 373*7e3d5c1fSJean-Sébastien Pédron case PAM_SYSTEM_ERR: 374*7e3d5c1fSJean-Sébastien Pédron break; 375*7e3d5c1fSJean-Sébastien Pédron default: 376*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s returned invalid code %d", 377*7e3d5c1fSJean-Sébastien Pédron argv[0], ret); 378*7e3d5c1fSJean-Sébastien Pédron ret = PAM_SERVICE_ERR; 379*7e3d5c1fSJean-Sébastien Pédron } 380*7e3d5c1fSJean-Sébastien Pédron 381*7e3d5c1fSJean-Sébastien Pédron return (ret); 382f65b2180SDag-Erling Smørgrav } 383f65b2180SDag-Erling Smørgrav 384f65b2180SDag-Erling Smørgrav PAM_EXTERN int 385f65b2180SDag-Erling Smørgrav pam_sm_close_session(pam_handle_t *pamh, int flags, 386f65b2180SDag-Erling Smørgrav int argc, const char *argv[]) 387f65b2180SDag-Erling Smørgrav { 388*7e3d5c1fSJean-Sébastien Pédron int ret; 389f65b2180SDag-Erling Smørgrav 390*7e3d5c1fSJean-Sébastien Pédron ret = _pam_exec(pamh, __func__, flags, argc, argv); 391*7e3d5c1fSJean-Sébastien Pédron 392*7e3d5c1fSJean-Sébastien Pédron /* 393*7e3d5c1fSJean-Sébastien Pédron * We must check that the program returned a valid code for this 394*7e3d5c1fSJean-Sébastien Pédron * function. 395*7e3d5c1fSJean-Sébastien Pédron */ 396*7e3d5c1fSJean-Sébastien Pédron switch (ret) { 397*7e3d5c1fSJean-Sébastien Pédron case PAM_SUCCESS: 398*7e3d5c1fSJean-Sébastien Pédron case PAM_ABORT: 399*7e3d5c1fSJean-Sébastien Pédron case PAM_BUF_ERR: 400*7e3d5c1fSJean-Sébastien Pédron case PAM_CONV_ERR: 401*7e3d5c1fSJean-Sébastien Pédron case PAM_IGNORE: 402*7e3d5c1fSJean-Sébastien Pédron case PAM_PERM_DENIED: 403*7e3d5c1fSJean-Sébastien Pédron case PAM_SERVICE_ERR: 404*7e3d5c1fSJean-Sébastien Pédron case PAM_SESSION_ERR: 405*7e3d5c1fSJean-Sébastien Pédron case PAM_SYSTEM_ERR: 406*7e3d5c1fSJean-Sébastien Pédron break; 407*7e3d5c1fSJean-Sébastien Pédron default: 408*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s returned invalid code %d", 409*7e3d5c1fSJean-Sébastien Pédron argv[0], ret); 410*7e3d5c1fSJean-Sébastien Pédron ret = PAM_SERVICE_ERR; 411*7e3d5c1fSJean-Sébastien Pédron } 412*7e3d5c1fSJean-Sébastien Pédron 413*7e3d5c1fSJean-Sébastien Pédron return (ret); 414f65b2180SDag-Erling Smørgrav } 415f65b2180SDag-Erling Smørgrav 416f65b2180SDag-Erling Smørgrav PAM_EXTERN int 417f65b2180SDag-Erling Smørgrav pam_sm_chauthtok(pam_handle_t *pamh, int flags, 418f65b2180SDag-Erling Smørgrav int argc, const char *argv[]) 419f65b2180SDag-Erling Smørgrav { 420*7e3d5c1fSJean-Sébastien Pédron int ret; 421f65b2180SDag-Erling Smørgrav 422*7e3d5c1fSJean-Sébastien Pédron ret = _pam_exec(pamh, __func__, flags, argc, argv); 423*7e3d5c1fSJean-Sébastien Pédron 424*7e3d5c1fSJean-Sébastien Pédron /* 425*7e3d5c1fSJean-Sébastien Pédron * We must check that the program returned a valid code for this 426*7e3d5c1fSJean-Sébastien Pédron * function. 427*7e3d5c1fSJean-Sébastien Pédron */ 428*7e3d5c1fSJean-Sébastien Pédron switch (ret) { 429*7e3d5c1fSJean-Sébastien Pédron case PAM_SUCCESS: 430*7e3d5c1fSJean-Sébastien Pédron case PAM_ABORT: 431*7e3d5c1fSJean-Sébastien Pédron case PAM_AUTHTOK_DISABLE_AGING: 432*7e3d5c1fSJean-Sébastien Pédron case PAM_AUTHTOK_ERR: 433*7e3d5c1fSJean-Sébastien Pédron case PAM_AUTHTOK_LOCK_BUSY: 434*7e3d5c1fSJean-Sébastien Pédron case PAM_AUTHTOK_RECOVERY_ERR: 435*7e3d5c1fSJean-Sébastien Pédron case PAM_BUF_ERR: 436*7e3d5c1fSJean-Sébastien Pédron case PAM_CONV_ERR: 437*7e3d5c1fSJean-Sébastien Pédron case PAM_IGNORE: 438*7e3d5c1fSJean-Sébastien Pédron case PAM_PERM_DENIED: 439*7e3d5c1fSJean-Sébastien Pédron case PAM_SERVICE_ERR: 440*7e3d5c1fSJean-Sébastien Pédron case PAM_SYSTEM_ERR: 441*7e3d5c1fSJean-Sébastien Pédron case PAM_TRY_AGAIN: 442*7e3d5c1fSJean-Sébastien Pédron break; 443*7e3d5c1fSJean-Sébastien Pédron default: 444*7e3d5c1fSJean-Sébastien Pédron openpam_log(PAM_LOG_ERROR, "%s returned invalid code %d", 445*7e3d5c1fSJean-Sébastien Pédron argv[0], ret); 446*7e3d5c1fSJean-Sébastien Pédron ret = PAM_SERVICE_ERR; 447*7e3d5c1fSJean-Sébastien Pédron } 448*7e3d5c1fSJean-Sébastien Pédron 449*7e3d5c1fSJean-Sébastien Pédron return (ret); 450f65b2180SDag-Erling Smørgrav } 451f65b2180SDag-Erling Smørgrav 452f65b2180SDag-Erling Smørgrav PAM_MODULE_ENTRY("pam_exec"); 453