summaryrefslogtreecommitdiff
path: root/source4/ntvfs
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs')
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c30
-rw-r--r--source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c30
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c30
-rw-r--r--source4/ntvfs/nbench/vfs_nbench.c5
-rw-r--r--source4/ntvfs/ntvfs.h2
-rw-r--r--source4/ntvfs/ntvfs_interface.c9
-rw-r--r--source4/ntvfs/posix/vfs_posix.c30
-rw-r--r--source4/ntvfs/print/vfs_print.c7
-rw-r--r--source4/ntvfs/simple/vfs_simple.c30
-rw-r--r--source4/ntvfs/smb2/vfs_smb2.c31
-rw-r--r--source4/ntvfs/unixuid/vfs_unixuid.c4
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;
}