static bool
postfix_input_user(struct auth_postfix_connection *conn, const char *username)
{
	struct auth_request *auth_request;
	const char *error;

	io_remove(&conn->io);
	if (!postfix_input_auth_request(conn, username,
					&auth_request, &error)) {
		auth_request_log_info(auth_request, "postfix", "%s", error);
		user_callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
	} else {
		auth_request_set_state(auth_request, AUTH_REQUEST_STATE_USERDB);
		auth_request_lookup_user(auth_request, user_callback);
	}
	return TRUE;
}
static bool
master_input_user(struct auth_master_connection *conn, const char *args)
{
	struct auth_request *auth_request;
	const char *error;
	int ret;

	ret = master_input_auth_request(conn, args, "USER",
					&auth_request, &error);
	if (ret <= 0) {
		if (ret < 0)
			return FALSE;
		auth_request_log_info(auth_request, "userdb", "%s", error);
		user_callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
	} else {
		auth_request_set_state(auth_request, AUTH_REQUEST_STATE_USERDB);
		auth_request_lookup_user(auth_request, user_callback);
	}
	return TRUE;
}
bool auth_request_handler_master_request(struct auth_request_handler *handler,
					 struct auth_master_connection *master,
					 unsigned int id, unsigned int client_id,
					 const char *const *params)
{
	struct auth_request *request;
	struct net_unix_cred cred;

	request = hash_table_lookup(handler->requests, POINTER_CAST(client_id));
	if (request == NULL) {
		i_error("Master request %u.%u not found",
			handler->client_pid, client_id);
		return auth_master_request_failed(handler, master, id);
	}

	auth_request_ref(request);
	auth_request_handler_remove(handler, request);

	for (; *params != NULL; params++) {
		const char *name, *param = strchr(*params, '=');

		if (param == NULL) {
			name = *params;
			param = "";
		} else {
			name = t_strdup_until(*params, param);
			param++;
		}

		(void)auth_request_import_master(request, name, param);
	}

	/* verify session pid if specified and possible */
	if (request->session_pid != (pid_t)-1 &&
	    net_getunixcred(master->fd, &cred) == 0 &&
	    cred.pid != (pid_t)-1 && request->session_pid != cred.pid) {
		i_error("Session pid %ld provided by master for request %u.%u "
			"did not match peer credentials (pid=%ld, uid=%ld)",
			(long)request->session_pid,
			handler->client_pid, client_id,
			(long)cred.pid, (long)cred.uid);
		return auth_master_request_failed(handler, master, id);
	}

	if (request->state != AUTH_REQUEST_STATE_FINISHED ||
	    !request->successful) {
		i_error("Master requested unfinished authentication request "
			"%u.%u", handler->client_pid, client_id);
		handler->master_callback(t_strdup_printf("FAIL\t%u", id),
					 master);
		auth_request_unref(&request);
	} else {
		/* the request isn't being referenced anywhere anymore,
		   so we can do a bit of kludging.. replace the request's
		   old client_id with master's id. */
		auth_request_set_state(request, AUTH_REQUEST_STATE_USERDB);
		request->id = id;
		request->master = master;

		/* master and handler are referenced until userdb_callback i
		   s called. */
		auth_master_connection_ref(master);
		handler->refcount++;
		auth_request_lookup_user(request, userdb_callback);
	}
	return TRUE;
}