home *** CD-ROM | disk | FTP | other *** search
- /*
- * mountd This program handles RPC "NFS" mount requests.
- *
- * Usage: [rpc.]mountd [-dhnpv] [-f authfile]
- *
- * Authors: Mark A. Shand, May 1988
- * Donald J. Becker, <becker@super.org>
- * Rick Sladkey, <jrs@world.std.com>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * Copyright 1988 Mark A. Shand
- * This software maybe be used for any purpose provided
- * the above copyright notice is retained. It is supplied
- * as is, with no warranty expressed or implied.
- */
-
- #include "nfsd.h"
- #include "getopt.h"
-
- #ifndef HAVE_RPCGEN_C
- #define mountproc_null_1_svc mountproc_null_1
- #define mountproc_mnt_1_svc mountproc_mnt_1
- #define mountproc_dump_1_svc mountproc_dump_1
- #define mountproc_umnt_1_svc mountproc_umnt_1
- #define mountproc_umntall_1_svc mountproc_umntall_1
- #define mountproc_export_1_svc mountproc_export_1
- #define mountproc_exportall_1_svc mountproc_exportall_1
- #endif
-
- char argbuf[MNTPATHLEN + 1];
- char *auth_file = NULL;
- #ifndef HAVE_RPCGEN_I
- int _rpcpmstart = 0;
- #endif
-
- static _PRO(void usage, (FILE *, int));
- extern _PRO(int mountd_main, (int, char **));
-
- extern char version[];
- static char *program_name;
- static struct option longopts[] =
- {
- { "debug", 0, 0, 'd' },
- { "exports-file", 1, 0, 'f' },
- { "help", 0, 0, 'h' },
- { "allow-non-root", 0, 0, 'n' },
- { "promiscous", 0, 0, 'p' },
- { "re-export", 0, 0, 'r', },
- { "version", 0, 0, 'v' },
- { NULL, 0, 0, 0 }
- };
-
- /* In mount_svc.c: */
- extern _PRO(void mount_run, (void));
-
- /* The NULL request handler. */
- void *mountproc_null_1_svc(argp, rqstp)
- void *argp;
- struct svc_req *rqstp;
- {
- static char res;
-
- memset(&res, '\0', sizeof(res));
- log_call(rqstp, "mountproc_null_1", "");
- return ((void *) &res);
- }
-
- fhstatus *mountproc_mnt_1_svc(argp, rqstp)
- dirpath *argp;
- struct svc_req *rqstp;
- {
- static fhstatus res;
- struct stat stbuf;
- clnt_param *cp;
- char nargbuf[MNTPATHLEN + 1];
-
- memset(&res, '\0', sizeof(res));
- sprintf(argbuf, "%s", *argp);
- log_call(rqstp, "mountproc_mnt_1", argbuf);
-
- /* It is important to resolve symlinks before checking permissions. */
- if (realpath(argbuf, nargbuf) == NULL) {
- res.fhs_status = nfs_errno();
- return (&res);
- }
- strcpy(argbuf, nargbuf);
- if (stat(argbuf, &stbuf) < 0) {
- res.fhs_status = nfs_errno();
- return (&res);
- }
-
- /* Now authenticate the intruder... */
- if (((cp = auth_clnt(rqstp, argbuf)) == NULL))
- res.fhs_status = NFSERR_ACCES;
- else if (!S_ISDIR(stbuf.st_mode) && !S_ISREG(stbuf.st_mode))
- res.fhs_status = NFSERR_NOTDIR;
- else
- res.fhs_status = fh_create((nfs_fh *)
- &res.fhstatus_u.fhs_fhandle, argbuf);
- return (&res);
- }
-
- mountlist *mountproc_dump_1_svc(argp, rqstp)
- void *argp;
- struct svc_req *rqstp;
- {
- static mountlist res;
-
- memset(&res, '\0', sizeof(res));
- log_call(rqstp, "mountproc_dump_1", "");
- return (&res);
- }
-
- void *mountproc_umnt_1_svc(argp, rqstp)
- dirpath *argp;
- struct svc_req *rqstp;
- {
- static char res;
-
- memset(&res, '\0', sizeof(res));
- sprintf(argbuf, "%s", *argp);
- log_call(rqstp, "mountproc_umnt_1", argbuf);
- return ((void *) &res);
- }
-
- void *mountproc_umntall_1_svc(argp, rqstp)
- void *argp;
- struct svc_req *rqstp;
- {
- static char res;
-
- memset(&res, '\0', sizeof(res));
- log_call(rqstp, "mountproc_umntall_1", "");
- return ((void *) &res);
- }
-
- exports *mountproc_export_1_svc(argp, rqstp)
- void *argp;
- struct svc_req *rqstp;
- {
- static exports res;
-
- memset(&res, '\0', sizeof(res));
- log_call(rqstp, "mountproc_export_1", "");
- res = export_list;
- return (&res);
- }
-
- exports *mountproc_exportall_1_svc(argp, rqstp)
- void *argp;
- struct svc_req *rqstp;
- {
- log_call(rqstp, "mountproc_exportall_1", "");
- return (mountproc_export_1_svc(argp, rqstp));
- }
-
- static void mountd_init(argc, argv)
- int argc;
- char *argv[];
- {
- int c;
-
- program_name = argv[0];
-
- /* Parse the command line options and arguments. */
- opterr = 0;
- while ((c = getopt_long(argc, argv, "df:hnprv", longopts, NULL)) != EOF)
- switch (c) {
- case 'h':
- usage(stdout, 0);
- break;
- case 'd':
- toggle_logging(0);
- break;
- case 'f':
- auth_file = optarg;
- break;
- case 'n':
- allow_non_root = 1;
- break;
- case 'p':
- promiscuous = 1;
- break;
- case 'r':
- re_export = 1;
- break;
- case 'v':
- printf("%s\n", version);
- exit(0);
- case 0:
- break;
- case '?':
- default:
- usage(stderr, 1);
- }
-
- /* No more arguments allowed. */
- if (optind != argc)
- usage(stderr, 1);
-
- #ifndef HAVE_RPCGEN_I
- #ifndef RPC_SVC_FG
- /* We first fork off a child. */
- if ((c = fork()) > 0)
- exit(0);
- if (c < 0) {
- fprintf(stderr, "mountd: cannot fork: %s\n", strerror(errno));
- exit(-1);
- }
- /* Now we remove ourselves from the foreground. */
- (void) close(0);
- (void) close(1);
- (void) close(2);
- #ifdef TIOCNOTTY
- if ((c = open("/dev/tty", O_RDWR)) >= 0) {
- (void) ioctl(c, TIOCNOTTY, (char *) NULL);
- (void) close(c);
- }
- #else
- setsid();
- #endif
- #endif /* not RPC_SVC_FG */
- #endif /* not HAVE_RPCGEN_I */
-
- /* Initialize logging. */
- log_open("mountd");
-
- /* Initialize the FH module. */
- fh_init();
-
- /* Initialize the AUTH module. */
- auth_init(auth_file);
-
- /* Enable the LOG toggle with a signal. */
- (void) signal(SIGUSR1, toggle_logging);
- }
-
- int main(argc, argv)
- int argc;
- char *argv[];
- {
- mountd_init(argc, argv);
- mountd_main(argc, argv);
- exit(0);
- }
-
- static void usage(fp, n)
- FILE *fp;
- int n;
- {
- fprintf(fp, "Usage: %s [-dhnpv] [-f exports-file]\n", program_name);
- fprintf(fp, " [--debug] [--help] [--allow-non-root]\n");
- fprintf(fp, " [--promiscuous] [--version]\n");
- fprintf(fp, " [--exports-file=file]\n");
- exit(n);
- }
-
-