archie/prospero/server/pstart.c
2024-05-27 16:13:40 +02:00

161 lines
4.8 KiB
C

/*
* Copyright (c) 1989, 1990, 1991 by the University of Washington
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the files
* <uw-copyright.h> and <usc-copyr.h>
*
* Written by bcn 1989 modified 1989-1991
* modified by bcn 1/19/93 to support new argument conventions for dirsrv
* Modified by swa 7/09/93 to take -p# option to specify a port.
*/
#include <uw-copyright.h>
#include <usc-copyr.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/param.h>
#include <pmachine.h> /* SCOUNIX for socket.h need sys/types.h*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <pwd.h>
#include <unistd.h> /* getuid etc */
#include <pserver.h>
#include <pfs.h> /* For qsscanf */
#include <pprot.h>
char prog[100];
void
main(argc,argv)
int argc;
char *argv[];
{
char *dsargv[11]; /* Args to dirsrv */
int dsargc = 0; /* Count of args to dirsrv */
char prvparg[10]; /* -p%d (%d is file desc) */
char shadowarg[MAXPATHLEN];
char securityarg[MAXPATHLEN];
char datarg[MAXPATHLEN];
char aftparg[MAXPATHLEN];
struct sockaddr_in s_in = {AF_INET};
int prvport = -1;
int alternate_portnum = 0;
int ruid,euid;
struct servent *sp;
struct passwd *pw;
int one = 1;
if (argv[1] && qsscanf(argv[1], "-p#%d", &alternate_portnum) == 1)
++argv, --argc;
if (argc > 2) {
usage:
fprintf(stderr,
"Usage: %s [-p#<alternate-port>] [full-host-name]\n",
argv[0]);
exit(1);
}
strcpy(prog,argv[0]);
ruid = getuid();
euid = geteuid();
/* If root and alternate port wasn't specified, try to bind privileged
port before changing uid */
/* The effective uid needs to be root for bind() to succeed on
the privileged port ; real uid of root isn't enough (bug fixed,
sw@isi.edu, 1 Sept. 1993). */
if(!alternate_portnum && euid == 0) {
assert(P_IS_THIS_THREAD_MASTER()); /*getpwuid MT-Unsafe*/
if ((sp = getservbyname("prospero", "udp")) == 0)
s_in.sin_port = htons((ushort) PROSPERO_PORT);
else s_in.sin_port = sp->s_port;
if ((prvport = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
fprintf(stderr, "pstart: Can't open socket\n");
setsockopt(prvport, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
if (bind(prvport, &s_in, S_AD_SZ) < 0) {
fprintf(stderr, "pstart: Can not bind privileged port\n");
close(prvport);
prvport = -1;
}
}
/* Find the Prospero UID, so we can setuid if we are root */
if((pw = getpwnam(PSRV_USER_ID)) == NULL) {
fprintf(stderr,"%s: Can't find passwd entry for %s.\n",
argv[0],PSRV_USER_ID);
exit(1);
}
/* Don't allow changes to paths unless running as root or */
/* already running as PSRV_USER_ID */
if((ruid != 0) && (ruid != pw->pw_uid) &&
(getenv("PSRV_ROOT") || getenv("PSRV_FSHADOW") ||
getenv("PSRV_FSTORAGE") || getenv("PSRV_FSECURITY") ||
getenv("PSRV_AFTPDIR") ||
getenv("PSRV_AFSDIR") || getenv("PSRV_LOGFILE"))) {
fprintf(stderr,"%s: PSRV_* environment variables set but not authorized.\n",argv[0]);
exit(1);
}
/* Set the uid and gid if necessary */
if((ruid != pw->pw_uid) || (euid != pw->pw_uid)) {
if(setgid(pw->pw_gid)) {
fprintf(stderr,"%s: Can't set gid.\n",argv[0]);
exit(1);
}
if(setuid(pw->pw_uid)) {
fprintf(stderr,"%s: Can't set uid.\n",argv[0]);
exit(1);
}
}
dsargv[0] = "dirsrv"; dsargc++;
/* prvport and alternate_port can't both be specified at once. */
if(prvport >= 0) {
sprintf(prvparg,"-p%d",prvport);
dsargv[dsargc++] = prvparg;
} else if (alternate_portnum) {
sprintf(prvparg,"-p#%d",alternate_portnum);
dsargv[dsargc++] = prvparg;
}
#ifdef P_UNDER_UDIR
sprintf(shadowarg,"-S%s/%s",pw->pw_dir,PSRV_SHADOW);
sprintf(securityarg,"-s%s/%s",pw->pw_dir,PSRV_SECURITY);
sprintf(datarg,"-T%s/%s",pw->pw_dir,PSRV_STORAGE);
dsargv[dsargc++] = shadowarg;
dsargv[dsargc++] = securityarg;
dsargv[dsargc++] = datarg;
#endif P_UNDER_UDIR
#ifdef AFTPUSER
/* Find FTP directory - if error, use AFTPDIRECTORY */
if((pw = getpwnam(AFTPUSER)) != NULL) {
sprintf(aftparg,"-f%s",pw->pw_dir);
dsargv[dsargc++] = aftparg;
}
#endif AFTPUSER
if(argc > 1) {
dsargv[argc++] = "-h";
dsargv[argc++] = argv[1];
}
dsargv[dsargc++] = NULL;
umask(7);
execv(P_DIRSRV_BINARY,dsargv);
/* Execl failed */
exit(1);
}