diff options
Diffstat (limited to 'source4')
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; |