|
|
@ -5,9 +5,7 @@ |
|
|
|
* wherein you authenticate a user by seeing what IP address the system |
|
|
|
* wherein you authenticate a user by seeing what IP address the system |
|
|
|
* says he comes from and possibly using ident). |
|
|
|
* says he comes from and possibly using ident). |
|
|
|
* |
|
|
|
* |
|
|
|
* |
|
|
|
* $Id: hba.c,v 1.37 1998/12/14 06:50:25 scrappy Exp $ |
|
|
|
* IDENTIFICATION |
|
|
|
|
|
|
|
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.36 1998/10/02 16:18:20 momjian Exp $ |
|
|
|
|
|
|
|
* |
|
|
|
* |
|
|
|
*------------------------------------------------------------------------- |
|
|
|
*------------------------------------------------------------------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -287,7 +285,7 @@ process_hba_record(FILE *file, SockAddr *raddr, const char *user, |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
syntax: |
|
|
|
syntax: |
|
|
|
sprintf(PQerrormsg, |
|
|
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH, |
|
|
|
"process_hba_record: invalid syntax in pg_hba.conf file\n"); |
|
|
|
"process_hba_record: invalid syntax in pg_hba.conf file\n"); |
|
|
|
|
|
|
|
|
|
|
|
fputs(PQerrormsg, stderr); |
|
|
|
fputs(PQerrormsg, stderr); |
|
|
@ -358,28 +356,28 @@ static void |
|
|
|
find_hba_entry(SockAddr *raddr, const char *user, const char *database, |
|
|
|
find_hba_entry(SockAddr *raddr, const char *user, const char *database, |
|
|
|
bool *host_ok_p, UserAuth *userauth_p, char *auth_arg) |
|
|
|
bool *host_ok_p, UserAuth *userauth_p, char *auth_arg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
Read the config file and find an entry that allows connection from |
|
|
|
* Read the config file and find an entry that allows connection from |
|
|
|
host "*raddr" to database "database". If found, return *host_ok_p == true |
|
|
|
* host "*raddr" to database "database". If found, return *host_ok_p == true |
|
|
|
and *userauth_p and *auth_arg representing the contents of that entry. |
|
|
|
* and *userauth_p and *auth_arg representing the contents of that entry. |
|
|
|
|
|
|
|
* |
|
|
|
When a record has invalid syntax, we either ignore it or reject the |
|
|
|
* When a record has invalid syntax, we either ignore it or reject the |
|
|
|
connection (depending on where it's invalid). No message or anything. |
|
|
|
* connection (depending on where it's invalid). No message or anything. |
|
|
|
We need to fix that some day. |
|
|
|
* We need to fix that some day. |
|
|
|
|
|
|
|
* |
|
|
|
If we don't find or can't access the config file, we issue an error |
|
|
|
* If we don't find or can't access the config file, we issue an error |
|
|
|
message and deny the connection. |
|
|
|
* message and deny the connection. |
|
|
|
|
|
|
|
* |
|
|
|
If we find a file by the old name of the config file (pg_hba), we issue |
|
|
|
* If we find a file by the old name of the config file (pg_hba), we issue |
|
|
|
an error message because it probably needs to be converted. He didn't |
|
|
|
* an error message because it probably needs to be converted. He didn't |
|
|
|
follow directions and just installed his old hba file in the new database |
|
|
|
* follow directions and just installed his old hba file in the new database |
|
|
|
system. |
|
|
|
* system. |
|
|
|
|
|
|
|
* |
|
|
|
---------------------------------------------------------------------------*/ |
|
|
|
*/ |
|
|
|
int fd; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int fd, |
|
|
|
|
|
|
|
bufsize; |
|
|
|
FILE *file; /* The config file we have to read */ |
|
|
|
FILE *file; /* The config file we have to read */ |
|
|
|
|
|
|
|
|
|
|
|
char *old_conf_file; |
|
|
|
char *old_conf_file; |
|
|
|
|
|
|
|
|
|
|
|
/* The name of old config file that better not exist. */ |
|
|
|
/* The name of old config file that better not exist. */ |
|
|
@ -388,15 +386,15 @@ find_hba_entry(SockAddr *raddr, const char *user, const char *database, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* put together the full pathname to the old config file */ |
|
|
|
/* put together the full pathname to the old config file */ |
|
|
|
old_conf_file = (char *) palloc((strlen(DataDir) + |
|
|
|
bufsize = (strlen(DataDir) + strlen(OLD_CONF_FILE) + 2) * sizeof(char); |
|
|
|
strlen(OLD_CONF_FILE) + 2) * sizeof(char)); |
|
|
|
old_conf_file = (char *) palloc(bufsize); |
|
|
|
sprintf(old_conf_file, "%s/%s", DataDir, OLD_CONF_FILE); |
|
|
|
snprintf(old_conf_file, bufsize, "%s/%s", DataDir, OLD_CONF_FILE); |
|
|
|
|
|
|
|
|
|
|
|
if ((fd = open(old_conf_file, O_RDONLY, 0)) != -1) |
|
|
|
if ((fd = open(old_conf_file, O_RDONLY, 0)) != -1) |
|
|
|
{ |
|
|
|
{ |
|
|
|
/* Old config file exists. Tell this guy he needs to upgrade. */ |
|
|
|
/* Old config file exists. Tell this guy he needs to upgrade. */ |
|
|
|
close(fd); |
|
|
|
close(fd); |
|
|
|
sprintf(PQerrormsg, |
|
|
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH, |
|
|
|
"A file exists by the name used for host-based authentication " |
|
|
|
"A file exists by the name used for host-based authentication " |
|
|
|
"in prior releases of Postgres (%s). The name and format of " |
|
|
|
"in prior releases of Postgres (%s). The name and format of " |
|
|
|
"the configuration file have changed, so this file should be " |
|
|
|
"the configuration file have changed, so this file should be " |
|
|
@ -407,20 +405,19 @@ find_hba_entry(SockAddr *raddr, const char *user, const char *database, |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
char *conf_file; /* The name of the config file we have to
|
|
|
|
char *conf_file; /* The name of the config file we have to read */ |
|
|
|
* read */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* put together the full pathname to the config file */ |
|
|
|
/* put together the full pathname to the config file */ |
|
|
|
conf_file = (char *) palloc((strlen(DataDir) + |
|
|
|
bufsize = (strlen(DataDir) + strlen(CONF_FILE) + 2) * sizeof(char); |
|
|
|
strlen(CONF_FILE) + 2) * sizeof(char)); |
|
|
|
conf_file = (char *) palloc(bufsize); |
|
|
|
sprintf(conf_file, "%s/%s", DataDir, CONF_FILE); |
|
|
|
snprintf(conf_file, bufsize, "%s/%s", DataDir, CONF_FILE); |
|
|
|
|
|
|
|
|
|
|
|
file = AllocateFile(conf_file, "r"); |
|
|
|
file = AllocateFile(conf_file, "r"); |
|
|
|
if (file == NULL) |
|
|
|
if (file == NULL) |
|
|
|
{ |
|
|
|
{ |
|
|
|
/* The open of the config file failed. */ |
|
|
|
/* The open of the config file failed. */ |
|
|
|
|
|
|
|
|
|
|
|
sprintf(PQerrormsg, |
|
|
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH, |
|
|
|
"find_hba_entry: Host-based authentication config file " |
|
|
|
"find_hba_entry: Host-based authentication config file " |
|
|
|
"does not exist or permissions are not setup correctly! " |
|
|
|
"does not exist or permissions are not setup correctly! " |
|
|
|
"Unable to open file \"%s\".\n", |
|
|
|
"Unable to open file \"%s\".\n", |
|
|
@ -430,8 +427,8 @@ find_hba_entry(SockAddr *raddr, const char *user, const char *database, |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
process_open_config_file(file, raddr, user, database, host_ok_p, userauth_p, |
|
|
|
process_open_config_file(file, raddr, user, database, host_ok_p,
|
|
|
|
auth_arg); |
|
|
|
userauth_p, auth_arg); |
|
|
|
FreeFile(file); |
|
|
|
FreeFile(file); |
|
|
|
} |
|
|
|
} |
|
|
|
pfree(conf_file); |
|
|
|
pfree(conf_file); |
|
|
@ -545,17 +542,14 @@ ident(const struct in_addr remote_ip_addr, const struct in_addr local_ip_addr, |
|
|
|
*ident_failed == true (and *ident_username undefined). |
|
|
|
*ident_failed == true (and *ident_username undefined). |
|
|
|
----------------------------------------------------------------------------*/ |
|
|
|
----------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
|
|
|
|
int sock_fd; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* File descriptor for socket on which we talk to Ident */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int rc; /* Return code from a locally called
|
|
|
|
int sock_fd, /* File descriptor for socket on which we talk to Ident */ |
|
|
|
* function */ |
|
|
|
rc; /* Return code from a locally called function */ |
|
|
|
|
|
|
|
|
|
|
|
sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); |
|
|
|
sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); |
|
|
|
if (sock_fd == -1) |
|
|
|
if (sock_fd == -1) |
|
|
|
{ |
|
|
|
{ |
|
|
|
sprintf(PQerrormsg, |
|
|
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH,
|
|
|
|
"Failed to create socket on which to talk to Ident server. " |
|
|
|
"Failed to create socket on which to talk to Ident server. " |
|
|
|
"socket() returned errno = %s (%d)\n", |
|
|
|
"socket() returned errno = %s (%d)\n", |
|
|
|
strerror(errno), errno); |
|
|
|
strerror(errno), errno); |
|
|
@ -592,7 +586,7 @@ ident(const struct in_addr remote_ip_addr, const struct in_addr local_ip_addr, |
|
|
|
} |
|
|
|
} |
|
|
|
if (rc != 0) |
|
|
|
if (rc != 0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
sprintf(PQerrormsg, |
|
|
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH, |
|
|
|
"Unable to connect to Ident server on the host which is " |
|
|
|
"Unable to connect to Ident server on the host which is " |
|
|
|
"trying to connect to Postgres " |
|
|
|
"trying to connect to Postgres " |
|
|
|
"(IP address %s, Port %d). " |
|
|
|
"(IP address %s, Port %d). " |
|
|
@ -607,12 +601,12 @@ ident(const struct in_addr remote_ip_addr, const struct in_addr local_ip_addr, |
|
|
|
char ident_query[80]; |
|
|
|
char ident_query[80]; |
|
|
|
|
|
|
|
|
|
|
|
/* The query we send to the Ident server */ |
|
|
|
/* The query we send to the Ident server */ |
|
|
|
sprintf(ident_query, "%d,%d\n", |
|
|
|
snprintf(ident_query, 80, "%d,%d\n", |
|
|
|
ntohs(remote_port), ntohs(local_port)); |
|
|
|
ntohs(remote_port), ntohs(local_port)); |
|
|
|
rc = send(sock_fd, ident_query, strlen(ident_query), 0); |
|
|
|
rc = send(sock_fd, ident_query, strlen(ident_query), 0); |
|
|
|
if (rc < 0) |
|
|
|
if (rc < 0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
sprintf(PQerrormsg, |
|
|
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH, |
|
|
|
"Unable to send query to Ident server on the host which is " |
|
|
|
"Unable to send query to Ident server on the host which is " |
|
|
|
"trying to connect to Postgres (Host %s, Port %d)," |
|
|
|
"trying to connect to Postgres (Host %s, Port %d)," |
|
|
|
"even though we successfully connected to it. " |
|
|
|
"even though we successfully connected to it. " |
|
|
@ -629,7 +623,7 @@ ident(const struct in_addr remote_ip_addr, const struct in_addr local_ip_addr, |
|
|
|
rc = recv(sock_fd, ident_response, sizeof(ident_response) - 1, 0); |
|
|
|
rc = recv(sock_fd, ident_response, sizeof(ident_response) - 1, 0); |
|
|
|
if (rc < 0) |
|
|
|
if (rc < 0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
sprintf(PQerrormsg, |
|
|
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH, |
|
|
|
"Unable to receive response from Ident server " |
|
|
|
"Unable to receive response from Ident server " |
|
|
|
"on the host which is " |
|
|
|
"on the host which is " |
|
|
|
"trying to connect to Postgres (Host %s, Port %d)," |
|
|
|
"trying to connect to Postgres (Host %s, Port %d)," |
|
|
@ -694,7 +688,8 @@ parse_map_record(FILE *file, |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
sprintf(PQerrormsg, "Incomplete line in pg_ident: %s", file_map); |
|
|
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH,
|
|
|
|
|
|
|
|
"Incomplete line in pg_ident: %s", file_map); |
|
|
|
fputs(PQerrormsg, stderr); |
|
|
|
fputs(PQerrormsg, stderr); |
|
|
|
pqdebug("%s", PQerrormsg); |
|
|
|
pqdebug("%s", PQerrormsg); |
|
|
|
} |
|
|
|
} |
|
|
@ -776,7 +771,7 @@ verify_against_usermap(const char *pguser, |
|
|
|
if (usermap_name[0] == '\0') |
|
|
|
if (usermap_name[0] == '\0') |
|
|
|
{ |
|
|
|
{ |
|
|
|
*checks_out_p = false; |
|
|
|
*checks_out_p = false; |
|
|
|
sprintf(PQerrormsg, |
|
|
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH, |
|
|
|
"verify_against_usermap: hba configuration file does not " |
|
|
|
"verify_against_usermap: hba configuration file does not " |
|
|
|
"have the usermap field filled in in the entry that pertains " |
|
|
|
"have the usermap field filled in in the entry that pertains " |
|
|
|
"to this connection. That field is essential for Ident-based " |
|
|
|
"to this connection. That field is essential for Ident-based " |
|
|
@ -787,21 +782,24 @@ verify_against_usermap(const char *pguser, |
|
|
|
else if (strcmp(usermap_name, "sameuser") == 0) |
|
|
|
else if (strcmp(usermap_name, "sameuser") == 0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (strcmp(ident_username, pguser) == 0) |
|
|
|
if (strcmp(ident_username, pguser) == 0) |
|
|
|
|
|
|
|
{ |
|
|
|
*checks_out_p = true; |
|
|
|
*checks_out_p = true; |
|
|
|
|
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
*checks_out_p = false; |
|
|
|
*checks_out_p = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
FILE *file; /* The map file we have to read */ |
|
|
|
FILE *file; /* The map file we have to read */ |
|
|
|
|
|
|
|
char *map_file; /* The name of the map file we have to read */ |
|
|
|
char *map_file; /* The name of the map file we have to
|
|
|
|
int bufsize; |
|
|
|
* read */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* put together the full pathname to the map file */ |
|
|
|
/* put together the full pathname to the map file */ |
|
|
|
map_file = (char *) palloc((strlen(DataDir) + |
|
|
|
bufsize = (strlen(DataDir) + strlen(MAP_FILE) + 2) * sizeof(char); |
|
|
|
strlen(MAP_FILE) + 2) * sizeof(char)); |
|
|
|
map_file = (char *) palloc(bufsize); |
|
|
|
sprintf(map_file, "%s/%s", DataDir, MAP_FILE); |
|
|
|
snprintf(map_file, bufsize, "%s/%s", DataDir, MAP_FILE); |
|
|
|
|
|
|
|
|
|
|
|
file = AllocateFile(map_file, "r"); |
|
|
|
file = AllocateFile(map_file, "r"); |
|
|
|
if (file == NULL) |
|
|
|
if (file == NULL) |
|
|
@ -810,7 +808,7 @@ verify_against_usermap(const char *pguser, |
|
|
|
|
|
|
|
|
|
|
|
*checks_out_p = false; |
|
|
|
*checks_out_p = false; |
|
|
|
|
|
|
|
|
|
|
|
sprintf(PQerrormsg, |
|
|
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH, |
|
|
|
"verify_against_usermap: usermap file for Ident-based " |
|
|
|
"verify_against_usermap: usermap file for Ident-based " |
|
|
|
"authentication " |
|
|
|
"authentication " |
|
|
|
"does not exist or permissions are not setup correctly! " |
|
|
|
"does not exist or permissions are not setup correctly! " |
|
|
@ -960,22 +958,26 @@ GetCharSetByHost(char *TableName, int host, const char *DataDir) |
|
|
|
BaseCharset[MAX_TOKEN], |
|
|
|
BaseCharset[MAX_TOKEN], |
|
|
|
OrigCharset[MAX_TOKEN], |
|
|
|
OrigCharset[MAX_TOKEN], |
|
|
|
DestCharset[MAX_TOKEN], |
|
|
|
DestCharset[MAX_TOKEN], |
|
|
|
HostCharset[MAX_TOKEN]; |
|
|
|
HostCharset[MAX_TOKEN], |
|
|
|
char c, |
|
|
|
c, |
|
|
|
eof = false; |
|
|
|
eof = false, |
|
|
|
char *map_file; |
|
|
|
*map_file; |
|
|
|
int key = 0, |
|
|
|
int key = 0, |
|
|
|
i; |
|
|
|
ChIndex = 0, |
|
|
|
|
|
|
|
i, |
|
|
|
|
|
|
|
bufsize; |
|
|
|
|
|
|
|
|
|
|
|
struct CharsetItem *ChArray[MAX_CHARSETS]; |
|
|
|
struct CharsetItem *ChArray[MAX_CHARSETS]; |
|
|
|
int ChIndex = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*TableName = '\0'; |
|
|
|
*TableName = '\0'; |
|
|
|
map_file = (char *) malloc((strlen(DataDir) + |
|
|
|
bufsize = (strlen(DataDir) + strlen(CHARSET_FILE) + 2) * sizeof(char); |
|
|
|
strlen(CHARSET_FILE) + 2) * sizeof(char)); |
|
|
|
map_file = (char *) palloc(bufsize); |
|
|
|
sprintf(map_file, "%s/%s", DataDir, CHARSET_FILE); |
|
|
|
snprintf(map_file, bufsize, "%s/%s", DataDir, CHARSET_FILE); |
|
|
|
file = fopen(map_file, "r"); |
|
|
|
file = fopen(map_file, "r"); |
|
|
|
if (file == NULL) |
|
|
|
if (file == NULL) |
|
|
|
|
|
|
|
{ |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
while (!eof) |
|
|
|
while (!eof) |
|
|
|
{ |
|
|
|
{ |
|
|
|
c = getc(file); |
|
|
|
c = getc(file); |
|
|
@ -1035,7 +1037,8 @@ GetCharSetByHost(char *TableName, int host, const char *DataDir) |
|
|
|
next_token(file, buf, sizeof(buf)); |
|
|
|
next_token(file, buf, sizeof(buf)); |
|
|
|
if (buf[0] != '\0') |
|
|
|
if (buf[0] != '\0') |
|
|
|
{ |
|
|
|
{ |
|
|
|
ChArray[ChIndex] = (struct CharsetItem *) malloc(sizeof(struct CharsetItem)); |
|
|
|
ChArray[ChIndex] =
|
|
|
|
|
|
|
|
(struct CharsetItem *) palloc(sizeof(struct CharsetItem)); |
|
|
|
strcpy(ChArray[ChIndex]->Orig, OrigCharset); |
|
|
|
strcpy(ChArray[ChIndex]->Orig, OrigCharset); |
|
|
|
strcpy(ChArray[ChIndex]->Dest, DestCharset); |
|
|
|
strcpy(ChArray[ChIndex]->Dest, DestCharset); |
|
|
|
strcpy(ChArray[ChIndex]->Table, buf); |
|
|
|
strcpy(ChArray[ChIndex]->Table, buf); |
|
|
@ -1051,14 +1054,14 @@ GetCharSetByHost(char *TableName, int host, const char *DataDir) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
fclose(file); |
|
|
|
fclose(file); |
|
|
|
free(map_file); |
|
|
|
pfree(map_file); |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < ChIndex; i++) |
|
|
|
for (i = 0; i < ChIndex; i++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!strcasecmp(BaseCharset, ChArray[i]->Orig) && |
|
|
|
if (!strcasecmp(BaseCharset, ChArray[i]->Orig) && |
|
|
|
!strcasecmp(HostCharset, ChArray[i]->Dest)) |
|
|
|
!strcasecmp(HostCharset, ChArray[i]->Dest)) |
|
|
|
strncpy(TableName, ChArray[i]->Table, 79); |
|
|
|
strncpy(TableName, ChArray[i]->Table, 79); |
|
|
|
free((struct CharsetItem *) ChArray[i]); |
|
|
|
pfree((struct CharsetItem *) ChArray[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|