cluster: STABLE3 - rgmanager: Allow non-root clustat

Lon Hohberger lon at fedoraproject.org
Thu Jan 7 18:57:52 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=6bc4d0979fb55f170a59574b2ef092284b2e0e79
Commit:        6bc4d0979fb55f170a59574b2ef092284b2e0e79
Parent:        287c8cb0c681bf7d6c62112869105a8a7d995a4b
Author:        Lon Hohberger <lhh at redhat.com>
AuthorDate:    Wed Oct 28 16:54:53 2009 -0400
Committer:     Lon Hohberger <lhh at redhat.com>
CommitterDate: Thu Jan 7 13:51:31 2010 -0500

rgmanager: Allow non-root clustat

This allows non-root users access to the running cluster
and service states.

This requires you to add a user to the 'root' group,
matching cman_tool's requirements.

Resolves: rhbz#531273

Signed-off-by: Lon Hohberger <lhh at redhat.com>
---
 rgmanager/include/message.h       |    1 +
 rgmanager/include/resgroup.h      |    1 +
 rgmanager/src/clulib/msg_socket.c |   16 +++++++++++++++-
 rgmanager/src/clulib/rg_strings.c |    2 ++
 rgmanager/src/daemons/Makefile    |    2 +-
 rgmanager/src/daemons/main.c      |   36 +++++++++++++++++++++++++++++++++++-
 rgmanager/src/utils/clusvcadm.c   |    5 -----
 7 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/rgmanager/include/message.h b/rgmanager/include/message.h
index fb3ec9a..e9d7797 100644
--- a/rgmanager/include/message.h
+++ b/rgmanager/include/message.h
@@ -90,6 +90,7 @@ typedef struct ALIGNED _msgctx {
 		} cluster_info;
 		struct {
 			int sockfd;
+			struct ucred cred;
 			int pad;
 		} local_info;
 	} u;
diff --git a/rgmanager/include/resgroup.h b/rgmanager/include/resgroup.h
index 5a13fcf..3afbce2 100644
--- a/rgmanager/include/resgroup.h
+++ b/rgmanager/include/resgroup.h
@@ -198,6 +198,7 @@ int rg_unlock(struct dlm_lksb *p);
 
 
 /* Return codes */
+#define RG_EPERM	-18		/* Permission denied */
 #define RG_ERELO	-17		/* Relocation failure; service running
 					   on original node */
 #define RG_EEXCL	-16		/* Service not runnable due to
diff --git a/rgmanager/src/clulib/msg_socket.c b/rgmanager/src/clulib/msg_socket.c
index 130cbd7..b6b603e 100644
--- a/rgmanager/src/clulib/msg_socket.c
+++ b/rgmanager/src/clulib/msg_socket.c
@@ -312,6 +312,8 @@ static int
 sock_msg_accept(msgctx_t *listenctx, msgctx_t *acceptctx)
 {
 	errno = EINVAL;
+	struct ucred cred;
+	socklen_t credlen = sizeof(cred);
 
 	if (!listenctx || !acceptctx)
 		return -1;
@@ -327,6 +329,18 @@ sock_msg_accept(msgctx_t *listenctx, msgctx_t *acceptctx)
 	if (acceptctx->u.local_info.sockfd < 0)
 		return -1;
 
+	memset(&cred, 0, sizeof(cred));
+	if (getsockopt(acceptctx->u.local_info.sockfd, SOL_SOCKET,
+		       SO_PEERCRED, (void *)&cred, &credlen) < 0) {
+		perror("getsockopt");
+		cred.uid = (uid_t)-1;
+		cred.gid = (gid_t)-1;
+		cred.pid = (pid_t)-1;
+	}
+
+	memcpy(&acceptctx->u.local_info.cred, &cred,
+	       sizeof(cred));
+
 	set_cloexec(acceptctx->u.local_info.sockfd);
 
 	acceptctx->flags = (SKF_READ | SKF_WRITE);
@@ -354,7 +368,7 @@ sock_msg_listen(int me, const void *portp, msgctx_t **listen_ctx)
 
 	set_cloexec(sock);
 	unlink(RGMGR_SOCK);
-	om = umask(077);
+	om = umask(0117);
 	su.sun_family = PF_LOCAL;
 	snprintf(su.sun_path, sizeof(su.sun_path), "%s", path);
 
diff --git a/rgmanager/src/clulib/rg_strings.c b/rgmanager/src/clulib/rg_strings.c
index cc34a9f..24ee479 100644
--- a/rgmanager/src/clulib/rg_strings.c
+++ b/rgmanager/src/clulib/rg_strings.c
@@ -8,7 +8,9 @@ struct string_val {
 
 
 const struct string_val rg_error_strings[] = {
+	{ RG_EPERM,	"Permissing denied" },
 	{ RG_ERELO,	"Failed; service running on original owner" },
+	{ RG_EEXCL,	"Service not runnable: cannot run exclusive" },
 	{ RG_EDOMAIN,   "Service not runnable" },
 	{ RG_ESCRIPT,   "S/Lang Script Error" },
 	{ RG_EFENCE,    "Fencing operation pending; try again later" },
diff --git a/rgmanager/src/daemons/Makefile b/rgmanager/src/daemons/Makefile
index de36971..94e0dbb 100644
--- a/rgmanager/src/daemons/Makefile
+++ b/rgmanager/src/daemons/Makefile
@@ -40,7 +40,7 @@ OBJS2=	test-noccs.o \
 	rg_locks-noccs.o \
 	event_config-noccs.o
 
-CFLAGS += -DSHAREDIR=\"${sharedir}\"
+CFLAGS += -DSHAREDIR=\"${sharedir}\" -D_GNU_SOURCE
 CFLAGS += -fPIC
 CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${dlmincdir} -I${logtincdir}
 CFLAGS += `xml2-config --cflags` -I${slangincdir}
diff --git a/rgmanager/src/daemons/main.c b/rgmanager/src/daemons/main.c
index 883266a..885d89d 100644
--- a/rgmanager/src/daemons/main.c
+++ b/rgmanager/src/daemons/main.c
@@ -14,6 +14,7 @@
 #include <msgsimple.h>
 #include <vf.h>
 #include <lock.h>
+#include <sys/socket.h>
 #include <message.h>
 #include <rg_queue.h>
 #include <malloc.h>
@@ -338,11 +339,17 @@ do_lockreq(msgctx_t *ctx, int req)
 static int
 dispatch_msg(msgctx_t *ctx, int nodeid, int need_close)
 {
-	int ret = 0, sz = -1, nid;
+	int ret = 0, sz = -1, nid, read_only = 1;
 	char msgbuf[4096];
 	generic_msg_hdr	*msg_hdr = (generic_msg_hdr *)msgbuf;
 	SmMessageSt	*msg_sm = (SmMessageSt *)msgbuf;
 
+	if (ctx->type == MSG_CLUSTER) {
+		read_only = 0;
+	} else if (ctx->u.local_info.cred.uid == 0) {
+		read_only = 0;
+	}
+
 	memset(msgbuf, 0, sizeof(msgbuf));
 
 	/* Peek-a-boo */
@@ -396,6 +403,10 @@ dispatch_msg(msgctx_t *ctx, int nodeid, int need_close)
 
 	case RG_LOCK:
 	case RG_UNLOCK:
+		if (read_only) {
+			msg_send_simple(ctx, RG_FAIL, RG_EPERM, 0);
+			goto out;
+		}
 		if (rg_quorate())
 			do_lockreq(ctx, msg_hdr->gh_command);
 		break;
@@ -408,6 +419,10 @@ dispatch_msg(msgctx_t *ctx, int nodeid, int need_close)
 		break;
 
 	case RG_ACTION_REQUEST:
+		if (read_only) {
+			msg_send_simple(ctx, RG_FAIL, RG_EPERM, 0);
+			goto out;
+		}
 
 		if (sz < (int)sizeof(msg_sm)) {
 			logt_print(LOG_ERR,
@@ -476,6 +491,11 @@ dispatch_msg(msgctx_t *ctx, int nodeid, int need_close)
 		return 0;
 
 	case RG_EVENT:
+		if (read_only) {
+			msg_send_simple(ctx, RG_FAIL, RG_EPERM, 0);
+			goto out;
+		}
+
 		/* Service event.  Run a dependency check */
 		if (sz < (int)sizeof(msg_sm)) {
 			logt_print(LOG_ERR,
@@ -498,6 +518,11 @@ dispatch_msg(msgctx_t *ctx, int nodeid, int need_close)
 		break;
 
 	case RG_EXITING:
+		if (read_only) {
+			msg_send_simple(ctx, RG_FAIL, RG_EPERM, 0);
+			goto out;
+		}
+
 		if (!member_online(msg_hdr->gh_arg1))
 			break;
 
@@ -508,6 +533,11 @@ dispatch_msg(msgctx_t *ctx, int nodeid, int need_close)
 		break;
 
 	case VF_MESSAGE:
+		if (read_only) {
+			msg_send_simple(ctx, RG_FAIL, RG_EPERM, 0);
+			goto out;
+		}
+
 		/* Ignore; our VF thread handles these
 		    - except for VF_CURRENT XXX (bad design) */
 		if (msg_hdr->gh_arg1 == VF_CURRENT)
@@ -515,6 +545,10 @@ dispatch_msg(msgctx_t *ctx, int nodeid, int need_close)
 		break;
 
 	default:
+		if (read_only) {
+			goto out;
+		}
+
 		logt_print(LOG_DEBUG, "unhandled message request %d\n",
 		       msg_hdr->gh_command);
 		break;
diff --git a/rgmanager/src/utils/clusvcadm.c b/rgmanager/src/utils/clusvcadm.c
index d543d27..137837a 100644
--- a/rgmanager/src/utils/clusvcadm.c
+++ b/rgmanager/src/utils/clusvcadm.c
@@ -235,11 +235,6 @@ main(int argc, char **argv)
 	const char *actionstr = NULL;
 	cluster_member_list_t *membership;
 
-	if (geteuid() != (uid_t) 0) {
-		fprintf(stderr, "%s must be run as the root user.\n", argv[0]);
-		return 1;
-	}
-
 	while ((opt = getopt(argc, argv, "lSue:M:d:r:n:m:FvR:s:Z:U:qh?")) != EOF) {
 		switch (opt) {
 		case 'l':


More information about the cluster-commits mailing list