1 /**************************************************
3 module for Authentication by PAM
5 Copyright (C) 2002 Yoshiaki Watanabe
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 Email: watanaby@is.saga-u.ac.jp
22 **************************************************/
24 Thanks to programs and documentations refered.
25 The Linux-PAM Application Developer's Guide by A. G. Morgan.
26 The example appilication in above doc by Shane Watts
27 Manual files about PAM.
30 #include <security/pam_appl.h>
31 #include "opengatesrv.h"
33 int pamCallback(int num_msg, const struct pam_message **msg,
34 struct pam_response **resp, void *appdata_ptr);
36 static struct pam_conv pamConv; /* PAM conversation info */
43 /******************************/
44 /* authentication by PAM */
45 /* need to edit /etc/pam.conf */
46 /******************************/
47 int authPam(char *serviceName, char *userid, char *passwd)
49 pam_handle_t *pamh=NULL;
53 if(serviceName[0]=='\0'){
54 strncpy(serviceName, PAMSERVICENAME, ADDRMAXLN);
57 if(!userid || !passwd) return DENY;
59 /* set userInfo which is passed to call back function */
60 userInfo.userid=userid;
61 userInfo.password=passwd;
63 /* setting of call back function (its name and data) */
64 pamConv.conv=pamCallback;
65 pamConv.appdata_ptr=&userInfo;
68 retval = pam_start(serviceName, userid, &pamConv, &pamh);
70 /* at success, check auth */
71 if (retval == PAM_SUCCESS){
72 retval = pam_authenticate(pamh, 0); /* is user really user? */
75 /* at success, check account */
76 if (retval == PAM_SUCCESS){
77 retval = pam_acct_mgmt(pamh, 0); /* permitted access? */
80 /* error message if not success */
81 if (retval != PAM_SUCCESS){
82 err_msg("ERR in auth-pam: %s\n", pam_strerror(pamh, retval));
86 if (pam_end(pamh,retval) != PAM_SUCCESS) {
88 err_msg("ERR in auth-pam: failed to release authenticator\n");
91 userInfo.password = NULL;
92 return ( retval == PAM_SUCCESS ? ACCEPT:DENY ); /* indicate success */
95 /**************************************************************/
96 /* Send user information to PAM. Called back from PAM module. */
97 /**************************************************************/
98 int pamCallback(int num_msg, const struct pam_message **msg,
99 struct pam_response **resp, void *appdata_ptr)
101 userInfo_t *userInfo = (userInfo_t *)appdata_ptr;
102 struct pam_response *response=NULL;
105 /* parameter check */
106 if(!resp || !msg || !userInfo) return PAM_CONV_ERR;
108 /* allocate memory to store response */
109 response = (struct pam_response *)
110 malloc(num_msg * sizeof(struct pam_response));
111 if(!response) return PAM_CONV_ERR;
113 /* set user informations */
114 for(i=0; i<num_msg; i++){
115 response[i].resp_retcode=0;
116 response[i].resp=NULL;
118 switch(msg[i]->msg_style){
119 case PAM_PROMPT_ECHO_ON: /* must be requesting userid */
120 response[i].resp=(char *)strdup(userInfo->userid);
122 case PAM_PROMPT_ECHO_OFF: /* must be requesting password */
123 response[i].resp=(char *)strdup(userInfo->password);
134 /************ For DEBUG ********************/
135 int AuthPam(char *serviceName, char *userid, char *passwd)
139 if(DEBUG) err_msg("DEBUG:=>authPam(%s,%s,passwd)",serviceName,userid);
140 ret=authPam(serviceName, userid, passwd);
141 if(DEBUG) err_msg("DEBUG:(%d)<=authPam( )",ret);