auth-server-connection.c revision 0cb5a9bfbf40b3b323956792aa13d342a459585e
c533a883a71cff9ff32df1c53c31201e1cbf371fhx/* Copyright (c) 2003-2007 Dovecot authors, see the included COPYING file */
c533a883a71cff9ff32df1c53c31201e1cbf371fhxstatic void auth_server_connection_unref(struct auth_server_connection *conn);
c533a883a71cff9ff32df1c53c31201e1cbf371fhxstatic void update_available_auth_mechs(struct auth_server_connection *conn)
c533a883a71cff9ff32df1c53c31201e1cbf371fhx unsigned int i;
c533a883a71cff9ff32df1c53c31201e1cbf371fhx if (auth_client_find_mech(client, mech[i].name) == NULL) {
c533a883a71cff9ff32df1c53c31201e1cbf371fhxstatic bool
c533a883a71cff9ff32df1c53c31201e1cbf371fhxauth_client_input_mech(struct auth_server_connection *conn, const char *args)
c533a883a71cff9ff32df1c53c31201e1cbf371fhx const char *const *list;
c533a883a71cff9ff32df1c53c31201e1cbf371fhx i_error("BUG: Authentication server already sent handshake");
c533a883a71cff9ff32df1c53c31201e1cbf371fhx i_error("BUG: Authentication server sent broken MECH line");
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China if (strcmp(mech_desc.name, "PLAIN") == 0)
c533a883a71cff9ff32df1c53c31201e1cbf371fhx buffer_append(conn->auth_mechs_buf, &mech_desc, sizeof(mech_desc));
c533a883a71cff9ff32df1c53c31201e1cbf371fhxstatic bool
c533a883a71cff9ff32df1c53c31201e1cbf371fhxauth_client_input_spid(struct auth_server_connection *conn, const char *args)
c533a883a71cff9ff32df1c53c31201e1cbf371fhx i_error("BUG: Authentication server already sent handshake");
c533a883a71cff9ff32df1c53c31201e1cbf371fhx conn->server_pid = (unsigned int)strtoul(args, NULL, 10);
c533a883a71cff9ff32df1c53c31201e1cbf371fhxstatic bool
c533a883a71cff9ff32df1c53c31201e1cbf371fhxauth_client_input_cuid(struct auth_server_connection *conn, const char *args)
c533a883a71cff9ff32df1c53c31201e1cbf371fhx i_error("BUG: Authentication server already sent handshake");
c533a883a71cff9ff32df1c53c31201e1cbf371fhx conn->connect_uid = (unsigned int)strtoul(args, NULL, 10);
c533a883a71cff9ff32df1c53c31201e1cbf371fhxstatic bool auth_client_input_done(struct auth_server_connection *conn)
c533a883a71cff9ff32df1c53c31201e1cbf371fhx conn->auth_mechs_buf->used / sizeof(struct auth_mech_desc);
c533a883a71cff9ff32df1c53c31201e1cbf371fhx i_error("BUG: Authentication server returned no mechanisms");
c533a883a71cff9ff32df1c53c31201e1cbf371fhx conn->client->connect_notify_callback(conn->client, TRUE,
c533a883a71cff9ff32df1c53c31201e1cbf371fhxstatic void auth_client_input(struct auth_server_connection *conn)
c533a883a71cff9ff32df1c53c31201e1cbf371fhx const char *line;
c533a883a71cff9ff32df1c53c31201e1cbf371fhx /* disconnected */
c533a883a71cff9ff32df1c53c31201e1cbf371fhx /* buffer full - can't happen unless auth is buggy */
c533a883a71cff9ff32df1c53c31201e1cbf371fhx i_error("BUG: Auth server sent us more than %d bytes of data",
c533a883a71cff9ff32df1c53c31201e1cbf371fhx /* make sure the major version matches */
c533a883a71cff9ff32df1c53c31201e1cbf371fhx "this client (mixed old and new binaries?)");
c533a883a71cff9ff32df1c53c31201e1cbf371fhx while ((line = i_stream_next_line(conn->input)) != NULL) {
c533a883a71cff9ff32df1c53c31201e1cbf371fhx /* ignore unknown command */
c533a883a71cff9ff32df1c53c31201e1cbf371fhxstatic void auth_client_handshake_timeout(struct auth_server_connection *conn)
c533a883a71cff9ff32df1c53c31201e1cbf371fhx i_error("Timeout waiting for handshake from auth server. "
c533a883a71cff9ff32df1c53c31201e1cbf371fhxauth_server_connection_new(struct auth_client *client, const char *path)
c533a883a71cff9ff32df1c53c31201e1cbf371fhx const char *handshake;
c533a883a71cff9ff32df1c53c31201e1cbf371fhx /* max. 1 second wait here. */
c533a883a71cff9ff32df1c53c31201e1cbf371fhx if (fd != -1 || (errno != EAGAIN && errno != ECONNREFUSED))
c533a883a71cff9ff32df1c53c31201e1cbf371fhx /* busy. wait for a while. */
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China usleep(((rand() % 10) + 1) * 10000);
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China i_error("Can't connect to auth server at %s: %m", path);
b510adae7e8895b2bf58eda3537fd56df35302e4fei feng - Sun Microsystems - Beijing China /* use blocking connection since we depend on auth server -
c533a883a71cff9ff32df1c53c31201e1cbf371fhx if it's slow, just wait */
c533a883a71cff9ff32df1c53c31201e1cbf371fhx conn->input = i_stream_create_fd(fd, AUTH_CLIENT_MAX_LINE_LENGTH,
c533a883a71cff9ff32df1c53c31201e1cbf371fhx conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
c533a883a71cff9ff32df1c53c31201e1cbf371fhx conn->requests = hash_create(default_pool, pool, 100, NULL, NULL);
c533a883a71cff9ff32df1c53c31201e1cbf371fhx conn->auth_mechs_buf = buffer_create_dynamic(default_pool, 256);
c533a883a71cff9ff32df1c53c31201e1cbf371fhx handshake = t_strdup_printf("VERSION\t%u\t%u\nCPID\t%u\n",
c533a883a71cff9ff32df1c53c31201e1cbf371fhxvoid auth_server_connection_destroy(struct auth_server_connection **_conn,
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China struct auth_client *client = conn->client;
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China if (conn->fd == -1)
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China timeout_remove(&conn->to);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China if (conn->io != NULL)
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China io_remove(&conn->io);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China i_stream_close(conn->input);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China o_stream_close(conn->output);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China if (close(conn->fd) < 0)
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China i_error("close(auth) failed: %m");
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China conn->fd = -1;
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China auth_server_requests_remove_all(conn);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China auth_server_connection_unref(conn);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China if (reconnect)
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China auth_client_connect_missing_servers(client);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China else if (client->connect_notify_callback != NULL) {
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China client->connect_notify_callback(client,
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China auth_client_is_connected(client),
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China client->connect_notify_context);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing Chinastatic void auth_server_connection_unref(struct auth_server_connection *conn)
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China if (--conn->refcount > 0)
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China i_assert(conn->refcount == 0);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China hash_destroy(&conn->requests);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China buffer_free(&conn->auth_mechs_buf);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China i_stream_unref(&conn->input);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China o_stream_unref(&conn->output);
cdc64593cc1046229f4ac4daf5ead688b5efe6ebxinghua wen - Sun Microsystems - Beijing China pool_unref(&conn->pool);
c533a883a71cff9ff32df1c53c31201e1cbf371fhxauth_server_connection_find_path(struct auth_client *client, const char *path)
c533a883a71cff9ff32df1c53c31201e1cbf371fhx for (conn = client->connections; conn != NULL; conn = conn->next) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerauth_server_connection_find_mech(struct auth_client *client,
c533a883a71cff9ff32df1c53c31201e1cbf371fhx unsigned int i, n, match_n;
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China /* find a connection which has this mechanism. if there are multiple
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China available connections to use, do round robin load balancing */
6f12def440a1ce798ab128210a43414d173669f0pengcheng chen - Sun Microsystems - Beijing China match = NULL; match_n = n = 0;
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China for (conn = client->connections; conn != NULL; conn = conn->next, n++) {
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China mech = conn->available_auth_mechs;
19d332fefbc61327bb6187d0eb818629f3b52c6ffei feng - Sun Microsystems - Beijing China for (i = 0; i < conn->available_auth_mechs_count; i++) {
d2a61391af480de12cf4264080d7254a6de96e2apengcheng chen - Sun Microsystems - Beijing China *error_r = "Authentication server isn't connected, "
c533a883a71cff9ff32df1c53c31201e1cbf371fhx "try again later..";