CVSROOT:        /cvs/cluster
Module name:    conga
Changes by:     [EMAIL PROTECTED]       2008-02-19 03:14:12

Modified files:
        ricci/common   : daemon_init.c 
        ricci/ricci    : Makefile Ricci.cpp main.cpp 
Added files:
        ricci/test_suite/ricci: self_fence.xml 

Log message:
        add support for quick and dirty fencing (a la 'reboot -fn') via a 
'self_fence' or 'force_reboot' function

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/common/daemon_init.c.diff?cvsroot=cluster&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/ricci/Makefile.diff?cvsroot=cluster&r1=1.25&r2=1.26
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/ricci/Ricci.cpp.diff?cvsroot=cluster&r1=1.30&r2=1.31
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/ricci/main.cpp.diff?cvsroot=cluster&r1=1.8&r2=1.9
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/test_suite/ricci/self_fence.xml.diff?cvsroot=cluster&r1=NONE&r2=1.1

--- conga/ricci/common/daemon_init.c    2008/01/02 20:47:34     1.4
+++ conga/ricci/common/daemon_init.c    2008/02/19 03:14:11     1.5
@@ -20,7 +20,7 @@
 /** @file
  * daemon_init function, does sanity checks and calls daemon().
  *
- * $Id: daemon_init.c,v 1.4 2008/01/02 20:47:34 rmccabe Exp $
+ * $Id: daemon_init.c,v 1.5 2008/02/19 03:14:11 rmccabe Exp $
  *
  * Author: Jeff Moyer <[EMAIL PROTECTED]>
  */
@@ -232,5 +232,4 @@
 
        update_pidfile(prog);
        nice(-1);
-       //mlockall(MCL_CURRENT | MCL_FUTURE);
 }
--- conga/ricci/ricci/Makefile  2008/01/02 20:47:38     1.25
+++ conga/ricci/ricci/Makefile  2008/02/19 03:14:12     1.26
@@ -39,7 +39,7 @@
 INCLUDE += `pkg-config --cflags dbus-1` -I../common
 CFLAGS +=
 CXXFLAGS += -DDBUS_MAJOR_VERSION="${dbus_major_version}" 
-DDBUS_MINOR_VERSION="${dbus_minor_version}" -DPARANOIA=$(PARANOID)
-LDFLAGS += `pkg-config --libs dbus-1`
+LDFLAGS += -lcap `pkg-config --libs dbus-1`
 
 ifeq ($(PARANOID), 1)
        LDFLAGS += ${top_srcdir}/common/paranoid/*.o
--- conga/ricci/ricci/Ricci.cpp 2008/01/02 20:47:38     1.30
+++ conga/ricci/ricci/Ricci.cpp 2008/02/19 03:14:12     1.31
@@ -34,6 +34,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/reboot.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <dirent.h>
@@ -160,6 +161,11 @@
                        remove_cert = true;
                }
                authenticated = false;
+       } else if (function == "force_reboot" || function == "self_fence") {
+               if (reboot(RB_AUTOBOOT) == 0)
+                       success = RRC_SUCCESS;
+               else
+                       success = RRC_INTERNAL_ERROR;
        } else if (function == "list_modules") {
                // available modules
                if (!authenticated) {
--- conga/ricci/ricci/main.cpp  2008/01/02 20:47:38     1.8
+++ conga/ricci/ricci/main.cpp  2008/02/19 03:14:12     1.9
@@ -14,20 +14,24 @@
 ** along with this program; see the file COPYING. If not, write to the
 ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 ** MA 02139, USA.
+**
+** Authors:
+**  Stanko Kupcevic <[EMAIL PROTECTED]>
+**  Ryan McCabe <[EMAIL PROTECTED]>
 */
 
-/*
- * Author: Stanko Kupcevic <[EMAIL PROTECTED]>
- */
-
 #include "Server.h"
 #include "ricci_defines.h"
 
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
 #include <errno.h>
+#include <sys/mman.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
 
 extern "C" {
        void daemon_init(char *prog);
@@ -41,15 +45,65 @@
 bool foreground = false;
 bool debug = false;
 bool advertise_cluster = false;
+bool self_fence = false;
+
+int drop_privs(uid_t new_uid) {
+       int ret;
+       cap_t caps = cap_get_proc();
+       cap_value_t saved_caps[] = { CAP_SYS_BOOT, CAP_SETUID };
+       cap_value_t saved_caps_final[] = { CAP_SYS_BOOT };
+
+       ret = prctl(PR_SET_KEEPCAPS, 1);
+       if (ret != 0)
+               return -errno;
+
+       cap_clear(caps);
+       ret = cap_set_flag(caps, CAP_PERMITTED,
+                       sizeof(saved_caps) / sizeof(saved_caps[0]), saved_caps, 
CAP_SET);
+       if (ret != 0)
+               return -errno;
+
+       ret = cap_set_flag(caps, CAP_EFFECTIVE,
+                       sizeof(saved_caps) / sizeof(saved_caps[0]), saved_caps, 
CAP_SET);
+       if (ret != 0)
+               return -errno;
+
+       ret = cap_set_proc(caps);
+       if (ret != 0)
+               return -errno;
+
+       ret = setuid(new_uid);
+       if (ret != 0)
+               return -errno;
+
+       cap_clear(caps);
+       ret = cap_set_flag(caps, CAP_PERMITTED,
+                       sizeof(saved_caps_final) / sizeof(saved_caps_final[0]),
+                       saved_caps_final, CAP_SET);
+       if (ret != 0)
+               return -errno;
+
+       ret = cap_set_flag(caps, CAP_EFFECTIVE,
+                       sizeof(saved_caps_final) / sizeof(saved_caps_final[0]),
+                       saved_caps_final, CAP_SET);
+       if (ret != 0)
+               return -errno;
+
+       ret = cap_set_proc(caps);
+       if (ret != 0)
+               return -errno;
 
-int main(int argc, char** argv)
-{
+       prctl(PR_SET_KEEPCAPS, 0);
+       return (0);
+}
+
+int main(int argc, char **argv) {
        uint32_t uid = 0;
        int32_t ricci_port = RICCI_SERVER_PORT;
+       int ret;
 
-       int rv;
-       while ((rv = getopt(argc, argv, "cdfu:p:")) != EOF) {
-               switch (rv) {
+       while ((ret = getopt(argc, argv, "cdfFu:p:")) != EOF) {
+               switch (ret) {
                        case 'c':
                                advertise_cluster = true;
                                break;
@@ -62,6 +116,10 @@
                                foreground = true;
                                break;
 
+                       case 'F':
+                               self_fence = true;
+                               break;
+
                        case 'p':
                                if (optarg != NULL) {
                                        uint32_t port;
@@ -103,11 +161,21 @@
                if (!foreground)
                        daemon_init(argv[0]);
 
+               if (self_fence)
+                       mlockall(MCL_CURRENT);
+
                if (uid != getuid()) {
-                       // change user
-                       if (setreuid(uid, uid)) {
+                       if (self_fence)
+                               ret = drop_privs(uid);
+                       else {
+                               ret = setuid(uid);
+                               if (ret != 0)
+                                       ret = -errno;
+                       }
+
+                       if (ret != 0) {
                                fprintf(stderr, "Error changing uid to %u: 
%s\n",
-                                       uid, strerror(errno));
+                                       uid, strerror(-ret));
                                exit(1);
                        }
                }
/cvs/cluster/conga/ricci/test_suite/ricci/self_fence.xml,v  -->  standard output
revision 1.1
--- conga/ricci/test_suite/ricci/self_fence.xml
+++ -   2008-02-19 03:14:13.086521000 +0000
@@ -0,0 +1,2 @@
+<?xml version="1.0" ?>
+<ricci version="1.0" function="self_fence"/>

Reply via email to