OSDN Git Service

Ver.1.1.0: Add many parameters in conf file. Add programs for test.
[opengate/opengate.git] / opengate / opengatesrv / auth-pam.c
1 /**************************************************
2 opengate server
3  module for Authentication by PAM
4
5 Copyright (C) 2002 Yoshiaki Watanabe
6
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.
11
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.
16
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.
20
21 Email: watanaby@is.saga-u.ac.jp
22 **************************************************/
23 /*
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.
28 */
29
30 #include <security/pam_appl.h>
31 #include "opengatesrv.h"
32
33 int pamCallback(int num_msg, const struct pam_message **msg,
34                     struct pam_response **resp, void *appdata_ptr);
35
36 static struct pam_conv pamConv; /* PAM conversation info */
37
38 typedef struct {
39   char *userid;
40   char *password;
41 } userInfo_t;
42
43 /******************************/
44 /* authentication by PAM      */
45 /* need to edit /etc/pam.conf */
46 /******************************/
47 int authPam(char *userid, char *passwd)
48 {
49   char* serviceName;
50   pam_handle_t *pamh=NULL;
51   int retval;
52   userInfo_t userInfo;
53   
54   /* get pam service name used in pam config file */
55   serviceName=GetPamServiceName();
56
57   if(serviceName==NULL){
58     strncpy(serviceName, PAMSERVICENAME, ADDRMAXLN);
59   }
60   
61   if(!userid || !passwd) return DENY;
62   
63   /* set userInfo which is passed to call back function */
64   userInfo.userid=userid;
65   userInfo.password=passwd;
66   
67   /* setting of call back function (its name and data) */
68   pamConv.conv=pamCallback;
69   pamConv.appdata_ptr=&userInfo;
70   
71   /* PAM start */
72   retval = pam_start(serviceName, userid, &pamConv, &pamh);
73   
74   /* at success, check auth */
75   if (retval == PAM_SUCCESS){
76     retval = pam_authenticate(pamh, 0);    /* is user really user? */
77   }
78   
79   /* at success, check account */
80   if (retval == PAM_SUCCESS){
81     retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
82   }
83   
84   /* error message if not success */
85   if (retval != PAM_SUCCESS){
86     err_msg("ERR in auth-pam: %s\n", pam_strerror(pamh, retval));
87   }
88   
89   /* PAM end */
90   if (pam_end(pamh,retval) != PAM_SUCCESS) {
91     pamh = NULL;
92     err_msg("ERR in auth-pam: failed to release authenticator\n");
93   }
94   
95   userInfo.password = NULL;
96   return ( retval == PAM_SUCCESS ? ACCEPT:DENY );       /* indicate success */
97 }
98
99 /**************************************************************/
100 /* Send user information to PAM. Called back from PAM module. */
101 /**************************************************************/
102 int pamCallback(int num_msg, const struct pam_message **msg,
103                     struct pam_response **resp, void *appdata_ptr)
104 {
105   userInfo_t *userInfo = (userInfo_t *)appdata_ptr;
106   struct pam_response *response=NULL;
107   int i;
108   
109   /* parameter check */
110   if(!resp || !msg || !userInfo) return PAM_CONV_ERR;
111
112   /* allocate memory to store response */
113   response = (struct pam_response *)
114     malloc(num_msg * sizeof(struct pam_response));
115   if(!response) return PAM_CONV_ERR;
116
117   /* set user informations */
118   for(i=0; i<num_msg; i++){
119     response[i].resp_retcode=0;
120     response[i].resp=NULL;
121
122     switch(msg[i]->msg_style){
123     case PAM_PROMPT_ECHO_ON:   /* must be requesting userid */
124       response[i].resp=(char *)strdup(userInfo->userid);
125       break;
126     case PAM_PROMPT_ECHO_OFF:   /* must be requesting password */
127       response[i].resp=(char *)strdup(userInfo->password);
128       break;                 
129     default:                 
130       break;                 
131     }
132   }
133
134   *resp = response;
135   return PAM_SUCCESS;
136 }
137
138 /************ For DEBUG ********************/
139 int AuthPam(char *userid, char *passwd)
140 {
141   int ret;
142
143   if(DEBUG) err_msg("DEBUG:=>authPam(%s,passwd)",userid);
144   ret=authPam(userid, passwd);
145   if(DEBUG) err_msg("DEBUG:(%d)<=authPam( )",ret);
146
147   return ret;
148 }
149
150