OSDN Git Service

Ver.0.8.1
[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(isNull(serviceNameInConf)){
60     strncpy(serviceName, PAMSERVICENAME, ADDRMAXLN);
61   }else{
62     strncpy(serviceName, serviceNameInConf, ADDRMAXLN);
63   }
64   
65   if(!userid || !passwd) return DENY;
66   
67   /* set userInfo which is passed to call back function */
68   userInfo.userid=userid;
69   userInfo.password=passwd;
70   
71   /* setting of call back function (its name and data) */
72   pamConv.conv=pamCallback;
73   pamConv.appdata_ptr=&userInfo;
74   
75   /* root privilege is needed to control PAM */
76   if(seteuid(0)!=0){
77     err_msg("ERR at %s#%d: cannot add root privilege ",
78             __FILE__,__LINE__);
79   } 
80
81   /* PAM start */
82   retval = pam_start(serviceName, userid, &pamConv, &pamh);
83   
84   /* at success, check auth */
85   if (retval == PAM_SUCCESS){
86     retval = pam_authenticate(pamh, 0);    /* is user really user? */
87   }
88   
89   /* at success, check account */
90   if (retval == PAM_SUCCESS){
91     retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
92   }
93   
94   /* error message if not success */
95   if (retval != PAM_SUCCESS){
96     err_msg("ERR at %s#%d: %s\n",__FILE__,__LINE__,pam_strerror(pamh, retval));
97   }
98   
99   /* PAM end */
100   if (pam_end(pamh,retval) != PAM_SUCCESS) {
101     pamh = NULL;
102     err_msg("ERR at %s#%d: failed to release authenticator",__FILE__,__LINE__);
103   }
104   
105   /* remove root privilege */
106   seteuid(getuid()); 
107
108   /* clear password */
109   userInfo.password = NULL;
110
111   return ( retval == PAM_SUCCESS ? ACCEPT:DENY );       /* indicate success */
112 }
113
114 /**************************************************************/
115 /* Send user information to PAM. Called back from PAM module. */
116 /**************************************************************/
117 int pamCallback(int num_msg, const struct pam_message **msg,
118                     struct pam_response **resp, void *appdata_ptr)
119 {
120   userInfo_t *userInfo = (userInfo_t *)appdata_ptr;
121   struct pam_response *response=NULL;
122   int i;
123   
124   /* parameter check */
125   if(!resp || !msg || !userInfo) return PAM_CONV_ERR;
126
127   /* allocate memory to store response */
128   response = (struct pam_response *)
129     malloc(num_msg * sizeof(struct pam_response));
130   if(!response) return PAM_CONV_ERR;
131
132   /* set user informations */
133   for(i=0; i<num_msg; i++){
134     response[i].resp_retcode=0;
135     response[i].resp=NULL;
136
137     switch(msg[i]->msg_style){
138     case PAM_PROMPT_ECHO_ON:   /* must be requesting userid */
139       response[i].resp=(char *)strdup(userInfo->userid);
140       break;
141     case PAM_PROMPT_ECHO_OFF:   /* must be requesting password */
142       response[i].resp=(char *)strdup(userInfo->password);
143       break;                 
144     default:                 
145       break;                 
146     }
147   }
148
149   *resp = response;
150   return PAM_SUCCESS;
151 }
152
153 /************ For DEBUG ********************/
154 int AuthPam(char *userid, char *passwd)
155 {
156   int ret;
157
158   if(debug>1) err_msg("DEBUG:=>authPam(%s,passwd)",userid);
159   ret=authPam(userid, passwd);
160   if(debug>1) err_msg("DEBUG:(%d)<=authPam( )",ret);
161
162   return ret;
163 }