xref: /illumos-gate/usr/src/lib/pam_modules/sample/sample_utils.c (revision 29267a9d01e87d9c5d871a7bb863719d89a51281)
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