blob: 5cf3b40754363463aec4cb677b77434bb38014dd [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2004-2006 Intel Corp. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corp. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @author Vadim Revyakin
*/
#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif
#define NO_DLLOAD
#include <string.h>
#include <stdlib.h>
#if defined(HAVE_PAM_PAM_APPL_H)
#include <pam/pam_appl.h>
#elif defined(HAVE_SECURITY_PAM_APPL_H)
#include <security/pam_appl.h>
#endif
#if defined(HAVE_PAM_PAM_MISC_H)
#include <pam/pam_misc.h>
#elif defined(HAVE_SECURITY_PAM_MISC_H)
#include <security/pam_misc.h>
#endif
#ifndef STANDALONE
#include "u/libu.h"
int initialize(void *arg);
int authorize(char *username, const char *password);
#endif
static char *service = "openwsman";
#define debug_dlsym(sym) \
debug("Could not dlsym %s", sym)
#ifdef STANDALONE
#include <stdio.h>
#define debug(frmt, ...) \
printf(frmt, __VA_ARGS__); printf("\n")
#define PAM_start pam_start
#define PAM_authenticate pam_authenticate
#define PAM_acct_mgmt pam_acct_mgmt
#define PAM_end pam_end
#define PAM_strerror pam_strerror
#else
#ifdef NO_DLLOAD
#define PAM_start pam_start
#define PAM_authenticate pam_authenticate
#define PAM_acct_mgmt pam_acct_mgmt
#define PAM_end pam_end
#define PAM_strerror pam_strerror
int
initialize(void *arg)
{
return 0;
}
#else // !STANDALONE && !NO_DLLOAD
#include <dlfcn.h>
#define LIBPAM "libpam.so"
static int (*PAM_start)(const char *service_name,
const char *user,
const struct pam_conv *pam_conversation,
pam_handle_t **pamh);
static int (*PAM_authenticate)(pam_handle_t *pamh, int flags);
static int (*PAM_acct_mgmt)(pam_handle_t *pamh, int flags);
static int (*PAM_end)(pam_handle_t *pamh, int pam_status);
static int (*PAM_strerror)(pam_handle_t *pamh, int errnum);
int
initialize(void *arg)
{
void *hnd;
hnd = dlopen(LIBPAM, RTLD_LAZY | RTLD_GLOBAL);
if (hnd == NULL) {
debug("Could not dlopen %s", LIBPAM);
return 1;
}
PAM_start = dlsym(hnd, "pam_start");
if (PAM_start == NULL) {
debug_dlsym("pam_start");
dlclose(hnd);
return 1;
}
PAM_authenticate = dlsym(hnd, "pam_authenticate");
if (PAM_authenticate == NULL) {
debug_dlsym("pam_authenticate");
dlclose(hnd);
return 1;
}
PAM_acct_mgmt = dlsym(hnd, "pam_acct_mgmt");
if (PAM_acct_mgmt == NULL) {
debug_dlsym("pam_acct_mgmt");
dlclose(hnd);
return 1;
}
PAM_end = dlsym(hnd, "pam_end");
if (PAM_end == NULL) {
debug_dlsym("pam_end");
dlclose(hnd);
return 1;
}
PAM_strerror = dlsym(hnd, "pam_strerror");
if (PAM_strerror == NULL) {
debug_dlsym("pam_strerror");
dlclose(hnd);
return 1;
}
if (arg != NULL) {
service = (char *)arg;
}
// debug_level = dbg_lvl;
return 0;
}
#endif // NO_DLLOAD
#endif // STANDALONE
static int
#if defined (__SVR4) && defined (__sun)
pwd_conv(int num_msg, struct pam_message **msgm,
#else
pwd_conv(int num_msg, const struct pam_message **msgm,
#endif
struct pam_response **response, void *appdata_ptr)
{
char *pwd = (char *)appdata_ptr;
int n;
struct pam_response *reply;
reply = (struct pam_response *) calloc(num_msg,
sizeof(struct pam_response));
if (reply == NULL) {
debug("No %s", "memory");
return PAM_CONV_ERR;
}
for (n = 0; n < num_msg; n++) {
switch (msgm[n]->msg_style) {
case PAM_PROMPT_ECHO_OFF:
case PAM_PROMPT_ECHO_ON:
reply[n].resp = strdup(pwd);
break;
}
}
*response = reply;
return PAM_SUCCESS;
}
#ifdef STANDALONE
static
#endif
int
authorize(char *username, const char *password)
{
struct pam_conv conv = {
pwd_conv,
(void *)password
};
pam_handle_t *pamh = NULL;
int r;
int res = 0;
// printf("service = %s\n", service);
r = PAM_start(service, username, &conv, &pamh);
if (r != PAM_SUCCESS) {
debug("pam_start failed = %d(%s)", r, PAM_strerror(pamh, r));
return 0;
}
r = PAM_authenticate(pamh, PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
if (r != PAM_SUCCESS) {
debug("pam_authenticate failed = %d(%s)", r, PAM_strerror(pamh, r));
goto DONE;
}
r = PAM_acct_mgmt(pamh, PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
if (r != PAM_SUCCESS) {
debug("pam_ acct_mgmt failed = %d(%s)", r, PAM_strerror(pamh, r));
goto DONE;
}
res = 1;
DONE:
r = PAM_end(pamh, r);
if (r != PAM_SUCCESS) {
debug("pam_end failed = %d(%s)", r, PAM_strerror(pamh, r));
}
return res;
}
#ifdef STANDALONE
/*
* run
* gcc -o wspam -DSTANDALONE wsmand_pam.c -lpam
* to build a program
*/
int main(int argc, char **argv)
{
char *user;
char *pwd;
int res;
if ((argc != 3) && (argc != 4)) {
printf("Usage: wsmand_pam <user> <password> [<service>]\n");
return 1;
}
if (argc == 4) {
service = argv[3];
}
if (authorize(argv[1], argv[2])) {
printf("Authenticated\n");
} else {
printf("Not Authenticated\n");
}
if (authorize(argv[1], argv[2])) {
printf("Authenticated\n");
} else {
printf("Not Authenticated\n");
}
return 0;
}
#endif