freebsd-dev/usr.sbin/mount_portalfs/pt_tcp.c
gpalmer 58cb77c258 Bugfixes :
- in mount_portal.c: included catching of SIGHUP to get portald to
  re-read the config file.

  - in mount_portal.c: in SIGCHLD handler the return values checked from
  waitpid were wrong. Note. this routine was written correclty according
  to the manual page for 4.4BSD, but waitpid does not exhibit this
  behaviour. It is not returning 0 when WNOHANG is specified. I havent
  checked this properly.

  - in mount_portal.c: initialized the fdset for the select properly.

  - in mount_portal.c: corrected poor casting in the select.

  - in mount_portal.c: changed a break; to exit (0); so that the
  children die after doing the hard work, this stops the select: bad
  file descriptor messages.

  - in pt_file.c: the kernel passes kernel style open flags to the
  portal code which aren't compatible with "normal" O_ flags. I have
  adjusted these in pt_file.c. In general I think the portal fs code
  and portal_cred structure need changing to pass to the portald
  the right style of flags _and_ the permissions.

  - in pt_tcp.c: a few mistakes in typing of the socket structures,
  getservbyname returns the port number as an int but sockaddr wants
  the port number as an u_short.

  - in pt_tcp.c: someone wrote this on a VAX/Sun whatever and forget
  about byte ordering!! I've included a few htons about the place.

  - in all the above I have sprinkled a few more debugging printf's.

Submitted by:	"Duncan McL Barclay" <dmlb@ohm.york.ac.uk
1995-04-19 12:24:08 +00:00

165 lines
4.3 KiB
C

/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pt_tcp.c 8.3 (Berkeley) 3/27/94
*
* $Id: pt_tcp.c,v 1.1.1.1 1994/05/26 06:34:34 rgrimes Exp $
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/syslog.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "portald.h"
/*
* Key will be tcp/host/port[/"priv"]
* Create a TCP socket connected to the
* requested host and port.
* Some trailing suffix values have special meanings.
* An unrecognised suffix is an error.
*/
int portal_tcp(pcr, key, v, kso, fdp)
struct portal_cred *pcr;
char *key;
char **v;
int kso;
int *fdp;
{
char host[MAXHOSTNAMELEN];
char port[MAXHOSTNAMELEN];
char *p = key + (v[1] ? strlen(v[1]) : 0);
char *q;
struct hostent *hp;
struct servent *sp;
struct in_addr **ipp;
struct in_addr *ip[2];
struct in_addr ina;
u_short s_port;
int priv = 0;
struct sockaddr_in sain;
q = strchr(p, '/');
if (q == 0 || q - p >= sizeof(host))
return (EINVAL);
*q = '\0';
strcpy(host, p);
p = q + 1;
q = strchr(p, '/');
if (q)
*q = '\0';
if (strlen(p) >= sizeof(port))
return (EINVAL);
strcpy(port, p);
if (q) {
p = q + 1;
if (strcmp(p, "priv") == 0) {
if (pcr->pcr_uid == 0)
priv = 1;
else
return (EPERM);
} else {
return (EINVAL);
}
}
hp = gethostbyname(host);
if (hp != 0) {
ipp = (struct in_addr **) hp->h_addr_list;
} else {
ina.s_addr = inet_addr(host);
if (ina.s_addr == INADDR_NONE)
return (EINVAL);
ip[0] = &ina;
ip[1] = 0;
ipp = ip;
}
#ifdef DEBUG
printf ("inet address for %s is %s\n", host, inet_ntoa(*ipp[0]));
#endif
sp = getservbyname(port, "tcp");
if (sp != NULL)
s_port = (u_short)sp->s_port;
else {
s_port = htons ((u_short)strtol (port, (char**)NULL, 10));
if (s_port == 0)
return (EINVAL);
}
#ifdef DEBUG
printf ("port number for %s is %d\n", port, s_port);
#endif
bzero(&sain, sizeof(sain));
sain.sin_len = sizeof(sain);
sain.sin_family = AF_INET;
sain.sin_port = s_port;
while (ipp[0]) {
int so;
if (priv)
so = rresvport((int *) 0);
else
so = socket(AF_INET, SOCK_STREAM, 0);
if (so < 0) {
syslog(LOG_ERR, "socket: %m");
return (errno);
}
sain.sin_addr = *ipp[0];
if (connect(so, (struct sockaddr *) &sain, sizeof(sain)) == 0) {
*fdp = so;
return (0);
}
(void) close(so);
ipp++;
}
return (errno);
}