PasswordMapping *pwdMapping = NULL;
char buf[1024];
-
if (!username)
ereport(ERROR,
(errmsg("unable to get password, username is NULL")));
if (!passwd_fd)
- ereport(ERROR,
+ {
+ ereport(WARNING,
(errmsg("unable to get password, password file descriptor is NULL")));
-
+ return NULL;
+ }
rewind(passwd_fd);
while (!feof(passwd_fd) && !ferror(passwd_fd))
t = getNextToken(t, &tok);
if (tok)
{
- pwdMapping = palloc(sizeof(PasswordMapping));
+ pwdMapping = palloc0(sizeof(PasswordMapping));
pwdMapping->pgpoolUser.password = tok;
pwdMapping->pgpoolUser.passwordType = get_password_type(pwdMapping->pgpoolUser.password);
- pwdMapping->pgpoolUser.userName = pstrdup(username);
+ pwdMapping->pgpoolUser.userName = (char*) pstrdup(username);
pwdMapping->mappedUser = false;
}
else
return pwdMapping;
}
+void delete_passwordMapping(PasswordMapping *pwdMapping)
+{
+ if (!pwdMapping)
+ return;
+ if (pwdMapping->pgpoolUser.password)
+ pfree(pwdMapping->pgpoolUser.password);
+ if (pwdMapping->pgpoolUser.userName)
+ pfree(pwdMapping->pgpoolUser.userName);
+
+ if (pwdMapping->backendUser.password)
+ pfree(pwdMapping->backendUser.password);
+ if (pwdMapping->backendUser.userName)
+ pfree(pwdMapping->backendUser.userName);
+
+ pfree(pwdMapping);
+}
+
/*
* Delete the entry by username. If specified entry does not exist,
* does nothing.
pool_init_pool_passwd(saved_passwd_filename, pool_passwd_mode);
}
+/*
+ * function first uses the password in the argument, if the
+ * argument is empty string or NULL, it looks for the password
+ * for uset in pool_passwd file.
+ * The returned password is always in plain text and palloc'd (if not null)
+ */
+char *get_pgpool_config_user_password(char *username, char *password_in_config)
+{
+ PasswordType passwordType = PASSWORD_TYPE_UNKNOWN;
+ char *password = NULL;
+ PasswordMapping* password_mapping = NULL;
+ /*
+ * if the password specified in confg is empty strin or NULL
+ * look for the password in pool_passwd file
+ */
+ if (password_in_config == NULL || strlen(password_in_config) == 0)
+ {
+ password_mapping = pool_get_user_credentials(username);
+ if (password_mapping == NULL)
+ {
+ return NULL;
+ }
+ passwordType = password_mapping->pgpoolUser.passwordType;
+ password = password_mapping->pgpoolUser.password;
+ }
+ else
+ {
+ passwordType = get_password_type(password_in_config);
+ password = password_in_config;
+ }
+
+ if (passwordType == PASSWORD_TYPE_AES)
+ {
+ /*
+ * decrypt the stored AES password
+ * for comparing it
+ */
+ password = get_decrypted_password(password);
+ if (password == NULL)
+ {
+ ereport(WARNING,
+ (errmsg("could not get the password for user:%s",username),
+ errdetail("unable to decrypt password from pool_passwd"),
+ errhint("verify the valid pool_key exists")));
+ }
+ else
+ {
+ delete_passwordMapping(password_mapping);
+ /* the password returned by get_decrypted_password() is
+ * already palloc'd */
+ return password;
+ }
+ }
+
+ if (passwordType != PASSWORD_TYPE_PLAINTEXT)
+ {
+ ereport(WARNING,
+ (errmsg("could not get the password for user:%s",username),
+ errdetail("username \"%s\" has invalid password type",username)));
+ password = NULL;
+ }
+ if (password)
+ password = (char*)pstrdup(password);
+
+ delete_passwordMapping(password_mapping);
+
+ return password;
+}
+
#ifndef POOL_PRIVATE
char *get_decrypted_password(const char *shadow_pass)
{
}
#endif
-/*
-* What kind of a password verifier is 'shadow_pass'?
-*/
PasswordType
get_password_type(const char *shadow_pass)
{
return PASSWORD_TYPE_AES;
if (strncmp(shadow_pass, PASSWORD_SCRAM_PREFIX, strlen(PASSWORD_SCRAM_PREFIX)) == 0)
return PASSWORD_TYPE_SCRAM_SHA_256;
+
return PASSWORD_TYPE_PLAINTEXT;
}
#define PASSWORD_MD5_PREFIX "md5"
#define PASSWORD_AES_PREFIX "AES"
#define PASSWORD_SCRAM_PREFIX "SCRAM-SHA-256$"
+#define PASSWORD_TEXT_PREFIX "TEXT"
typedef enum {
POOL_PASSWD_R, /* open pool_passwd in read only mode. used by pgpool-II child main process */
extern void pool_reopen_passwd_file(void);
extern char *get_decrypted_password(const char *shadow_pass);
extern char *read_pool_key(char *key_file_path);
-
+extern char *get_pgpool_config_user_password(char *username, char *password_in_config);
+extern void delete_passwordMapping(PasswordMapping *pwdMapping);
#endif /* POOL_PASSWD_H */
{
retry_cnt = pool_config->health_check_params[node].health_check_max_retries;
+ char *password = get_pgpool_config_user_password(pool_config->health_check_params[node].health_check_user,
+ pool_config->health_check_params[node].health_check_password);
+
do
{
/*
bkinfo->backend_port,
pool_config->health_check_params[node].health_check_database,
pool_config->health_check_params[node].health_check_user,
- pool_config->health_check_params[node].health_check_password, false);
+ password?password:"", false);
if (pool_config->health_check_params[node].health_check_timeout > 0)
{
sleep(pool_config->health_check_params[node].health_check_retry_delay);
}
} while (retry_cnt >= 0);
+
+ if (password)
+ pfree(password);
}
return true;
}
static char *dbname;
int i;
bool all_nodes_healthy = false;
-
+ char *password = get_pgpool_config_user_password(pool_config->health_check_user,
+ pool_config->health_check_password);
/* Do not execute health check during recovery */
if (*InRecovery)
return false;
bkinfo->backend_port,
dbname,
pool_config->health_check_user,
- pool_config->health_check_password, false);
+ password?password:"", false);
ereport(DEBUG1,
(errmsg("persistent DB connection to backend node %d having status %d is successful", i, bkinfo->backend_status)));
discard_persistent_db_connection(slot);
}
+ if (password)
+ pfree(password);
return all_nodes_healthy;
}
#endif
int i;
POOL_NODE_STATUS *status;
int primary = -1;
+ char *password = get_pgpool_config_user_password(pool_config->sr_check_user,
+ pool_config->sr_check_password);
+
/* Streaming replication mode? */
if (!SL_MODE)
bkinfo->backend_port,
pool_config->sr_check_database,
pool_config->sr_check_user,
- pool_config->sr_check_password, true);
+ password?password:"", true);
if (!slots[i])
{
ereport(LOG,
}
}
+ if(password)
+ pfree(password);
+
/* Verify backend status */
status = verify_backend_node_status(slots);
char port_str[16];
PGconn *conn;
char *dbname;
+ char *password = get_pgpool_config_user_password(pool_config->recovery_user,
+ pool_config->recovery_password);
snprintf(port_str, sizeof(port_str),"%d", backend->backend_port);
NULL,
dbname,
pool_config->recovery_user,
- pool_config->recovery_password);
+ password?password:NULL);
r = PQstatus(conn);
PQfinish(conn);
if (r == CONNECTION_OK)
- return;
-
+ {
+ if (password)
+ pfree(password);
+ return;
+ }
ereport(LOG,
(errmsg("checking if postmaster is started"),
errdetail("failed to connect to postmaster on hostname:%s database:%s user:%s",
NULL,
dbname,
pool_config->recovery_user,
- pool_config->recovery_password);
+ password?password:NULL);
r = PQstatus(conn);
PQfinish(conn);
if (r == CONNECTION_OK)
+ {
+ if (password)
+ pfree(password);
return;
+ }
ereport(LOG,
(errmsg("checking if postmaster is started"),
sleep(3);
} while (i++ < WAIT_RETRY_COUNT);
+ if (password)
+ pfree(password);
+
ereport(ERROR,
(errmsg("recovery is checking if postmaster is started"),
errdetail("postmaster on hostname:\"%s\" database:\"%s\" user:\"%s\" failed to start in %d second",
{
char port_str[16];
PGconn *conn;
+ char *password = get_pgpool_config_user_password(pool_config->recovery_user,
+ pool_config->recovery_password);
snprintf(port_str, sizeof(port_str),
"%d", backend->backend_port);
NULL,
"template1",
pool_config->recovery_user,
- pool_config->recovery_password);
+ password?password:"");
+
+ if (password)
+ pfree(password);
if (PQstatus(conn) != CONNECTION_OK)
{
{
int i;
BackendInfo *bkinfo;
-
+
+ char *password = get_pgpool_config_user_password(pool_config->sr_check_user,
+ pool_config->sr_check_password);
+
for (i=0;i<NUM_BACKENDS;i++)
{
if (!VALID_BACKEND(i))
bkinfo->backend_port,
pool_config->sr_check_database,
pool_config->sr_check_user,
- pool_config->sr_check_password, true);
+ password?password:"", true);
}
}
+
+ if(password)
+ pfree(password);
}
/*
{
static char conninfo[1024];
PGconn *conn;
+ char *password = get_pgpool_config_user_password(pool_config->wd_lifecheck_user,
+ pool_config->wd_lifecheck_password);
+
if (strlen(pool_config->wd_lifecheck_dbname) == 0)
{
port,
pool_config->wd_lifecheck_dbname,
pool_config->wd_lifecheck_user,
- pool_config->wd_lifecheck_password,
+ password?password:"",
pool_config->wd_interval / 2 + 1);
conn = PQconnectdb(conninfo);
+ if (password)
+ pfree(password);
+
if (PQstatus(conn) != CONNECTION_OK)
{
ereport(DEBUG1,