auth-master-connection.c revision 137ea7ca34005345aa2304a940149b7f3774d727
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (C) 2002 Timo Sirainen */
1d048c5050f03c24251e5af8087e640de21b2d62Timo Sirainen unsigned int id;
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid auth_master_request_callback(const char *reply, void *context)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct auth_master_connection *conn = context;
7384b4e78eaab44693c985192276e31322155e32Stephan Boschmaster_input_request(struct auth_master_connection *conn, const char *args)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const char *const *list;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* <id> <client-pid> <client-id> */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (list[0] == NULL || list[1] == NULL || list[2] == NULL) {
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch id = (unsigned int)strtoul(list[0], NULL, 10);
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch client_pid = (unsigned int)strtoul(list[1], NULL, 10);
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch client_id = (unsigned int)strtoul(list[2], NULL, 10);
7abab3b191860a3d77af5192b0649833c8a0c803Stephan Bosch client_conn = auth_client_connection_lookup(conn->listener, client_pid);
7a358ecd8918d1280a0b68cdf348c23f6721c799Stephan Bosch i_error("Master requested auth for nonexisting client %u",
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch client_conn->request_handler, conn, id, client_id);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct auth_master_connection *conn = auth_request->context;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch str_printfa(str, "NOTFOUND\t%u\n", auth_request->id);
6d573191bea1a64d6046be070487a5705a2d0204Stephan Bosch str_printfa(str, "USER\t%u\t", auth_request->id);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch str_append(str, auth_stream_reply_export(reply));
5b6bfa39481f719c1fd6ed3febeaf7f0be9e8886Timo Sirainen (void)o_stream_send(conn->output, str_data(str), str_len(str));
7384b4e78eaab44693c985192276e31322155e32Stephan Boschmaster_input_user(struct auth_master_connection *conn, const char *args)
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch /* <id> <userid> [<parameters>] */
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch auth_request = auth_request_new_dummy(conn->listener->auth);
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch auth_request->id = (unsigned int)strtoul(list[0], NULL, 10);
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch auth_request->user = p_strdup(auth_request->pool, list[1]);
30f35cf5d1e1374d7fab4231e86144fc106a8e79Stephan Bosch (void)auth_request_import(auth_request, name, arg);
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch i_error("BUG: Master sent USER request without service");
e46130f48a6962734bfde7e71906d3894bedf45bStephan Bosch auth_request_lookup_user(auth_request, user_callback);
e46130f48a6962734bfde7e71906d3894bedf45bStephan Boschmaster_input_die(struct auth_master_connection *conn)
e46130f48a6962734bfde7e71906d3894bedf45bStephan Bosch struct auth_master_connection *conn = context;
e46130f48a6962734bfde7e71906d3894bedf45bStephan Bosch /* disconnected */
e46130f48a6962734bfde7e71906d3894bedf45bStephan Bosch /* buffer full */
e46130f48a6962734bfde7e71906d3894bedf45bStephan Bosch i_error("BUG: Master sent us more than %d bytes",
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch /* make sure the major version matches */
a62fe4b300e2f591e939993aec4cac1e7ae30ad1Stephan Bosch i_error("Master not compatible with this server "
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch "(mixed old and new binaries?)");
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch while ((line = i_stream_next_line(conn->input)) != NULL) {
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch /* ignore unknown command */
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch struct auth_master_connection *conn = context;
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch if ((ret = o_stream_flush(conn->output)) < 0) {
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch /* transmit error, probably master died */
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch if (o_stream_get_buffer_used_size(conn->output) <= MAX_OUTBUF_SIZE/2) {
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch /* allow input again */
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch conn->io = io_add(conn->fd, IO_READ, master_input, conn);
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Boschauth_master_connection_create(struct auth_master_listener *listener, int fd)
e9228a3918aa0243eff4aae1ff5462bd3198417fTimo Sirainen conn = i_new(struct auth_master_connection, 1);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch conn->input = i_stream_create_file(fd, default_pool,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch conn->output = o_stream_create_file(fd, default_pool,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch o_stream_set_flush_callback(conn->output, master_output, conn);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch conn->io = io_add(fd, IO_READ, master_input, conn);
d1f964d3f1dd9c5868b134c4f44dd63f3722eef7Timo Sirainenvoid auth_master_connection_send_handshake(struct auth_master_connection *conn)
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch line = t_strdup_printf("VERSION\t%u\t%u\nSPID\t%u\n",
fe681e6db72f30bd754b622005bbe298e5ca775aTimo Sirainenvoid auth_master_connection_destroy(struct auth_master_connection *conn)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int i, count;
79f8a20424633e806447bc9375a5ab403aabc758Stephan Bosch conns = array_get(&conn->listener->masters, &count);
79f8a20424633e806447bc9375a5ab403aabc758Stephan Bosch for (i = 0; i < count; i++) {