X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fsvcgssd%2Fsvcgssd.c;fp=utils%2Fsvcgssd%2Fsvcgssd.c;h=9dd5a3abb545ac0e87f1a54315ae181357175da9;hp=0000000000000000000000000000000000000000;hb=f1bfe0916c04d93de7a4fae5315fff6e4ccac23f;hpb=981d25a37fe4a71eddd162672a658da223453985 diff --git a/utils/svcgssd/svcgssd.c b/utils/svcgssd/svcgssd.c new file mode 100644 index 0000000..9dd5a3a --- /dev/null +++ b/utils/svcgssd/svcgssd.c @@ -0,0 +1,209 @@ +/* + gssd.c + + Copyright (c) 2000 The Regents of the University of Michigan. + All rights reserved. + + Copyright (c) 2000 Dug Song . + Copyright (c) 2002 Andy Adamson . + Copyright (c) 2002 Marius Aamodt Eriksen . + Copyright (c) 2002 J. Bruce Fields . + All rights reserved, all wrongs reversed. + + 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. 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 ``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. + +*/ + +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include "svcgssd.h" +#include "gss_util.h" +#include "err_util.h" + +/* + * mydaemon creates a pipe between the partent and child + * process. The parent process will wait until the + * child dies or writes a '1' on the pipe signaling + * that it started successfully. + */ +int pipefds[2] = { -1, -1}; + +static void +mydaemon(int nochdir, int noclose) +{ + int pid, status, tempfd, fdmax, filedes; + + if (pipe(pipefds) < 0) { + printerr(1, "mydaemon: pipe() failed: errno %d (%s)\n", + errno, strerror(errno)); + exit(1); + } + if ((pid = fork ()) < 0) { + printerr(1, "mydaemon: fork() failed: errno %d (%s)\n", + errno, strerror(errno)); + exit(1); + } + + if (pid != 0) { + /* + * Parent. Wait for status from child. + */ + close(pipefds[1]); + if (read(pipefds[0], &status, 1) != 1) + exit(1); + exit (0); + } + /* Child. */ + close(pipefds[0]); + setsid (); + if (nochdir == 0) { + if (chdir ("/") == -1) { + printerr(1, "mydaemon: chdir() failed: errno %d (%s)\n", + errno, strerror(errno)); + exit(1); + } + } + + while (pipefds[1] <= 2) { + pipefds[1] = dup(pipefds[1]); + if (pipefds[1] < 0) { + printerr(1, "mydaemon: dup() failed: errno %d (%s)\n", + errno, strerror(errno)); + exit(1); + } + } + + if (noclose == 0) { + tempfd = open("/dev/null", O_RDWR); + close(0); dup2(tempfd, 0); + close(1); dup2(tempfd, 1); + close(2); dup2(tempfd, 2); + fdmax = sysconf (_SC_OPEN_MAX); + for (filedes = 3; filedes < fdmax; filedes++) + if (filedes != pipefds[1]) + close (filedes); + } + + return; +} + +static void +release_parent() +{ + int status; + + if (pipefds[1] > 0) { + write(pipefds[1], &status, 1); + close(pipefds[1]); + pipefds[1] = -1; + } +} + +void +sig_die(int signal) +{ + /* destroy krb5 machine creds */ + printerr(1, "exiting on signal %d\n", signal); + exit(1); +} + +static void +usage(char *progname) +{ + fprintf(stderr, "usage: %s [-n] [-f] [-v]\n", + progname); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int get_creds = 1; + int fg = 0; + int verbosity = 0; + int opt; + extern char *optarg; + char *progname; + + while ((opt = getopt(argc, argv, "fvnp:")) != -1) { + switch (opt) { + case 'f': + fg = 1; + break; + case 'n': + get_creds = 0; + break; + case 'v': + verbosity++; + break; + default: + usage(argv[0]); + break; + } + } + + if ((progname = strrchr(argv[0], '/'))) + progname++; + else + progname = argv[0]; + + initerr(progname, verbosity, fg); + + if (!fg) + mydaemon(0, 0); + + signal(SIGINT, sig_die); + signal(SIGTERM, sig_die); + signal(SIGHUP, sig_die); + + 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/@ in " + "/etc/krb5.keytab?\n"); + exit(1); + } + + if (!fg) + release_parent(); + + gssd_run(); + printerr(0, "gssd_run returned!\n"); + abort(); +}