OSDN Git Service

e24d7422b47432f6e18daed59d087543f0971768
[opengatem/opengatem.git] / mngsrc / auth-pam.c
1 /**************************************************
2 OpengateM - MAC address authentication system 
3  module for Authentication by PAM
4
5 Copyright (C) 2002 Opengate Project Team
6 Written by Yoshiaki Watanabe
7
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.
12
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.
17
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.
21
22 Email: watanaby@is.saga-u.ac.jp
23 **************************************************/
24 /*
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.
29 */
30
31 #include <security/pam_appl.h>
32 #include "opengatemmng.h"
33
34 int pamCallback(int num_msg, const struct pam_message **msg,
35                     struct pam_response **resp, void *appdata_ptr);
36
37 static struct pam_conv pamConv; /* PAM conversation info */
38
39 typedef struct {
40   char *userid;
41   char *password;
42 } userInfo_t;
43
44 /******************************/
45 /* authentication by PAM      */
46 /* need to edit /etc/pam.conf */
47 /******************************/
48 int authPam(char *userid, char *passwd)
49 {
50   char serviceName[ADDRMAXLN];
51   char *serviceNameInConf;
52   pam_handle_t *pamh=NULL;
53   int retval;
54   userInfo_t userInfo;
55   
56   /* get pam service name used in pam config file */
57   serviceNameInConf=GetConfValue("AuthServer/ServiceName");
58
59   /* if not defined in conf, use the default name 'opengate' */
60   if(isNull(serviceNameInConf)){
61     strlcpy(serviceName, PAMSERVICENAME, ADDRMAXLN);
62   }else{
63     strlcpy(serviceName, serviceNameInConf, ADDRMAXLN);
64   }
65   
66   if(!userid || !passwd) return DENY;
67   
68   /* set userInfo which is passed to call-back function */
69   userInfo.userid=userid;
70   userInfo.password=passwd;
71   
72   /* setting of call back function (its name and data) */
73   pamConv.conv=pamCallback;
74   pamConv.appdata_ptr=&userInfo;
75   
76   /* root privilege is needed to control PAM */
77   if(seteuid(0)!=0){
78     err_msg("ERR at %s#%d: cannot add root privilege ",
79             __FILE__,__LINE__);
80   } 
81
82   /* PAM start */
83   retval = pam_start(serviceName, userid, &pamConv, &pamh);
84   
85   /* at success, check auth */
86   if (retval == PAM_SUCCESS){
87     retval = pam_authenticate(pamh, 0);    /* is user really user? */
88   }
89   
90   /* at success, check account */
91   if (retval == PAM_SUCCESS){
92     retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
93   }
94   
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));
98   }
99   
100   /* PAM end */
101   if (pam_end(pamh,retval) != PAM_SUCCESS) {
102     pamh = NULL;
103     err_msg("ERR at %s#%d: failed to release authenticator",__FILE__,__LINE__);
104   }
105   
106   /* remove root privilege */
107   seteuid(getuid()); 
108
109   /* clear password */
110   userInfo.password = NULL;
111
112   return ( retval == PAM_SUCCESS ? ACCEPT:DENY );       /* indicate success */
113 }
114
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)
120 {
121   userInfo_t *userInfo = (userInfo_t *)appdata_ptr;
122   struct pam_response *response=NULL;
123   int i;
124   
125   /* parameter check */
126   if(!resp || !msg || !userInfo) return PAM_CONV_ERR;
127
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;
132
133   /* set user informations */
134   for(i=0; i<num_msg; i++){
135     response[i].resp_retcode=0;
136     response[i].resp=NULL;
137
138     switch(msg[i]->msg_style){
139     case PAM_PROMPT_ECHO_ON:   /* must be requesting userid */
140       response[i].resp=(char *)strdup(userInfo->userid);
141       break;
142     case PAM_PROMPT_ECHO_OFF:   /* must be requesting password */
143       response[i].resp=(char *)strdup(userInfo->password);
144       break;                 
145     default:                 
146       break;                 
147     }
148   }
149
150   *resp = response;
151   return PAM_SUCCESS;
152 }
153
154 /************ For DEBUG ********************/
155 int AuthPam(char *userid, char *passwd)
156 {
157   int ret;
158
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);
162
163   return ret;
164 }