Archive

Monthly Archives: September 2010

I have problem with PgPool II 3.0. I have downloaded the source code from http://pgfoundry.org/projects/pgpool. Extract and compile it successfully. Configure it just to have connection pooling enabled (other features: Replication, LoadBalance, Parallel Query are disabled). But, I can not connect to PostgreSQL 9.0 via PgPool port at 9999 with authentication mode set to md5 in pg_hba.conf (pool_hba.conf is disabled).

After take some time to trace the source code, I have found bug in file pool_auth.c. Inside function:

static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor)
variable int size is declared but it never have the length of password.

4 steps to fix the problem:
  1. Modify forward declaration of function int read_password_packet(…), add int *pwdSize as the fourth argument:
    //static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password);
    static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize);

  2. Modify function body of function int read_password_packet(…). Watch that *pwdSize has the password length at the end of the function body:
    /*
    * Read password packet from frontend
    */
    //static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password)
    static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize)
    {
      int size;
      /* Read password packet */
      if (protoMajor == PROTO_MAJOR_V2)
      {
        if (pool_read(frontend, &size, sizeof(size)))
        {
          pool_error(“read_password_packet: failed to read password packet size”);
          return -1;
        }
      }
      else
      {
        char k;
        if (pool_read(frontend, &k, sizeof(k)))
        {
          pool_debug(“read_password_packet_password: failed to read password packet \”p\””);
          return -1;
        }
        if (k != ‘p’)
        {
          pool_error(“read_password_packet_password: password packet does not start with \”p\””);
          return -1;
        }
        if (pool_read(frontend, &size, sizeof(size)))
        {
          pool_error(“read_password_packet_password: failed to read password packet size”);
          return -1;
        }
      }
      if (pool_read(frontend, password, ntohl(size) – 4))
      {
          pool_error(“read_password_packet: failed to read password (size: %d)”, ntohl(size) – 4);
          return -1;
      }
      *pwdSize=size; //now *pwdSize has password length
      return 0;
    }

  3. Inside function
    static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor)
    add &size as fourth argument to every read_password_packet function call, for example:

    read_password_packet(frontend, protoMajor, password, &size)
  4. Recompile and reinstall pgpool project.

Done. Now. I can login to PostgreSQL 9.0 smoothly through PgPool port: 9999.

Advertisements