mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
MDEV-26212 PAM authentication fails with ENOMEM
use posix_spawn(), not fork() - it's better for systems that don't overcommit memory
This commit is contained in:
parent
d45841b9be
commit
e6bbc83d5e
1 changed files with 32 additions and 45 deletions
|
@ -20,6 +20,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <spawn.h>
|
||||||
#include <mysql/plugin_auth.h>
|
#include <mysql/plugin_auth.h>
|
||||||
#include "auth_pam_tool.h"
|
#include "auth_pam_tool.h"
|
||||||
#include <my_global.h>
|
#include <my_global.h>
|
||||||
|
@ -51,44 +52,25 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
|
||||||
unsigned char field, *pkt;
|
unsigned char field, *pkt;
|
||||||
unsigned int n_sleep= 0;
|
unsigned int n_sleep= 0;
|
||||||
useconds_t sleep_time= 100;
|
useconds_t sleep_time= 100;
|
||||||
|
posix_spawn_file_actions_t file_actions;
|
||||||
|
char toolpath[FN_REFLEN];
|
||||||
|
size_t plugin_dir_len= strlen(opt_plugin_dir);
|
||||||
|
char *const argv[2]= {toolpath, 0};
|
||||||
|
int res;
|
||||||
|
|
||||||
PAM_DEBUG((stderr, "PAM: opening pipes.\n"));
|
PAM_DEBUG((stderr, "PAM: opening pipes.\n"));
|
||||||
if (pipe(p_to_c) < 0 || pipe(c_to_p) < 0)
|
if (pipe(p_to_c) < 0 || pipe(c_to_p) < 0)
|
||||||
{
|
{
|
||||||
/* Error creating pipes. */
|
my_printf_error(ENOEXEC, "pam: cannot create pipes (errno: %M)",
|
||||||
|
ME_ERROR_LOG_ONLY, errno);
|
||||||
return CR_ERROR;
|
return CR_ERROR;
|
||||||
}
|
}
|
||||||
PAM_DEBUG((stderr, "PAM: forking.\n"));
|
|
||||||
if ((proc_id= fork()) < 0)
|
|
||||||
{
|
|
||||||
/* Error forking. */
|
|
||||||
close(p_to_c[0]);
|
|
||||||
close(c_to_p[1]);
|
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proc_id == 0)
|
|
||||||
{
|
|
||||||
/* The 'sandbox' process started. */
|
|
||||||
char toolpath[FN_REFLEN];
|
|
||||||
size_t plugin_dir_len= strlen(opt_plugin_dir);
|
|
||||||
|
|
||||||
PAM_DEBUG((stderr, "PAM: Child process prepares pipes.\n"));
|
|
||||||
|
|
||||||
if (close(p_to_c[1]) < 0 ||
|
|
||||||
close(c_to_p[0]) < 0 ||
|
|
||||||
dup2(p_to_c[0], 0) < 0 || /* Parent's pipe to STDIN. */
|
|
||||||
dup2(c_to_p[1], 1) < 0) /* Sandbox's pipe to STDOUT. */
|
|
||||||
{
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
PAM_DEBUG((stderr, "PAM: check tool directory: %s, %s.\n",
|
|
||||||
opt_plugin_dir, tool_name));
|
|
||||||
if (plugin_dir_len + tool_name_len + 2 > sizeof(toolpath))
|
if (plugin_dir_len + tool_name_len + 2 > sizeof(toolpath))
|
||||||
{
|
{
|
||||||
/* Tool path too long. */
|
my_printf_error(ENOEXEC, "pam: too long path to <plugindir>/%s",
|
||||||
exit(-1);
|
ME_ERROR_LOG_ONLY, tool_name);
|
||||||
|
return CR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(toolpath, opt_plugin_dir, plugin_dir_len);
|
memcpy(toolpath, opt_plugin_dir, plugin_dir_len);
|
||||||
|
@ -96,20 +78,25 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
|
||||||
toolpath[plugin_dir_len++]= FN_LIBCHAR;
|
toolpath[plugin_dir_len++]= FN_LIBCHAR;
|
||||||
memcpy(toolpath+plugin_dir_len, tool_name, tool_name_len+1);
|
memcpy(toolpath+plugin_dir_len, tool_name, tool_name_len+1);
|
||||||
|
|
||||||
PAM_DEBUG((stderr, "PAM: execute pam sandbox [%s].\n", toolpath));
|
PAM_DEBUG((stderr, "PAM: forking %s\n", toolpath));
|
||||||
(void) execl(toolpath, toolpath, NULL);
|
res= posix_spawn_file_actions_init(&file_actions) ||
|
||||||
PAM_DEBUG((stderr, "PAM: exec() failed.\n"));
|
posix_spawn_file_actions_addclose(&file_actions, p_to_c[1]) ||
|
||||||
my_printf_error(1, "PAM: Cannot execute %s (errno: %M)", ME_ERROR_LOG_ONLY,
|
posix_spawn_file_actions_addclose(&file_actions, c_to_p[0]) ||
|
||||||
toolpath, errno);
|
posix_spawn_file_actions_adddup2(&file_actions, p_to_c[0], 0) ||
|
||||||
exit(-1);
|
posix_spawn_file_actions_adddup2(&file_actions, c_to_p[1], 1) ||
|
||||||
}
|
posix_spawn(&proc_id, toolpath, &file_actions, NULL, argv, NULL);
|
||||||
|
|
||||||
/* Parent process continues. */
|
/* Parent process continues. */
|
||||||
|
posix_spawn_file_actions_destroy(&file_actions);
|
||||||
|
close(p_to_c[0]);
|
||||||
|
close(c_to_p[1]);
|
||||||
|
|
||||||
PAM_DEBUG((stderr, "PAM: parent continues.\n"));
|
if (res)
|
||||||
if (close(p_to_c[0]) < 0 ||
|
{
|
||||||
close(c_to_p[1]) < 0)
|
my_printf_error(ENOEXEC, "pam: cannot exec %s (errno: %M)",
|
||||||
|
ME_ERROR_LOG_ONLY, toolpath, errno);
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* no user name yet ? read the client handshake packet with the user name */
|
/* no user name yet ? read the client handshake packet with the user name */
|
||||||
if (info->user_name == 0)
|
if (info->user_name == 0)
|
||||||
|
|
Loading…
Reference in a new issue