xref: /freebsd/contrib/openpam/bin/pamtest/pamtest.c (revision 7f106882fe02eed8861e8e9df7ab1e1100283cc0)
1*7f106882SDag-Erling Smørgrav /*-
2*7f106882SDag-Erling Smørgrav  * Copyright (c) 2011 Dag-Erling Smørgrav
3*7f106882SDag-Erling Smørgrav  * All rights reserved.
4*7f106882SDag-Erling Smørgrav  *
5*7f106882SDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
6*7f106882SDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
7*7f106882SDag-Erling Smørgrav  * are met:
8*7f106882SDag-Erling Smørgrav  * 1. Redistributions of source code must retain the above copyright
9*7f106882SDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer
10*7f106882SDag-Erling Smørgrav  *    in this position and unchanged.
11*7f106882SDag-Erling Smørgrav  * 2. Redistributions in binary form must reproduce the above copyright
12*7f106882SDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer in the
13*7f106882SDag-Erling Smørgrav  *    documentation and/or other materials provided with the distribution.
14*7f106882SDag-Erling Smørgrav  *
15*7f106882SDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16*7f106882SDag-Erling Smørgrav  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*7f106882SDag-Erling Smørgrav  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*7f106882SDag-Erling Smørgrav  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19*7f106882SDag-Erling Smørgrav  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20*7f106882SDag-Erling Smørgrav  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21*7f106882SDag-Erling Smørgrav  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22*7f106882SDag-Erling Smørgrav  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23*7f106882SDag-Erling Smørgrav  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24*7f106882SDag-Erling Smørgrav  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25*7f106882SDag-Erling Smørgrav  * SUCH DAMAGE.
26*7f106882SDag-Erling Smørgrav  *
27*7f106882SDag-Erling Smørgrav  * $Id: pamtest.c 472 2011-11-03 09:46:52Z des $
28*7f106882SDag-Erling Smørgrav  */
29*7f106882SDag-Erling Smørgrav 
30*7f106882SDag-Erling Smørgrav #ifdef HAVE_CONFIG_H
31*7f106882SDag-Erling Smørgrav # include "config.h"
32*7f106882SDag-Erling Smørgrav #endif
33*7f106882SDag-Erling Smørgrav 
34*7f106882SDag-Erling Smørgrav #include <err.h>
35*7f106882SDag-Erling Smørgrav #include <pwd.h>
36*7f106882SDag-Erling Smørgrav #include <stdarg.h>
37*7f106882SDag-Erling Smørgrav #include <stdio.h>
38*7f106882SDag-Erling Smørgrav #include <stdlib.h>
39*7f106882SDag-Erling Smørgrav #include <string.h>
40*7f106882SDag-Erling Smørgrav #include <unistd.h>
41*7f106882SDag-Erling Smørgrav 
42*7f106882SDag-Erling Smørgrav #include <security/pam_appl.h>
43*7f106882SDag-Erling Smørgrav #include <security/openpam.h>	/* for openpam_ttyconv() */
44*7f106882SDag-Erling Smørgrav 
45*7f106882SDag-Erling Smørgrav /* OpenPAM internals */
46*7f106882SDag-Erling Smørgrav extern const char *pam_item_name[PAM_NUM_ITEMS];
47*7f106882SDag-Erling Smørgrav extern int openpam_debug;
48*7f106882SDag-Erling Smørgrav 
49*7f106882SDag-Erling Smørgrav static pam_handle_t *pamh;
50*7f106882SDag-Erling Smørgrav static struct pam_conv pamc;
51*7f106882SDag-Erling Smørgrav 
52*7f106882SDag-Erling Smørgrav static int silent;
53*7f106882SDag-Erling Smørgrav static int verbose;
54*7f106882SDag-Erling Smørgrav 
55*7f106882SDag-Erling Smørgrav static void pt_verbose(const char *, ...)
56*7f106882SDag-Erling Smørgrav 	OPENPAM_FORMAT ((__printf__, 1, 2));
57*7f106882SDag-Erling Smørgrav static void pt_error(int, const char *, ...)
58*7f106882SDag-Erling Smørgrav 	OPENPAM_FORMAT ((__printf__, 2, 3));
59*7f106882SDag-Erling Smørgrav 
60*7f106882SDag-Erling Smørgrav /*
61*7f106882SDag-Erling Smørgrav  * Print an information message if -v was specified at least once
62*7f106882SDag-Erling Smørgrav  */
63*7f106882SDag-Erling Smørgrav static void
64*7f106882SDag-Erling Smørgrav pt_verbose(const char *fmt, ...)
65*7f106882SDag-Erling Smørgrav {
66*7f106882SDag-Erling Smørgrav 	va_list ap;
67*7f106882SDag-Erling Smørgrav 
68*7f106882SDag-Erling Smørgrav 	if (verbose) {
69*7f106882SDag-Erling Smørgrav 		va_start(ap, fmt);
70*7f106882SDag-Erling Smørgrav 		vfprintf(stderr, fmt, ap);
71*7f106882SDag-Erling Smørgrav 		va_end(ap);
72*7f106882SDag-Erling Smørgrav 		fprintf(stderr, "\n");
73*7f106882SDag-Erling Smørgrav 	}
74*7f106882SDag-Erling Smørgrav }
75*7f106882SDag-Erling Smørgrav 
76*7f106882SDag-Erling Smørgrav /*
77*7f106882SDag-Erling Smørgrav  * Print an error message
78*7f106882SDag-Erling Smørgrav  */
79*7f106882SDag-Erling Smørgrav static void
80*7f106882SDag-Erling Smørgrav pt_error(int e, const char *fmt, ...)
81*7f106882SDag-Erling Smørgrav {
82*7f106882SDag-Erling Smørgrav 	va_list ap;
83*7f106882SDag-Erling Smørgrav 
84*7f106882SDag-Erling Smørgrav 	if (e == PAM_SUCCESS && !verbose)
85*7f106882SDag-Erling Smørgrav 		return;
86*7f106882SDag-Erling Smørgrav 	va_start(ap, fmt);
87*7f106882SDag-Erling Smørgrav 	vfprintf(stderr, fmt, ap);
88*7f106882SDag-Erling Smørgrav 	va_end(ap);
89*7f106882SDag-Erling Smørgrav 	fprintf(stderr, ": %s\n", pam_strerror(NULL, e));
90*7f106882SDag-Erling Smørgrav }
91*7f106882SDag-Erling Smørgrav 
92*7f106882SDag-Erling Smørgrav /*
93*7f106882SDag-Erling Smørgrav  * Wrapper for pam_start(3)
94*7f106882SDag-Erling Smørgrav  */
95*7f106882SDag-Erling Smørgrav static int
96*7f106882SDag-Erling Smørgrav pt_start(const char *service, const char *user)
97*7f106882SDag-Erling Smørgrav {
98*7f106882SDag-Erling Smørgrav 	int pame;
99*7f106882SDag-Erling Smørgrav 
100*7f106882SDag-Erling Smørgrav 	pamc.conv = &openpam_ttyconv;
101*7f106882SDag-Erling Smørgrav 	pt_verbose("pam_start(%s, %s)", service, user);
102*7f106882SDag-Erling Smørgrav 	if ((pame = pam_start(service, user, &pamc, &pamh)) != PAM_SUCCESS)
103*7f106882SDag-Erling Smørgrav 		pt_error(pame, "pam_start(%s)", service);
104*7f106882SDag-Erling Smørgrav 	return (pame);
105*7f106882SDag-Erling Smørgrav }
106*7f106882SDag-Erling Smørgrav 
107*7f106882SDag-Erling Smørgrav /*
108*7f106882SDag-Erling Smørgrav  * Wrapper for pam_authenticate(3)
109*7f106882SDag-Erling Smørgrav  */
110*7f106882SDag-Erling Smørgrav static int
111*7f106882SDag-Erling Smørgrav pt_authenticate(int flags)
112*7f106882SDag-Erling Smørgrav {
113*7f106882SDag-Erling Smørgrav 	int pame;
114*7f106882SDag-Erling Smørgrav 
115*7f106882SDag-Erling Smørgrav 	flags |= silent;
116*7f106882SDag-Erling Smørgrav 	if ((pame = pam_authenticate(pamh, flags)) != PAM_SUCCESS)
117*7f106882SDag-Erling Smørgrav 		pt_error(pame, "pam_authenticate()");
118*7f106882SDag-Erling Smørgrav 	return (pame);
119*7f106882SDag-Erling Smørgrav }
120*7f106882SDag-Erling Smørgrav 
121*7f106882SDag-Erling Smørgrav /*
122*7f106882SDag-Erling Smørgrav  * Wrapper for pam_acct_mgmt(3)
123*7f106882SDag-Erling Smørgrav  */
124*7f106882SDag-Erling Smørgrav static int
125*7f106882SDag-Erling Smørgrav pt_acct_mgmt(int flags)
126*7f106882SDag-Erling Smørgrav {
127*7f106882SDag-Erling Smørgrav 	int pame;
128*7f106882SDag-Erling Smørgrav 
129*7f106882SDag-Erling Smørgrav 	flags |= silent;
130*7f106882SDag-Erling Smørgrav 	if ((pame = pam_acct_mgmt(pamh, flags)) != PAM_SUCCESS)
131*7f106882SDag-Erling Smørgrav 		pt_error(pame, "pam_acct_mgmt()");
132*7f106882SDag-Erling Smørgrav 	return (pame);
133*7f106882SDag-Erling Smørgrav }
134*7f106882SDag-Erling Smørgrav 
135*7f106882SDag-Erling Smørgrav /*
136*7f106882SDag-Erling Smørgrav  * Wrapper for pam_chauthtok(3)
137*7f106882SDag-Erling Smørgrav  */
138*7f106882SDag-Erling Smørgrav static int
139*7f106882SDag-Erling Smørgrav pt_chauthtok(int flags)
140*7f106882SDag-Erling Smørgrav {
141*7f106882SDag-Erling Smørgrav 	int pame;
142*7f106882SDag-Erling Smørgrav 
143*7f106882SDag-Erling Smørgrav 	flags |= silent;
144*7f106882SDag-Erling Smørgrav 	if ((pame = pam_chauthtok(pamh, flags)) != PAM_SUCCESS)
145*7f106882SDag-Erling Smørgrav 		pt_error(pame, "pam_chauthtok()");
146*7f106882SDag-Erling Smørgrav 	return (pame);
147*7f106882SDag-Erling Smørgrav }
148*7f106882SDag-Erling Smørgrav 
149*7f106882SDag-Erling Smørgrav /*
150*7f106882SDag-Erling Smørgrav  * Wrapper for pam_setcred(3)
151*7f106882SDag-Erling Smørgrav  */
152*7f106882SDag-Erling Smørgrav static int
153*7f106882SDag-Erling Smørgrav pt_setcred(int flags)
154*7f106882SDag-Erling Smørgrav {
155*7f106882SDag-Erling Smørgrav 	int pame;
156*7f106882SDag-Erling Smørgrav 
157*7f106882SDag-Erling Smørgrav 	flags |= silent;
158*7f106882SDag-Erling Smørgrav 	if ((pame = pam_setcred(pamh, flags)) != PAM_SUCCESS)
159*7f106882SDag-Erling Smørgrav 		pt_error(pame, "pam_setcred()");
160*7f106882SDag-Erling Smørgrav 	return (pame);
161*7f106882SDag-Erling Smørgrav }
162*7f106882SDag-Erling Smørgrav 
163*7f106882SDag-Erling Smørgrav /*
164*7f106882SDag-Erling Smørgrav  * Wrapper for pam_open_session(3)
165*7f106882SDag-Erling Smørgrav  */
166*7f106882SDag-Erling Smørgrav static int
167*7f106882SDag-Erling Smørgrav pt_open_session(int flags)
168*7f106882SDag-Erling Smørgrav {
169*7f106882SDag-Erling Smørgrav 	int pame;
170*7f106882SDag-Erling Smørgrav 
171*7f106882SDag-Erling Smørgrav 	flags |= silent;
172*7f106882SDag-Erling Smørgrav 	if ((pame = pam_open_session(pamh, flags)) != PAM_SUCCESS)
173*7f106882SDag-Erling Smørgrav 		pt_error(pame, "pam_open_session()");
174*7f106882SDag-Erling Smørgrav 	return (pame);
175*7f106882SDag-Erling Smørgrav }
176*7f106882SDag-Erling Smørgrav 
177*7f106882SDag-Erling Smørgrav /*
178*7f106882SDag-Erling Smørgrav  * Wrapper for pam_close_session(3)
179*7f106882SDag-Erling Smørgrav  */
180*7f106882SDag-Erling Smørgrav static int
181*7f106882SDag-Erling Smørgrav pt_close_session(int flags)
182*7f106882SDag-Erling Smørgrav {
183*7f106882SDag-Erling Smørgrav 	int pame;
184*7f106882SDag-Erling Smørgrav 
185*7f106882SDag-Erling Smørgrav 	flags |= silent;
186*7f106882SDag-Erling Smørgrav 	if ((pame = pam_close_session(pamh, flags)) != PAM_SUCCESS)
187*7f106882SDag-Erling Smørgrav 		pt_error(pame, "pam_close_session()");
188*7f106882SDag-Erling Smørgrav 	return (pame);
189*7f106882SDag-Erling Smørgrav }
190*7f106882SDag-Erling Smørgrav 
191*7f106882SDag-Erling Smørgrav /*
192*7f106882SDag-Erling Smørgrav  * Wrapper for pam_set_item(3)
193*7f106882SDag-Erling Smørgrav  */
194*7f106882SDag-Erling Smørgrav static int
195*7f106882SDag-Erling Smørgrav pt_set_item(int item, const char *p)
196*7f106882SDag-Erling Smørgrav {
197*7f106882SDag-Erling Smørgrav 	int pame;
198*7f106882SDag-Erling Smørgrav 
199*7f106882SDag-Erling Smørgrav 	switch (item) {
200*7f106882SDag-Erling Smørgrav 	case PAM_SERVICE:
201*7f106882SDag-Erling Smørgrav 	case PAM_USER:
202*7f106882SDag-Erling Smørgrav 	case PAM_AUTHTOK:
203*7f106882SDag-Erling Smørgrav 	case PAM_OLDAUTHTOK:
204*7f106882SDag-Erling Smørgrav 	case PAM_TTY:
205*7f106882SDag-Erling Smørgrav 	case PAM_RHOST:
206*7f106882SDag-Erling Smørgrav 	case PAM_RUSER:
207*7f106882SDag-Erling Smørgrav 	case PAM_USER_PROMPT:
208*7f106882SDag-Erling Smørgrav 	case PAM_AUTHTOK_PROMPT:
209*7f106882SDag-Erling Smørgrav 	case PAM_OLDAUTHTOK_PROMPT:
210*7f106882SDag-Erling Smørgrav 	case PAM_HOST:
211*7f106882SDag-Erling Smørgrav 		pt_verbose("setting %s to %s", pam_item_name[item], p);
212*7f106882SDag-Erling Smørgrav 		break;
213*7f106882SDag-Erling Smørgrav 	default:
214*7f106882SDag-Erling Smørgrav 		pt_verbose("setting %s", pam_item_name[item]);
215*7f106882SDag-Erling Smørgrav 		break;
216*7f106882SDag-Erling Smørgrav 	}
217*7f106882SDag-Erling Smørgrav 	if ((pame = pam_set_item(pamh, item, p)) != PAM_SUCCESS)
218*7f106882SDag-Erling Smørgrav 		pt_error(pame, "pam_set_item(%s)", pam_item_name[item]);
219*7f106882SDag-Erling Smørgrav 	return (pame);
220*7f106882SDag-Erling Smørgrav }
221*7f106882SDag-Erling Smørgrav 
222*7f106882SDag-Erling Smørgrav /*
223*7f106882SDag-Erling Smørgrav  * Wrapper for pam_end(3)
224*7f106882SDag-Erling Smørgrav  */
225*7f106882SDag-Erling Smørgrav static int
226*7f106882SDag-Erling Smørgrav pt_end(int pame)
227*7f106882SDag-Erling Smørgrav {
228*7f106882SDag-Erling Smørgrav 
229*7f106882SDag-Erling Smørgrav 	if (pamh != NULL && (pame = pam_end(pamh, pame)) != PAM_SUCCESS)
230*7f106882SDag-Erling Smørgrav 		/* can't happen */
231*7f106882SDag-Erling Smørgrav 		pt_error(pame, "pam_end()");
232*7f106882SDag-Erling Smørgrav 	return (pame);
233*7f106882SDag-Erling Smørgrav }
234*7f106882SDag-Erling Smørgrav 
235*7f106882SDag-Erling Smørgrav /*
236*7f106882SDag-Erling Smørgrav  * Retrieve and list the PAM environment variables
237*7f106882SDag-Erling Smørgrav  */
238*7f106882SDag-Erling Smørgrav static int
239*7f106882SDag-Erling Smørgrav pt_listenv(void)
240*7f106882SDag-Erling Smørgrav {
241*7f106882SDag-Erling Smørgrav 	char **pam_envlist, **pam_env;
242*7f106882SDag-Erling Smørgrav 
243*7f106882SDag-Erling Smørgrav 	if ((pam_envlist = pam_getenvlist(pamh)) == NULL ||
244*7f106882SDag-Erling Smørgrav 	    *pam_envlist == NULL) {
245*7f106882SDag-Erling Smørgrav 		pt_verbose("no environment variables.");
246*7f106882SDag-Erling Smørgrav 	} else {
247*7f106882SDag-Erling Smørgrav 		pt_verbose("environment variables:");
248*7f106882SDag-Erling Smørgrav 		for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env) {
249*7f106882SDag-Erling Smørgrav 			printf(" %s\n", *pam_env);
250*7f106882SDag-Erling Smørgrav 			free(*pam_env);
251*7f106882SDag-Erling Smørgrav 		}
252*7f106882SDag-Erling Smørgrav 	}
253*7f106882SDag-Erling Smørgrav 	free(pam_envlist);
254*7f106882SDag-Erling Smørgrav 	return (PAM_SUCCESS);
255*7f106882SDag-Erling Smørgrav }
256*7f106882SDag-Erling Smørgrav 
257*7f106882SDag-Erling Smørgrav /*
258*7f106882SDag-Erling Smørgrav  * Print usage string and exit
259*7f106882SDag-Erling Smørgrav  */
260*7f106882SDag-Erling Smørgrav static void
261*7f106882SDag-Erling Smørgrav usage(void)
262*7f106882SDag-Erling Smørgrav {
263*7f106882SDag-Erling Smørgrav 
264*7f106882SDag-Erling Smørgrav 	fprintf(stderr, "usage: pamtest [-dksv] %s\n",
265*7f106882SDag-Erling Smørgrav 	    "[-H rhost] [-h host] [-t tty] [-U ruser] [-u user] service");
266*7f106882SDag-Erling Smørgrav 	exit(1);
267*7f106882SDag-Erling Smørgrav }
268*7f106882SDag-Erling Smørgrav 
269*7f106882SDag-Erling Smørgrav /*
270*7f106882SDag-Erling Smørgrav  * Handle an option that takes a string argument and can be used only once
271*7f106882SDag-Erling Smørgrav  */
272*7f106882SDag-Erling Smørgrav static void
273*7f106882SDag-Erling Smørgrav opt_str_once(int opt, const char **p, const char *arg)
274*7f106882SDag-Erling Smørgrav {
275*7f106882SDag-Erling Smørgrav 
276*7f106882SDag-Erling Smørgrav 	if (*p != NULL) {
277*7f106882SDag-Erling Smørgrav 		fprintf(stderr, "The -%c option can only be used once\n", opt);
278*7f106882SDag-Erling Smørgrav 		usage();
279*7f106882SDag-Erling Smørgrav 	}
280*7f106882SDag-Erling Smørgrav 	*p = arg;
281*7f106882SDag-Erling Smørgrav }
282*7f106882SDag-Erling Smørgrav 
283*7f106882SDag-Erling Smørgrav /*
284*7f106882SDag-Erling Smørgrav  * Entry point
285*7f106882SDag-Erling Smørgrav  */
286*7f106882SDag-Erling Smørgrav int
287*7f106882SDag-Erling Smørgrav main(int argc, char *argv[])
288*7f106882SDag-Erling Smørgrav {
289*7f106882SDag-Erling Smørgrav 	char hostname[1024];
290*7f106882SDag-Erling Smørgrav 	const char *rhost = NULL;
291*7f106882SDag-Erling Smørgrav 	const char *host = NULL;
292*7f106882SDag-Erling Smørgrav 	const char *ruser = NULL;
293*7f106882SDag-Erling Smørgrav 	const char *user = NULL;
294*7f106882SDag-Erling Smørgrav 	const char *service = NULL;
295*7f106882SDag-Erling Smørgrav 	const char *tty = NULL;
296*7f106882SDag-Erling Smørgrav 	int keepatit = 0;
297*7f106882SDag-Erling Smørgrav 	int pame;
298*7f106882SDag-Erling Smørgrav 	int opt;
299*7f106882SDag-Erling Smørgrav 
300*7f106882SDag-Erling Smørgrav 	while ((opt = getopt(argc, argv, "dH:h:kst:U:u:v")) != -1)
301*7f106882SDag-Erling Smørgrav 		switch (opt) {
302*7f106882SDag-Erling Smørgrav 		case 'd':
303*7f106882SDag-Erling Smørgrav 			openpam_debug++;
304*7f106882SDag-Erling Smørgrav 			break;
305*7f106882SDag-Erling Smørgrav 		case 'H':
306*7f106882SDag-Erling Smørgrav 			opt_str_once(opt, &rhost, optarg);
307*7f106882SDag-Erling Smørgrav 			break;
308*7f106882SDag-Erling Smørgrav 		case 'h':
309*7f106882SDag-Erling Smørgrav 			opt_str_once(opt, &host, optarg);
310*7f106882SDag-Erling Smørgrav 			break;
311*7f106882SDag-Erling Smørgrav 		case 'k':
312*7f106882SDag-Erling Smørgrav 			keepatit = 1;
313*7f106882SDag-Erling Smørgrav 			break;
314*7f106882SDag-Erling Smørgrav 		case 's':
315*7f106882SDag-Erling Smørgrav 			silent = PAM_SILENT;
316*7f106882SDag-Erling Smørgrav 			break;
317*7f106882SDag-Erling Smørgrav 		case 't':
318*7f106882SDag-Erling Smørgrav 			opt_str_once(opt, &tty, optarg);
319*7f106882SDag-Erling Smørgrav 			break;
320*7f106882SDag-Erling Smørgrav 		case 'U':
321*7f106882SDag-Erling Smørgrav 			opt_str_once(opt, &ruser, optarg);
322*7f106882SDag-Erling Smørgrav 			break;
323*7f106882SDag-Erling Smørgrav 		case 'u':
324*7f106882SDag-Erling Smørgrav 			opt_str_once(opt, &user, optarg);
325*7f106882SDag-Erling Smørgrav 			break;
326*7f106882SDag-Erling Smørgrav 		case 'v':
327*7f106882SDag-Erling Smørgrav 			verbose++;
328*7f106882SDag-Erling Smørgrav 			break;
329*7f106882SDag-Erling Smørgrav 		default:
330*7f106882SDag-Erling Smørgrav 			usage();
331*7f106882SDag-Erling Smørgrav 		}
332*7f106882SDag-Erling Smørgrav 
333*7f106882SDag-Erling Smørgrav 	argc -= optind;
334*7f106882SDag-Erling Smørgrav 	argv += optind;
335*7f106882SDag-Erling Smørgrav 
336*7f106882SDag-Erling Smørgrav 	if (argc < 1)
337*7f106882SDag-Erling Smørgrav 		usage();
338*7f106882SDag-Erling Smørgrav 
339*7f106882SDag-Erling Smørgrav 	service = *argv;
340*7f106882SDag-Erling Smørgrav 	--argc;
341*7f106882SDag-Erling Smørgrav 	++argv;
342*7f106882SDag-Erling Smørgrav 
343*7f106882SDag-Erling Smørgrav 	/* defaults */
344*7f106882SDag-Erling Smørgrav 	if (rhost == NULL) {
345*7f106882SDag-Erling Smørgrav 		if (gethostname(hostname, sizeof(hostname)) == -1)
346*7f106882SDag-Erling Smørgrav 			err(1, "gethostname()");
347*7f106882SDag-Erling Smørgrav 		rhost = hostname;
348*7f106882SDag-Erling Smørgrav 	}
349*7f106882SDag-Erling Smørgrav 	if (tty == NULL)
350*7f106882SDag-Erling Smørgrav 		tty = ttyname(STDERR_FILENO);
351*7f106882SDag-Erling Smørgrav 	if (user == NULL)
352*7f106882SDag-Erling Smørgrav 		user = getlogin();
353*7f106882SDag-Erling Smørgrav 	if (ruser == NULL)
354*7f106882SDag-Erling Smørgrav 		ruser = user;
355*7f106882SDag-Erling Smørgrav 
356*7f106882SDag-Erling Smørgrav 	/* initialize PAM */
357*7f106882SDag-Erling Smørgrav 	if ((pame = pt_start(service, user)) != PAM_SUCCESS)
358*7f106882SDag-Erling Smørgrav 		goto end;
359*7f106882SDag-Erling Smørgrav 
360*7f106882SDag-Erling Smørgrav 	/*
361*7f106882SDag-Erling Smørgrav 	 * pam_start(3) sets this to the machine's hostname, but we allow
362*7f106882SDag-Erling Smørgrav 	 * the user to override it.
363*7f106882SDag-Erling Smørgrav 	 */
364*7f106882SDag-Erling Smørgrav 	if (host != NULL)
365*7f106882SDag-Erling Smørgrav 		if ((pame = pt_set_item(PAM_HOST, host)) != PAM_SUCCESS)
366*7f106882SDag-Erling Smørgrav 		    goto end;
367*7f106882SDag-Erling Smørgrav 
368*7f106882SDag-Erling Smørgrav 	/*
369*7f106882SDag-Erling Smørgrav 	 * The remote host / user / tty are usually set by the
370*7f106882SDag-Erling Smørgrav 	 * application.
371*7f106882SDag-Erling Smørgrav 	 */
372*7f106882SDag-Erling Smørgrav 	if ((pame = pt_set_item(PAM_RHOST, rhost)) != PAM_SUCCESS ||
373*7f106882SDag-Erling Smørgrav 	    (pame = pt_set_item(PAM_RUSER, ruser)) != PAM_SUCCESS ||
374*7f106882SDag-Erling Smørgrav 	    (pame = pt_set_item(PAM_TTY, tty)) != PAM_SUCCESS)
375*7f106882SDag-Erling Smørgrav 		goto end;
376*7f106882SDag-Erling Smørgrav 
377*7f106882SDag-Erling Smørgrav 	while (argc > 0) {
378*7f106882SDag-Erling Smørgrav 		if (strcmp(*argv, "listenv") == 0 ||
379*7f106882SDag-Erling Smørgrav 		    strcmp(*argv, "env") == 0) {
380*7f106882SDag-Erling Smørgrav 			pame = pt_listenv();
381*7f106882SDag-Erling Smørgrav 		} else if (strcmp(*argv, "authenticate") == 0 ||
382*7f106882SDag-Erling Smørgrav 		    strcmp(*argv, "auth") == 0) {
383*7f106882SDag-Erling Smørgrav 			pame = pt_authenticate(0);
384*7f106882SDag-Erling Smørgrav 		} else if (strcmp(*argv, "acct_mgmt") == 0 ||
385*7f106882SDag-Erling Smørgrav 		    strcmp(*argv, "account") == 0) {
386*7f106882SDag-Erling Smørgrav 			pame = pt_acct_mgmt(0);
387*7f106882SDag-Erling Smørgrav 		} else if (strcmp(*argv, "chauthtok") == 0 ||
388*7f106882SDag-Erling Smørgrav 		    strcmp(*argv, "change") == 0) {
389*7f106882SDag-Erling Smørgrav 			pame = pt_chauthtok(PAM_CHANGE_EXPIRED_AUTHTOK);
390*7f106882SDag-Erling Smørgrav 		} else if (strcmp(*argv, "forcechauthtok") == 0 ||
391*7f106882SDag-Erling Smørgrav 		    strcmp(*argv, "forcechange") == 0) {
392*7f106882SDag-Erling Smørgrav 			pame = pt_chauthtok(0);
393*7f106882SDag-Erling Smørgrav 		} else if (strcmp(*argv, "setcred") == 0 ||
394*7f106882SDag-Erling Smørgrav 		    strcmp(*argv, "establish_cred") == 0) {
395*7f106882SDag-Erling Smørgrav 			pame = pt_setcred(PAM_ESTABLISH_CRED);
396*7f106882SDag-Erling Smørgrav 		} else if (strcmp(*argv, "open_session") == 0 ||
397*7f106882SDag-Erling Smørgrav 		    strcmp(*argv, "open") == 0) {
398*7f106882SDag-Erling Smørgrav 			pame = pt_open_session(0);
399*7f106882SDag-Erling Smørgrav 		} else if (strcmp(*argv, "close_session") == 0 ||
400*7f106882SDag-Erling Smørgrav 		    strcmp(*argv, "close") == 0) {
401*7f106882SDag-Erling Smørgrav 			pame = pt_close_session(0);
402*7f106882SDag-Erling Smørgrav 		} else if (strcmp(*argv, "unsetcred") == 0 ||
403*7f106882SDag-Erling Smørgrav 		    strcmp(*argv, "delete_cred") == 0) {
404*7f106882SDag-Erling Smørgrav 			pame = pt_setcred(PAM_DELETE_CRED);
405*7f106882SDag-Erling Smørgrav 		} else {
406*7f106882SDag-Erling Smørgrav 			warnx("unknown primitive: %s", *argv);
407*7f106882SDag-Erling Smørgrav 			pame = PAM_SYSTEM_ERR;
408*7f106882SDag-Erling Smørgrav 		}
409*7f106882SDag-Erling Smørgrav 		if (pame != PAM_SUCCESS && !keepatit) {
410*7f106882SDag-Erling Smørgrav 			warnx("test aborted");
411*7f106882SDag-Erling Smørgrav 			break;
412*7f106882SDag-Erling Smørgrav 		}
413*7f106882SDag-Erling Smørgrav 		--argc;
414*7f106882SDag-Erling Smørgrav 		++argv;
415*7f106882SDag-Erling Smørgrav 	}
416*7f106882SDag-Erling Smørgrav 
417*7f106882SDag-Erling Smørgrav end:
418*7f106882SDag-Erling Smørgrav 	(void)pt_end(pame);
419*7f106882SDag-Erling Smørgrav 	exit(pame == PAM_SUCCESS ? 0 : 1);
420*7f106882SDag-Erling Smørgrav }
421