1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright (c) 1992-1995, by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27#pragma	ident	"%Z%%M%	%I%	%E% SMI"
28
29#include <security/pam_appl.h>
30#include <string.h>
31#include <stdlib.h>
32#include <malloc.h>
33
34#include "sample_utils.h"
35
36/* ******************************************************************** */
37/*									*/
38/* 		Utilities Functions					*/
39/*									*/
40/* ******************************************************************** */
41
42/*
43 * __free_msg():
44 *	free storage for messages used in the call back "pam_conv" functions
45 */
46
47void
48__free_msg(num_msg, msg)
49	int num_msg;
50	struct pam_message *msg;
51{
52	int 			i;
53	struct pam_message 	*m;
54
55	if (msg) {
56		m = msg;
57		for (i = 0; i < num_msg; i++, m++) {
58			if (m->msg)
59				free(m->msg);
60		}
61		free(msg);
62	}
63}
64
65/*
66 * __free_resp():
67 *	free storage for responses used in the call back "pam_conv" functions
68 */
69
70void
71__free_resp(num_msg, resp)
72	int num_msg;
73	struct pam_response *resp;
74{
75	int			i;
76	struct pam_response	*r;
77
78	if (resp) {
79		r = resp;
80		for (i = 0; i < num_msg; i++, r++) {
81			if (r->resp)
82				free(r->resp);
83		}
84		free(resp);
85	}
86}
87
88/*
89 * __display_errmsg():
90 *	display error message by calling the call back functions
91 *	provided by the application through "pam_conv" structure
92 */
93
94int
95__display_errmsg(conv_funp, num_msg, messages, conv_apdp)
96	int (*conv_funp)();
97	int num_msg;
98	char messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE];
99	void *conv_apdp;
100{
101	struct pam_message	*msg;
102	struct pam_message	*m;
103	struct pam_response	*resp;
104	int			i;
105	int			k;
106	int			retcode;
107
108	msg = (struct pam_message *)calloc(num_msg,
109					sizeof (struct pam_message));
110	if (msg == NULL) {
111		return (PAM_CONV_ERR);
112	}
113	m = msg;
114
115	i = 0;
116	k = num_msg;
117	resp = NULL;
118	while (k--) {
119		/*
120		 * fill out the pam_message structure to display error message
121		 */
122		m->msg_style = PAM_ERROR_MSG;
123		m->msg = (char *)malloc(PAM_MAX_MSG_SIZE);
124		if (m->msg != NULL)
125			(void) strcpy(m->msg, (const char *)messages[i]);
126		else
127			continue;
128		m++;
129		i++;
130	}
131
132	/*
133	 * Call conv function to display the message,
134	 * ignoring return value for now
135	 */
136	retcode = conv_funp(num_msg, &msg, &resp, conv_apdp);
137	__free_msg(num_msg, msg);
138	__free_resp(num_msg, resp);
139	return (retcode);
140}
141
142/*
143 * __get_authtok():
144 *	get authentication token by calling the call back functions
145 *	provided by the application through "pam_conv" structure
146 */
147
148int
149__get_authtok(conv_funp, num_msg, messages, conv_apdp, ret_respp)
150	int (*conv_funp)();
151	int num_msg;
152	char messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE];
153	void *conv_apdp;
154	struct pam_response	**ret_respp;
155{
156	struct pam_message	*msg;
157	struct pam_message	*m;
158	int			i;
159	int			k;
160	int			retcode;
161
162	i = 0;
163	k = num_msg;
164
165	msg = (struct pam_message *)calloc(num_msg,
166						sizeof (struct pam_message));
167	if (msg == NULL) {
168		return (PAM_CONV_ERR);
169	}
170	m = msg;
171
172	while (k--) {
173		/*
174		 * fill out the message structure to display error message
175		 */
176		m->msg_style = PAM_PROMPT_ECHO_OFF;
177		m->msg = (char *)malloc(PAM_MAX_MSG_SIZE);
178		if (m->msg != NULL)
179			(void) strcpy(m->msg, (char *)messages[i]);
180		else
181			continue;
182		m++;
183		i++;
184	}
185
186	/*
187	 * Call conv function to display the prompt,
188	 * ignoring return value for now
189	 */
190	retcode = conv_funp(num_msg, &msg, ret_respp, conv_apdp);
191	__free_msg(num_msg, msg);
192	return (retcode);
193}
194