auth-worker-client.c revision 938835576b218f6bb9498d829cef9514f8609c6f
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschauth_worker_client_check_throttle(struct auth_worker_client *client)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (o_stream_get_buffer_used_size(client->output) >=
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* stop reading new requests until client has read the pending
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschworker_auth_request_new(struct auth_worker_client *client, unsigned int id,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_request = auth_request_new_dummy(client->auth);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch for (tmp = t_strsplit(args, "\t"); *tmp != NULL; tmp++) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch (void)auth_request_import(auth_request, key, value);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschadd_userdb_replies(struct auth_stream_reply *reply,
499ca6dc5d746fd7a7efc6d497deede89553669fStephan Bosch const char *const *tmp;
499ca6dc5d746fd7a7efc6d497deede89553669fStephan Bosch /* first field is the user name */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstatic void auth_worker_send_reply(struct auth_worker_client *client,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch o_stream_send_str(client->output, "SHUTDOWN\n");
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch o_stream_send(client->output, str_data(str), str_len(str));
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstatic void verify_plain_callback(enum passdb_result result,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct auth_worker_client *client = request->context;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (request->passdb_failure && result == PASSDB_RESULT_OK)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch reply = auth_stream_reply_init(pool_datastack_create());
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_stream_reply_add(reply, NULL, dec2str(request->id));
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (result != PASSDB_RESULT_INTERNAL_FAILURE) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_stream_reply_add(reply, NULL, request->user);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_stream_reply_add(reply, "nopassword", NULL);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *fields =
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_stream_reply_export(request->extra_fields);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *fields =
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_stream_reply_export(request->extra_cache_fields);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschauth_worker_handle_passv(struct auth_worker_client *client,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* verify plaintext password */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch i_error("BUG: Auth worker server sent us invalid PASSV");
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_request = worker_auth_request_new(client, id, args);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (auth_request->user == NULL || auth_request->service == NULL) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch while (passdb != NULL && passdb->id != passdb_id)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* could be a masterdb */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch while (passdb != NULL && passdb->id != passdb_id)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch verify_plain(auth_request, password, verify_plain_callback);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschlookup_credentials_callback(enum passdb_result result,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const unsigned char *credentials, size_t size,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct auth_worker_client *client = request->context;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (request->passdb_failure && result == PASSDB_RESULT_OK)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch reply = auth_stream_reply_init(pool_datastack_create());
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_stream_reply_add(reply, NULL, dec2str(request->id));
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_stream_reply_add(reply, NULL, request->user);
9249c80276766fdc4d31fc3eebc22fba7d53d77cStephan Bosch str_printfa(str, "{%s.b64}", request->credentials_scheme);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_stream_reply_add(reply, NULL, str_c(str));
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *fields =
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_stream_reply_export(request->extra_fields);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *fields =
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_stream_reply_export(request->extra_cache_fields);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch add_userdb_replies(reply, request->userdb_reply);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschauth_worker_handle_passl(struct auth_worker_client *client,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* lookup credentials */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch i_error("BUG: Auth worker server sent us invalid PASSL");
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_request = worker_auth_request_new(client, id, args);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_request->credentials_scheme = p_strdup(auth_request->pool, scheme);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (auth_request->user == NULL || auth_request->service == NULL) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch while (auth_request->passdb->id != passdb_id) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_request->passdb = auth_request->passdb->next;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (auth_request->passdb->passdb->iface.lookup_credentials == NULL) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch i_error("BUG: PASSL lookup not supported by given passdb");
40a926a1aeae93b3d4944b56eacb013d3059b549Stephan Bosch lookup_credentials(auth_request, lookup_credentials_callback);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschset_credentials_callback(bool success, struct auth_request *request)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct auth_worker_client *client = request->context;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch str_printfa(str, "%u\t%s\n", request->id, success ? "OK" : "FAIL");
b85a1bcaa9f82dd5b326967da5f1a26595173ee9Stephan Boschauth_worker_handle_setcred(struct auth_worker_client *client,
912e87d5be9dd8895e8cb7c6cb51d8a752edbe8cStephan Bosch i_error("BUG: Auth worker server sent us invalid SETCRED");
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_request = worker_auth_request_new(client, id, args);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (auth_request->user == NULL || auth_request->service == NULL) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch i_error("BUG: SETCRED had missing parameters");
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch while (auth_request->passdb->id != passdb_id) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_request->passdb = auth_request->passdb->next;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch i_error("BUG: SETCRED had invalid passdb ID");
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch set_credentials(auth_request, data, set_credentials_callback);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschlookup_user_callback(enum userdb_result result,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct auth_worker_client *client = auth_request->context;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct auth_stream_reply *reply = auth_request->userdb_reply;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch str_append(str, auth_stream_reply_export(reply));
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschauth_worker_handle_user(struct auth_worker_client *client,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* lookup user */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int num;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_request = worker_auth_request_new(client, id, args);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (auth_request->user == NULL || auth_request->service == NULL) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_request->userdb = auth_request->userdb->next;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschauth_worker_handle_line(struct auth_worker_client *client, const char *line)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch const char *p;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch unsigned int id;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch id = (unsigned int)strtoul(t_strdup_until(line, p), NULL, 10);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_worker_handle_passv(client, id, line + 6);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_worker_handle_passl(client, id, line + 6);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_worker_handle_setcred(client, id, line + 8);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch auth_worker_handle_user(client, id, line + 5);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstatic void auth_worker_input(struct auth_worker_client *client)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* disconnected */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* buffer full */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch i_error("BUG: Auth worker server sent us more than %d bytes",
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch while ((line = i_stream_next_line(client->input)) != NULL) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstatic int auth_worker_output(struct auth_worker_client *client)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (o_stream_get_buffer_used_size(client->output) <=
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch OUTBUF_THROTTLE_SIZE/3 && client->io == NULL) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* allow input again */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschauth_worker_client_create(struct auth *auth, int fd)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch client->input = i_stream_create_fd(fd, AUTH_WORKER_MAX_LINE_LENGTH,
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch client->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch o_stream_set_flush_callback(client->output, auth_worker_output, client);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch client->io = io_add(fd, IO_READ, auth_worker_input, client);