auth-process.c revision b67cf4235f18327c2ee5c5142310e87a2b7b42d3
/* Copyright (C) 2002 Timo Sirainen */
#include "common.h"
#include "ioloop.h"
#include "env-util.h"
#include "fd-close-on-exec.h"
#include "network.h"
#include "ostream.h"
#include "restrict-access.h"
#include "restrict-process-size.h"
#include "auth-process.h"
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <syslog.h>
struct auth_process {
struct auth_process *next;
char *name;
int fd;
unsigned int reply_pos;
char reply_buf[sizeof(struct auth_cookie_reply_data)];
unsigned int initialized:1;
};
struct waiting_request {
struct waiting_request *next;
unsigned int id;
void *context;
};
static struct auth_process *processes;
static void auth_process_destroy(struct auth_process *p);
{
struct waiting_request *req;
}
struct auth_cookie_reply_data *reply)
{
struct waiting_request *req;
i_warning("imap-auth %s sent us unrequested reply for id %d",
return;
}
i_fatal("imap-auth %s sent invalid id for reply "
"(got %d, expecting %d)",
}
/* auth process isn't trusted, validate all data to make sure
it's not trying to exploit us */
i_error("auth: Received corrupted data");
return;
}
}
{
struct auth_process *p = context;
int ret;
if (ret < 0) {
/* disconnected */
return;
}
if (!p->initialized) {
if (p->reply_buf[0] != 'O') {
i_fatal("Auth process sent invalid initialization "
"notification");
}
p->initialized = TRUE;
ret--;
}
return;
/* reply is now read */
p->reply_pos = 0;
}
static struct auth_process *
{
struct auth_process *p;
sizeof(struct auth_cookie_request_data)*100,
p->next_request = &p->requests;
processes = p;
return p;
}
static void auth_process_destroy(struct auth_process *p)
{
struct auth_process **pos;
struct waiting_request *next;
if (!p->initialized) {
i_error("Auth process died too early - shutting down");
}
if (*pos == p) {
break;
}
}
}
o_stream_unref(p->output);
i_error("close(auth) failed: %m");
i_free(p);
}
{
const char *path;
/* 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;
}
/* create socket for listening auth requests from imap-login */
if (listen_fd < 0)
/* set correct permissions */
i_fatal("login: chown(%s, %s, %s) failed: %m",
}
/* move master communication handle to 0 */
i_fatal("login: dup2(0) failed: %m");
i_fatal("login: dup2(1) failed: %m");
i_fatal("login: dup2(2) failed: %m");
/* move login communication handle to 3. do it last so we can be
sure it's not closed afterwards. */
if (listen_fd != 3) {
i_fatal("login: dup2() failed: %m");
}
for (i = 0; i <= 2; i++)
fd_close_on_exec(i, FALSE);
/* setup access environment - needs to be done after
clean_child_process() since it clears environment */
/* set other environment */
if (config->use_cyrus_sasl)
env_put("USE_CYRUS_SASL=1");
env_put("VERBOSE=1");
/* make sure we don't leak syslog fd, but do it last so that
any errors above will be logged */
closelog();
/* hide the path, it's ugly */
return -1;
}
{
struct auth_process *p;
return p;
}
return NULL;
}
void auth_process_request(unsigned int login_pid,
unsigned char cookie[AUTH_COOKIE_SIZE],
{
struct auth_cookie_request_data req;
}
static unsigned int auth_process_get_count(const char *name)
{
struct auth_process *p;
unsigned int count = 0;
count++;
}
return count;
}
void auth_processes_destroy_all(void)
{
struct auth_process *next;
}
}
static void
{
struct auth_config *config;
unsigned int count;
(void)create_auth_process(config);
}
}
void auth_processes_init(void)
{
}
void auth_processes_deinit(void)
{
}