auth-master-connection.c revision 645397402d1d0c755cd485ecf721b59b6babc874
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen unsigned int id;
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainenstatic array_t ARRAY_DEFINE(master_connections,
70905e51a5148bd5613cb04720807177474a2496Timo Sirainenstatic void auth_listener_destroy(struct auth_listener *l);
657afb33796f8216c568ad813627da89970760beTimo Sirainenvoid auth_master_request_callback(const char *reply, void *context)
657afb33796f8216c568ad813627da89970760beTimo Sirainen struct auth_master_connection *conn = context;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenmaster_input_request(struct auth_master_connection *conn, const char *args)
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen const char *const *list;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen /* <id> <client-pid> <client-id> */
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen if (list[0] == NULL || list[1] == NULL || list[2] == NULL) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen id = (unsigned int)strtoul(list[0], NULL, 10);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen client_pid = (unsigned int)strtoul(list[1], NULL, 10);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen client_id = (unsigned int)strtoul(list[2], NULL, 10);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen client_conn = auth_client_connection_lookup(conn, client_pid);
657afb33796f8216c568ad813627da89970760beTimo Sirainen i_error("Master requested auth for nonexisting client %u",
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainenuser_callback(const char *result, struct auth_request *auth_request)
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen struct auth_master_connection *conn = auth_request->context;
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen str_printfa(str, "NOTFOUND\t%u\n", auth_request->id);
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen str_printfa(str, "USER\t%u\t", auth_request->id);
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen (void)o_stream_send(conn->output, str_data(str), str_len(str));
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainenmaster_input_user(struct auth_master_connection *conn, const char *args)
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen const char *const *list;
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen /* <id> <userid> */
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen auth_request = auth_request_new_dummy(conn->auth);
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen auth_request->id = (unsigned int)strtoul(list[0], NULL, 10);
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen auth_request->user = p_strdup(auth_request->pool, list[1]);
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen auth_request_lookup_user(auth_request, user_callback);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenmaster_input_die(struct auth_master_connection *conn)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen struct auth_master_connection *conn = context;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen /* disconnected */
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen /* buffer full */
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen i_error("BUG: Master sent us more than %d bytes",
b0df0e9a8ed8889ad4bf032043ab245ce8851fdeTimo Sirainen /* make sure the major version matches */
b0df0e9a8ed8889ad4bf032043ab245ce8851fdeTimo Sirainen i_error("Master not compatible with this server "
b0df0e9a8ed8889ad4bf032043ab245ce8851fdeTimo Sirainen "(mixed old and new binaries?)");
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen while ((line = i_stream_next_line(conn->input)) != NULL) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen /* ignore unknown command */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen struct auth_master_connection *conn = context;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if ((ret = o_stream_flush(conn->output)) < 0) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* transmit error, probably master died */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (o_stream_get_buffer_used_size(conn->output) <= MAX_OUTBUF_SIZE/2) {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* allow input again */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen conn->io = io_add(conn->fd, IO_READ, master_input, conn);
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainenauth_master_connection_set_fd(struct auth_master_connection *conn, int fd)
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen conn->input = i_stream_create_file(fd, default_pool,
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainen conn->output = o_stream_create_file(fd, default_pool,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen o_stream_set_flush_callback(conn->output, master_output, conn);
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainen conn->io = io_add(fd, IO_READ, master_input, conn);
657afb33796f8216c568ad813627da89970760beTimo Sirainenauth_master_connection_create(struct auth *auth, int fd)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen conn = i_new(struct auth_master_connection, 1);
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen conn->listeners_buf = buffer_create_dynamic(default_pool, 64);
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainenvoid auth_master_connection_send_handshake(struct auth_master_connection *conn)
657afb33796f8216c568ad813627da89970760beTimo Sirainen line = t_strdup_printf("VERSION\t%u\t%u\nSPID\t%u\n",
657afb33796f8216c568ad813627da89970760beTimo Sirainen AUTH_MASTER_PROTOCOL_MINOR_VERSION, conn->pid);
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainenvoid auth_master_connection_destroy(struct auth_master_connection *conn)
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen unsigned int i, count;
70905e51a5148bd5613cb04720807177474a2496Timo Sirainen l = buffer_get_modifyable_data(conn->listeners_buf, NULL);
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen conns = array_get(&master_connections, &count);
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen for (i = 0; i < count; i++) {
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen if (!standalone && array_count(&master_connections) == 0)
70905e51a5148bd5613cb04720807177474a2496Timo Sirainen i_fatal("accept(type %d) failed: %m", l->type);
70905e51a5148bd5613cb04720807177474a2496Timo Sirainen switch (l->type) {
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainen (void)auth_client_connection_create(l->master, fd);
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainen /* we'll just replace the previous master.. */
70905e51a5148bd5613cb04720807177474a2496Timo Sirainen auth_master_connection_send_handshake(l->master);
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainenvoid auth_master_connection_add_listener(struct auth_master_connection *conn,
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainen buffer_append(conn->listeners_buf, &l, sizeof(l));
70905e51a5148bd5613cb04720807177474a2496Timo Sirainenstatic void auth_listener_destroy(struct auth_listener *l)
70905e51a5148bd5613cb04720807177474a2496Timo Sirainen lp = buffer_get_modifyable_data(l->master->listeners_buf, &size);
70905e51a5148bd5613cb04720807177474a2496Timo Sirainen for (i = 0; i < size; i++) {
70905e51a5148bd5613cb04720807177474a2496Timo Sirainen if (lp[i] == l) {
70905e51a5148bd5613cb04720807177474a2496Timo Sirainen i * sizeof(l), sizeof(l));
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainenvoid auth_master_connections_send_handshake(void)
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen unsigned int i, count;
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen conns = array_get(&master_connections, &count);
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen for (i = 0; i < count; i++)
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen auth_master_connection_send_handshake(conns[i]);
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen ARRAY_CREATE(&master_connections, default_pool,
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen unsigned int i, count;
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen conns = array_get(&master_connections, &count);
645397402d1d0c755cd485ecf721b59b6babc874Timo Sirainen for (i = count; i > 0; i--)