00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <config.h>
00026
00027 #include <security/pam_appl.h>
00028 #if !defined(__sun) && !defined(__FreeBSD__)
00029 #include <security/pam_misc.h>
00030 #endif
00031
00032 #include <drizzled/identifier.h>
00033 #include <drizzled/plugin/authentication.h>
00034
00035 using namespace drizzled;
00036
00037 typedef struct {
00038 const char *name;
00039 const char *password;
00040 } auth_pam_userinfo;
00041
00042 extern "C"
00043 int auth_pam_talker(int num_msg,
00044 #ifdef __sun
00045 struct pam_message **msg,
00046 #else
00047 const struct pam_message **msg,
00048 #endif
00049 struct pam_response **resp,
00050 void *appdata_ptr);
00051
00052 int auth_pam_talker(int num_msg,
00053 #ifdef __sun
00054 struct pam_message **msg,
00055 #else
00056 const struct pam_message **msg,
00057 #endif
00058 struct pam_response **resp,
00059 void *appdata_ptr)
00060 {
00061 auth_pam_userinfo *userinfo = (auth_pam_userinfo*)appdata_ptr;
00062 struct pam_response *response = 0;
00063
00064
00065 if(not resp || not msg || not userinfo)
00066 return PAM_CONV_ERR;
00067
00068
00069 response= (struct pam_response*)malloc(num_msg * sizeof(struct pam_response));
00070 if(!response)
00071 return PAM_CONV_ERR;
00072
00073
00074 for(int x= 0; x < num_msg; x++)
00075 {
00076
00077 response[x].resp_retcode= 0;
00078 response[x].resp= 0;
00079
00080
00081 switch(msg[x]->msg_style)
00082 {
00083 case PAM_PROMPT_ECHO_ON:
00084
00085 response[x].resp = strdup(userinfo->name);
00086 break;
00087 case PAM_PROMPT_ECHO_OFF:
00088 response[x].resp = strdup(userinfo->password);
00089 break;
00090 default:
00091 if(response)
00092 free(response);
00093 return PAM_CONV_ERR;
00094 }
00095 }
00096
00097
00098 *resp = response;
00099
00100 return PAM_SUCCESS;
00101 }
00102
00103 class Auth_pam : public drizzled::plugin::Authentication
00104 {
00105 public:
00106 Auth_pam(std::string name_arg)
00107 : drizzled::plugin::Authentication(name_arg) {}
00108 virtual bool authenticate(const identifier::User &sctx,
00109 const std::string &password)
00110 {
00111 int retval;
00112 auth_pam_userinfo userinfo= { NULL, NULL };
00113 struct pam_conv conv_info= { &auth_pam_talker, (void*)&userinfo };
00114 pam_handle_t *pamh= NULL;
00115
00116 userinfo.name= sctx.username().c_str();
00117 userinfo.password= password.c_str();
00118
00119 retval= pam_start("drizzle", userinfo.name, &conv_info, &pamh);
00120
00121 if (retval == PAM_SUCCESS)
00122 retval= pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK);
00123
00124 if (retval == PAM_SUCCESS)
00125 retval= pam_acct_mgmt(pamh, PAM_DISALLOW_NULL_AUTHTOK);
00126
00127 pam_end(pamh, retval);
00128
00129 return (retval == PAM_SUCCESS) ? true: false;
00130 }
00131 };
00132
00133
00134 static Auth_pam *auth= NULL;
00135
00136 static int initialize(drizzled::module::Context &context)
00137 {
00138 auth= new Auth_pam("auth_pam");
00139 context.add(auth);
00140 return 0;
00141 }
00142
00143 DRIZZLE_DECLARE_PLUGIN
00144 {
00145 DRIZZLE_VERSION_ID,
00146 "pam",
00147 "0.1",
00148 "Brian Aker",
00149 "PAM based authenication.",
00150 PLUGIN_LICENSE_GPL,
00151 initialize,
00152 NULL,
00153 NULL
00154 }
00155 DRIZZLE_DECLARE_PLUGIN_END;