diff options
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/rpc.statd/procs.c | 132 | ||||
-rw-r--r-- | usr.sbin/rpc.statd/statd.h | 1 |
2 files changed, 95 insertions, 38 deletions
diff --git a/usr.sbin/rpc.statd/procs.c b/usr.sbin/rpc.statd/procs.c index b508f33..bd58b1d 100644 --- a/usr.sbin/rpc.statd/procs.c +++ b/usr.sbin/rpc.statd/procs.c @@ -43,11 +43,51 @@ static const char rcsid[] = #include <unistd.h> #include <rpc/rpc.h> #include <syslog.h> +#include <vis.h> #include <netdb.h> /* for gethostbyname() */ #include "statd.h" -/* sm_stat_1 --------------------------------------------------------------- */ +/* sm_check_hostname -------------------------------------------------------- */ +/* + * Purpose: Check `mon_name' member of sm_name struct to ensure that the array + * consists only of printable characters. + * + * Returns: TRUE if hostname is good. FALSE if hostname contains binary or + * otherwise non-printable characters. + * + * Notes: Will syslog(3) to warn of corrupt hostname. + */ + +int sm_check_hostname(struct svc_req *req, char *arg) +{ + int len, dstlen, ret; + struct sockaddr_in *claddr; + char *dst; + + len = strlen(arg); + dstlen = (4 * len) + 1; + dst = malloc(dstlen); + claddr = svc_getcaller(req->rq_xprt); + ret = 1; + + if (claddr == NULL || dst == NULL) + { + ret = 0; + } + else if (strvis(dst, arg, VIS_WHITE) != len) + { + syslog(LOG_ERR, + "sm_stat: client %s hostname %s contained invalid characters.", + inet_ntoa(claddr->sin_addr), + dst); + ret = 0; + } + free(dst); + return (ret); +} + +/* sm_stat_1 --------------------------------------------------------------- */ /* Purpose: RPC call to enquire if a host can be monitored Returns: TRUE for any hostname that can be looked up to give @@ -57,16 +97,25 @@ static const char rcsid[] = struct sm_stat_res *sm_stat_1_svc(sm_name *arg, struct svc_req *req) { static sm_stat_res res; + static int err; - if (debug) syslog(LOG_DEBUG, "stat called for host %s", arg->mon_name); - - if (gethostbyname(arg->mon_name)) res.res_stat = stat_succ; - else - { - syslog(LOG_ERR, "invalid hostname to sm_stat: %s", arg->mon_name); + err = 1; + if ((err = sm_check_hostname(req, arg->mon_name)) == 0) + { res.res_stat = stat_fail; } - + if (err != 0) + { + if (debug) + syslog(LOG_DEBUG, "stat called for host %s", arg->mon_name); + if (gethostbyname(arg->mon_name)) + res.res_stat = stat_succ; + else + { + syslog(LOG_ERR, "invalid hostname to sm_stat: %s", arg->mon_name); + res.res_stat = stat_fail; + } + } res.state = status_info->ourState; return (&res); } @@ -84,49 +133,56 @@ struct sm_stat_res *sm_mon_1_svc(mon *arg, struct svc_req *req) { static sm_stat_res res; HostInfo *hp; + static int err; MonList *lp; - if (debug) + if ((err = sm_check_hostname(req, arg->mon_id.mon_name)) == 0) { - syslog(LOG_DEBUG, "monitor request for host %s", arg->mon_id.mon_name); - syslog(LOG_DEBUG, "recall host: %s prog: %d ver: %d proc: %d", - arg->mon_id.mon_name, arg->mon_id.my_id.my_name, - arg->mon_id.my_id.my_prog, arg->mon_id.my_id.my_vers, - arg->mon_id.my_id.my_proc); + res.res_stat = stat_fail; } - res.res_stat = stat_fail; /* Assume fail until set otherwise */ - res.state = status_info->ourState; - - /* Find existing host entry, or create one if not found */ - /* If find_host() fails, it will have logged the error already. */ - if (!gethostbyname(arg->mon_id.mon_name)) + if (err != 0) { - syslog(LOG_ERR, "Invalid hostname to sm_mon: %s", arg->mon_id.mon_name); - } - else if ((hp = find_host(arg->mon_id.mon_name, TRUE))) - { - lp = (MonList *)malloc(sizeof(MonList)); - if (!lp) + if (debug) { - syslog(LOG_ERR, "Out of memory"); + syslog(LOG_DEBUG, "monitor request for host %s", arg->mon_id.mon_name); + syslog(LOG_DEBUG, "recall host: %s prog: %d ver: %d proc: %d", + arg->mon_id.mon_name, arg->mon_id.my_id.my_name, + arg->mon_id.my_id.my_prog, arg->mon_id.my_id.my_vers, + arg->mon_id.my_id.my_proc); } - else + res.res_stat = stat_fail; /* Assume fail until set otherwise */ + res.state = status_info->ourState; + + /* Find existing host entry, or create one if not found */ + /* If find_host() fails, it will have logged the error already. */ + if (!gethostbyname(arg->mon_id.mon_name)) + { + syslog(LOG_ERR, "Invalid hostname to sm_mon: %s", arg->mon_id.mon_name); + } + else if ((hp = find_host(arg->mon_id.mon_name, TRUE))) { - strncpy(lp->notifyHost, arg->mon_id.my_id.my_name, SM_MAXSTRLEN); - lp->notifyProg = arg->mon_id.my_id.my_prog; - lp->notifyVers = arg->mon_id.my_id.my_vers; - lp->notifyProc = arg->mon_id.my_id.my_proc; - memcpy(lp->notifyData, arg->priv, sizeof(lp->notifyData)); + lp = (MonList *)malloc(sizeof(MonList)); + if (!lp) + { + syslog(LOG_ERR, "Out of memory"); + } + else + { + strncpy(lp->notifyHost, arg->mon_id.my_id.my_name, SM_MAXSTRLEN); + lp->notifyProg = arg->mon_id.my_id.my_prog; + lp->notifyVers = arg->mon_id.my_id.my_vers; + lp->notifyProc = arg->mon_id.my_id.my_proc; + memcpy(lp->notifyData, arg->priv, sizeof(lp->notifyData)); - lp->next = hp->monList; - hp->monList = lp; - sync_file(); + lp->next = hp->monList; + hp->monList = lp; + sync_file(); - res.res_stat = stat_succ; /* Report success */ + res.res_stat = stat_succ; /* Report success */ + } } } - return (&res); } diff --git a/usr.sbin/rpc.statd/statd.h b/usr.sbin/rpc.statd/statd.h index 7bf7b1d..b3c5d41 100644 --- a/usr.sbin/rpc.statd/statd.h +++ b/usr.sbin/rpc.statd/statd.h @@ -108,3 +108,4 @@ extern HostInfo *find_host(char * /*hostname*/, int /*create*/); extern void init_file(char * /*filename*/); extern void notify_hosts(void); extern void sync_file(void); +extern int sm_check_hostname(struct svc_req *req, char *arg); |