--- postgresql-7.1.2.orig/src/backend/libpq/hba.c Mon Jul 2 16:25:56 2001 +++ postgresql-7.1.2/src/backend/libpq/hba.c Tue Jul 3 14:01:20 2001 @@ -17,6 +17,7 @@ #include #include #include +#include #include "postgres.h" @@ -31,6 +32,9 @@ #define IDENT_USERNAME_MAX 512 /* Max size of username ident server can return */ +#define MAX_HOSTNAME 1024 + /* Max size of hostname */ + /* Some standard C libraries, including GNU, have an isblank() function. Others, including Solaris, do not. So we have our own. @@ -256,8 +260,38 @@ if (!inet_aton(buf, &file_ip_addr)) { + if (!strncmp(buf, "samehost", 8)) /* samehost.somedomain */ + { + struct hostent* he; + char host[MAX_HOSTNAME]; + + strcpy(host, port->user); + if(strlen(buf) > 8) + { + strncat(host, buf + 8, MAX_HOSTNAME - 1 - strlen(host)); + host[MAX_HOSTNAME - 1] = '\0'; + } + he = gethostbyname(host); + + if(he != NULL) + { + file_ip_addr.s_addr = *(int*)he->h_addr; + } + else /* Error or Host not found */ + { + read_through_eol(file); + snprintf(PQerrormsg, PQERRORMSG_LENGTH, + "process_hba_record: samehost '%s' not found in pg_hba.conf file\n", host); + fputs(PQerrormsg, stderr); + pqdebug("%s", PQerrormsg); + return; + } + } + else + { read_through_eol(file); goto syntax; + } } /* Read the mask field. */ @@ -299,6 +333,301 @@ (strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) || port->raddr.sa.sa_family != AF_INET || ((file_ip_addr.s_addr ^ port->raddr.in.sin_addr.s_addr) & mask.s_addr) != 0x0000) + return; + } + else if (strcmp(buf, "virtualhost") == 0 || strcmp(buf, "virtualhostssl") == 0) + { + struct in_addr file_ip_addr, + mask; + bool discard = 0;/* Discard this entry */ + +#ifdef USE_SSL + /* If SSL, then check that we are on SSL */ + if (strcmp(buf, "virtualhostssl") == 0) + { + if (!port->ssl) + discard = 1; + + /* Placeholder to require specific SSL level, perhaps? */ + /* Or a client certificate */ + + /* Since we were on SSL, proceed as with normal 'host' mode */ + } +#else + /* If not SSL, we don't support this */ + if (strcmp(buf, "virtualhostssl") == 0) + goto syntax; +#endif + + /* Get the database. */ + + next_token(file, db, sizeof(db)); + + if (db[0] == '\0') + goto syntax; + + /* Read the IP address field. */ + + next_token(file, buf, sizeof(buf)); + + if (buf[0] == '\0') + goto syntax; + + /* Remember the IP address field and go get mask field. */ + + if (!inet_aton(buf, &file_ip_addr)) + { + if (!strncmp(buf, "samehost", 8)) /* samehost.somedomain */ + { + struct hostent* he; + char host[MAX_HOSTNAME]; + + strcpy(host, port->user); + if(strlen(buf) > 8) + { + strncat(host, buf + 8, MAX_HOSTNAME - 1 - strlen(host)); + host[MAX_HOSTNAME - 1] = '\0'; + } + he = gethostbyname(host); + + if(he != NULL) + { + file_ip_addr.s_addr = *(int*)he->h_addr; + } + else /* Error or Host not found */ + { + read_through_eol(file); + snprintf(PQerrormsg, PQERRORMSG_LENGTH, + "process_hba_record: samehost '%s' not found in pg_hba.conf file\n", host); + fputs(PQerrormsg, stderr); + pqdebug("%s", PQerrormsg); + return; + } + } + else + { + read_through_eol(file); + goto syntax; + } + } + + /* Read the mask field. */ + + next_token(file, buf, sizeof(buf)); + + if (buf[0] == '\0') + goto syntax; + + if (!inet_aton(buf, &mask)) + { + read_through_eol(file); + goto syntax; + } + + /* + * This is the record we're looking for. Read the rest of the + * info from it. + */ + + read_hba_entry2(file, &port->auth_method, port->auth_arg, error_p); + + if (*error_p) + goto syntax; + + /* + * If told to discard earlier. Moved down here so we don't get + * "out of sync" with the file. + */ + if (discard) + return; + + /* + * If this record isn't for our database, or this is the wrong + * sort of connection, ignore it. + */ + + if ((strcmp(db, port->database) != 0 && strcmp(db, "all") != 0 && + (strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) || + port->laddr.sa.sa_family != AF_INET || + ((file_ip_addr.s_addr ^ port->laddr.in.sin_addr.s_addr) & mask.s_addr) != 0x0000) + return; + } + else if (strcmp(buf, "connection") == 0 || strcmp(buf, "connectionssl") == 0) + { + struct in_addr file_ip_raddr, + rmask; + struct in_addr file_ip_laddr, + lmask; + bool discard = 0;/* Discard this entry */ + +#ifdef USE_SSL + /* If SSL, then check that we are on SSL */ + if (strcmp(buf, "connectionssl") == 0) + { + if (!port->ssl) + discard = 1; + + /* Placeholder to require specific SSL level, perhaps? */ + /* Or a client certificate */ + + /* Since we were on SSL, proceed as with normal 'host' mode */ + } +#else + /* If not SSL, we don't support this */ + if (strcmp(buf, "connectionssl") == 0) + goto syntax; +#endif + + /* Get the database. */ + + next_token(file, db, sizeof(db)); + + if (db[0] == '\0') + goto syntax; + + /* Read the remote IP address field. */ + + next_token(file, buf, sizeof(buf)); + + if (buf[0] == '\0') + goto syntax; + + /* Remember the IP address field and go get mask field. */ + + if (!inet_aton(buf, &file_ip_raddr)) + { + if (!strncmp(buf, "samehost", 8)) /* samehost.somedomain */ + { + struct hostent* he; + char host[MAX_HOSTNAME]; + + strcpy(host, port->user); + if(strlen(buf) > 8) + { + strncat(host, buf + 8, MAX_HOSTNAME - 1 - strlen(host)); + host[MAX_HOSTNAME - 1] = '\0'; + } + he = gethostbyname(host); + + if(he != NULL) + { + file_ip_raddr.s_addr = *(int*)he->h_addr; + } + else /* Error or Host not found */ + { + read_through_eol(file); + snprintf(PQerrormsg, PQERRORMSG_LENGTH, + "process_hba_record: samehost '%s' not found in pg_hba.conf file\n", host); + fputs(PQerrormsg, stderr); + pqdebug("%s", PQerrormsg); + return; + } + } + else + { + read_through_eol(file); + goto syntax; + } + } + + /* Read the remote mask field. */ + + next_token(file, buf, sizeof(buf)); + + if (buf[0] == '\0') + goto syntax; + + if (!inet_aton(buf, &rmask)) + { + read_through_eol(file); + goto syntax; + } + + /* Read the local IP address field. */ + + next_token(file, buf, sizeof(buf)); + + if (buf[0] == '\0') + goto syntax; + + /* Remember the IP address field and go get mask field. */ + + if (!inet_aton(buf, &file_ip_laddr)) + { + if (!strncmp(buf, "samehost", 8)) /* samehost.somedomain */ + { + struct hostent* he; + char host[MAX_HOSTNAME]; + + strcpy(host, port->user); + if(strlen(buf) > 8) + { + strncat(host, buf + 8, MAX_HOSTNAME - 1 - strlen(host)); + host[MAX_HOSTNAME - 1] = '\0'; + } + he = gethostbyname(host); + + if(he != NULL) + { + file_ip_laddr.s_addr = *(int*)he->h_addr; + } + else /* Error or Host not found */ + { + read_through_eol(file); + snprintf(PQerrormsg, PQERRORMSG_LENGTH, + "process_hba_record: samehost '%s' not found in pg_hba.conf file\n", host); + fputs(PQerrormsg, stderr); + pqdebug("%s", PQerrormsg); + return; + } + } + else + { + read_through_eol(file); + goto syntax; + } + } + + /* Read the source mask field. */ + + next_token(file, buf, sizeof(buf)); + + if (buf[0] == '\0') + goto syntax; + + if (!inet_aton(buf, &lmask)) + { + read_through_eol(file); + goto syntax; + } + + /* + * This is the record we're looking for. Read the rest of the + * info from it. + */ + + read_hba_entry2(file, &port->auth_method, port->auth_arg, error_p); + + if (*error_p) + goto syntax; + + /* + * If told to discard earlier. Moved down here so we don't get + * "out of sync" with the file. + */ + if (discard) + return; + + /* + * If this record isn't for our database, or this is the wrong + * sort of connection, ignore it. + */ + + if ((strcmp(db, port->database) != 0 && strcmp(db, "all") != 0 && + (strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) || + port->laddr.sa.sa_family != AF_INET || + ((file_ip_raddr.s_addr ^ port->raddr.in.sin_addr.s_addr) & rmask.s_addr) != 0x0000 || + ((file_ip_laddr.s_addr ^ port->laddr.in.sin_addr.s_addr) & lmask.s_addr) != 0x0000) return; } else