summaryrefslogtreecommitdiff
path: root/source4/ntvfs
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs')
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c2
-rw-r--r--source4/ntvfs/common/config.mk18
-rw-r--r--source4/ntvfs/common/notify.c4
-rw-r--r--source4/ntvfs/config.mk64
-rw-r--r--source4/ntvfs/ipc/ipc_rap.c11
-rw-r--r--source4/ntvfs/ipc/rap_server.c3
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c2
-rw-r--r--source4/ntvfs/ntvfs_base.c12
-rw-r--r--source4/ntvfs/ntvfs_generic.c114
-rw-r--r--source4/ntvfs/posix/config.mk29
-rw-r--r--source4/ntvfs/posix/pvfs_acl.c2
-rw-r--r--source4/ntvfs/posix/pvfs_fileinfo.c7
-rw-r--r--source4/ntvfs/posix/pvfs_open.c44
-rw-r--r--source4/ntvfs/posix/pvfs_qfileinfo.c9
-rw-r--r--source4/ntvfs/posix/pvfs_resolve.c8
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c2
-rw-r--r--source4/ntvfs/posix/pvfs_streams.c7
-rw-r--r--source4/ntvfs/posix/pvfs_xattr.c32
-rw-r--r--source4/ntvfs/posix/vfs_posix.c2
-rw-r--r--source4/ntvfs/posix/vfs_posix.h3
-rw-r--r--source4/ntvfs/smb2/vfs_smb2.c844
-rw-r--r--source4/ntvfs/sysdep/config.mk29
-rw-r--r--source4/ntvfs/sysdep/sys_lease.c8
-rw-r--r--source4/ntvfs/sysdep/sys_notify.c4
-rw-r--r--source4/ntvfs/unixuid/config.mk4
25 files changed, 1111 insertions, 153 deletions
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);
diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk
index 3963ebcdee..1fe093bb69 100644
--- a/source4/ntvfs/common/config.mk
+++ b/source4/ntvfs/common/config.mk
@@ -1,18 +1,12 @@
################################################
# 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 $(ntvfssrcdir)/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o)
+
+$(eval $(call proto_header_template,$(ntvfssrcdir)/common/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c)))
+
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/config.mk b/source4/ntvfs/config.mk
index 2f57c787ef..bf34c4082a 100644
--- a/source4/ntvfs/config.mk
+++ b/source4/ntvfs/config.mk
@@ -9,85 +9,95 @@ 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 = $(ntvfssrcdir)/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]
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 $(ntvfssrcdir)/simple/, vfs_simple.o svfs_util.o)
+
+$(eval $(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
-OBJ_FILES = \
- cifs_posix_cli/vfs_cifs_posix.o \
- cifs_posix_cli/svfs_util.o
# End MODULE ntvfs_cifsposix
################################################
+ntvfs_cifsposix_OBJ_FILES = \
+ $(addprefix $(ntvfssrcdir)/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o)
+
+$(eval $(call proto_header_template,$(ntvfssrcdir)/cifs_posix_cli/proto.h,$(ntvfs_cifsposix_OBJ_FILES:.o=.c)))
+
################################################
# 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 = $(ntvfssrcdir)/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 $(ntvfssrcdir)/ipc/, vfs_ipc.o ipc_rap.o rap_server.o)
+
+$(eval $(call proto_header_template,$(ntvfssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES:.o=.c)))
################################################
# 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 = $(ntvfssrcdir)/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
-
-# PUBLIC_HEADERS += ntvfs/ntvfs.h
+
+ntvfs_OBJ_FILES = $(addprefix $(ntvfssrcdir)/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o)
+
+$(eval $(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/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;
diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c
index 51faa44372..6de13e4a0a 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"
@@ -204,6 +203,17 @@ 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_smb2_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/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index e1a86c07c0..62a1427405 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 BATCH_OPLOCK_RETURN:
+ io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_BATCH;
+ break;
+ case EXCLUSIVE_OPLOCK_RETURN:
+ io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_EXCLUSIVE;
+ break;
+ case LEVEL_II_OPLOCK_RETURN:
+ 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;
@@ -986,37 +1011,72 @@ 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;i<lck->smb2.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;i<lck->smb2.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.reserved = 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.out.unknown1 = 0;
+ 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;
}
@@ -1214,7 +1274,13 @@ 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;
+ 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;
diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk
index 88048c2af7..0ee3e3be16 100644
--- a/source4/ntvfs/posix/config.mk
+++ b/source4/ntvfs/posix/config.mk
@@ -3,38 +3,44 @@
[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 = $(ntvfssrcdir)/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 = $(ntvfssrcdir)/posix/pvfs_acl_nfs4.o
+
################################################
[MODULE::pvfs_aio]
SUBSYSTEM = ntvfs
-OBJ_FILES = pvfs_aio.o
PRIVATE_DEPENDENCIES = LIBAIO_LINUX
################################################
+pvfs_aio_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_aio.o
+
################################################
# Start MODULE ntvfs_posix
[MODULE::ntvfs_posix]
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 $(ntvfssrcdir)/posix/, \
vfs_posix.o \
pvfs_util.o \
pvfs_search.o \
@@ -62,8 +68,7 @@ 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)
+
+$(eval $(call proto_header_template,$(ntvfssrcdir)/posix/vfs_posix_proto.h,$(ntvfs_posix_OBJ_FILES:.o=.c)))
+
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);
diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c
index 4c383ed45d..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 */
@@ -75,6 +77,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_open.c b/source4/ntvfs/posix/pvfs_open.c
index 6e77cb7c75..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,
@@ -262,7 +269,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 +422,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;
@@ -559,6 +555,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;
@@ -707,7 +707,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,
@@ -1129,6 +1128,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)) {
@@ -1257,7 +1270,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 +1491,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_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c
index 6bc21e5e3e..6e3092b744 100644
--- a/source4/ntvfs/posix/pvfs_qfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_qfileinfo.c
@@ -301,7 +301,14 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs,
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;
}
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,
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_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;
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.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,
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;
};
diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c
new file mode 100644
index 0000000000..cc09daf83f
--- /dev/null
+++ b/source4/ntvfs/smb2/vfs_smb2.c
@@ -0,0 +1,844 @@
+/*
+ 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 <myersjj@samba.org>
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+/*
+ this implements a CIFS->CIFS NTVFS filesystem backend.
+
+*/
+
+#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"
+#include "ntvfs/ntvfs.h"
+#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;
+ uint16_t fnum;
+ struct ntvfs_handle *h;
+};
+
+/* this is stored in ntvfs_private */
+struct cvfs_private {
+ struct smb2_tree *tree;
+ struct smb2_transport *transport;
+ struct ntvfs_module_context *ntvfs;
+ struct async_info *pending;
+ struct cvfs_file *files;
+
+ /* 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;
+};
+
+
+/* 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;
+ void *c_req;
+ struct composite_context *c_comp;
+ struct cvfs_file *f;
+ void *parms;
+};
+
+#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 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 SMB2_USE_MACHINE_ACCT_DEFAULT false
+
+/*
+ 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_smb2: ignoring oplock break level %d for fnum %d\n", level, fnum));
+ return true;
+ }
+
+ 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.
+*/
+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 composite_context *creq;
+ struct share_config *scfg = ntvfs->ctx->config;
+ struct smb2_tree *tree;
+
+ 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, 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, SMB2_USE_MACHINE_ACCT, SMB2_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;
+ }
+
+ creq = smb2_connect_send(private, host, remote_share,
+ lp_resolve_context(ntvfs->ctx->lp_ctx),
+ credentials,
+ ntvfs->ctx->event_ctx);
+
+ status = smb2_connect_recv(creq, private, &tree);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ status = smb2_get_roothandle(tree, &private->roothandle);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ private->tree = tree;
+ private->transport = private->tree->session->transport;
+ 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 */
+ /* TODO: enable oplocks
+ smbcli_oplock_handler(private->transport, oplock_handler, private);
+ */
+ 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;
+ talloc_free(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 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_smb2(struct smb2_request *c_req)
+{
+ struct async_info *async = c_req->async.private_data;
+ struct ntvfs_request *req = async->req;
+
+ smb2_request_receive(c_req);
+ req->async_states->status = smb2_request_destroy(c_req);
+ talloc_free(async);
+ 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 { \
+ 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_data = 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_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.
+ 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)
+{
+ struct cvfs_private *private = ntvfs->private_data;
+ struct composite_context *c_req;
+
+ CHECK_ASYNC(req);
+
+ c_req = smb2_composite_unlink_send(private->tree, unl);
+
+ SIMPLE_COMPOSITE_TAIL;
+}
+
+/*
+ ioctl interface
+*/
+static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_ioctl *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ 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 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
+ 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;
+
+ c_req = smb2_find_send(private->tree, &f);
+
+ SIMPLE_ASYNC_TAIL;
+}
+
+/*
+ return info on a pathname
+*/
+static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_fileinfo *info)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ query info on a open file
+*/
+static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_fileinfo *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+/*
+ set info on a pathname
+*/
+static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_setfileinfo *st)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+/*
+ open a file
+*/
+static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_open *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ 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 composite_context *c_req;
+
+ CHECK_ASYNC(req);
+
+ c_req = smb2_composite_mkdir_send(private->tree, md);
+
+ SIMPLE_COMPOSITE_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 composite_context *c_req;
+
+ CHECK_ASYNC(req);
+
+ c_req = smb2_composite_rmdir_send(private->tree, rd);
+
+ SIMPLE_COMPOSITE_TAIL;
+}
+
+/*
+ rename a set of files
+*/
+static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_rename *ren)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ 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;
+}
+
+/*
+ read from a file
+*/
+static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_read *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ write to a file
+*/
+static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_write *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ seek in a file
+*/
+static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req,
+ union smb_seek *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ flush a file
+*/
+static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req,
+ union smb_flush *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ close a file
+*/
+static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_close *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ exit - closing files open by the pid
+*/
+static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ 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)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ lock a byte range
+*/
+static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_lock *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ set info on a open file
+*/
+static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req,
+ union smb_setfileinfo *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+
+/*
+ a handler for async fsinfo replies
+ */
+static void async_fsinfo(struct smb2_request *c_req)
+{
+ 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);
+ 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 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:
+ 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;
+
+ /* 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;
+
+ c_req = smb2_getinfo_fs_send(private->tree, 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;
+ struct smb2_find f;
+ enum smb_search_data_level smb2_level;
+ 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);
+
+ for (i=0;i<count;i++) {
+ if (!callback(search_private, &data[i])) break;
+ }
+
+ io->t2ffirst.out.handle = 0;
+ io->t2ffirst.out.count = i;
+ /* TODO: fix end_of_file */
+ io->t2ffirst.out.end_of_search = 1;
+
+ talloc_free(data);
+
+ return NT_STATUS_OK;
+}
+
+/* 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 *))
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/* close a search */
+static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req, union smb_search_close *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/* 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;
+}
+
+/* change notify request - always async */
+static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs,
+ struct ntvfs_request *req,
+ union smb_notify *io)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ 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;
+
+ /* 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;
+}
diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk
index 048226efad..1122d5c39d 100644
--- a/source4/ntvfs/sysdep/config.mk
+++ b/source4/ntvfs/sysdep/config.mk
@@ -3,34 +3,23 @@
[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 = $(ntvfssrcdir)/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
-[MODULE::sys_lease_linux]
-SUBSYSTEM = sys_lease
-INIT_FUNCTION = sys_lease_linux_init
-OBJ_FILES = \
- sys_lease_linux.o
-# End MODULE sys_lease_linux
-################################################
+sys_notify_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_notify.o
+
+[SUBSYSTEM::sys_lease_linux]
+
+sys_lease_linux_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_lease_linux.o
-################################################
-# Start SUBSYSTEM sys_lease
[SUBSYSTEM::sys_lease]
-OBJ_FILES = \
- sys_lease.o
-# End SUBSYSTEM sys_lease
-################################################
+
+sys_lease_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_lease.o
diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c
index 28dd27a708..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;
@@ -55,7 +54,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);
@@ -109,9 +108,14 @@ _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;
+ 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..9770323c3f 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;
@@ -52,7 +51,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);
@@ -124,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 };
diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk
index 91976c6811..6377657cec 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 = $(ntvfssrcdir)/unixuid/vfs_unixuid.o