cluster: RHEL57 - rgmanager: Allow non-root clustat

Lon Hohberger lon at fedoraproject.org
Fri Apr 8 13:47:00 UTC 2011


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=640f9211a325d1e093fd3c108a97fedae646e86e
Commit:        640f9211a325d1e093fd3c108a97fedae646e86e
Parent:        d4dd514faa27f4f7c91205d7525c7f3bc1885aa3
Author:        Lon Hohberger <lhh at redhat.com>
AuthorDate:    Mon Mar 28 15:56:08 2011 -0400
Committer:     Lon Hohberger <lhh at redhat.com>
CommitterDate: Fri Apr 8 09:31:15 2011 -0400

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.

Simple backport from RHEL6 / STABLE31

Resolves: rhbz#510300

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

diff --git a/rgmanager/include/message.h b/rgmanager/include/message.h
index f987ec6..4b9ae3a 100644
--- a/rgmanager/include/message.h
+++ b/rgmanager/include/message.h
@@ -89,6 +89,7 @@ typedef struct _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 ded11f4..793ad3b 100644
--- a/rgmanager/include/resgroup.h
+++ b/rgmanager/include/resgroup.h
@@ -187,6 +187,9 @@ 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
 					   the fact that it is tagged 
 					   exclusive and there are no
diff --git a/rgmanager/src/clulib/msg_socket.c b/rgmanager/src/clulib/msg_socket.c
index c392757..4fc9f88 100644
--- a/rgmanager/src/clulib/msg_socket.c
+++ b/rgmanager/src/clulib/msg_socket.c
@@ -330,6 +330,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;
@@ -345,6 +347,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);
@@ -372,7 +386,7 @@ sock_msg_listen(int me, 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 4d1eccb..47b06e0 100644
--- a/rgmanager/src/clulib/rg_strings.c
+++ b/rgmanager/src/clulib/rg_strings.c
@@ -26,6 +26,8 @@ struct string_val {
 
 
 const struct string_val rg_error_strings[] = {
+	{ RG_EPERM,	"Permission denied" },
+	{ RG_ERELO,	"Failed; service running on original owner" },
 	{ RG_EEXCL,	"Service not runnable: cannot run exclusive" },
 	{ RG_EDOMAIN,   "Service not runnable: restricted failover domain offline" },
 	{ RG_ESCRIPT,   "S/Lang Script Error" },
diff --git a/rgmanager/src/daemons/main.c b/rgmanager/src/daemons/main.c
index 52e38bc..aa78cef 100644
--- a/rgmanager/src/daemons/main.c
+++ b/rgmanager/src/daemons/main.c
@@ -32,6 +32,8 @@
 #include <msgsimple.h>
 #include <vf.h>
 #include <lock.h>
+#include <sys/socket.h>
+#include <message.h>
 #include <rg_queue.h>
 #include <malloc.h>
 #include <cman-private.h>
@@ -428,11 +430,17 @@ do_lockreq(msgctx_t *ctx, int req)
 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 */
@@ -486,6 +494,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;
@@ -498,6 +510,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)) {
 			clulog(LOG_ERR,
@@ -557,6 +573,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)) {
 			clulog(LOG_ERR,
@@ -579,6 +600,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;
 
@@ -589,6 +615,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)


More information about the cluster-commits mailing list