This is mostly required to access leases that resides on NFS exports with the root_squash option enabled. The sanlock process will acquire all the supplementary groups of the sanlock user.
Signed-off-by: Federico Simoncelli fsimonce@redhat.com --- init.d/sanlock | 2 +- src/main.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ src/sanlock_internal.h | 2 + 3 files changed, 70 insertions(+), 1 deletions(-)
diff --git a/init.d/sanlock b/init.d/sanlock index 7004f1f..5f049a6 100644 --- a/init.d/sanlock +++ b/init.d/sanlock @@ -39,7 +39,7 @@ start() { fi
echo -n $"Starting $prog: " - daemon --user=$SANLOCKUSER $prog daemon $SANLOCKOPTS + daemon $prog daemon $SANLOCKOPTS retval=$? echo [ $retval -eq 0 ] diff --git a/src/main.c b/src/main.c index 82c39af..f8c74af 100644 --- a/src/main.c +++ b/src/main.c @@ -1182,6 +1182,69 @@ static void setup_host_name(void) uuid, name.nodename); }
+static void setup_groups(void) +{ + int rv, i, j, h; + int pngroups, sngroups, ngroups_max; + gid_t *pgroup, *sgroup; + + ngroups_max = sysconf(_SC_NGROUPS_MAX); + if (ngroups_max < 0) { + log_error("cannot get the max number of groups %i", errno); + return; + } + + pgroup = malloc(ngroups_max * 2 * sizeof(gid_t)); + if (!pgroup) { + log_error("cannot malloc the group list %i", errno); + exit(EXIT_FAILURE); + } + + pngroups = getgroups(ngroups_max, pgroup); + if (pngroups < 0) { + log_error("cannot get the process groups %i", errno); + goto out; + } + + sgroup = pgroup + ngroups_max; + sngroups = ngroups_max; + + rv = getgrouplist(com.uname, com.gid, sgroup, &sngroups); + if (rv < -1) { + log_error("cannot get the user %s groups %i", com.uname, errno); + goto out; + } + + for (i = 0, j = pngroups; i < sngroups; i++) { + if (j >= ngroups_max) { + log_error("too many groups for the user %s", com.uname); + break; + } + + /* check if the groups is already present in the list */ + for (h = 0; h < j; h++) { + if (pgroup[h] == sgroup[i]) { + goto skip_gid; + } + } + + pgroup[j] = sgroup[i]; + j++; + + skip_gid: + ; /* skipping the gid because it's already present */ + } + + rv = setgroups(j, pgroup); + if (rv < 0) { + log_error("cannot set the user %s groups %i", com.uname, errno); + goto out; + } + + out: + free(pgroup); +} + static int do_daemon(void) { struct sigaction act; @@ -1223,6 +1286,8 @@ static int do_daemon(void)
setup_host_name();
+ setup_groups(); + log_error("sanlock daemon started %s aio %d %d renew %d %d host %s time %llu", RELEASE_VERSION, main_task.use_aio, main_task.io_timeout_seconds, @@ -1635,9 +1700,11 @@ static int read_command_line(int argc, char *argv[]) parse_arg_resource(optionarg); /* com.res_args[] */ break; case 'U': + com.uname = optionarg; com.uid = user_to_uid(optionarg); break; case 'G': + com.gname = optionarg; com.gid = group_to_gid(optionarg); break;
diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h index 4565855..d3ab366 100644 --- a/src/sanlock_internal.h +++ b/src/sanlock_internal.h @@ -531,7 +531,9 @@ struct command_line { int max_worker_threads; int aio_arg; int io_timeout_arg; + char *uname; /* -U */ int uid; /* -U */ + char *gname; /* -G */ int gid; /* -G */ int pid; /* -p */ char sort_arg;
sanlock-devel@lists.fedorahosted.org