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
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #include "OW_String.hpp"
00038 #include "OW_ConfigOpts.hpp"
00039 #include "OW_AuthenticatorIFC.hpp"
00040 #include "OW_Array.hpp"
00041
00042 #include <string.h>
00043
00044 #ifdef OW_GNU_LINUX
00045 #ifdef OW_HAVE_PWD_H
00046 #include <pwd.h>
00047 #endif
00048 #ifdef OW_HAVE_UNISTD_H
00049 #include <unistd.h>
00050 #endif
00051 #ifdef OW_HAVE_SYS_TYPES_H
00052 #include <sys/types.h>
00053 #endif
00054 #endif
00055
00056
00057 extern "C"
00058 {
00059 #if defined OW_HAVE_PAM_PAM_APPL_H
00060 #include <pam/pam_appl.h>
00061 #elif defined OW_HAVE_SECURITY_PAM_APPL_H
00062 #include <security/pam_appl.h>
00063 #endif
00064 #if defined OW_HAVE_PAM_PAM_MISC_H
00065 #include <pam/pam_misc.h>
00066 #elif defined OW_HAVE_SECURITY_PAM_MISC_H
00067 #include <security/pam_misc.h>
00068 #endif
00069 }
00070
00071 namespace OW_NAMESPACE
00072 {
00073
00082 #if defined(OW_HPUX) || defined(OW_SOLARIS) || defined(OW_AIX)
00083 static int PAM_conv(int num_msg, struct pam_message **msgm, struct pam_response **response, void *appdata_ptr);
00084 #else
00085 static int PAM_conv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *appdata_ptr);
00086 #endif
00087
00088 class LinuxPAMAuthentication : public AuthenticatorIFC
00089 {
00103 private:
00104 virtual bool doAuthenticate(String &userName, const String &info,
00105 String &details, OperationContext& context);
00106
00107 virtual void doInit(ServiceEnvironmentIFCRef env);
00108 String m_allowedUsers;
00109 };
00110
00112 bool
00113 LinuxPAMAuthentication::doAuthenticate(String &userName, const String &info,
00114 String &details, OperationContext& context)
00115 {
00116 if (info.empty())
00117 {
00118 details = "You must authenticate to access this resource";
00119 return false;
00120 }
00121 Array<String> allowedUsers = m_allowedUsers.tokenize();
00122 bool nameFound = false;
00123 for (size_t i = 0; i < allowedUsers.size(); i++)
00124 {
00125 if (allowedUsers[i].equals(userName)
00126 || allowedUsers[i].equals("*"))
00127 {
00128 nameFound = true;
00129 break;
00130 }
00131 }
00132 if (!nameFound)
00133 {
00134 details = "You must authenticate to access this resource";
00135 return false;
00136 }
00137
00138
00139
00140
00141 char* pPasswd = strdup(info.c_str());
00142 char* pUserName = strdup(userName.c_str());
00143 struct pam_conv conv = {
00144 PAM_conv,
00145 pPasswd
00146 };
00147 pam_handle_t *pamh=NULL;
00148 int rval;
00149 rval = pam_start(OW_PACKAGE_PREFIX"openwbem", pUserName, &conv, &pamh);
00150 if (rval == PAM_SUCCESS)
00151 {
00152 rval = pam_authenticate(pamh, 0);
00153 }
00154 if (rval == PAM_SUCCESS)
00155 {
00156 rval = pam_acct_mgmt(pamh, 0);
00157 }
00158 if (rval == PAM_CONV_ERR)
00159 {
00160 pam_end(pamh, rval);
00161 free(pUserName);
00162 details = "Error in Linux-PAM conversation function";
00163 return false;
00164 }
00165 if (pam_end(pamh,rval) != PAM_SUCCESS)
00166 {
00167 pamh = NULL;
00168 details = "Unable to close PAM transaction";
00169 return false;
00170 }
00171 free(pUserName);
00172
00173 bool retval = ( rval == PAM_SUCCESS ? true : false );
00174
00175 if (!retval)
00176 {
00177 details = "Invalid credentials";
00178 }
00179
00180
00181 return retval;
00182 }
00183
00184 #if !defined(_pam_overwrite)
00185 #define _pam_overwrite(x) \
00186 do { \
00187 register char *__xx__; \
00188 if ((__xx__=(x))) \
00189 { \
00190 while (*__xx__) \
00191 { \
00192 *__xx__++ = '\0'; \
00193 } \
00194 } \
00195 } while (0)
00196
00197 #endif
00198
00199
00201
00202
00203 #if defined(OW_HPUX) || defined(OW_SOLARIS) || defined(OW_AIX)
00204 int
00205 PAM_conv(int num_msg, struct pam_message **msgm, struct pam_response **response, void *appdata_ptr)
00206 #else
00207 int
00208 PAM_conv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *appdata_ptr)
00209 #endif
00210 {
00211 int count=0;
00212 struct pam_response *reply;
00213 if (num_msg <= 0)
00214 {
00215 return PAM_CONV_ERR;
00216 }
00217
00218 reply = static_cast<struct pam_response *>(calloc(num_msg, sizeof(struct pam_response)));
00219 if (reply == NULL)
00220 {
00221
00222 return PAM_CONV_ERR;
00223 }
00224 bool failed = false;
00225
00226 for (count=0; count < num_msg; ++count)
00227 {
00228 char *string=NULL;
00229 if (failed == true)
00230 {
00231 break;
00232 }
00233 switch (msgm[count]->msg_style)
00234 {
00235 case PAM_PROMPT_ECHO_OFF:
00236 string = reinterpret_cast<char*>(appdata_ptr);
00237 if (string == NULL)
00238 {
00239 failed = true;
00240 }
00241 break;
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 default:
00274
00275
00276 failed = true;
00277 }
00278 if (string)
00279 {
00280
00281 reply[count].resp_retcode = 0;
00282 reply[count].resp = string;
00283 string = NULL;
00284 }
00285 }
00286
00287
00288 if (!failed)
00289 {
00290 *response = reply;
00291 reply = NULL;
00292 }
00293 else
00294 {
00295 if (reply)
00296 {
00297 for (count=0; count<num_msg; ++count)
00298 {
00299 if (reply[count].resp == NULL)
00300 {
00301 continue;
00302 }
00303 switch (msgm[count]->msg_style)
00304 {
00305
00306 case PAM_PROMPT_ECHO_OFF:
00307 _pam_overwrite(reply[count].resp);
00308 free(reply[count].resp);
00309 break;
00310
00311
00312
00313
00314
00315
00316
00317 }
00318 reply[count].resp = NULL;
00319 }
00320 free(reply);
00321 reply = NULL;
00322 }
00323 return PAM_CONV_ERR;
00324 }
00325 return PAM_SUCCESS;
00326 }
00327 void LinuxPAMAuthentication::doInit(ServiceEnvironmentIFCRef env)
00328 {
00329 m_allowedUsers = env->getConfigItem(ConfigOpts::PAM_ALLOWED_USERS_opt);
00330 }
00331
00332 }
00333
00334 OW_AUTHENTICATOR_FACTORY(OpenWBEM::LinuxPAMAuthentication,pam);
00335
00336