bool set_pool(PgSocket *client, const char *dbname, const char *username) { PgDatabase *db; PgUser *user; /* find database */ db = find_database(dbname); if (!db) { db = register_auto_database(dbname); if (!db) { disconnect_client(client, true, "No such database: %s", dbname); return false; } else { slog_info(client, "registered new auto-database: db = %s", dbname ); } } /* are new connections allowed? */ if (db->db_disabled) { disconnect_client(client, true, "database does not allow connections: %s", dbname); return false; } /* find user */ if (cf_auth_type == AUTH_ANY) { /* ignore requested user */ user = NULL; if (db->forced_user == NULL) { slog_error(client, "auth_type=any requires forced user"); disconnect_client(client, true, "bouncer config error"); return false; } client->auth_user = db->forced_user; } else { /* the user clients wants to log in as */ user = find_user(username); if (!user) { disconnect_client(client, true, "No such user: %s", username); return false; } client->auth_user = user; } /* pool user may be forced */ if (db->forced_user) user = db->forced_user; client->pool = get_pool(db, user); if (!client->pool) { disconnect_client(client, true, "no memory for pool"); return false; } return check_fast_fail(client); }
static bool finish_set_pool(PgSocket *client, bool takeover) { PgUser *user = client->auth_user; /* pool user may be forced */ if (client->db->forced_user) { user = client->db->forced_user; } client->pool = get_pool(client->db, user); if (!client->pool) { disconnect_client(client, true, "no memory for pool"); return false; } if (cf_log_connections) slog_info(client, "login attempt: db=%s user=%s", client->db->name, client->auth_user->name); if (!check_fast_fail(client)) return false; if (takeover) return true; if (client->pool->db->admin) { if (!admin_post_login(client)) return false; } if (cf_auth_type <= AUTH_TRUST || client->own_user) { if (!finish_client_login(client)) return false; } else { if (!send_client_authreq(client)) { disconnect_client(client, false, "failed to send auth req"); return false; } } return true; }
static bool finish_set_pool(PgSocket *client, bool takeover) { PgUser *user = client->auth_user; bool ok = false; int auth; /* pool user may be forced */ if (client->db->forced_user) { user = client->db->forced_user; } client->pool = get_pool(client->db, user); if (!client->pool) { disconnect_client(client, true, "no memory for pool"); return false; } if (cf_log_connections) { if (client->sbuf.tls) { char infobuf[96] = ""; tls_get_connection_info(client->sbuf.tls, infobuf, sizeof infobuf); slog_info(client, "login attempt: db=%s user=%s tls=%s", client->db->name, client->auth_user->name, infobuf); } else { slog_info(client, "login attempt: db=%s user=%s tls=no", client->db->name, client->auth_user->name); } } if (!check_fast_fail(client)) return false; if (takeover) return true; if (client->pool->db->admin) { if (!admin_post_login(client)) return false; } if (client->own_user) return finish_client_login(client); auth = cf_auth_type; if (auth == AUTH_HBA) { auth = hba_eval(parsed_hba, &client->remote_addr, !!client->sbuf.tls, client->db->name, client->auth_user->name); } /* remember method */ client->client_auth_type = auth; switch (auth) { case AUTH_ANY: case AUTH_TRUST: ok = finish_client_login(client); break; case AUTH_PLAIN: case AUTH_MD5: case AUTH_PAM: ok = send_client_authreq(client); break; case AUTH_CERT: ok = login_via_cert(client); break; case AUTH_PEER: ok = login_as_unix_peer(client); break; default: disconnect_client(client, true, "login rejected"); ok = false; } return ok; }