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(a)redhat.com>
---
init.d/sanlock | 2 +-
src/main.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++
src/sanlock_internal.h | 2 +
3 files changed, 75 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..3894ac1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1182,6 +1182,74 @@ 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) + 1;
+ if (ngroups_max < 0) {
+ log_error("cannot determine the max number of groups %i", errno);
+ return;
+ }
+
+ pgroup = malloc(ngroups_max * sizeof(gid_t));
+ if (!pgroup) {
+ log_error("cannot malloc the pgroup list %i", errno);
+ exit(EXIT_FAILURE);
+ }
+
+ sgroup = malloc(ngroups_max * sizeof(gid_t));
+ if (!sgroup) {
+ log_error("cannot malloc the sgroup 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;
+ }
+
+ 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) {
+
+ }
+
+ /* 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);
+ free(sgroup);
+}
+
static int do_daemon(void)
{
struct sigaction act;
@@ -1223,6 +1291,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 +1705,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;
--
1.7.1