summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Disseldorp <ddiss@suse.de>2011-03-01 19:17:49 +0100
committerJeremy Allison <jra@samba.org>2011-03-02 01:16:30 +0100
commit016a8d214ab23883e9d50c46d3a8cc18f9454368 (patch)
tree6be73542e65e0e3cc72124dd1123e0aa68aa5eef
parent09b4acfd81669583a38352550dc61107c72a1d42 (diff)
downloadsamba-016a8d214ab23883e9d50c46d3a8cc18f9454368.tar.gz
samba-016a8d214ab23883e9d50c46d3a8cc18f9454368.tar.bz2
samba-016a8d214ab23883e9d50c46d3a8cc18f9454368.zip
s3-printing: vfs_connect prior to driver/dfs IO
samba3.posix_s3.rpc.spoolss.driver fails with the xattr_tdb vfs module loaded as a part of make test. The (now checked) create_directory() call in move_driver_to_download_area() fails, uncovering another bug in the printer driver upload code path. move_driver_to_download_area() creates a new conn_struct for manipulating files in [print$]. The VFS layer is plumbed through with the call to create_conn_struct(), however SMB_VFS_CONNECT() is never called. Many vfs modules expect state stored at connect time with SMB_VFS_HANDLE_SET_DATA() to be available on any IO operation and fail if this is not the case. This fix adds a call to SMB_VFS_CONNECT() in create_conn_struct() prior to IO. https://bugzilla.samba.org/show_bug.cgi?id=7976 Autobuild-User: Jeremy Allison <jra@samba.org> Autobuild-Date: Wed Mar 2 01:16:30 CET 2011 on sn-devel-104
-rw-r--r--source3/printing/nt_printing.c3
-rw-r--r--source3/rpc_server/srvsvc/srv_srvsvc_nt.c2
-rw-r--r--source3/smbd/msdfs.c34
3 files changed, 29 insertions, 10 deletions
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 3b805f4f55..d77320cf02 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -726,6 +726,7 @@ static uint32 get_correct_cversion(struct pipes_struct *p,
}
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
}
if (!NT_STATUS_IS_OK(*perr)) {
@@ -1130,6 +1131,7 @@ WERROR move_driver_to_download_area(struct pipes_struct *p,
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
}
@@ -1968,6 +1970,7 @@ bool delete_driver_files(const struct auth_serversupplied_info *session_info,
err_out:
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
}
return ret;
diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
index 31df4886bb..40687a0e4e 100644
--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
@@ -2231,6 +2231,7 @@ error_exit:
}
if (conn) {
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
}
@@ -2374,6 +2375,7 @@ error_exit:
}
if (conn) {
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
}
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 07b0933031..c11e66e3b8 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -212,7 +212,7 @@ static NTSTATUS parse_dfs_path(connection_struct *conn,
/********************************************************
Fake up a connection struct for the VFS layer.
- Note this CHANGES CWD !!!! JRA.
+ Note: this performs a vfs connect and CHANGES CWD !!!! JRA.
*********************************************************/
NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
@@ -225,6 +225,7 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
connection_struct *conn;
char *connpath;
char *oldcwd;
+ const char *vfs_user;
conn = TALLOC_ZERO_P(ctx, connection_struct);
if (conn == NULL) {
@@ -265,6 +266,10 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
TALLOC_FREE(conn);
return NT_STATUS_NO_MEMORY;
}
+ vfs_user = conn->session_info->unix_name;
+ } else {
+ /* use current authenticated user in absence of session_info */
+ vfs_user = get_current_username();
}
set_conn_connectpath(conn, connpath);
@@ -276,6 +281,13 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
return status;
}
+ /* this must be the first filesystem operation that we do */
+ if (SMB_VFS_CONNECT(conn, lp_servicename(snum), vfs_user) < 0) {
+ DEBUG(0,("VFS connect failed!\n"));
+ conn_free(conn);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
/*
@@ -937,10 +949,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
if (!NT_STATUS_EQUAL(status, NT_STATUS_PATH_NOT_COVERED)) {
DEBUG(3,("get_referred_path: No valid referrals for path %s\n",
dfs_path));
- vfs_ChDir(conn, oldpath);
- conn_free(conn);
- TALLOC_FREE(pdp);
- return status;
+ goto err_exit;
}
/* We know this is a valid dfs link. Parse the targetpath. */
@@ -949,16 +958,17 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
&jucn->referral_count)) {
DEBUG(3,("get_referred_path: failed to parse symlink "
"target %s\n", targetpath ));
- vfs_ChDir(conn, oldpath);
- conn_free(conn);
- TALLOC_FREE(pdp);
- return NT_STATUS_NOT_FOUND;
+ status = NT_STATUS_NOT_FOUND;
+ goto err_exit;
}
+ status = NT_STATUS_OK;
+ err_exit:
vfs_ChDir(conn, oldpath);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
TALLOC_FREE(pdp);
- return NT_STATUS_OK;
+ return status;
}
static int setup_ver2_dfs_referral(const char *pathname,
@@ -1373,6 +1383,7 @@ static bool junction_to_local_path(const struct junction_map *jucn,
jucn->volume_name);
if (!*pp_path_out) {
vfs_ChDir(*conn_out, *oldpath);
+ SMB_VFS_DISCONNECT(*conn_out);
conn_free(*conn_out);
return False;
}
@@ -1461,6 +1472,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
out:
vfs_ChDir(conn, cwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
return ret;
}
@@ -1492,6 +1504,7 @@ bool remove_msdfs_link(const struct junction_map *jucn)
TALLOC_FREE(smb_fname);
vfs_ChDir(conn, cwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
return ret;
}
@@ -1556,6 +1569,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
out:
vfs_ChDir(conn, cwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
return cnt;
}