OW_PAMAuthSA.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00036 #include "OW_config.h"
00037 #include <iostream>
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 
00042 extern "C"
00043 {
00044 #if defined OW_HAVE_PAM_PAM_APPL_H
00045 #include <pam/pam_appl.h>
00046 #elif defined OW_HAVE_SECURITY_PAM_APPL_H
00047 #include <security/pam_appl.h>
00048 #endif
00049 #if defined OW_HAVE_PAM_PAM_MISC_H
00050 #include <pam/pam_misc.h>
00051 #elif defined OW_HAVE_SECURITY_PAM_MISC_H
00052 #include <security/pam_misc.h>
00053 #endif
00054 }
00055 using std::cin;
00056 using std::endl;
00057 
00058 #if !defined(_pam_overwrite)
00059 #define _pam_overwrite(x)        \
00060 do {                             \
00061    register char *__xx__;       \
00062    if ((__xx__=(x)))            \
00063    {                            \
00064       while (*__xx__)          \
00065       {                        \
00066          *__xx__++ = '\0';    \
00067       }                        \
00068    }                            \
00069 } while (0)
00070 
00071 #endif
00072 
00073 
00075 #if defined(OW_HPUX) || defined(OW_SOLARIS) || defined(OW_AIX)
00076 int
00077 MY_PAM_conv(int num_msg, struct pam_message **msgm, struct pam_response **response, void *appdata_ptr)
00078 #else
00079 int
00080 MY_PAM_conv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *appdata_ptr)
00081 #endif
00082 {
00083    int count=0;
00084    struct pam_response *reply;
00085    if (num_msg <= 0)
00086    {
00087       return PAM_CONV_ERR;
00088    }
00089    //D(("allocating empty response structure array."));
00090    reply = static_cast<struct pam_response *>(calloc(num_msg, sizeof(struct pam_response)));
00091    if (reply == NULL)
00092    {
00093       //D(("no memory for responses"));
00094       return PAM_CONV_ERR;
00095    }
00096    bool failed(false);
00097    //D(("entering conversation function."));
00098    for (count=0; count < num_msg; ++count)
00099    {
00100       char *string=NULL;
00101       if (failed == true)
00102       {
00103          break;
00104       }
00105       switch (msgm[count]->msg_style)
00106       {
00107          case PAM_PROMPT_ECHO_OFF:
00108             string = reinterpret_cast<char*>(appdata_ptr);
00109             if (string == NULL)
00110             {
00111                failed = true;
00112             }
00113             break;
00114             /*case PAM_PROMPT_ECHO_ON:
00115                string = read_string(CONV_ECHO_ON,msgm[count]->msg);
00116                if (string == NULL) {
00117                   goto failed_conversation;
00118                }
00119                break;
00120             case PAM_ERROR_MSG:
00121                if (fprintf(stderr,"%s\n",msgm[count]->msg) < 0) {
00122                   goto failed_conversation;
00123                }
00124                break;
00125             case PAM_TEXT_INFO:
00126                if (fprintf(stdout,"%s\n",msgm[count]->msg) < 0) {
00127                   goto failed_conversation;
00128                }
00129                break;
00130             case PAM_BINARY_PROMPT:
00131                {
00132                   void *pack_out=NULL;
00133                   const void *pack_in = msgm[count]->msg;
00134    
00135                   if (!pam_binary_handler_fn
00136                         || pam_binary_handler_fn(pack_in, &pack_out) != PAM_SUCCESS
00137                         || pack_out == NULL) {
00138                      goto failed_conversation;
00139                   }
00140                   string = (char *) pack_out;
00141                   pack_out = NULL;
00142    
00143                   break;
00144                }*/
00145          default:
00146             fprintf(stderr, "erroneous conversation (%d)\n"
00147                     ,msgm[count]->msg_style);
00148             failed = true;
00149       }
00150       if (string)
00151       {                         /* must add to reply array */
00152          /* add string to list of responses */
00153          reply[count].resp_retcode = 0;
00154          reply[count].resp = string;
00155          string = NULL;
00156       }
00157    }
00158    /* New (0.59+) behavior is to always have a reply - this is
00159       compatable with the X/Open (March 1997) spec. */
00160    if (!failed)
00161    {
00162       *response = reply;
00163       reply = NULL;
00164    }
00165    else
00166    {
00167       if (reply)
00168       {
00169          for (count=0; count<num_msg; ++count)
00170          {
00171             if (reply[count].resp == NULL)
00172             {
00173                continue;
00174             }
00175             switch (msgm[count]->msg_style)
00176             {
00177                /*case PAM_PROMPT_ECHO_ON:*/
00178                case PAM_PROMPT_ECHO_OFF:
00179                   _pam_overwrite(reply[count].resp);
00180                   free(reply[count].resp);
00181                   break;
00182                /*case PAM_BINARY_PROMPT:
00183                   pam_binary_handler_free((void **) &reply[count].resp);
00184                   break;
00185                case PAM_ERROR_MSG:
00186                case PAM_TEXT_INFO:
00187                   // should not actually be able to get here...
00188                   free(reply[count].resp);*/
00189             } // switch
00190             reply[count].resp = NULL;
00191          } // for
00192          free(reply);
00193          reply = NULL;
00194       } // if (reply)
00195       return PAM_CONV_ERR;
00196    } // else
00197    return PAM_SUCCESS;
00198 }
00199    
00201 bool
00202 authenticate(const char* userName,
00203                const char* password)
00204 {
00205    char* pPasswd = strdup(password);
00206    char* pUserName = strdup(userName);
00207    struct pam_conv conv = {
00208       MY_PAM_conv,
00209       pPasswd
00210    };
00211    pam_handle_t *pamh=NULL;
00212    int rval;
00213    rval = pam_start(OW_PACKAGE_PREFIX"openwbem", pUserName, &conv, &pamh);
00214    if (rval == PAM_SUCCESS)
00215    {
00216       rval = pam_authenticate(pamh, 0);    /* is user really user? */
00217    }
00218    if (rval == PAM_SUCCESS)
00219    {
00220       rval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
00221    }
00222    if (rval == PAM_CONV_ERR)
00223    {
00224       pam_end(pamh, rval);
00225       free(pUserName);
00226       return false;
00227    }
00228    if (pam_end(pamh,rval) != PAM_SUCCESS)
00229    {     // close Linux-PAM
00230       pamh = NULL;
00231       return false;
00232    }
00233    free(pUserName);
00234    return( rval == PAM_SUCCESS ? true : false );       /* indicate success */
00235 }
00237 int main()
00238 {
00239    char name[80];
00240    char passwd[80];
00241    memset(name, 0, sizeof(name));
00242    memset(passwd, 0, sizeof(passwd));
00243    cin >> name;
00244    cin >> passwd;
00245    bool rval = authenticate(name, passwd);
00246    return (rval == true) ? 0: 1;
00247 }
00248 

Generated on Thu Feb 9 08:48:07 2006 for openwbem by  doxygen 1.4.6