Version bump
[shibboleth/cpp-sp.git] / shibd / shibd.cpp
index eee5c8b..c79e1dc 100644 (file)
@@ -1,25 +1,25 @@
-/*
- *  Copyright 2001-2009 Internet2
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * UCAID licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the
+ * License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
  */
 
 /*
- * shar.cpp -- the shibd "main" code.  All the functionality is elsewhere
- *
- * Created By: Derek Atkins <derek@ihtfp.com>
- *
- * $Id: shar.cpp 2164 2007-02-11 05:26:18 +0000 (Sun, 11 Feb 2007) cantor $
+ * shibd.cpp -- the shibd "main" code.
  */
 
 
 #include <shibsp/SPConfig.h>
 
 #ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#include <sys/select.h>
+# include <unistd.h>
+# include <sys/select.h>
+#endif
+
+#if defined(HAVE_GRP_H) && defined(HAVE_PWD_H)
+# include <pwd.h>
+# include <grp.h>
 #endif
 
 #include <stdio.h>
@@ -56,13 +61,13 @@ using namespace xmltooling;
 using namespace std;
 
 bool shibd_shutdown = false;
-const char* shar_config = NULL;
-const char* shar_schemadir = NULL;
-const char* shar_prefix = NULL;
+const char* shar_config = nullptr;
+const char* shar_schemadir = nullptr;
+const char* shar_prefix = nullptr;
 bool shar_checkonly = false;
 bool shar_version = false;
 static bool unlink_socket = false;
-const char* pidfile = NULL;
+const char* pidfile = nullptr;
 
 #ifdef WIN32
 
@@ -105,9 +110,14 @@ int MyAllocHook(int nAllocType, void *pvData,
 
 int real_main(int preinit)
 {
-    SPConfig& conf=SPConfig::getConfig();
-    if (preinit) {
+    if (shar_version) {
+        if (preinit)
+            fprintf(stdout, PACKAGE_STRING"\n");
+        return 0;
+    }
 
+    SPConfig& conf = SPConfig::getConfig();
+    if (preinit) {
         // Initialize the SP library.
         conf.setFeatures(
             SPConfig::Listener |
@@ -168,6 +178,8 @@ int real_main(int preinit)
 int daemon_wait = 3;
 bool shibd_running = false;
 bool daemonize = true;
+const char* runasuser = nullptr;
+const char* runasgroup = nullptr;
 
 static void term_handler(int arg)
 {
@@ -191,7 +203,7 @@ static int setup_signals(void)
     sa.sa_handler = SIG_IGN;
     sa.sa_flags = SA_RESTART;
 
-    if (sigaction(SIGPIPE, &sa, NULL) < 0) {
+    if (sigaction(SIGPIPE, &sa, nullptr) < 0) {
         return -1;
     }
 
@@ -199,16 +211,16 @@ static int setup_signals(void)
     sa.sa_handler = term_handler;
     sa.sa_flags = SA_RESTART;
 
-    if (sigaction(SIGHUP, &sa, NULL) < 0) {
+    if (sigaction(SIGHUP, &sa, nullptr) < 0) {
         return -1;
     }
-    if (sigaction(SIGINT, &sa, NULL) < 0) {
+    if (sigaction(SIGINT, &sa, nullptr) < 0) {
         return -1;
     }
-    if (sigaction(SIGQUIT, &sa, NULL) < 0) {
+    if (sigaction(SIGQUIT, &sa, nullptr) < 0) {
         return -1;
     }
-    if (sigaction(SIGTERM, &sa, NULL) < 0) {
+    if (sigaction(SIGTERM, &sa, nullptr) < 0) {
         return -1;
     }
 
@@ -216,14 +228,14 @@ static int setup_signals(void)
         memset(&sa, 0, sizeof (sa));
         sa.sa_handler = run_handler;
 
-        if (sigaction(SIGUSR1, &sa, NULL) < 0) {
+        if (sigaction(SIGUSR1, &sa, nullptr) < 0) {
             return -1;
         }
 
         memset(&sa, 0, sizeof (sa));
         sa.sa_handler = child_handler;
 
-        if (sigaction(SIGCHLD, &sa, NULL) < 0) {
+        if (sigaction(SIGCHLD, &sa, nullptr) < 0) {
             return -1;
         }
     }
@@ -233,17 +245,19 @@ static int setup_signals(void)
 
 static void usage(char* whoami)
 {
-    fprintf(stderr, "usage: %s [-dcxtfpvh]\n", whoami);
-    fprintf(stderr, "  -d\tinstallation prefix to use.\n");
-    fprintf(stderr, "  -c\tconfig file to use.\n");
-    fprintf(stderr, "  -x\tXML schema catalogs to use.\n");
-    fprintf(stderr, "  -t\ttest configuration file for problems.\n");
-    fprintf(stderr, "  -f\tforce removal of listener socket.\n");
-    fprintf(stderr, "  -F\tstay in the foreground.\n");
-    fprintf(stderr, "  -p\tpid file to use.\n");
-    fprintf(stderr, "  -w\tseconds to wait for successful daemonization.\n");
-    fprintf(stderr, "  -v\tprint software version.\n");
-    fprintf(stderr, "  -h\tprint this help message.\n");
+    fprintf(stderr, "usage: %s [-dcxtfFpwugvh]\n", whoami);
+    fprintf(stderr, "  -d\tinstallation prefix to use\n");
+    fprintf(stderr, "  -c\tconfig file to use\n");
+    fprintf(stderr, "  -x\tXML schema catalogs to use\n");
+    fprintf(stderr, "  -t\ttest configuration file for problems\n");
+    fprintf(stderr, "  -f\tforce removal of listener socket\n");
+    fprintf(stderr, "  -F\tstay in the foreground\n");
+    fprintf(stderr, "  -p\tpid file to use\n");
+    fprintf(stderr, "  -w\tseconds to wait for successful daemonization\n");
+    fprintf(stderr, "  -u\tuser to run under\n");
+    fprintf(stderr, "  -g\tgroup to run under\n");
+    fprintf(stderr, "  -v\tprint software version\n");
+    fprintf(stderr, "  -h\tprint this help message\n");
     exit(1);
 }
 
@@ -251,7 +265,7 @@ static int parse_args(int argc, char* argv[])
 {
     int opt;
 
-    while ((opt = getopt(argc, argv, "d:c:x:p:w:fFtvh")) > 0) {
+    while ((opt = getopt(argc, argv, "d:c:x:p:w:u:g:fFtvh")) > 0) {
         switch (opt) {
             case 'd':
                 shar_prefix=optarg;
@@ -284,6 +298,14 @@ static int parse_args(int argc, char* argv[])
                 if (daemon_wait <= 0)
                     daemon_wait = 3;
                 break;
+            case 'u':
+                if (optarg)
+                    runasuser = optarg;
+                break;
+            case 'g':
+                if (optarg)
+                    runasgroup = optarg;
+                break;
             default:
                 return -1;
         }
@@ -303,6 +325,40 @@ int main(int argc, char *argv[])
     if (setup_signals() != 0)
         return -1;
 
+    if (runasgroup) {
+#ifdef HAVE_GETGRNAM
+        struct group* grp = getgrnam(runasgroup);
+        if (!grp) {
+            fprintf(stderr, "getgrnam failed, check -g option\n");
+            return -1;
+        }
+        if (setgid(grp->gr_gid) != 0) {
+            fprintf(stderr, "setgid failed, check -g option\n");
+            return -1;
+        }
+#else
+        fprintf(stderr, "-g not supported on this platform");
+        return -1;
+#endif
+    }
+
+    if (runasuser) {
+#ifdef HAVE_GETPWNAM
+        struct passwd* pwd = getpwnam(runasuser);
+        if (!pwd) {
+            fprintf(stderr, "getpwnam failed, check -u option\n");
+            return -1;
+        }
+        if (setuid(pwd->pw_uid) != 0) {
+            fprintf(stderr, "setuid failed, check -u option\n");
+            return -1;
+        }
+#else
+        fprintf(stderr, "-u not supported on this platform");
+        return -1;
+#endif
+    }
+
     // initialize the shib-target library
     SPConfig& conf=SPConfig::getConfig();
     conf.setFeatures(