1/*-
2 * Copyright (c) 2001,2003 Networks Associates Technology, Inc.
3 * All rights reserved.
4 *
5 * This software was developed for the FreeBSD Project by ThinkSec AS and
6 * NAI Labs, the Security Research Division of Network Associates, Inc.
7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
8 * DARPA CHATS research program.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote
19 *    products derived from this software without specific prior written
20 *    permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: releng/10.2/lib/libpam/modules/pam_echo/pam_echo.c 123448 2003-12-11 13:55:16Z des $");
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41
42#include <security/pam_appl.h>
43#include <security/pam_modules.h>
44#include <security/openpam.h>
45
46static int
47_pam_echo(pam_handle_t *pamh, int flags,
48    int argc, const char *argv[])
49{
50	char msg[PAM_MAX_MSG_SIZE];
51	const void *str;
52	const char *p, *q;
53	int err, i, item;
54	size_t len;
55
56	if (flags & PAM_SILENT)
57		return (PAM_SUCCESS);
58	for (i = 0, len = 0; i < argc && len < sizeof(msg) - 1; ++i) {
59		if (i > 0)
60			msg[len++] = ' ';
61		for (p = argv[i]; *p != '\0' && len < sizeof(msg) - 1; ++p) {
62			if (*p != '%' || p[1] == '\0') {
63				msg[len++] = *p;
64				continue;
65			}
66			switch (*++p) {
67			case 'H':
68				item = PAM_RHOST;
69				break;
70			case 'h':
71				/* not implemented */
72				item = -1;
73				break;
74			case 's':
75				item = PAM_SERVICE;
76				break;
77			case 't':
78				item = PAM_TTY;
79				break;
80			case 'U':
81				item = PAM_RUSER;
82				break;
83			case 'u':
84				item = PAM_USER;
85				break;
86			default:
87				item = -1;
88				msg[len++] = *p;
89				break;
90			}
91			if (item == -1)
92				continue;
93			err = pam_get_item(pamh, item, &str);
94			if (err != PAM_SUCCESS)
95				return (err);
96			if (str == NULL)
97				str = "(null)";
98			for (q = str; *q != '\0' && len < sizeof(msg) - 1; ++q)
99				msg[len++] = *q;
100		}
101	}
102	msg[len] = '\0';
103	return (pam_info(pamh, "%s", msg));
104}
105
106PAM_EXTERN int
107pam_sm_authenticate(pam_handle_t *pamh, int flags,
108    int argc, const char *argv[])
109{
110
111	return (_pam_echo(pamh, flags, argc, argv));
112}
113
114PAM_EXTERN int
115pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused,
116    int argc __unused, const char *argv[] __unused)
117{
118
119	return (PAM_SUCCESS);
120}
121
122PAM_EXTERN int
123pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
124    int argc, const char *argv[])
125{
126
127	return (_pam_echo(pamh, flags, argc, argv));
128}
129
130PAM_EXTERN int
131pam_sm_open_session(pam_handle_t *pamh, int flags,
132    int argc, const char *argv[])
133{
134
135	return (_pam_echo(pamh, flags, argc, argv));
136}
137
138PAM_EXTERN int
139pam_sm_close_session(pam_handle_t *pamh, int flags,
140    int argc, const char *argv[])
141{
142
143	return (_pam_echo(pamh, flags, argc, argv));
144}
145
146PAM_EXTERN int
147pam_sm_chauthtok(pam_handle_t *pamh, int flags,
148    int argc, const char *argv[])
149{
150
151	if (flags & PAM_PRELIM_CHECK)
152		return (PAM_SUCCESS);
153	return (_pam_echo(pamh, flags, argc, argv));
154}
155
156PAM_MODULE_ENTRY("pam_echo");
157