Changing smb_filename->base_name in VFS module.

Jeremy Allison jra at samba.org
Wed Sep 5 20:52:57 UTC 2018


On Wed, Sep 05, 2018 at 12:40:57PM +0300, Vadim Lazovskiy wrote:
> 
> 
> вт, 4 сент. 2018 г. в 20:13, Jeremy Allison <jra at samba.org>:
> 
> 
>     Can you post the entire source code of your vfs module please ?
> 
>     That way I can take a look at it in entirity.
> 
> 
> Sure!

Thanks ! Can you also send a debug level 10 log of failed
access from a client so we can see where it's going wrong
(info on what file is being requested would help).

Thanks,

	Jeremy.

> Vadim Lazovskiy

> #include <syslog.h>
> #include "includes.h"
> #include "include/smb.h"
> #include "smbd/proto.h"
> #include "system/filesys.h"
> 
> #include "includes.h"
> #include "system/filesys.h"
> #include "system/syslog.h"
> #include "smbd/smbd.h"
> #include "../librpc/gen_ndr/ndr_netlogon.h"
> #include "auth.h"
> #include "ntioctl.h"
> 
> #include "smbd/globals.h"
> #include "lib/tsocket/tsocket.h"
> 
> typedef struct vfs_ssdcache_module_ctx {
> 	unsigned char initialized;
> 	const char **cache_paths;
> 	size_t cache_path_max_len;
> } vfs_ssdcache_module_ctx_t;
> 
> const char *ssdcache_get_cache_path(vfs_handle_struct *handle, const char *path)
> {
> 	vfs_ssdcache_module_ctx_t *ctx;
> 	int i;
> 
> 	SMB_VFS_HANDLE_GET_DATA(handle, ctx, vfs_ssdcache_module_ctx_t, return NULL);
> 
> 	if (!ctx->initialized) {
> 		return NULL;
> 	}
> 
> 	for (i = 0; ctx->cache_paths[i]; i++) {
> 		if (strstr(path, ctx->cache_paths[i]) != NULL) {
> 			return ctx->cache_paths[i];
> 		}
> 	}
> 
> 	return NULL;
> }
> 
> void ssdcache_log_file_access(vfs_handle_struct *handle, const struct smb_filename *smb_fname)
> {
> 	const char *remote_addr;
> 	struct timeval tv;
> 
> 	gettimeofday(&tv, NULL);
> 
> 	remote_addr = tsocket_address_inet_addr_string(handle->conn->sconn->remote_address, handle->conn);
> 
> 	if (remote_addr == NULL) {
> 		return;
> 	}
> 
> 	syslog(LOG_INFO, "ssdcache: %s %lu.%03lu \"%s\"", remote_addr, tv.tv_sec, tv.tv_usec / 1000,  smb_fname->base_name);
> }
> 
> 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_open(vfs_handle_struct *handle, struct smb_filename *smb_fname, files_struct *fsp, int flags, mode_t mode)
> {
> 	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_OPEN(handle, smb_fname, fsp, flags, mode);
> 	}
> 
> 	/* stat file */
> 	if ((ret = sys_stat(smb_fname->base_name, &smb_fname->st, true)) != 0) {
> 		return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
> 	}
> 
> 	/* skip directories */
> 	if (S_ISDIR(smb_fname->st.st_ex_mode)) {
> 		return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
> 	}
> 
> 	syslog(LOG_INFO, "ssdcache: open file '%s'", smb_fname->base_name);
> 
> 	/* find cached copy */
> 	smb_fname_new = ssdcache_find_cached_file(handle, smb_fname);
> 	
> 	if (smb_fname_new != NULL) {
> 		TALLOC_FREE(smb_fname);
> 		smb_fname = smb_fname_new;
> 	} else {
> 		if (errno != ENOENT) {
> 			return -1;
> 		}
> 	}
> 
> 	sys_stat(smb_fname->base_name, &smb_fname->st, true);
> 
> 	ssdcache_log_file_access(handle, smb_fname);
> 	return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
> }
> 
> 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;
> 	const char *cache_path;
> 	char *new_base_name;
> 	size_t new_base_name_len;
> 
>         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;
> }
> 
> static int ssdcache_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
> {
> 	int result;
> 
> 	syslog(LOG_INFO, "ssdcache: fstat fd: %d, filename: %s %s %s", fsp->fh->fd, fsp->fsp_name->base_name, fsp->fsp_name->stream_name, fsp->fsp_name->original_lcomp);
> 
> 	result = sys_fstat(fsp->fh->fd, sbuf, lp_fake_directory_create_times(SNUM(handle->conn)));
> 	return result;
> }
> 
> static char *ssdcache_realpath(vfs_handle_struct *handle, const char *path)
> {
> 	syslog(LOG_INFO, "ssdcache: realpath file '%s'", path);
> 	return SMB_VFS_NEXT_REALPATH(handle, path);
> }
> 
> static int ssdcache_close(vfs_handle_struct *handle, files_struct *fsp)
> {
> 	return SMB_VFS_NEXT_CLOSE(handle, fsp);
> }
> 
> static int ssdcache_connect(vfs_handle_struct *handle, const char *svc, const char *user)
> {
> 	vfs_ssdcache_module_ctx_t *ctx;
> 
> 	size_t i, len;
> 
> 	ctx = talloc_zero(handle->conn, vfs_ssdcache_module_ctx_t);
> 
> 	if (!ctx) {
> 		SMB_VFS_NEXT_DISCONNECT(handle);
> 		return -1;
> 	}
> 
> 	ctx->cache_paths = lp_parm_string_list(SNUM(handle->conn), "ssdcache", "cache_paths", NULL);
> 
> 	if (!ctx->cache_paths || !ctx->cache_paths[0]) {
> 		syslog(LOG_INFO, "ssdcache: cache paths are not configured. Using normal open operations.");
> 		ctx->initialized = 0;
> 	} else {
> 		for (i = 0; ctx->cache_paths[i]; i++) {
> 			len = strlen(ctx->cache_paths[i]);
> 
> 			if(len > ctx->cache_path_max_len) {
> 				ctx->cache_path_max_len = len;
> 			}
> 		}
> 
> 		ctx->initialized = 1;
> 	}
> 
> 	SMB_VFS_HANDLE_SET_DATA(handle, ctx, NULL, vfs_ssdcache_module_ctx_t, return -1);
> 
>         return SMB_VFS_NEXT_CONNECT(handle, svc, user);
> }
> 
> static void ssdcache_disconnect(vfs_handle_struct *handle)
> {
> 	SMB_VFS_NEXT_DISCONNECT(handle);
> 	return;
> }
> 
> struct vfs_fn_pointers ssdcache_fns = {
> 	.realpath_fn = ssdcache_realpath,
> 	.stat_fn = ssdcache_stat,
> 	.fstat_fn = ssdcache_fstat,
> 	.open_fn = ssdcache_open,
> 	.close_fn = ssdcache_close,
> 	.connect_fn = ssdcache_connect,
> 	.disconnect_fn = ssdcache_disconnect,
> };
> 
> NTSTATUS vfs_ssdcache_init(void);
> NTSTATUS vfs_ssdcache_init(void)
> {
> 	return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "ssdcache", &ssdcache_fns);
> }




More information about the samba-technical mailing list