auth-worker-client.c revision b624773984e35dd894db8dff976c1a2114c70782
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2005-2011 Dovecot authors, see the included COPYING file */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "auth-common.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "base64.h"
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen#include "ioloop.h"
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include "network.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "istream.h"
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen#include "ostream.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "hex-binary.h"
146f9076cd456ea1e9b3f8536456d9d3c962fadbStephan Bosch#include "str.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "master-service.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "auth-request.h"
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen#include "auth-worker-client.h"
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen#include <stdlib.h>
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen#define OUTBUF_THROTTLE_SIZE (1024*10)
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen
3ed2d0f6b5e67e2663d44489d9da3176823789a8Timo Sirainen#define CLIENT_STATE_HANDSHAKE "handshaking"
65f8fb656051f1059f7b5a2da9c5555adcc30439Timo Sirainen#define CLIENT_STATE_IDLE "idling"
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainen
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainenstruct auth_worker_client {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen int refcount;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct auth *auth;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen int fd;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct io *io;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct istream *input;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct ostream *output;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen unsigned int version_received:1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen unsigned int dbhash_received:1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstruct auth_worker_list_context {
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen struct auth_worker_client *client;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct auth_request *auth_request;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen struct userdb_iterate_context *iter;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen bool sending, sent, done;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstruct auth_worker_client *auth_worker_client;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic void auth_worker_input(struct auth_worker_client *client);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int auth_worker_output(struct auth_worker_client *client);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic void
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainenauth_worker_client_check_throttle(struct auth_worker_client *client)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen{
3e564425db51f3921ce4de11859777135fdedd15Timo Sirainen if (o_stream_get_buffer_used_size(client->output) >=
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen OUTBUF_THROTTLE_SIZE) {
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen /* stop reading new requests until client has read the pending
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen replies. */
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen if (client->io != NULL)
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen io_remove(&client->io);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic struct auth_request *
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenworker_auth_request_new(struct auth_worker_client *client, unsigned int id,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const char *const *args)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen struct auth_request *auth_request;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen const char *key, *value;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen auth_request = auth_request_new_dummy();
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen client->refcount++;
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen auth_request->context = client;
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen auth_request->id = id;
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen for (; *args != NULL; args++) {
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen value = strchr(*args, '=');
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen if (value != NULL) {
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen key = t_strdup_until(*args, value++);
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen (void)auth_request_import(auth_request, key, value);
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen }
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen }
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen auth_request_init(auth_request);
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen return auth_request;
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen}
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainenstatic void auth_worker_send_reply(struct auth_worker_client *client,
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen string_t *str)
291ce16fffca75e8598a8c9dceb08613413dcb07Timo Sirainen{
291ce16fffca75e8598a8c9dceb08613413dcb07Timo Sirainen if (shutdown_request)
291ce16fffca75e8598a8c9dceb08613413dcb07Timo Sirainen o_stream_send_str(client->output, "SHUTDOWN\n");
08e9fd42eb8007e1f9db62c088eef74f906114a5Josef 'Jeff' Sipek o_stream_send(client->output, str_data(str), str_len(str));
08e9fd42eb8007e1f9db62c088eef74f906114a5Josef 'Jeff' Sipek}
08e9fd42eb8007e1f9db62c088eef74f906114a5Josef 'Jeff' Sipek
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainenstatic void verify_plain_callback(enum passdb_result result,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen struct auth_request *request)
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen{
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen struct auth_worker_client *client = request->context;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen struct auth_stream_reply *reply;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen string_t *str;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen if (request->passdb_failure && result == PASSDB_RESULT_OK)
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen result = PASSDB_RESULT_PASSWORD_MISMATCH;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen reply = auth_stream_reply_init(pool_datastack_create());
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen auth_stream_reply_add(reply, NULL, dec2str(request->id));
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen if (result == PASSDB_RESULT_OK)
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen auth_stream_reply_add(reply, "OK", NULL);
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen else {
30d50c7e8706f2d750215e009504109ca19cd485Timo Sirainen auth_stream_reply_add(reply, "FAIL", NULL);
30d50c7e8706f2d750215e009504109ca19cd485Timo Sirainen auth_stream_reply_add(reply, NULL,
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen t_strdup_printf("%d", result));
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (result != PASSDB_RESULT_INTERNAL_FAILURE) {
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen auth_stream_reply_add(reply, NULL, request->user);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen auth_stream_reply_add(reply, NULL,
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen request->passdb_password == NULL ? "" :
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen request->passdb_password);
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen if (request->extra_fields != NULL) {
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen const char *fields =
afe1da042382720393eca6497253106e4eec75e0Timo Sirainen auth_stream_reply_export(request->extra_fields);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen auth_stream_reply_import(reply, fields);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (request->extra_cache_fields != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *fields =
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen auth_stream_reply_export(request->extra_cache_fields);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen auth_stream_reply_import(reply, fields);
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen }
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen }
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen str = auth_stream_reply_get_str(reply);
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen str_append_c(str, '\n');
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen auth_worker_send_reply(client, str);
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen auth_request_unref(&request);
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen auth_worker_client_check_throttle(client);
7900eb30bac4a46b259522c58362884661483d7cJosef 'Jeff' Sipek auth_worker_client_unref(&client);
7900eb30bac4a46b259522c58362884661483d7cJosef 'Jeff' Sipek}
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstatic bool
98c217499d578495e982ea6010ebff831e9669aeMartti Rannanjärviauth_worker_handle_passv(struct auth_worker_client *client,
98c217499d578495e982ea6010ebff831e9669aeMartti Rannanjärvi unsigned int id, const char *const *args)
98c217499d578495e982ea6010ebff831e9669aeMartti Rannanjärvi{
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen /* verify plaintext password */
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen struct auth_request *auth_request;
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen struct auth_passdb *passdb;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen const char *password;
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen unsigned int passdb_id;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
70ead6466f9baa8294e71fc2fba0a4f54f488b5eTimo Sirainen /* <passdb id> <password> [<args>] */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen i_error("BUG: Auth worker server sent us invalid PASSV");
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainen return FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen password = args[1];
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen auth_request = worker_auth_request_new(client, id, args + 2);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen auth_request->mech_password =
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen p_strdup(auth_request->pool, password);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen if (auth_request->user == NULL || auth_request->service == NULL) {
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen i_error("BUG: PASSV had missing parameters");
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen auth_request_unref(&auth_request);
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen return FALSE;
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen }
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen passdb = auth_request->passdb;
98c217499d578495e982ea6010ebff831e9669aeMartti Rannanjärvi while (passdb != NULL && passdb->passdb->id != passdb_id)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen passdb = passdb->next;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen if (passdb == NULL) {
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen /* could be a masterdb */
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen passdb = auth_request_get_auth(auth_request)->masterdbs;
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen while (passdb != NULL && passdb->passdb->id != passdb_id)
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen passdb = passdb->next;
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen if (passdb == NULL) {
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen i_error("BUG: PASSV had invalid passdb ID");
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen auth_request_unref(&auth_request);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen return FALSE;
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen }
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen }
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen auth_request->passdb = passdb;
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen passdb->passdb->iface.
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen verify_plain(auth_request, password, verify_plain_callback);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen return TRUE;
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen}
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainenstatic void
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainenlookup_credentials_callback(enum passdb_result result,
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen const unsigned char *credentials, size_t size,
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen struct auth_request *request)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen struct auth_worker_client *client = request->context;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct auth_stream_reply *reply;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen string_t *str;
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen if (request->passdb_failure && result == PASSDB_RESULT_OK)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen result = PASSDB_RESULT_PASSWORD_MISMATCH;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
e03d986a74128f5ba30fcfda9f6e36578f5d8decTimo Sirainen reply = auth_stream_reply_init(pool_datastack_create());
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_stream_reply_add(reply, NULL, dec2str(request->id));
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen if (result != PASSDB_RESULT_OK) {
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen auth_stream_reply_add(reply, "FAIL", NULL);
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen auth_stream_reply_add(reply, NULL,
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen t_strdup_printf("%d", result));
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen } else {
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen auth_stream_reply_add(reply, "OK", NULL);
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen auth_stream_reply_add(reply, NULL, request->user);
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen str = t_str_new(64);
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen str_printfa(str, "{%s.b64}", request->credentials_scheme);
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen base64_encode(credentials, size, str);
6469cf211a57433335641725dc236ebb2b9fdd3bTimo Sirainen auth_stream_reply_add(reply, NULL, str_c(str));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen if (request->extra_fields != NULL) {
6cc4cce2078aca138fbce19305e69e77edcee614Timo Sirainen const char *fields =
bd6a8056771b6150685dea319ab5a94e021d17f1Josef 'Jeff' Sipek auth_stream_reply_export(request->extra_fields);
9f37ef2a9192e7d47e3d7ac959080fd01120f2e9Aki Tuomi auth_stream_reply_import(reply, fields);
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen }
bd6a8056771b6150685dea319ab5a94e021d17f1Josef 'Jeff' Sipek if (request->extra_cache_fields != NULL) {
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen const char *fields =
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen auth_stream_reply_export(request->extra_cache_fields);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen auth_stream_reply_import(reply, fields);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen }
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen }
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen str = auth_stream_reply_get_str(reply);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen str_append_c(str, '\n');
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen auth_worker_send_reply(client, str);
aa47c9bd1d1fc70cd699c49fd1ca92dbc7615953Timo Sirainen
aa47c9bd1d1fc70cd699c49fd1ca92dbc7615953Timo Sirainen auth_request_unref(&request);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen auth_worker_client_check_throttle(client);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen auth_worker_client_unref(&client);
aa47c9bd1d1fc70cd699c49fd1ca92dbc7615953Timo Sirainen}
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainenstatic bool
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainenauth_worker_handle_passl(struct auth_worker_client *client,
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen unsigned int id, const char *const *args)
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen{
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen /* lookup credentials */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen struct auth_request *auth_request;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen const char *scheme;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen unsigned int passdb_id;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen /* <passdb id> <scheme> [<args>] */
2584e86cc2d8c31ba30a4109cf4ba09d1e37e28aTimo Sirainen if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen i_error("BUG: Auth worker server sent us invalid PASSL");
4b41116563110d00330896a568eff1078c382827Timo Sirainen return FALSE;
4b41116563110d00330896a568eff1078c382827Timo Sirainen }
4b41116563110d00330896a568eff1078c382827Timo Sirainen scheme = args[1];
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen auth_request = worker_auth_request_new(client, id, args + 2);
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen auth_request->credentials_scheme = p_strdup(auth_request->pool, scheme);
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (auth_request->user == NULL || auth_request->service == NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("BUG: PASSL had missing parameters");
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen auth_request_unref(&auth_request);
c6ce2e251ac75fa650c7fbfa52150eae69386293Martti Rannanjärvi return FALSE;
c6ce2e251ac75fa650c7fbfa52150eae69386293Martti Rannanjärvi }
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainen
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen while (auth_request->passdb->passdb->id != passdb_id) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_request->passdb = auth_request->passdb->next;
dbe64f3893616a4005c8946be75d2dc8f6823d72Timo Sirainen if (auth_request->passdb == NULL) {
8a13b020f90e080570658b18c042e7e352c8b14fTimo Sirainen i_error("BUG: PASSL had invalid passdb ID");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_request_unref(&auth_request);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return FALSE;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (auth_request->passdb->passdb->iface.lookup_credentials == NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("BUG: PASSL lookup not supported by given passdb");
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen auth_request_unref(&auth_request);
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen return FALSE;
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen }
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen auth_request->prefer_plain_credentials = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_request->passdb->passdb->iface.
f3bb2fbe87425dc89a839908985af496f7f65702Timo Sirainen lookup_credentials(auth_request, lookup_credentials_callback);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen return TRUE;
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen}
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainenset_credentials_callback(bool success, struct auth_request *request)
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen{
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen struct auth_worker_client *client = request->context;
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen string_t *str;
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen str = t_str_new(64);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_printfa(str, "%u\t%s\n", request->id, success ? "OK" : "FAIL");
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen auth_worker_send_reply(client, str);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen auth_request_unref(&request);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen auth_worker_client_check_throttle(client);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen auth_worker_client_unref(&client);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen}
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenstatic bool
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenauth_worker_handle_setcred(struct auth_worker_client *client,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int id, const char *const *args)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct auth_request *auth_request;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen unsigned int passdb_id;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const char *creds;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen /* <passdb id> <credentials> [<args>] */
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen i_error("BUG: Auth worker server sent us invalid SETCRED");
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen return FALSE;
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen }
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen creds = args[1];
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen auth_request = worker_auth_request_new(client, id, args + 2);
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen if (auth_request->user == NULL || auth_request->service == NULL) {
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen i_error("BUG: SETCRED had missing parameters");
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen auth_request_unref(&auth_request);
2c70086138fe7ac9abf52cd4223c224fe0bbb488Timo Sirainen return FALSE;
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen }
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen while (auth_request->passdb->passdb->id != passdb_id) {
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen auth_request->passdb = auth_request->passdb->next;
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen if (auth_request->passdb == NULL) {
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen i_error("BUG: SETCRED had invalid passdb ID");
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen auth_request_unref(&auth_request);
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen return FALSE;
1ae5d61ec366fdb2f3c5b150ca378d6141b0f4bdTimo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen auth_request->passdb->passdb->iface.
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen set_credentials(auth_request, creds, set_credentials_callback);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return TRUE;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainenstatic void
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainenlookup_user_callback(enum userdb_result result,
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen struct auth_request *auth_request)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen{
d938e9e4ec4c0f326dffd5ebe42c1ad893ce7e52Timo Sirainen struct auth_worker_client *client = auth_request->context;
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen struct auth_stream_reply *reply = auth_request->userdb_reply;
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen string_t *str;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen str = t_str_new(128);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen str_printfa(str, "%u\t", auth_request->id);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen switch (result) {
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen case USERDB_RESULT_INTERNAL_FAILURE:
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen str_append(str, "FAIL\t");
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen break;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen case USERDB_RESULT_USER_UNKNOWN:
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen str_append(str, "NOTFOUND\t");
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen break;
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen case USERDB_RESULT_OK:
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen str_append(str, "OK\t");
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen str_append(str, auth_stream_reply_export(reply));
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen if (auth_request->userdb_lookup_failed)
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen str_append(str, "\ttempfail");
546335814920fb6b5b44c68c7803e654eefeae9dTimo Sirainen break;
546335814920fb6b5b44c68c7803e654eefeae9dTimo Sirainen }
546335814920fb6b5b44c68c7803e654eefeae9dTimo Sirainen str_append_c(str, '\n');
4b41218f9e09386ad5d8f279355aad1dfb64392dTimo Sirainen
4b41218f9e09386ad5d8f279355aad1dfb64392dTimo Sirainen auth_worker_send_reply(client, str);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen auth_request_unref(&auth_request);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen auth_worker_client_check_throttle(client);
eb1572d7c44ebc7b0b039d085c3dbab2ef7043ddTimo Sirainen auth_worker_client_unref(&client);
eb1572d7c44ebc7b0b039d085c3dbab2ef7043ddTimo Sirainen}
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainenstatic struct auth_userdb *
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainenauth_userdb_find_by_id(struct auth_userdb *userdbs, unsigned int id)
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen{
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen struct auth_userdb *db;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen for (db = userdbs; db != NULL; db = db->next) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (db->userdb->id == id)
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen return db;
c0c346d0e6a76137ba5006857ed03b1227804170Timo Sirainen }
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen return NULL;
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen}
382f23541ce657be87b079abd6784d376fb4eb43Timo Sirainen
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainenstatic bool
97a5e150cacf7da9dd200e317b75460352038d65Timo Sirainenauth_worker_handle_user(struct auth_worker_client *client,
3743948b65bd079cd6f2502d35bd21666c1a2f5aAki Tuomi unsigned int id, const char *const *args)
134987bc3b685d7ec71c04e9337f7125cff0698fTimo Sirainen{
42507d758b053bb483de58fba55c73a9eb5d3fbaTimo Sirainen /* lookup user */
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen struct auth_request *auth_request;
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen unsigned int userdb_id;
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen /* <userdb id> [<args>] */
817d027593510c3ba70ad542ce0011f5f6916d1eTimo Sirainen if (str_to_uint(args[0], &userdb_id) < 0) {
6ae329de09afb7214c906d762320847e05469d53Timo Sirainen i_error("BUG: Auth worker server sent us invalid USER");
6ae329de09afb7214c906d762320847e05469d53Timo Sirainen return FALSE;
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen }
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen auth_request = worker_auth_request_new(client, id, args + 1);
7e2671b295927b461adc8b6c4ed6a1c4761fb323Timo Sirainen if (auth_request->user == NULL || auth_request->service == NULL) {
7e2671b295927b461adc8b6c4ed6a1c4761fb323Timo Sirainen i_error("BUG: USER had missing parameters");
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen auth_request_unref(&auth_request);
fcfe85637e1ee14a9fc39c41fd6ceca106301542Timo Sirainen return FALSE;
fcfe85637e1ee14a9fc39c41fd6ceca106301542Timo Sirainen }
fcfe85637e1ee14a9fc39c41fd6ceca106301542Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen auth_request->userdb =
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen auth_userdb_find_by_id(auth_request->userdb, userdb_id);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (auth_request->userdb == NULL) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_error("BUG: USER had invalid userdb ID");
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen auth_request_unref(&auth_request);
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen return FALSE;
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen }
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen auth_request->userdb->userdb->iface->
4bbd396aa6198c84f3f7763b6e8a63a26e97e141Timo Sirainen lookup(auth_request, lookup_user_callback);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen return TRUE;
7baab0b0b60df7ce9093d0881cd322dff1e79491Timo Sirainen}
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainenstatic void list_iter_deinit(struct auth_worker_list_context *ctx)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen{
3857e2945a3b6744d603f0f5a656849ed8436ba3Timo Sirainen struct auth_worker_client *client = ctx->client;
3857e2945a3b6744d603f0f5a656849ed8436ba3Timo Sirainen string_t *str;
f90cbe597c41d5cc91debd371f8648bd8e6ffbc2Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen i_assert(client->io == NULL);
33b469d1ca66dd2cc496d2d990b8b98e72952a29Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen str = t_str_new(32);
58ba0fe5a6904d3a65cfe268411f4cbb881234eeTimo Sirainen if (ctx->auth_request->userdb->userdb->iface->
58ba0fe5a6904d3a65cfe268411f4cbb881234eeTimo Sirainen iterate_deinit(ctx->iter) < 0)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen str_printfa(str, "%u\tFAIL\n", ctx->auth_request->id);
6b0d8106ae51ffc6ce45636b34d2e21cbefca7fdTimo Sirainen else
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen str_printfa(str, "%u\tOK\n", ctx->auth_request->id);
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen auth_worker_send_reply(client, str);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen client->io = io_add(client->fd, IO_READ, auth_worker_input, client);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen o_stream_set_flush_callback(client->output, auth_worker_output, client);
7f735cb86b2d8abd8f230089065eacfc24e9e5d6Timo Sirainen auth_request_unref(&ctx->auth_request);
7f735cb86b2d8abd8f230089065eacfc24e9e5d6Timo Sirainen auth_worker_client_unref(&client);
7f735cb86b2d8abd8f230089065eacfc24e9e5d6Timo Sirainen i_free(ctx);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen}
b3484b5b1f47e4cf112f0e371478a2d7794b31bbTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenstatic void list_iter_callback(const char *user, void *context)
d81131d3bbb4f0befb62a661d1785cf8c84a17e2Timo Sirainen{
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen struct auth_worker_list_context *ctx = context;
9456a4a3e74929f9d3d5b00b93be6d8eb69bc52aTimo Sirainen string_t *str;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
4e3bcf7fdaeef92dd07a2acb1ded58422a907e87Timo Sirainen if (user == NULL) {
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen if (ctx->sending)
19e161dd9e2c3a2ffc96ee8852bec0720cb30d1cTimo Sirainen ctx->done = TRUE;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen else
540555c5b435203e1c26c8e7b924b2643ae07ae3Timo Sirainen list_iter_deinit(ctx);
540555c5b435203e1c26c8e7b924b2643ae07ae3Timo Sirainen return;
540555c5b435203e1c26c8e7b924b2643ae07ae3Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen T_BEGIN {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen str = t_str_new(128);
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainen str_printfa(str, "%u\t*\t%s\n", ctx->auth_request->id, user);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen o_stream_send(ctx->client->output, str_data(str), str_len(str));
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen } T_END;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
aa247243412a49f9bdebf7255e131dc6ece4ed46Timo Sirainen if (ctx->sending) {
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* avoid recursively looping to this same function */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen ctx->sent = TRUE;
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen return;
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen }
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen do {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->sending = TRUE;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->sent = FALSE;
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen ctx->auth_request->userdb->userdb->iface->
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen iterate_next(ctx->iter);
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen } while (ctx->sent &&
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen o_stream_get_buffer_used_size(ctx->client->output) == 0);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen ctx->sending = FALSE;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (ctx->done)
c0225f7f6b43d34dc58c17d3304f0fd60ab89894Timo Sirainen list_iter_deinit(ctx);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen}
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int auth_worker_list_output(struct auth_worker_list_context *ctx)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen{
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen int ret;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if ((ret = o_stream_flush(ctx->client->output)) < 0) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen list_iter_deinit(ctx);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return 1;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (ret > 0) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen ctx->auth_request->userdb->userdb->iface->
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen iterate_next(ctx->iter);
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen }
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen return 1;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen}
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainenstatic bool
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainenauth_worker_handle_list(struct auth_worker_client *client,
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen unsigned int id, const char *const *args)
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen{
e53ab6c7081246c865917f9aa0eff031a08ad1e7Timo Sirainen struct auth_worker_list_context *ctx;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct auth_userdb *userdb;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen unsigned int userdb_id;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
21aaa6affb9f134112b75b5db737309fc35ef1cfMartti Rannanjärvi if (str_to_uint(args[0], &userdb_id) < 0) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_error("BUG: Auth worker server sent us invalid LIST");
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return FALSE;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen }
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen userdb = auth_userdb_find_by_id(client->auth->userdbs, userdb_id);
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen if (userdb == NULL) {
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen i_error("BUG: LIST had invalid userdb ID");
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen return FALSE;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen }
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen
0206dc57f2c04da69599dea5816235cfeb2b897aMartti Rannanjärvi ctx = i_new(struct auth_worker_list_context, 1);
0206dc57f2c04da69599dea5816235cfeb2b897aMartti Rannanjärvi ctx->client = client;
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen ctx->auth_request = worker_auth_request_new(client, id, args + 1);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->auth_request->userdb = userdb;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (ctx->auth_request->user == NULL ||
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ctx->auth_request->service == NULL) {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen i_error("BUG: LIST had missing parameters");
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen auth_request_unref(&ctx->auth_request);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen i_free(ctx);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return FALSE;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen io_remove(&ctx->client->io);
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen o_stream_set_flush_callback(ctx->client->output,
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen auth_worker_list_output, ctx);
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen ctx->iter = ctx->auth_request->userdb->userdb->iface->
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen iterate_init(ctx->auth_request, list_iter_callback, ctx);
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen ctx->auth_request->userdb->userdb->iface->iterate_next(ctx->iter);
13e130c3af3032982de6b1d13c6dcddda9164848Timo Sirainen return TRUE;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenstatic bool
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainenauth_worker_handle_line(struct auth_worker_client *client, const char *line)
310767ca33e7636d40ec45dee68a2c319a5fa3c0Timo Sirainen{
310767ca33e7636d40ec45dee68a2c319a5fa3c0Timo Sirainen const char *const *args;
310767ca33e7636d40ec45dee68a2c319a5fa3c0Timo Sirainen unsigned int id;
5f44975ec6c5755dd74bcd4c47a123a7242ecab3Timo Sirainen bool ret = FALSE;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen args = t_strsplit(line, "\t");
2c8ca7e88ec881c473fb90e5f647c1f563877164Timo Sirainen if (args[0] == NULL || args[1] == NULL || args[2] == NULL ||
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi str_to_uint(args[0], &id) < 0) {
6c51e3c3dc8dc5dc6fef2280b7c2c9ebef3de8f0Aki Tuomi i_error("BUG: Invalid input: %s", line);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return FALSE;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_worker_refresh_proctitle(args[1]);
e4c90f0b88e40a8f92b8f5e1f1a3ea701e5c965cTimo Sirainen if (strcmp(args[1], "PASSV") == 0)
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainen ret = auth_worker_handle_passv(client, id, args + 2);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else if (strcmp(args[1], "PASSL") == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = auth_worker_handle_passl(client, id, args + 2);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen else if (strcmp(args[1], "SETCRED") == 0)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ret = auth_worker_handle_setcred(client, id, args + 2);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen else if (strcmp(args[1], "USER") == 0)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ret = auth_worker_handle_user(client, id, args + 2);
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen else if (strcmp(args[1], "LIST") == 0)
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen ret = auth_worker_handle_list(client, id, args + 2);
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen else {
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen i_error("BUG: Auth-worker received unknown command: %s",
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen args[1]);
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen }
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen auth_worker_refresh_proctitle(CLIENT_STATE_IDLE);
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen return ret;
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen}
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainenstatic bool auth_worker_verify_db_hash(const char *line)
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen{
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen string_t *str;
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen unsigned char passdb_md5[MD5_RESULTLEN];
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen unsigned char userdb_md5[MD5_RESULTLEN];
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen passdbs_generate_md5(passdb_md5);
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen userdbs_generate_md5(userdb_md5);
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str = t_str_new(128);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(str, "DBHASH\t");
194603b35061fea1ee8d171a7104b6985c610966Timo Sirainen binary_to_hex_append(str, passdb_md5, sizeof(passdb_md5));
d1fbd2c264368d8b4c7139b96e3b21f45930b857Timo Sirainen str_append_c(str, '\t');
194603b35061fea1ee8d171a7104b6985c610966Timo Sirainen binary_to_hex_append(str, userdb_md5, sizeof(userdb_md5));
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen return strcmp(line, str_c(str)) == 0;
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen}
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainenstatic void auth_worker_input(struct auth_worker_client *client)
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen{
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen char *line;
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen bool ret;
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen switch (i_stream_read(client->input)) {
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen case 0:
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen return;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen case -1:
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen /* disconnected */
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen auth_worker_client_destroy(&client);
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen return;
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen case -2:
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen /* buffer full */
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen i_error("BUG: Auth worker server sent us more than %d bytes",
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen (int)AUTH_WORKER_MAX_LINE_LENGTH);
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen auth_worker_client_destroy(&client);
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen return;
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen }
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen if (!client->version_received) {
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen line = i_stream_next_line(client->input);
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen if (line == NULL)
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen return;
1eaaa2c9003cf3fbf672d597473e3f84e70d2ee6Timo Sirainen
1eaaa2c9003cf3fbf672d597473e3f84e70d2ee6Timo Sirainen if (!version_string_verify(line, "auth-worker",
2d01cc1880cf2afd4fb1c8ad7fa6ce78e562e71eTimo Sirainen AUTH_WORKER_PROTOCOL_MAJOR_VERSION)) {
1eaaa2c9003cf3fbf672d597473e3f84e70d2ee6Timo Sirainen i_error("Auth worker not compatible with this server "
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen "(mixed old and new binaries?)");
900bb5e316d030cdebff7ee128ce65881dfb27f7Timo Sirainen auth_worker_client_destroy(&client);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen return;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen client->version_received = TRUE;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (!client->dbhash_received) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen line = i_stream_next_line(client->input);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (line == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
e63bdfedcf61e1a9ee21990140cbd0d0638da7e1Timo Sirainen if (!auth_worker_verify_db_hash(line)) {
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen i_error("Auth worker sees different passdbs/userdbs "
e63bdfedcf61e1a9ee21990140cbd0d0638da7e1Timo Sirainen "than auth server. Maybe config just changed "
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen "and this goes away automatically?");
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen auth_worker_client_destroy(&client);
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen return;
e63bdfedcf61e1a9ee21990140cbd0d0638da7e1Timo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen client->dbhash_received = TRUE;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen auth_worker_refresh_proctitle(CLIENT_STATE_IDLE);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen client->refcount++;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen while ((line = i_stream_next_line(client->input)) != NULL) {
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen T_BEGIN {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen ret = auth_worker_handle_line(client, line);
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen } T_END;
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen if (!ret) {
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen struct auth_worker_client *client2 = client;
4321f6c969e7b8f6b243ff5bb6b8d297921676f6Timo Sirainen auth_worker_client_destroy(&client2);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen break;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_worker_client_unref(&client);
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen}
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainenstatic int auth_worker_output(struct auth_worker_client *client)
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen{
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen if (o_stream_flush(client->output) < 0) {
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen auth_worker_client_destroy(&client);
0cce885512b836ce021260a58e7b4f099b36d0f1Timo Sirainen return 1;
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen }
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen
61cae213dc69070c1cef266578057710e34e0d12Timo Sirainen if (o_stream_get_buffer_used_size(client->output) <=
0cce885512b836ce021260a58e7b4f099b36d0f1Timo Sirainen OUTBUF_THROTTLE_SIZE/3 && client->io == NULL) {
9617ac7078a17bd346fed69526861c3e7fd9d809Timo Sirainen /* allow input again */
4d527c363482be2b65dd0573d878ecda86cbb0bbTimo Sirainen client->io = io_add(client->fd, IO_READ,
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen auth_worker_input, client);
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen }
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen return 1;
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen}
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainenstruct auth_worker_client *
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainenauth_worker_client_create(struct auth *auth, int fd)
d0d37a769d7e54646de025a43d2cb888478cb218Timo Sirainen{
d0d37a769d7e54646de025a43d2cb888478cb218Timo Sirainen struct auth_worker_client *client;
d0d37a769d7e54646de025a43d2cb888478cb218Timo Sirainen
d0d37a769d7e54646de025a43d2cb888478cb218Timo Sirainen client = i_new(struct auth_worker_client, 1);
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen client->refcount = 1;
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen client->auth = auth;
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen client->fd = fd;
b62140c5849297a800fee942026d9c3cb8c60206Timo Sirainen client->input = i_stream_create_fd(fd, AUTH_WORKER_MAX_LINE_LENGTH,
b62140c5849297a800fee942026d9c3cb8c60206Timo Sirainen FALSE);
b62140c5849297a800fee942026d9c3cb8c60206Timo Sirainen client->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
b62140c5849297a800fee942026d9c3cb8c60206Timo Sirainen o_stream_set_flush_callback(client->output, auth_worker_output, client);
b09eaeb9a81e5b58c6e605eb762573a2b4a69e0eTimo Sirainen client->io = io_add(fd, IO_READ, auth_worker_input, client);
b09eaeb9a81e5b58c6e605eb762573a2b4a69e0eTimo Sirainen auth_worker_refresh_proctitle(CLIENT_STATE_HANDSHAKE);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
ba8ff75a149d6936f769a2d1dfceaab9da87863bTimo Sirainen auth_worker_client = client;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen return client;
05150df8fbda6b8fdfafcfb0aa9003f1da4ecacaTimo Sirainen}
05150df8fbda6b8fdfafcfb0aa9003f1da4ecacaTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenvoid auth_worker_client_destroy(struct auth_worker_client **_client)
05150df8fbda6b8fdfafcfb0aa9003f1da4ecacaTimo Sirainen{
05150df8fbda6b8fdfafcfb0aa9003f1da4ecacaTimo Sirainen struct auth_worker_client *client = *_client;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
05150df8fbda6b8fdfafcfb0aa9003f1da4ecacaTimo Sirainen *_client = NULL;
05150df8fbda6b8fdfafcfb0aa9003f1da4ecacaTimo Sirainen if (client->fd == -1)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen return;
05150df8fbda6b8fdfafcfb0aa9003f1da4ecacaTimo Sirainen
05150df8fbda6b8fdfafcfb0aa9003f1da4ecacaTimo Sirainen i_stream_close(client->input);
05150df8fbda6b8fdfafcfb0aa9003f1da4ecacaTimo Sirainen o_stream_close(client->output);
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen if (client->io != NULL)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen io_remove(&client->io);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen net_disconnect(client->fd);
4906f652013f9f9ea806602b5cd677ef0d039d62Timo Sirainen client->fd = -1;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen auth_worker_client_unref(&client);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen auth_worker_refresh_proctitle(NULL);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen auth_worker_client = NULL;
a4f09749814b93e8ad3ec8a0dc18885b874d6f8cTimo Sirainen master_service_client_connection_destroyed(master_service);
de58be41126e5d68008d2ea706d62ccdc1f29337Timo Sirainen}
a4f09749814b93e8ad3ec8a0dc18885b874d6f8cTimo Sirainen
a4f09749814b93e8ad3ec8a0dc18885b874d6f8cTimo Sirainenvoid auth_worker_client_unref(struct auth_worker_client **_client)
a4f09749814b93e8ad3ec8a0dc18885b874d6f8cTimo Sirainen{
a4f09749814b93e8ad3ec8a0dc18885b874d6f8cTimo Sirainen struct auth_worker_client *client = *_client;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen *_client = NULL;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen if (--client->refcount > 0)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen i_stream_unref(&client->input);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen o_stream_unref(&client->output);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen i_free(client);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen