auth-master-connection.c revision 8eea67470c1bd8562a62e7445d930bb2079b1a43
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;
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainenstatic void auth_master_connection_close(struct auth_master_connection *conn);
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 *)
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainenstatic void master_get_handshake_reply(struct auth_master_connection *master)
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen struct auth_client_handshake_mech_desc mech_desc;
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen buf = buffer_create_dynamic(default_pool, 128, (size_t)-1);
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen for (list = mech_modules; list != NULL; list = list->next)
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen for (list = mech_modules; list != NULL; list = list->next) {
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen mech_desc.name_idx = buffer_get_used_size(buf) - sizeof(reply);
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen memcpy(buffer_get_space_unsafe(buf, mech_desc_offset,
8eea67470c1bd8562a62e7445d930bb2079b1a43Timo Sirainen reply.data_size = buffer_get_used_size(buf) - sizeof(reply);
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen memcpy(buffer_get_space_unsafe(buf, 0, sizeof(reply)),
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen master->handshake_reply = buffer_free_without_data(buf);
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainenauth_master_connection_set_fd(struct auth_master_connection *conn, int fd)
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainen conn->output = o_stream_create_file(fd, default_pool,
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainen conn->io = io_add(fd, IO_READ, master_input, conn);
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainenauth_master_connection_create(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 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. */
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainen o_stream_send(conn->output, &reply, sizeof(reply));
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainenstatic void auth_master_connection_close(struct auth_master_connection *conn)
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainenvoid auth_master_connection_destroy(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)
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainen (void)auth_client_connection_create(l->master, fd);
6b46a500174ace25494b8f0547283eb60dc13756Timo Sirainen /* we'll just replace the previous master.. */
6b46a500174ace25494b8f0547283eb60dc13756Timo 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));