]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/gssd/svcgssd.c
nfs-utils: Add support to svcgssd to limit the negotiated enctypes
[nfs-utils.git] / utils / gssd / svcgssd.c
index 4e0806c30a425df6f915825d469e196e2e54c2b3..1afff9e5a4935c3a9be76b4ccaf2d02f3463e74c 100644 (file)
@@ -37,7 +37,9 @@
 
 */
 
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -54,6 +56,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <signal.h>
+#include <nfsidmap.h>
 #include "nfslib.h"
 #include "svcgssd.h"
 #include "gss_util.h"
@@ -114,22 +117,32 @@ mydaemon(int nochdir, int noclose)
 
        if (noclose == 0) {
                tempfd = open("/dev/null", O_RDWR);
-               dup2(tempfd, 0);
-               dup2(tempfd, 1);
-               dup2(tempfd, 2);
-               closeall(3);
+               if (tempfd >= 0) {
+                       dup2(tempfd, 0);
+                       dup2(tempfd, 1);
+                       dup2(tempfd, 2);
+                       close(tempfd);
+               } else {
+                       printerr(1, "mydaemon: can't open /dev/null: errno %d "
+                                   "(%s)\n", errno, strerror(errno));
+                       exit(1);
+               }
        }
 
        return;
 }
 
 static void
-release_parent()
+release_parent(void)
 {
        int status;
 
        if (pipefds[1] > 0) {
-               write(pipefds[1], &status, 1);
+               if (write(pipefds[1], &status, 1) != 1) {
+                       printerr(1, 
+                               "WARN: writing to parent pipe failed: errno %d (%s)\n",
+                               errno, strerror(errno));
+               }
                close(pipefds[1]);
                pipefds[1] = -1;
        }
@@ -147,14 +160,14 @@ void
 sig_hup(int signal)
 {
        /* don't exit on SIGHUP */
-       printerr(1, "Received SIGHUP... Ignoring.\n");
+       printerr(1, "Received SIGHUP(%d)... Ignoring.\n", signal);
        return;
 }
 
 static void
 usage(char *progname)
 {
-       fprintf(stderr, "usage: %s [-n] [-f] [-v] [-r]\n",
+       fprintf(stderr, "usage: %s [-n] [-f] [-v] [-r] [-i] [-p principal]\n",
                progname);
        exit(1);
 }
@@ -166,15 +179,20 @@ main(int argc, char *argv[])
        int fg = 0;
        int verbosity = 0;
        int rpc_verbosity = 0;
-       int opt;
+       int idmap_verbosity = 0;
+       int opt, status;
        extern char *optarg;
        char *progname;
+       char *principal = NULL;
 
-       while ((opt = getopt(argc, argv, "fvrnp:")) != -1) {
+       while ((opt = getopt(argc, argv, "fivrnp:")) != -1) {
                switch (opt) {
                        case 'f':
                                fg = 1;
                                break;
+                       case 'i':
+                               idmap_verbosity++;
+                               break;
                        case 'n':
                                get_creds = 0;
                                break;
@@ -184,6 +202,9 @@ main(int argc, char *argv[])
                        case 'r':
                                rpc_verbosity++;
                                break;
+                       case 'p':
+                               principal = optarg;
+                               break;
                        default:
                                usage(argv[0]);
                                break;
@@ -197,12 +218,28 @@ main(int argc, char *argv[])
 
        initerr(progname, verbosity, fg);
 #ifdef HAVE_AUTHGSS_SET_DEBUG_LEVEL
+       if (verbosity && rpc_verbosity == 0)
+               rpc_verbosity = verbosity;
        authgss_set_debug_level(rpc_verbosity);
 #else
        if (rpc_verbosity > 0)
                printerr(0, "Warning: rpcsec_gss library does not "
                            "support setting debug level\n");
 #endif
+#ifdef HAVE_NFS4_SET_DEBUG
+               if (verbosity && idmap_verbosity == 0)
+                       idmap_verbosity = verbosity;
+        nfs4_set_debug(idmap_verbosity, NULL);
+#else
+       if (idmap_verbosity > 0)
+               printerr(0, "Warning: your nfsidmap library does not "
+                           "support setting debug level\n");
+#endif
+
+       if (gssd_check_mechs() != 0) {
+               printerr(0, "ERROR: Problem with gssapi library\n");
+               exit(1);
+       }
 
        if (!fg)
                mydaemon(0, 0);
@@ -211,17 +248,33 @@ main(int argc, char *argv[])
        signal(SIGTERM, sig_die);
        signal(SIGHUP, sig_hup);
 
-       if (get_creds && !gssd_acquire_cred(GSSD_SERVICE_NAME)) {
-                printerr(0, "unable to obtain root (machine) credentials\n");
-                printerr(0, "do you have a keytab entry for "
-                           "nfs/<your.host>@<YOUR.REALM> in "
-                           "/etc/krb5.keytab?\n");
-               exit(1);
+       if (get_creds) {
+               if (principal)
+                       status = gssd_acquire_cred(principal, 
+                               ((const gss_OID)GSS_C_NT_USER_NAME));
+               else
+                       status = gssd_acquire_cred(GSSD_SERVICE_NAME, 
+                               (const gss_OID)GSS_C_NT_HOSTBASED_SERVICE);
+               if (status == FALSE) {
+                       printerr(0, "unable to obtain root (machine) credentials\n");
+                       printerr(0, "do you have a keytab entry for "
+                               "nfs/<your.host>@<YOUR.REALM> in "
+                               "/etc/krb5.keytab?\n");
+                       exit(1);
+               }
+       } else {
+               status = gssd_acquire_cred(NULL,
+                       (const gss_OID)GSS_C_NT_HOSTBASED_SERVICE);
+               if (status == FALSE) {
+                       printerr(0, "unable to obtain nameless credentials\n");
+                       exit(1);
+               }
        }
 
        if (!fg)
                release_parent();
 
+       nfs4_init_name_mapping(NULL); /* XXX: should only do this once */
        gssd_run();
        printerr(0, "gssd_run returned!\n");
        abort();