summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenky Shankar <venky@gluster.com>2011-10-05 16:56:30 +0530
committerVijay Bellur <vijay@gluster.com>2011-10-28 08:08:40 -0700
commita29f1a0e36bde5ca7b8f3762f10b210b5e12a875 (patch)
treee44c9bd019796c61e7f7059f34f40de0f984b5c7
parentaf708e9fc2eb2104b9e8e3b5a3eaf99201664324 (diff)
fuse: flip xattr key from user to trusted namespace for certain
clients. This is needed for gsyncd/hadoop-plugin running as non-super user to be able to request extended attributes under trusted namespace. Request for a key is made under 'user.' namespace and is flipped by fuse xlator for specific xattr name to the corresponding 'trusted.' extended attribute. Both applications set a identifier (client-pid) while doing a FUSE mount, which is checked by get/set/remove interfaces in FUSE translator. Change-Id: I72f77a5dd1ee1d69c8b0e09209449348dbcf879a BUG: 3701 Reviewed-on: http://review.gluster.com/563 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
-rw-r--r--libglusterfs/src/common-utils.c8
-rw-r--r--libglusterfs/src/common-utils.h17
-rw-r--r--xlators/features/marker/src/marker.c4
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-mountbroker.c7
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c37
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h3
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c84
7 files changed, 151 insertions, 9 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index e7d54d48b..6a5e2504b 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -1946,3 +1946,11 @@ get_mem_size ()
return memsize;
}
+
+
+int
+gf_client_pid_check (gf_client_pid_t npid)
+{
+ return ( (npid > GF_CLIENT_PID_MIN) && (npid < GF_CLIENT_PID_MAX) )
+ ? 0 : -1;
+}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index 2a5e00c5e..6c83a1004 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -78,7 +78,23 @@ enum _gf_boolean
_gf_true = 1
};
+/*
+ * we could have initialized these as +ve values and treated
+ * them as negative while comparing etc.. (which would have
+ * saved us with the pain of assigning values), but since we
+ * only have a couple of clients that use this feature, it's
+ * okay.
+ */
+enum _gf_client_pid
+{
+ GF_CLIENT_PID_MAX = 0,
+ GF_CLIENT_PID_GSYNCD = -1,
+ GF_CLIENT_PID_HADOOP = -2,
+ GF_CLIENT_PID_MIN = -3
+};
+
typedef enum _gf_boolean gf_boolean_t;
+typedef enum _gf_client_pid gf_client_pid_t;
typedef int (*gf_cmp) (void *, void *);
void gf_global_variable_init(void);
@@ -401,4 +417,5 @@ char *get_host_name (char *word, char **host);
char *get_path_name (char *word, char **path);
void gf_path_strip_trailing_slashes (char *path);
uint64_t get_mem_size ();
+int gf_client_pid_check (gf_client_pid_t npid);
#endif /* _COMMON_UTILS_H */
diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c
index 0faa8be58..0de391c56 100644
--- a/xlators/features/marker/src/marker.c
+++ b/xlators/features/marker/src/marker.c
@@ -256,7 +256,7 @@ call_from_special_client (call_frame_t *frame, xlator_t *this, const char *name)
priv = (marker_conf_t *)this->private;
- if (frame->root->pid != -1 || name == NULL ||
+ if (frame->root->pid != GF_CLIENT_PID_GSYNCD || name == NULL ||
strcmp (name, MARKER_XATTR_PREFIX "." VOLUME_MARK) != 0) {
ret = _gf_false;
goto out;
@@ -1765,7 +1765,7 @@ call_from_sp_client_to_reset_tmfile (call_frame_t *frame,
if (data == NULL)
return -1;
- if (frame->root->pid != -1) {
+ if (frame->root->pid != GF_CLIENT_PID_GSYNCD) {
op_ret = -1;
op_errno = EPERM;
diff --git a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c
index f847298c7..b00145f8c 100644
--- a/xlators/mgmt/glusterd/src/glusterd-mountbroker.c
+++ b/xlators/mgmt/glusterd/src/glusterd-mountbroker.c
@@ -268,7 +268,7 @@ const char *georep_mnt_desc_template =
"SUP("
"xlator-option=\\*-dht.assert-no-child-down=true "
"volfile-server=localhost "
- "client-pid=-1 "
+ "client-pid=%d "
"volfile-id=%s "
"user-map-root=%s "
")"
@@ -280,6 +280,7 @@ const char *georep_mnt_desc_template =
const char *hadoop_mnt_desc_template =
"SUP("
"volfile-server=%s "
+ "client-pid=%d "
"volfile-id=%s "
"user-map-root=%s "
")"
@@ -296,7 +297,7 @@ make_georep_mountspec (gf_mount_spec_t *mspec, const char *volname,
int ret = 0;
ret = gf_asprintf (&georep_mnt_desc, georep_mnt_desc_template,
- volname, user);
+ GF_CLIENT_PID_GSYNCD, volname, user);
if (ret == -1)
return ret;
@@ -311,7 +312,7 @@ make_ghadoop_mountspec (gf_mount_spec_t *mspec, const char *volname,
int ret = 0;
ret = gf_asprintf (&hadoop_mnt_desc, hadoop_mnt_desc_template,
- server, volname, user);
+ server, GF_CLIENT_PID_HADOOP, volname, user);
if (ret == -1)
return ret;
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 78bed0480..7e0022d3d 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -2338,6 +2338,7 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_state_t *state = NULL;
char *dict_value = NULL;
int32_t ret = -1;
+ char *newkey = NULL;
priv = this->private;
@@ -2405,13 +2406,20 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
+ ret = fuse_flip_xattr_ns (priv, name, &newkey);
+ if (ret) {
+ send_fuse_err (this, finh, ENOMEM);
+ free_fuse_state (state);
+ return;
+ }
+
dict_value = memdup (value, fsi->size);
- dict_set (state->dict, (char *)name,
+ dict_set (state->dict, newkey,
data_from_dynptr ((void *)dict_value, fsi->size));
dict_ref (state->dict);
state->flags = fsi->flags;
- state->name = gf_strdup (name);
+ state->name = newkey;
uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
state->resolve.path = gf_strdup (state->loc.path);
@@ -2557,6 +2565,8 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_state_t *state = NULL;
int32_t ret = -1;
struct fuse_private *priv = NULL;
+ int rv = 0;
+ char *newkey = NULL;
priv = this->private;
@@ -2611,13 +2621,21 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
+ rv = fuse_flip_xattr_ns (priv, name, &newkey);
+ if (rv) {
+ send_fuse_err (this, finh, ENOMEM);
+ free_fuse_state (state);
+ goto out;
+ }
+
state->size = fgxi->size;
- state->name = gf_strdup (name);
+ state->name = newkey;
uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
state->resolve.path = gf_strdup (state->loc.path);
fuse_resolve_and_resume (state, fuse_getxattr_resume);
+ out:
return;
}
@@ -2681,7 +2699,11 @@ fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
char *name = msg;
fuse_state_t *state = NULL;
+ fuse_private_t *priv = NULL;
int32_t ret = -1;
+ char *newkey = NULL;
+
+ priv = this->private;
GET_STATE (this, finh, state);
ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL);
@@ -2696,7 +2718,14 @@ fuse_removexattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
return;
}
- state->name = gf_strdup (name);
+ ret = fuse_flip_xattr_ns (priv, name, &newkey);
+ if (ret) {
+ send_fuse_err (this, finh, ENOMEM);
+ free_fuse_state (state);
+ return;
+ }
+
+ state->name = newkey;
uuid_copy (state->resolve.gfid, state->loc.inode->gfid);
state->resolve.path = gf_strdup (state->loc.path);
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index c729c9468..2215ad22f 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -292,4 +292,7 @@ inode_t *fuse_ino_to_inode (uint64_t ino, xlator_t *fuse);
int fuse_resolve_and_resume (fuse_state_t *state, fuse_resume_fn_t fn);
int send_fuse_err (xlator_t *this, fuse_in_header_t *finh, int error);
int fuse_gfid_set (fuse_state_t *state);
+int fuse_flip_xattr_ns (struct fuse_private *priv, char *okey, char **nkey);
+int fuse_flip_user_to_trusted (char *okey, char **nkey);
+int fuse_xattr_alloc_default (char *okey, char **nkey);
#endif /* _GF_FUSE_BRIDGE_H_ */
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c
index 5fe3dc9f4..f40d1d6a5 100644
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ b/xlators/mount/fuse/src/fuse-helpers.c
@@ -360,5 +360,89 @@ gf_fuse_stat2attr (struct iatt *st, struct fuse_attr *fa)
#endif
}
+int
+fuse_flip_user_to_trusted (char *okey, char **nkey)
+{
+ int ret = 0;
+ char *key = NULL;
+
+ key = GF_CALLOC (1, strlen(okey) + 10, gf_common_mt_char);
+ if (!key) {
+ ret = -1;
+ goto out;
+ }
+
+ okey += 5;
+ strncpy(key, "trusted.", 8);
+ strncat(key+8, okey, strlen(okey));
+
+ *nkey = key;
+
+ out:
+ return ret;
+}
+
+int
+fuse_xattr_alloc_default (char *okey, char **nkey)
+{
+ int ret = 0;
+ *nkey = gf_strdup (okey);
+ if (!*nkey)
+ ret = -1;
+ return ret;
+}
+int
+fuse_flip_xattr_ns (fuse_private_t *priv, char *okey, char **nkey)
+{
+ int ret = 0;
+ gf_boolean_t need_flip = _gf_false;
+ gf_client_pid_t npid = 0;
+
+ npid = priv->client_pid;
+ if (gf_client_pid_check (npid)) {
+ ret = fuse_xattr_alloc_default (okey, nkey);
+ goto out;
+ }
+
+ switch (npid) {
+ /*
+ * These two cases will never execute as we check the
+ * pid range above, but are kept to keep the compiler
+ * happy.
+ */
+ case GF_CLIENT_PID_MAX:
+ case GF_CLIENT_PID_MIN:
+ goto out;
+
+ case GF_CLIENT_PID_GSYNCD:
+ /* valid xattr(s): *xtime, volume-mark* */
+ gf_log("glusterfs-fuse", GF_LOG_DEBUG, "PID: %d, checking xattr(s): "
+ "volume-mark*, *xtime", npid);
+ if ( (strcmp (okey, "user.glusterfs.volume-mark") == 0)
+ || (fnmatch (okey, "user.glusterfs.volume-mark.*", FNM_PERIOD) == 0)
+ || (fnmatch ("user.glusterfs.*.xtime", okey, FNM_PERIOD) == 0) )
+ need_flip = _gf_true;
+ break;
+
+ case GF_CLIENT_PID_HADOOP:
+ /* valid xattr(s): pathinfo */
+ gf_log("glusterfs-fuse", GF_LOG_DEBUG, "PID: %d, checking xattr(s): "
+ "pathinfo", npid);
+ if (strcmp (okey, "user.glusterfs.pathinfo") == 0)
+ need_flip = _gf_true;
+ break;
+ }
+
+ if (need_flip) {
+ gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "flipping %s to trusted equivalent",
+ okey);
+ ret = fuse_flip_user_to_trusted (okey, nkey);
+ } else {
+ /* if we cannot match, continue with what we got */
+ ret = fuse_xattr_alloc_default (okey, nkey);
+ }
+ out:
+ return ret;
+}