auth-master.c revision 4b1359bde7d32667197548652a4b4f540062e2ac
/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "lib-signals.h"
#include "array.h"
#include "ioloop.h"
#include "network.h"
#include "istream.h"
#include "ostream.h"
#include "auth-master.h"
#include <stdlib.h>
#include <unistd.h>
#define AUTH_PROTOCOL_MAJOR 1
#define AUTH_PROTOCOL_MINOR 0
#define AUTH_REQUEST_TIMEOUT_SECS 30
#define AUTH_MASTER_IDLE_SECS 60
#define MAX_INBUF_SIZE 8192
#define MAX_OUTBUF_SIZE 1024
#define DEFAULT_USERDB_LOOKUP_PREFIX "userdb lookup"
struct auth_master_connection {
char *auth_socket_path;
int fd;
const char *prefix;
unsigned int request_counter;
void *context);
void *reply_context;
unsigned int debug:1;
unsigned int sent_handshake:1;
unsigned int handshaked:1;
unsigned int aborted:1;
};
struct auth_master_user_lookup_ctx {
struct auth_master_connection *conn;
const char *user;
struct auth_user_reply *user_reply;
int return_value;
};
struct auth_master_user_list_ctx {
struct auth_master_connection *conn;
const char *const *user_strings;
unsigned int idx, user_count;
bool failed;
};
struct auth_master_connection *
{
struct auth_master_connection *conn;
return conn;
}
{
}
}
{
}
{
}
const char *const *args)
{
else {
}
}
}
{
i_error("userdb lookup: "
"Auth protocol version mismatch "
return -1;
}
break;
}
}
return 0;
}
void *context)
{
return TRUE;
}
ctx->return_value = 0;
return TRUE;
}
return TRUE;
}
return FALSE;
}
{
case 0:
return;
case -1:
/* disconnected */
i_error("%s: Disconnected unexpectedly",
return;
case -2:
/* buffer full */
i_error("%s: BUG: Received more than %d bytes",
return;
}
if (!conn->handshaked) {
if (auth_input_handshake(conn) < 0)
return;
}
return;
id = "";
else {
args++;
}
return;
}
i_error("%s: %s is an auth client socket. "
"It should be a master socket.",
} else {
}
}
{
/* max. 1 second wait here. */
break;
/* busy. wait for a while. */
}
if (fd == -1) {
i_error("userdb lookup: connect(%s) failed: %m",
return -1;
}
return 0;
}
{
if (!conn->handshaked)
else
}
{
}
{
}
struct ioloop *prev_ioloop)
{
}
static bool is_valid_string(const char *str)
{
const char *p;
/* make sure we're not sending any characters that have a special
meaning. */
for (p = str; *p != '\0'; p++) {
if (*p == '\t' || *p == '\n' || *p == '\r')
return FALSE;
}
return TRUE;
}
const char *cmd)
{
struct ioloop *prev_ioloop;
const char *str;
if (auth_master_connect(conn) < 0)
return -1;
}
if (!conn->sent_handshake) {
}
i_error("write(auth socket) failed: %m");
} else {
}
return -1;
}
return 0;
}
{
struct auth_master_user_lookup_ctx ctx;
const char *str;
/* non-allowed characters, the user can't exist */
return 0;
}
if (++conn->request_counter == 0) {
/* avoid zero */
conn->request_counter++;
}
return ctx.return_value;
}
static bool
void *context)
{
const char *user;
i_error("User listing returned failure");
}
return TRUE;
}
/* we'll just read all the users into memory. otherwise we'd
have to use a separate connection for listing and there's
a higher chance of a failure since the connection could be
open to dovecot-auth for a long time. */
return TRUE;
}
return FALSE;
}
struct auth_master_user_list_ctx *
{
struct auth_master_user_list_ctx *ctx;
const char *str;
if (++conn->request_counter == 0) {
/* avoid zero */
conn->request_counter++;
}
return ctx;
}
{
return NULL;
}
{
return ret;
}