mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
s3: VFS: Change SMB_VFS_CHDIR to use const struct smb_filename * instead of const char *.
We need to migrate all pathname based VFS calls to use a struct to finish modernising the VFS with extra timestamp and flags parameters. Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Richard Sharpe <realrichardsharpe@gmail.com>
This commit is contained in:
parent
73bee8b690
commit
6acb0d6ca0
@ -412,7 +412,8 @@ static int skel_lchown(vfs_handle_struct *handle,
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int skel_chdir(vfs_handle_struct *handle, const char *path)
|
||||
static int skel_chdir(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
|
@ -515,9 +515,10 @@ static int skel_lchown(vfs_handle_struct *handle,
|
||||
return SMB_VFS_NEXT_LCHOWN(handle, smb_fname, uid, gid);
|
||||
}
|
||||
|
||||
static int skel_chdir(vfs_handle_struct *handle, const char *path)
|
||||
static int skel_chdir(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
return SMB_VFS_NEXT_CHDIR(handle, path);
|
||||
return SMB_VFS_NEXT_CHDIR(handle, smb_fname);
|
||||
}
|
||||
|
||||
static char *skel_getwd(vfs_handle_struct *handle)
|
||||
|
@ -228,6 +228,8 @@
|
||||
to const struct smb_filename * */
|
||||
/* Version 37 - Change symlink from const char *
|
||||
to const struct smb_filename * */
|
||||
/* Version 37 - Change chdir from const char *
|
||||
to const struct smb_filename * */
|
||||
|
||||
#define SMB_VFS_INTERFACE_VERSION 37
|
||||
|
||||
@ -731,7 +733,8 @@ struct vfs_fn_pointers {
|
||||
const struct smb_filename *smb_fname,
|
||||
uid_t uid,
|
||||
gid_t gid);
|
||||
int (*chdir_fn)(struct vfs_handle_struct *handle, const char *path);
|
||||
int (*chdir_fn)(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname);
|
||||
char *(*getwd_fn)(struct vfs_handle_struct *handle);
|
||||
int (*ntimes_fn)(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
@ -1232,7 +1235,8 @@ int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
uid_t uid,
|
||||
gid_t gid);
|
||||
int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path);
|
||||
int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname);
|
||||
char *smb_vfs_call_getwd(struct vfs_handle_struct *handle);
|
||||
int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname,
|
||||
|
@ -266,10 +266,10 @@
|
||||
#define SMB_VFS_NEXT_LCHOWN(handle, smb_fname, uid, gid) \
|
||||
smb_vfs_call_lchown((handle)->next, (smb_fname), (uid), (gid))
|
||||
|
||||
#define SMB_VFS_CHDIR(conn, path) \
|
||||
smb_vfs_call_chdir((conn)->vfs_handles, (path))
|
||||
#define SMB_VFS_NEXT_CHDIR(handle, path) \
|
||||
smb_vfs_call_chdir((handle)->next, (path))
|
||||
#define SMB_VFS_CHDIR(conn, smb_fname) \
|
||||
smb_vfs_call_chdir((conn)->vfs_handles, (smb_fname))
|
||||
#define SMB_VFS_NEXT_CHDIR(handle, smb_fname) \
|
||||
smb_vfs_call_chdir((handle)->next, (smb_fname))
|
||||
|
||||
#define SMB_VFS_GETWD(conn) \
|
||||
smb_vfs_call_getwd((conn)->vfs_handles)
|
||||
|
@ -1288,7 +1288,7 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp,
|
||||
}
|
||||
|
||||
static int acl_common_remove_object(vfs_handle_struct *handle,
|
||||
const char *path,
|
||||
const struct smb_filename *smb_fname,
|
||||
bool is_directory)
|
||||
{
|
||||
connection_struct *conn = handle->conn;
|
||||
@ -1297,17 +1297,20 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
|
||||
int ret = 0;
|
||||
char *parent_dir = NULL;
|
||||
const char *final_component = NULL;
|
||||
struct smb_filename local_fname;
|
||||
struct smb_filename local_fname = {0};
|
||||
struct smb_filename parent_dir_fname = {0};
|
||||
int saved_errno = 0;
|
||||
char *saved_dir = NULL;
|
||||
struct smb_filename saved_dir_fname = {0};
|
||||
|
||||
saved_dir = vfs_GetWd(talloc_tos(),conn);
|
||||
if (!saved_dir) {
|
||||
saved_errno = errno;
|
||||
goto out;
|
||||
}
|
||||
saved_dir_fname = (struct smb_filename) { .base_name = saved_dir };
|
||||
|
||||
if (!parent_dirname(talloc_tos(), path,
|
||||
if (!parent_dirname(talloc_tos(), smb_fname->base_name,
|
||||
&parent_dir, &final_component)) {
|
||||
saved_errno = ENOMEM;
|
||||
goto out;
|
||||
@ -1316,14 +1319,15 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
|
||||
DBG_DEBUG("removing %s %s/%s\n", is_directory ? "directory" : "file",
|
||||
parent_dir, final_component);
|
||||
|
||||
parent_dir_fname = (struct smb_filename) { .base_name = parent_dir };
|
||||
|
||||
/* cd into the parent dir to pin it. */
|
||||
ret = vfs_ChDir(conn, parent_dir);
|
||||
ret = vfs_ChDir(conn, &parent_dir_fname);
|
||||
if (ret == -1) {
|
||||
saved_errno = errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(local_fname);
|
||||
local_fname.base_name = discard_const_p(char, final_component);
|
||||
|
||||
/* Must use lstat here. */
|
||||
@ -1371,7 +1375,7 @@ static int acl_common_remove_object(vfs_handle_struct *handle,
|
||||
TALLOC_FREE(parent_dir);
|
||||
|
||||
if (saved_dir) {
|
||||
vfs_ChDir(conn, saved_dir);
|
||||
vfs_ChDir(conn, &saved_dir_fname);
|
||||
}
|
||||
if (saved_errno) {
|
||||
errno = saved_errno;
|
||||
@ -1393,7 +1397,7 @@ static int rmdir_acl_common(struct vfs_handle_struct *handle,
|
||||
/* Failed due to access denied,
|
||||
see if we need to root override. */
|
||||
return acl_common_remove_object(handle,
|
||||
smb_fname->base_name,
|
||||
smb_fname,
|
||||
true);
|
||||
}
|
||||
|
||||
@ -1422,7 +1426,7 @@ static int unlink_acl_common(struct vfs_handle_struct *handle,
|
||||
return -1;
|
||||
}
|
||||
return acl_common_remove_object(handle,
|
||||
smb_fname->base_name,
|
||||
smb_fname,
|
||||
false);
|
||||
}
|
||||
|
||||
|
@ -436,16 +436,40 @@ static int cap_lchown(vfs_handle_struct *handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cap_chdir(vfs_handle_struct *handle, const char *path)
|
||||
static int cap_chdir(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
char *cappath = capencode(talloc_tos(), path);
|
||||
struct smb_filename *cap_smb_fname = NULL;
|
||||
char *cappath = capencode(talloc_tos(), smb_fname->base_name);
|
||||
int ret;
|
||||
int saved_errno = 0;
|
||||
|
||||
if (!cappath) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
DEBUG(3,("cap: cap_chdir for %s\n", path));
|
||||
return SMB_VFS_NEXT_CHDIR(handle, cappath);
|
||||
DEBUG(3,("cap: cap_chdir for %s\n", smb_fname->base_name));
|
||||
|
||||
cap_smb_fname = synthetic_smb_fname(talloc_tos(),
|
||||
cappath,
|
||||
NULL,
|
||||
NULL,
|
||||
smb_fname->flags);
|
||||
if (cap_smb_fname == NULL) {
|
||||
TALLOC_FREE(cappath);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
ret = SMB_VFS_NEXT_CHDIR(handle, cap_smb_fname);
|
||||
if (ret == -1) {
|
||||
saved_errno = errno;
|
||||
}
|
||||
TALLOC_FREE(cappath);
|
||||
TALLOC_FREE(cap_smb_fname);
|
||||
if (saved_errno != 0) {
|
||||
errno = saved_errno;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cap_ntimes(vfs_handle_struct *handle,
|
||||
|
@ -991,21 +991,35 @@ static int catia_mkdir(vfs_handle_struct *handle,
|
||||
}
|
||||
|
||||
static int catia_chdir(vfs_handle_struct *handle,
|
||||
const char *path)
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
char *name = NULL;
|
||||
struct smb_filename *catia_smb_fname = NULL;
|
||||
NTSTATUS status;
|
||||
int ret;
|
||||
|
||||
status = catia_string_replace_allocate(handle->conn, path,
|
||||
&name, vfs_translate_to_unix);
|
||||
status = catia_string_replace_allocate(handle->conn,
|
||||
smb_fname->base_name,
|
||||
&name,
|
||||
vfs_translate_to_unix);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
errno = map_errno_from_nt_status(status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = SMB_VFS_NEXT_CHDIR(handle, name);
|
||||
catia_smb_fname = synthetic_smb_fname(talloc_tos(),
|
||||
name,
|
||||
NULL,
|
||||
NULL,
|
||||
smb_fname->flags);
|
||||
if (catia_smb_fname == NULL) {
|
||||
TALLOC_FREE(name);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
ret = SMB_VFS_NEXT_CHDIR(handle, catia_smb_fname);
|
||||
TALLOC_FREE(name);
|
||||
TALLOC_FREE(catia_smb_fname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -931,18 +931,20 @@ static int cephwrap_lchown(struct vfs_handle_struct *handle,
|
||||
WRAP_RETURN(result);
|
||||
}
|
||||
|
||||
static int cephwrap_chdir(struct vfs_handle_struct *handle, const char *path)
|
||||
static int cephwrap_chdir(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
int result = -1;
|
||||
DBG_DEBUG("[CEPH] chdir(%p, %s)\n", handle, path);
|
||||
DBG_DEBUG("[CEPH] chdir(%p, %s)\n", handle, smb_fname->base_name);
|
||||
/*
|
||||
* If the path is just / use chdir because Ceph is below / and
|
||||
* cannot deal with changing directory above its mount point
|
||||
*/
|
||||
if (path && !strcmp(path, "/"))
|
||||
return chdir(path);
|
||||
if (!strcmp(smb_fname->base_name, "/")) {
|
||||
return chdir(smb_fname->base_name);
|
||||
}
|
||||
|
||||
result = ceph_chdir(handle->data, path);
|
||||
result = ceph_chdir(handle->data, smb_fname->base_name);
|
||||
DBG_DEBUG("[CEPH] chdir(...) = %d\n", result);
|
||||
WRAP_RETURN(result);
|
||||
}
|
||||
|
@ -228,10 +228,18 @@ static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
|
||||
!handle->conn->sconn->using_smb2,
|
||||
junction, &consumedcnt, &self_referral);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
vfs_ChDir(handle->conn, handle->conn->connectpath);
|
||||
struct smb_filename connectpath_fname = {
|
||||
.base_name = handle->conn->connectpath
|
||||
};
|
||||
vfs_ChDir(handle->conn, &connectpath_fname);
|
||||
return status;
|
||||
}
|
||||
vfs_ChDir(handle->conn, handle->conn->connectpath);
|
||||
{
|
||||
struct smb_filename connectpath_fname = {
|
||||
.base_name = handle->conn->connectpath
|
||||
};
|
||||
vfs_ChDir(handle->conn, &connectpath_fname);
|
||||
}
|
||||
|
||||
if (!self_referral) {
|
||||
pathnamep[consumedcnt] = '\0';
|
||||
@ -2080,12 +2088,13 @@ static int vfswrap_lchown(vfs_handle_struct *handle,
|
||||
return result;
|
||||
}
|
||||
|
||||
static int vfswrap_chdir(vfs_handle_struct *handle, const char *path)
|
||||
static int vfswrap_chdir(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
int result;
|
||||
|
||||
START_PROFILE(syscall_chdir);
|
||||
result = chdir(path);
|
||||
result = chdir(smb_fname->base_name);
|
||||
END_PROFILE(syscall_chdir);
|
||||
return result;
|
||||
}
|
||||
|
@ -1509,13 +1509,14 @@ static int smb_full_audit_lchown(vfs_handle_struct *handle,
|
||||
}
|
||||
|
||||
static int smb_full_audit_chdir(vfs_handle_struct *handle,
|
||||
const char *path)
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = SMB_VFS_NEXT_CHDIR(handle, path);
|
||||
result = SMB_VFS_NEXT_CHDIR(handle, smb_fname);
|
||||
|
||||
do_log(SMB_VFS_OP_CHDIR, (result >= 0), handle, "chdir|%s", path);
|
||||
do_log(SMB_VFS_OP_CHDIR, (result >= 0), handle, "chdir|%s",
|
||||
smb_fname->base_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1070,9 +1070,10 @@ static int vfs_gluster_lchown(struct vfs_handle_struct *handle,
|
||||
return glfs_lchown(handle->data, smb_fname->base_name, uid, gid);
|
||||
}
|
||||
|
||||
static int vfs_gluster_chdir(struct vfs_handle_struct *handle, const char *path)
|
||||
static int vfs_gluster_chdir(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
return glfs_chdir(handle->data, path);
|
||||
return glfs_chdir(handle->data, smb_fname->base_name);
|
||||
}
|
||||
|
||||
static char *vfs_gluster_getwd(struct vfs_handle_struct *handle)
|
||||
|
@ -1648,32 +1648,28 @@ out:
|
||||
* Failure: set errno, return -1
|
||||
*/
|
||||
static int mh_chdir(vfs_handle_struct *handle,
|
||||
const char *path)
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
int status;
|
||||
char *clientPath;
|
||||
TALLOC_CTX *ctx;
|
||||
struct smb_filename *clientFname = NULL;
|
||||
|
||||
DEBUG(MH_INFO_DEBUG, ("Entering mh_chdir\n"));
|
||||
if (!is_in_media_files(path))
|
||||
{
|
||||
status = SMB_VFS_NEXT_CHDIR(handle, path);
|
||||
if (!is_in_media_files(smb_fname->base_name)) {
|
||||
status = SMB_VFS_NEXT_CHDIR(handle, smb_fname);
|
||||
goto out;
|
||||
}
|
||||
|
||||
clientPath = NULL;
|
||||
ctx = talloc_tos();
|
||||
|
||||
if ((status = alloc_get_client_path(handle, ctx,
|
||||
path,
|
||||
&clientPath)))
|
||||
{
|
||||
status = alloc_get_client_smb_fname(handle,
|
||||
talloc_tos(),
|
||||
smb_fname,
|
||||
&clientFname);
|
||||
if (status != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
status = SMB_VFS_NEXT_CHDIR(handle, clientPath);
|
||||
status = SMB_VFS_NEXT_CHDIR(handle, clientFname);
|
||||
err:
|
||||
TALLOC_FREE(clientPath);
|
||||
TALLOC_FREE(clientFname);
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
@ -1550,7 +1550,7 @@ static void store_cwd_data(vfs_handle_struct *handle,
|
||||
}
|
||||
|
||||
static int shadow_copy2_chdir(vfs_handle_struct *handle,
|
||||
const char *fname)
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
time_t timestamp = 0;
|
||||
char *stripped = NULL;
|
||||
@ -1559,9 +1559,14 @@ static int shadow_copy2_chdir(vfs_handle_struct *handle,
|
||||
int saved_errno = 0;
|
||||
char *conv = NULL;
|
||||
size_t rootpath_len = 0;
|
||||
struct smb_filename *conv_smb_fname = NULL;
|
||||
|
||||
if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, fname,
|
||||
×tamp, &stripped, &snappath)) {
|
||||
if (!shadow_copy2_strip_snapshot_internal(talloc_tos(),
|
||||
handle,
|
||||
smb_fname->base_name,
|
||||
×tamp,
|
||||
&stripped,
|
||||
&snappath)) {
|
||||
return -1;
|
||||
}
|
||||
if (stripped != NULL) {
|
||||
@ -1574,10 +1579,22 @@ static int shadow_copy2_chdir(vfs_handle_struct *handle,
|
||||
if (conv == NULL) {
|
||||
return -1;
|
||||
}
|
||||
fname = conv;
|
||||
conv_smb_fname = synthetic_smb_fname(talloc_tos(),
|
||||
conv,
|
||||
NULL,
|
||||
NULL,
|
||||
smb_fname->flags);
|
||||
} else {
|
||||
conv_smb_fname = cp_smb_filename(talloc_tos(), smb_fname);
|
||||
}
|
||||
|
||||
ret = SMB_VFS_NEXT_CHDIR(handle, fname);
|
||||
if (conv_smb_fname == NULL) {
|
||||
TALLOC_FREE(conv);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = SMB_VFS_NEXT_CHDIR(handle, conv_smb_fname);
|
||||
if (ret == -1) {
|
||||
saved_errno = errno;
|
||||
}
|
||||
@ -1594,6 +1611,7 @@ static int shadow_copy2_chdir(vfs_handle_struct *handle,
|
||||
|
||||
TALLOC_FREE(stripped);
|
||||
TALLOC_FREE(conv);
|
||||
TALLOC_FREE(conv_smb_fname);
|
||||
|
||||
if (saved_errno != 0) {
|
||||
errno = saved_errno;
|
||||
|
@ -2344,29 +2344,49 @@ static int snapper_gmt_chown(vfs_handle_struct *handle,
|
||||
}
|
||||
|
||||
static int snapper_gmt_chdir(vfs_handle_struct *handle,
|
||||
const char *fname)
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
time_t timestamp;
|
||||
char *stripped;
|
||||
int ret, saved_errno;
|
||||
char *conv;
|
||||
time_t timestamp = 0;
|
||||
char *stripped = NULL;
|
||||
int ret;
|
||||
int saved_errno = 0;
|
||||
char *conv = NULL;
|
||||
struct smb_filename *conv_smb_fname = NULL;
|
||||
|
||||
if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname,
|
||||
×tamp, &stripped)) {
|
||||
if (!snapper_gmt_strip_snapshot(talloc_tos(),
|
||||
handle,
|
||||
smb_fname->base_name,
|
||||
×tamp,
|
||||
&stripped)) {
|
||||
return -1;
|
||||
}
|
||||
if (timestamp == 0) {
|
||||
return SMB_VFS_NEXT_CHDIR(handle, fname);
|
||||
return SMB_VFS_NEXT_CHDIR(handle, smb_fname);
|
||||
}
|
||||
conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
|
||||
TALLOC_FREE(stripped);
|
||||
if (conv == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ret = SMB_VFS_NEXT_CHDIR(handle, conv);
|
||||
saved_errno = errno;
|
||||
conv_smb_fname = synthetic_smb_fname(talloc_tos(),
|
||||
conv,
|
||||
NULL,
|
||||
NULL,
|
||||
smb_fname->flags);
|
||||
if (conv_smb_fname == NULL) {
|
||||
TALLOC_FREE(conv);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
ret = SMB_VFS_NEXT_CHDIR(handle, conv_smb_fname);
|
||||
if (ret == -1) {
|
||||
saved_errno = errno;
|
||||
}
|
||||
TALLOC_FREE(conv);
|
||||
errno = saved_errno;
|
||||
TALLOC_FREE(conv_smb_fname);
|
||||
if (saved_errno != 0) {
|
||||
errno = saved_errno;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1236,19 +1236,22 @@ static int smb_time_audit_lchown(vfs_handle_struct *handle,
|
||||
return result;
|
||||
}
|
||||
|
||||
static int smb_time_audit_chdir(vfs_handle_struct *handle, const char *path)
|
||||
static int smb_time_audit_chdir(vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
int result;
|
||||
struct timespec ts1,ts2;
|
||||
double timediff;
|
||||
|
||||
clock_gettime_mono(&ts1);
|
||||
result = SMB_VFS_NEXT_CHDIR(handle, path);
|
||||
result = SMB_VFS_NEXT_CHDIR(handle, smb_fname);
|
||||
clock_gettime_mono(&ts2);
|
||||
timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
|
||||
|
||||
if (timediff > audit_timeout) {
|
||||
smb_time_audit_log_fname("chdir", timediff, path);
|
||||
smb_time_audit_log_fname("chdir",
|
||||
timediff,
|
||||
smb_fname->base_name);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1267,27 +1267,29 @@ err:
|
||||
}
|
||||
|
||||
static int um_chdir(vfs_handle_struct *handle,
|
||||
const char *path)
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
int status;
|
||||
char *client_path = NULL;
|
||||
struct smb_filename *client_fname = NULL;
|
||||
|
||||
DEBUG(10, ("Entering um_chdir\n"));
|
||||
|
||||
if (!is_in_media_files(path)) {
|
||||
return SMB_VFS_NEXT_CHDIR(handle, path);
|
||||
if (!is_in_media_files(smb_fname->base_name)) {
|
||||
return SMB_VFS_NEXT_CHDIR(handle, smb_fname);
|
||||
}
|
||||
|
||||
status = alloc_get_client_path(handle, talloc_tos(),
|
||||
path, &client_path);
|
||||
status = alloc_get_client_smb_fname(handle,
|
||||
talloc_tos(),
|
||||
smb_fname,
|
||||
&client_fname);
|
||||
if (status != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
status = SMB_VFS_NEXT_CHDIR(handle, client_path);
|
||||
status = SMB_VFS_NEXT_CHDIR(handle, client_fname);
|
||||
|
||||
err:
|
||||
TALLOC_FREE(client_path);
|
||||
TALLOC_FREE(client_fname);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -674,7 +674,7 @@ static uint32_t get_correct_cversion(struct auth_session_info *session_info,
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
files_struct *fsp = NULL;
|
||||
connection_struct *conn = NULL;
|
||||
char *oldcwd;
|
||||
struct smb_filename *oldcwd_fname = NULL;
|
||||
char *printdollar = NULL;
|
||||
char *printdollar_path = NULL;
|
||||
char *working_dir = NULL;
|
||||
@ -733,7 +733,7 @@ static uint32_t get_correct_cversion(struct auth_session_info *session_info,
|
||||
&conn,
|
||||
printdollar_snum,
|
||||
working_dir,
|
||||
session_info, &oldcwd);
|
||||
session_info, &oldcwd_fname);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(0,("get_correct_cversion: create_conn_struct "
|
||||
"returned %s\n", nt_errstr(nt_status)));
|
||||
@ -851,7 +851,8 @@ static uint32_t get_correct_cversion(struct auth_session_info *session_info,
|
||||
close_file(NULL, fsp, NORMAL_CLOSE);
|
||||
}
|
||||
if (conn != NULL) {
|
||||
vfs_ChDir(conn, oldcwd);
|
||||
vfs_ChDir(conn, oldcwd_fname);
|
||||
TALLOC_FREE(oldcwd_fname);
|
||||
SMB_VFS_DISCONNECT(conn);
|
||||
conn_free(conn);
|
||||
}
|
||||
@ -1168,7 +1169,7 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info,
|
||||
int i;
|
||||
TALLOC_CTX *ctx = talloc_tos();
|
||||
int ver = 0;
|
||||
char *oldcwd;
|
||||
struct smb_filename *oldcwd_fname = NULL;
|
||||
char *printdollar = NULL;
|
||||
int printdollar_snum;
|
||||
WERROR err = WERR_OK;
|
||||
@ -1209,7 +1210,7 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info,
|
||||
&conn,
|
||||
printdollar_snum,
|
||||
lp_path(talloc_tos(), printdollar_snum),
|
||||
session_info, &oldcwd);
|
||||
session_info, &oldcwd_fname);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(0,("move_driver_to_download_area: create_conn_struct "
|
||||
"returned %s\n", nt_errstr(nt_status)));
|
||||
@ -1374,7 +1375,8 @@ WERROR move_driver_to_download_area(struct auth_session_info *session_info,
|
||||
TALLOC_FREE(smb_dname);
|
||||
|
||||
if (conn != NULL) {
|
||||
vfs_ChDir(conn, oldcwd);
|
||||
vfs_ChDir(conn, oldcwd_fname);
|
||||
TALLOC_FREE(oldcwd_fname);
|
||||
SMB_VFS_DISCONNECT(conn);
|
||||
conn_free(conn);
|
||||
}
|
||||
@ -1728,7 +1730,7 @@ bool delete_driver_files(const struct auth_session_info *session_info,
|
||||
const char *short_arch;
|
||||
connection_struct *conn;
|
||||
NTSTATUS nt_status;
|
||||
char *oldcwd;
|
||||
struct smb_filename *oldcwd_fname = NULL;
|
||||
char *printdollar = NULL;
|
||||
int printdollar_snum;
|
||||
bool ret = false;
|
||||
@ -1754,7 +1756,7 @@ bool delete_driver_files(const struct auth_session_info *session_info,
|
||||
&conn,
|
||||
printdollar_snum,
|
||||
lp_path(talloc_tos(), printdollar_snum),
|
||||
session_info, &oldcwd);
|
||||
session_info, &oldcwd_fname);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(0,("delete_driver_files: create_conn_struct "
|
||||
"returned %s\n", nt_errstr(nt_status)));
|
||||
@ -1823,7 +1825,8 @@ bool delete_driver_files(const struct auth_session_info *session_info,
|
||||
unbecome_user();
|
||||
err_free_conn:
|
||||
if (conn != NULL) {
|
||||
vfs_ChDir(conn, oldcwd);
|
||||
vfs_ChDir(conn, oldcwd_fname);
|
||||
TALLOC_FREE(oldcwd_fname);
|
||||
SMB_VFS_DISCONNECT(conn);
|
||||
conn_free(conn);
|
||||
}
|
||||
|
@ -2323,7 +2323,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
|
||||
struct sec_desc_buf *sd_buf = NULL;
|
||||
files_struct *fsp = NULL;
|
||||
int snum;
|
||||
char *oldcwd = NULL;
|
||||
struct smb_filename *oldcwd_fname = NULL;
|
||||
uint32_t ucf_flags = 0;
|
||||
|
||||
ZERO_STRUCT(st);
|
||||
@ -2348,7 +2348,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
|
||||
server_messaging_context(),
|
||||
&conn,
|
||||
snum, lp_path(talloc_tos(), snum),
|
||||
p->session_info, &oldcwd);
|
||||
p->session_info, &oldcwd_fname);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(10, ("create_conn_struct failed: %s\n",
|
||||
nt_errstr(nt_status)));
|
||||
@ -2423,12 +2423,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
|
||||
|
||||
*r->out.sd_buf = sd_buf;
|
||||
|
||||
close_file(NULL, fsp, NORMAL_CLOSE);
|
||||
vfs_ChDir(conn, oldcwd);
|
||||
SMB_VFS_DISCONNECT(conn);
|
||||
conn_free(conn);
|
||||
werr = WERR_OK;
|
||||
goto done;
|
||||
|
||||
error_exit:
|
||||
|
||||
@ -2436,8 +2431,9 @@ error_exit:
|
||||
close_file(NULL, fsp, NORMAL_CLOSE);
|
||||
}
|
||||
|
||||
if (oldcwd) {
|
||||
vfs_ChDir(conn, oldcwd);
|
||||
if (oldcwd_fname) {
|
||||
vfs_ChDir(conn, oldcwd_fname);
|
||||
TALLOC_FREE(oldcwd_fname);
|
||||
}
|
||||
|
||||
if (conn) {
|
||||
@ -2445,8 +2441,6 @@ error_exit:
|
||||
conn_free(conn);
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
TALLOC_FREE(smb_fname);
|
||||
|
||||
return werr;
|
||||
@ -2468,7 +2462,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
|
||||
WERROR werr;
|
||||
connection_struct *conn = NULL;
|
||||
int snum;
|
||||
char *oldcwd = NULL;
|
||||
struct smb_filename *oldcwd_fname = NULL;
|
||||
struct security_descriptor *psd = NULL;
|
||||
uint32_t security_info_sent = 0;
|
||||
uint32_t ucf_flags = 0;
|
||||
@ -2497,7 +2491,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
|
||||
server_messaging_context(),
|
||||
&conn,
|
||||
snum, lp_path(talloc_tos(), snum),
|
||||
p->session_info, &oldcwd);
|
||||
p->session_info, &oldcwd_fname);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(10, ("create_conn_struct failed: %s\n",
|
||||
nt_errstr(nt_status)));
|
||||
@ -2555,12 +2549,7 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
close_file(NULL, fsp, NORMAL_CLOSE);
|
||||
vfs_ChDir(conn, oldcwd);
|
||||
SMB_VFS_DISCONNECT(conn);
|
||||
conn_free(conn);
|
||||
werr = WERR_OK;
|
||||
goto done;
|
||||
|
||||
error_exit:
|
||||
|
||||
@ -2568,8 +2557,9 @@ error_exit:
|
||||
close_file(NULL, fsp, NORMAL_CLOSE);
|
||||
}
|
||||
|
||||
if (oldcwd) {
|
||||
vfs_ChDir(conn, oldcwd);
|
||||
if (oldcwd_fname) {
|
||||
vfs_ChDir(conn, oldcwd_fname);
|
||||
TALLOC_FREE(oldcwd_fname);
|
||||
}
|
||||
|
||||
if (conn) {
|
||||
@ -2577,7 +2567,6 @@ error_exit:
|
||||
conn_free(conn);
|
||||
}
|
||||
|
||||
done:
|
||||
TALLOC_FREE(smb_fname);
|
||||
|
||||
return werr;
|
||||
|
@ -399,7 +399,8 @@ static struct smb_Dir *open_dir_with_privilege(connection_struct *conn,
|
||||
uint32_t attr)
|
||||
{
|
||||
struct smb_Dir *dir_hnd = NULL;
|
||||
struct smb_filename *smb_fname_cwd;
|
||||
struct smb_filename *smb_fname_cwd = NULL;
|
||||
struct smb_filename saved_dir_fname = {0};
|
||||
char *saved_dir = vfs_GetWd(talloc_tos(), conn);
|
||||
struct privilege_paths *priv_paths = req->priv_paths;
|
||||
int ret;
|
||||
@ -408,7 +409,9 @@ static struct smb_Dir *open_dir_with_privilege(connection_struct *conn,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (vfs_ChDir(conn, smb_dname->base_name) == -1) {
|
||||
saved_dir_fname = (struct smb_filename) { .base_name = saved_dir };
|
||||
|
||||
if (vfs_ChDir(conn, smb_dname) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -438,7 +441,8 @@ static struct smb_Dir *open_dir_with_privilege(connection_struct *conn,
|
||||
|
||||
out:
|
||||
|
||||
vfs_ChDir(conn, saved_dir);
|
||||
vfs_ChDir(conn, &saved_dir_fname);
|
||||
TALLOC_FREE(saved_dir);
|
||||
return dir_hnd;
|
||||
}
|
||||
|
||||
@ -1679,6 +1683,7 @@ static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx,
|
||||
{
|
||||
struct smb_Dir *dir_hnd = NULL;
|
||||
struct smb_filename *smb_fname_cwd = NULL;
|
||||
struct smb_filename saved_dir_fname = {0};
|
||||
char *saved_dir = vfs_GetWd(ctx, conn);
|
||||
NTSTATUS status;
|
||||
|
||||
@ -1686,7 +1691,9 @@ static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (vfs_ChDir(conn, smb_dname->base_name) == -1) {
|
||||
saved_dir_fname = (struct smb_filename) { .base_name = saved_dir };
|
||||
|
||||
if (vfs_ChDir(conn, smb_dname) == -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1731,7 +1738,7 @@ static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx,
|
||||
|
||||
out:
|
||||
|
||||
vfs_ChDir(conn, saved_dir);
|
||||
vfs_ChDir(conn, &saved_dir_fname);
|
||||
TALLOC_FREE(saved_dir);
|
||||
return dir_hnd;
|
||||
}
|
||||
|
@ -400,10 +400,12 @@ NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
|
||||
int snum,
|
||||
const char *path,
|
||||
const struct auth_session_info *session_info,
|
||||
char **poldcwd)
|
||||
struct smb_filename **poldcwd_fname)
|
||||
{
|
||||
connection_struct *conn;
|
||||
char *oldcwd;
|
||||
char *oldcwd = NULL;
|
||||
struct smb_filename *smb_fname_oldcwd = NULL;
|
||||
struct smb_filename smb_fname_connectpath = {0};
|
||||
|
||||
NTSTATUS status = create_conn_struct(ctx, ev,
|
||||
msg, &conn,
|
||||
@ -427,17 +429,33 @@ NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
|
||||
return status;
|
||||
}
|
||||
|
||||
if (vfs_ChDir(conn,conn->connectpath) != 0) {
|
||||
smb_fname_oldcwd = synthetic_smb_fname(ctx,
|
||||
oldcwd,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
if (smb_fname_oldcwd == NULL) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
conn_free(conn);
|
||||
return status;
|
||||
}
|
||||
|
||||
smb_fname_connectpath = (struct smb_filename) {
|
||||
.base_name = conn->connectpath
|
||||
};
|
||||
|
||||
if (vfs_ChDir(conn, &smb_fname_connectpath) != 0) {
|
||||
status = map_nt_error_from_unix(errno);
|
||||
DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. "
|
||||
"Error was %s\n",
|
||||
conn->connectpath, strerror(errno) ));
|
||||
TALLOC_FREE(smb_fname_oldcwd);
|
||||
conn_free(conn);
|
||||
return status;
|
||||
}
|
||||
|
||||
*pconn = conn;
|
||||
*poldcwd = oldcwd;
|
||||
*poldcwd_fname = smb_fname_oldcwd;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@ -957,7 +975,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
|
||||
NTSTATUS status = NT_STATUS_NOT_FOUND;
|
||||
bool dummy;
|
||||
struct dfs_path *pdp = talloc(ctx, struct dfs_path);
|
||||
char *oldpath;
|
||||
struct smb_filename *oldcwd_fname = NULL;
|
||||
|
||||
if (!pdp) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
@ -1054,8 +1072,11 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
|
||||
status = create_conn_struct_cwd(ctx,
|
||||
server_event_context(),
|
||||
server_messaging_context(),
|
||||
&conn, snum,
|
||||
lp_path(talloc_tos(), snum), NULL, &oldpath);
|
||||
&conn,
|
||||
snum,
|
||||
lp_path(talloc_tos(), snum),
|
||||
NULL,
|
||||
&oldcwd_fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(pdp);
|
||||
return status;
|
||||
@ -1121,7 +1142,8 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
|
||||
|
||||
status = NT_STATUS_OK;
|
||||
err_exit:
|
||||
vfs_ChDir(conn, oldpath);
|
||||
vfs_ChDir(conn, oldcwd_fname);
|
||||
TALLOC_FREE(oldcwd_fname);
|
||||
SMB_VFS_DISCONNECT(conn);
|
||||
conn_free(conn);
|
||||
TALLOC_FREE(pdp);
|
||||
@ -1257,7 +1279,7 @@ bool create_junction(TALLOC_CTX *ctx,
|
||||
static bool junction_to_local_path(const struct junction_map *jucn,
|
||||
char **pp_path_out,
|
||||
connection_struct **conn_out,
|
||||
char **oldpath)
|
||||
struct smb_filename **oldpath_fname)
|
||||
{
|
||||
int snum;
|
||||
NTSTATUS status;
|
||||
@ -1270,7 +1292,10 @@ static bool junction_to_local_path(const struct junction_map *jucn,
|
||||
server_event_context(),
|
||||
server_messaging_context(),
|
||||
conn_out,
|
||||
snum, lp_path(talloc_tos(), snum), NULL, oldpath);
|
||||
snum,
|
||||
lp_path(talloc_tos(), snum),
|
||||
NULL,
|
||||
oldpath_fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return False;
|
||||
}
|
||||
@ -1280,7 +1305,7 @@ static bool junction_to_local_path(const struct junction_map *jucn,
|
||||
lp_path(talloc_tos(), snum),
|
||||
jucn->volume_name);
|
||||
if (!*pp_path_out) {
|
||||
vfs_ChDir(*conn_out, *oldpath);
|
||||
vfs_ChDir(*conn_out, *oldpath_fname);
|
||||
SMB_VFS_DISCONNECT(*conn_out);
|
||||
conn_free(*conn_out);
|
||||
return False;
|
||||
@ -1291,7 +1316,7 @@ static bool junction_to_local_path(const struct junction_map *jucn,
|
||||
bool create_msdfs_link(const struct junction_map *jucn)
|
||||
{
|
||||
char *path = NULL;
|
||||
char *cwd;
|
||||
struct smb_filename *cwd_fname = NULL;
|
||||
char *msdfs_link = NULL;
|
||||
connection_struct *conn;
|
||||
int i=0;
|
||||
@ -1299,7 +1324,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
|
||||
bool ret = False;
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
|
||||
if(!junction_to_local_path(jucn, &path, &conn, &cwd)) {
|
||||
if(!junction_to_local_path(jucn, &path, &conn, &cwd_fname)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -1369,7 +1394,8 @@ bool create_msdfs_link(const struct junction_map *jucn)
|
||||
|
||||
out:
|
||||
TALLOC_FREE(smb_fname);
|
||||
vfs_ChDir(conn, cwd);
|
||||
vfs_ChDir(conn, cwd_fname);
|
||||
TALLOC_FREE(cwd_fname);
|
||||
SMB_VFS_DISCONNECT(conn);
|
||||
conn_free(conn);
|
||||
return ret;
|
||||
@ -1378,12 +1404,12 @@ out:
|
||||
bool remove_msdfs_link(const struct junction_map *jucn)
|
||||
{
|
||||
char *path = NULL;
|
||||
char *cwd;
|
||||
struct smb_filename *cwd_fname = NULL;
|
||||
connection_struct *conn;
|
||||
bool ret = False;
|
||||
struct smb_filename *smb_fname;
|
||||
|
||||
if (!junction_to_local_path(jucn, &path, &conn, &cwd)) {
|
||||
if (!junction_to_local_path(jucn, &path, &conn, &cwd_fname)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1402,7 +1428,8 @@ bool remove_msdfs_link(const struct junction_map *jucn)
|
||||
}
|
||||
|
||||
TALLOC_FREE(smb_fname);
|
||||
vfs_ChDir(conn, cwd);
|
||||
vfs_ChDir(conn, cwd_fname);
|
||||
TALLOC_FREE(cwd_fname);
|
||||
SMB_VFS_DISCONNECT(conn);
|
||||
conn_free(conn);
|
||||
return ret;
|
||||
@ -1422,7 +1449,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
|
||||
const char *msdfs_proxy = lp_msdfs_proxy(talloc_tos(), snum);
|
||||
connection_struct *conn;
|
||||
NTSTATUS status;
|
||||
char *cwd;
|
||||
struct smb_filename *cwd_fname = NULL;
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
|
||||
if(*connect_path == '\0') {
|
||||
@ -1437,7 +1464,10 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
|
||||
server_event_context(),
|
||||
server_messaging_context(),
|
||||
&conn,
|
||||
snum, connect_path, NULL, &cwd);
|
||||
snum,
|
||||
connect_path,
|
||||
NULL,
|
||||
&cwd_fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(3, ("create_conn_struct failed: %s\n",
|
||||
nt_errstr(status)));
|
||||
@ -1489,7 +1519,8 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
|
||||
|
||||
out:
|
||||
TALLOC_FREE(smb_fname);
|
||||
vfs_ChDir(conn, cwd);
|
||||
vfs_ChDir(conn, cwd_fname);
|
||||
TALLOC_FREE(cwd_fname);
|
||||
SMB_VFS_DISCONNECT(conn);
|
||||
conn_free(conn);
|
||||
return cnt;
|
||||
@ -1512,7 +1543,7 @@ static int form_junctions(TALLOC_CTX *ctx,
|
||||
const char *msdfs_proxy = lp_msdfs_proxy(talloc_tos(), snum);
|
||||
connection_struct *conn;
|
||||
struct referral *ref = NULL;
|
||||
char *cwd;
|
||||
struct smb_filename *cwd_fname = NULL;
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
@ -1531,8 +1562,11 @@ static int form_junctions(TALLOC_CTX *ctx,
|
||||
status = create_conn_struct_cwd(ctx,
|
||||
server_event_context(),
|
||||
server_messaging_context(),
|
||||
&conn, snum, connect_path, NULL,
|
||||
&cwd);
|
||||
&conn,
|
||||
snum,
|
||||
connect_path,
|
||||
NULL,
|
||||
&cwd_fname);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(3, ("create_conn_struct failed: %s\n",
|
||||
nt_errstr(status)));
|
||||
@ -1646,7 +1680,8 @@ out:
|
||||
}
|
||||
|
||||
TALLOC_FREE(smb_fname);
|
||||
vfs_ChDir(conn, cwd);
|
||||
vfs_ChDir(conn, cwd_fname);
|
||||
TALLOC_FREE(cwd_fname);
|
||||
conn_free(conn);
|
||||
return cnt;
|
||||
}
|
||||
|
@ -389,7 +389,7 @@ static int link_errno_convert(int err)
|
||||
}
|
||||
|
||||
static int non_widelink_open(struct connection_struct *conn,
|
||||
const char *conn_rootdir,
|
||||
const struct smb_filename *conn_rootdir_fname,
|
||||
files_struct *fsp,
|
||||
struct smb_filename *smb_fname,
|
||||
int flags,
|
||||
@ -401,7 +401,7 @@ static int non_widelink_open(struct connection_struct *conn,
|
||||
****************************************************************************/
|
||||
|
||||
static int process_symlink_open(struct connection_struct *conn,
|
||||
const char *conn_rootdir,
|
||||
const struct smb_filename *conn_rootdir_fname,
|
||||
files_struct *fsp,
|
||||
struct smb_filename *smb_fname,
|
||||
int flags,
|
||||
@ -412,6 +412,7 @@ static int process_symlink_open(struct connection_struct *conn,
|
||||
char *link_target = NULL;
|
||||
int link_len = -1;
|
||||
char *oldwd = NULL;
|
||||
struct smb_filename oldwd_fname = {0};
|
||||
size_t rootdir_len = 0;
|
||||
char *resolved_name = NULL;
|
||||
bool matched = false;
|
||||
@ -456,9 +457,11 @@ static int process_symlink_open(struct connection_struct *conn,
|
||||
* does not end in '/'. FIXME ! Should we
|
||||
* smb_assert this ?
|
||||
*/
|
||||
rootdir_len = strlen(conn_rootdir);
|
||||
rootdir_len = strlen(conn_rootdir_fname->base_name);
|
||||
|
||||
matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0);
|
||||
matched = (strncmp(conn_rootdir_fname->base_name,
|
||||
resolved_name,
|
||||
rootdir_len) == 0);
|
||||
if (!matched) {
|
||||
errno = EACCES;
|
||||
goto out;
|
||||
@ -486,14 +489,16 @@ static int process_symlink_open(struct connection_struct *conn,
|
||||
goto out;
|
||||
}
|
||||
|
||||
oldwd_fname = (struct smb_filename) { .base_name = oldwd };
|
||||
|
||||
/* Ensure we operate from the root of the share. */
|
||||
if (vfs_ChDir(conn, conn_rootdir) == -1) {
|
||||
if (vfs_ChDir(conn, conn_rootdir_fname) == -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* And do it all again.. */
|
||||
fd = non_widelink_open(conn,
|
||||
conn_rootdir,
|
||||
conn_rootdir_fname,
|
||||
fsp,
|
||||
smb_fname,
|
||||
flags,
|
||||
@ -508,7 +513,7 @@ static int process_symlink_open(struct connection_struct *conn,
|
||||
SAFE_FREE(resolved_name);
|
||||
TALLOC_FREE(link_target);
|
||||
if (oldwd != NULL) {
|
||||
int ret = vfs_ChDir(conn, oldwd);
|
||||
int ret = vfs_ChDir(conn, &oldwd_fname);
|
||||
if (ret == -1) {
|
||||
smb_panic("unable to get back to old directory\n");
|
||||
}
|
||||
@ -525,7 +530,7 @@ static int process_symlink_open(struct connection_struct *conn,
|
||||
****************************************************************************/
|
||||
|
||||
static int non_widelink_open(struct connection_struct *conn,
|
||||
const char *conn_rootdir,
|
||||
const struct smb_filename *conn_rootdir_fname,
|
||||
files_struct *fsp,
|
||||
struct smb_filename *smb_fname,
|
||||
int flags,
|
||||
@ -537,7 +542,9 @@ static int non_widelink_open(struct connection_struct *conn,
|
||||
struct smb_filename *smb_fname_rel = NULL;
|
||||
int saved_errno = 0;
|
||||
char *oldwd = NULL;
|
||||
struct smb_filename oldwd_fname = {0};
|
||||
char *parent_dir = NULL;
|
||||
struct smb_filename parent_dir_fname = {0};
|
||||
const char *final_component = NULL;
|
||||
|
||||
if (!parent_dirname(talloc_tos(),
|
||||
@ -547,13 +554,17 @@ static int non_widelink_open(struct connection_struct *conn,
|
||||
goto out;
|
||||
}
|
||||
|
||||
parent_dir_fname = (struct smb_filename) { .base_name = parent_dir };
|
||||
|
||||
oldwd = vfs_GetWd(talloc_tos(), conn);
|
||||
if (oldwd == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
oldwd_fname = (struct smb_filename) { .base_name = oldwd };
|
||||
|
||||
/* Pin parent directory in place. */
|
||||
if (vfs_ChDir(conn, parent_dir) == -1) {
|
||||
if (vfs_ChDir(conn, &parent_dir_fname) == -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -606,7 +617,7 @@ static int non_widelink_open(struct connection_struct *conn,
|
||||
* to ensure it's under the share definition.
|
||||
*/
|
||||
fd = process_symlink_open(conn,
|
||||
conn_rootdir,
|
||||
conn_rootdir_fname,
|
||||
fsp,
|
||||
smb_fname_rel,
|
||||
flags,
|
||||
@ -634,7 +645,7 @@ static int non_widelink_open(struct connection_struct *conn,
|
||||
TALLOC_FREE(smb_fname_rel);
|
||||
|
||||
if (oldwd != NULL) {
|
||||
int ret = vfs_ChDir(conn, oldwd);
|
||||
int ret = vfs_ChDir(conn, &oldwd_fname);
|
||||
if (ret == -1) {
|
||||
smb_panic("unable to get back to old directory\n");
|
||||
}
|
||||
@ -669,22 +680,41 @@ NTSTATUS fd_open(struct connection_struct *conn,
|
||||
|
||||
/* Ensure path is below share definition. */
|
||||
if (!lp_widelinks(SNUM(conn))) {
|
||||
struct smb_filename *conn_rootdir_fname = NULL;
|
||||
const char *conn_rootdir = SMB_VFS_CONNECTPATH(conn,
|
||||
smb_fname->base_name);
|
||||
int saved_errno = 0;
|
||||
|
||||
if (conn_rootdir == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
conn_rootdir_fname = synthetic_smb_fname(talloc_tos(),
|
||||
conn_rootdir,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
if (conn_rootdir_fname == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only follow symlinks within a share
|
||||
* definition.
|
||||
*/
|
||||
fsp->fh->fd = non_widelink_open(conn,
|
||||
conn_rootdir,
|
||||
conn_rootdir_fname,
|
||||
fsp,
|
||||
smb_fname,
|
||||
flags,
|
||||
mode,
|
||||
0);
|
||||
if (fsp->fh->fd == -1) {
|
||||
saved_errno = errno;
|
||||
}
|
||||
TALLOC_FREE(conn_rootdir_fname);
|
||||
if (saved_errno != 0) {
|
||||
errno = saved_errno;
|
||||
}
|
||||
} else {
|
||||
fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
|
||||
}
|
||||
@ -800,14 +830,15 @@ void change_file_owner_to_parent(connection_struct *conn,
|
||||
TALLOC_FREE(smb_fname_parent);
|
||||
}
|
||||
|
||||
NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
|
||||
const char *inherit_from_dir,
|
||||
const char *fname,
|
||||
SMB_STRUCT_STAT *psbuf)
|
||||
static NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
|
||||
const char *inherit_from_dir,
|
||||
struct smb_filename *smb_dname,
|
||||
SMB_STRUCT_STAT *psbuf)
|
||||
{
|
||||
struct smb_filename *smb_fname_parent;
|
||||
struct smb_filename *smb_fname_cwd = NULL;
|
||||
char *saved_dir = NULL;
|
||||
struct smb_filename smb_fname_saved_dir = {0};
|
||||
TALLOC_CTX *ctx = talloc_tos();
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
int ret;
|
||||
@ -847,12 +878,14 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
|
||||
goto out;
|
||||
}
|
||||
|
||||
smb_fname_saved_dir = (struct smb_filename) { .base_name = saved_dir };
|
||||
|
||||
/* Chdir into the new path. */
|
||||
if (vfs_ChDir(conn, fname) == -1) {
|
||||
if (vfs_ChDir(conn, smb_dname) == -1) {
|
||||
status = map_nt_error_from_unix(errno);
|
||||
DEBUG(0,("change_dir_owner_to_parent: failed to change "
|
||||
"current working directory to %s. Error "
|
||||
"was %s\n", fname, strerror(errno) ));
|
||||
"was %s\n", smb_dname->base_name, strerror(errno) ));
|
||||
goto chdir;
|
||||
}
|
||||
|
||||
@ -867,7 +900,7 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
|
||||
status = map_nt_error_from_unix(errno);
|
||||
DEBUG(0,("change_dir_owner_to_parent: failed to stat "
|
||||
"directory '.' (%s) Error was %s\n",
|
||||
fname, strerror(errno)));
|
||||
smb_dname->base_name, strerror(errno)));
|
||||
goto chdir;
|
||||
}
|
||||
|
||||
@ -876,7 +909,8 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
|
||||
smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino) {
|
||||
DEBUG(0,("change_dir_owner_to_parent: "
|
||||
"device/inode on directory %s changed. "
|
||||
"Refusing to chown !\n", fname ));
|
||||
"Refusing to chown !\n",
|
||||
smb_dname->base_name ));
|
||||
status = NT_STATUS_ACCESS_DENIED;
|
||||
goto chdir;
|
||||
}
|
||||
@ -885,7 +919,7 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
|
||||
/* Already this uid - no need to change. */
|
||||
DEBUG(10,("change_dir_owner_to_parent: directory %s "
|
||||
"is already owned by uid %d\n",
|
||||
fname,
|
||||
smb_dname->base_name,
|
||||
(int)smb_fname_cwd->st.st_ex_uid ));
|
||||
status = NT_STATUS_OK;
|
||||
goto chdir;
|
||||
@ -901,20 +935,23 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
|
||||
status = map_nt_error_from_unix(errno);
|
||||
DEBUG(10,("change_dir_owner_to_parent: failed to chown "
|
||||
"directory %s to parent directory uid %u. "
|
||||
"Error was %s\n", fname,
|
||||
"Error was %s\n",
|
||||
smb_dname->base_name,
|
||||
(unsigned int)smb_fname_parent->st.st_ex_uid,
|
||||
strerror(errno) ));
|
||||
} else {
|
||||
DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
|
||||
"directory %s to parent directory uid %u.\n",
|
||||
fname, (unsigned int)smb_fname_parent->st.st_ex_uid ));
|
||||
smb_dname->base_name,
|
||||
(unsigned int)smb_fname_parent->st.st_ex_uid ));
|
||||
/* Ensure the uid entry is updated. */
|
||||
psbuf->st_ex_uid = smb_fname_parent->st.st_ex_uid;
|
||||
}
|
||||
|
||||
chdir:
|
||||
vfs_ChDir(conn,saved_dir);
|
||||
vfs_ChDir(conn, &smb_fname_saved_dir);
|
||||
out:
|
||||
TALLOC_FREE(saved_dir);
|
||||
TALLOC_FREE(smb_fname_parent);
|
||||
TALLOC_FREE(smb_fname_cwd);
|
||||
return status;
|
||||
@ -3875,7 +3912,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
|
||||
/* Change the owner if required. */
|
||||
if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
|
||||
change_dir_owner_to_parent(conn, parent_dir,
|
||||
smb_dname->base_name,
|
||||
smb_dname,
|
||||
&smb_dname->st);
|
||||
need_re_stat = true;
|
||||
}
|
||||
|
@ -510,7 +510,7 @@ NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
|
||||
int snum,
|
||||
const char *path,
|
||||
const struct auth_session_info *session_info,
|
||||
char **poldcwd);
|
||||
struct smb_filename **poldcwd_fname);
|
||||
|
||||
/* The following definitions come from smbd/negprot.c */
|
||||
|
||||
@ -649,10 +649,6 @@ NTSTATUS fd_close(files_struct *fsp);
|
||||
void change_file_owner_to_parent(connection_struct *conn,
|
||||
const char *inherit_from_dir,
|
||||
files_struct *fsp);
|
||||
NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
|
||||
const char *inherit_from_dir,
|
||||
const char *fname,
|
||||
SMB_STRUCT_STAT *psbuf);
|
||||
bool is_stat_open(uint32_t access_mask);
|
||||
NTSTATUS send_break_message(struct messaging_context *msg_ctx,
|
||||
const struct share_mode_entry *exclusive,
|
||||
@ -1234,7 +1230,8 @@ int vfs_fill_sparse(files_struct *fsp, off_t len);
|
||||
off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n);
|
||||
const char *vfs_readdirname(connection_struct *conn, void *p,
|
||||
SMB_STRUCT_STAT *sbuf, char **talloced);
|
||||
int vfs_ChDir(connection_struct *conn, const char *path);
|
||||
int vfs_ChDir(connection_struct *conn,
|
||||
const struct smb_filename *smb_fname);
|
||||
char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn);
|
||||
NTSTATUS check_reduced_name(connection_struct *conn,
|
||||
const char *cwd_name,
|
||||
|
@ -95,12 +95,22 @@ bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir)
|
||||
|
||||
snum = SNUM(conn);
|
||||
|
||||
if (do_chdir &&
|
||||
vfs_ChDir(conn,conn->connectpath) != 0 &&
|
||||
vfs_ChDir(conn,conn->origpath) != 0) {
|
||||
DEBUG(((errno!=EACCES)?0:3),("chdir (%s) failed, reason: %s\n",
|
||||
conn->connectpath, strerror(errno)));
|
||||
return(False);
|
||||
{
|
||||
struct smb_filename connectpath_fname = {
|
||||
.base_name = conn->connectpath
|
||||
};
|
||||
struct smb_filename origpath_fname = {
|
||||
.base_name = conn->origpath
|
||||
};
|
||||
|
||||
if (do_chdir &&
|
||||
vfs_ChDir(conn, &connectpath_fname) != 0 &&
|
||||
vfs_ChDir(conn, &origpath_fname) != 0) {
|
||||
DEBUG(((errno!=EACCES)?0:3),
|
||||
("chdir (%s) failed, reason: %s\n",
|
||||
conn->connectpath, strerror(errno)));
|
||||
return(False);
|
||||
}
|
||||
}
|
||||
|
||||
if ((conn == last_conn) && (last_flags == flags)) {
|
||||
@ -1083,6 +1093,9 @@ connection_struct *make_connection(struct smb_request *req,
|
||||
|
||||
void close_cnum(connection_struct *conn, uint64_t vuid)
|
||||
{
|
||||
char rootpath[2] = { '/', '\0'};
|
||||
struct smb_filename root_fname = { .base_name = rootpath };
|
||||
|
||||
file_close_conn(conn);
|
||||
|
||||
if (!IS_IPC(conn)) {
|
||||
@ -1098,7 +1111,7 @@ void close_cnum(connection_struct *conn, uint64_t vuid)
|
||||
lp_servicename(talloc_tos(), SNUM(conn))));
|
||||
|
||||
/* make sure we leave the directory available for unmount */
|
||||
vfs_ChDir(conn, "/");
|
||||
vfs_ChDir(conn, &root_fname);
|
||||
|
||||
/* Call VFS disconnect hook */
|
||||
SMB_VFS_DISCONNECT(conn);
|
||||
|
@ -855,7 +855,7 @@ const char *vfs_readdirname(connection_struct *conn, void *p,
|
||||
A wrapper for vfs_chdir().
|
||||
********************************************************************/
|
||||
|
||||
int vfs_ChDir(connection_struct *conn, const char *path)
|
||||
int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -863,21 +863,22 @@ int vfs_ChDir(connection_struct *conn, const char *path)
|
||||
LastDir = SMB_STRDUP("");
|
||||
}
|
||||
|
||||
if (ISDOT(path)) {
|
||||
if (ISDOT(smb_fname->base_name)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*path == '/' && strcsequal(LastDir,path)) {
|
||||
if (*smb_fname->base_name == '/' &&
|
||||
strcsequal(LastDir,smb_fname->base_name)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUG(4,("vfs_ChDir to %s\n",path));
|
||||
DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
|
||||
|
||||
ret = SMB_VFS_CHDIR(conn,path);
|
||||
ret = SMB_VFS_CHDIR(conn, smb_fname);
|
||||
if (ret == 0) {
|
||||
/* Global cache. */
|
||||
SAFE_FREE(LastDir);
|
||||
LastDir = SMB_STRDUP(path);
|
||||
LastDir = SMB_STRDUP(smb_fname->base_name);
|
||||
|
||||
/* conn cache. */
|
||||
TALLOC_FREE(conn->cwd);
|
||||
@ -1009,6 +1010,7 @@ NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
|
||||
const char *last_component = NULL;
|
||||
char *resolved_name = NULL;
|
||||
char *saved_dir = NULL;
|
||||
struct smb_filename *saved_dir_fname = NULL;
|
||||
struct smb_filename *smb_fname_cwd = NULL;
|
||||
struct privilege_paths *priv_paths = NULL;
|
||||
int ret;
|
||||
@ -1049,8 +1051,18 @@ NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
|
||||
goto err;
|
||||
}
|
||||
|
||||
saved_dir_fname = synthetic_smb_fname(ctx,
|
||||
saved_dir,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
if (saved_dir_fname == NULL) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Go to the parent directory to lock in memory. */
|
||||
if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
|
||||
if (vfs_ChDir(conn, &priv_paths->parent_name) == -1) {
|
||||
status = map_nt_error_from_unix(errno);
|
||||
goto err;
|
||||
}
|
||||
@ -1165,8 +1177,10 @@ NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
|
||||
|
||||
err:
|
||||
|
||||
if (saved_dir) {
|
||||
vfs_ChDir(conn, saved_dir);
|
||||
if (saved_dir_fname) {
|
||||
vfs_ChDir(conn, saved_dir_fname);
|
||||
TALLOC_FREE(saved_dir);
|
||||
TALLOC_FREE(saved_dir_fname);
|
||||
}
|
||||
SAFE_FREE(resolved_name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
@ -2014,6 +2028,8 @@ NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
|
||||
char *parent_dir = NULL;
|
||||
const char *final_component = NULL;
|
||||
struct smb_filename *local_smb_fname = NULL;
|
||||
struct smb_filename parent_dir_fname = {0};
|
||||
struct smb_filename saved_dir_fname = {0};
|
||||
|
||||
saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
|
||||
if (!saved_dir) {
|
||||
@ -2024,6 +2040,10 @@ NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
|
||||
return status;
|
||||
}
|
||||
|
||||
saved_dir_fname = (struct smb_filename) {
|
||||
.base_name = saved_dir
|
||||
};
|
||||
|
||||
if (!parent_dirname(talloc_tos(),
|
||||
fsp->fsp_name->base_name,
|
||||
&parent_dir,
|
||||
@ -2031,8 +2051,13 @@ NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
parent_dir_fname = (struct smb_filename) {
|
||||
.base_name = parent_dir,
|
||||
.flags = fsp->fsp_name->flags
|
||||
};
|
||||
|
||||
/* cd into the parent dir to pin it. */
|
||||
ret = vfs_ChDir(fsp->conn, parent_dir);
|
||||
ret = vfs_ChDir(fsp->conn, &parent_dir_fname);
|
||||
if (ret == -1) {
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
@ -2073,7 +2098,7 @@ NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
|
||||
|
||||
out:
|
||||
|
||||
vfs_ChDir(fsp->conn,saved_dir);
|
||||
vfs_ChDir(fsp->conn, &saved_dir_fname);
|
||||
TALLOC_FREE(local_smb_fname);
|
||||
TALLOC_FREE(saved_dir);
|
||||
TALLOC_FREE(parent_dir);
|
||||
@ -2099,10 +2124,11 @@ NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
|
||||
return status;
|
||||
}
|
||||
|
||||
int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
|
||||
int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *smb_fname)
|
||||
{
|
||||
VFS_FIND(chdir);
|
||||
return handle->fns->chdir_fn(handle, path);
|
||||
return handle->fns->chdir_fn(handle, smb_fname);
|
||||
}
|
||||
|
||||
char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
|
||||
|
@ -463,7 +463,8 @@ static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
|
||||
ret = SMB_VFS_UNLINK(vfs->conn, smb_fname);
|
||||
TALLOC_FREE(smb_fname);
|
||||
} else if (strcmp("chdir", argv[0]) == 0 ) {
|
||||
ret = SMB_VFS_CHDIR(vfs->conn, argv[1]);
|
||||
ret = SMB_VFS_CHDIR(vfs->conn, smb_fname);
|
||||
TALLOC_FREE(smb_fname);
|
||||
} else {
|
||||
printf("%s: error=%d (invalid function name!)\n", argv[0], errno);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user