admserv/cgi-src40/htmladmin.c | 77 ++++++++++++++++++++++-------------
admserv/cgi-src40/statpingserv.c | 84 ++++++++++++++++++++-------------------
2 files changed, 93 insertions(+), 68 deletions(-)
New commits:
commit 26869affd9e594ae71c3a7ad4b7c230c78f4fde2
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Mar 15 17:07:44 2012 -0700
Trac Ticket #307 - htmladmin keeps segfaulting
https://fedorahosted.org/389/ticket/307
Fix Description:
PR_GetHostByName was used to get PRHostEnt in htmladmin, but it
was called only when the first character of host was not digit.
The direct cause of the crash was the PRHostEnt variable to fill
in in PR_GetHostByName was not initialized, thus if the hostname
started with digit, the uninitialized, garbage address in the
variable was accessed, which crashed htmladmin.
This patch removes the hostname check and replaces PR_GetHostByName
with PR_GetAddrInfoByName to support IPv6 environment. Also, to
support numerical address, PR_StringToNetAddr is added before
trying PR_GetAddrInfoByName.
Another cgi statpingserv has the same coding style. It is being
fixed, too.
diff --git a/admserv/cgi-src40/htmladmin.c b/admserv/cgi-src40/htmladmin.c
index a294766..09d0ad0 100644
--- a/admserv/cgi-src40/htmladmin.c
+++ b/admserv/cgi-src40/htmladmin.c
@@ -854,6 +854,7 @@ LDAP *server_bind(const char *securitydir, char *host, int port, int
security, c
return server;
}
+#if 0 /* NOT USED */
/* rate is specified in seconds */
static int get_topology_refresh_rate(AdmldapInfo admInfo) {
@@ -868,7 +869,7 @@ static int get_topology_refresh_rate(AdmldapInfo admInfo) {
return rate;
}
-
+#endif
/* rate is specified in seconds */
static int get_cgi_timeout_rate(AdmldapInfo admInfo) {
@@ -895,38 +896,58 @@ static int get_cgi_timeout_rate(AdmldapInfo admInfo) {
* -1 = unknown error
*/
-int server_status(char *host, int port) {
-
- PRHostEnt *hstruct;
- PRHostEnt hent;
- char buf[PR_NETDB_BUF_SIZE];
+int
+server_status(char *host, int port)
+{
+ PRNetAddr *netaddr = NULL;
PRStatus err;
-
PRFileDesc *req_socket= NULL;
- int retcode;
- PRNetAddr netAddr;
-
- if(!isdigit(host[0])) {
- err = PR_GetHostByName(host,
- buf,
- PR_NETDB_BUF_SIZE,
- &hent);
- if(err == PR_FAILURE)
- return -1;
- }
+ int retcode = 0;
- hstruct = &hent;
- PR_InitializeNetAddr(PR_IpAddrNull, (PRUint16)port, &netAddr);
- netAddr.inet.ip = *((PRUint32*)hstruct->h_addr_list[0]);
-
- req_socket = PR_NewTCPSocket();
- retcode = PR_Connect(req_socket, &netAddr, 10000);
+ if (NULL == host) {
+ return -1;
+ }
- if(retcode != 0)
- return 0;
- else
- return 1;
+ netaddr = (PRNetAddr *)calloc(1, sizeof(PRNetAddr));
+ if (NULL == netaddr) {
+ rpt_err(APP_ERROR, "Failed to allocate PRNetAddr", NULL, NULL);
+ return -1;
+ }
+ err = PR_StringToNetAddr(host, netaddr);
+ if (PR_SUCCESS == err) {
+ PR_InitializeNetAddr(PR_IpAddrNull, (PRUint16)port, netaddr);
+ } else {
+ PRAddrInfo *infop = PR_GetAddrInfoByName(host,
+ PR_AF_UNSPEC, (PR_AI_ADDRCONFIG|PR_AI_NOCANONNAME));
+ if (infop) {
+ void *iter = NULL;
+ memset( netaddr, 0, sizeof( PRNetAddr ));
+ /* need just one address */
+ iter = PR_EnumerateAddrInfo(iter, infop, (PRUint16)port, netaddr);
+ if (NULL == iter) {
+ rpt_err(APP_ERROR, "Failed to enumerate addrinfo", NULL, NULL);
+ retcode = -1;
+ }
+ PR_FreeAddrInfo(infop);
+ } else {
+ rpt_err(APP_ERROR, "Failed to get addrinfo", NULL, NULL);
+ retcode = -1;
+ }
+ }
+ if (retcode < 0) {
+ free(netaddr);
+ return retcode;
+ } else {
+ req_socket = PR_NewTCPSocket();
+ err = PR_Connect(req_socket, netaddr, 10000);
+ free(netaddr);
+ if (PR_SUCCESS == err) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
}
diff --git a/admserv/cgi-src40/statpingserv.c b/admserv/cgi-src40/statpingserv.c
index 363eed3..d6e55f7 100644
--- a/admserv/cgi-src40/statpingserv.c
+++ b/admserv/cgi-src40/statpingserv.c
@@ -59,16 +59,13 @@ int main(int argc, char *argv[])
char *m;
char *qs = getenv("QUERY_STRING");
- PRHostEnt hent;
- char buf[PR_NETDB_BUF_SIZE];
PRStatus err;
char gifbuf[BUFSIZ];
PRInt32 bytes;
PRFileDesc *req_socket= NULL;
- int retcode;
- PRNetAddr netAddr;
-
+ int retcode = 0;
+ PRNetAddr *netaddr = NULL;
char *result;
char *host;
int port;
@@ -79,13 +76,6 @@ int main(int argc, char *argv[])
struct PRFileInfo64 prfileinfo;
m = getenv("REQUEST_METHOD");
- /*
- {
- int d=1;
- while(d>0)
- {;}
- }
- */
if(!strcmp(m, "GET")) {
if(qs)
@@ -93,54 +83,68 @@ int main(int argc, char *argv[])
result = get_cgi_var("result", NULL, NULL);
host = get_cgi_var("host", NULL, NULL);
- portstr = get_cgi_var("port", NULL, NULL);
- if (portstr) {
- port = atoi(portstr);
- } else {
- port = 0;
- }
+ portstr = get_cgi_var("port", NULL, NULL);
+ if (portstr) {
+ port = atoi(portstr);
+ } else {
+ port = 0;
+ }
if(result && !strcmp(result, "text"))
fprintf(stdout, "Content-type: text/html\n");
else
fprintf(stdout, "Content-type: image/gif\n");
- if (!host || !port) {
- rpt_err(APP_ERROR, "Invalid hostname and/or port number!", NULL, NULL);
- }
- if(!isdigit(host[0])) {
- err = PR_GetHostByName(host, buf, sizeof(buf), &hent);
- if(err == PR_FAILURE) {
- rpt_err(APP_ERROR, "Cannot resolve host name!", NULL, NULL);
- }
-
- PR_InitializeNetAddr(PR_IpAddrNull, (PRUint16)port, &netAddr);
- memcpy((void *) &netAddr.inet.ip, (void const *) hent.h_addr_list[0],
sizeof(netAddr.inet.ip));
+ if (!host || !port) {
+ rpt_err(APP_ERROR, "Invalid hostname and/or port number!", NULL, NULL);
+ return -1;
+ }
+ netaddr = (PRNetAddr *)calloc(1, sizeof(PRNetAddr));
+ if (NULL == netaddr) {
+ rpt_err(APP_ERROR, "Failed to allocate PRNetAddr", NULL, NULL);
+ return -1;
+ }
+ err = PR_StringToNetAddr(host, netaddr);
+ if (PR_SUCCESS == err) {
+ PR_InitializeNetAddr(PR_IpAddrNull, (PRUint16)port, netaddr);
} else {
- PR_InitializeNetAddr(PR_IpAddrNull, (PRUint16)port, &netAddr);
- err = PR_StringToNetAddr(host, &netAddr);
- if(err == PR_FAILURE) {
- rpt_err(APP_ERROR, "Cannot parse host address!", NULL, NULL);
+ PRAddrInfo *infop = PR_GetAddrInfoByName(host,
+ PR_AF_UNSPEC, (PR_AI_ADDRCONFIG|PR_AI_NOCANONNAME));
+ if (infop) {
+ void *iter = NULL;
+ memset( netaddr, 0, sizeof( PRNetAddr ));
+ /* need just one address */
+ iter = PR_EnumerateAddrInfo(iter, infop, (PRUint16)port, netaddr);
+ if (NULL == iter) {
+ rpt_err(APP_ERROR, "Failed to enumerate addrinfo", NULL, NULL);
+ retcode = -1;
+ }
+ PR_FreeAddrInfo(infop);
+ } else {
+ rpt_err(APP_ERROR, "Failed to get addrinfo", NULL, NULL);
+ retcode = -1;
}
}
- req_socket = PR_NewTCPSocket();
-
- retcode = PR_Connect(req_socket, &netAddr, 10000);
+ if (retcode > -1) {
+ req_socket = PR_NewTCPSocket();
+ retcode = PR_Connect(req_socket, netaddr, 10000);
+ }
+ free(netaddr);
if (retcode != 0) {
/* SERVER IS DOWN - output the OFF button */
if(result && !strcmp(result, "text")) {
- rpt_success("The server is DOWN.");
- return 1;
+ rpt_success("The server is DOWN.");
+ return 1;
}
file = PR_smprintf("%s/togoff.gif", ICONDIR);
}
else {
/* SERVER IS RUNNING - output of ON button */
if(result && !strcmp(result, "text")) {
- rpt_success("The server is UP.");
- return 1;
+ rpt_success("The server is UP.");
+ return 1;
}
file = PR_smprintf("%s/togon.gif", ICONDIR);
}