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 <drizzled/identifier.h>
00028 #include <drizzled/plugin/authentication.h>
00029
00030 #include <security/pam_appl.h>
00031 #if !defined(__sun) && !defined(__FreeBSD__)
00032 #include <security/pam_misc.h>
00033 #endif
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
00071
00072 for(int x= 0; x < num_msg; x++)
00073 {
00074
00075 response[x].resp_retcode= 0;
00076 response[x].resp= 0;
00077
00078
00079 switch(msg[x]->msg_style)
00080 {
00081 case PAM_PROMPT_ECHO_ON:
00082
00083 response[x].resp = strdup(userinfo->name);
00084 break;
00085 case PAM_PROMPT_ECHO_OFF:
00086 response[x].resp = strdup(userinfo->password);
00087 break;
00088 default:
00089 free(response);
00090 return PAM_CONV_ERR;
00091 }
00092 }
00093
00094
00095 *resp = response;
00096
00097 return PAM_SUCCESS;
00098 }
00099
00100 class Auth_pam : public drizzled::plugin::Authentication
00101 {
00102 public:
00103 Auth_pam(std::string name_arg)
00104 : drizzled::plugin::Authentication(name_arg) {}
00105 virtual bool authenticate(const identifier::User &sctx,
00106 const std::string &password)
00107 {
00108 int retval;
00109 auth_pam_userinfo userinfo= { NULL, NULL };
00110 struct pam_conv conv_info= { &auth_pam_talker, (void*)&userinfo };
00111 pam_handle_t *pamh= NULL;
00112
00113 userinfo.name= sctx.username().c_str();
00114 userinfo.password= password.c_str();
00115
00116 retval= pam_start("drizzle", userinfo.name, &conv_info, &pamh);
00117
00118 if (retval == PAM_SUCCESS)
00119 retval= pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK);
00120
00121 if (retval == PAM_SUCCESS)
00122 retval= pam_acct_mgmt(pamh, PAM_DISALLOW_NULL_AUTHTOK);
00123
00124 pam_end(pamh, retval);
00125
00126 return (retval == PAM_SUCCESS) ? true: false;
00127 }
00128 };
00129
00130
00131 static Auth_pam *auth= NULL;
00132
00133 static int initialize(drizzled::module::Context &context)
00134 {
00135 auth= new Auth_pam("auth_pam");
00136 context.add(auth);
00137 return 0;
00138 }
00139
00140 DRIZZLE_DECLARE_PLUGIN
00141 {
00142 DRIZZLE_VERSION_ID,
00143 "pam",
00144 "0.1",
00145 "Brian Aker",
00146 "PAM based authenication.",
00147 PLUGIN_LICENSE_GPL,
00148 initialize,
00149 NULL,
00150 NULL
00151 }
00152 DRIZZLE_DECLARE_PLUGIN_END;