xref: /netbsd-src/external/bsd/openpam/dist/bin/pamtest/pamtest.c (revision 0d9d0fd8a30be9a1924e715bbcf67a4a83efd262)
1*0d9d0fd8Schristos /*	$NetBSD: pamtest.c,v 1.8 2023/06/30 21:46:20 christos Exp $	*/
244269bb5Schristos 
344269bb5Schristos /*-
444269bb5Schristos  * Copyright (c) 2011 Dag-Erling Smørgrav
544269bb5Schristos  * All rights reserved.
644269bb5Schristos  *
744269bb5Schristos  * Redistribution and use in source and binary forms, with or without
844269bb5Schristos  * modification, are permitted provided that the following conditions
944269bb5Schristos  * are met:
1044269bb5Schristos  * 1. Redistributions of source code must retain the above copyright
118fa0fefeSchristos  *    notice, this list of conditions and the following disclaimer.
1244269bb5Schristos  * 2. Redistributions in binary form must reproduce the above copyright
1344269bb5Schristos  *    notice, this list of conditions and the following disclaimer in the
1444269bb5Schristos  *    documentation and/or other materials provided with the distribution.
15e1b25b17Schristos  * 3. The name of the author may not be used to endorse or promote
16e1b25b17Schristos  *    products derived from this software without specific prior written
17e1b25b17Schristos  *    permission.
1844269bb5Schristos  *
1944269bb5Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2044269bb5Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2144269bb5Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2244269bb5Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2344269bb5Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2444269bb5Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2544269bb5Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2644269bb5Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2744269bb5Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2844269bb5Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2944269bb5Schristos  * SUCH DAMAGE.
3044269bb5Schristos  */
3144269bb5Schristos 
3244269bb5Schristos #ifdef HAVE_CONFIG_H
3344269bb5Schristos # include "config.h"
3444269bb5Schristos #endif
3544269bb5Schristos 
3644269bb5Schristos #include <err.h>
378fa0fefeSchristos #include <limits.h>
3844269bb5Schristos #include <pwd.h>
3944269bb5Schristos #include <stdarg.h>
4044269bb5Schristos #include <stdio.h>
4144269bb5Schristos #include <stdlib.h>
4244269bb5Schristos #include <string.h>
4344269bb5Schristos #include <unistd.h>
4444269bb5Schristos 
4544269bb5Schristos #include <security/pam_appl.h>
4644269bb5Schristos #include <security/openpam.h>	/* for openpam_ttyconv() */
4744269bb5Schristos 
4844269bb5Schristos /* OpenPAM internals */
4944269bb5Schristos extern const char *pam_item_name[PAM_NUM_ITEMS];
5044269bb5Schristos extern int openpam_debug;
5144269bb5Schristos 
5244269bb5Schristos static pam_handle_t *pamh;
5344269bb5Schristos static struct pam_conv pamc;
5444269bb5Schristos 
5544269bb5Schristos static int silent;
5644269bb5Schristos static int verbose;
5744269bb5Schristos 
5844269bb5Schristos static void pt_verbose(const char *, ...)
5944269bb5Schristos 	OPENPAM_FORMAT ((__printf__, 1, 2));
6044269bb5Schristos static void pt_error(int, const char *, ...)
6144269bb5Schristos 	OPENPAM_FORMAT ((__printf__, 2, 3));
6244269bb5Schristos 
6344269bb5Schristos /*
6444269bb5Schristos  * Print an information message if -v was specified at least once
6544269bb5Schristos  */
6644269bb5Schristos static void
pt_verbose(const char * fmt,...)6744269bb5Schristos pt_verbose(const char *fmt, ...)
6844269bb5Schristos {
6944269bb5Schristos 	va_list ap;
7044269bb5Schristos 
7144269bb5Schristos 	if (verbose) {
7244269bb5Schristos 		va_start(ap, fmt);
7344269bb5Schristos 		vfprintf(stderr, fmt, ap);
7444269bb5Schristos 		va_end(ap);
7544269bb5Schristos 		fprintf(stderr, "\n");
7644269bb5Schristos 	}
7744269bb5Schristos }
7844269bb5Schristos 
7944269bb5Schristos /*
8044269bb5Schristos  * Print an error message
8144269bb5Schristos  */
8244269bb5Schristos static void
pt_error(int e,const char * fmt,...)8344269bb5Schristos pt_error(int e, const char *fmt, ...)
8444269bb5Schristos {
8544269bb5Schristos 	va_list ap;
8644269bb5Schristos 
8744269bb5Schristos 	if (e == PAM_SUCCESS && !verbose)
8844269bb5Schristos 		return;
8944269bb5Schristos 	va_start(ap, fmt);
9044269bb5Schristos 	vfprintf(stderr, fmt, ap);
9144269bb5Schristos 	va_end(ap);
9244269bb5Schristos 	fprintf(stderr, ": %s\n", pam_strerror(NULL, e));
9344269bb5Schristos }
9444269bb5Schristos 
9544269bb5Schristos /*
9644269bb5Schristos  * Wrapper for pam_start(3)
9744269bb5Schristos  */
9844269bb5Schristos static int
pt_start(const char * service,const char * user)9944269bb5Schristos pt_start(const char *service, const char *user)
10044269bb5Schristos {
10144269bb5Schristos 	int pame;
10244269bb5Schristos 
10344269bb5Schristos 	pamc.conv = &openpam_ttyconv;
10444269bb5Schristos 	pt_verbose("pam_start(%s, %s)", service, user);
10544269bb5Schristos 	if ((pame = pam_start(service, user, &pamc, &pamh)) != PAM_SUCCESS)
10644269bb5Schristos 		pt_error(pame, "pam_start(%s)", service);
10744269bb5Schristos 	return (pame);
10844269bb5Schristos }
10944269bb5Schristos 
11044269bb5Schristos /*
11144269bb5Schristos  * Wrapper for pam_authenticate(3)
11244269bb5Schristos  */
11344269bb5Schristos static int
pt_authenticate(int flags)11444269bb5Schristos pt_authenticate(int flags)
11544269bb5Schristos {
11644269bb5Schristos 	int pame;
11744269bb5Schristos 
11844269bb5Schristos 	flags |= silent;
1198fa0fefeSchristos 	pt_verbose("pam_authenticate()");
12044269bb5Schristos 	if ((pame = pam_authenticate(pamh, flags)) != PAM_SUCCESS)
12144269bb5Schristos 		pt_error(pame, "pam_authenticate()");
12244269bb5Schristos 	return (pame);
12344269bb5Schristos }
12444269bb5Schristos 
12544269bb5Schristos /*
12644269bb5Schristos  * Wrapper for pam_acct_mgmt(3)
12744269bb5Schristos  */
12844269bb5Schristos static int
pt_acct_mgmt(int flags)12944269bb5Schristos pt_acct_mgmt(int flags)
13044269bb5Schristos {
13144269bb5Schristos 	int pame;
13244269bb5Schristos 
13344269bb5Schristos 	flags |= silent;
1348fa0fefeSchristos 	pt_verbose("pam_acct_mgmt()");
13544269bb5Schristos 	if ((pame = pam_acct_mgmt(pamh, flags)) != PAM_SUCCESS)
13644269bb5Schristos 		pt_error(pame, "pam_acct_mgmt()");
13744269bb5Schristos 	return (pame);
13844269bb5Schristos }
13944269bb5Schristos 
14044269bb5Schristos /*
14144269bb5Schristos  * Wrapper for pam_chauthtok(3)
14244269bb5Schristos  */
14344269bb5Schristos static int
pt_chauthtok(int flags)14444269bb5Schristos pt_chauthtok(int flags)
14544269bb5Schristos {
14644269bb5Schristos 	int pame;
14744269bb5Schristos 
14844269bb5Schristos 	flags |= silent;
1498fa0fefeSchristos 	pt_verbose("pam_chauthtok()");
15044269bb5Schristos 	if ((pame = pam_chauthtok(pamh, flags)) != PAM_SUCCESS)
15144269bb5Schristos 		pt_error(pame, "pam_chauthtok()");
15244269bb5Schristos 	return (pame);
15344269bb5Schristos }
15444269bb5Schristos 
15544269bb5Schristos /*
15644269bb5Schristos  * Wrapper for pam_setcred(3)
15744269bb5Schristos  */
15844269bb5Schristos static int
pt_setcred(int flags)15944269bb5Schristos pt_setcred(int flags)
16044269bb5Schristos {
16144269bb5Schristos 	int pame;
16244269bb5Schristos 
16344269bb5Schristos 	flags |= silent;
1648fa0fefeSchristos 	pt_verbose("pam_setcred()");
16544269bb5Schristos 	if ((pame = pam_setcred(pamh, flags)) != PAM_SUCCESS)
16644269bb5Schristos 		pt_error(pame, "pam_setcred()");
16744269bb5Schristos 	return (pame);
16844269bb5Schristos }
16944269bb5Schristos 
17044269bb5Schristos /*
17144269bb5Schristos  * Wrapper for pam_open_session(3)
17244269bb5Schristos  */
17344269bb5Schristos static int
pt_open_session(int flags)17444269bb5Schristos pt_open_session(int flags)
17544269bb5Schristos {
17644269bb5Schristos 	int pame;
17744269bb5Schristos 
17844269bb5Schristos 	flags |= silent;
1798fa0fefeSchristos 	pt_verbose("pam_open_session()");
18044269bb5Schristos 	if ((pame = pam_open_session(pamh, flags)) != PAM_SUCCESS)
18144269bb5Schristos 		pt_error(pame, "pam_open_session()");
18244269bb5Schristos 	return (pame);
18344269bb5Schristos }
18444269bb5Schristos 
18544269bb5Schristos /*
18644269bb5Schristos  * Wrapper for pam_close_session(3)
18744269bb5Schristos  */
18844269bb5Schristos static int
pt_close_session(int flags)18944269bb5Schristos pt_close_session(int flags)
19044269bb5Schristos {
19144269bb5Schristos 	int pame;
19244269bb5Schristos 
19344269bb5Schristos 	flags |= silent;
1948fa0fefeSchristos 	pt_verbose("pam_close_session()");
19544269bb5Schristos 	if ((pame = pam_close_session(pamh, flags)) != PAM_SUCCESS)
19644269bb5Schristos 		pt_error(pame, "pam_close_session()");
19744269bb5Schristos 	return (pame);
19844269bb5Schristos }
19944269bb5Schristos 
20044269bb5Schristos /*
20144269bb5Schristos  * Wrapper for pam_set_item(3)
20244269bb5Schristos  */
20344269bb5Schristos static int
pt_set_item(int item,const char * p)20444269bb5Schristos pt_set_item(int item, const char *p)
20544269bb5Schristos {
20644269bb5Schristos 	int pame;
20744269bb5Schristos 
20844269bb5Schristos 	switch (item) {
20944269bb5Schristos 	case PAM_SERVICE:
21044269bb5Schristos 	case PAM_USER:
21144269bb5Schristos 	case PAM_AUTHTOK:
21244269bb5Schristos 	case PAM_OLDAUTHTOK:
21344269bb5Schristos 	case PAM_TTY:
21444269bb5Schristos 	case PAM_RHOST:
21544269bb5Schristos 	case PAM_RUSER:
21644269bb5Schristos 	case PAM_USER_PROMPT:
21744269bb5Schristos 	case PAM_AUTHTOK_PROMPT:
21844269bb5Schristos 	case PAM_OLDAUTHTOK_PROMPT:
21944269bb5Schristos 	case PAM_HOST:
22044269bb5Schristos 		pt_verbose("setting %s to %s", pam_item_name[item], p);
22144269bb5Schristos 		break;
22244269bb5Schristos 	default:
22344269bb5Schristos 		pt_verbose("setting %s", pam_item_name[item]);
22444269bb5Schristos 		break;
22544269bb5Schristos 	}
22644269bb5Schristos 	if ((pame = pam_set_item(pamh, item, p)) != PAM_SUCCESS)
22744269bb5Schristos 		pt_error(pame, "pam_set_item(%s)", pam_item_name[item]);
22844269bb5Schristos 	return (pame);
22944269bb5Schristos }
23044269bb5Schristos 
23144269bb5Schristos /*
23244269bb5Schristos  * Wrapper for pam_end(3)
23344269bb5Schristos  */
23444269bb5Schristos static int
pt_end(int pame)23544269bb5Schristos pt_end(int pame)
23644269bb5Schristos {
23744269bb5Schristos 
23844269bb5Schristos 	if (pamh != NULL && (pame = pam_end(pamh, pame)) != PAM_SUCCESS)
23944269bb5Schristos 		/* can't happen */
24044269bb5Schristos 		pt_error(pame, "pam_end()");
24144269bb5Schristos 	return (pame);
24244269bb5Schristos }
24344269bb5Schristos 
24444269bb5Schristos /*
24544269bb5Schristos  * Retrieve and list the PAM environment variables
24644269bb5Schristos  */
24744269bb5Schristos static int
pt_listenv(void)24844269bb5Schristos pt_listenv(void)
24944269bb5Schristos {
25044269bb5Schristos 	char **pam_envlist, **pam_env;
25144269bb5Schristos 
25244269bb5Schristos 	if ((pam_envlist = pam_getenvlist(pamh)) == NULL ||
25344269bb5Schristos 	    *pam_envlist == NULL) {
25444269bb5Schristos 		pt_verbose("no environment variables.");
25544269bb5Schristos 	} else {
25644269bb5Schristos 		pt_verbose("environment variables:");
25744269bb5Schristos 		for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env) {
25844269bb5Schristos 			printf(" %s\n", *pam_env);
25944269bb5Schristos 			free(*pam_env);
26044269bb5Schristos 		}
26144269bb5Schristos 	}
26244269bb5Schristos 	free(pam_envlist);
26344269bb5Schristos 	return (PAM_SUCCESS);
26444269bb5Schristos }
26544269bb5Schristos 
26644269bb5Schristos /*
26744269bb5Schristos  * Print usage string and exit
26844269bb5Schristos  */
26944269bb5Schristos static void
usage(void)27044269bb5Schristos usage(void)
27144269bb5Schristos {
27244269bb5Schristos 
273e1b25b17Schristos 	fprintf(stderr, "usage: pamtest %s service command ...\n",
274e1b25b17Schristos 	    "[-dkMPsv] [-H rhost] [-h host] [-t tty] [-U ruser] [-u user]");
27544269bb5Schristos 	exit(1);
27644269bb5Schristos }
27744269bb5Schristos 
27844269bb5Schristos /*
2798fa0fefeSchristos  * Handle an option that takes an int argument and can be used only once
2808fa0fefeSchristos  */
2818fa0fefeSchristos static void
opt_num_once(int opt,long * num,const char * arg)2828fa0fefeSchristos opt_num_once(int opt, long *num, const char *arg)
2838fa0fefeSchristos {
2848fa0fefeSchristos 	char *end;
2858fa0fefeSchristos 	long l;
2868fa0fefeSchristos 
2878fa0fefeSchristos 	l = strtol(arg, &end, 0);
2888fa0fefeSchristos 	if (end == optarg || *end != '\0') {
2898fa0fefeSchristos 		fprintf(stderr,
2908fa0fefeSchristos 		    "The -%c option expects a numeric argument\n", opt);
2918fa0fefeSchristos 		usage();
2928fa0fefeSchristos 	}
2938fa0fefeSchristos 	*num = l;
2948fa0fefeSchristos }
2958fa0fefeSchristos 
2968fa0fefeSchristos /*
29744269bb5Schristos  * Handle an option that takes a string argument and can be used only once
29844269bb5Schristos  */
29944269bb5Schristos static void
opt_str_once(int opt,const char ** p,const char * arg)30044269bb5Schristos opt_str_once(int opt, const char **p, const char *arg)
30144269bb5Schristos {
30244269bb5Schristos 
30344269bb5Schristos 	if (*p != NULL) {
30444269bb5Schristos 		fprintf(stderr, "The -%c option can only be used once\n", opt);
30544269bb5Schristos 		usage();
30644269bb5Schristos 	}
30744269bb5Schristos 	*p = arg;
30844269bb5Schristos }
30944269bb5Schristos 
31044269bb5Schristos /*
31144269bb5Schristos  * Entry point
31244269bb5Schristos  */
31344269bb5Schristos int
main(int argc,char * argv[])31444269bb5Schristos main(int argc, char *argv[])
31544269bb5Schristos {
31644269bb5Schristos 	char hostname[1024];
31744269bb5Schristos 	const char *rhost = NULL;
31844269bb5Schristos 	const char *host = NULL;
31944269bb5Schristos 	const char *ruser = NULL;
32044269bb5Schristos 	const char *user = NULL;
32144269bb5Schristos 	const char *service = NULL;
32244269bb5Schristos 	const char *tty = NULL;
3238fa0fefeSchristos 	long timeout = 0;
32444269bb5Schristos 	int keepatit = 0;
32544269bb5Schristos 	int pame;
32644269bb5Schristos 	int opt;
32744269bb5Schristos 
3288fa0fefeSchristos 	while ((opt = getopt(argc, argv, "dH:h:kMPsT:t:U:u:v")) != -1)
32944269bb5Schristos 		switch (opt) {
33044269bb5Schristos 		case 'd':
33144269bb5Schristos 			openpam_debug++;
33244269bb5Schristos 			break;
33344269bb5Schristos 		case 'H':
33444269bb5Schristos 			opt_str_once(opt, &rhost, optarg);
33544269bb5Schristos 			break;
33644269bb5Schristos 		case 'h':
33744269bb5Schristos 			opt_str_once(opt, &host, optarg);
33844269bb5Schristos 			break;
33944269bb5Schristos 		case 'k':
34044269bb5Schristos 			keepatit = 1;
34144269bb5Schristos 			break;
342e1b25b17Schristos 		case 'M':
343e1b25b17Schristos 			openpam_set_feature(OPENPAM_RESTRICT_MODULE_NAME, 0);
344e1b25b17Schristos 			openpam_set_feature(OPENPAM_VERIFY_MODULE_FILE, 0);
345e1b25b17Schristos 			break;
346e1b25b17Schristos 		case 'P':
347e1b25b17Schristos 			openpam_set_feature(OPENPAM_RESTRICT_SERVICE_NAME, 0);
348e1b25b17Schristos 			openpam_set_feature(OPENPAM_VERIFY_POLICY_FILE, 0);
349e1b25b17Schristos 			break;
35044269bb5Schristos 		case 's':
35144269bb5Schristos 			silent = PAM_SILENT;
35244269bb5Schristos 			break;
3538fa0fefeSchristos 		case 'T':
3548fa0fefeSchristos 			opt_num_once(opt, &timeout, optarg);
3558fa0fefeSchristos 			if (timeout < 0 || timeout > INT_MAX) {
3568fa0fefeSchristos 				fprintf(stderr,
3578fa0fefeSchristos 				    "Invalid conversation timeout\n");
3588fa0fefeSchristos 				usage();
3598fa0fefeSchristos 			}
3608fa0fefeSchristos 			openpam_ttyconv_timeout = (int)timeout;
3618fa0fefeSchristos 			break;
36244269bb5Schristos 		case 't':
36344269bb5Schristos 			opt_str_once(opt, &tty, optarg);
36444269bb5Schristos 			break;
36544269bb5Schristos 		case 'U':
36644269bb5Schristos 			opt_str_once(opt, &ruser, optarg);
36744269bb5Schristos 			break;
36844269bb5Schristos 		case 'u':
36944269bb5Schristos 			opt_str_once(opt, &user, optarg);
37044269bb5Schristos 			break;
37144269bb5Schristos 		case 'v':
37244269bb5Schristos 			verbose++;
37344269bb5Schristos 			break;
37444269bb5Schristos 		default:
37544269bb5Schristos 			usage();
37644269bb5Schristos 		}
37744269bb5Schristos 
37844269bb5Schristos 	argc -= optind;
37944269bb5Schristos 	argv += optind;
38044269bb5Schristos 
38144269bb5Schristos 	if (argc < 1)
38244269bb5Schristos 		usage();
38344269bb5Schristos 
38444269bb5Schristos 	service = *argv;
38544269bb5Schristos 	--argc;
38644269bb5Schristos 	++argv;
38744269bb5Schristos 
38844269bb5Schristos 	/* defaults */
3898fa0fefeSchristos 	if (service == NULL)
3908fa0fefeSchristos 		service = "pamtest";
39144269bb5Schristos 	if (rhost == NULL) {
39244269bb5Schristos 		if (gethostname(hostname, sizeof(hostname)) == -1)
39344269bb5Schristos 			err(1, "gethostname()");
39444269bb5Schristos 		rhost = hostname;
39544269bb5Schristos 	}
39644269bb5Schristos 	if (tty == NULL)
39744269bb5Schristos 		tty = ttyname(STDERR_FILENO);
39844269bb5Schristos 	if (user == NULL)
39944269bb5Schristos 		user = getlogin();
40044269bb5Schristos 	if (ruser == NULL)
40144269bb5Schristos 		ruser = user;
40244269bb5Schristos 
40344269bb5Schristos 	/* initialize PAM */
40444269bb5Schristos 	if ((pame = pt_start(service, user)) != PAM_SUCCESS)
40544269bb5Schristos 		goto end;
40644269bb5Schristos 
40744269bb5Schristos 	/*
40844269bb5Schristos 	 * pam_start(3) sets this to the machine's hostname, but we allow
40944269bb5Schristos 	 * the user to override it.
41044269bb5Schristos 	 */
41144269bb5Schristos 	if (host != NULL)
41244269bb5Schristos 		if ((pame = pt_set_item(PAM_HOST, host)) != PAM_SUCCESS)
41344269bb5Schristos 		    goto end;
41444269bb5Schristos 
41544269bb5Schristos 	/*
41644269bb5Schristos 	 * The remote host / user / tty are usually set by the
41744269bb5Schristos 	 * application.
41844269bb5Schristos 	 */
41944269bb5Schristos 	if ((pame = pt_set_item(PAM_RHOST, rhost)) != PAM_SUCCESS ||
42044269bb5Schristos 	    (pame = pt_set_item(PAM_RUSER, ruser)) != PAM_SUCCESS ||
42144269bb5Schristos 	    (pame = pt_set_item(PAM_TTY, tty)) != PAM_SUCCESS)
42244269bb5Schristos 		goto end;
42344269bb5Schristos 
42444269bb5Schristos 	while (argc > 0) {
42544269bb5Schristos 		if (strcmp(*argv, "listenv") == 0 ||
42644269bb5Schristos 		    strcmp(*argv, "env") == 0) {
42744269bb5Schristos 			pame = pt_listenv();
42844269bb5Schristos 		} else if (strcmp(*argv, "authenticate") == 0 ||
42944269bb5Schristos 		    strcmp(*argv, "auth") == 0) {
43044269bb5Schristos 			pame = pt_authenticate(0);
43144269bb5Schristos 		} else if (strcmp(*argv, "acct_mgmt") == 0 ||
43244269bb5Schristos 		    strcmp(*argv, "account") == 0) {
43344269bb5Schristos 			pame = pt_acct_mgmt(0);
43444269bb5Schristos 		} else if (strcmp(*argv, "chauthtok") == 0 ||
43544269bb5Schristos 		    strcmp(*argv, "change") == 0) {
43644269bb5Schristos 			pame = pt_chauthtok(PAM_CHANGE_EXPIRED_AUTHTOK);
43744269bb5Schristos 		} else if (strcmp(*argv, "forcechauthtok") == 0 ||
43844269bb5Schristos 		    strcmp(*argv, "forcechange") == 0) {
43944269bb5Schristos 			pame = pt_chauthtok(0);
44044269bb5Schristos 		} else if (strcmp(*argv, "setcred") == 0 ||
44144269bb5Schristos 		    strcmp(*argv, "establish_cred") == 0) {
44244269bb5Schristos 			pame = pt_setcred(PAM_ESTABLISH_CRED);
44344269bb5Schristos 		} else if (strcmp(*argv, "open_session") == 0 ||
44444269bb5Schristos 		    strcmp(*argv, "open") == 0) {
44544269bb5Schristos 			pame = pt_open_session(0);
44644269bb5Schristos 		} else if (strcmp(*argv, "close_session") == 0 ||
44744269bb5Schristos 		    strcmp(*argv, "close") == 0) {
44844269bb5Schristos 			pame = pt_close_session(0);
44944269bb5Schristos 		} else if (strcmp(*argv, "unsetcred") == 0 ||
45044269bb5Schristos 		    strcmp(*argv, "delete_cred") == 0) {
45144269bb5Schristos 			pame = pt_setcred(PAM_DELETE_CRED);
45244269bb5Schristos 		} else {
45344269bb5Schristos 			warnx("unknown primitive: %s", *argv);
45444269bb5Schristos 			pame = PAM_SYSTEM_ERR;
45544269bb5Schristos 		}
45644269bb5Schristos 		if (pame != PAM_SUCCESS && !keepatit) {
45744269bb5Schristos 			warnx("test aborted");
45844269bb5Schristos 			break;
45944269bb5Schristos 		}
46044269bb5Schristos 		--argc;
46144269bb5Schristos 		++argv;
46244269bb5Schristos 	}
46344269bb5Schristos 
46444269bb5Schristos end:
46544269bb5Schristos 	(void)pt_end(pame);
46644269bb5Schristos 	exit(pame == PAM_SUCCESS ? 0 : 1);
46744269bb5Schristos }
468