45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync * VirtualBox External Authentication Library:
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * Linux PAM Authentication.
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2012 Oracle Corporation
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * available from http://www.virtualbox.org. This file is free software;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * General Public License (GPL) as published by the Free Software
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync/* The PAM service name.
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * The service name is the name of a file in the /etc/pam.d which contains
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * authentication rules. It is possible to use an existing service
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * name, like "login" for example. But if different set of rules
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * is required, one can create a new file /etc/pam.d/vrdpauth
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * specially for VRDP authentication. Note that the name of the
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * service must be lowercase. See PAM documentation for details.
b8908d384db2324f04a2f68a13e67ea32ebf609avboxsync * The Auth module takes the PAM service name from the
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync * environment variable VBOX_AUTH_PAM_SERVICE. If the variable
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * is not specified, then the 'login' PAM service is used.
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#define VBOX_AUTH_PAM_SERVICE_NAME_ENV_OLD "VRDP_AUTH_PAM_SERVICE"
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#define VBOX_AUTH_PAM_SERVICE_NAME_ENV "VBOX_AUTH_PAM_SERVICE"
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync/* The debug log file name.
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * If defined, debug messages will be written to the file specified in the
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync * VBOX_AUTH_DEBUG_FILENAME (or deprecated VRDP_AUTH_DEBUG_FILENAME) environment
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync * variable:
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync * export VBOX_AUTH_DEBUG_FILENAME=pam.log
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * The above will cause writing to the pam.log.
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#define VBOX_AUTH_DEBUG_FILENAME_ENV_OLD "VRDP_AUTH_DEBUG_FILENAME"
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#define VBOX_AUTH_DEBUG_FILENAME_ENV "VBOX_AUTH_DEBUG_FILENAME"
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync/* Dynamic loading of the PAM library.
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * If defined, the libpam.so is loaded dynamically.
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * Enabled by default since it is often required,
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * and does not harm.
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync/* The name of the PAM library */
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#endif /* VBOX_AUTH_USE_PAM_DLLOAD */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsyncstatic int (*fn_pam_start)(const char *service_name,
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync const char *user,
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsyncstatic int (*fn_pam_authenticate)(pam_handle_t *pamh, int flags);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsyncstatic int (*fn_pam_acct_mgmt)(pam_handle_t *pamh, int flags);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsyncstatic int (*fn_pam_end)(pam_handle_t *pamh, int pam_status);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsyncstatic const char * (*fn_pam_strerror)(pam_handle_t *pamh, int errnum);
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#endif /* VBOX_AUTH_USE_PAM_DLLOAD */
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#if defined(VBOX_AUTH_DEBUG_FILENAME_ENV) || defined(VBOX_AUTH_DEBUG_FILENAME_ENV_OLD)
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#endif /* VBOX_AUTH_DEBUG_FILENAME_ENV */
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync filename = getenv (VBOX_AUTH_DEBUG_FILENAME_ENV_OLD);
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#endif /* VBOX_AUTH_DEBUG_FILENAME_ENV_OLD */
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#endif /* VBOX_AUTH_DEBUG_FILENAME_ENV || VBOX_AUTH_DEBUG_FILENAME_ENV_OLD */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync { (void **)&fn_pam_authenticate, "pam_authenticate" },
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync gpvLibPam = dlopen(PAM_LIB_NAME, RTLD_LAZY | RTLD_GLOBAL);
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync debug_printf("auth_pam_init: dlopen %s failed\n", PAM_LIB_NAME);
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync debug_printf("auth_pam_init: dlsym %s failed\n", iter->pszName);
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync#endif /* VBOX_AUTH_USE_PAM_DLLOAD */
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync const char *service = getenv (VBOX_AUTH_PAM_SERVICE_NAME_ENV);
2c9f3fde0860800f2237593200b107464e67ab70vboxsync service = getenv (VBOX_AUTH_PAM_SERVICE_NAME_ENV_OLD);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsyncstatic int conv (int num_msg, const struct pam_message **msg,
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync debug_printf("conv: num %d u[%s] p[%d]\n", num_msg, ctx->szUser, ctx->szPassword? strlen (ctx->szPassword): 0);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync r = (struct pam_response *) calloc (num_msg, sizeof (struct pam_response));
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync for (i = 0; i < num_msg; i++)
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync debug_printf("conv: %d returning password [%d]\n", i, r[i].resp? strlen (r[i].resp): 0);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync debug_printf("conv: %d returning name [%s]\n", i, r[i].resp);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync debug_printf("conv: %d style %d: [%s]\n", i, msg[i]->msg_style, msg[i]->msg? msg[i]->msg: "(null)");
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync/* The entry point must be visible. */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync# define DECLEXPORT(type) __declspec(dllexport) type
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync# define DECLEXPORT(type) __attribute__((visibility("default"))) type
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync/* prototype to prevent gcc warning */
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsyncDECLEXPORT(AuthResult) AUTHCALL AuthEntry(const char *szCaller,
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync const char *szUser,
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync const char *szDomain,
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsyncDECLEXPORT(AuthResult) AUTHCALL AuthEntry(const char *szCaller,
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync const char *szUser,
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync const char *szDomain,
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync /* Only process logon requests. */
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync return result; /* Return value is ignored by the caller. */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync debug_printf("u[%s], d[%s], p[%d]\n", szUser, szDomain, szPassword? strlen (szPassword): 0);
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync rc = fn_pam_start(auth_get_pam_service (), szUser, &pam_conversation, &pam_handle);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync debug_printf("pam_acct_mgmt failed %d. %s\n", rc, fn_pam_strerror (pam_handle, rc));
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync debug_printf("pam_authenticate failed %d. %s\n", rc, fn_pam_strerror (pam_handle, rc));
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync/* Verify the function prototype. */