1 /**************************************************
2 OpengateM - MAC address authentication system
3 module for Authentication by PAM
5 Copyright (C) 2002 Opengate Project Team
6 Written by Yoshiaki Watanabe
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 Email: watanaby@is.saga-u.ac.jp
23 **************************************************/
25 Thanks to programs and documentations refered.
26 The Linux-PAM Application Developer's Guide by A. G. Morgan.
27 The example appilication in above doc by Shane Watts
28 Manual files about PAM.
31 #include <security/pam_appl.h>
32 #include "opengatemmng.h"
34 int pamCallback(int num_msg, const struct pam_message **msg,
35 struct pam_response **resp, void *appdata_ptr);
37 static struct pam_conv pamConv; /* PAM conversation info */
44 /******************************/
45 /* authentication by PAM */
46 /* need to edit /etc/pam.conf */
47 /******************************/
48 int authPam(char *userid, char *passwd)
50 char serviceName[ADDRMAXLN];
51 char *serviceNameInConf;
52 pam_handle_t *pamh=NULL;
56 /* get pam service name used in pam config file */
57 serviceNameInConf=GetConfValue("AuthServer/ServiceName");
59 /* if not defined in conf, use the default name 'opengate' */
60 if(isNull(serviceNameInConf)){
61 strlcpy(serviceName, PAMSERVICENAME, ADDRMAXLN);
63 strlcpy(serviceName, serviceNameInConf, ADDRMAXLN);
66 if(!userid || !passwd) return DENY;
68 /* set userInfo which is passed to call-back function */
69 userInfo.userid=userid;
70 userInfo.password=passwd;
72 /* setting of call back function (its name and data) */
73 pamConv.conv=pamCallback;
74 pamConv.appdata_ptr=&userInfo;
76 /* root privilege is needed to control PAM */
78 err_msg("ERR at %s#%d: cannot add root privilege ",
83 retval = pam_start(serviceName, userid, &pamConv, &pamh);
85 /* at success, check auth */
86 if (retval == PAM_SUCCESS){
87 retval = pam_authenticate(pamh, 0); /* is user really user? */
90 /* at success, check account */
91 if (retval == PAM_SUCCESS){
92 retval = pam_acct_mgmt(pamh, 0); /* permitted access? */
95 /* error message if not success */
96 if (retval != PAM_SUCCESS){
97 err_msg("ERR at %s#%d: %s\n",__FILE__,__LINE__,pam_strerror(pamh, retval));
101 if (pam_end(pamh,retval) != PAM_SUCCESS) {
103 err_msg("ERR at %s#%d: failed to release authenticator",__FILE__,__LINE__);
106 /* remove root privilege */
110 userInfo.password = NULL;
112 return ( retval == PAM_SUCCESS ? ACCEPT:DENY ); /* indicate success */
115 /**************************************************************/
116 /* Send user information to PAM. Called back from PAM module. */
117 /**************************************************************/
118 int pamCallback(int num_msg, const struct pam_message **msg,
119 struct pam_response **resp, void *appdata_ptr)
121 userInfo_t *userInfo = (userInfo_t *)appdata_ptr;
122 struct pam_response *response=NULL;
125 /* parameter check */
126 if(!resp || !msg || !userInfo) return PAM_CONV_ERR;
128 /* allocate memory to store response */
129 response = (struct pam_response *)
130 malloc(num_msg * sizeof(struct pam_response));
131 if(!response) return PAM_CONV_ERR;
133 /* set user informations */
134 for(i=0; i<num_msg; i++){
135 response[i].resp_retcode=0;
136 response[i].resp=NULL;
138 switch(msg[i]->msg_style){
139 case PAM_PROMPT_ECHO_ON: /* must be requesting userid */
140 response[i].resp=(char *)strdup(userInfo->userid);
142 case PAM_PROMPT_ECHO_OFF: /* must be requesting password */
143 response[i].resp=(char *)strdup(userInfo->password);
154 /************ For DEBUG ********************/
155 int AuthPam(char *userid, char *passwd)
159 if(debug>1) err_msg("DEBUG:=>authPam(%s,passwd)",userid);
160 ret=authPam(userid, passwd);
161 if(debug>1) err_msg("DEBUG:(%d)<=authPam( )",ret);