summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c79
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c20
-rw-r--r--source4/ntvfs/nbench/vfs_nbench.c97
-rw-r--r--source4/ntvfs/ntvfs.h8
-rw-r--r--source4/ntvfs/ntvfs_base.c21
-rw-r--r--source4/ntvfs/ntvfs_generic.c22
-rw-r--r--source4/ntvfs/posix/pvfs_fsinfo.c4
-rw-r--r--source4/ntvfs/posix/pvfs_mkdir.c4
-rw-r--r--source4/ntvfs/posix/pvfs_open.c6
-rw-r--r--source4/ntvfs/posix/pvfs_qfileinfo.c8
-rw-r--r--source4/ntvfs/posix/pvfs_read.c2
-rw-r--r--source4/ntvfs/posix/pvfs_rename.c2
-rw-r--r--source4/ntvfs/posix/pvfs_resolve.c14
-rw-r--r--source4/ntvfs/posix/pvfs_search.c10
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c2
-rw-r--r--source4/ntvfs/posix/pvfs_unlink.c2
-rw-r--r--source4/ntvfs/posix/pvfs_write.c2
-rw-r--r--source4/ntvfs/posix/vfs_posix.c10
-rw-r--r--source4/ntvfs/posix/vfs_posix.h2
-rw-r--r--source4/ntvfs/simple/svfs.h2
-rw-r--r--source4/ntvfs/simple/svfs_util.c2
-rw-r--r--source4/ntvfs/simple/vfs_simple.c40
-rw-r--r--source4/param/loadparm.c6
-rw-r--r--source4/smb_server/service.c4
-rw-r--r--source4/smb_server/smb_server.h7
25 files changed, 192 insertions, 184 deletions
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c
index f0fa5dc85b..2ae41a674c 100644
--- a/source4/ntvfs/cifs/vfs_cifs.c
+++ b/source4/ntvfs/cifs/vfs_cifs.c
@@ -32,7 +32,7 @@ struct cvfs_private {
struct smbcli_tree *tree;
struct smbcli_transport *transport;
struct smbsrv_tcon *tcon;
- const char *map_calls;
+ const struct ntvfs_ops *ops;
};
@@ -89,12 +89,11 @@ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde,
/*
connect to a share - used when a tree_connect operation comes in.
*/
-static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename)
+static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename, int depth)
{
struct smbsrv_tcon *tcon = req->tcon;
NTSTATUS status;
struct cvfs_private *private;
- const char *map_calls;
const char *host, *user, *pass, *domain, *remote_share;
/* Here we need to determine which server to connect to.
@@ -121,7 +120,7 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename)
}
ZERO_STRUCTP(private);
- req->tcon->ntvfs_private = (void *)private;
+ ntvfs_set_private(req->tcon, depth, private);
status = smbcli_tree_full_connection(&private->tree,
"vfs_cifs",
@@ -137,27 +136,11 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename)
private->transport = private->tree->session->transport;
private->tree->session->pid = SVAL(req->in.hdr, HDR_PID);
private->tcon = req->tcon;
+ private->ops = ntvfs_backend_byname("cifs", NTVFS_DISK);
tcon->fs_type = talloc_strdup(tcon, "NTFS");
tcon->dev_type = talloc_strdup(tcon, "A:");
- map_calls = lp_parm_string(req->tcon->service, "cifs", "map calls");
- if (map_calls) {
- private->map_calls = talloc_strdup(tcon, map_calls);
- }
-
- /* if we are mapping trans2, then we need to give a trans2
- pointer in the operations structure */
- if (private->map_calls && in_list("trans2", private->map_calls, True)) {
- struct ntvfs_ops *ops = talloc_memdup(tcon, tcon->ntvfs_ops,sizeof(*ops));
- static NTSTATUS cvfs_trans2(struct smbsrv_request *,struct smb_trans2 *);
- if (!ops) {
- return NT_STATUS_NO_MEMORY;
- }
- ops->trans2 = cvfs_trans2;
- tcon->ntvfs_ops = ops;
- }
-
/* we need to receive oplock break requests from the server */
smbcli_oplock_handler(private->transport, oplock_handler, private);
smbcli_transport_idle_handler(private->transport, idle_func, 1, private);
@@ -174,9 +157,9 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename)
/*
disconnect from a share
*/
-static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon)
+static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon, int depth)
{
- struct cvfs_private *private = tcon->ntvfs_private;
+ struct cvfs_private *private = tcon->ntvfs_private_list[depth];
smb_tree_disconnect(private->tree);
smbcli_tree_close(private->tree);
@@ -222,7 +205,7 @@ static void async_simple(struct smbcli_request *c_req)
*/
static NTSTATUS cvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
/* see if the front end will allow us to perform this
@@ -252,7 +235,7 @@ static void async_ioctl(struct smbcli_request *c_req)
*/
static NTSTATUS cvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
/* see if the front end will allow us to perform this
@@ -271,7 +254,7 @@ static NTSTATUS cvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io)
*/
static NTSTATUS cvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -299,7 +282,7 @@ static void async_qpathinfo(struct smbcli_request *c_req)
*/
static NTSTATUS cvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -327,7 +310,7 @@ static void async_qfileinfo(struct smbcli_request *c_req)
*/
static NTSTATUS cvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -345,7 +328,7 @@ static NTSTATUS cvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *i
*/
static NTSTATUS cvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -374,14 +357,9 @@ static void async_open(struct smbcli_request *c_req)
*/
static NTSTATUS cvfs_open(struct smbsrv_request *req, union smb_open *io)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
- if (private->map_calls && in_list("open", private->map_calls, True) &&
- io->generic.level != RAW_OPEN_GENERIC) {
- return ntvfs_map_open(req, io);
- }
-
if (!req->async.send_fn) {
return smb_raw_open(private->tree, req, io);
}
@@ -396,7 +374,7 @@ static NTSTATUS cvfs_open(struct smbsrv_request *req, union smb_open *io)
*/
static NTSTATUS cvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -413,7 +391,7 @@ static NTSTATUS cvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md)
*/
static NTSTATUS cvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -429,7 +407,7 @@ static NTSTATUS cvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd)
*/
static NTSTATUS cvfs_rename(struct smbsrv_request *req, union smb_rename *ren)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -465,7 +443,7 @@ static void async_read(struct smbcli_request *c_req)
*/
static NTSTATUS cvfs_read(struct smbsrv_request *req, union smb_read *rd)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -493,7 +471,7 @@ static void async_write(struct smbcli_request *c_req)
*/
static NTSTATUS cvfs_write(struct smbsrv_request *req, union smb_write *wr)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -526,7 +504,7 @@ static NTSTATUS cvfs_flush(struct smbsrv_request *req, struct smb_flush *io)
*/
static NTSTATUS cvfs_close(struct smbsrv_request *req, union smb_close *io)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -551,7 +529,7 @@ static NTSTATUS cvfs_exit(struct smbsrv_request *req)
*/
static NTSTATUS cvfs_lock(struct smbsrv_request *req, union smb_lock *lck)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -568,7 +546,7 @@ static NTSTATUS cvfs_lock(struct smbsrv_request *req, union smb_lock *lck)
static NTSTATUS cvfs_setfileinfo(struct smbsrv_request *req,
union smb_setfileinfo *info)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -596,7 +574,7 @@ static void async_fsinfo(struct smbcli_request *c_req)
*/
static NTSTATUS cvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -623,7 +601,7 @@ static NTSTATUS cvfs_search_first(struct smbsrv_request *req, union smb_search_f
void *search_private,
BOOL (*callback)(void *, union smb_search_data *))
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
return smb_raw_search_first(private->tree, req, io, search_private, callback);
}
@@ -633,7 +611,7 @@ static NTSTATUS cvfs_search_next(struct smbsrv_request *req, union smb_search_ne
void *search_private,
BOOL (*callback)(void *, union smb_search_data *))
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
return smb_raw_search_next(private->tree, req, io, search_private, callback);
}
@@ -641,7 +619,7 @@ static NTSTATUS cvfs_search_next(struct smbsrv_request *req, union smb_search_ne
/* close a search */
static NTSTATUS cvfs_search_close(struct smbsrv_request *req, union smb_search_close *io)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
return smb_raw_search_close(private->tree, io);
}
@@ -660,7 +638,7 @@ static void async_trans2(struct smbcli_request *c_req)
/* raw trans2 */
static NTSTATUS cvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2)
{
- struct cvfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req;
if (!req->async.send_fn) {
@@ -722,8 +700,9 @@ NTSTATUS ntvfs_cifs_init(void)
ops.search_close = cvfs_search_close;
ops.trans = cvfs_trans;
- /* only define this one for trans2 testing */
- ops.trans2 = NULL;
+ if (lp_parm_bool(-1, "cifs", "maptrans2", False)) {
+ ops.trans2 = cvfs_trans2;
+ }
/* register ourselves with the NTVFS subsystem. We register
under the name 'cifs'. */
diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c
index 053222460c..96e7820be5 100644
--- a/source4/ntvfs/ipc/vfs_ipc.c
+++ b/source4/ntvfs/ipc/vfs_ipc.c
@@ -105,7 +105,7 @@ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t
/*
connect to a share - always works
*/
-static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename)
+static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename, int depth)
{
struct smbsrv_tcon *tcon = req->tcon;
struct ipc_private *private;
@@ -118,7 +118,7 @@ static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename)
if (!private) {
return NT_STATUS_NO_MEMORY;
}
- tcon->ntvfs_private = (void *)private;
+ ntvfs_set_private(tcon, depth, private);
private->pipe_list = NULL;
private->next_fnum = 1;
@@ -130,9 +130,9 @@ static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename)
/*
disconnect from a share
*/
-static NTSTATUS ipc_disconnect(struct smbsrv_tcon *tcon)
+static NTSTATUS ipc_disconnect(struct smbsrv_tcon *tcon, int depth)
{
- struct ipc_private *private = tcon->ntvfs_private;
+ struct ipc_private *private = tcon->ntvfs_private_list[depth];
/* close any pipes that are open. Discard any unread data */
while (private->pipe_list) {
@@ -196,7 +196,7 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname,
NTSTATUS status;
struct dcesrv_ep_description ep_description;
struct auth_session_info *session_info = NULL;
- struct ipc_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(ipc_private, private, req);
mem_ctx = talloc_init("ipc_open '%s'", fname);
if (!mem_ctx) {
@@ -374,7 +374,7 @@ static NTSTATUS ipc_copy(struct smbsrv_request *req, struct smb_copy *cp)
*/
static NTSTATUS ipc_read(struct smbsrv_request *req, union smb_read *rd)
{
- struct ipc_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(ipc_private, private, req);
DATA_BLOB data;
uint16_t fnum;
struct pipe_state *p;
@@ -426,7 +426,7 @@ static NTSTATUS ipc_read(struct smbsrv_request *req, union smb_read *rd)
*/
static NTSTATUS ipc_write(struct smbsrv_request *req, union smb_write *wr)
{
- struct ipc_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(ipc_private, private, req);
DATA_BLOB data;
uint16_t fnum;
struct pipe_state *p;
@@ -495,7 +495,7 @@ static NTSTATUS ipc_flush(struct smbsrv_request *req, struct smb_flush *io)
*/
static NTSTATUS ipc_close(struct smbsrv_request *req, union smb_close *io)
{
- struct ipc_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(ipc_private, private, req);
struct pipe_state *p;
if (io->generic.level != RAW_CLOSE_CLOSE) {
@@ -595,7 +595,7 @@ NTSTATUS ipc_search_close(struct smbsrv_request *req, union smb_search_close *io
static NTSTATUS ipc_dcerpc_cmd(struct smbsrv_request *req, struct smb_trans2 *trans)
{
struct pipe_state *p;
- struct ipc_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(ipc_private, private, req);
NTSTATUS status;
/* the fnum is in setup[1] */
@@ -639,8 +639,8 @@ static NTSTATUS ipc_dcerpc_cmd(struct smbsrv_request *req, struct smb_trans2 *tr
/* SMBtrans - set named pipe state */
static NTSTATUS ipc_set_nm_pipe_state(struct smbsrv_request *req, struct smb_trans2 *trans)
{
+ NTVFS_GET_PRIVATE(ipc_private, private, req);
struct pipe_state *p;
- struct ipc_private *private = req->tcon->ntvfs_private;
/* the fnum is in setup[1] */
p = pipe_state_find(private, trans->in.setup[1]);
diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c
index 549d1d893f..b88c65d5db 100644
--- a/source4/ntvfs/nbench/vfs_nbench.c
+++ b/source4/ntvfs/nbench/vfs_nbench.c
@@ -29,8 +29,6 @@
/* this is stored in ntvfs_private */
struct nbench_private {
const struct ntvfs_ops *passthru_ops;
- void *passthru_private;
- const struct ntvfs_ops *nbench_ops;
int log_fd;
};
@@ -57,23 +55,9 @@ static void nbench_log(struct nbench_private *private,
/*
- when we call the next stacked level of NTVFS module we need
- to give it its own private pointer, plus its own NTVFS operations structure.
- Then we need to restore both of these after the call, as the next level could
- modify either of these
+ this is used to call the next module in the ntvfs chain
*/
-#define PASS_THRU(tcon, op, args) do { \
- tcon->ntvfs_private = private->passthru_private; \
- tcon->ntvfs_ops = private->passthru_ops; \
-\
- status = private->passthru_ops->op args; \
-\
- private->passthru_private = tcon->ntvfs_private; \
- private->passthru_ops = tcon->ntvfs_ops; \
-\
- tcon->ntvfs_private = private; \
- tcon->ntvfs_ops = private->nbench_ops; \
-} while (0)
+#define PASS_THRU(tcon, op, args) private->passthru_ops->op args;
/*
this pass through macro operates on request contexts, and disables
@@ -85,7 +69,9 @@ static void nbench_log(struct nbench_private *private,
#define PASS_THRU_REQ(req, op, args) do { \
void *send_fn_saved = req->async.send_fn; \
req->async.send_fn = NULL; \
- PASS_THRU(req->tcon, op, args); \
+ req->ntvfs_depth++; \
+ status = PASS_THRU(req->tcon, op, args); \
+ req->ntvfs_depth--; \
req->async.send_fn = send_fn_saved; \
} while (0)
@@ -93,19 +79,20 @@ static void nbench_log(struct nbench_private *private,
/*
connect to a share - used when a tree_connect operation comes in.
*/
-static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename)
+static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename, int depth)
{
struct nbench_private *private;
const char *passthru;
NTSTATUS status;
char *logname = NULL;
+ const char **handlers = lp_ntvfs_handler(req->tcon->service);
private = talloc_p(req->tcon, struct nbench_private);
if (!private) {
return NT_STATUS_NO_MEMORY;
}
- asprintf(&logname, "/tmp/nbenchlog.%u", getpid());
+ asprintf(&logname, "/tmp/nbenchlog%d.%u", depth, getpid());
private->log_fd = open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644);
free(logname);
@@ -114,18 +101,16 @@ static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename
return NT_STATUS_UNSUCCESSFUL;
}
- passthru = lp_parm_string(req->tcon->service, "nbench", "passthru");
-
- private->passthru_private = NULL;
- private->nbench_ops = req->tcon->ntvfs_ops;
- private->passthru_ops = ntvfs_backend_byname(passthru, NTVFS_DISK);
+ private->passthru_ops = ntvfs_backend_byname(handlers[depth+1], NTVFS_DISK);
if (!private->passthru_ops) {
DEBUG(0,("Unable to connect to '%s' pass through backend\n", passthru));
return NT_STATUS_UNSUCCESSFUL;
}
+
+ ntvfs_set_private(req->tcon, depth, private);
- PASS_THRU(req->tcon, connect, (req, sharename));
+ PASS_THRU(req->tcon, connect, (req, sharename, depth+1));
return status;
}
@@ -133,15 +118,15 @@ static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename
/*
disconnect from a share
*/
-static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon)
+static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon, int depth)
{
- struct nbench_private *private = tcon->ntvfs_private;
+ struct nbench_private *private = tcon->ntvfs_private_list[depth];
NTSTATUS status;
- PASS_THRU(tcon, disconnect, (tcon));
-
close(private->log_fd);
+ PASS_THRU(tcon, disconnect, (tcon, depth+1));
+
return status;
}
@@ -151,7 +136,7 @@ static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon)
*/
static NTSTATUS nbench_unlink(struct smbsrv_request *req, struct smb_unlink *unl)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, unlink, (req, unl));
@@ -168,7 +153,7 @@ static NTSTATUS nbench_unlink(struct smbsrv_request *req, struct smb_unlink *unl
*/
static NTSTATUS nbench_ioctl(struct smbsrv_request *req, union smb_ioctl *io)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, ioctl, (req, io));
@@ -183,7 +168,7 @@ static NTSTATUS nbench_ioctl(struct smbsrv_request *req, union smb_ioctl *io)
*/
static NTSTATUS nbench_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, chkpath, (req, cp));
@@ -200,7 +185,7 @@ static NTSTATUS nbench_chkpath(struct smbsrv_request *req, struct smb_chkpath *c
*/
static NTSTATUS nbench_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, qpathinfo, (req, info));
@@ -218,7 +203,7 @@ static NTSTATUS nbench_qpathinfo(struct smbsrv_request *req, union smb_fileinfo
*/
static NTSTATUS nbench_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, qfileinfo, (req, info));
@@ -237,7 +222,7 @@ static NTSTATUS nbench_qfileinfo(struct smbsrv_request *req, union smb_fileinfo
*/
static NTSTATUS nbench_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, setpathinfo, (req, st));
@@ -255,7 +240,7 @@ static NTSTATUS nbench_setpathinfo(struct smbsrv_request *req, union smb_setfile
*/
static NTSTATUS nbench_open(struct smbsrv_request *req, union smb_open *io)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, open, (req, io));
@@ -284,7 +269,7 @@ static NTSTATUS nbench_open(struct smbsrv_request *req, union smb_open *io)
*/
static NTSTATUS nbench_mkdir(struct smbsrv_request *req, union smb_mkdir *md)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, mkdir, (req, md));
@@ -299,7 +284,7 @@ static NTSTATUS nbench_mkdir(struct smbsrv_request *req, union smb_mkdir *md)
*/
static NTSTATUS nbench_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, rmdir, (req, rd));
@@ -316,7 +301,7 @@ static NTSTATUS nbench_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd)
*/
static NTSTATUS nbench_rename(struct smbsrv_request *req, union smb_rename *ren)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, rename, (req, ren));
@@ -343,7 +328,7 @@ static NTSTATUS nbench_rename(struct smbsrv_request *req, union smb_rename *ren)
*/
static NTSTATUS nbench_copy(struct smbsrv_request *req, struct smb_copy *cp)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, copy, (req, cp));
@@ -358,7 +343,7 @@ static NTSTATUS nbench_copy(struct smbsrv_request *req, struct smb_copy *cp)
*/
static NTSTATUS nbench_read(struct smbsrv_request *req, union smb_read *rd)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, read, (req, rd));
@@ -386,7 +371,7 @@ static NTSTATUS nbench_read(struct smbsrv_request *req, union smb_read *rd)
*/
static NTSTATUS nbench_write(struct smbsrv_request *req, union smb_write *wr)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, write, (req, wr));
@@ -424,7 +409,7 @@ static NTSTATUS nbench_write(struct smbsrv_request *req, union smb_write *wr)
*/
static NTSTATUS nbench_seek(struct smbsrv_request *req, struct smb_seek *io)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, seek, (req, io));
@@ -439,7 +424,7 @@ static NTSTATUS nbench_seek(struct smbsrv_request *req, struct smb_seek *io)
*/
static NTSTATUS nbench_flush(struct smbsrv_request *req, struct smb_flush *io)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, flush, (req, io));
@@ -456,7 +441,7 @@ static NTSTATUS nbench_flush(struct smbsrv_request *req, struct smb_flush *io)
*/
static NTSTATUS nbench_close(struct smbsrv_request *req, union smb_close *io)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, close, (req, io));
@@ -482,7 +467,7 @@ static NTSTATUS nbench_close(struct smbsrv_request *req, union smb_close *io)
*/
static NTSTATUS nbench_exit(struct smbsrv_request *req)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, exit, (req));
@@ -495,7 +480,7 @@ static NTSTATUS nbench_exit(struct smbsrv_request *req)
*/
static NTSTATUS nbench_lock(struct smbsrv_request *req, union smb_lock *lck)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, lock, (req, lck));
@@ -528,7 +513,7 @@ static NTSTATUS nbench_lock(struct smbsrv_request *req, union smb_lock *lck)
static NTSTATUS nbench_setfileinfo(struct smbsrv_request *req,
union smb_setfileinfo *info)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, setfileinfo, (req, info));
@@ -547,7 +532,7 @@ static NTSTATUS nbench_setfileinfo(struct smbsrv_request *req,
*/
static NTSTATUS nbench_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, fsinfo, (req, fs));
@@ -564,7 +549,7 @@ static NTSTATUS nbench_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs)
*/
static NTSTATUS nbench_lpq(struct smbsrv_request *req, union smb_lpq *lpq)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, lpq, (req, lpq));
@@ -581,7 +566,7 @@ static NTSTATUS nbench_search_first(struct smbsrv_request *req, union smb_search
void *search_private,
BOOL (*callback)(void *, union smb_search_data *))
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, search_first, (req, io, search_private, callback));
@@ -609,7 +594,7 @@ static NTSTATUS nbench_search_next(struct smbsrv_request *req, union smb_search_
void *search_private,
BOOL (*callback)(void *, union smb_search_data *))
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, search_next, (req, io, search_private, callback));
@@ -622,7 +607,7 @@ static NTSTATUS nbench_search_next(struct smbsrv_request *req, union smb_search_
/* close a search */
static NTSTATUS nbench_search_close(struct smbsrv_request *req, union smb_search_close *io)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, search_close, (req, io));
@@ -635,7 +620,7 @@ static NTSTATUS nbench_search_close(struct smbsrv_request *req, union smb_search
/* SMBtrans - not used on file shares */
static NTSTATUS nbench_trans(struct smbsrv_request *req, struct smb_trans2 *trans2)
{
- struct nbench_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status;
PASS_THRU_REQ(req, trans, (req,trans2));
diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h
index b7c110ebdb..c9cf6de1e0 100644
--- a/source4/ntvfs/ntvfs.h
+++ b/source4/ntvfs/ntvfs.h
@@ -30,8 +30,8 @@ struct ntvfs_ops {
enum ntvfs_type type;
/* initial setup */
- NTSTATUS (*connect)(struct smbsrv_request *req, const char *sharename);
- NTSTATUS (*disconnect)(struct smbsrv_tcon *tcon);
+ NTSTATUS (*connect)(struct smbsrv_request *req, const char *sharename, int depth);
+ NTSTATUS (*disconnect)(struct smbsrv_tcon *tcon, int depth);
/* path operations */
NTSTATUS (*unlink)(struct smbsrv_request *req, struct smb_unlink *unl);
@@ -85,3 +85,7 @@ struct ntvfs_critical_sizes {
int sizeof_smbsrv_tcon;
int sizeof_smbsrv_request;
};
+
+/* useful macro for backends */
+#define NTVFS_GET_PRIVATE(struct_name, name, req) \
+ struct struct_name *name = req->tcon->ntvfs_private_list[req->ntvfs_depth]
diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c
index 923a131d5e..03873ce697 100644
--- a/source4/ntvfs/ntvfs_base.c
+++ b/source4/ntvfs/ntvfs_base.c
@@ -135,14 +135,29 @@ BOOL ntvfs_init(void)
*/
NTSTATUS ntvfs_init_connection(struct smbsrv_request *req)
{
- const char *handler = lp_ntvfs_handler(req->tcon->service);
+ const char **handlers = lp_ntvfs_handler(req->tcon->service);
- req->tcon->ntvfs_ops = ntvfs_backend_byname(handler, req->tcon->type);
+ req->tcon->ntvfs_ops = ntvfs_backend_byname(handlers[0], req->tcon->type);
if (!req->tcon->ntvfs_ops) {
- DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", handler, req->tcon->type));
+ DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", handlers[0], req->tcon->type));
return NT_STATUS_UNSUCCESSFUL;
}
return NT_STATUS_OK;
}
+
+
+/*
+ set the private pointer for a backend
+*/
+void ntvfs_set_private(struct smbsrv_tcon *tcon, int depth, void *value)
+{
+ if (!tcon->ntvfs_private_list) {
+ tcon->ntvfs_private_list = talloc_array_p(tcon, void *, depth+1);
+ } else {
+ tcon->ntvfs_private_list = talloc_realloc_p(tcon->ntvfs_private_list,
+ void *, depth+1);
+ }
+ tcon->ntvfs_private_list[depth] = value;
+}
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index 29f21b1863..731e91f5c9 100644
--- a/source4/ntvfs/ntvfs_generic.c
+++ b/source4/ntvfs/ntvfs_generic.c
@@ -57,7 +57,8 @@ static BOOL is_exe_file(const char *fname)
/*
NTVFS open generic to any mapper
*/
-NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io)
+NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io,
+ const struct ntvfs_ops *ops)
{
NTSTATUS status;
union smb_open io2;
@@ -145,7 +146,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io)
io2.generic.in.file_attr = io->openx.in.file_attrs;
io2.generic.in.fname = io->openx.in.fname;
- status = req->tcon->ntvfs_ops->open(req, &io2);
+ status = ops->open(req, &io2);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -227,7 +228,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io)
DEBUG(9,("ntvfs_map_open(OPEN): mapped flags=0x%x to access_mask=0x%x and share_access=0x%x\n",
io->open.in.flags, io2.generic.in.access_mask, io2.generic.in.share_access));
- status = req->tcon->ntvfs_ops->open(req, &io2);
+ status = ops->open(req, &io2);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -249,7 +250,8 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io)
/*
NTVFS fsinfo generic to any mapper
*/
-NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs)
+NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs,
+ const struct ntvfs_ops *ops)
{
NTSTATUS status;
union smb_fsinfo fs2;
@@ -261,7 +263,7 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs)
/* ask the backend for the generic info */
fs2.generic.level = RAW_QFS_GENERIC;
- status = req->tcon->ntvfs_ops->fsinfo(req, &fs2);
+ status = ops->fsinfo(req, &fs2);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -590,7 +592,8 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info
/*
NTVFS fileinfo generic to any mapper
*/
-NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info)
+NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info,
+ const struct ntvfs_ops *ops)
{
NTSTATUS status;
union smb_fileinfo info2;
@@ -603,7 +606,7 @@ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *inf
info2.generic.level = RAW_FILEINFO_GENERIC;
info2.generic.in.fnum = info->generic.in.fnum;
- status = req->tcon->ntvfs_ops->qfileinfo(req, &info2);
+ status = ops->qfileinfo(req, &info2);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -613,7 +616,8 @@ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *inf
/*
NTVFS pathinfo generic to any mapper
*/
-NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info)
+NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info,
+ const struct ntvfs_ops *ops)
{
NTSTATUS status;
union smb_fileinfo info2;
@@ -626,7 +630,7 @@ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *inf
info2.generic.level = RAW_FILEINFO_GENERIC;
info2.generic.in.fname = info->generic.in.fname;
- status = req->tcon->ntvfs_ops->qpathinfo(req, &info2);
+ status = ops->qpathinfo(req, &info2);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c
index 826e331b84..f1c42e8920 100644
--- a/source4/ntvfs/posix/pvfs_fsinfo.c
+++ b/source4/ntvfs/posix/pvfs_fsinfo.c
@@ -29,11 +29,11 @@
*/
NTSTATUS pvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct stat st;
if (fs->generic.level != RAW_QFS_GENERIC) {
- return ntvfs_map_fsinfo(req, fs);
+ return ntvfs_map_fsinfo(req, fs, pvfs->ops);
}
if (sys_fsusage(pvfs->base_directory,
diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c
index 4881326ecb..de51d2e8fd 100644
--- a/source4/ntvfs/posix/pvfs_mkdir.c
+++ b/source4/ntvfs/posix/pvfs_mkdir.c
@@ -28,7 +28,7 @@
*/
NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
NTSTATUS status;
struct pvfs_filename *name;
@@ -62,7 +62,7 @@ NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md)
*/
NTSTATUS pvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
NTSTATUS status;
struct pvfs_filename *name;
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index 26fd444984..1c6ecc1eb2 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -45,14 +45,14 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, uint16_t fnum)
*/
NTSTATUS pvfs_open(struct smbsrv_request *req, union smb_open *io)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
int fd, flags;
struct pvfs_filename *name;
struct pvfs_file *f;
NTSTATUS status;
if (io->generic.level != RAW_OPEN_GENERIC) {
- return ntvfs_map_open(req, io);
+ return ntvfs_map_open(req, io, pvfs->ops);
}
/* resolve the cifs name to a posix name */
@@ -155,7 +155,7 @@ do_open:
*/
NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_file *f;
if (io->generic.level != RAW_CLOSE_CLOSE) {
diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c
index 691ba91532..649036b09a 100644
--- a/source4/ntvfs/posix/pvfs_qfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_qfileinfo.c
@@ -80,12 +80,12 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
*/
NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_filename *name;
NTSTATUS status;
if (info->generic.level != RAW_FILEINFO_GENERIC) {
- return ntvfs_map_qpathinfo(req, info);
+ return ntvfs_map_qpathinfo(req, info, pvfs->ops);
}
/* resolve the cifs name to a posix name */
@@ -106,12 +106,12 @@ NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info)
*/
NTSTATUS pvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_file *f;
NTSTATUS status;
if (info->generic.level != RAW_FILEINFO_GENERIC) {
- return ntvfs_map_qfileinfo(req, info);
+ return ntvfs_map_qfileinfo(req, info, pvfs->ops);
}
f = pvfs_find_fd(pvfs, info->generic.in.fnum);
diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c
index d30645e76d..cbb0317638 100644
--- a/source4/ntvfs/posix/pvfs_read.c
+++ b/source4/ntvfs/posix/pvfs_read.c
@@ -28,7 +28,7 @@
*/
NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd)
{
- struct pvfs_private *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
ssize_t ret;
struct pvfs_file *f;
diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c
index 40b84f7628..a58a1e9c6e 100644
--- a/source4/ntvfs/posix/pvfs_rename.c
+++ b/source4/ntvfs/posix/pvfs_rename.c
@@ -28,7 +28,7 @@
*/
NTSTATUS pvfs_rename(struct smbsrv_request *req, union smb_rename *ren)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
NTSTATUS status;
struct pvfs_filename *name1, *name2;
diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c
index 5c535c9880..dfd6744eff 100644
--- a/source4/ntvfs/posix/pvfs_resolve.c
+++ b/source4/ntvfs/posix/pvfs_resolve.c
@@ -164,10 +164,18 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
name->stream_name = NULL;
name->has_wildcard = False;
- if (*cifs_name == '\\') {
+ while (*cifs_name == '\\') {
cifs_name++;
}
+ if (*cifs_name == 0) {
+ name->full_name = talloc_asprintf(name, "%s/.", pvfs->base_directory);
+ if (name->full_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ return NT_STATUS_OK;
+ }
+
ret = talloc_asprintf(name, "%s/%s", pvfs->base_directory, cifs_name);
if (ret == NULL) {
return NT_STATUS_NO_MEMORY;
@@ -175,6 +183,10 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
p = ret + strlen(pvfs->base_directory) + 1;
+ if (p[strlen(cifs_name)-1] == '\\') {
+ p[strlen(cifs_name)-1] = 0;
+ }
+
/* now do an in-place conversion of '\' to '/', checking
for legal characters */
for (;*p;p++) {
diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c
index 1d1d973d3f..414b010263 100644
--- a/source4/ntvfs/posix/pvfs_search.c
+++ b/source4/ntvfs/posix/pvfs_search.c
@@ -255,7 +255,7 @@ static NTSTATUS pvfs_search_first_old(struct smbsrv_request *req, union smb_sear
BOOL (*callback)(void *, union smb_search_data *))
{
struct pvfs_dir *dir;
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_search_state *search;
uint_t reply_count;
uint16_t search_attrib;
@@ -331,7 +331,7 @@ static NTSTATUS pvfs_search_next_old(struct smbsrv_request *req, union smb_searc
void *search_private,
BOOL (*callback)(void *, union smb_search_data *))
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_search_state *search;
struct pvfs_dir *dir;
uint_t reply_count, max_count;
@@ -379,7 +379,7 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i
BOOL (*callback)(void *, union smb_search_data *))
{
struct pvfs_dir *dir;
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_search_state *search;
uint_t reply_count;
uint16_t search_attrib, max_count;
@@ -470,7 +470,7 @@ NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io,
void *search_private,
BOOL (*callback)(void *, union smb_search_data *))
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_search_state *search;
struct pvfs_dir *dir;
uint_t reply_count;
@@ -547,7 +547,7 @@ found:
/* close a search */
NTSTATUS pvfs_search_close(struct smbsrv_request *req, union smb_search_close *io)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_search_state *search;
uint16_t handle;
diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index a271b43d38..c2c58415be 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -29,7 +29,7 @@
NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req,
union smb_setfileinfo *info)
{
- struct pvfs_private *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_private, pvfs, req);
struct utimbuf unix_times;
struct pvfs_file *f;
diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c
index 98151d4e75..9e0353c041 100644
--- a/source4/ntvfs/posix/pvfs_unlink.c
+++ b/source4/ntvfs/posix/pvfs_unlink.c
@@ -63,7 +63,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
*/
NTSTATUS pvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_dir *dir;
NTSTATUS status;
uint32_t i, total_deleted=0;
diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c
index 4194ced431..ac9d23b88f 100644
--- a/source4/ntvfs/posix/pvfs_write.c
+++ b/source4/ntvfs/posix/pvfs_write.c
@@ -29,7 +29,7 @@
*/
NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr)
{
- struct pvfs_private *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
ssize_t ret;
struct pvfs_file *f;
diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c
index 84a5647075..9bd060c639 100644
--- a/source4/ntvfs/posix/vfs_posix.c
+++ b/source4/ntvfs/posix/vfs_posix.c
@@ -50,7 +50,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs)
directory exists (tho it doesn't need to be accessible by the user,
that comes later)
*/
-static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename)
+static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename, int depth)
{
struct smbsrv_tcon *tcon = req->tcon;
struct pvfs_state *pvfs;
@@ -71,6 +71,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename)
pvfs->tcon = tcon;
pvfs->base_directory = base_directory;
+ pvfs->ops = ntvfs_backend_byname("posix", NTVFS_DISK);
/* the directory must exist. Note that we deliberately don't
check that it is readable */
@@ -82,7 +83,8 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename)
tcon->fs_type = talloc_strdup(tcon, "NTFS");
tcon->dev_type = talloc_strdup(tcon, "A:");
- tcon->ntvfs_private = pvfs;
+
+ ntvfs_set_private(tcon, depth, pvfs);
pvfs_setup_options(pvfs);
@@ -92,7 +94,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename)
/*
disconnect from a share
*/
-static NTSTATUS pvfs_disconnect(struct smbsrv_tcon *tcon)
+static NTSTATUS pvfs_disconnect(struct smbsrv_tcon *tcon, int depth)
{
return NT_STATUS_OK;
}
@@ -110,7 +112,7 @@ static NTSTATUS pvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io)
*/
static NTSTATUS pvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp)
{
- struct pvfs_state *pvfs = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_filename *name;
NTSTATUS status;
diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h
index 8b7ddfad88..bfb1fbf7ca 100644
--- a/source4/ntvfs/posix/vfs_posix.h
+++ b/source4/ntvfs/posix/vfs_posix.h
@@ -49,6 +49,8 @@ struct pvfs_state {
} search;
struct pvfs_file *open_files;
+
+ const struct ntvfs_ops *ops;
};
diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h
index 98ce6469a2..33b7cb7011 100644
--- a/source4/ntvfs/simple/svfs.h
+++ b/source4/ntvfs/simple/svfs.h
@@ -10,6 +10,8 @@ struct svfs_private {
uint16_t next_search_handle;
struct svfs_file *open_files;
+
+ const struct ntvfs_ops *ops;
};
struct svfs_dir {
diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c
index 04165cadd9..2e64920fc8 100644
--- a/source4/ntvfs/simple/svfs_util.c
+++ b/source4/ntvfs/simple/svfs_util.c
@@ -31,7 +31,7 @@
*/
char *svfs_unix_path(struct smbsrv_request *req, const char *name)
{
- struct svfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(svfs_private, private, req);
char *ret;
if (*name != '\\') {
diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c
index 34a9c27f34..5bdec64f2b 100644
--- a/source4/ntvfs/simple/vfs_simple.c
+++ b/source4/ntvfs/simple/vfs_simple.c
@@ -61,15 +61,13 @@ static ssize_t pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offs
directory exists (tho it doesn't need to be accessible by the user,
that comes later)
*/
-static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename)
+static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename, int depth)
{
struct stat st;
struct smbsrv_tcon *tcon = req->tcon;
struct svfs_private *private;
- tcon->ntvfs_private = talloc_p(tcon, struct svfs_private);
-
- private = tcon->ntvfs_private;
+ private = talloc_p(tcon, struct svfs_private);
private->next_search_handle = 0;
private->connectpath = talloc_strdup(tcon, lp_pathname(tcon->service));
@@ -85,6 +83,8 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename)
tcon->fs_type = talloc_strdup(tcon, "NTFS");
tcon->dev_type = talloc_strdup(tcon, "A:");
+ ntvfs_set_private(tcon, depth, private);
+
DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename));
return NT_STATUS_OK;
@@ -93,7 +93,7 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename)
/*
disconnect from a share
*/
-static NTSTATUS svfs_disconnect(struct smbsrv_tcon *tcon)
+static NTSTATUS svfs_disconnect(struct smbsrv_tcon *tcon, int depth)
{
return NT_STATUS_OK;
}
@@ -242,12 +242,13 @@ static NTSTATUS svfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo
*/
static NTSTATUS svfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info)
{
+ NTVFS_GET_PRIVATE(svfs_private, private, req);
char *unix_path;
struct stat st;
DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.fname, info->generic.level));
if (info->generic.level != RAW_FILEINFO_GENERIC) {
- return ntvfs_map_qpathinfo(req, info);
+ return ntvfs_map_qpathinfo(req, info, private->ops);
}
unix_path = svfs_unix_path(req, info->generic.in.fname);
@@ -267,12 +268,12 @@ static NTSTATUS svfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *i
*/
static NTSTATUS svfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info)
{
- struct svfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(svfs_private, private, req);
struct svfs_file *f;
struct stat st;
if (info->generic.level != RAW_FILEINFO_GENERIC) {
- return ntvfs_map_qfileinfo(req, info);
+ return ntvfs_map_qfileinfo(req, info, private->ops);
}
f = find_fd(private, info->generic.in.fnum);
@@ -295,7 +296,7 @@ static NTSTATUS svfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *i
*/
static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io)
{
- struct svfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(svfs_private, private, req);
char *unix_path;
struct stat st;
int fd, flags;
@@ -303,7 +304,7 @@ static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io)
int create_flags, rdwr_flags;
if (io->generic.level != RAW_OPEN_GENERIC) {
- return ntvfs_map_open(req, io);
+ return ntvfs_map_open(req, io, private->ops);
}
if (lp_readonly(req->tcon->service)) {
@@ -561,7 +562,7 @@ static NTSTATUS svfs_flush(struct smbsrv_request *req, struct smb_flush *io)
*/
static NTSTATUS svfs_close(struct smbsrv_request *req, union smb_close *io)
{
- struct svfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(svfs_private, private, req);
struct svfs_file *f;
if (io->generic.level != RAW_CLOSE_CLOSE) {
@@ -660,11 +661,11 @@ static NTSTATUS svfs_setfileinfo(struct smbsrv_request *req,
*/
static NTSTATUS svfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs)
{
- struct svfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(svfs_private, private, req);
struct stat st;
if (fs->generic.level != RAW_QFS_GENERIC) {
- return ntvfs_map_fsinfo(req, fs);
+ return ntvfs_map_fsinfo(req, fs, private->ops);
}
if (sys_fsusage(private->connectpath,
@@ -702,7 +703,7 @@ static NTSTATUS svfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs)
static NTSTATUS svfs_fsattr(struct smbsrv_request *req, union smb_fsattr *fs)
{
struct stat st;
- struct svfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(svfs_private, private, req);
if (fs->generic.level != RAW_FSATTR_GENERIC) {
return ntvfs_map_fsattr(req, fs);
@@ -744,7 +745,7 @@ static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_f
{
struct svfs_dir *dir;
int i;
- struct svfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(svfs_private, private, req);
struct search_state *search;
union smb_search_data file;
uint_t max_count;
@@ -813,7 +814,7 @@ static NTSTATUS svfs_search_next(struct smbsrv_request *req, union smb_search_ne
{
struct svfs_dir *dir;
int i;
- struct svfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(svfs_private, private, req);
struct search_state *search;
union smb_search_data file;
uint_t max_count;
@@ -896,7 +897,7 @@ found:
/* close a search */
static NTSTATUS svfs_search_close(struct smbsrv_request *req, union smb_search_close *io)
{
- struct svfs_private *private = req->tcon->ntvfs_private;
+ NTVFS_GET_PRIVATE(svfs_private, private, req);
struct search_state *search;
for (search=private->search; search; search = search->next) {
@@ -931,9 +932,6 @@ NTSTATUS ntvfs_simple_init(void)
ZERO_STRUCT(ops);
- /* fill in the name and type */
- ops.type = NTVFS_DISK;
-
/* fill in all the operations */
ops.connect = svfs_connect;
ops.disconnect = svfs_disconnect;
@@ -966,6 +964,8 @@ NTSTATUS ntvfs_simple_init(void)
/* register ourselves with the NTVFS subsystem. We register
under names 'simple'
*/
+
+ ops.type = NTVFS_DISK;
ops.name = "simple";
ret = register_backend("ntvfs", &ops);
diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c
index 2a361b5432..8448cdeb04 100644
--- a/source4/param/loadparm.c
+++ b/source4/param/loadparm.c
@@ -246,7 +246,7 @@ typedef struct
char *volume;
char *fstype;
char *szMSDfsProxy;
- char *ntvfs_handler;
+ char **ntvfs_handler;
int iMinPrintSpace;
int iMaxPrintJobs;
int iMaxConnections;
@@ -516,7 +516,7 @@ static struct parm_struct parm_table[] = {
{"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
{"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
{"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"ntvfs handler", P_STRING, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
+ {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
{"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
{"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
@@ -1231,7 +1231,7 @@ FN_LOCAL_STRING(lp_comment, comment)
FN_LOCAL_STRING(lp_fstype, fstype)
FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
static FN_LOCAL_STRING(lp_volume, volume)
-FN_LOCAL_STRING(lp_ntvfs_handler, ntvfs_handler)
+FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
FN_LOCAL_BOOL(lp_browseable, bBrowseable)
diff --git a/source4/smb_server/service.c b/source4/smb_server/service.c
index 275e625386..bc436172a1 100644
--- a/source4/smb_server/service.c
+++ b/source4/smb_server/service.c
@@ -182,7 +182,7 @@ static NTSTATUS make_connection_snum(struct smbsrv_request *req,
/* Invoke NTVFS connection hook */
if (tcon->ntvfs_ops->connect) {
- status = tcon->ntvfs_ops->connect(req, lp_servicename(snum));
+ status = tcon->ntvfs_ops->connect(req, lp_servicename(snum), 0);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("make_connection: NTVFS make connection failed!\n"));
conn_free(req->smb_conn, tcon);
@@ -252,7 +252,7 @@ void close_cnum(struct smbsrv_tcon *tcon)
lp_servicename(SNUM(tcon))));
/* tell the ntvfs backend that we are disconnecting */
- tcon->ntvfs_ops->disconnect(tcon);
+ tcon->ntvfs_ops->disconnect(tcon, 0);
conn_free(tcon->smb_conn, tcon);
}
diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h
index 59fb03ea2e..b7f9e04385 100644
--- a/source4/smb_server/smb_server.h
+++ b/source4/smb_server/smb_server.h
@@ -62,8 +62,8 @@ struct smbsrv_tcon {
/* the server context that this was created on */
struct smbsrv_connection *smb_conn;
- /* a private structure used by the active NTVFS backend */
- void *ntvfs_private;
+ /* an array of private structures used by the active NTVFS backends */
+ void **ntvfs_private_list;
uint16_t cnum; /* an index passed over the wire (the TID) */
int service;
@@ -93,6 +93,9 @@ struct smbsrv_request {
/* the session context is derived from the vuid */
struct smbsrv_session *session;
+ /* the ntvfs chaining depth */
+ int ntvfs_depth;
+
/* a set of flags to control usage of the request. See REQ_CONTROL_* */
unsigned control_flags;