1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-05 20:58:40 +03:00

r2561: completely redid the ntvfs module chaining code, You can now do something like:

ntvfs handler = nbench posix

and the nbench pass-thru module will be called before the posix
module. The chaining logic is now much saner, and less racy, with each
level in the chain getting its own private pointer rather than relying
on save/restore logic in the pass-thru module.

The only pass-thru module we have at the moment is the nbench one
(which records all traffic in a nbench compatibe format), but I plan
on soon writing a "unixuid" pass-thru module that will implement the
setegid()/setgroups()/seteuid() logic for standard posix uid
handling. This separation of the posix backend from the uid handling
should simplify the code, and make development easier.

I also modified the nbench module so it can do multiple chaining, so
if you want to you can do:

   ntvfs module = nbench nbench posix

and it will save 2 copies of the log file in /tmp. This is really only
useful for testing at the moment until we have more than one pass-thru
module.
This commit is contained in:
Andrew Tridgell 2004-09-23 07:44:42 +00:00 committed by Gerald (Jerry) Carter
parent 3170f6ed84
commit f84c0af35c
25 changed files with 192 additions and 184 deletions

View File

@ -32,7 +32,7 @@ struct cvfs_private {
struct smbcli_tree *tree; struct smbcli_tree *tree;
struct smbcli_transport *transport; struct smbcli_transport *transport;
struct smbsrv_tcon *tcon; 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. 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; struct smbsrv_tcon *tcon = req->tcon;
NTSTATUS status; NTSTATUS status;
struct cvfs_private *private; struct cvfs_private *private;
const char *map_calls;
const char *host, *user, *pass, *domain, *remote_share; const char *host, *user, *pass, *domain, *remote_share;
/* Here we need to determine which server to connect to. /* 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); ZERO_STRUCTP(private);
req->tcon->ntvfs_private = (void *)private; ntvfs_set_private(req->tcon, depth, private);
status = smbcli_tree_full_connection(&private->tree, status = smbcli_tree_full_connection(&private->tree,
"vfs_cifs", "vfs_cifs",
@ -137,27 +136,11 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename)
private->transport = private->tree->session->transport; private->transport = private->tree->session->transport;
private->tree->session->pid = SVAL(req->in.hdr, HDR_PID); private->tree->session->pid = SVAL(req->in.hdr, HDR_PID);
private->tcon = req->tcon; private->tcon = req->tcon;
private->ops = ntvfs_backend_byname("cifs", NTVFS_DISK);
tcon->fs_type = talloc_strdup(tcon, "NTFS"); tcon->fs_type = talloc_strdup(tcon, "NTFS");
tcon->dev_type = talloc_strdup(tcon, "A:"); 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 */ /* we need to receive oplock break requests from the server */
smbcli_oplock_handler(private->transport, oplock_handler, private); smbcli_oplock_handler(private->transport, oplock_handler, private);
smbcli_transport_idle_handler(private->transport, idle_func, 1, 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 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); smb_tree_disconnect(private->tree);
smbcli_tree_close(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) 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; struct smbcli_request *c_req;
/* see if the front end will allow us to perform this /* 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) 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; struct smbcli_request *c_req;
/* see if the front end will allow us to perform this /* 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; 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) { if (!req->async.send_fn) {
return smb_raw_open(private->tree, req, io); 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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, static NTSTATUS cvfs_setfileinfo(struct smbsrv_request *req,
union smb_setfileinfo *info) union smb_setfileinfo *info)
{ {
struct cvfs_private *private = req->tcon->ntvfs_private; NTVFS_GET_PRIVATE(cvfs_private, private, req);
struct smbcli_request *c_req; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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) 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; struct smbcli_request *c_req;
if (!req->async.send_fn) { 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, void *search_private,
BOOL (*callback)(void *, union smb_search_data *)) 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); 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, void *search_private,
BOOL (*callback)(void *, union smb_search_data *)) 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); 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 */ /* close a search */
static NTSTATUS cvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) 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); return smb_raw_search_close(private->tree, io);
} }
@ -660,7 +638,7 @@ static void async_trans2(struct smbcli_request *c_req)
/* raw trans2 */ /* raw trans2 */
static NTSTATUS cvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *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; struct smbcli_request *c_req;
if (!req->async.send_fn) { if (!req->async.send_fn) {
@ -722,8 +700,9 @@ NTSTATUS ntvfs_cifs_init(void)
ops.search_close = cvfs_search_close; ops.search_close = cvfs_search_close;
ops.trans = cvfs_trans; ops.trans = cvfs_trans;
/* only define this one for trans2 testing */ if (lp_parm_bool(-1, "cifs", "maptrans2", False)) {
ops.trans2 = NULL; ops.trans2 = cvfs_trans2;
}
/* register ourselves with the NTVFS subsystem. We register /* register ourselves with the NTVFS subsystem. We register
under the name 'cifs'. */ under the name 'cifs'. */

View File

@ -105,7 +105,7 @@ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t
/* /*
connect to a share - always works 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 smbsrv_tcon *tcon = req->tcon;
struct ipc_private *private; struct ipc_private *private;
@ -118,7 +118,7 @@ static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename)
if (!private) { if (!private) {
return NT_STATUS_NO_MEMORY; return NT_STATUS_NO_MEMORY;
} }
tcon->ntvfs_private = (void *)private; ntvfs_set_private(tcon, depth, private);
private->pipe_list = NULL; private->pipe_list = NULL;
private->next_fnum = 1; private->next_fnum = 1;
@ -130,9 +130,9 @@ static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename)
/* /*
disconnect from a share 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 */ /* close any pipes that are open. Discard any unread data */
while (private->pipe_list) { while (private->pipe_list) {
@ -196,7 +196,7 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname,
NTSTATUS status; NTSTATUS status;
struct dcesrv_ep_description ep_description; struct dcesrv_ep_description ep_description;
struct auth_session_info *session_info = NULL; 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); mem_ctx = talloc_init("ipc_open '%s'", fname);
if (!mem_ctx) { 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) 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; DATA_BLOB data;
uint16_t fnum; uint16_t fnum;
struct pipe_state *p; 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) 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; DATA_BLOB data;
uint16_t fnum; uint16_t fnum;
struct pipe_state *p; 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) 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; struct pipe_state *p;
if (io->generic.level != RAW_CLOSE_CLOSE) { 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) static NTSTATUS ipc_dcerpc_cmd(struct smbsrv_request *req, struct smb_trans2 *trans)
{ {
struct pipe_state *p; struct pipe_state *p;
struct ipc_private *private = req->tcon->ntvfs_private; NTVFS_GET_PRIVATE(ipc_private, private, req);
NTSTATUS status; NTSTATUS status;
/* the fnum is in setup[1] */ /* 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 */ /* SMBtrans - set named pipe state */
static NTSTATUS ipc_set_nm_pipe_state(struct smbsrv_request *req, struct smb_trans2 *trans) 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 pipe_state *p;
struct ipc_private *private = req->tcon->ntvfs_private;
/* the fnum is in setup[1] */ /* the fnum is in setup[1] */
p = pipe_state_find(private, trans->in.setup[1]); p = pipe_state_find(private, trans->in.setup[1]);

View File

@ -29,8 +29,6 @@
/* this is stored in ntvfs_private */ /* this is stored in ntvfs_private */
struct nbench_private { struct nbench_private {
const struct ntvfs_ops *passthru_ops; const struct ntvfs_ops *passthru_ops;
void *passthru_private;
const struct ntvfs_ops *nbench_ops;
int log_fd; 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 this is used to call the next module in the ntvfs chain
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
*/ */
#define PASS_THRU(tcon, op, args) do { \ #define PASS_THRU(tcon, op, args) private->passthru_ops->op args;
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)
/* /*
this pass through macro operates on request contexts, and disables 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 { \ #define PASS_THRU_REQ(req, op, args) do { \
void *send_fn_saved = req->async.send_fn; \ void *send_fn_saved = req->async.send_fn; \
req->async.send_fn = NULL; \ 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; \ req->async.send_fn = send_fn_saved; \
} while (0) } 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. 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; struct nbench_private *private;
const char *passthru; const char *passthru;
NTSTATUS status; NTSTATUS status;
char *logname = NULL; char *logname = NULL;
const char **handlers = lp_ntvfs_handler(req->tcon->service);
private = talloc_p(req->tcon, struct nbench_private); private = talloc_p(req->tcon, struct nbench_private);
if (!private) { if (!private) {
return NT_STATUS_NO_MEMORY; 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); private->log_fd = open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644);
free(logname); free(logname);
@ -114,18 +101,16 @@ static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename
return NT_STATUS_UNSUCCESSFUL; return NT_STATUS_UNSUCCESSFUL;
} }
passthru = lp_parm_string(req->tcon->service, "nbench", "passthru"); private->passthru_ops = ntvfs_backend_byname(handlers[depth+1], NTVFS_DISK);
private->passthru_private = NULL;
private->nbench_ops = req->tcon->ntvfs_ops;
private->passthru_ops = ntvfs_backend_byname(passthru, NTVFS_DISK);
if (!private->passthru_ops) { if (!private->passthru_ops) {
DEBUG(0,("Unable to connect to '%s' pass through backend\n", passthru)); DEBUG(0,("Unable to connect to '%s' pass through backend\n", passthru));
return NT_STATUS_UNSUCCESSFUL; 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; return status;
} }
@ -133,15 +118,15 @@ static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename
/* /*
disconnect from a share 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; NTSTATUS status;
PASS_THRU(tcon, disconnect, (tcon));
close(private->log_fd); close(private->log_fd);
PASS_THRU(tcon, disconnect, (tcon, depth+1));
return status; 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, unlink, (req, unl)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, ioctl, (req, io)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, chkpath, (req, cp)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, qpathinfo, (req, info)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, qfileinfo, (req, info)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, setpathinfo, (req, st)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, open, (req, io)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, mkdir, (req, md)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, rmdir, (req, rd)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, rename, (req, ren)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, copy, (req, cp)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, read, (req, rd)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, write, (req, wr)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, seek, (req, io)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, flush, (req, io)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, close, (req, io)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, exit, (req)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, lock, (req, lck)); 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, static NTSTATUS nbench_setfileinfo(struct smbsrv_request *req,
union smb_setfileinfo *info) union smb_setfileinfo *info)
{ {
struct nbench_private *private = req->tcon->ntvfs_private; NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status; NTSTATUS status;
PASS_THRU_REQ(req, setfileinfo, (req, info)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, fsinfo, (req, fs)); 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) 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; NTSTATUS status;
PASS_THRU_REQ(req, lpq, (req, lpq)); 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, void *search_private,
BOOL (*callback)(void *, union smb_search_data *)) BOOL (*callback)(void *, union smb_search_data *))
{ {
struct nbench_private *private = req->tcon->ntvfs_private; NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status; NTSTATUS status;
PASS_THRU_REQ(req, search_first, (req, io, search_private, callback)); 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, void *search_private,
BOOL (*callback)(void *, union smb_search_data *)) BOOL (*callback)(void *, union smb_search_data *))
{ {
struct nbench_private *private = req->tcon->ntvfs_private; NTVFS_GET_PRIVATE(nbench_private, private, req);
NTSTATUS status; NTSTATUS status;
PASS_THRU_REQ(req, search_next, (req, io, search_private, callback)); 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 */ /* close a search */
static NTSTATUS nbench_search_close(struct smbsrv_request *req, union smb_search_close *io) 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; NTSTATUS status;
PASS_THRU_REQ(req, search_close, (req, io)); 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 */ /* SMBtrans - not used on file shares */
static NTSTATUS nbench_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) 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; NTSTATUS status;
PASS_THRU_REQ(req, trans, (req,trans2)); PASS_THRU_REQ(req, trans, (req,trans2));

View File

@ -30,8 +30,8 @@ struct ntvfs_ops {
enum ntvfs_type type; enum ntvfs_type type;
/* initial setup */ /* initial setup */
NTSTATUS (*connect)(struct smbsrv_request *req, const char *sharename); NTSTATUS (*connect)(struct smbsrv_request *req, const char *sharename, int depth);
NTSTATUS (*disconnect)(struct smbsrv_tcon *tcon); NTSTATUS (*disconnect)(struct smbsrv_tcon *tcon, int depth);
/* path operations */ /* path operations */
NTSTATUS (*unlink)(struct smbsrv_request *req, struct smb_unlink *unl); 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_tcon;
int sizeof_smbsrv_request; 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]

View File

@ -135,14 +135,29 @@ BOOL ntvfs_init(void)
*/ */
NTSTATUS ntvfs_init_connection(struct smbsrv_request *req) 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) { 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_UNSUCCESSFUL;
} }
return NT_STATUS_OK; 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;
}

View File

@ -57,7 +57,8 @@ static BOOL is_exe_file(const char *fname)
/* /*
NTVFS open generic to any mapper 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; NTSTATUS status;
union smb_open io2; 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.file_attr = io->openx.in.file_attrs;
io2.generic.in.fname = io->openx.in.fname; 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)) { if (!NT_STATUS_IS_OK(status)) {
return 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", 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)); 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)) { if (!NT_STATUS_IS_OK(status)) {
return 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 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; NTSTATUS status;
union smb_fsinfo fs2; 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 */ /* ask the backend for the generic info */
fs2.generic.level = RAW_QFS_GENERIC; 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)) { if (!NT_STATUS_IS_OK(status)) {
return 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 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; NTSTATUS status;
union smb_fileinfo info2; 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.level = RAW_FILEINFO_GENERIC;
info2.generic.in.fnum = info->generic.in.fnum; 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)) { if (!NT_STATUS_IS_OK(status)) {
return 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 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; NTSTATUS status;
union smb_fileinfo info2; 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.level = RAW_FILEINFO_GENERIC;
info2.generic.in.fname = info->generic.in.fname; 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)) { if (!NT_STATUS_IS_OK(status)) {
return status; return status;
} }

View File

@ -29,11 +29,11 @@
*/ */
NTSTATUS pvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) 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; struct stat st;
if (fs->generic.level != RAW_QFS_GENERIC) { 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, if (sys_fsusage(pvfs->base_directory,

View File

@ -28,7 +28,7 @@
*/ */
NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) 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; NTSTATUS status;
struct pvfs_filename *name; 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) 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; NTSTATUS status;
struct pvfs_filename *name; struct pvfs_filename *name;

View File

@ -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) 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; int fd, flags;
struct pvfs_filename *name; struct pvfs_filename *name;
struct pvfs_file *f; struct pvfs_file *f;
NTSTATUS status; NTSTATUS status;
if (io->generic.level != RAW_OPEN_GENERIC) { 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 */ /* 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) 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; struct pvfs_file *f;
if (io->generic.level != RAW_CLOSE_CLOSE) { if (io->generic.level != RAW_CLOSE_CLOSE) {

View File

@ -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) 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; struct pvfs_filename *name;
NTSTATUS status; NTSTATUS status;
if (info->generic.level != RAW_FILEINFO_GENERIC) { 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 */ /* 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) 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; struct pvfs_file *f;
NTSTATUS status; NTSTATUS status;
if (info->generic.level != RAW_FILEINFO_GENERIC) { 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); f = pvfs_find_fd(pvfs, info->generic.in.fnum);

View File

@ -28,7 +28,7 @@
*/ */
NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd) 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; ssize_t ret;
struct pvfs_file *f; struct pvfs_file *f;

View File

@ -28,7 +28,7 @@
*/ */
NTSTATUS pvfs_rename(struct smbsrv_request *req, union smb_rename *ren) 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; NTSTATUS status;
struct pvfs_filename *name1, *name2; struct pvfs_filename *name1, *name2;

View File

@ -164,10 +164,18 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
name->stream_name = NULL; name->stream_name = NULL;
name->has_wildcard = False; name->has_wildcard = False;
if (*cifs_name == '\\') { while (*cifs_name == '\\') {
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); ret = talloc_asprintf(name, "%s/%s", pvfs->base_directory, cifs_name);
if (ret == NULL) { if (ret == NULL) {
return NT_STATUS_NO_MEMORY; 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; 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 /* now do an in-place conversion of '\' to '/', checking
for legal characters */ for legal characters */
for (;*p;p++) { for (;*p;p++) {

View File

@ -255,7 +255,7 @@ static NTSTATUS pvfs_search_first_old(struct smbsrv_request *req, union smb_sear
BOOL (*callback)(void *, union smb_search_data *)) BOOL (*callback)(void *, union smb_search_data *))
{ {
struct pvfs_dir *dir; struct pvfs_dir *dir;
struct pvfs_state *pvfs = req->tcon->ntvfs_private; NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_search_state *search; struct pvfs_search_state *search;
uint_t reply_count; uint_t reply_count;
uint16_t search_attrib; uint16_t search_attrib;
@ -331,7 +331,7 @@ static NTSTATUS pvfs_search_next_old(struct smbsrv_request *req, union smb_searc
void *search_private, void *search_private,
BOOL (*callback)(void *, union smb_search_data *)) 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_search_state *search;
struct pvfs_dir *dir; struct pvfs_dir *dir;
uint_t reply_count, max_count; 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 *)) BOOL (*callback)(void *, union smb_search_data *))
{ {
struct pvfs_dir *dir; struct pvfs_dir *dir;
struct pvfs_state *pvfs = req->tcon->ntvfs_private; NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
struct pvfs_search_state *search; struct pvfs_search_state *search;
uint_t reply_count; uint_t reply_count;
uint16_t search_attrib, max_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, void *search_private,
BOOL (*callback)(void *, union smb_search_data *)) 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_search_state *search;
struct pvfs_dir *dir; struct pvfs_dir *dir;
uint_t reply_count; uint_t reply_count;
@ -547,7 +547,7 @@ found:
/* close a search */ /* close a search */
NTSTATUS pvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) 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; struct pvfs_search_state *search;
uint16_t handle; uint16_t handle;

View File

@ -29,7 +29,7 @@
NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req, NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req,
union smb_setfileinfo *info) union smb_setfileinfo *info)
{ {
struct pvfs_private *pvfs = req->tcon->ntvfs_private; NTVFS_GET_PRIVATE(pvfs_private, pvfs, req);
struct utimbuf unix_times; struct utimbuf unix_times;
struct pvfs_file *f; struct pvfs_file *f;

View File

@ -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) 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; struct pvfs_dir *dir;
NTSTATUS status; NTSTATUS status;
uint32_t i, total_deleted=0; uint32_t i, total_deleted=0;

View File

@ -29,7 +29,7 @@
*/ */
NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr) 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; ssize_t ret;
struct pvfs_file *f; struct pvfs_file *f;

View File

@ -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, directory exists (tho it doesn't need to be accessible by the user,
that comes later) 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 smbsrv_tcon *tcon = req->tcon;
struct pvfs_state *pvfs; struct pvfs_state *pvfs;
@ -71,6 +71,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename)
pvfs->tcon = tcon; pvfs->tcon = tcon;
pvfs->base_directory = base_directory; pvfs->base_directory = base_directory;
pvfs->ops = ntvfs_backend_byname("posix", NTVFS_DISK);
/* the directory must exist. Note that we deliberately don't /* the directory must exist. Note that we deliberately don't
check that it is readable */ 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->fs_type = talloc_strdup(tcon, "NTFS");
tcon->dev_type = talloc_strdup(tcon, "A:"); tcon->dev_type = talloc_strdup(tcon, "A:");
tcon->ntvfs_private = pvfs;
ntvfs_set_private(tcon, depth, pvfs);
pvfs_setup_options(pvfs); pvfs_setup_options(pvfs);
@ -92,7 +94,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename)
/* /*
disconnect from a share 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; 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) 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; struct pvfs_filename *name;
NTSTATUS status; NTSTATUS status;

View File

@ -49,6 +49,8 @@ struct pvfs_state {
} search; } search;
struct pvfs_file *open_files; struct pvfs_file *open_files;
const struct ntvfs_ops *ops;
}; };

View File

@ -10,6 +10,8 @@ struct svfs_private {
uint16_t next_search_handle; uint16_t next_search_handle;
struct svfs_file *open_files; struct svfs_file *open_files;
const struct ntvfs_ops *ops;
}; };
struct svfs_dir { struct svfs_dir {

View File

@ -31,7 +31,7 @@
*/ */
char *svfs_unix_path(struct smbsrv_request *req, const char *name) 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; char *ret;
if (*name != '\\') { if (*name != '\\') {

View File

@ -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, directory exists (tho it doesn't need to be accessible by the user,
that comes later) 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 stat st;
struct smbsrv_tcon *tcon = req->tcon; struct smbsrv_tcon *tcon = req->tcon;
struct svfs_private *private; struct svfs_private *private;
tcon->ntvfs_private = talloc_p(tcon, struct svfs_private); private = talloc_p(tcon, struct svfs_private);
private = tcon->ntvfs_private;
private->next_search_handle = 0; private->next_search_handle = 0;
private->connectpath = talloc_strdup(tcon, lp_pathname(tcon->service)); 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->fs_type = talloc_strdup(tcon, "NTFS");
tcon->dev_type = talloc_strdup(tcon, "A:"); 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)); DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename));
return NT_STATUS_OK; return NT_STATUS_OK;
@ -93,7 +93,7 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename)
/* /*
disconnect from a share 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; 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) static NTSTATUS svfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info)
{ {
NTVFS_GET_PRIVATE(svfs_private, private, req);
char *unix_path; char *unix_path;
struct stat st; struct stat st;
DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.fname, info->generic.level)); DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.fname, info->generic.level));
if (info->generic.level != RAW_FILEINFO_GENERIC) { 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); 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) 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 svfs_file *f;
struct stat st; struct stat st;
if (info->generic.level != RAW_FILEINFO_GENERIC) { 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); 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) 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; char *unix_path;
struct stat st; struct stat st;
int fd, flags; int fd, flags;
@ -303,7 +304,7 @@ static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io)
int create_flags, rdwr_flags; int create_flags, rdwr_flags;
if (io->generic.level != RAW_OPEN_GENERIC) { 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)) { 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) 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; struct svfs_file *f;
if (io->generic.level != RAW_CLOSE_CLOSE) { 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) 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; struct stat st;
if (fs->generic.level != RAW_QFS_GENERIC) { 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, 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) static NTSTATUS svfs_fsattr(struct smbsrv_request *req, union smb_fsattr *fs)
{ {
struct stat st; 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) { if (fs->generic.level != RAW_FSATTR_GENERIC) {
return ntvfs_map_fsattr(req, fs); 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; struct svfs_dir *dir;
int i; int i;
struct svfs_private *private = req->tcon->ntvfs_private; NTVFS_GET_PRIVATE(svfs_private, private, req);
struct search_state *search; struct search_state *search;
union smb_search_data file; union smb_search_data file;
uint_t max_count; 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; struct svfs_dir *dir;
int i; int i;
struct svfs_private *private = req->tcon->ntvfs_private; NTVFS_GET_PRIVATE(svfs_private, private, req);
struct search_state *search; struct search_state *search;
union smb_search_data file; union smb_search_data file;
uint_t max_count; uint_t max_count;
@ -896,7 +897,7 @@ found:
/* close a search */ /* close a search */
static NTSTATUS svfs_search_close(struct smbsrv_request *req, union smb_search_close *io) 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; struct search_state *search;
for (search=private->search; search; search = search->next) { for (search=private->search; search; search = search->next) {
@ -931,9 +932,6 @@ NTSTATUS ntvfs_simple_init(void)
ZERO_STRUCT(ops); ZERO_STRUCT(ops);
/* fill in the name and type */
ops.type = NTVFS_DISK;
/* fill in all the operations */ /* fill in all the operations */
ops.connect = svfs_connect; ops.connect = svfs_connect;
ops.disconnect = svfs_disconnect; ops.disconnect = svfs_disconnect;
@ -966,6 +964,8 @@ NTSTATUS ntvfs_simple_init(void)
/* register ourselves with the NTVFS subsystem. We register /* register ourselves with the NTVFS subsystem. We register
under names 'simple' under names 'simple'
*/ */
ops.type = NTVFS_DISK;
ops.name = "simple"; ops.name = "simple";
ret = register_backend("ntvfs", &ops); ret = register_backend("ntvfs", &ops);

View File

@ -246,7 +246,7 @@ typedef struct
char *volume; char *volume;
char *fstype; char *fstype;
char *szMSDfsProxy; char *szMSDfsProxy;
char *ntvfs_handler; char **ntvfs_handler;
int iMinPrintSpace; int iMinPrintSpace;
int iMaxPrintJobs; int iMaxPrintJobs;
int iMaxConnections; 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}, {"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}, {"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}, {"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}, {"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}, {"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_fstype, fstype)
FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy) FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
static FN_LOCAL_STRING(lp_volume, volume) 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_msdfs_root, bMSDfsRoot)
FN_LOCAL_BOOL(lp_autoloaded, autoloaded) FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
FN_LOCAL_BOOL(lp_browseable, bBrowseable) FN_LOCAL_BOOL(lp_browseable, bBrowseable)

View File

@ -182,7 +182,7 @@ static NTSTATUS make_connection_snum(struct smbsrv_request *req,
/* Invoke NTVFS connection hook */ /* Invoke NTVFS connection hook */
if (tcon->ntvfs_ops->connect) { 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)) { if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("make_connection: NTVFS make connection failed!\n")); DEBUG(0,("make_connection: NTVFS make connection failed!\n"));
conn_free(req->smb_conn, tcon); conn_free(req->smb_conn, tcon);
@ -252,7 +252,7 @@ void close_cnum(struct smbsrv_tcon *tcon)
lp_servicename(SNUM(tcon)))); lp_servicename(SNUM(tcon))));
/* tell the ntvfs backend that we are disconnecting */ /* 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); conn_free(tcon->smb_conn, tcon);
} }

View File

@ -62,8 +62,8 @@ struct smbsrv_tcon {
/* the server context that this was created on */ /* the server context that this was created on */
struct smbsrv_connection *smb_conn; struct smbsrv_connection *smb_conn;
/* a private structure used by the active NTVFS backend */ /* an array of private structures used by the active NTVFS backends */
void *ntvfs_private; void **ntvfs_private_list;
uint16_t cnum; /* an index passed over the wire (the TID) */ uint16_t cnum; /* an index passed over the wire (the TID) */
int service; int service;
@ -93,6 +93,9 @@ struct smbsrv_request {
/* the session context is derived from the vuid */ /* the session context is derived from the vuid */
struct smbsrv_session *session; struct smbsrv_session *session;
/* the ntvfs chaining depth */
int ntvfs_depth;
/* a set of flags to control usage of the request. See REQ_CONTROL_* */ /* a set of flags to control usage of the request. See REQ_CONTROL_* */
unsigned control_flags; unsigned control_flags;