login-process.c revision 66251e6ab31e5cc153fe5cae608e416dacafe9cd
/* Copyright (C) 2002 Timo Sirainen */
#include "common.h"
#include "network.h"
#include "iobuffer.h"
#include "fdpass.h"
#include "restrict-access.h"
#include "login-process.h"
#include "auth-process.h"
#include "master-interface.h"
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
typedef struct {
int refcount;
int fd;
unsigned int destroyed:1;
} LoginProcess;
typedef struct {
int login_id;
int auth_id;
int fd;
char login_tag[LOGIN_TAG_SIZE];
static int auth_id_counter;
static void login_process_destroy(LoginProcess *p);
static void login_process_unref(LoginProcess *p);
{
const char *env[] = {
"MAIL", NULL,
"LOGIN_TAG", NULL,
};
else {
}
/* reply to login */
}
{
LoginProcess *p = user_data;
if (ret == 0) {
/* disconnected, ie. the login process died */
} else if (ret > 0) {
/* req wasn't fully read */
i_error("login: fd_read() couldn't read all req");
} else {
i_error("login: fd_read() failed: %m");
}
return;
}
/* login process isn't trusted, validate all data to make sure
it's not trying to exploit us */
i_error("login: Received corrupted data");
return;
}
/* ask the cookie from the auth process */
p->refcount++;
if (auth_process == NULL) {
i_error("login: Authentication process %u doesn't exist",
} else {
}
}
{
LoginProcess *p;
p->refcount = 1;
sizeof(MasterReply)*10);
return p;
}
static void login_process_destroy(LoginProcess *p)
{
if (p->destroyed)
return;
io_buffer_close(p->outbuf);
}
static void login_process_unref(LoginProcess *p)
{
if (--p->refcount > 0)
return;
io_buffer_destroy(p->outbuf);
i_free(p);
}
static pid_t create_login_process(void)
{
int fd[2];
if (set_login_uid == 0)
i_fatal("Login process must not run as root");
/* create communication to process with a socket pair */
i_error("socketpair() failed: %m");
return -1;
}
if (pid < 0) {
i_error("fork() failed: %m");
return -1;
}
if (pid != 0) {
/* master */
return pid;
}
/* move communication handle */
i_fatal("login: dup2() failed: %m");
/* move the listen handle */
i_fatal("login: dup2() failed: %m");
/* move the SSL listen handle */
i_fatal("login: dup2() failed: %m");
/* imap_fd and imaps_fd are closed by clean_child_process() */
/* setup access environment - needs to be done after
clean_child_process() since it clears environment */
if (!set_login_chroot) {
/* no chrooting, but still change to the directory */
if (chdir(set_login_dir) < 0) {
i_fatal("chdir(%s) failed: %m",
}
}
if (set_ssl_cert_file != NULL) {
}
if (set_ssl_key_file != NULL) {
set_ssl_key_file, NULL));
}
putenv("DISABLE_PLAINTEXT_AUTH=1");
/* hide the path, it's ugly */
return -1;
}
void *user_data __attr_unused__)
{
LoginProcess *p = value;
}
void login_processes_cleanup(void)
{
}
{
/* create max. one process every second, that way if it keeps
dying all the time we don't eat all cpu with fork()ing. */
(void)create_login_process();
}
void login_processes_init(void)
{
auth_id_counter = 0;
}
void *user_data __attr_unused__)
{
}
void login_processes_deinit(void)
{
}