From c5d77a1c2414d930ccbedbe05e124df69242a144 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 26 Feb 2008 17:17:52 +0100 Subject: Move public header accumulation out of the perl code. (This used to be commit 89f7c74924965071981bbe7e05ff69847b0a3a03) --- source4/ntvfs/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index dbc1a4c277..0f8e88eaa6 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -80,13 +80,14 @@ OBJ_FILES = \ ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::ntvfs] -PUBLIC_HEADERS = ntvfs.h PRIVATE_PROTO_HEADER = ntvfs_proto.h OBJ_FILES = \ ntvfs_base.o \ ntvfs_generic.o \ ntvfs_interface.o \ ntvfs_util.o + +PUBLIC_HEADERS += ntvfs/ntvfs.h # # End SUBSYSTEM NTVFS ################################################ -- cgit From b29d47edcf2767d7f9e9f63332079c6e8e89946c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Mar 2008 18:25:28 +0100 Subject: Move object file lists to the Makefile. (This used to be commit a7e6d2a1832db388fdafa1279f84c9a8bbfc87d6) --- source4/ntvfs/common/config.mk | 10 +++------- source4/ntvfs/config.mk | 34 +++++++++++++--------------------- source4/ntvfs/posix/config.mk | 25 ++++++++++++++----------- source4/ntvfs/sysdep/config.mk | 9 ++++----- source4/ntvfs/unixuid/config.mk | 4 ++-- 5 files changed, 36 insertions(+), 46 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 2fc0942ed4..99a8a7af45 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -2,14 +2,10 @@ # Start LIBRARY ntvfs_common [SUBSYSTEM::ntvfs_common] PRIVATE_PROTO_HEADER = proto.h -OBJ_FILES = \ - init.o \ - brlock.o \ - brlock_tdb.o \ - opendb.o \ - opendb_tdb.o \ - notify.o PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share LIBDBWRAP PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ + +NTVFS_COMMON_OBJ_FILES = $(addprefix ntvfs/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) + diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 0f8e88eaa6..436fe11522 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -9,25 +9,24 @@ mkinclude sysdep/config.mk [MODULE::ntvfs_cifs] INIT_FUNCTION = ntvfs_cifs_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - cifs/vfs_cifs.o PRIVATE_DEPENDENCIES = \ LIBCLI_SMB LIBCLI_RAW # End MODULE ntvfs_cifs ################################################ +ntvfs_cifs_OBJ_FILES = ntvfs/cifs/vfs_cifs.o + ################################################ # Start MODULE ntvfs_simple [MODULE::ntvfs_simple] INIT_FUNCTION = ntvfs_simple_init SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = simple/proto.h -OBJ_FILES = \ - simple/vfs_simple.o \ - simple/svfs_util.o # End MODULE ntvfs_simple ################################################ +ntvfs_simple_OBJ_FILES = $(addprefix ntvfs/simple/, vfs_simple.o svfs_util.o) + ################################################ # Start MODULE ntvfs_cifsposix [MODULE::ntvfs_cifsposix] @@ -35,57 +34,50 @@ OBJ_FILES = \ INIT_FUNCTION = ntvfs_cifs_posix_init SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h -OBJ_FILES = \ - cifs_posix_cli/vfs_cifs_posix.o \ - cifs_posix_cli/svfs_util.o # End MODULE ntvfs_cifsposix ################################################ +ntvfs_cifsposix_OBJ_FILES = \ + $(addprefix ntvfs/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) + ################################################ # Start MODULE ntvfs_print [MODULE::ntvfs_print] INIT_FUNCTION = ntvfs_print_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - print/vfs_print.o # End MODULE ntvfs_print ################################################ +ntvfs_print_OBJ_FILES = ntvfs/print/vfs_print.o + ################################################ # Start MODULE ntvfs_ipc [MODULE::ntvfs_ipc] SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_ipc_init PRIVATE_PROTO_HEADER = ipc/proto.h -OBJ_FILES = \ - ipc/vfs_ipc.o \ - ipc/ipc_rap.o \ - ipc/rap_server.o PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON # End MODULE ntvfs_ipc ################################################ +ntvfs_ipc_OBJ_FILES = $(addprefix ntvfs/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) ################################################ # Start MODULE ntvfs_nbench [MODULE::ntvfs_nbench] SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_nbench_init -OBJ_FILES = \ - nbench/vfs_nbench.o # End MODULE ntvfs_nbench ################################################ +ntvfs_nbench_OBJ_FILES = ntvfs/nbench/vfs_nbench.o ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::ntvfs] PRIVATE_PROTO_HEADER = ntvfs_proto.h -OBJ_FILES = \ - ntvfs_base.o \ - ntvfs_generic.o \ - ntvfs_interface.o \ - ntvfs_util.o + +ntvfs_OBJ_FILES = $(addprefix ntvfs/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) PUBLIC_HEADERS += ntvfs/ntvfs.h # diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 88048c2af7..249f1ba3d8 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -3,30 +3,31 @@ [MODULE::pvfs_acl_xattr] INIT_FUNCTION = pvfs_acl_xattr_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - pvfs_acl_xattr.o PRIVATE_DEPENDENCIES = NDR_XATTR ntvfs_posix # End MODULE pvfs_acl_xattr ################################################ +pvfs_acl_xattr_OBJ_FILES = ntvfs/posix/pvfs_acl_xattr.o + ################################################ # Start MODULE pvfs_acl_nfs4 [MODULE::pvfs_acl_nfs4] INIT_FUNCTION = pvfs_acl_nfs4_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - pvfs_acl_nfs4.o PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix # End MODULE pvfs_acl_nfs4 ################################################ +pvfs_acl_nfs4_OBJ_FILES = ntvfs/posix/pvfs_acl_nfs4.o + ################################################ [MODULE::pvfs_aio] SUBSYSTEM = ntvfs -OBJ_FILES = pvfs_aio.o PRIVATE_DEPENDENCIES = LIBAIO_LINUX ################################################ +pvfs_aio_OBJ_FILES = ntvfs/posix/pvfs_aio.o + ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] @@ -34,7 +35,12 @@ SUBSYSTEM = ntvfs OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init PRIVATE_PROTO_HEADER = vfs_posix_proto.h -OBJ_FILES = \ +#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 +PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio +# End MODULE ntvfs_posix +################################################ + +ntvfs_posix_OBJ_FILES = $(addprefix ntvfs/posix/, \ vfs_posix.o \ pvfs_util.o \ pvfs_search.o \ @@ -62,8 +68,5 @@ OBJ_FILES = \ pvfs_acl.o \ pvfs_notify.o \ xattr_system.o \ - xattr_tdb.o -#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 -PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio -# End MODULE ntvfs_posix -################################################ + xattr_tdb.o) + diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index dee198c9da..6cd5d88aca 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -3,16 +3,15 @@ [MODULE::sys_notify_inotify] SUBSYSTEM = sys_notify INIT_FUNCTION = sys_notify_inotify_init -OBJ_FILES = \ - inotify.o # End MODULE sys_notify_inotify ################################################ +sys_notify_inotify_OBJ_FILES = ntvfs/sysdep/inotify.o + ################################################ # Start SUBSYSTEM sys_notify [SUBSYSTEM::sys_notify] -OBJ_FILES = \ - sys_notify.o -PUBLIC_DEPENDENCIES = # End SUBSYSTEM sys_notify ################################################ + +sys_notify_OBJ_FILES = ntvfs/sysdep/sys_notify.o diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 91976c6811..968e56bde4 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -3,8 +3,8 @@ [MODULE::ntvfs_unixuid] INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - vfs_unixuid.o PRIVATE_DEPENDENCIES = SAMDB NSS_WRAPPER # End MODULE ntvfs_unixuid ################################################ + +ntvfs_unixuid_OBJ_FILES = ntvfs/unixuid/vfs_unixuid.o -- cgit From a69acf7cb96bf41bafce303a2cf21c31f1366328 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 4 Mar 2008 01:37:18 +0100 Subject: Deal with subsystems with no settings, several other minor fixes. (This used to be commit 10cf48591e8d6bfb750a6ff187f04ea24a1f8cd7) --- source4/ntvfs/common/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 99a8a7af45..356f6465c3 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -7,5 +7,5 @@ PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ -NTVFS_COMMON_OBJ_FILES = $(addprefix ntvfs/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) +ntvfs_common_OBJ_FILES = $(addprefix ntvfs/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) -- cgit From 2bf39edc9d0abf3306bd25b9c40d88aceb029be7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Mar 2008 15:28:12 +0100 Subject: Push SOVERSION and VERSION out of perl code. (This used to be commit 0ba8ac6a14c62ff9edfe9f0bf43b8a7406b85291) --- source4/ntvfs/ntvfs_base.c | 1 - source4/ntvfs/sysdep/sys_notify.c | 1 - 2 files changed, 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 35becabcf9..0cffdb7fa9 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -24,7 +24,6 @@ #include "includes.h" #include "lib/util/dlinklist.h" -#include "build.h" #include "ntvfs/ntvfs.h" #include "param/param.h" diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 84ba745f5b..e5d6c75f71 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -28,7 +28,6 @@ #include "lib/events/events.h" #include "lib/util/dlinklist.h" #include "param/param.h" -#include "build.h" /* list of registered backends */ static struct sys_notify_backend *backends; -- cgit From fb6fdfce37a91021c346a52bd7d55a5ee576580a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Mar 2008 17:02:40 +0100 Subject: Fix the build. (This used to be commit f2e49744717eb46bbfafeea9e2eb412a38a142e7) --- source4/ntvfs/ntvfs_base.c | 10 ++++++++++ source4/ntvfs/sysdep/sys_notify.c | 1 + 2 files changed, 11 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 0cffdb7fa9..4cd6192c77 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -203,6 +203,16 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) { static bool initialized = false; + extern NTSTATUS ntvfs_posix_init(void); + extern NTSTATUS ntvfs_cifs_init(void); + extern NTSTATUS ntvfs_nbench_init(void); + extern NTSTATUS ntvfs_unixuid_init(void); + extern NTSTATUS ntvfs_ipc_init(void); + extern NTSTATUS pvfs_acl_nfs4_init(void); + extern NTSTATUS pvfs_acl_xattr_init(void); + extern NTSTATUS ntvfs_print_init(void); + extern NTSTATUS ntvfs_simple_init(void); + extern NTSTATUS ntvfs_cifs_posix_init(void); init_module_fn static_init[] = { STATIC_ntvfs_MODULES }; init_module_fn *shared_init; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index e5d6c75f71..c628b9068c 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -123,6 +123,7 @@ _PUBLIC_ NTSTATUS sys_notify_register(struct sys_notify_backend *backend) _PUBLIC_ NTSTATUS sys_notify_init(void) { static bool initialized = false; + extern NTSTATUS sys_notify_inotify_init(void); init_module_fn static_init[] = { STATIC_sys_notify_MODULES }; -- cgit From 275f32ae2df333c089343dd20fc4efee1bed2b7b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Apr 2008 11:31:17 +0200 Subject: fill in unknown fields in SMB2 READ call (This used to be commit 9b686c138037f613da15168d0722786e00f023e5) --- source4/ntvfs/ntvfs_generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index e1a86c07c0..fee3269eaf 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1214,7 +1214,8 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs, break; case RAW_READ_SMB2: rd->smb2.out.data.length= rd2->generic.out.nread; - rd->smb2.out.unknown1 = 0; + rd->smb2.out.remaining = 0; + rd->smb2.out.reserved = 0; break; default: return NT_STATUS_INVALID_LEVEL; -- cgit From f78bc8c489b02b521e9ecbdbdc72d160c6911b6b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 11:54:50 +0200 Subject: Remove prototypes from build.h in preparation of removing build.h altogether. (This used to be commit dbeab2a9cdee4e5f69afeb2603ba29cbed56debd) --- source4/ntvfs/ntvfs_base.c | 10 ++++++++++ source4/ntvfs/sysdep/sys_lease.c | 1 + source4/ntvfs/sysdep/sys_notify.c | 1 + 3 files changed, 12 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 51faa44372..8f574fa96b 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -204,6 +204,16 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) { static bool initialized = false; + extern NTSTATUS ntvfs_posix_init(void); + extern NTSTATUS ntvfs_cifs_init(void); + extern NTSTATUS ntvfs_nbench_init(void); + extern NTSTATUS ntvfs_unixuid_init(void); + extern NTSTATUS ntvfs_ipc_init(void); + extern NTSTATUS pvfs_acl_nfs4_init(void); + extern NTSTATUS pvfs_acl_xattr_init(void); + extern NTSTATUS ntvfs_print_init(void); + extern NTSTATUS ntvfs_simple_init(void); + extern NTSTATUS ntvfs_cifs_posix_init(void); init_module_fn static_init[] = { STATIC_ntvfs_MODULES }; init_module_fn *shared_init; diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c index 28dd27a708..b8a165aa51 100644 --- a/source4/ntvfs/sysdep/sys_lease.c +++ b/source4/ntvfs/sysdep/sys_lease.c @@ -112,6 +112,7 @@ _PUBLIC_ NTSTATUS sys_lease_register(const struct sys_lease_ops *backend) _PUBLIC_ NTSTATUS sys_lease_init(void) { static bool initialized = false; + extern NTSTATUS sys_lease_linux_init(void); init_module_fn static_init[] = { STATIC_sys_lease_MODULES }; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 84ba745f5b..eb5cc3793f 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -124,6 +124,7 @@ _PUBLIC_ NTSTATUS sys_notify_register(struct sys_notify_backend *backend) _PUBLIC_ NTSTATUS sys_notify_init(void) { static bool initialized = false; + extern NTSTATUS sys_notify_inotify_init(void); init_module_fn static_init[] = { STATIC_sys_notify_MODULES }; -- cgit From e9017ba418202b4b191c5a9ad4a96857558ce606 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 17:22:58 +0200 Subject: Use _OBJ_FILES variables in a couple more places. (This used to be commit 92856d5054106894b65cd1a1b5119c0facfc4cff) --- source4/ntvfs/common/config.mk | 15 ++++----------- source4/ntvfs/config.mk | 34 +++++++++++++--------------------- source4/ntvfs/posix/config.mk | 26 +++++++++++++++----------- source4/ntvfs/sysdep/config.mk | 26 ++++++++------------------ source4/ntvfs/unixuid/config.mk | 4 ++-- 5 files changed, 42 insertions(+), 63 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 3963ebcdee..c66257b73f 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -2,17 +2,10 @@ # Start LIBRARY ntvfs_common [SUBSYSTEM::ntvfs_common] PRIVATE_PROTO_HEADER = proto.h -OBJ_FILES = \ - init.o \ - brlock.o \ - brlock_tdb.o \ - opendb.o \ - opendb_tdb.o \ - notify.o -PUBLIC_DEPENDENCIES = \ - NDR_OPENDB NDR_NOTIFY \ - sys_notify sys_lease \ - share LIBDBWRAP +PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify sys_lease share LIBDBWRAP PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ + +ntvfs_common_OBJ_FILES = $(addprefix ntvfs/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) + diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 2f57c787ef..93cbf64d8f 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -9,25 +9,24 @@ mkinclude sysdep/config.mk [MODULE::ntvfs_cifs] INIT_FUNCTION = ntvfs_cifs_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - cifs/vfs_cifs.o PRIVATE_DEPENDENCIES = \ LIBCLI_SMB LIBCLI_RAW # End MODULE ntvfs_cifs ################################################ +ntvfs_cifs_OBJ_FILES = ntvfs/cifs/vfs_cifs.o + ################################################ # Start MODULE ntvfs_simple [MODULE::ntvfs_simple] INIT_FUNCTION = ntvfs_simple_init SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = simple/proto.h -OBJ_FILES = \ - simple/vfs_simple.o \ - simple/svfs_util.o # End MODULE ntvfs_simple ################################################ +ntvfs_simple_OBJ_FILES = $(addprefix ntvfs/simple/, vfs_simple.o svfs_util.o) + ################################################ # Start MODULE ntvfs_cifsposix [MODULE::ntvfs_cifsposix] @@ -35,57 +34,50 @@ OBJ_FILES = \ INIT_FUNCTION = ntvfs_cifs_posix_init SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h -OBJ_FILES = \ - cifs_posix_cli/vfs_cifs_posix.o \ - cifs_posix_cli/svfs_util.o # End MODULE ntvfs_cifsposix ################################################ +ntvfs_cifsposix_OBJ_FILES = \ + $(addprefix ntvfs/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) + ################################################ # Start MODULE ntvfs_print [MODULE::ntvfs_print] INIT_FUNCTION = ntvfs_print_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - print/vfs_print.o # End MODULE ntvfs_print ################################################ +ntvfs_print_OBJ_FILES = ntvfs/print/vfs_print.o + ################################################ # Start MODULE ntvfs_ipc [MODULE::ntvfs_ipc] SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_ipc_init PRIVATE_PROTO_HEADER = ipc/proto.h -OBJ_FILES = \ - ipc/vfs_ipc.o \ - ipc/ipc_rap.o \ - ipc/rap_server.o PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON # End MODULE ntvfs_ipc ################################################ +ntvfs_ipc_OBJ_FILES = $(addprefix ntvfs/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) ################################################ # Start MODULE ntvfs_nbench [MODULE::ntvfs_nbench] SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_nbench_init -OBJ_FILES = \ - nbench/vfs_nbench.o # End MODULE ntvfs_nbench ################################################ +ntvfs_nbench_OBJ_FILES = ntvfs/nbench/vfs_nbench.o ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::ntvfs] PRIVATE_PROTO_HEADER = ntvfs_proto.h -OBJ_FILES = \ - ntvfs_base.o \ - ntvfs_generic.o \ - ntvfs_interface.o \ - ntvfs_util.o + +ntvfs_OBJ_FILES = $(addprefix ntvfs/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) # PUBLIC_HEADERS += ntvfs/ntvfs.h # diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 88048c2af7..865a0ffd4a 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -3,30 +3,31 @@ [MODULE::pvfs_acl_xattr] INIT_FUNCTION = pvfs_acl_xattr_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - pvfs_acl_xattr.o PRIVATE_DEPENDENCIES = NDR_XATTR ntvfs_posix # End MODULE pvfs_acl_xattr ################################################ +pvfs_acl_xattr_OBJ_FILES = ntvfs/posix/pvfs_acl_xattr.o + ################################################ # Start MODULE pvfs_acl_nfs4 [MODULE::pvfs_acl_nfs4] INIT_FUNCTION = pvfs_acl_nfs4_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - pvfs_acl_nfs4.o PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix # End MODULE pvfs_acl_nfs4 ################################################ +pvfs_acl_nfs4_OBJ_FILES = ntvfs/posix/pvfs_acl_nfs4.o + ################################################ [MODULE::pvfs_aio] SUBSYSTEM = ntvfs -OBJ_FILES = pvfs_aio.o PRIVATE_DEPENDENCIES = LIBAIO_LINUX ################################################ +pvfs_aio_OBJ_FILES = ntvfs/posix/pvfs_aio.o + ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] @@ -34,7 +35,13 @@ SUBSYSTEM = ntvfs OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init PRIVATE_PROTO_HEADER = vfs_posix_proto.h -OBJ_FILES = \ +#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 +PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio \ + LIBWBCLIENT +# End MODULE ntvfs_posix +################################################ + +ntvfs_posix_OBJ_FILES = $(addprefix ntvfs/posix/, \ vfs_posix.o \ pvfs_util.o \ pvfs_search.o \ @@ -62,8 +69,5 @@ OBJ_FILES = \ pvfs_acl.o \ pvfs_notify.o \ xattr_system.o \ - xattr_tdb.o -#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 -PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio -# End MODULE ntvfs_posix -################################################ + xattr_tdb.o) + diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index 048226efad..de445bff7b 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -3,34 +3,24 @@ [MODULE::sys_notify_inotify] SUBSYSTEM = sys_notify INIT_FUNCTION = sys_notify_inotify_init -OBJ_FILES = \ - inotify.o # End MODULE sys_notify_inotify ################################################ +sys_notify_inotify_OBJ_FILES = ntvfs/sysdep/inotify.o + ################################################ # Start SUBSYSTEM sys_notify [SUBSYSTEM::sys_notify] -OBJ_FILES = \ - sys_notify.o -PUBLIC_DEPENDENCIES = # End SUBSYSTEM sys_notify ################################################ -################################################ -# Start MODULE sys_lease_linux +sys_notify_OBJ_FILES = ntvfs/sysdep/sys_notify.o + [MODULE::sys_lease_linux] SUBSYSTEM = sys_lease -INIT_FUNCTION = sys_lease_linux_init -OBJ_FILES = \ - sys_lease_linux.o -# End MODULE sys_lease_linux -################################################ -################################################ -# Start SUBSYSTEM sys_lease +sys_lease_linux_OBJ_FILES = ntvfs/sysdep/sys_lease_linux.o + [SUBSYSTEM::sys_lease] -OBJ_FILES = \ - sys_lease.o -# End SUBSYSTEM sys_lease -################################################ + +sys_lease_OBJ_FILES = ntvfs/sysdep/sys_lease.o diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 91976c6811..968e56bde4 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -3,8 +3,8 @@ [MODULE::ntvfs_unixuid] INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - vfs_unixuid.o PRIVATE_DEPENDENCIES = SAMDB NSS_WRAPPER # End MODULE ntvfs_unixuid ################################################ + +ntvfs_unixuid_OBJ_FILES = ntvfs/unixuid/vfs_unixuid.o -- cgit From 292ed5d04f9b7442bf878c36be24a46fc0373d9c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Apr 2008 18:44:43 +0200 Subject: fixed an unitialised write warning in valgrind the 'reserved' field was not being initialised before being pushed to the wire (This used to be commit dfe4b5009885c4eeca24569f35b9fc85bfe6346b) --- source4/ntvfs/ntvfs_generic.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index fee3269eaf..01c3a16433 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -209,6 +209,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, case RAW_OPEN_SMB2: io->smb2.out.file.ntvfs = io2->generic.out.file.ntvfs; io->smb2.out.oplock_level = 0; + io->smb2.out.reserved = 0; io->smb2.out.create_action = io2->generic.out.create_action; io->smb2.out.create_time = io2->generic.out.create_time; io->smb2.out.access_time = io2->generic.out.access_time; -- cgit From 79af7ff2f7f6fabe8a2a48386088228096e218b4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Apr 2008 18:59:40 +0200 Subject: fixed a valgrind error in id mapping the status field is sent on both call and reply, but was only being initialised on reply (This used to be commit 2ebd7b80998775168959d511fbc987f8b5b7bd34) --- source4/ntvfs/posix/pvfs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 2393a2e7a3..f1e469f790 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -135,7 +135,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, } sd = *psd; - ids = talloc_array(sd, struct id_mapping, 2); + ids = talloc_zero_array(sd, struct id_mapping, 2); NT_STATUS_HAVE_NO_MEMORY(ids); ids[0].unixid = talloc(ids, struct unixid); -- cgit From a195cd9d8f3d0c0185fbf82388bd1efaa63e7bd5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 16 Apr 2008 22:52:07 +0200 Subject: Use readily available event context. (This used to be commit 2823fca23a4cacc996c808f22cba50b4482b5921) --- source4/ntvfs/posix/vfs_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ebc2d88e70..14b5210fd0 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -219,7 +219,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->ntvfs->ctx->server_id, pvfs->ntvfs->ctx->msg_ctx, pvfs->ntvfs->ctx->lp_ctx, - event_context_find(pvfs), + pvfs->ntvfs->ctx->event_ctx, pvfs->ntvfs->ctx->config); pvfs->wbc_ctx = wbc_init(pvfs, -- cgit From 1efbd5fbf6b0f606ed29a763e2adfa6f99c6beac Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 01:03:18 +0200 Subject: Remove event context tracking from the credentials struct. (This used to be commit 4d7fc946b2ec50e774689c9036423b6feef99b8e) --- source4/ntvfs/cifs/vfs_cifs.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 2feb1a0efe..2b61268733 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -171,7 +171,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, if (!credentials) { return NT_STATUS_NO_MEMORY; } - cli_credentials_set_event_context(credentials, ntvfs->ctx->event_ctx); cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); cli_credentials_set_username(credentials, user, CRED_SPECIFIED); if (domain) { @@ -181,7 +180,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, } else if (machine_account) { DEBUG(5, ("CIFS backend: Using machine account\n")); credentials = cli_credentials_init(private); - cli_credentials_set_event_context(credentials, ntvfs->ctx->event_ctx); cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); -- cgit From c15ffa27cb3a1cadbbf06d564146c1ab8dec952b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 01:19:53 +0200 Subject: Explicitly require event context to be specified. (This used to be commit a95a71fe45ef6a578569931a7c38061783d07db3) --- source4/ntvfs/common/notify.c | 4 ++++ source4/ntvfs/sysdep/sys_notify.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 23aa3fb668..9055d6ece3 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -93,6 +93,10 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, return NULL; } + if (ev == NULL) { + return NULL; + } + notify = talloc(mem_ctx, struct notify_context); if (notify == NULL) { return NULL; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index eb5cc3793f..22b72c4d63 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -52,7 +52,7 @@ _PUBLIC_ struct sys_notify_context *sys_notify_context_create(struct share_confi } if (ev == NULL) { - ev = event_context_find(mem_ctx); + return NULL; } ctx = talloc_zero(mem_ctx, struct sys_notify_context); -- cgit From 14023e502b7a1043afe0dde7f1c60a4b29a76646 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 01:22:39 +0200 Subject: Require explicit event context rather than looking if it is not specified. (This used to be commit 1da0063bd5fd18ad3ac7a07c985ec6be380486e2) --- source4/ntvfs/sysdep/sys_lease.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c index b8a165aa51..e6b11c450a 100644 --- a/source4/ntvfs/sysdep/sys_lease.c +++ b/source4/ntvfs/sysdep/sys_lease.c @@ -55,7 +55,7 @@ _PUBLIC_ struct sys_lease_context *sys_lease_context_create(struct share_config } if (ev == NULL) { - ev = event_context_find(mem_ctx); + return NULL; } ctx = talloc_zero(mem_ctx, struct sys_lease_context); -- cgit From baad7a7e56e2b0f24885e01672cd9bdc6667a6a8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 17 Apr 2008 03:54:26 +0200 Subject: ntvfs_generic: map SMB2 oplock levels to the generic ones metze (This used to be commit 9013748273378f88bfc66d3583814f0fee67c40f) --- source4/ntvfs/ntvfs_generic.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index fee3269eaf..5d4bbf388c 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -208,7 +208,21 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, case RAW_OPEN_SMB2: io->smb2.out.file.ntvfs = io2->generic.out.file.ntvfs; - io->smb2.out.oplock_level = 0; + switch (io2->generic.out.oplock_level) { + case OPLOCK_BATCH: + io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_BATCH; + break; + case OPLOCK_EXCLUSIVE: + io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; + break; + case OPLOCK_LEVEL_II: + io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_II; + break; + default: + io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_NONE; + break; + } + io->smb2.out.reserved = 0; io->smb2.out.create_action = io2->generic.out.create_action; io->smb2.out.create_time = io2->generic.out.create_time; io->smb2.out.access_time = io2->generic.out.access_time; @@ -484,7 +498,18 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_SMB2: - io2->generic.in.flags = 0; + switch (io->smb2.in.oplock_level) { + case SMB2_OPLOCK_LEVEL_BATCH: + io2->generic.in.flags = NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK | + NTCREATEX_FLAGS_REQUEST_OPLOCK; + break; + case SMB2_OPLOCK_LEVEL_EXCLUSIVE: + io2->generic.in.flags = NTCREATEX_FLAGS_REQUEST_OPLOCK; + break; + default: + io2->generic.in.flags = 0; + break; + } io2->generic.in.root_fid = 0; io2->generic.in.access_mask = io->smb2.in.desired_access; io2->generic.in.alloc_size = 0; -- cgit From 21fc7673780aa1d7c0caab7b17ff9171238913ba Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 12:23:44 +0200 Subject: Specify event_context to ldb_wrap_connect explicitly. (This used to be commit b4e1ae07a284c044704322446c94351c2decff91) --- source4/ntvfs/ipc/ipc_rap.c | 11 ++++++++--- source4/ntvfs/ipc/rap_server.c | 3 ++- source4/ntvfs/ipc/vfs_ipc.c | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index faf48705c4..4969f1a791 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/interfaces.h" #include "libcli/rap/rap.h" +#include "events/events.h" #include "ntvfs/ipc/proto.h" #include "librpc/ndr/libndr.h" #include "param/param.h" @@ -100,11 +101,14 @@ struct rap_call { struct ndr_pull *ndr_pull_param; struct ndr_pull *ndr_pull_data; + + struct event_context *event_ctx; }; #define RAPNDR_FLAGS (LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct smb_trans2 *trans) { @@ -118,6 +122,7 @@ static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, ZERO_STRUCTP(call); call->lp_ctx = talloc_reference(call, lp_ctx); + call->event_ctx = ev_ctx; call->mem_ctx = mem_ctx; @@ -271,7 +276,7 @@ static NTSTATUS _rap_netshareenum(struct rap_call *call) break; } - result = rap_netshareenum(call, call->lp_ctx, &r); + result = rap_netshareenum(call, call->event_ctx, call->lp_ctx, &r); if (!NT_STATUS_IS_OK(result)) return result; @@ -430,7 +435,7 @@ static const struct {NULL, -1, api_Unsupported} }; -NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, +NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, struct loadparm_context *lp_ctx, struct smb_trans2 *trans) { int i; @@ -440,7 +445,7 @@ NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct ndr_push *final_param; struct ndr_push *final_data; - call = new_rap_srv_call(mem_ctx, lp_ctx, trans); + call = new_rap_srv_call(mem_ctx, event_ctx, lp_ctx, trans); if (call == NULL) return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 633f0bf36e..d9fb7e21b2 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -29,6 +29,7 @@ * idea. */ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx, struct loadparm_context *lp_ctx, struct rap_NetShareEnum *r) { @@ -42,7 +43,7 @@ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, r->out.available = 0; r->out.info = NULL; - nterr = share_get_context_by_name(mem_ctx, lp_share_backend(lp_ctx), lp_ctx, &sctx); + nterr = share_get_context_by_name(mem_ctx, lp_share_backend(lp_ctx), event_ctx, lp_ctx, &sctx); if (!NT_STATUS_IS_OK(nterr)) { return nterr; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 92f0eadae1..ea7b54ae6a 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -805,7 +805,7 @@ static NTSTATUS ipc_trans(struct ntvfs_module_context *ntvfs, NTSTATUS status; if (strequal(trans->in.trans_name, "\\PIPE\\LANMAN")) - return ipc_rap_call(req, ntvfs->ctx->lp_ctx, trans); + return ipc_rap_call(req, ntvfs->ctx->event_ctx, ntvfs->ctx->lp_ctx, trans); if (trans->in.setup_count != 2) { return NT_STATUS_INVALID_PARAMETER; -- cgit From b2f2c1486e9c6bd6fdba3dc321f9df0d29d7def2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 19 Apr 2008 00:14:52 +0200 Subject: ntvfs_generic: fix mapping the granted oplocks for SMB2 metze (This used to be commit 60c4a4fc1afe88716ac63d3ea430e07fea7b9991) --- source4/ntvfs/ntvfs_generic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 5d4bbf388c..debcfc3f8a 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -209,13 +209,13 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, case RAW_OPEN_SMB2: io->smb2.out.file.ntvfs = io2->generic.out.file.ntvfs; switch (io2->generic.out.oplock_level) { - case OPLOCK_BATCH: + case BATCH_OPLOCK_RETURN: io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_BATCH; break; - case OPLOCK_EXCLUSIVE: + case EXCLUSIVE_OPLOCK_RETURN: io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; break; - case OPLOCK_LEVEL_II: + case LEVEL_II_OPLOCK_RETURN: io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_II; break; default: -- cgit From 39d23027218c02dc3055d8a0cc28dcc169e8b064 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Apr 2008 22:32:25 +0200 Subject: ntvfs_generic: map RAW_LOCK_SMB2_BREAK to RAW_LOCK_GENERIC metze (This used to be commit b781bb733c9a563457f87c94abe8c91b426c07ee) --- source4/ntvfs/ntvfs_generic.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index debcfc3f8a..3653ad82c1 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1043,6 +1043,23 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, /* initialize output value */ lck->smb2.out.unknown1 = 0; break; + + case RAW_LOCK_SMB2_BREAK: + lck2->generic.level = RAW_LOCK_GENERIC; + lck2->generic.in.file.ntvfs = lck->smb2_break.in.file.ntvfs; + lck2->generic.in.mode = LOCKING_ANDX_OPLOCK_RELEASE | + ((lck->smb2_break.in.oplock_level << 8) & 0xFF00); + lck2->generic.in.timeout = 0; + lck2->generic.in.ulock_cnt = 0; + lck2->generic.in.lock_cnt = 0; + lck2->generic.in.locks = NULL; + + /* initialize output value */ + lck->smb2_break.out.oplock_level= lck->smb2_break.in.oplock_level; + lck->smb2_break.out.reserved = lck->smb2_break.in.reserved; + lck->smb2_break.out.reserved2 = lck->smb2_break.in.reserved2; + lck->smb2_break.out.file = lck->smb2_break.in.file; + break; } /* -- cgit From 3e80085fb09a89957991780f79f5726029b8a26f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 7 May 2008 15:46:22 +0200 Subject: pvfs: remove XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME code I'll fix this more correctly very soon, so that we'll pass the BASE-DELAYWRITE test. metze (This used to be commit b09dd6b65d533832a025a51509dcc84f84b048aa) --- source4/ntvfs/posix/pvfs_open.c | 17 ----------------- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 -- source4/ntvfs/posix/pvfs_xattr.c | 32 +++++++++++++++----------------- source4/ntvfs/posix/vfs_posix.h | 3 --- 4 files changed, 15 insertions(+), 39 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 6e77cb7c75..c9c1c56f14 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -262,7 +262,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->position = 0; f->handle->mode = 0; f->handle->oplock = NULL; - f->handle->sticky_write_time = false; f->handle->open_completed = false; if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && @@ -416,16 +415,6 @@ cleanup_delete: */ static int pvfs_handle_destructor(struct pvfs_file_handle *h) { - /* the write time is no longer sticky */ - if (h->sticky_write_time) { - NTSTATUS status; - status = pvfs_dosattrib_load(h->pvfs, h->name, h->fd); - if (NT_STATUS_IS_OK(status)) { - h->name->dos.flags &= ~XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; - pvfs_dosattrib_save(h->pvfs, h->name, h->fd); - } - } - if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && h->name->stream_name) { NTSTATUS status; @@ -707,7 +696,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->mode = 0; f->handle->oplock = NULL; f->handle->have_opendb_entry = true; - f->handle->sticky_write_time = false; f->handle->open_completed = false; status = odb_open_file(lck, f->handle, name->full_name, @@ -1257,7 +1245,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->mode = 0; f->handle->oplock = NULL; f->handle->have_opendb_entry = false; - f->handle->sticky_write_time = false; f->handle->open_completed = false; /* form the lock context used for byte range locking and @@ -1479,10 +1466,6 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, unix_times.actime = 0; unix_times.modtime = io->close.in.write_time; utime(f->handle->name->full_name, &unix_times); - } else if (f->handle->sticky_write_time) { - unix_times.actime = 0; - unix_times.modtime = nt_time_to_unix(f->handle->name->dos.write_time); - utime(f->handle->name->full_name, &unix_times); } talloc_free(f); diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index ad47fe90c9..0beca75ead 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -342,8 +342,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } if (!null_nttime(info->basic_info.in.write_time)) { newstats.dos.write_time = info->basic_info.in.write_time; - newstats.dos.flags |= XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; - h->sticky_write_time = true; } if (!null_nttime(info->basic_info.in.change_time)) { newstats.dos.change_time = info->basic_info.in.change_time; diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 3043b80538..3cbbcbe92f 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -162,7 +162,7 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name struct xattr_DosAttrib attrib; TALLOC_CTX *mem_ctx = talloc_new(name); struct xattr_DosInfo1 *info1; - struct xattr_DosInfo2 *info2; + struct xattr_DosInfo2Old *info2; if (name->stream_name != NULL) { name->stream_exists = false; @@ -210,7 +210,11 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name break; case 2: - info2 = &attrib.info.info2; + /* + * Note: This is only used to parse existing values from disk + * We use xattr_DosInfo1 again for storing new values + */ + info2 = &attrib.info.oldinfo2; name->dos.attrib = pvfs_attrib_normalise(info2->attrib, name->st.st_mode); name->dos.ea_size = info2->ea_size; @@ -225,9 +229,6 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name name->dos.change_time = info2->change_time; } name->dos.flags = info2->flags; - if (name->dos.flags & XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME) { - name->dos.write_time = info2->write_time; - } break; default: @@ -250,26 +251,23 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name NTSTATUS pvfs_dosattrib_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) { struct xattr_DosAttrib attrib; - struct xattr_DosInfo2 *info2; + struct xattr_DosInfo1 *info1; if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { return NT_STATUS_OK; } - attrib.version = 2; - info2 = &attrib.info.info2; + attrib.version = 1; + info1 = &attrib.info.info1; name->dos.attrib = pvfs_attrib_normalise(name->dos.attrib, name->st.st_mode); - info2->attrib = name->dos.attrib; - info2->ea_size = name->dos.ea_size; - info2->size = name->st.st_size; - info2->alloc_size = name->dos.alloc_size; - info2->create_time = name->dos.create_time; - info2->change_time = name->dos.change_time; - info2->write_time = name->dos.write_time; - info2->flags = name->dos.flags; - info2->name = ""; + info1->attrib = name->dos.attrib; + info1->ea_size = name->dos.ea_size; + info1->size = name->st.st_size; + info1->alloc_size = name->dos.alloc_size; + info1->create_time = name->dos.create_time; + info1->change_time = name->dos.change_time; return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, XATTR_DOSATTRIB_NAME, &attrib, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 441424142f..c194698b64 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -169,9 +169,6 @@ struct pvfs_file_handle { /* we need this hook back to our parent for lock destruction */ struct pvfs_state *pvfs; - /* have we set a sticky write time that we should remove on close */ - bool sticky_write_time; - /* the open went through to completion */ bool open_completed; }; -- cgit From 7c7de11f20c5330c40c24d341056fb92806bbf37 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 May 2008 01:53:11 +0200 Subject: Fix LDB module initialization when using external ldb. (This used to be commit b7b4aff8b52742d69526dc0ef5da2fe3c05e3af8) --- source4/ntvfs/sysdep/sys_lease.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c index e6b11c450a..a0322bbcc1 100644 --- a/source4/ntvfs/sysdep/sys_lease.c +++ b/source4/ntvfs/sysdep/sys_lease.c @@ -28,7 +28,6 @@ #include "lib/events/events.h" #include "lib/util/dlinklist.h" #include "param/param.h" -#include "build.h" /* list of registered backends */ static struct sys_lease_ops *backends; @@ -109,6 +108,10 @@ _PUBLIC_ NTSTATUS sys_lease_register(const struct sys_lease_ops *backend) return NT_STATUS_OK; } +#ifndef STATIC_sys_lease_MODULES +#define STATIC_sys_lease_MODULES NULL +#endif + _PUBLIC_ NTSTATUS sys_lease_init(void) { static bool initialized = false; -- cgit From ca3257b286ed2e1b87a7d56ba290d01cd2078023 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 May 2008 10:57:22 +1000 Subject: started new vfs_smb2 module This new module is based on the vfs_cifs module. The idea is to create a backend which maps SMB requests to a SMB2 server. This will allow existing test suites for SMB to be run against our SMB2 client and server code. It will also help validate our SMB2 client library, probably leading to some API changes to make it flexible enough (This used to be commit 6ea8295a64ff5425def11b0d1cd988ef000320be) --- source4/ntvfs/config.mk | 14 + source4/ntvfs/ntvfs_base.c | 1 + source4/ntvfs/smb2/vfs_smb2.c | 1137 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1152 insertions(+) create mode 100644 source4/ntvfs/smb2/vfs_smb2.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 93cbf64d8f..ceb952d25c 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -16,6 +16,20 @@ PRIVATE_DEPENDENCIES = \ ntvfs_cifs_OBJ_FILES = ntvfs/cifs/vfs_cifs.o + +################################################ +# Start MODULE ntvfs_smb2 +[MODULE::ntvfs_smb2] +INIT_FUNCTION = ntvfs_smb2_init +SUBSYSTEM = ntvfs +PRIVATE_DEPENDENCIES = \ + LIBCLI_SMB LIBCLI_RAW +# End MODULE ntvfs_smb2 +################################################ + +ntvfs_smb2_OBJ_FILES = ntvfs/smb2/vfs_smb2.o + + ################################################ # Start MODULE ntvfs_simple [MODULE::ntvfs_simple] diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 3706cd172c..6de13e4a0a 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -205,6 +205,7 @@ NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) static bool initialized = false; extern NTSTATUS ntvfs_posix_init(void); extern NTSTATUS ntvfs_cifs_init(void); + extern NTSTATUS ntvfs_smb2_init(void); extern NTSTATUS ntvfs_nbench_init(void); extern NTSTATUS ntvfs_unixuid_init(void); extern NTSTATUS ntvfs_ipc_init(void); diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c new file mode 100644 index 0000000000..f253fcecaf --- /dev/null +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -0,0 +1,1137 @@ +/* + Unix SMB/CIFS implementation. + + CIFS-to-SMB2 NTVFS filesystem backend + + Copyright (C) Andrew Tridgell 2008 + + largely based on vfs_cifs.c which was + Copyright (C) Andrew Tridgell 2003 + Copyright (C) James J Myers 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/* + this implements a CIFS->CIFS NTVFS filesystem backend. + +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" +#include "libcli/smb_composite/smb_composite.h" +#include "auth/auth.h" +#include "auth/credentials/credentials.h" +#include "ntvfs/ntvfs.h" +#include "lib/util/dlinklist.h" +#include "param/param.h" +#include "libcli/resolve/resolve.h" + +struct cvfs_file { + struct cvfs_file *prev, *next; + uint16_t fnum; + struct ntvfs_handle *h; +}; + +/* this is stored in ntvfs_private */ +struct cvfs_private { + struct smbcli_tree *tree; + struct smbcli_transport *transport; + struct ntvfs_module_context *ntvfs; + struct async_info *pending; + struct cvfs_file *files; + bool map_generic; + bool map_trans2; +}; + + +/* a structure used to pass information to an async handler */ +struct async_info { + struct async_info *next, *prev; + struct cvfs_private *cvfs; + struct ntvfs_request *req; + struct smbcli_request *c_req; + struct cvfs_file *f; + void *parms; +}; + +#define SETUP_PID private->tree->session->pid = req->smbpid + +#define SETUP_FILE_HERE(f) do { \ + f = ntvfs_handle_get_backend_data(io->generic.in.file.ntvfs, ntvfs); \ + if (!f) return NT_STATUS_INVALID_HANDLE; \ + io->generic.in.file.fnum = f->fnum; \ +} while (0) + +#define SETUP_FILE do { \ + struct cvfs_file *f; \ + SETUP_FILE_HERE(f); \ +} while (0) + +#define SETUP_PID_AND_FILE do { \ + SETUP_PID; \ + SETUP_FILE; \ +} while (0) + +#define CIFS_SERVER "cifs:server" +#define CIFS_USER "cifs:user" +#define CIFS_PASSWORD "cifs:password" +#define CIFS_DOMAIN "cifs:domain" +#define CIFS_SHARE "cifs:share" +#define CIFS_USE_MACHINE_ACCT "cifs:use-machine-account" +#define CIFS_MAP_GENERIC "cifs:map-generic" +#define CIFS_MAP_TRANS2 "cifs:map-trans2" + +#define CIFS_USE_MACHINE_ACCT_DEFAULT false +#define CIFS_MAP_GENERIC_DEFAULT false +#define CIFS_MAP_TRANS2_DEFAULT true + +/* + a handler for oplock break events from the server - these need to be passed + along to the client + */ +static bool oplock_handler(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *p_private) +{ + struct cvfs_private *private = p_private; + NTSTATUS status; + struct ntvfs_handle *h = NULL; + struct cvfs_file *f; + + for (f=private->files; f; f=f->next) { + if (f->fnum != fnum) continue; + h = f->h; + break; + } + + if (!h) { + DEBUG(5,("vfs_cifs: ignoring oplock break level %d for fnum %d\n", level, fnum)); + return true; + } + + DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level, fnum)); + status = ntvfs_send_oplock_break(private->ntvfs, h, level); + if (!NT_STATUS_IS_OK(status)) return false; + return true; +} + +/* + connect to a share - used when a tree_connect operation comes in. +*/ +static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, const char *sharename) +{ + NTSTATUS status; + struct cvfs_private *private; + const char *host, *user, *pass, *domain, *remote_share; + struct smb_composite_connect io; + struct composite_context *creq; + struct share_config *scfg = ntvfs->ctx->config; + + struct cli_credentials *credentials; + bool machine_account; + + /* Here we need to determine which server to connect to. + * For now we use parametric options, type cifs. + * Later we will use security=server and auth_server.c. + */ + host = share_string_option(scfg, CIFS_SERVER, NULL); + user = share_string_option(scfg, CIFS_USER, NULL); + pass = share_string_option(scfg, CIFS_PASSWORD, NULL); + domain = share_string_option(scfg, CIFS_DOMAIN, NULL); + remote_share = share_string_option(scfg, CIFS_SHARE, NULL); + if (!remote_share) { + remote_share = sharename; + } + + machine_account = share_bool_option(scfg, CIFS_USE_MACHINE_ACCT, CIFS_USE_MACHINE_ACCT_DEFAULT); + + private = talloc_zero(ntvfs, struct cvfs_private); + if (!private) { + return NT_STATUS_NO_MEMORY; + } + + ntvfs->private_data = private; + + if (!host) { + DEBUG(1,("CIFS backend: You must supply server\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (user && pass) { + DEBUG(5, ("CIFS backend: Using specified password\n")); + credentials = cli_credentials_init(private); + if (!credentials) { + return NT_STATUS_NO_MEMORY; + } + cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); + cli_credentials_set_username(credentials, user, CRED_SPECIFIED); + if (domain) { + cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); + } + cli_credentials_set_password(credentials, pass, CRED_SPECIFIED); + } else if (machine_account) { + DEBUG(5, ("CIFS backend: Using machine account\n")); + credentials = cli_credentials_init(private); + cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); + if (domain) { + cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); + } + status = cli_credentials_set_machine_account(credentials, ntvfs->ctx->lp_ctx); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } else if (req->session_info->credentials) { + DEBUG(5, ("CIFS backend: Using delegated credentials\n")); + credentials = req->session_info->credentials; + } else { + DEBUG(1,("CIFS backend: NO delegated credentials found: You must supply server, user and password or the client must supply delegated credentials\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* connect to the server, using the smbd event context */ + io.in.dest_host = host; + io.in.dest_ports = lp_smb_ports(ntvfs->ctx->lp_ctx); + io.in.called_name = host; + io.in.credentials = credentials; + io.in.fallback_to_anonymous = false; + io.in.workgroup = lp_workgroup(ntvfs->ctx->lp_ctx); + io.in.service = remote_share; + io.in.service_type = "?????"; + lp_smbcli_options(ntvfs->ctx->lp_ctx, &io.in.options); + + if (!(ntvfs->ctx->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS)) { + io.in.options.use_level2_oplocks = false; + } + + creq = smb_composite_connect_send(&io, private, + lp_resolve_context(ntvfs->ctx->lp_ctx), + ntvfs->ctx->event_ctx); + status = smb_composite_connect_recv(creq, private); + NT_STATUS_NOT_OK_RETURN(status); + + private->tree = io.out.tree; + + private->transport = private->tree->session->transport; + SETUP_PID; + private->ntvfs = ntvfs; + + ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); + ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + + /* we need to receive oplock break requests from the server */ + smbcli_oplock_handler(private->transport, oplock_handler, private); + + private->map_generic = share_bool_option(scfg, CIFS_MAP_GENERIC, CIFS_MAP_GENERIC_DEFAULT); + + private->map_trans2 = share_bool_option(scfg, CIFS_MAP_TRANS2, CIFS_MAP_TRANS2_DEFAULT); + + return NT_STATUS_OK; +} + +/* + disconnect from a share +*/ +static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs) +{ + struct cvfs_private *private = ntvfs->private_data; + struct async_info *a, *an; + + /* first cleanup pending requests */ + for (a=private->pending; a; a = an) { + an = a->next; + smbcli_request_destroy(a->c_req); + talloc_free(a); + } + + talloc_free(private); + ntvfs->private_data = NULL; + + return NT_STATUS_OK; +} + +/* + destroy an async info structure +*/ +static int async_info_destructor(struct async_info *async) +{ + DLIST_REMOVE(async->cvfs->pending, async); + return 0; +} + +/* + a handler for simple async replies + this handler can only be used for functions that don't return any + parameters (those that just return a status code) + */ +static void async_simple(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smbcli_request_simple_recv(c_req); + talloc_free(async); + req->async_states->send_fn(req); +} + + +/* save some typing for the simple functions */ +#define ASYNC_RECV_TAIL_F(io, async_fn, file) do { \ + if (!c_req) return NT_STATUS_UNSUCCESSFUL; \ + { \ + struct async_info *async; \ + async = talloc(req, struct async_info); \ + if (!async) return NT_STATUS_NO_MEMORY; \ + async->parms = io; \ + async->req = req; \ + async->f = file; \ + async->cvfs = private; \ + async->c_req = c_req; \ + DLIST_ADD(private->pending, async); \ + c_req->async.private = async; \ + talloc_set_destructor(async, async_info_destructor); \ + } \ + c_req->async.fn = async_fn; \ + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; \ + return NT_STATUS_OK; \ +} while (0) + +#define ASYNC_RECV_TAIL(io, async_fn) ASYNC_RECV_TAIL_F(io, async_fn, NULL) + +#define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple) + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_unlink *unl) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + /* see if the front end will allow us to perform this + function asynchronously. */ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_unlink(private->tree, unl); + } + + c_req = smb_raw_unlink_send(private->tree, unl); + + SIMPLE_ASYNC_TAIL; +} + +/* + a handler for async ioctl replies + */ +static void async_ioctl(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_ioctl_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + ioctl interface +*/ +static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_ioctl *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID_AND_FILE; + + /* see if the front end will allow us to perform this + function asynchronously. */ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_ioctl(private->tree, req, io); + } + + c_req = smb_raw_ioctl_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_ioctl); +} + +/* + check if a directory exists +*/ +static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_chkpath *cp) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_chkpath(private->tree, cp); + } + + c_req = smb_raw_chkpath_send(private->tree, cp); + + SIMPLE_ASYNC_TAIL; +} + +/* + a handler for async qpathinfo replies + */ +static void async_qpathinfo(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_pathinfo_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + return info on a pathname +*/ +static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *info) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_pathinfo(private->tree, req, info); + } + + c_req = smb_raw_pathinfo_send(private->tree, info); + + ASYNC_RECV_TAIL(info, async_qpathinfo); +} + +/* + a handler for async qfileinfo replies + */ +static void async_qfileinfo(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_fileinfo_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + query info on a open file +*/ +static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID_AND_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_fileinfo(private->tree, req, io); + } + + c_req = smb_raw_fileinfo_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_qfileinfo); +} + + +/* + set info on a pathname +*/ +static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_setfileinfo *st) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_setpathinfo(private->tree, st); + } + + c_req = smb_raw_setpathinfo_send(private->tree, st); + + SIMPLE_ASYNC_TAIL; +} + + +/* + a handler for async open replies + */ +static void async_open(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct cvfs_private *cvfs = async->cvfs; + struct ntvfs_request *req = async->req; + struct cvfs_file *f = async->f; + union smb_open *io = async->parms; + union smb_handle *file; + talloc_free(async); + req->async_states->status = smb_raw_open_recv(c_req, req, io); + SMB_OPEN_OUT_FILE(io, file); + f->fnum = file->fnum; + file->ntvfs = NULL; + if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; + req->async_states->status = ntvfs_handle_set_backend_data(f->h, cvfs->ntvfs, f); + if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; + file->ntvfs = f->h; + DLIST_ADD(cvfs->files, f); +failed: + req->async_states->send_fn(req); +} + +/* + open a file +*/ +static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_open *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + struct ntvfs_handle *h; + struct cvfs_file *f; + NTSTATUS status; + + SETUP_PID; + + if (io->generic.level != RAW_OPEN_GENERIC && + private->map_generic) { + return ntvfs_map_open(ntvfs, req, io); + } + + status = ntvfs_handle_new(ntvfs, req, &h); + NT_STATUS_NOT_OK_RETURN(status); + + f = talloc_zero(h, struct cvfs_file); + NT_STATUS_HAVE_NO_MEMORY(f); + f->h = h; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + union smb_handle *file; + + status = smb_raw_open(private->tree, req, io); + NT_STATUS_NOT_OK_RETURN(status); + + SMB_OPEN_OUT_FILE(io, file); + f->fnum = file->fnum; + file->ntvfs = NULL; + status = ntvfs_handle_set_backend_data(f->h, private->ntvfs, f); + NT_STATUS_NOT_OK_RETURN(status); + file->ntvfs = f->h; + DLIST_ADD(private->files, f); + + return NT_STATUS_OK; + } + + c_req = smb_raw_open_send(private->tree, io); + + ASYNC_RECV_TAIL_F(io, async_open, f); +} + +/* + create a directory +*/ +static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_mkdir *md) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_mkdir(private->tree, md); + } + + c_req = smb_raw_mkdir_send(private->tree, md); + + SIMPLE_ASYNC_TAIL; +} + +/* + remove a directory +*/ +static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_rmdir *rd) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_rmdir(private->tree, rd); + } + c_req = smb_raw_rmdir_send(private->tree, rd); + + SIMPLE_ASYNC_TAIL; +} + +/* + rename a set of files +*/ +static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_rename *ren) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (ren->nttrans.level == RAW_RENAME_NTTRANS) { + struct cvfs_file *f; + f = ntvfs_handle_get_backend_data(ren->nttrans.in.file.ntvfs, ntvfs); + if (!f) return NT_STATUS_INVALID_HANDLE; + ren->nttrans.in.file.fnum = f->fnum; + } + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_rename(private->tree, ren); + } + + c_req = smb_raw_rename_send(private->tree, ren); + + SIMPLE_ASYNC_TAIL; +} + +/* + copy a set of files +*/ +static NTSTATUS cvfs_copy(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_copy *cp) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + a handler for async read replies + */ +static void async_read(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_read_recv(c_req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + read from a file +*/ +static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_read *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (io->generic.level != RAW_READ_GENERIC && + private->map_generic) { + return ntvfs_map_read(ntvfs, req, io); + } + + SETUP_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_read(private->tree, io); + } + + c_req = smb_raw_read_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_read); +} + +/* + a handler for async write replies + */ +static void async_write(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_write_recv(c_req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + write to a file +*/ +static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_write *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (io->generic.level != RAW_WRITE_GENERIC && + private->map_generic) { + return ntvfs_map_write(ntvfs, req, io); + } + SETUP_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_write(private->tree, io); + } + + c_req = smb_raw_write_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_write); +} + +/* + a handler for async seek replies + */ +static void async_seek(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_seek_recv(c_req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + seek in a file +*/ +static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_seek *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID_AND_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_seek(private->tree, io); + } + + c_req = smb_raw_seek_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_seek); +} + +/* + flush a file +*/ +static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_flush *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + switch (io->generic.level) { + case RAW_FLUSH_FLUSH: + SETUP_FILE; + break; + case RAW_FLUSH_ALL: + io->generic.in.file.fnum = 0xFFFF; + break; + case RAW_FLUSH_SMB2: + return NT_STATUS_INVALID_LEVEL; + } + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_flush(private->tree, io); + } + + c_req = smb_raw_flush_send(private->tree, io); + + SIMPLE_ASYNC_TAIL; +} + +/* + close a file +*/ +static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_close *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + struct cvfs_file *f; + + SETUP_PID; + + if (io->generic.level != RAW_CLOSE_GENERIC && + private->map_generic) { + return ntvfs_map_close(ntvfs, req, io); + } + SETUP_FILE_HERE(f); + /* Note, we aren't free-ing f, or it's h here. Should we? + even if file-close fails, we'll remove it from the list, + what else would we do? Maybe we should not remove until + after the proxied call completes? */ + DLIST_REMOVE(private->files, f); + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_close(private->tree, io); + } + + c_req = smb_raw_close_send(private->tree, io); + + SIMPLE_ASYNC_TAIL; +} + +/* + exit - closing files open by the pid +*/ +static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_exit(private->tree->session); + } + + c_req = smb_raw_exit_send(private->tree->session); + + SIMPLE_ASYNC_TAIL; +} + +/* + logoff - closing files open by the user +*/ +static NTSTATUS cvfs_logoff(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + /* we can't do this right in the cifs backend .... */ + return NT_STATUS_OK; +} + +/* + setup for an async call - nothing to do yet +*/ +static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *private) +{ + return NT_STATUS_OK; +} + +/* + cancel an async call +*/ +static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + struct cvfs_private *private = ntvfs->private_data; + struct async_info *a; + + /* find the matching request */ + for (a=private->pending;a;a=a->next) { + if (a->req == req) { + break; + } + } + + if (a == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return smb_raw_ntcancel(a->c_req); +} + +/* + lock a byte range +*/ +static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lock *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (io->generic.level != RAW_LOCK_GENERIC && + private->map_generic) { + return ntvfs_map_lock(ntvfs, req, io); + } + SETUP_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_lock(private->tree, io); + } + + c_req = smb_raw_lock_send(private->tree, io); + SIMPLE_ASYNC_TAIL; +} + +/* + set info on a open file +*/ +static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_setfileinfo *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID_AND_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_setfileinfo(private->tree, io); + } + c_req = smb_raw_setfileinfo_send(private->tree, io); + + SIMPLE_ASYNC_TAIL; +} + + +/* + a handler for async fsinfo replies + */ +static void async_fsinfo(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_fsinfo_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + return filesystem space info +*/ +static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fsinfo *fs) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_fsinfo(private->tree, req, fs); + } + + c_req = smb_raw_fsinfo_send(private->tree, req, fs); + + ASYNC_RECV_TAIL(fs, async_fsinfo); +} + +/* + return print queue info +*/ +static NTSTATUS cvfs_lpq(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lpq *lpq) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + list files in a directory matching a wildcard pattern +*/ +static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_first *io, + void *search_private, + bool (*callback)(void *, const union smb_search_data *)) +{ + struct cvfs_private *private = ntvfs->private_data; + + SETUP_PID; + + return smb_raw_search_first(private->tree, req, io, search_private, callback); +} + +/* continue a search */ +static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_next *io, + void *search_private, + bool (*callback)(void *, const union smb_search_data *)) +{ + struct cvfs_private *private = ntvfs->private_data; + + SETUP_PID; + + return smb_raw_search_next(private->tree, req, io, search_private, callback); +} + +/* close a search */ +static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_close *io) +{ + struct cvfs_private *private = ntvfs->private_data; + + SETUP_PID; + + return smb_raw_search_close(private->tree, io); +} + +/* + a handler for async trans2 replies + */ +static void async_trans2(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_trans2_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* raw trans2 */ +static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_trans2 *trans2) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + if (private->map_trans2) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_trans2(private->tree, req, trans2); + } + + c_req = smb_raw_trans2_send(private->tree, trans2); + + ASYNC_RECV_TAIL(trans2, async_trans2); +} + + +/* SMBtrans - not used on file shares */ +static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_trans2 *trans2) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + a handler for async change notify replies + */ +static void async_changenotify(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_changenotify_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* change notify request - always async */ +static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_notify *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + int saved_timeout = private->transport->options.request_timeout; + struct cvfs_file *f; + + if (io->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + SETUP_PID; + + f = ntvfs_handle_get_backend_data(io->nttrans.in.file.ntvfs, ntvfs); + if (!f) return NT_STATUS_INVALID_HANDLE; + io->nttrans.in.file.fnum = f->fnum; + + /* this request doesn't make sense unless its async */ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* we must not timeout on notify requests - they wait + forever */ + private->transport->options.request_timeout = 0; + + c_req = smb_raw_changenotify_send(private->tree, io); + + private->transport->options.request_timeout = saved_timeout; + + ASYNC_RECV_TAIL(io, async_changenotify); +} + +/* + initialise the CIFS->CIFS backend, registering ourselves with the ntvfs subsystem + */ +NTSTATUS ntvfs_smb2_init(void) +{ + NTSTATUS ret; + struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); + + ZERO_STRUCT(ops); + + /* fill in the name and type */ + ops.name = "smb2"; + ops.type = NTVFS_DISK; + + /* fill in all the operations */ + ops.connect = cvfs_connect; + ops.disconnect = cvfs_disconnect; + ops.unlink = cvfs_unlink; + ops.chkpath = cvfs_chkpath; + ops.qpathinfo = cvfs_qpathinfo; + ops.setpathinfo = cvfs_setpathinfo; + ops.open = cvfs_open; + ops.mkdir = cvfs_mkdir; + ops.rmdir = cvfs_rmdir; + ops.rename = cvfs_rename; + ops.copy = cvfs_copy; + ops.ioctl = cvfs_ioctl; + ops.read = cvfs_read; + ops.write = cvfs_write; + ops.seek = cvfs_seek; + ops.flush = cvfs_flush; + ops.close = cvfs_close; + ops.exit = cvfs_exit; + ops.lock = cvfs_lock; + ops.setfileinfo = cvfs_setfileinfo; + ops.qfileinfo = cvfs_qfileinfo; + ops.fsinfo = cvfs_fsinfo; + ops.lpq = cvfs_lpq; + ops.search_first = cvfs_search_first; + ops.search_next = cvfs_search_next; + ops.search_close = cvfs_search_close; + ops.trans = cvfs_trans; + ops.logoff = cvfs_logoff; + ops.async_setup = cvfs_async_setup; + ops.cancel = cvfs_cancel; + ops.notify = cvfs_notify; + ops.trans2 = cvfs_trans2; + + /* register ourselves with the NTVFS subsystem. We register + under the name 'smb2'. */ + ret = ntvfs_register(&ops, &vers); + + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register SMB2 backend\n")); + } + + return ret; +} -- cgit From d9f47ba00b910ecbe031e635eeaf50b1c05a79cb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 May 2008 20:47:28 +1000 Subject: added handlers for connect, search_first and fsinfo. Directory listing in smbclient now works (This used to be commit 8007342061d77eb711af0652ecd38aec0d3cc9d1) --- source4/ntvfs/smb2/vfs_smb2.c | 377 +++++++++++++++++++++++++----------------- 1 file changed, 225 insertions(+), 152 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index f253fcecaf..6b0f3e62f4 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -37,6 +37,8 @@ #include "lib/util/dlinklist.h" #include "param/param.h" #include "libcli/resolve/resolve.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" struct cvfs_file { struct cvfs_file *prev, *next; @@ -46,13 +48,17 @@ struct cvfs_file { /* this is stored in ntvfs_private */ struct cvfs_private { - struct smbcli_tree *tree; + struct smb2_tree *tree; struct smbcli_transport *transport; struct ntvfs_module_context *ntvfs; struct async_info *pending; struct cvfs_file *files; - bool map_generic; - bool map_trans2; + + /* a handle on the root of the share */ + /* TODO: leaving this handle open could prevent other users + from opening the share with exclusive access. We probably + need to open it on demand */ + struct smb2_handle roothandle; }; @@ -61,13 +67,11 @@ struct async_info { struct async_info *next, *prev; struct cvfs_private *cvfs; struct ntvfs_request *req; - struct smbcli_request *c_req; + struct smb2_request *c_req; struct cvfs_file *f; void *parms; }; -#define SETUP_PID private->tree->session->pid = req->smbpid - #define SETUP_FILE_HERE(f) do { \ f = ntvfs_handle_get_backend_data(io->generic.in.file.ntvfs, ntvfs); \ if (!f) return NT_STATUS_INVALID_HANDLE; \ @@ -79,23 +83,14 @@ struct async_info { SETUP_FILE_HERE(f); \ } while (0) -#define SETUP_PID_AND_FILE do { \ - SETUP_PID; \ - SETUP_FILE; \ -} while (0) +#define SMB2_SERVER "smb2:server" +#define SMB2_USER "smb2:user" +#define SMB2_PASSWORD "smb2:password" +#define SMB2_DOMAIN "smb2:domain" +#define SMB2_SHARE "smb2:share" +#define SMB2_USE_MACHINE_ACCT "smb2:use-machine-account" -#define CIFS_SERVER "cifs:server" -#define CIFS_USER "cifs:user" -#define CIFS_PASSWORD "cifs:password" -#define CIFS_DOMAIN "cifs:domain" -#define CIFS_SHARE "cifs:share" -#define CIFS_USE_MACHINE_ACCT "cifs:use-machine-account" -#define CIFS_MAP_GENERIC "cifs:map-generic" -#define CIFS_MAP_TRANS2 "cifs:map-trans2" - -#define CIFS_USE_MACHINE_ACCT_DEFAULT false -#define CIFS_MAP_GENERIC_DEFAULT false -#define CIFS_MAP_TRANS2_DEFAULT true +#define SMB2_USE_MACHINE_ACCT_DEFAULT false /* a handler for oplock break events from the server - these need to be passed @@ -115,16 +110,44 @@ static bool oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin } if (!h) { - DEBUG(5,("vfs_cifs: ignoring oplock break level %d for fnum %d\n", level, fnum)); + DEBUG(5,("vfs_smb2: ignoring oplock break level %d for fnum %d\n", level, fnum)); return true; } - DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level, fnum)); + DEBUG(5,("vfs_smb2: sending oplock break level %d for fnum %d\n", level, fnum)); status = ntvfs_send_oplock_break(private->ntvfs, h, level); if (!NT_STATUS_IS_OK(status)) return false; return true; } +/* + return a handle to the root of the share +*/ +static NTSTATUS smb2_get_roothandle(struct smb2_tree *tree, struct smb2_handle *handle) +{ + struct smb2_create io; + NTSTATUS status; + + ZERO_STRUCT(io); + io.in.oplock_level = 0; + io.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE | SEC_DIR_LIST; + io.in.file_attributes = 0; + io.in.create_disposition = NTCREATEX_DISP_OPEN; + io.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE| + NTCREATEX_SHARE_ACCESS_DELETE; + io.in.create_options = 0; + io.in.fname = NULL; + + status = smb2_create(tree, tree, &io); + NT_STATUS_NOT_OK_RETURN(status); + + *handle = io.out.file.handle; + + return NT_STATUS_OK; +} + /* connect to a share - used when a tree_connect operation comes in. */ @@ -134,9 +157,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, NTSTATUS status; struct cvfs_private *private; const char *host, *user, *pass, *domain, *remote_share; - struct smb_composite_connect io; struct composite_context *creq; struct share_config *scfg = ntvfs->ctx->config; + struct smb2_tree *tree; struct cli_credentials *credentials; bool machine_account; @@ -145,16 +168,16 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, * For now we use parametric options, type cifs. * Later we will use security=server and auth_server.c. */ - host = share_string_option(scfg, CIFS_SERVER, NULL); - user = share_string_option(scfg, CIFS_USER, NULL); - pass = share_string_option(scfg, CIFS_PASSWORD, NULL); - domain = share_string_option(scfg, CIFS_DOMAIN, NULL); - remote_share = share_string_option(scfg, CIFS_SHARE, NULL); + host = share_string_option(scfg, SMB2_SERVER, NULL); + user = share_string_option(scfg, SMB2_USER, NULL); + pass = share_string_option(scfg, SMB2_PASSWORD, NULL); + domain = share_string_option(scfg, SMB2_DOMAIN, NULL); + remote_share = share_string_option(scfg, SMB2_SHARE, NULL); if (!remote_share) { remote_share = sharename; } - machine_account = share_bool_option(scfg, CIFS_USE_MACHINE_ACCT, CIFS_USE_MACHINE_ACCT_DEFAULT); + machine_account = share_bool_option(scfg, SMB2_USE_MACHINE_ACCT, SMB2_USE_MACHINE_ACCT_DEFAULT); private = talloc_zero(ntvfs, struct cvfs_private); if (!private) { @@ -199,31 +222,19 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - /* connect to the server, using the smbd event context */ - io.in.dest_host = host; - io.in.dest_ports = lp_smb_ports(ntvfs->ctx->lp_ctx); - io.in.called_name = host; - io.in.credentials = credentials; - io.in.fallback_to_anonymous = false; - io.in.workgroup = lp_workgroup(ntvfs->ctx->lp_ctx); - io.in.service = remote_share; - io.in.service_type = "?????"; - lp_smbcli_options(ntvfs->ctx->lp_ctx, &io.in.options); - - if (!(ntvfs->ctx->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS)) { - io.in.options.use_level2_oplocks = false; - } + creq = smb2_connect_send(private, host, remote_share, + lp_resolve_context(ntvfs->ctx->lp_ctx), + credentials, + ntvfs->ctx->event_ctx); - creq = smb_composite_connect_send(&io, private, - lp_resolve_context(ntvfs->ctx->lp_ctx), - ntvfs->ctx->event_ctx); - status = smb_composite_connect_recv(creq, private); + status = smb2_connect_recv(creq, private, &tree); NT_STATUS_NOT_OK_RETURN(status); - private->tree = io.out.tree; + status = smb2_get_roothandle(tree, &private->roothandle); + NT_STATUS_NOT_OK_RETURN(status); + private->tree = tree; private->transport = private->tree->session->transport; - SETUP_PID; private->ntvfs = ntvfs; ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); @@ -232,12 +243,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); /* we need to receive oplock break requests from the server */ + /* TODO: enable oplocks smbcli_oplock_handler(private->transport, oplock_handler, private); - - private->map_generic = share_bool_option(scfg, CIFS_MAP_GENERIC, CIFS_MAP_GENERIC_DEFAULT); - - private->map_trans2 = share_bool_option(scfg, CIFS_MAP_TRANS2, CIFS_MAP_TRANS2_DEFAULT); - + */ return NT_STATUS_OK; } @@ -252,7 +260,7 @@ static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs) /* first cleanup pending requests */ for (a=private->pending; a; a = an) { an = a->next; - smbcli_request_destroy(a->c_req); + smb2_request_destroy(a->c_req); talloc_free(a); } @@ -276,11 +284,13 @@ static int async_info_destructor(struct async_info *async) this handler can only be used for functions that don't return any parameters (those that just return a status code) */ -static void async_simple(struct smbcli_request *c_req) +static void async_simple(struct smb2_request *c_req) { struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; - req->async_states->status = smbcli_request_simple_recv(c_req); + + smb2_request_receive(c_req); + req->async_states->status = smb2_request_destroy(c_req); talloc_free(async); req->async_states->send_fn(req); } @@ -321,8 +331,7 @@ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - + return NT_STATUS_NOT_IMPLEMENTED; /* see if the front end will allow us to perform this function asynchronously. */ if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { @@ -355,7 +364,7 @@ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID_AND_FILE; + SETUP_FILE; /* see if the front end will allow us to perform this function asynchronously. */ @@ -375,15 +384,31 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_chkpath *cp) { struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - - SETUP_PID; - + struct smb2_request *c_req; + struct smb2_find f; + + /* SMB2 doesn't have a chkpath operation, and also doesn't + have a query path info call, so the best seems to be to do a + find call, using the roothandle we established at connect + time */ + ZERO_STRUCT(f); + f.in.file.handle = private->roothandle; + f.in.level = SMB2_FIND_DIRECTORY_INFO; + f.in.pattern = cp->chkpath.in.path; + /* SMB2 find doesn't accept \ or the empty string - this is the best + approximation */ + if (strcmp(f.in.pattern, "\\") == 0 || + strcmp(f.in.pattern, "") == 0) { + f.in.pattern = "?"; + } + f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE | SMB2_CONTINUE_FLAG_RESTART; + f.in.max_response_size = 0x1000; + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_chkpath(private->tree, cp); + return smb2_find(private->tree, req, &f); } - c_req = smb_raw_chkpath_send(private->tree, cp); + c_req = smb2_find_send(private->tree, &f); SIMPLE_ASYNC_TAIL; } @@ -395,6 +420,7 @@ static void async_qpathinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; + return NT_STATUS_NOT_IMPLEMENTED; req->async_states->status = smb_raw_pathinfo_recv(c_req, req, async->parms); talloc_free(async); req->async_states->send_fn(req); @@ -409,8 +435,6 @@ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_pathinfo(private->tree, req, info); } @@ -427,6 +451,7 @@ static void async_qfileinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; + return NT_STATUS_NOT_IMPLEMENTED; req->async_states->status = smb_raw_fileinfo_recv(c_req, req, async->parms); talloc_free(async); req->async_states->send_fn(req); @@ -441,7 +466,8 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID_AND_FILE; + return NT_STATUS_NOT_IMPLEMENTED; + SETUP_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_fileinfo(private->tree, req, io); @@ -462,8 +488,7 @@ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - + return NT_STATUS_NOT_IMPLEMENTED; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_setpathinfo(private->tree, st); } @@ -511,10 +536,8 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, struct cvfs_file *f; NTSTATUS status; - SETUP_PID; - - if (io->generic.level != RAW_OPEN_GENERIC && - private->map_generic) { + return NT_STATUS_NOT_IMPLEMENTED; + if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(ntvfs, req, io); } @@ -556,8 +579,7 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - + return NT_STATUS_NOT_IMPLEMENTED; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_mkdir(private->tree, md); } @@ -576,8 +598,7 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - + return NT_STATUS_NOT_IMPLEMENTED; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_rmdir(private->tree, rd); } @@ -595,7 +616,7 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; + return NT_STATUS_NOT_IMPLEMENTED; if (ren->nttrans.level == RAW_RENAME_NTTRANS) { struct cvfs_file *f; @@ -643,10 +664,8 @@ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - - if (io->generic.level != RAW_READ_GENERIC && - private->map_generic) { + return NT_STATUS_NOT_IMPLEMENTED; + if (io->generic.level != RAW_READ_GENERIC) { return ntvfs_map_read(ntvfs, req, io); } @@ -682,10 +701,8 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - - if (io->generic.level != RAW_WRITE_GENERIC && - private->map_generic) { + return NT_STATUS_NOT_IMPLEMENTED; + if (io->generic.level != RAW_WRITE_GENERIC) { return ntvfs_map_write(ntvfs, req, io); } SETUP_FILE; @@ -721,7 +738,8 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID_AND_FILE; + return NT_STATUS_NOT_IMPLEMENTED; + SETUP_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_seek(private->tree, io); @@ -742,7 +760,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; + return NT_STATUS_NOT_IMPLEMENTED; switch (io->generic.level) { case RAW_FLUSH_FLUSH: SETUP_FILE; @@ -773,10 +791,8 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, struct smbcli_request *c_req; struct cvfs_file *f; - SETUP_PID; - - if (io->generic.level != RAW_CLOSE_GENERIC && - private->map_generic) { + return NT_STATUS_NOT_IMPLEMENTED; + if (io->generic.level != RAW_CLOSE_GENERIC) { return ntvfs_map_close(ntvfs, req, io); } SETUP_FILE_HERE(f); @@ -804,8 +820,7 @@ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - + return NT_STATUS_NOT_IMPLEMENTED; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_exit(private->tree->session); } @@ -844,6 +859,7 @@ static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct async_info *a; + return NT_STATUS_NOT_IMPLEMENTED; /* find the matching request */ for (a=private->pending;a;a=a->next) { if (a->req == req) { @@ -867,10 +883,8 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - - if (io->generic.level != RAW_LOCK_GENERIC && - private->map_generic) { + return NT_STATUS_NOT_IMPLEMENTED; + if (io->generic.level != RAW_LOCK_GENERIC) { return ntvfs_map_lock(ntvfs, req, io); } SETUP_FILE; @@ -893,7 +907,8 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID_AND_FILE; + return NT_STATUS_NOT_IMPLEMENTED; + SETUP_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_setfileinfo(private->tree, io); @@ -907,11 +922,11 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* a handler for async fsinfo replies */ -static void async_fsinfo(struct smbcli_request *c_req) +static void async_fsinfo(struct smb2_request *c_req) { struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_fsinfo_recv(c_req, req, async->parms); + req->async_states->status = smb2_getinfo_fs_recv(c_req, req, async->parms); talloc_free(async); req->async_states->send_fn(req); } @@ -923,15 +938,49 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsinfo *fs) { struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; + struct smb2_request *c_req; + enum smb_fsinfo_level level = fs->generic.level; + + switch (level) { + /* some levels go straight through */ + case RAW_QFS_VOLUME_INFORMATION: + case RAW_QFS_SIZE_INFORMATION: + case RAW_QFS_DEVICE_INFORMATION: + case RAW_QFS_ATTRIBUTE_INFORMATION: + case RAW_QFS_QUOTA_INFORMATION: + case RAW_QFS_FULL_SIZE_INFORMATION: + case RAW_QFS_OBJECTID_INFORMATION: + break; - SETUP_PID; + /* some get mapped */ + case RAW_QFS_VOLUME_INFO: + level = RAW_QFS_VOLUME_INFORMATION; + break; + case RAW_QFS_SIZE_INFO: + level = RAW_QFS_SIZE_INFORMATION; + break; + case RAW_QFS_DEVICE_INFO: + level = RAW_QFS_DEVICE_INFORMATION; + break; + case RAW_QFS_ATTRIBUTE_INFO: + level = RAW_QFS_ATTRIBUTE_INFO; + break; + + default: + /* the rest get refused for now */ + DEBUG(0,("fsinfo level %u not possible on SMB2\n", + (unsigned)fs->generic.level)); + break; + } + + fs->generic.level = level; + fs->generic.handle = private->roothandle; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_fsinfo(private->tree, req, fs); + return smb2_getinfo_fs(private->tree, req, fs); } - c_req = smb_raw_fsinfo_send(private->tree, req, fs); + c_req = smb2_getinfo_fs_send(private->tree, fs); ASYNC_RECV_TAIL(fs, async_fsinfo); } @@ -954,10 +1003,72 @@ static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, bool (*callback)(void *, const union smb_search_data *)) { struct cvfs_private *private = ntvfs->private_data; + struct smb2_find f; + enum smb_search_data_level smb2_level; + uint32_t continue_flags = 0; + uint_t count, i; + union smb_search_data *data; + NTSTATUS status; + + if (io->generic.level != RAW_SEARCH_TRANS2) { + DEBUG(0,("We only support trans2 search in smb2 backend\n")); + return NT_STATUS_NOT_SUPPORTED; + } + + switch (io->generic.data_level) { + case RAW_SEARCH_DATA_DIRECTORY_INFO: + smb2_level = SMB2_FIND_DIRECTORY_INFO; + break; + case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: + smb2_level = SMB2_FIND_FULL_DIRECTORY_INFO; + break; + case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: + smb2_level = SMB2_FIND_BOTH_DIRECTORY_INFO; + break; + case RAW_SEARCH_DATA_NAME_INFO: + smb2_level = SMB2_FIND_NAME_INFO; + break; + case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO: + smb2_level = SMB2_FIND_ID_FULL_DIRECTORY_INFO; + break; + case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: + smb2_level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO; + break; + default: + DEBUG(0,("Unsupported search level %u for smb2 backend\n", + (unsigned)io->generic.data_level)); + return NT_STATUS_INVALID_INFO_CLASS; + } + + /* we do the search on the roothandle. This only works because + search is synchronous, otherwise we'd have no way to + distinguish multiple searches happening at once + */ + ZERO_STRUCT(f); + f.in.file.handle = private->roothandle; + f.in.level = smb2_level; + f.in.pattern = io->t2ffirst.in.pattern; + while (f.in.pattern[0] == '\\') { + f.in.pattern++; + } + f.in.continue_flags = 0; + f.in.max_response_size = 0x10000; + + status = smb2_find_level(private->tree, req, &f, &count, &data); + NT_STATUS_NOT_OK_RETURN(status); - SETUP_PID; + for (i=0;it2ffirst.out.handle = 0; + io->t2ffirst.out.count = i; + /* TODO: fix end_of_file */ + io->t2ffirst.out.end_of_search = 1; - return smb_raw_search_first(private->tree, req, io, search_private, callback); + talloc_free(data); + + return NT_STATUS_OK; } /* continue a search */ @@ -968,7 +1079,7 @@ static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, { struct cvfs_private *private = ntvfs->private_data; - SETUP_PID; + return NT_STATUS_NOT_IMPLEMENTED; return smb_raw_search_next(private->tree, req, io, search_private, callback); } @@ -979,47 +1090,11 @@ static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs, { struct cvfs_private *private = ntvfs->private_data; - SETUP_PID; + return NT_STATUS_NOT_IMPLEMENTED; return smb_raw_search_close(private->tree, io); } -/* - a handler for async trans2 replies - */ -static void async_trans2(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_trans2_recv(c_req, req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); -} - -/* raw trans2 */ -static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, - struct smb_trans2 *trans2) -{ - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - - if (private->map_trans2) { - return NT_STATUS_NOT_IMPLEMENTED; - } - - SETUP_PID; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_trans2(private->tree, req, trans2); - } - - c_req = smb_raw_trans2_send(private->tree, trans2); - - ASYNC_RECV_TAIL(trans2, async_trans2); -} - - /* SMBtrans - not used on file shares */ static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, @@ -1050,12 +1125,11 @@ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, int saved_timeout = private->transport->options.request_timeout; struct cvfs_file *f; + return NT_STATUS_NOT_IMPLEMENTED; if (io->nttrans.level != RAW_NOTIFY_NTTRANS) { return NT_STATUS_NOT_IMPLEMENTED; } - SETUP_PID; - f = ntvfs_handle_get_backend_data(io->nttrans.in.file.ntvfs, ntvfs); if (!f) return NT_STATUS_INVALID_HANDLE; io->nttrans.in.file.fnum = f->fnum; @@ -1123,7 +1197,6 @@ NTSTATUS ntvfs_smb2_init(void) ops.async_setup = cvfs_async_setup; ops.cancel = cvfs_cancel; ops.notify = cvfs_notify; - ops.trans2 = cvfs_trans2; /* register ourselves with the NTVFS subsystem. We register under the name 'smb2'. */ -- cgit From 9b177f8d586830887282dc30e712bae0e9a06f33 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 May 2008 15:01:31 +1000 Subject: added SMB2 proxying for unlink (This used to be commit a5459bd88092863668db199953458fe97162240c) --- source4/ntvfs/smb2/vfs_smb2.c | 470 ++++-------------------------------------- 1 file changed, 43 insertions(+), 427 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index 6b0f3e62f4..13dbb4ea2e 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -30,6 +30,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/raw/raw_proto.h" +#include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" #include "auth/auth.h" #include "auth/credentials/credentials.h" @@ -49,7 +50,7 @@ struct cvfs_file { /* this is stored in ntvfs_private */ struct cvfs_private { struct smb2_tree *tree; - struct smbcli_transport *transport; + struct smb2_transport *transport; struct ntvfs_module_context *ntvfs; struct async_info *pending; struct cvfs_file *files; @@ -67,7 +68,8 @@ struct async_info { struct async_info *next, *prev; struct cvfs_private *cvfs; struct ntvfs_request *req; - struct smb2_request *c_req; + void *c_req; + struct composite_context *c_comp; struct cvfs_file *f; void *parms; }; @@ -260,7 +262,7 @@ static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs) /* first cleanup pending requests */ for (a=private->pending; a; a = an) { an = a->next; - smb2_request_destroy(a->c_req); + talloc_free(a->c_req); talloc_free(a); } @@ -280,13 +282,13 @@ static int async_info_destructor(struct async_info *async) } /* - a handler for simple async replies + a handler for simple async SMB2 replies this handler can only be used for functions that don't return any parameters (those that just return a status code) */ -static void async_simple(struct smb2_request *c_req) +static void async_simple_smb2(struct smb2_request *c_req) { - struct async_info *async = c_req->async.private; + struct async_info *async = c_req->async.private_data; struct ntvfs_request *req = async->req; smb2_request_receive(c_req); @@ -295,6 +297,21 @@ static void async_simple(struct smb2_request *c_req) req->async_states->send_fn(req); } +/* + a handler for simple async composite replies + this handler can only be used for functions that don't return any + parameters (those that just return a status code) + */ +static void async_simple_composite(struct composite_context *c_req) +{ + struct async_info *async = c_req->async.private_data; + struct ntvfs_request *req = async->req; + + req->async_states->status = composite_wait_free(c_req); + talloc_free(async); + req->async_states->send_fn(req); +} + /* save some typing for the simple functions */ #define ASYNC_RECV_TAIL_F(io, async_fn, file) do { \ @@ -309,7 +326,7 @@ static void async_simple(struct smb2_request *c_req) async->cvfs = private; \ async->c_req = c_req; \ DLIST_ADD(private->pending, async); \ - c_req->async.private = async; \ + c_req->async.private_data = async; \ talloc_set_destructor(async, async_info_destructor); \ } \ c_req->async.fn = async_fn; \ @@ -319,7 +336,15 @@ static void async_simple(struct smb2_request *c_req) #define ASYNC_RECV_TAIL(io, async_fn) ASYNC_RECV_TAIL_F(io, async_fn, NULL) -#define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple) +#define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple_smb2) +#define SIMPLE_COMPOSITE_TAIL ASYNC_RECV_TAIL(NULL, async_simple_composite) + +#define CHECK_ASYNC(req) do { \ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { \ + DEBUG(0,("SMB2 proxy backend does not support sync operation at %s\n", \ + __location__)); \ + return NT_STATUS_NOT_IMPLEMENTED; \ + }} while (0) /* delete a file - the dirtype specifies the file types to include in the search. @@ -329,30 +354,13 @@ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_unlink *unl) { struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; + struct composite_context *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - /* see if the front end will allow us to perform this - function asynchronously. */ - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_unlink(private->tree, unl); - } + CHECK_ASYNC(req); - c_req = smb_raw_unlink_send(private->tree, unl); + c_req = smb2_composite_unlink_send(private->tree, unl); - SIMPLE_ASYNC_TAIL; -} - -/* - a handler for async ioctl replies - */ -static void async_ioctl(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_ioctl_recv(c_req, req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); + SIMPLE_COMPOSITE_TAIL; } /* @@ -361,20 +369,7 @@ static void async_ioctl(struct smbcli_request *c_req) static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_ioctl *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - - SETUP_FILE; - - /* see if the front end will allow us to perform this - function asynchronously. */ - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_ioctl(private->tree, req, io); - } - - c_req = smb_raw_ioctl_send(private->tree, io); - - ASYNC_RECV_TAIL(io, async_ioctl); + return NT_STATUS_NOT_IMPLEMENTED; } /* @@ -386,6 +381,8 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smb2_request *c_req; struct smb2_find f; + + CHECK_ASYNC(req); /* SMB2 doesn't have a chkpath operation, and also doesn't have a query path info call, so the best seems to be to do a @@ -404,57 +401,18 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE | SMB2_CONTINUE_FLAG_RESTART; f.in.max_response_size = 0x1000; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb2_find(private->tree, req, &f); - } - c_req = smb2_find_send(private->tree, &f); SIMPLE_ASYNC_TAIL; } -/* - a handler for async qpathinfo replies - */ -static void async_qpathinfo(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - return NT_STATUS_NOT_IMPLEMENTED; - req->async_states->status = smb_raw_pathinfo_recv(c_req, req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); -} - /* return info on a pathname */ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_pathinfo(private->tree, req, info); - } - - c_req = smb_raw_pathinfo_send(private->tree, info); - - ASYNC_RECV_TAIL(info, async_qpathinfo); -} - -/* - a handler for async qfileinfo replies - */ -static void async_qfileinfo(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; return NT_STATUS_NOT_IMPLEMENTED; - req->async_states->status = smb_raw_fileinfo_recv(c_req, req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); } /* @@ -463,19 +421,7 @@ static void async_qfileinfo(struct smbcli_request *c_req) static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_fileinfo(private->tree, req, io); - } - - c_req = smb_raw_fileinfo_send(private->tree, io); - - ASYNC_RECV_TAIL(io, async_qfileinfo); } @@ -485,89 +431,17 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *st) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_setpathinfo(private->tree, st); - } - - c_req = smb_raw_setpathinfo_send(private->tree, st); - - SIMPLE_ASYNC_TAIL; } -/* - a handler for async open replies - */ -static void async_open(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct cvfs_private *cvfs = async->cvfs; - struct ntvfs_request *req = async->req; - struct cvfs_file *f = async->f; - union smb_open *io = async->parms; - union smb_handle *file; - talloc_free(async); - req->async_states->status = smb_raw_open_recv(c_req, req, io); - SMB_OPEN_OUT_FILE(io, file); - f->fnum = file->fnum; - file->ntvfs = NULL; - if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; - req->async_states->status = ntvfs_handle_set_backend_data(f->h, cvfs->ntvfs, f); - if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; - file->ntvfs = f->h; - DLIST_ADD(cvfs->files, f); -failed: - req->async_states->send_fn(req); -} - /* open a file */ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_open *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - struct ntvfs_handle *h; - struct cvfs_file *f; - NTSTATUS status; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->generic.level != RAW_OPEN_GENERIC) { - return ntvfs_map_open(ntvfs, req, io); - } - - status = ntvfs_handle_new(ntvfs, req, &h); - NT_STATUS_NOT_OK_RETURN(status); - - f = talloc_zero(h, struct cvfs_file); - NT_STATUS_HAVE_NO_MEMORY(f); - f->h = h; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - union smb_handle *file; - - status = smb_raw_open(private->tree, req, io); - NT_STATUS_NOT_OK_RETURN(status); - - SMB_OPEN_OUT_FILE(io, file); - f->fnum = file->fnum; - file->ntvfs = NULL; - status = ntvfs_handle_set_backend_data(f->h, private->ntvfs, f); - NT_STATUS_NOT_OK_RETURN(status); - file->ntvfs = f->h; - DLIST_ADD(private->files, f); - - return NT_STATUS_OK; - } - - c_req = smb_raw_open_send(private->tree, io); - - ASYNC_RECV_TAIL_F(io, async_open, f); } /* @@ -576,17 +450,7 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_mkdir *md) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_mkdir(private->tree, md); - } - - c_req = smb_raw_mkdir_send(private->tree, md); - - SIMPLE_ASYNC_TAIL; } /* @@ -595,16 +459,7 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_rmdir *rd) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_rmdir(private->tree, rd); - } - c_req = smb_raw_rmdir_send(private->tree, rd); - - SIMPLE_ASYNC_TAIL; } /* @@ -613,25 +468,7 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_rename *ren) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - - if (ren->nttrans.level == RAW_RENAME_NTTRANS) { - struct cvfs_file *f; - f = ntvfs_handle_get_backend_data(ren->nttrans.in.file.ntvfs, ntvfs); - if (!f) return NT_STATUS_INVALID_HANDLE; - ren->nttrans.in.file.fnum = f->fnum; - } - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_rename(private->tree, ren); - } - - c_req = smb_raw_rename_send(private->tree, ren); - - SIMPLE_ASYNC_TAIL; } /* @@ -643,53 +480,13 @@ static NTSTATUS cvfs_copy(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } -/* - a handler for async read replies - */ -static void async_read(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_read_recv(c_req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); -} - /* read from a file */ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_read *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->generic.level != RAW_READ_GENERIC) { - return ntvfs_map_read(ntvfs, req, io); - } - - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_read(private->tree, io); - } - - c_req = smb_raw_read_send(private->tree, io); - - ASYNC_RECV_TAIL(io, async_read); -} - -/* - a handler for async write replies - */ -static void async_write(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_write_recv(c_req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); } /* @@ -698,34 +495,7 @@ static void async_write(struct smbcli_request *c_req) static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_write *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->generic.level != RAW_WRITE_GENERIC) { - return ntvfs_map_write(ntvfs, req, io); - } - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_write(private->tree, io); - } - - c_req = smb_raw_write_send(private->tree, io); - - ASYNC_RECV_TAIL(io, async_write); -} - -/* - a handler for async seek replies - */ -static void async_seek(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_seek_recv(c_req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); } /* @@ -735,19 +505,7 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_seek *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_seek(private->tree, io); - } - - c_req = smb_raw_seek_send(private->tree, io); - - ASYNC_RECV_TAIL(io, async_seek); } /* @@ -757,28 +515,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_flush *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - switch (io->generic.level) { - case RAW_FLUSH_FLUSH: - SETUP_FILE; - break; - case RAW_FLUSH_ALL: - io->generic.in.file.fnum = 0xFFFF; - break; - case RAW_FLUSH_SMB2: - return NT_STATUS_INVALID_LEVEL; - } - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_flush(private->tree, io); - } - - c_req = smb_raw_flush_send(private->tree, io); - - SIMPLE_ASYNC_TAIL; } /* @@ -787,28 +524,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_close *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - struct cvfs_file *f; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->generic.level != RAW_CLOSE_GENERIC) { - return ntvfs_map_close(ntvfs, req, io); - } - SETUP_FILE_HERE(f); - /* Note, we aren't free-ing f, or it's h here. Should we? - even if file-close fails, we'll remove it from the list, - what else would we do? Maybe we should not remove until - after the proxied call completes? */ - DLIST_REMOVE(private->files, f); - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_close(private->tree, io); - } - - c_req = smb_raw_close_send(private->tree, io); - - SIMPLE_ASYNC_TAIL; } /* @@ -817,17 +533,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_exit(private->tree->session); - } - - c_req = smb_raw_exit_send(private->tree->session); - - SIMPLE_ASYNC_TAIL; } /* @@ -856,22 +562,7 @@ static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { - struct cvfs_private *private = ntvfs->private_data; - struct async_info *a; - return NT_STATUS_NOT_IMPLEMENTED; - /* find the matching request */ - for (a=private->pending;a;a=a->next) { - if (a->req == req) { - break; - } - } - - if (a == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - return smb_raw_ntcancel(a->c_req); } /* @@ -880,21 +571,7 @@ static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_lock *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->generic.level != RAW_LOCK_GENERIC) { - return ntvfs_map_lock(ntvfs, req, io); - } - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_lock(private->tree, io); - } - - c_req = smb_raw_lock_send(private->tree, io); - SIMPLE_ASYNC_TAIL; } /* @@ -904,18 +581,7 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_setfileinfo(private->tree, io); - } - c_req = smb_raw_setfileinfo_send(private->tree, io); - - SIMPLE_ASYNC_TAIL; } @@ -924,7 +590,7 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, */ static void async_fsinfo(struct smb2_request *c_req) { - struct async_info *async = c_req->async.private; + struct async_info *async = c_req->async.private_data; struct ntvfs_request *req = async->req; req->async_states->status = smb2_getinfo_fs_recv(c_req, req, async->parms); talloc_free(async); @@ -941,6 +607,8 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, struct smb2_request *c_req; enum smb_fsinfo_level level = fs->generic.level; + CHECK_ASYNC(req); + switch (level) { /* some levels go straight through */ case RAW_QFS_VOLUME_INFORMATION: @@ -976,10 +644,6 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, fs->generic.level = level; fs->generic.handle = private->roothandle; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb2_getinfo_fs(private->tree, req, fs); - } - c_req = smb2_getinfo_fs_send(private->tree, fs); ASYNC_RECV_TAIL(fs, async_fsinfo); @@ -1005,7 +669,6 @@ static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smb2_find f; enum smb_search_data_level smb2_level; - uint32_t continue_flags = 0; uint_t count, i; union smb_search_data *data; NTSTATUS status; @@ -1077,22 +740,14 @@ static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, void *search_private, bool (*callback)(void *, const union smb_search_data *)) { - struct cvfs_private *private = ntvfs->private_data; - return NT_STATUS_NOT_IMPLEMENTED; - - return smb_raw_search_next(private->tree, req, io, search_private, callback); } /* close a search */ static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_close *io) { - struct cvfs_private *private = ntvfs->private_data; - return NT_STATUS_NOT_IMPLEMENTED; - - return smb_raw_search_close(private->tree, io); } /* SMBtrans - not used on file shares */ @@ -1103,51 +758,12 @@ static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } -/* - a handler for async change notify replies - */ -static void async_changenotify(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_changenotify_recv(c_req, req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); -} - /* change notify request - always async */ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_notify *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - int saved_timeout = private->transport->options.request_timeout; - struct cvfs_file *f; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->nttrans.level != RAW_NOTIFY_NTTRANS) { - return NT_STATUS_NOT_IMPLEMENTED; - } - - f = ntvfs_handle_get_backend_data(io->nttrans.in.file.ntvfs, ntvfs); - if (!f) return NT_STATUS_INVALID_HANDLE; - io->nttrans.in.file.fnum = f->fnum; - - /* this request doesn't make sense unless its async */ - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return NT_STATUS_INVALID_PARAMETER; - } - - /* we must not timeout on notify requests - they wait - forever */ - private->transport->options.request_timeout = 0; - - c_req = smb_raw_changenotify_send(private->tree, io); - - private->transport->options.request_timeout = saved_timeout; - - ASYNC_RECV_TAIL(io, async_changenotify); } /* -- cgit From 03643aec88244d976da394521adbd29a31339569 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 19:54:27 +0200 Subject: Use variables for source directory in a couple more places. (This used to be commit c41bd3005f5f0b9cfd3709fc9217b4a401d265b4) --- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/config.mk | 16 ++++++++-------- source4/ntvfs/posix/config.mk | 8 ++++---- source4/ntvfs/sysdep/config.mk | 8 ++++---- source4/ntvfs/unixuid/config.mk | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index c66257b73f..f4518698ea 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -7,5 +7,5 @@ PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ -ntvfs_common_OBJ_FILES = $(addprefix ntvfs/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) +ntvfs_common_OBJ_FILES = $(addprefix $(ntvfssrcdir)/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 93cbf64d8f..81c295ef67 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -14,7 +14,7 @@ PRIVATE_DEPENDENCIES = \ # End MODULE ntvfs_cifs ################################################ -ntvfs_cifs_OBJ_FILES = ntvfs/cifs/vfs_cifs.o +ntvfs_cifs_OBJ_FILES = $(ntvfssrcdir)/cifs/vfs_cifs.o ################################################ # Start MODULE ntvfs_simple @@ -25,7 +25,7 @@ PRIVATE_PROTO_HEADER = simple/proto.h # End MODULE ntvfs_simple ################################################ -ntvfs_simple_OBJ_FILES = $(addprefix ntvfs/simple/, vfs_simple.o svfs_util.o) +ntvfs_simple_OBJ_FILES = $(addprefix $(ntvfssrcdir)/simple/, vfs_simple.o svfs_util.o) ################################################ # Start MODULE ntvfs_cifsposix @@ -38,7 +38,7 @@ PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h ################################################ ntvfs_cifsposix_OBJ_FILES = \ - $(addprefix ntvfs/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) + $(addprefix $(ntvfssrcdir)/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) ################################################ # Start MODULE ntvfs_print @@ -48,7 +48,7 @@ SUBSYSTEM = ntvfs # End MODULE ntvfs_print ################################################ -ntvfs_print_OBJ_FILES = ntvfs/print/vfs_print.o +ntvfs_print_OBJ_FILES = $(ntvfssrcdir)/print/vfs_print.o ################################################ # Start MODULE ntvfs_ipc @@ -60,7 +60,7 @@ PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON # End MODULE ntvfs_ipc ################################################ -ntvfs_ipc_OBJ_FILES = $(addprefix ntvfs/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) +ntvfs_ipc_OBJ_FILES = $(addprefix $(ntvfssrcdir)/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) ################################################ # Start MODULE ntvfs_nbench @@ -70,16 +70,16 @@ INIT_FUNCTION = ntvfs_nbench_init # End MODULE ntvfs_nbench ################################################ -ntvfs_nbench_OBJ_FILES = ntvfs/nbench/vfs_nbench.o +ntvfs_nbench_OBJ_FILES = $(ntvfssrcdir)/nbench/vfs_nbench.o ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::ntvfs] PRIVATE_PROTO_HEADER = ntvfs_proto.h -ntvfs_OBJ_FILES = $(addprefix ntvfs/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) +ntvfs_OBJ_FILES = $(addprefix $(ntvfssrcdir)/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) -# PUBLIC_HEADERS += ntvfs/ntvfs.h +# PUBLIC_HEADERS += $(ntvfssrcdir)/ntvfs.h # # End SUBSYSTEM NTVFS ################################################ diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 865a0ffd4a..256ad44b59 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -7,7 +7,7 @@ PRIVATE_DEPENDENCIES = NDR_XATTR ntvfs_posix # End MODULE pvfs_acl_xattr ################################################ -pvfs_acl_xattr_OBJ_FILES = ntvfs/posix/pvfs_acl_xattr.o +pvfs_acl_xattr_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_xattr.o ################################################ # Start MODULE pvfs_acl_nfs4 @@ -18,7 +18,7 @@ PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix # End MODULE pvfs_acl_nfs4 ################################################ -pvfs_acl_nfs4_OBJ_FILES = ntvfs/posix/pvfs_acl_nfs4.o +pvfs_acl_nfs4_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_nfs4.o ################################################ [MODULE::pvfs_aio] @@ -26,7 +26,7 @@ SUBSYSTEM = ntvfs PRIVATE_DEPENDENCIES = LIBAIO_LINUX ################################################ -pvfs_aio_OBJ_FILES = ntvfs/posix/pvfs_aio.o +pvfs_aio_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_aio.o ################################################ # Start MODULE ntvfs_posix @@ -41,7 +41,7 @@ PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_ai # End MODULE ntvfs_posix ################################################ -ntvfs_posix_OBJ_FILES = $(addprefix ntvfs/posix/, \ +ntvfs_posix_OBJ_FILES = $(addprefix $(ntvfssrcdir)/posix/, \ vfs_posix.o \ pvfs_util.o \ pvfs_search.o \ diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index 68be660049..1122d5c39d 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -6,7 +6,7 @@ INIT_FUNCTION = sys_notify_inotify_init # End MODULE sys_notify_inotify ################################################ -sys_notify_inotify_OBJ_FILES = ntvfs/sysdep/inotify.o +sys_notify_inotify_OBJ_FILES = $(ntvfssrcdir)/sysdep/inotify.o ################################################ # Start SUBSYSTEM sys_notify @@ -14,12 +14,12 @@ sys_notify_inotify_OBJ_FILES = ntvfs/sysdep/inotify.o # End SUBSYSTEM sys_notify ################################################ -sys_notify_OBJ_FILES = ntvfs/sysdep/sys_notify.o +sys_notify_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_notify.o [SUBSYSTEM::sys_lease_linux] -sys_lease_linux_OBJ_FILES = ntvfs/sysdep/sys_lease_linux.o +sys_lease_linux_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_lease_linux.o [SUBSYSTEM::sys_lease] -sys_lease_OBJ_FILES = ntvfs/sysdep/sys_lease.o +sys_lease_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_lease.o diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 968e56bde4..6377657cec 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -7,4 +7,4 @@ PRIVATE_DEPENDENCIES = SAMDB NSS_WRAPPER # End MODULE ntvfs_unixuid ################################################ -ntvfs_unixuid_OBJ_FILES = ntvfs/unixuid/vfs_unixuid.o +ntvfs_unixuid_OBJ_FILES = $(ntvfssrcdir)/unixuid/vfs_unixuid.o -- cgit From 4c8756f147f8b9a2806fd76e4cb06bb99d391516 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 22:30:08 +0200 Subject: Create prototype headers from Makefile directory, without smb_build in the middle. (This used to be commit f4a77b96f9c17d853348b70794026e5b9e384942) --- source4/ntvfs/common/config.mk | 3 ++- source4/ntvfs/config.mk | 12 ++++++++---- source4/ntvfs/posix/config.mk | 3 ++- 3 files changed, 12 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index f4518698ea..0771733eff 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -1,7 +1,6 @@ ################################################ # Start LIBRARY ntvfs_common [SUBSYSTEM::ntvfs_common] -PRIVATE_PROTO_HEADER = proto.h PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify sys_lease share LIBDBWRAP PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common @@ -9,3 +8,5 @@ PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb ntvfs_common_OBJ_FILES = $(addprefix $(ntvfssrcdir)/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) +$(call proto_header_template,$(ntvfssrcdir)/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c)) + diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 81c295ef67..aa952e1017 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -21,25 +21,27 @@ ntvfs_cifs_OBJ_FILES = $(ntvfssrcdir)/cifs/vfs_cifs.o [MODULE::ntvfs_simple] INIT_FUNCTION = ntvfs_simple_init SUBSYSTEM = ntvfs -PRIVATE_PROTO_HEADER = simple/proto.h # End MODULE ntvfs_simple ################################################ ntvfs_simple_OBJ_FILES = $(addprefix $(ntvfssrcdir)/simple/, vfs_simple.o svfs_util.o) +$(call proto_header_template,$(ntvfssrcdir)/simple/proto.h,$(ntvfs_simple_OBJ_FILES:.o=.c)) + ################################################ # Start MODULE ntvfs_cifsposix [MODULE::ntvfs_cifsposix] #ENABLE = NO INIT_FUNCTION = ntvfs_cifs_posix_init SUBSYSTEM = ntvfs -PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h # End MODULE ntvfs_cifsposix ################################################ ntvfs_cifsposix_OBJ_FILES = \ $(addprefix $(ntvfssrcdir)/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) +$(call proto_header_template,$(ntvfssrcdir)/cifs_posix_cli/proto.h,$(ntvfs_cifsposix_OBJ_FILES:.o=.c)) + ################################################ # Start MODULE ntvfs_print [MODULE::ntvfs_print] @@ -55,13 +57,14 @@ ntvfs_print_OBJ_FILES = $(ntvfssrcdir)/print/vfs_print.o [MODULE::ntvfs_ipc] SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_ipc_init -PRIVATE_PROTO_HEADER = ipc/proto.h PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON # End MODULE ntvfs_ipc ################################################ ntvfs_ipc_OBJ_FILES = $(addprefix $(ntvfssrcdir)/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) +$(call proto_header_template,$(ntvssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES)) + ################################################ # Start MODULE ntvfs_nbench [MODULE::ntvfs_nbench] @@ -75,10 +78,11 @@ ntvfs_nbench_OBJ_FILES = $(ntvfssrcdir)/nbench/vfs_nbench.o ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::ntvfs] -PRIVATE_PROTO_HEADER = ntvfs_proto.h ntvfs_OBJ_FILES = $(addprefix $(ntvfssrcdir)/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) +$(call proto_header_template,$(ntvfssrcdir)/ntvfs_proto.h,$(ntvfs_OBJ_FILES:.o=.c)) + # PUBLIC_HEADERS += $(ntvfssrcdir)/ntvfs.h # # End SUBSYSTEM NTVFS diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 256ad44b59..5d90942b12 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -34,7 +34,6 @@ pvfs_aio_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_aio.o SUBSYSTEM = ntvfs OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init -PRIVATE_PROTO_HEADER = vfs_posix_proto.h #PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio \ LIBWBCLIENT @@ -71,3 +70,5 @@ ntvfs_posix_OBJ_FILES = $(addprefix $(ntvfssrcdir)/posix/, \ xattr_system.o \ xattr_tdb.o) +$(call proto_header_template,$(ntvfssrcdir)/posix/vfs_posix_proto.h,$(ntvfs_posix_OBJ_FILES:.o=.c)) + -- cgit From 4c70cda986c86fe536327321d04c29eca81b6409 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 23:02:47 +0200 Subject: Fix a couple (well, little more than that..) of typos. (This used to be commit a6b52119940a900fb0de3864b8bca94e2965cc24) --- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/config.mk | 8 ++++---- source4/ntvfs/posix/config.mk | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 0771733eff..a10ae16afd 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -8,5 +8,5 @@ PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb ntvfs_common_OBJ_FILES = $(addprefix $(ntvfssrcdir)/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) -$(call proto_header_template,$(ntvfssrcdir)/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c))) diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index aa952e1017..bd54fc75e5 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -26,7 +26,7 @@ SUBSYSTEM = ntvfs ntvfs_simple_OBJ_FILES = $(addprefix $(ntvfssrcdir)/simple/, vfs_simple.o svfs_util.o) -$(call proto_header_template,$(ntvfssrcdir)/simple/proto.h,$(ntvfs_simple_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/simple/proto.h,$(ntvfs_simple_OBJ_FILES:.o=.c))) ################################################ # Start MODULE ntvfs_cifsposix @@ -40,7 +40,7 @@ SUBSYSTEM = ntvfs ntvfs_cifsposix_OBJ_FILES = \ $(addprefix $(ntvfssrcdir)/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) -$(call proto_header_template,$(ntvfssrcdir)/cifs_posix_cli/proto.h,$(ntvfs_cifsposix_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/cifs_posix_cli/proto.h,$(ntvfs_cifsposix_OBJ_FILES:.o=.c))) ################################################ # Start MODULE ntvfs_print @@ -63,7 +63,7 @@ PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON ntvfs_ipc_OBJ_FILES = $(addprefix $(ntvfssrcdir)/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) -$(call proto_header_template,$(ntvssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES))) ################################################ # Start MODULE ntvfs_nbench @@ -81,7 +81,7 @@ ntvfs_nbench_OBJ_FILES = $(ntvfssrcdir)/nbench/vfs_nbench.o ntvfs_OBJ_FILES = $(addprefix $(ntvfssrcdir)/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) -$(call proto_header_template,$(ntvfssrcdir)/ntvfs_proto.h,$(ntvfs_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/ntvfs_proto.h,$(ntvfs_OBJ_FILES:.o=.c))) # PUBLIC_HEADERS += $(ntvfssrcdir)/ntvfs.h # diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 5d90942b12..0ee3e3be16 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -70,5 +70,5 @@ ntvfs_posix_OBJ_FILES = $(addprefix $(ntvfssrcdir)/posix/, \ xattr_system.o \ xattr_tdb.o) -$(call proto_header_template,$(ntvfssrcdir)/posix/vfs_posix_proto.h,$(ntvfs_posix_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/posix/vfs_posix_proto.h,$(ntvfs_posix_OBJ_FILES:.o=.c))) -- cgit From 60ae8f06574c74261643f469e6be2a945fd90880 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 23:40:23 +0200 Subject: Fix a bunch of dependencies. (This used to be commit a63f458462d207d215a6e4ef8e480b0c8daedf6a) --- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/config.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index a10ae16afd..1fe093bb69 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -8,5 +8,5 @@ PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb ntvfs_common_OBJ_FILES = $(addprefix $(ntvfssrcdir)/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) -$(eval $(call proto_header_template,$(ntvfssrcdir)/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c))) +$(eval $(call proto_header_template,$(ntvfssrcdir)/common/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c))) diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index bd54fc75e5..8e647516ef 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -63,7 +63,7 @@ PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON ntvfs_ipc_OBJ_FILES = $(addprefix $(ntvfssrcdir)/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) -$(eval $(call proto_header_template,$(ntvfssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES))) +$(eval $(call proto_header_template,$(ntvfssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES:.o=.c))) ################################################ # Start MODULE ntvfs_nbench -- cgit From 66cbf7eb59ab4a29dca1d30850c9aeb35a598b3d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 May 2008 11:39:16 +1000 Subject: added mkdir to SMB2 proxy (This used to be commit 1323aab11fbf346e19c4cef227d727ddfcaa7d60) --- source4/ntvfs/smb2/vfs_smb2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index 13dbb4ea2e..3a9a74a928 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -450,7 +450,14 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_mkdir *md) { - return NT_STATUS_NOT_IMPLEMENTED; + struct cvfs_private *private = ntvfs->private_data; + struct composite_context *c_req; + + CHECK_ASYNC(req); + + c_req = smb2_composite_mkdir_send(private->tree, md); + + SIMPLE_COMPOSITE_TAIL; } /* -- cgit From e7d993b8b26e121ff37640825b4d2f2c4d6332bf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 May 2008 13:05:08 +1000 Subject: added SMB2 proxying of rmdir (This used to be commit 1e0c24b2760f2a632333b51710cd9581f0cee851) --- source4/ntvfs/smb2/vfs_smb2.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index 3a9a74a928..cc09daf83f 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -349,6 +349,10 @@ static void async_simple_composite(struct composite_context *c_req) /* delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) + + BUGS: + - doesn't handle wildcards + - doesn't obey attrib restrictions */ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_unlink *unl) @@ -466,7 +470,14 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_rmdir *rd) { - return NT_STATUS_NOT_IMPLEMENTED; + struct cvfs_private *private = ntvfs->private_data; + struct composite_context *c_req; + + CHECK_ASYNC(req); + + c_req = smb2_composite_rmdir_send(private->tree, rd); + + SIMPLE_COMPOSITE_TAIL; } /* -- cgit From 2352602a57989ac1572151cba1da1e78b9410860 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 May 2008 11:58:47 +1000 Subject: check the creation options where the client can require a path to be a file or a directory (This used to be commit c05b58940f06b01b9770c218eb0708cb621215ef) --- source4/ntvfs/posix/pvfs_open.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index c9c1c56f14..67937324cc 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1117,6 +1117,20 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } + /* if the client specified that it must not be a directory then + check that it isn't */ + if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) && + (io->generic.in.create_options & NTCREATEX_OPTIONS_NON_DIRECTORY_FILE)) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + + /* if the client specified that it must be a directory then + check that it is */ + if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) && + (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + /* directory opens are handled separately */ if ((name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) || (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) { -- cgit From 4d39976dddf2adf6a0d659050c3a21a6e0ff8ab2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 May 2008 22:12:20 +1000 Subject: fixed SMB2 locking - SMB2 locking is different in several ways from SMB locking. To fix it properly we will need a new generic mapping structure for locking, but for now do a best effort mapping - added locking to gentest_smb2 (This used to be commit ea6d9cf602302adafe0f9d5f5f90a9b26d1ead6f) --- source4/ntvfs/ntvfs_generic.c | 62 ++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 22 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 3653ad82c1..a706e621c9 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1011,38 +1011,56 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, locks->count = lck->unlock.in.count; break; - case RAW_LOCK_SMB2: - if (lck->smb2.in.unknown1 != 1) { + case RAW_LOCK_SMB2: { + /* this is only approximate! We need to change the + generic structure to fix this properly */ + int i; + if (lck->smb2.in.lock_count < 1) { return NT_STATUS_INVALID_PARAMETER; } lck2->generic.level = RAW_LOCK_GENERIC; lck2->generic.in.file.ntvfs= lck->smb2.in.file.ntvfs; - if (lck->smb2.in.flags & SMB2_LOCK_FLAG_EXCLUSIV) { - lck2->generic.in.mode = 0; - } else { - lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK; + lck2->generic.in.timeout = UINT32_MAX; + lck2->generic.in.mode = 0; + lck2->generic.in.lock_cnt = 0; + lck2->generic.in.ulock_cnt = 0; + lck2->generic.in.locks = talloc_zero_array(lck2, struct smb_lock_entry, + lck->smb2.in.lock_count); + if (lck2->generic.in.locks == NULL) { + return NT_STATUS_NO_MEMORY; } - if (lck->smb2.in.flags & SMB2_LOCK_FLAG_NO_PENDING) { - lck2->generic.in.timeout = 0; - } else { - lck2->generic.in.timeout = UINT32_MAX; + for (i=0;ismb2.in.lock_count;i++) { + if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) { + int j = lck2->generic.in.ulock_cnt; + lck2->generic.in.ulock_cnt++; + lck2->generic.in.locks[j].pid = 0; + lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; + lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length; + lck2->generic.in.locks[j].pid = 0; + } } - if (lck->smb2.in.flags & SMB2_LOCK_FLAG_UNLOCK) { - lck2->generic.in.ulock_cnt = 1; - lck2->generic.in.lock_cnt = 0; - } else { - lck2->generic.in.ulock_cnt = 0; - lck2->generic.in.lock_cnt = 1; + for (i=0;ismb2.in.lock_count;i++) { + if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) { + int j = lck2->generic.in.ulock_cnt + + lck2->generic.in.lock_cnt; + lck2->generic.in.lock_cnt++; + lck2->generic.in.locks[j].pid = 0; + lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; + lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length; + lck2->generic.in.locks[j].pid = 0; + if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) { + lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK; + } + if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_FAIL_IMMEDIATELY) { + lck2->generic.in.timeout = 0; + } + } } - lck2->generic.in.locks = locks; - locks->pid = 0; - locks->offset = lck->smb2.in.offset; - locks->count = lck->smb2.in.count; - /* initialize output value */ - lck->smb2.out.unknown1 = 0; + lck->smb2.out.reserved = 0; break; + } case RAW_LOCK_SMB2_BREAK: lck2->generic.level = RAW_LOCK_GENERIC; -- cgit From 7a9ffeca21666935ba08cd909b63fc063f7607f7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 May 2008 17:53:50 +1000 Subject: check for invalid file attribute values in create (This used to be commit dd21e3d9d788a67d4673625ed4892a875f4600dc) --- source4/ntvfs/posix/pvfs_open.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 67937324cc..cc4f0add27 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -548,6 +548,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, uint32_t oplock_level = OPLOCK_NONE, oplock_granted; bool allow_level_II_oplock = false; + if (io->ntcreatex.in.file_attr & ~FILE_ATTRIBUTE_ALL_MASK) { + return NT_STATUS_INVALID_PARAMETER; + } + if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { return NT_STATUS_CANNOT_DELETE; -- cgit From ac185ae0c5bca7fdf82e90a7d925c77e9cbe1888 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 May 2008 23:00:08 +1000 Subject: fixes for EAs and filename in gentest_smb2 results - SMB2 returns 0 for a null EA - return the share qualified name for the filename in SMB2 ALL_INFO level (This used to be commit f9708184a2037f83ebb97c847414326a42436154) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 6bc21e5e3e..102660a0bf 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -298,10 +298,21 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; info->all_info2.out.file_id = name->dos.file_id; info->all_info2.out.ea_size = name->dos.ea_size; + if (info->all_info2.out.ea_size == 4) { + /* SMB2 uses zero for a empty EA set */ + info->all_info2.out.ea_size = 0; + } info->all_info2.out.access_mask = 0; /* only set by qfileinfo */ info->all_info2.out.position = 0; /* only set by qfileinfo */ info->all_info2.out.mode = 0; /* only set by qfileinfo */ - info->all_info2.out.fname.s = name->original_name; + /* windows wants the full path on disk for this + result, but I really don't want to expose that on + the wire, so I'll give the path with a share + prefix, which is a good approximation */ + info->all_info2.out.fname.s = talloc_asprintf(req, "\\%s\\%s", + pvfs->share_name, + name->original_name); + NT_STATUS_HAVE_NO_MEMORY(info->all_info2.out.fname.s); return NT_STATUS_OK; } -- cgit From 2e0f61a18ab002a90faa06477fa258e36b8a5fc0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 May 2008 23:07:16 +1000 Subject: SMB2 read returns NT_STATUS_END_OF_FILE on read past end of file (This used to be commit 1590494daf5abe43e43402e7602f92267bcda34b) --- source4/ntvfs/ntvfs_generic.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index a706e621c9..62a1427405 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1276,6 +1276,11 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs, rd->smb2.out.data.length= rd2->generic.out.nread; rd->smb2.out.remaining = 0; rd->smb2.out.reserved = 0; + if (NT_STATUS_IS_OK(status) && + rd->smb2.out.data.length == 0 && + rd->smb2.in.length != 0) { + status = NT_STATUS_END_OF_FILE; + } break; default: return NT_STATUS_INVALID_LEVEL; -- cgit From ec7a6ee8ab25f4550a68b286d9eba32b955a73a1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 23 May 2008 00:07:12 +1000 Subject: fix make test for EAs again - go back to 4 byte alignment until I work out the rules that Vista wants more exactly - add the zero sized EA handling for SMB2 more generically (This used to be commit 326b69bc8064cbea357864cecd6bd27b50c57184) --- source4/ntvfs/posix/pvfs_fileinfo.c | 5 +++++ source4/ntvfs/posix/pvfs_qfileinfo.c | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 4c383ed45d..e35f42e955 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -75,6 +75,11 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, name->dos.alloc_size = pvfs_round_alloc_size(pvfs, name->st.st_size); name->dos.nlink = name->st.st_nlink; name->dos.ea_size = 4; + if (pvfs->ntvfs->ctx->protocol == PROTOCOL_SMB2) { + /* SMB2 represents a null EA with zero bytes */ + name->dos.ea_size = 0; + } + name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; name->dos.flags = 0; diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 102660a0bf..6e3092b744 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -298,10 +298,6 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; info->all_info2.out.file_id = name->dos.file_id; info->all_info2.out.ea_size = name->dos.ea_size; - if (info->all_info2.out.ea_size == 4) { - /* SMB2 uses zero for a empty EA set */ - info->all_info2.out.ea_size = 0; - } info->all_info2.out.access_mask = 0; /* only set by qfileinfo */ info->all_info2.out.position = 0; /* only set by qfileinfo */ info->all_info2.out.mode = 0; /* only set by qfileinfo */ -- cgit From c78bf3c2c925060df3362625bbd1c3e96751c087 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 May 2008 09:45:46 +0200 Subject: pvfs_streams: directories don't have streams metze (This used to be commit 9ed7bb5afe6a73206bcba85f25305eb6630a5571) --- source4/ntvfs/posix/pvfs_streams.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 7e6173ef2f..3cd9952fd5 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -36,6 +36,13 @@ NTSTATUS pvfs_stream_information(struct pvfs_state *pvfs, int i; NTSTATUS status; + /* directories don't have streams */ + if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + info->num_streams = 0; + info->streams = NULL; + return NT_STATUS_OK; + } + streams = talloc(mem_ctx, struct xattr_DosStreams); if (streams == NULL) { return NT_STATUS_NO_MEMORY; -- cgit From 391b746430ad3d0b371930933e0a77e6a70a9ac0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 May 2008 09:46:50 +0200 Subject: pvfs_resolve: stream_name = "" is only the same as NULL for files metze (This used to be commit 47756129fdf01075bac06cdd24107d7dc8ba34af) --- source4/ntvfs/posix/pvfs_fileinfo.c | 2 ++ source4/ntvfs/posix/pvfs_resolve.c | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index e35f42e955..04f6ad78d0 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -58,6 +58,8 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, if (S_ISDIR(name->st.st_mode)) { name->st.st_size = 0; name->st.st_nlink = 1; + } else if (name->stream_id == 0) { + name->stream_name = NULL; } /* for now just use the simple samba mapping */ diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 325bc74f8f..2e97925c49 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -202,7 +202,13 @@ static NTSTATUS parse_stream_name(struct pvfs_filename *name, const char *s) } *p = 0; if (strcmp(name->stream_name, "") == 0) { - name->stream_name = NULL; + /* + * we don't set stream_name to NULL, here + * as this would be wrong for directories + * + * pvfs_fill_dos_info() will set it to NULL + * if it's not a directory. + */ name->stream_id = 0; } else { name->stream_id = pvfs_name_hash(name->stream_name, -- cgit From 5d648b4aa5540e91fa7ea77668965eefd8926b1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 May 2008 09:47:59 +0200 Subject: pvfs_open: return FILE_IS_A_DIRECTORY when opening a stream on a directory metze (This used to be commit 1421b1cc0c442be839be702647009ed5295f34a3) --- source4/ntvfs/posix/pvfs_open.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index cc4f0add27..926c99d37e 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -182,12 +182,19 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, bool del_on_close; uint32_t create_options; uint32_t share_access; + bool forced; create_options = io->generic.in.create_options; share_access = io->generic.in.share_access; + forced = (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)?true:false; + if (name->stream_name) { - return NT_STATUS_NOT_A_DIRECTORY; + if (forced) { + return NT_STATUS_NOT_A_DIRECTORY; + } else { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } } /* if the client says it must be a directory, and it isn't, -- cgit