diff options
| -rw-r--r-- | libglusterfs/src/common-utils.c | 8 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 17 | ||||
| -rw-r--r-- | xlators/features/marker/src/marker.c | 4 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-mountbroker.c | 7 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 37 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.h | 3 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-helpers.c | 84 | 
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; +}  | 
