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 
47 void
__free_msg(num_msg,msg)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 
70 void
__free_resp(num_msg,resp)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 
94 int
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 
148 int
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