xref: /illumos-gate/usr/src/lib/pam_modules/sample/sample_utils.c (revision da7fc762b82ced1a0ec19a51e04cdf823187ec77)
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 #include <security/pam_appl.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <malloc.h>
31 
32 #include "sample_utils.h"
33 
34 /* ******************************************************************** */
35 /*									*/
36 /* 		Utilities Functions					*/
37 /*									*/
38 /* ******************************************************************** */
39 
40 /*
41  * __free_msg():
42  *	free storage for messages used in the call back "pam_conv" functions
43  */
44 
45 void
46 __free_msg(num_msg, msg)
47 	int num_msg;
48 	struct pam_message *msg;
49 {
50 	int 			i;
51 	struct pam_message 	*m;
52 
53 	if (msg) {
54 		m = msg;
55 		for (i = 0; i < num_msg; i++, m++) {
56 			if (m->msg)
57 				free(m->msg);
58 		}
59 		free(msg);
60 	}
61 }
62 
63 /*
64  * __free_resp():
65  *	free storage for responses used in the call back "pam_conv" functions
66  */
67 
68 void
69 __free_resp(num_msg, resp)
70 	int num_msg;
71 	struct pam_response *resp;
72 {
73 	int			i;
74 	struct pam_response	*r;
75 
76 	if (resp) {
77 		r = resp;
78 		for (i = 0; i < num_msg; i++, r++) {
79 			if (r->resp)
80 				free(r->resp);
81 		}
82 		free(resp);
83 	}
84 }
85 
86 /*
87  * __display_errmsg():
88  *	display error message by calling the call back functions
89  *	provided by the application through "pam_conv" structure
90  */
91 
92 int
93 __display_errmsg(conv_funp, num_msg, messages, conv_apdp)
94 	int (*conv_funp)();
95 	int num_msg;
96 	char messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE];
97 	void *conv_apdp;
98 {
99 	struct pam_message	*msg;
100 	struct pam_message	*m;
101 	struct pam_response	*resp;
102 	int			i;
103 	int			k;
104 	int			retcode;
105 
106 	msg = (struct pam_message *)calloc(num_msg,
107 					sizeof (struct pam_message));
108 	if (msg == NULL) {
109 		return (PAM_CONV_ERR);
110 	}
111 	m = msg;
112 
113 	i = 0;
114 	k = num_msg;
115 	resp = NULL;
116 	while (k--) {
117 		/*
118 		 * fill out the pam_message structure to display error message
119 		 */
120 		m->msg_style = PAM_ERROR_MSG;
121 		m->msg = (char *)malloc(PAM_MAX_MSG_SIZE);
122 		if (m->msg != NULL)
123 			(void) strcpy(m->msg, (const char *)messages[i]);
124 		else
125 			continue;
126 		m++;
127 		i++;
128 	}
129 
130 	/*
131 	 * Call conv function to display the message,
132 	 * ignoring return value for now
133 	 */
134 	retcode = conv_funp(num_msg, &msg, &resp, conv_apdp);
135 	__free_msg(num_msg, msg);
136 	__free_resp(num_msg, resp);
137 	return (retcode);
138 }
139 
140 /*
141  * __get_authtok():
142  *	get authentication token by calling the call back functions
143  *	provided by the application through "pam_conv" structure
144  */
145 
146 int
147 __get_authtok(conv_funp, num_msg, messages, conv_apdp, ret_respp)
148 	int (*conv_funp)();
149 	int num_msg;
150 	char messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE];
151 	void *conv_apdp;
152 	struct pam_response	**ret_respp;
153 {
154 	struct pam_message	*msg;
155 	struct pam_message	*m;
156 	int			i;
157 	int			k;
158 	int			retcode;
159 
160 	i = 0;
161 	k = num_msg;
162 
163 	msg = (struct pam_message *)calloc(num_msg,
164 						sizeof (struct pam_message));
165 	if (msg == NULL) {
166 		return (PAM_CONV_ERR);
167 	}
168 	m = msg;
169 
170 	while (k--) {
171 		/*
172 		 * fill out the message structure to display error message
173 		 */
174 		m->msg_style = PAM_PROMPT_ECHO_OFF;
175 		m->msg = (char *)malloc(PAM_MAX_MSG_SIZE);
176 		if (m->msg != NULL)
177 			(void) strcpy(m->msg, (char *)messages[i]);
178 		else
179 			continue;
180 		m++;
181 		i++;
182 	}
183 
184 	/*
185 	 * Call conv function to display the prompt,
186 	 * ignoring return value for now
187 	 */
188 	retcode = conv_funp(num_msg, &msg, ret_respp, conv_apdp);
189 	__free_msg(num_msg, msg);
190 	return (retcode);
191 }
192