[dovecot-cvs] dovecot/src/master auth-process.c, 1.57,
1.58 master-settings.c, 1.55, 1.56 master-settings.h, 1.35, 1.36
cras at procontrol.fi
cras at procontrol.fi
Wed Jun 23 20:50:46 EEST 2004
- Previous message: [dovecot-cvs] dovecot/src/auth auth-master-connection.c, 1.7,
1.8 auth-master-connection.h, 1.3, 1.4 auth-master-interface.h,
1.4, 1.5 common.h, 1.6, 1.7 main.c, 1.26, 1.27
- Next message: [dovecot-cvs] dovecot/src/pop3-login client-authenticate.c, 1.19,
1.20
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/dovecot/src/master
In directory talvi:/tmp/cvs-serv5259/src/master
Modified Files:
auth-process.c master-settings.c master-settings.h
Log Message:
Dovecot can now connect to externally running dovecot-auth.
Index: auth-process.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/auth-process.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- auth-process.c 23 Jun 2004 14:50:47 -0000 1.57
+++ auth-process.c 23 Jun 2004 17:50:44 -0000 1.58
@@ -45,6 +45,7 @@
struct hash_table *requests;
+ unsigned int external:1;
unsigned int initialized:1;
unsigned int in_auth_reply:1;
};
@@ -152,16 +153,21 @@
}
if (!p->initialized) {
+ struct auth_master_handshake_reply rec;
+
data = i_stream_get_data(p->input, &size);
- i_assert(size > 0);
+ if (size < sizeof(rec))
+ return;
- if (data[0] != 'O') {
+ memcpy(&rec, data, sizeof(rec));
+ i_stream_skip(p->input, sizeof(rec));
+
+ if (rec.server_pid == 0) {
i_fatal("Auth process sent invalid initialization "
"notification");
}
- i_stream_skip(p->input, 1);
-
+ p->pid = rec.server_pid;
p->initialized = TRUE;
}
@@ -197,7 +203,8 @@
{
struct auth_process *p;
- PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_AUTH);
+ if (pid != 0)
+ PID_ADD_PROCESS_TYPE(pid, PROCESS_TYPE_AUTH);
p = i_new(struct auth_process, 1);
p->group = group;
@@ -223,7 +230,7 @@
void *key, *value;
struct auth_process **pos;
- if (!p->initialized && io_loop_is_running(ioloop)) {
+ if (!p->initialized && io_loop_is_running(ioloop) && !p->external) {
i_error("Auth process died too early - shutting down");
io_loop_stop(ioloop);
}
@@ -250,14 +257,54 @@
i_free(p);
}
-static pid_t create_auth_process(struct auth_process_group *group)
+static void
+socket_settings_env_put(const char *env_base, struct socket_settings *set)
+{
+ if (env_base == NULL)
+ return;
+
+ env_put(t_strdup_printf("%s_PATH=%s", env_base, set->path));
+ if (set->mode != 0)
+ env_put(t_strdup_printf("%s_MODE=%u", env_base, set->mode));
+ if (set->user != NULL)
+ env_put(t_strdup_printf("%s_USER=%s", env_base, set->user));
+ if (set->group != NULL)
+ env_put(t_strdup_printf("%s_GROUP=%s", env_base, set->group));
+}
+
+static int connect_auth_socket(struct auth_process_group *group,
+ const char *path)
+{
+ struct auth_process *auth;
+ int fd;
+
+ fd = net_connect_unix(path);
+ if (fd == -1) {
+ i_error("net_connect_unix(%s) failed: %m", path);
+ return -1;
+ }
+
+ net_set_nonblock(fd, TRUE);
+ fd_close_on_exec(fd, TRUE);
+ auth = auth_process_new(0, fd, group);
+ auth->external = TRUE;
+ return 0;
+}
+
+static int create_auth_process(struct auth_process_group *group)
{
static char *argv[] = { NULL, NULL };
- const char *prefix;
+ struct auth_socket_settings *as;
+ const char *prefix, *str;
struct log_io *log;
pid_t pid;
int fd[2], log_fd, i;
+ /* see if this is a connect socket */
+ as = group->set->sockets;
+ if (as != NULL && strcmp(as->type, "connect") == 0)
+ return connect_auth_socket(group, as->master.path);
+
/* create communication to process with a socket pair */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) {
i_error("socketpair() failed: %m");
@@ -290,7 +337,7 @@
auth_process_new(pid, fd[0], group);
(void)close(fd[1]);
(void)close(log_fd);
- return pid;
+ return 0;
}
prefix = t_strdup_printf("master-auth(%s): ", group->set->name);
@@ -337,7 +384,16 @@
env_put(t_strconcat("USERNAME_CHARS=", group->set->username_chars, NULL));
env_put(t_strconcat("ANONYMOUS_USERNAME=",
group->set->anonymous_username, NULL));
- env_put(t_strconcat("AUTH_SOCKETS=", group->set->extra_sockets));
+
+ for (as = group->set->sockets, i = 1; as != NULL; as = as->next, i++) {
+ if (strcmp(as->type, "listen") != 0)
+ continue;
+
+ str = t_strdup_printf("AUTH_%u", i);
+ socket_settings_env_put(str, &as->client);
+ socket_settings_env_put(t_strconcat(str, "_MASTER", NULL),
+ &as->master);
+ }
if (group->set->use_cyrus_sasl)
env_put("USE_CYRUS_SASL=1");
@@ -390,6 +446,13 @@
group = i_new(struct auth_process_group, 1);
group->set = auth_set;
+ group->next = process_groups;
+ process_groups = group;
+
+ if (auth_set->sockets != NULL &&
+ strcmp(auth_set->sockets->type, "connect") == 0)
+ return;
+
/* create socket for listening auth requests from login */
path = t_strconcat(auth_set->parent->defaults->login_dir, "/",
auth_set->name, NULL);
@@ -410,9 +473,6 @@
path, dec2str(master_uid),
dec2str(auth_set->parent->login_gid));
}
-
- group->next = process_groups;
- process_groups = group;
}
static void auth_process_group_destroy(struct auth_process_group *group)
Index: master-settings.c
===================================================================
RCS file: /home/cvs/dovecot/src/master/master-settings.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- master-settings.c 16 Jun 2004 02:04:02 -0000 1.55
+++ master-settings.c 23 Jun 2004 17:50:44 -0000 1.56
@@ -16,7 +16,9 @@
SETTINGS_TYPE_ROOT,
SETTINGS_TYPE_SERVER,
SETTINGS_TYPE_AUTH,
- SETTINGS_TYPE_NAMESPACE
+ SETTINGS_TYPE_AUTH_SOCKET,
+ SETTINGS_TYPE_NAMESPACE,
+ SETTINGS_TYPE_SOCKET
};
struct settings_parse_ctx {
@@ -25,6 +27,8 @@
struct server_settings *root, *server;
struct auth_settings *auth;
+ struct socket_settings *socket;
+ struct auth_socket_settings *auth_socket;
struct namespace_settings *namespace;
int level;
@@ -142,7 +146,29 @@
DEF(SET_INT, count),
DEF(SET_INT, process_size),
- DEF(SET_STR, extra_sockets),
+
+ { 0, NULL, 0 }
+};
+
+#undef DEF
+#define DEF(type, name) \
+ { type, #name, offsetof(struct socket_settings, name) }
+
+static struct setting_def socket_setting_defs[] = {
+ DEF(SET_STR, path),
+ DEF(SET_INT, mode),
+ DEF(SET_STR, user),
+ DEF(SET_STR, group),
+
+ { 0, NULL, 0 }
+};
+
+#undef DEF
+#define DEF(type, name) \
+ { type, #name, offsetof(struct auth_socket_settings, name) }
+
+static struct setting_def auth_socket_setting_defs[] = {
+ DEF(SET_STR, type),
{ 0, NULL, 0 }
};
@@ -281,11 +307,11 @@
MEMBER(count) 1,
MEMBER(process_size) 256,
- MEMBER(extra_sockets) NULL,
/* .. */
MEMBER(uid) 0,
- MEMBER(gid) 0
+ MEMBER(gid) 0,
+ MEMBER(sockets) NULL
};
static pool_t settings_pool, settings2_pool;
@@ -406,6 +432,22 @@
return TRUE;
}
+static int settings_have_connect_sockets(struct settings *set)
+{
+ struct auth_settings *auth;
+ struct server_settings *server;
+
+ for (server = set->server; server != NULL; server = server->next) {
+ for (auth = server->auths; auth != NULL; auth = auth->next) {
+ if (auth->sockets != NULL &&
+ strcmp(auth->sockets->type, "connect") == 0)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
static int settings_verify(struct settings *set)
{
const char *dir;
@@ -484,10 +526,15 @@
PKG_RUNDIR);
}
- /* wipe out contents of login directory, if it exists */
- if (unlink_directory(set->login_dir, FALSE) < 0) {
- i_error("unlink_directory() failed for %s: %m", set->login_dir);
- return FALSE;
+ /* wipe out contents of login directory, if it exists.
+ except if we're using external authentication - then we would
+ otherwise wipe existing auth sockets */
+ if (!settings_have_connect_sockets(set)) {
+ if (unlink_directory(set->login_dir, FALSE) < 0) {
+ i_error("unlink_directory() failed for %s: %m",
+ set->login_dir);
+ return FALSE;
+ }
}
if (safe_mkdir(set->login_dir, 0750,
@@ -570,6 +617,44 @@
return auth_settings_new(server, name);
}
+static struct auth_socket_settings *
+auth_socket_settings_new(struct auth_settings *auth, const char *type)
+{
+ struct auth_socket_settings *as, **as_p;
+
+ as = p_new(settings_pool, struct auth_socket_settings, 1);
+
+ as->parent = auth;
+ as->type = str_lcase(p_strdup(settings_pool, type));
+
+ as_p = &auth->sockets;
+ while (*as_p != NULL)
+ as_p = &(*as_p)->next;
+ *as_p = as;
+
+ return as;
+}
+
+static struct auth_socket_settings *
+parse_new_auth_socket(struct auth_settings *auth, const char *name,
+ const char **errormsg)
+{
+ if (strcmp(name, "connect") != 0 && strcmp(name, "listen") != 0) {
+ *errormsg = "Unknown auth socket type";
+ return NULL;
+ }
+
+ if ((auth->sockets != NULL && strcmp(name, "connect") == 0) ||
+ (auth->sockets != NULL &&
+ strcmp(auth->sockets->type, "listen") == 0)) {
+ *errormsg = "With connect auth socket no other sockets "
+ "can be used in same auth section";
+ return NULL;
+ }
+
+ return auth_socket_settings_new(auth, name);
+}
+
static struct namespace_settings *
namespace_settings_new(struct server_settings *server, const char *type)
{
@@ -657,10 +742,18 @@
key += 5;
return parse_setting_from_defs(settings_pool, auth_setting_defs,
ctx->auth, key, value);
+ case SETTINGS_TYPE_AUTH_SOCKET:
+ return parse_setting_from_defs(settings_pool,
+ auth_socket_setting_defs,
+ ctx->auth_socket, key, value);
case SETTINGS_TYPE_NAMESPACE:
return parse_setting_from_defs(settings_pool,
namespace_setting_defs,
ctx->namespace, key, value);
+ case SETTINGS_TYPE_SOCKET:
+ return parse_setting_from_defs(settings_pool,
+ socket_setting_defs,
+ ctx->socket, key, value);
}
i_unreached();
@@ -705,12 +798,20 @@
if (type == NULL) {
/* section closing */
- if (ctx->level > 0) {
- ctx->level--;
+ if (--ctx->level > 0) {
+ ctx->type = ctx->parent_type;
ctx->protocol = MAIL_PROTOCOL_ANY;
+
+ switch (ctx->type) {
+ case SETTINGS_TYPE_AUTH_SOCKET:
+ ctx->parent_type = SETTINGS_TYPE_AUTH;
+ break;
+ default:
+ ctx->parent_type = SETTINGS_TYPE_ROOT;
+ break;
+ }
} else {
- ctx->type = ctx->parent_type;
- ctx->parent_type = SETTINGS_TYPE_ROOT;
+ ctx->type = SETTINGS_TYPE_ROOT;
ctx->server = ctx->root;
ctx->auth = &ctx->root->auth_defaults;
ctx->namespace = NULL;
@@ -718,15 +819,16 @@
return TRUE;
}
+ ctx->level++;
+ ctx->parent_type = ctx->type;
+
if (strcmp(type, "server") == 0) {
if (ctx->type != SETTINGS_TYPE_ROOT) {
*errormsg = "Server section not allowed here";
return FALSE;
}
- ctx->parent_type = ctx->type;
ctx->type = SETTINGS_TYPE_SERVER;
-
ctx->server = create_new_server(name, ctx->server->imap,
ctx->server->pop3);
server = ctx->root;
@@ -739,7 +841,7 @@
if (strcmp(type, "protocol") == 0) {
if ((ctx->type != SETTINGS_TYPE_ROOT &&
ctx->type != SETTINGS_TYPE_SERVER) ||
- ctx->level != 0) {
+ ctx->level != 1) {
*errormsg = "Protocol section not allowed here";
return FALSE;
}
@@ -752,7 +854,6 @@
*errormsg = "Unknown protocol name";
return FALSE;
}
- ctx->level++;
return TRUE;
}
@@ -768,6 +869,28 @@
return ctx->auth != NULL;
}
+ if (ctx->type == SETTINGS_TYPE_AUTH &&
+ strcmp(type, "socket") == 0) {
+ ctx->type = SETTINGS_TYPE_AUTH_SOCKET;
+ ctx->auth_socket = parse_new_auth_socket(ctx->auth,
+ name, errormsg);
+ return ctx->auth_socket != NULL;
+ }
+
+ if (ctx->type == SETTINGS_TYPE_AUTH_SOCKET) {
+ ctx->type = SETTINGS_TYPE_SOCKET;
+
+ if (strcmp(type, "master") == 0) {
+ ctx->socket = &ctx->auth_socket->master;
+ return TRUE;
+ }
+
+ if (strcmp(type, "client") == 0) {
+ ctx->socket = &ctx->auth_socket->client;
+ return TRUE;
+ }
+ }
+
if (strcmp(type, "namespace") == 0) {
if (ctx->type != SETTINGS_TYPE_ROOT &&
ctx->type != SETTINGS_TYPE_SERVER) {
Index: master-settings.h
===================================================================
RCS file: /home/cvs/dovecot/src/master/master-settings.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- master-settings.h 16 Jun 2004 02:04:02 -0000 1.35
+++ master-settings.h 23 Jun 2004 17:50:44 -0000 1.36
@@ -98,6 +98,22 @@
int listen_fd, ssl_listen_fd;
};
+struct socket_settings {
+ const char *path;
+ unsigned int mode;
+ const char *user;
+ const char *group;
+};
+
+struct auth_socket_settings {
+ struct auth_settings *parent;
+ struct auth_socket_settings *next;
+
+ const char *type;
+ struct socket_settings master;
+ struct socket_settings client;
+};
+
struct auth_settings {
struct server_settings *parent;
struct auth_settings *next;
@@ -119,11 +135,11 @@
unsigned int count;
unsigned int process_size;
- const char *extra_sockets;
/* .. */
uid_t uid;
gid_t gid;
+ struct auth_socket_settings *sockets;
};
struct namespace_settings {
- Previous message: [dovecot-cvs] dovecot/src/auth auth-master-connection.c, 1.7,
1.8 auth-master-connection.h, 1.3, 1.4 auth-master-interface.h,
1.4, 1.5 common.h, 1.6, 1.7 main.c, 1.26, 1.27
- Next message: [dovecot-cvs] dovecot/src/pop3-login client-authenticate.c, 1.19,
1.20
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list