auth-process.c revision 7013075e208bc7aa87257df7d9664c84c7c220f3
/* 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 "istream.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>
#define MAX_INBUF_SIZE \
(sizeof(struct auth_master_reply) + AUTH_MASTER_MAX_REPLY_DATA_SIZE)
struct auth_process {
struct auth_process *next;
char *name;
int fd;
struct auth_master_reply auth_reply;
struct hash_table *requests;
unsigned int initialized:1;
unsigned int in_auth_reply:1;
};
static struct auth_process *processes;
static unsigned int auth_tag;
static void auth_process_destroy(struct auth_process *p);
struct auth_master_reply *reply,
const unsigned char *data)
{
void *context;
i_error("Auth process %s sent unrequested reply with tag %u",
return TRUE;
}
/* make sure the reply looks OK */
nul_pos = 0;
data = (const unsigned char *) "";
} else {
}
i_error("Auth process %s sent invalid reply",
return FALSE;
}
/* fix the request so that all the values point to \0 terminated
strings */
return TRUE;
}
{
struct auth_master_request req;
if (ret >= 0) {
/* FIXME: well .. I'm not sure if it'd be better to
just block here. I don't think this condition should
happen often, so this could mean that the auth
process is stuck. Or that the computer is just
too heavily loaded. Possibility to block infinitely
is annoying though, so for now don't do it. */
i_warning("Auth process %s transmit buffer full, "
}
return;
}
}
static void auth_process_input(void *context)
{
struct auth_process *p = context;
const unsigned char *data;
switch (i_stream_read(p->input)) {
case 0:
return;
case -1:
/* disconnected */
return;
case -2:
/* buffer full */
i_error("BUG: Auth process %s sent us more than %d "
return;
}
if (!p->initialized) {
if (data[0] != 'O') {
i_fatal("Auth process sent invalid initialization "
"notification");
}
p->initialized = TRUE;
}
if (!p->in_auth_reply) {
if (size < sizeof(struct auth_master_reply))
return;
p->in_auth_reply = TRUE;
}
return;
/* reply is now read */
else {
p->in_auth_reply = FALSE;
}
}
static struct auth_process *
{
struct auth_process *p;
sizeof(struct auth_master_request)*100,
processes = p;
return p;
}
{
}
static void auth_process_destroy(struct auth_process *p)
{
struct auth_process **pos;
i_error("Auth process died too early - shutting down");
}
if (*pos == p) {
break;
}
}
hash_destroy(p->requests);
i_stream_unref(p->input);
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;
}
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)
{
}