diff options
Diffstat (limited to 'source4/ntvfs')
-rw-r--r-- | source4/ntvfs/cifs/vfs_cifs.c | 30 | ||||
-rw-r--r-- | source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c | 30 | ||||
-rw-r--r-- | source4/ntvfs/ipc/vfs_ipc.c | 30 | ||||
-rw-r--r-- | source4/ntvfs/nbench/vfs_nbench.c | 5 | ||||
-rw-r--r-- | source4/ntvfs/ntvfs.h | 2 | ||||
-rw-r--r-- | source4/ntvfs/ntvfs_interface.c | 9 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.c | 30 | ||||
-rw-r--r-- | source4/ntvfs/print/vfs_print.c | 7 | ||||
-rw-r--r-- | source4/ntvfs/simple/vfs_simple.c | 30 | ||||
-rw-r--r-- | source4/ntvfs/smb2/vfs_smb2.c | 31 | ||||
-rw-r--r-- | source4/ntvfs/unixuid/vfs_unixuid.c | 4 |
11 files changed, 191 insertions, 17 deletions
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index be9096b01f..1cb6a46615 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -136,7 +136,8 @@ static bool oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin connect to a share - used when a tree_connect operation comes in. */ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) + struct ntvfs_request *req, + union smb_tcon *tcon) { NTSTATUS status; struct cvfs_private *p; @@ -147,6 +148,28 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, struct cli_credentials *credentials; bool machine_account; + const char* sharename; + + switch (tcon->generic.level) { + case RAW_TCON_TCON: + sharename = tcon->tcon.in.service; + break; + case RAW_TCON_TCONX: + sharename = tcon->tconx.in.path; + break; + case RAW_TCON_SMB2: + sharename = tcon->smb2.in.path; + break; + default: + return NT_STATUS_INVALID_LEVEL; + } + + if (strncmp(sharename, "\\\\", 2) == 0) { + char *p = strchr(sharename+2, '\\'); + if (p) { + sharename = p + 1; + } + } /* Here we need to determine which server to connect to. * For now we use parametric options, type cifs. @@ -242,6 +265,11 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + if (tcon->generic.level == RAW_TCON_TCONX) { + tcon->tconx.out.fs_type = ntvfs->ctx->fs_type; + tcon->tconx.out.dev_type = ntvfs->ctx->dev_type; + } + /* we need to receive oplock break requests from the server */ smbcli_oplock_handler(p->transport, oplock_handler, p); diff --git a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c index 02fe9f2264..7b7c17a9be 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c @@ -48,11 +48,34 @@ that comes later) */ static NTSTATUS cifspsx_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) + struct ntvfs_request *req, + union smb_tcon* tcon) { struct stat st; struct cifspsx_private *p; struct share_config *scfg = ntvfs->ctx->config; + const char *sharename; + + switch (tcon->generic.level) { + case RAW_TCON_TCON: + sharename = tcon->tcon.in.service; + break; + case RAW_TCON_TCONX: + sharename = tcon->tconx.in.path; + break; + case RAW_TCON_SMB2: + sharename = tcon->smb2.in.path; + break; + default: + return NT_STATUS_INVALID_LEVEL; + } + + if (strncmp(sharename, "\\\\", 2) == 0) { + char *p = strchr(sharename+2, '\\'); + if (p) { + sharename = p + 1; + } + } p = talloc(ntvfs, struct cifspsx_private); NT_STATUS_HAVE_NO_MEMORY(p); @@ -74,6 +97,11 @@ static NTSTATUS cifspsx_connect(struct ntvfs_module_context *ntvfs, ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + if (tcon->generic.level == RAW_TCON_TCONX) { + tcon->tconx.out.fs_type = ntvfs->ctx->fs_type; + tcon->tconx.out.dev_type = ntvfs->ctx->dev_type; + } + ntvfs->private_data = p; DEBUG(0,("WARNING: ntvfs cifs posix: connect to share [%s] with ROOT privileges!!!\n",sharename)); diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 2f05a86dfa..20b00f24e3 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -88,10 +88,33 @@ static struct pipe_state *pipe_state_find_key(struct ipc_private *ipriv, struct connect to a share - always works */ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) + struct ntvfs_request *req, + union smb_tcon* tcon) { NTSTATUS status; struct ipc_private *ipriv; + const char *sharename; + + switch (tcon->generic.level) { + case RAW_TCON_TCON: + sharename = tcon->tcon.in.service; + break; + case RAW_TCON_TCONX: + sharename = tcon->tconx.in.path; + break; + case RAW_TCON_SMB2: + sharename = tcon->smb2.in.path; + break; + default: + return NT_STATUS_INVALID_LEVEL; + } + + if (strncmp(sharename, "\\\\", 2) == 0) { + char *p = strchr(sharename+2, '\\'); + if (p) { + sharename = p + 1; + } + } ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "IPC"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); @@ -99,6 +122,11 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "IPC"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + if (tcon->generic.level == RAW_TCON_TCONX) { + tcon->tconx.out.fs_type = ntvfs->ctx->fs_type; + tcon->tconx.out.dev_type = ntvfs->ctx->dev_type; + } + /* prepare the private state for this connection */ ipriv = talloc(ntvfs, struct ipc_private); NT_STATUS_HAVE_NO_MEMORY(ipriv); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 7ba2e7c649..2500140762 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -111,7 +111,8 @@ static char *nbench_ntvfs_handle_string(struct ntvfs_request *req, struct ntvfs_ connect to a share - used when a tree_connect operation comes in. */ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) + struct ntvfs_request *req, + union smb_tcon* con) { struct nbench_private *nprivates; NTSTATUS status; @@ -133,7 +134,7 @@ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = nprivates; - status = ntvfs_next_connect(ntvfs, req, sharename); + status = ntvfs_next_connect(ntvfs, req, con); return status; } diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index b62595967f..5e9c657737 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -49,7 +49,7 @@ struct ntvfs_ops { /* initial setup */ NTSTATUS (*connect)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - const char *sharename); + union smb_tcon *tcon); NTSTATUS (*disconnect)(struct ntvfs_module_context *ntvfs); /* async_setup - called when a backend is processing a async request */ diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 6d3fe55c06..808bd97e61 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -22,13 +22,13 @@ #include "ntvfs/ntvfs.h" /* connect/disconnect */ -NTSTATUS ntvfs_connect(struct ntvfs_request *req, const char *sharename) +NTSTATUS ntvfs_connect(struct ntvfs_request *req, union smb_tcon *tcon) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->connect) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->connect(ntvfs, req, sharename); + return ntvfs->ops->connect(ntvfs, req, tcon); } NTSTATUS ntvfs_disconnect(struct ntvfs_context *ntvfs_ctx) @@ -335,12 +335,13 @@ NTSTATUS ntvfs_cancel(struct ntvfs_request *req) /* initial setup */ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) + struct ntvfs_request *req, + union smb_tcon *tcon) { if (!ntvfs->next || !ntvfs->next->ops->connect) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->connect(ntvfs->next, req, sharename); + return ntvfs->next->ops->connect(ntvfs->next, req, tcon); } NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs) diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 29ef701dee..5134c0a608 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -168,12 +168,35 @@ static int pvfs_state_destructor(struct pvfs_state *pvfs) that comes later) */ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) + struct ntvfs_request *req, + union smb_tcon* tcon) { struct pvfs_state *pvfs; struct stat st; char *base_directory; NTSTATUS status; + const char *sharename; + + switch (tcon->generic.level) { + case RAW_TCON_TCON: + sharename = tcon->tcon.in.service; + break; + case RAW_TCON_TCONX: + sharename = tcon->tconx.in.path; + break; + case RAW_TCON_SMB2: + sharename = tcon->smb2.in.path; + break; + default: + return NT_STATUS_INVALID_LEVEL; + } + + if (strncmp(sharename, "\\\\", 2) == 0) { + char *p = strchr(sharename+2, '\\'); + if (p) { + sharename = p + 1; + } + } /* * TODO: call this from ntvfs_posix_init() @@ -209,6 +232,11 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + if (tcon->generic.level == RAW_TCON_TCONX) { + tcon->tconx.out.fs_type = ntvfs->ctx->fs_type; + tcon->tconx.out.dev_type = ntvfs->ctx->dev_type; + } + ntvfs->private_data = pvfs; pvfs->brl_context = brl_init(pvfs, diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 540e51a43b..0530e04f6d 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -32,7 +32,7 @@ is available */ static NTSTATUS print_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) + struct ntvfs_request *req, union smb_tcon* tcon) { ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); @@ -40,6 +40,11 @@ static NTSTATUS print_connect(struct ntvfs_module_context *ntvfs, ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "LPT1:"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + if (tcon->generic.level == RAW_TCON_TCONX) { + tcon->tconx.out.fs_type = ntvfs->ctx->fs_type; + tcon->tconx.out.dev_type = ntvfs->ctx->dev_type; + } + return NT_STATUS_OK; } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index bf0afcec0a..aabaa3c47f 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -47,11 +47,34 @@ that comes later) */ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) + struct ntvfs_request *req, + union smb_tcon* tcon) { struct stat st; struct svfs_private *p; struct share_config *scfg = ntvfs->ctx->config; + const char *sharename; + + switch (tcon->generic.level) { + case RAW_TCON_TCON: + sharename = tcon->tcon.in.service; + break; + case RAW_TCON_TCONX: + sharename = tcon->tconx.in.path; + break; + case RAW_TCON_SMB2: + sharename = tcon->smb2.in.path; + break; + default: + return NT_STATUS_INVALID_LEVEL; + } + + if (strncmp(sharename, "\\\\", 2) == 0) { + char *p = strchr(sharename+2, '\\'); + if (p) { + sharename = p + 1; + } + } p = talloc(ntvfs, struct svfs_private); NT_STATUS_HAVE_NO_MEMORY(p); @@ -73,6 +96,11 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + if (tcon->generic.level == RAW_TCON_TCONX) { + tcon->tconx.out.fs_type = ntvfs->ctx->fs_type; + tcon->tconx.out.dev_type = ntvfs->ctx->dev_type; + } + ntvfs->private_data = p; return NT_STATUS_OK; diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index d1e194f638..6fc0d42b02 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -154,11 +154,12 @@ static NTSTATUS smb2_get_roothandle(struct smb2_tree *tree, struct smb2_handle * connect to a share - used when a tree_connect operation comes in. */ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) + struct ntvfs_request *req, + union smb_tcon* tcon) { NTSTATUS status; struct cvfs_private *p; - const char *host, *user, *pass, *domain, *remote_share; + const char *host, *user, *pass, *domain, *remote_share, *sharename; struct composite_context *creq; struct share_config *scfg = ntvfs->ctx->config; struct smb2_tree *tree; @@ -166,6 +167,27 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, bool machine_account; struct smbcli_options options; + switch (tcon->generic.level) { + case RAW_TCON_TCON: + sharename = tcon->tcon.in.service; + break; + case RAW_TCON_TCONX: + sharename = tcon->tconx.in.path; + break; + case RAW_TCON_SMB2: + sharename = tcon->smb2.in.path; + break; + default: + return NT_STATUS_INVALID_LEVEL; + } + + if (strncmp(sharename, "\\\\", 2) == 0) { + char *p = strchr(sharename+2, '\\'); + if (p) { + sharename = p + 1; + } + } + /* Here we need to determine which server to connect to. * For now we use parametric options, type cifs. * Later we will use security=server and auth_server.c. @@ -251,6 +273,11 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + if (tcon->generic.level == RAW_TCON_TCONX) { + tcon->tconx.out.fs_type = ntvfs->ctx->fs_type; + tcon->tconx.out.dev_type = ntvfs->ctx->dev_type; + } + /* we need to receive oplock break requests from the server */ /* TODO: enable oplocks smbcli_oplock_handler(p->transport, oplock_handler, p); diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 062fa41889..3ef341d61a 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -293,7 +293,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, connect to a share - used when a tree_connect operation comes in. */ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) + struct ntvfs_request *req, union smb_tcon *tcon) { struct unixuid_private *priv; NTSTATUS status; @@ -321,7 +321,7 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, /* we don't use PASS_THRU_REQ here, as the connect operation runs with root privileges. This allows the backends to setup any database links they might need during the connect. */ - status = ntvfs_next_connect(ntvfs, req, sharename); + status = ntvfs_next_connect(ntvfs, req, tcon); return status; } |