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