Changing smb_filename->base_name in VFS module.

Jeremy Allison jra at samba.org
Tue Sep 4 17:12:56 UTC 2018


On Mon, Sep 03, 2018 at 02:37:49PM +0300, Vadim Lazovskiy via samba-technical wrote:
> >
> >
> > You are going to have to implement more VFS functions. At least
> > realpath and stat, I would imagine.
> >
> >
> Thank you for your reply.
> 
> Still no luck.
> 
> I've implemented ssdcache_stat function as follows:
> 
> struct smb_filename *ssdcache_find_cached_file(vfs_handle_struct *handle,
> const struct smb_filename *smb_fname)
> {
>         vfs_ssdcache_module_ctx_t *ctx;
> 
>         size_t i, len, max_len = 0;
>         struct smb_filename *ret;
>         char *new_base_name;
>         const char **cache_paths;
> 
>         SMB_VFS_HANDLE_GET_DATA(handle, ctx, vfs_ssdcache_module_ctx_t,
> return NULL);
> 
>         if (!ctx->initialized) {
>                 errno = ENOENT;
>                 return NULL;
>         }
> 
>         for (i = 0; ctx->cache_paths[i]; i++) {
>                 if (strstr(smb_fname->base_name, ctx->cache_paths[i]) !=
> NULL) {
>                         errno = ENOENT;
>                         return NULL;
>                 }
>         }
> 
>         max_len = ctx->cache_path_max_len + strlen(smb_fname->base_name) +
> 2; // for slash and \0
>         new_base_name = talloc_zero_size(talloc_tos(), max_len);
> 
>         if (new_base_name == NULL) {
>                 errno = ENOMEM;
>                 return NULL;
>         }
> 
>         /* Allocate new smb_filename structure */
>         ret = synthetic_smb_fname(talloc_tos(), new_base_name, NULL, NULL,
> smb_fname->flags);
> 
>         if (ret == NULL) {
>                 errno = ENOMEM;
>                 return NULL;
>         }
> 
>         for (i = 0; ctx->cache_paths[i]; i++) {
>                 strlcat(ret->base_name, ctx->cache_paths[i], max_len);
>                 strlcat(ret->base_name, "/", max_len);
>                 strlcat(ret->base_name, smb_fname->base_name, max_len);
> 
>                 if (access(ret->base_name, F_OK) == 0) {
>                         break;
>                 }
> 
>                 *ret->base_name = '\0';
>         }
> 
>         if (*ret->base_name == '\0') {
>                 TALLOC_FREE(new_base_name);
>                 TALLOC_FREE(ret);
> 
>                 errno = ENOENT;
>                 return NULL;
>         }
> 
>         return ret;
> }
> 
> static int ssdcache_stat(vfs_handle_struct *handle, struct smb_filename
> *smb_fname)
> {
>         vfs_ssdcache_module_ctx_t *ctx;
> 
>         int ret;
>         struct smb_filename *smb_fname_new;
> 
>         SMB_VFS_HANDLE_GET_DATA(handle, ctx, vfs_ssdcache_module_ctx_t,
> return -1);
> 
>         if (!ctx->initialized) {
>                 return SMB_VFS_NEXT_STAT(handle, smb_fname);
>         }
> 
>         /* stat file */
>         if ((ret = sys_stat(smb_fname->base_name, &smb_fname->st, true)) !=
> 0) {
>                 return ret;
>         }
> 
>         /* skip directories */
>         if (S_ISDIR(smb_fname->st.st_ex_mode)) {
>                 return ret;
>         }
> 
>         /* find cached copy */
>         smb_fname_new = ssdcache_find_cached_file(handle, smb_fname);
> 
>         if (smb_fname_new != NULL) {
>                 smb_fname = smb_fname_new;
>                 ret = sys_stat(smb_fname->base_name, &smb_fname->st, true);
>         }
> 
>         return ret;
> }
> 
> It gave no results.
> Also realpath seems to be called only once at connect-to-share time.
> 
> I have no ideas left. I overwrite all possible stat structures in
> smb_filename, but somehow somewhere structure for original file persist.
> Judging to strace:
> 
> open(".cache/ssd03/1066/1066.1.avi", O_RDONLY) = 34
> fstat(34, {st_mode=S_IFREG|0666, st_size=727977984, ...}) = 0
> close(34)
> 
> I can conclude that original file stat structure is compared to the result
> of fstat call on the cached file descriptor. They are defenitely different,
> so I get an error.
> I want try to implement fstat function with dev/ino spoofing in my module,
> but stuck with NULL value of fsp->fsp_name->base_name and
> fsp->fsp_name->stream_name.
> Can't determine wheither fstat-ed descriptor's file exists in cache.
> 
> I appreciate any help. Thank you.

Can you post the entire source code of your vfs module please ?

That way I can take a look at it in entirity.



More information about the samba-technical mailing list