Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=6bc... Commit: 6bc4d0979fb55f170a59574b2ef092284b2e0e79 Parent: 287c8cb0c681bf7d6c62112869105a8a7d995a4b Author: Lon Hohberger lhh@redhat.com AuthorDate: Wed Oct 28 16:54:53 2009 -0400 Committer: Lon Hohberger lhh@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@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':
cluster-commits@lists.stg.fedorahosted.org