]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/rquotad/rquota_svc.c
2001-03-10 Tavis Barr <tavis@boole.isetr.columbia.edu>
[nfs-utils.git] / utils / rquotad / rquota_svc.c
index d402f0b2f952f32a73c2e882977adac2418efc75..104ba7eb8946cdb2675439f84d5896eaefd4c016 100644 (file)
  */
 #include "config.h"
 
+#ifdef HAVE_TCP_WRAPPER
+#include "tcpwrapper.h"
+#endif
+
 #include <unistd.h>
 #include <rpc/rpc.h>
 #include "rquota.h"
@@ -30,6 +34,9 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <syslog.h>
+#include <signal.h>
+#include <getopt.h>
+#include <rpcmisc.h>
 
 #ifdef __STDC__
 #define SIG_PF void(*)(int)
@@ -44,6 +51,14 @@ extern getquota_rslt *rquotaproc_getquota_2(ext_getquota_args *argp,
 extern getquota_rslt *rquotaproc_getactivequota_2(ext_getquota_args *argp,
                                                  struct svc_req *rqstp);
 
+static struct option longopts[] =
+{
+        { "help", 0, 0, 'h' },
+        { "version", 0, 0, 'v' },
+        { "port", 1, 0, 'p' },
+        { NULL, 0, 0, 0 }
+};
+
 /*
  * Global authentication credentials.
  */
@@ -59,6 +74,15 @@ static void rquotaprog_1(struct svc_req *rqstp, register SVCXPRT *transp)
    xdrproc_t xdr_argument, xdr_result;
    char *(*local)(char *, struct svc_req *);
 
+#ifdef HAVE_TCP_WRAPPER
+   /* remote host authorization check */
+   if (!check_default("rquotad", svc_getcaller(transp),
+                     rqstp->rq_proc, RQUOTAPROG)) {
+         svcerr_auth (transp, AUTH_FAILED);
+         return;
+   }
+#endif
+
    /*
     * Don't bother authentication for NULLPROC.
     */
@@ -125,6 +149,15 @@ static void rquotaprog_2(struct svc_req *rqstp, register SVCXPRT *transp)
    xdrproc_t xdr_argument, xdr_result;
    char *(*local)(char *, struct svc_req *);
 
+#ifdef HAVE_TCP_WRAPPER
+   /* remote host authorization check */
+   if (!check_default("rquotad", svc_getcaller(transp),
+                     rqstp->rq_proc, RQUOTAPROG)) {
+         svcerr_auth (transp, AUTH_FAILED);
+         return;
+   }
+#endif
+
    /*
     * Don't bother authentication for NULLPROC.
     */
@@ -181,16 +214,53 @@ static void rquotaprog_2(struct svc_req *rqstp, register SVCXPRT *transp)
    return;
 }
 
+static void
+usage(const char *prog, int n)
+{
+  fprintf(stderr, "Usage: %s [-p|--port port] [-h|-?|--help] [-v|--version]\n", prog);
+  exit(n);
+}
+
 int main(int argc, char **argv)
 {
    register SVCXPRT *transp;
+   char c;
+   int port = 0;
 
    (void) pmap_unset(RQUOTAPROG, RQUOTAVERS);
    (void) pmap_unset(RQUOTAPROG, EXT_RQUOTAVERS);
 
    openlog("rquota", LOG_PID, LOG_DAEMON);
 
-   transp = svcudp_create(RPC_ANYSOCK);
+   while ((c = getopt_long(argc, argv, "hp:v", longopts, NULL)) != EOF) {
+     switch (c) {
+     case '?':
+     case 'h':
+       usage(argv[0], 0);
+       break;
+     case 'p':
+       port = atoi(optarg);
+       if (port < 1 || port > 65535) {
+        fprintf(stderr, "%s: bad port number: %s\n",
+                argv[0], optarg);
+        usage(argv[0], 1);
+       }
+       break;
+     case 'v':
+       printf("rquotad %s\n", VERSION);
+       exit(0);
+     default:
+       usage(argv[0], 1);
+     }
+   }
+
+   /* WARNING: the following works on Linux and SysV, but not BSD! */
+   signal(SIGCHLD, SIG_IGN);
+
+   if (port)
+     transp = svcudp_create(makesock(port, IPPROTO_UDP));
+   else
+     transp = svcudp_create(RPC_ANYSOCK);
    if (transp == NULL) {
       syslog(LOG_ERR, "cannot create udp service.");
       exit(1);