1183370Simp/*	$NetBSD$	*/
2183370Simp
3183370Simp/*-
4183370Simp * Copyright (c) 2001,2003 Networks Associates Technology, Inc.
5183370Simp * All rights reserved.
6183370Simp *
7183370Simp * This software was developed for the FreeBSD Project by ThinkSec AS and
8183370Simp * NAI Labs, the Security Research Division of Network Associates, Inc.
9183370Simp * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
10183370Simp * DARPA CHATS research program.
11183370Simp *
12183370Simp * Redistribution and use in source and binary forms, with or without
13183370Simp * modification, are permitted provided that the following conditions
14183370Simp * are met:
15183370Simp * 1. Redistributions of source code must retain the above copyright
16183370Simp *    notice, this list of conditions and the following disclaimer.
17183370Simp * 2. Redistributions in binary form must reproduce the above copyright
18183370Simp *    notice, this list of conditions and the following disclaimer in the
19183370Simp *    documentation and/or other materials provided with the distribution.
20183370Simp * 3. The name of the author may not be used to endorse or promote
21183370Simp *    products derived from this software without specific prior written
22183370Simp *    permission.
23183370Simp *
24183370Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25183370Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26183370Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27183370Simp * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28183370Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29183370Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30183370Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31183370Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32183370Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33183370Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34183370Simp * SUCH DAMAGE.
35183370Simp */
36183370Simp
37183370Simp#include <sys/cdefs.h>
38183370Simp#ifdef __FreeBSD__
39183370Simp__FBSDID("$FreeBSD: src/lib/libpam/modules/pam_echo/pam_echo.c,v 1.4 2003/12/11 13:55:15 des Exp $");
40183370Simp#else
41183370Simp__RCSID("$NetBSD$");
42183370Simp#endif
43183370Simp
44183370Simp#include <stdio.h>
45183370Simp#include <stdlib.h>
46183370Simp#include <string.h>
47183370Simp
48183370Simp#include <security/pam_appl.h>
49183370Simp#include <security/pam_modules.h>
50183370Simp#include <security/openpam.h>
51183370Simp
52183370Simpstatic int
53183370Simp_pam_echo(pam_handle_t *pamh, int flags,
54183370Simp    int argc, const char *argv[])
55183370Simp{
56183370Simp	char msg[PAM_MAX_MSG_SIZE];
57183370Simp	const void *str;
58183370Simp	const char *p, *q;
59183370Simp	int err, i, item;
60183370Simp	size_t len;
61183370Simp
62183370Simp	if (flags & PAM_SILENT)
63183370Simp		return (PAM_SUCCESS);
64257341Snwhitehorn	for (i = 0, len = 0; i < argc && len < sizeof(msg) - 1; ++i) {
65183370Simp		if (i > 0)
66183370Simp			msg[len++] = ' ';
67183370Simp		for (p = argv[i]; *p != '\0' && len < sizeof(msg) - 1; ++p) {
68183370Simp			if (*p != '%' || p[1] == '\0') {
69183370Simp				msg[len++] = *p;
70183370Simp				continue;
71183370Simp			}
72183370Simp			switch (*++p) {
73183370Simp			case 'H':
74183370Simp				item = PAM_RHOST;
75183370Simp				break;
76183370Simp			case 'h':
77183370Simp				/* not implemented */
78183370Simp				item = -1;
79183370Simp				break;
80183370Simp			case 's':
81183370Simp				item = PAM_SERVICE;
82183370Simp				break;
83183370Simp			case 't':
84183370Simp				item = PAM_TTY;
85183370Simp				break;
86183370Simp			case 'U':
87183370Simp				item = PAM_RUSER;
88183370Simp				break;
89183370Simp			case 'u':
90183370Simp				item = PAM_USER;
91183370Simp				break;
92183370Simp			default:
93183370Simp				item = -1;
94183370Simp				msg[len++] = *p;
95183370Simp				break;
96183370Simp			}
97183370Simp			if (item == -1)
98183370Simp				continue;
99183370Simp			err = pam_get_item(pamh, item, &str);
100183370Simp			if (err != PAM_SUCCESS)
101183370Simp				return (err);
102183370Simp			if (str == NULL)
103183370Simp				str = "(null)";
104183370Simp			for (q = str; *q != '\0' && len < sizeof(msg) - 1; ++q)
105183370Simp				msg[len++] = *q;
106183370Simp		}
107183370Simp	}
108183370Simp	msg[len] = '\0';
109183370Simp	return (pam_info(pamh, "%s", msg));
110183370Simp}
111183370Simp
112183370SimpPAM_EXTERN int
113183370Simppam_sm_authenticate(pam_handle_t *pamh, int flags,
114183370Simp    int argc, const char *argv[])
115183370Simp{
116183370Simp
117183370Simp	return (_pam_echo(pamh, flags, argc, argv));
118183370Simp}
119183370Simp
120183370SimpPAM_EXTERN int
121183370Simppam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused,
122183370Simp    int argc __unused, const char *argv[] __unused)
123183370Simp{
124183370Simp
125183370Simp	return (PAM_SUCCESS);
126183370Simp}
127183370Simp
128183370SimpPAM_EXTERN int
129183370Simppam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
130183370Simp    int argc, const char *argv[])
131183370Simp{
132183370Simp
133183370Simp	return (_pam_echo(pamh, flags, argc, argv));
134183370Simp}
135183370Simp
136183370SimpPAM_EXTERN int
137183370Simppam_sm_open_session(pam_handle_t *pamh, int flags,
138183370Simp    int argc, const char *argv[])
139183370Simp{
140183370Simp
141183370Simp	return (_pam_echo(pamh, flags, argc, argv));
142183370Simp}
143183370Simp
144183370SimpPAM_EXTERN int
145183370Simppam_sm_close_session(pam_handle_t *pamh, int flags,
146183370Simp    int argc, const char *argv[])
147183370Simp{
148183370Simp
149183370Simp	return (_pam_echo(pamh, flags, argc, argv));
150183370Simp}
151183370Simp
152183370SimpPAM_EXTERN int
153183370Simppam_sm_chauthtok(pam_handle_t *pamh, int flags,
154183370Simp    int argc, const char *argv[])
155183370Simp{
156183370Simp
157183370Simp	if (flags & PAM_PRELIM_CHECK)
158183370Simp		return (PAM_SUCCESS);
159183370Simp	return (_pam_echo(pamh, flags, argc, argv));
160}
161
162PAM_MODULE_ENTRY("pam_echo");
163