VBoxAuthPAM.c revision 9c0076729ec8138e89ce8a6af9a772b68f1f8dc7
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * VBox Remote Desktop Protocol:
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * External Authentication Library:
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * Linux PAM Authentication.
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * Copyright (C) 2006-2010 Oracle Corporation
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * available from http://www.virtualbox.org. This file is free software;
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * General Public License (GPL) as published by the Free Software
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync/* The PAM service name.
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * The service name is the name of a file in the /etc/pam.d which contains
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * authentication rules. It is possible to use an existing service
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * name, like "login" for example. But if different set of rules
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * is required, one can create a new file /etc/pam.d/vrdpauth
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * specially for VRDP authentication. Note that the name of the
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * service must be lowercase. See PAM documentation for details.
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * The VRDPAuth module takes the PAM service name from the
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * environment variable VRDP_AUTH_PAM_SERVICE. If the variable
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * is not specified, then the 'login' PAM service is used.
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync#define VRDP_AUTH_PAM_SERVICE_NAME_ENV "VRDP_AUTH_PAM_SERVICE"
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync/* The debug log file name.
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * If defined, debug messages will be written to the file specified in the
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * VRDP_AUTH_DEBUG_FILENAME environment variable:
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * export VRDP_AUTH_DEBUG_FILENAME=pam.log
a3f3701cea1ba388e7c877955252bb7375eedebdvboxsync * The above will cause writing to the pam.log.
* If defined, the libpam.so is loaded dynamically.
#define VRDP_PAM_DLLOAD
#ifdef VRDP_PAM_DLLOAD
# ifdef RT_OS_SOLARIS
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#ifndef RT_OS_FREEBSD
# include <malloc.h>
#ifdef VRDP_PAM_DLLOAD
#include <dlfcn.h>
const char *user,
#ifdef VRDP_AUTH_DEBUG_FILENAME_ENV
if (filename)
FILE *f;
if (f != NULL)
fclose (f);
#ifdef VRDP_PAM_DLLOAD
typedef struct _SymMap
void **ppfn;
const char *pszName;
} SymMap;
static int vrdpauth_pam_init(void)
if (!gpvLibPam)
return PAM_SYSTEM_ERR;
return PAM_SYSTEM_ERR;
iter++;
return PAM_SUCCESS;
static void vrdpauth_pam_close(void)
if (gpvLibPam)
static int vrdpauth_pam_init(void)
return PAM_SUCCESS;
static void vrdpauth_pam_close(void)
static const char *vrdpauth_get_pam_service (void)
return service;
typedef struct _PamContext
char *szUser;
char *szPassword;
} PamContext;
struct pam_response *r;
return PAM_CONV_ERR;
debug_printf("conv: num %d u[%s] p[%d]\n", num_msg, ctx->szUser, ctx->szPassword? strlen (ctx->szPassword): 0);
if (r == NULL)
return PAM_CONV_ERR;
for (i = 0; i < num_msg; i++)
r[i].resp_retcode = 0;
debug_printf("conv: %d style %d: [%s]\n", i, msg[i]->msg_style, msg[i]->msg? msg[i]->msg: "(null)");
*resp = r;
return PAM_SUCCESS;
# ifdef VBOX_HAVE_VISIBILITY_HIDDEN
const char *szUser,
const char *szPassword,
const char *szDomain);
const char *szUser,
const char *szPassword,
const char *szDomain)
int rc;
return result;