summaryrefslogtreecommitdiffstats
path: root/xlators/mount/fuse/src
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mount/fuse/src')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c6
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h3
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c116
3 files changed, 86 insertions, 39 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index b67a60a76b1..d6edcb360cd 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -5427,6 +5427,8 @@ init (xlator_t *this_xl)
goto cleanup_exit;
}
+ GF_OPTION_INIT("resolve-gids", priv->resolve_gids, bool, cleanup_exit);
+
/* default values seemed to work fine during testing */
GF_OPTION_INIT ("background-qlen", priv->background_qlen, int32,
cleanup_exit);
@@ -5665,6 +5667,10 @@ struct volume_options options[] = {
.type = GF_OPTION_TYPE_INT,
.default_value = "300"
},
+ { .key = {"resolve-gids"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "false"
+ },
{ .key = {"acl"},
.type = GF_OPTION_TYPE_BOOL,
.default_value = "false"
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index a9705d6c654..850eeb60ea8 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -127,6 +127,9 @@ struct fuse_private {
/* fini started, helps prevent multiple epoll worker threads
* firing up the fini routine */
gf_boolean_t fini_invoked;
+
+ /* resolve gid with getgrouplist() instead of /proc/%d/status */
+ gf_boolean_t resolve_gids;
};
typedef struct fuse_private fuse_private_t;
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c
index 1c888276eb5..22aa9b486d1 100644
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ b/xlators/mount/fuse/src/fuse-helpers.c
@@ -20,6 +20,8 @@
#elif defined(CTL_KERN)
#include <sys/sysctl.h>
#endif
+#include <pwd.h>
+#include <grp.h>
#include "fuse-bridge.h"
@@ -146,51 +148,87 @@ void
frame_fill_groups (call_frame_t *frame)
{
#if defined(GF_LINUX_HOST_OS)
- char filename[32];
- char line[4096];
- char *ptr = NULL;
- FILE *fp = NULL;
- int idx = 0;
- long int id = 0;
- char *saveptr = NULL;
- char *endptr = NULL;
- int ret = 0;
-
- ret = snprintf (filename, sizeof filename, "/proc/%d/status",
- frame->root->pid);
- if (ret >= sizeof filename)
- goto out;
+ xlator_t *this = frame->this;
+ fuse_private_t *priv = this->private;
+ char filename[32];
+ char line[4096];
+ char *ptr = NULL;
+ FILE *fp = NULL;
+ int idx = 0;
+ long int id = 0;
+ char *saveptr = NULL;
+ char *endptr = NULL;
+ int ret = 0;
+ int ngroups = FUSE_MAX_AUX_GROUPS;
+ gid_t mygroups[GF_MAX_AUX_GROUPS];
+
+ if (priv->resolve_gids) {
+ struct passwd pwent;
+ char mystrs[1024];
+ struct passwd *result;
+
+ if (getpwuid_r (frame->root->uid, &pwent, mystrs,
+ sizeof(mystrs), &result) != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "getpwuid_r(%u) "
+ "failed", frame->root->uid);
+ return;
+ }
- fp = fopen (filename, "r");
- if (!fp)
- goto out;
+ ngroups = GF_MAX_AUX_GROUPS;
+ if (getgrouplist (result->pw_name, frame->root->gid, mygroups,
+ &ngroups) == -1) {
+ gf_log (this->name, GF_LOG_ERROR, "could not map %s to "
+ "group list (ngroups %d, max %d)",
+ result->pw_name, ngroups, GF_MAX_AUX_GROUPS);
+ return;
+ }
- if (call_stack_alloc_groups (frame->root, FUSE_MAX_AUX_GROUPS) != 0)
- goto out;
+ if (call_stack_alloc_groups (frame->root, ngroups) != 0)
+ goto out;
- while ((ptr = fgets (line, sizeof line, fp))) {
- if (strncmp (ptr, "Groups:", 7) != 0)
- continue;
-
- ptr = line + 8;
-
- for (ptr = strtok_r (ptr, " \t\r\n", &saveptr);
- ptr;
- ptr = strtok_r (NULL, " \t\r\n", &saveptr)) {
- errno = 0;
- id = strtol (ptr, &endptr, 0);
- if (errno == ERANGE)
- break;
- if (!endptr || *endptr)
- break;
- frame->root->groups[idx++] = id;
- if (idx == FUSE_MAX_AUX_GROUPS)
- break;
+ /* Copy data to the frame. */
+ for (idx = 0; idx < ngroups; ++idx) {
+ frame->root->groups[idx] = mygroups[idx];
}
+ frame->root->ngrps = ngroups;
+ } else {
+ ret = snprintf (filename, sizeof filename, "/proc/%d/status",
+ frame->root->pid);
+ if (ret >= sizeof filename)
+ goto out;
- frame->root->ngrps = idx;
- break;
+ fp = fopen (filename, "r");
+ if (!fp)
+ goto out;
+
+ if (call_stack_alloc_groups (frame->root, ngroups) != 0)
+ goto out;
+
+ while ((ptr = fgets (line, sizeof line, fp))) {
+ if (strncmp (ptr, "Groups:", 7) != 0)
+ continue;
+
+ ptr = line + 8;
+
+ for (ptr = strtok_r (ptr, " \t\r\n", &saveptr);
+ ptr;
+ ptr = strtok_r (NULL, " \t\r\n", &saveptr)) {
+ errno = 0;
+ id = strtol (ptr, &endptr, 0);
+ if (errno == ERANGE)
+ break;
+ if (!endptr || *endptr)
+ break;
+ frame->root->groups[idx++] = id;
+ if (idx == FUSE_MAX_AUX_GROUPS)
+ break;
+ }
+
+ frame->root->ngrps = idx;
+ break;
+ }
}
+
out:
if (fp)
fclose (fp);