auth-master-connection.c revision 76213404317a7ed17bec0beadb5137c82785d816
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenstatic struct auth_master_reply failure_reply =
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen unsigned int tag;
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenstatic int auth_master_connection_unref(struct auth_master_connection *conn);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenstatic size_t reply_add(buffer_t *buf, const char *str)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen index = buffer_get_used_size(buf) - sizeof(struct auth_master_reply);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenfill_reply(const struct user_data *user, size_t *reply_size)
cd466fe7b84b0223735a6469c7f7bc225f65996dTimo Sirainen buf = buffer_create_dynamic(pool_datastack_create(),
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen reply.system_user_idx = reply_add(buf, user->system_user);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen reply.virtual_user_idx = reply_add(buf, user->virtual_user);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen p = user->home != NULL ? strstr(user->home, "/./") : NULL;
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* wu-ftpd like <chroot>/./<home> */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen reply_add(buf, t_strdup_until(user->home, p));
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen reply.data_size = *reply_size - sizeof(reply);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen reply_p = buffer_get_space_unsafe(buf, 0, sizeof(reply));
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenstatic void master_send_reply(struct auth_master_connection *conn,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen ret = o_stream_send(conn->output, reply, reply_size);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* master died, kill ourself too */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* buffer full, we have to block */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen i_warning("Master transmit buffer full, blocking..");
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* transmit error, probably master died */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenstatic void userdb_callback(struct user_data *user, void *context)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen struct master_userdb_request *master_request = context;
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen if (auth_master_connection_unref(master_request->conn)) {
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen master_send_reply(master_request->conn, &failure_reply,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen master_send_reply(master_request->conn, reply,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenstatic void master_handle_request(struct auth_master_connection *conn,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen client_conn = auth_client_connection_lookup(conn, request->client_pid);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen master_send_reply(conn, &failure_reply, sizeof(failure_reply),
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen master_request = i_new(struct master_userdb_request, 1);
7a87427770874f38d1d299635b37d699f9772860Timo Sirainen /* the auth request is finished, we don't need it anymore */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen struct auth_master_connection *conn = context;
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen sizeof(conn->request_buf) - conn->request_pos);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* master died, kill ourself too */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen if (conn->request_pos >= sizeof(conn->request_buf)) {
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* reply is now read */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen master_handle_request(conn, (struct auth_master_request *)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenauth_master_connection_new(int fd, unsigned int pid)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen conn = i_new(struct auth_master_connection, 1);
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainen buffer_create_dynamic(default_pool, 64, (size_t)-1);
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainen conn->output = o_stream_create_file(fd, default_pool,
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainen conn->io = io_add(fd, IO_READ, master_input, conn);
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainenvoid auth_master_connection_send_handshake(struct auth_master_connection *conn)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* just a note to master that we're ok. if we die before,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen master should shutdown itself. */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenvoid auth_master_connection_free(struct auth_master_connection *conn)
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainen l = buffer_get_modifyable_data(conn->listeners_buf, &size);
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainen size /= sizeof(*l);
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainen for (i = 0; i < size; i++) {
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenstatic int auth_master_connection_unref(struct auth_master_connection *conn)
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainen (void)auth_client_connection_create(l->master, fd);
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainenvoid auth_master_connection_add_listener(struct auth_master_connection *conn,
76213404317a7ed17bec0beadb5137c82785d816Timo Sirainen buffer_append(conn->listeners_buf, &l, sizeof(l));