summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/VFS/skel_opaque.c5
-rw-r--r--examples/VFS/skel_transparent.c7
-rw-r--r--source3/include/vfs.h11
-rw-r--r--source3/modules/vfs_cap.c37
-rw-r--r--source3/modules/vfs_ceph.c12
-rw-r--r--source3/modules/vfs_default.c6
-rw-r--r--source3/modules/vfs_full_audit.c7
-rw-r--r--source3/modules/vfs_glusterfs.c7
-rw-r--r--source3/modules/vfs_media_harmony.c48
-rw-r--r--source3/modules/vfs_shadow_copy2.c21
-rw-r--r--source3/modules/vfs_snapper.c22
-rw-r--r--source3/modules/vfs_syncops.c44
-rw-r--r--source3/modules/vfs_time_audit.c8
-rw-r--r--source3/modules/vfs_unityed_media.c30
-rw-r--r--source3/smbd/msdfs.c29
-rw-r--r--source3/smbd/trans2.c7
-rw-r--r--source3/smbd/vfs.c7
-rw-r--r--source3/torture/cmd_vfs.c10
18 files changed, 186 insertions, 132 deletions
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 792f728f83a..d5c468ebd99 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -476,8 +476,9 @@ static bool skel_getlock(vfs_handle_struct *handle, files_struct *fsp,
return false;
}
-static int skel_symlink(vfs_handle_struct *handle, const char *oldpath,
- const char *newpath)
+static int skel_symlink(vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
errno = ENOSYS;
return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 11512e3815b..93872769422 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -570,10 +570,11 @@ static bool skel_getlock(vfs_handle_struct *handle, files_struct *fsp,
return SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
}
-static int skel_symlink(vfs_handle_struct *handle, const char *oldpath,
- const char *newpath)
+static int skel_symlink(vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- return SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ return SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
}
static int skel_vfs_readlink(vfs_handle_struct *handle,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 115a9dc01c6..db555f2cc2b 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -226,6 +226,8 @@
to const struct smb_filename * */
/* Version 37 - Change readlink from const char *
to const struct smb_filename * */
+/* Version 37 - Change symlink from const char *
+ to const struct smb_filename * */
#define SMB_VFS_INTERFACE_VERSION 37
@@ -745,7 +747,9 @@ struct vfs_fn_pointers {
uint32_t share_mode, uint32_t access_mask);
int (*linux_setlease_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, int leasetype);
bool (*getlock_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid);
- int (*symlink_fn)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath);
+ int (*symlink_fn)(struct vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname);
int (*readlink_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
char *buf,
@@ -1251,8 +1255,9 @@ int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
bool smb_vfs_call_getlock(struct vfs_handle_struct *handle,
struct files_struct *fsp, off_t *poffset,
off_t *pcount, int *ptype, pid_t *ppid);
-int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
- const char *newpath);
+int smb_vfs_call_symlink(struct vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname);
int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
char *buf,
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 2c21ab18c48..c07a05954c0 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -479,17 +479,44 @@ static int cap_ntimes(vfs_handle_struct *handle,
}
-static int cap_symlink(vfs_handle_struct *handle, const char *oldpath,
- const char *newpath)
+static int cap_symlink(vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- char *capold = capencode(talloc_tos(), oldpath);
- char *capnew = capencode(talloc_tos(), newpath);
+ char *capold = capencode(talloc_tos(), link_contents);
+ char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
+ struct smb_filename *new_cap_smb_fname = NULL;
+ int saved_errno = 0;
+ int ret;
if (!capold || !capnew) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew);
+ new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ capnew,
+ NULL,
+ NULL,
+ new_smb_fname->flags);
+ if (new_cap_smb_fname == NULL) {
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = SMB_VFS_NEXT_SYMLINK(handle,
+ capold,
+ new_cap_smb_fname);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ TALLOC_FREE(new_cap_smb_fname);
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+ return ret;
}
static int cap_readlink(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 3c38165b58f..7e2bd0e95d2 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -1125,11 +1125,17 @@ static int cephwrap_linux_setlease(struct vfs_handle_struct *handle, files_struc
return result;
}
-static int cephwrap_symlink(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int cephwrap_symlink(struct vfs_handle_struct *handle,
+ const char *link_target,
+ const struct smb_filename *new_smb_fname)
{
int result = -1;
- DBG_DEBUG("[CEPH] symlink(%p, %s, %s)\n", handle, oldpath, newpath);
- result = ceph_symlink(handle->data, oldpath, newpath);
+ DBG_DEBUG("[CEPH] symlink(%p, %s, %s)\n", handle,
+ link_target,
+ new_smb_fname->base_name);
+ result = ceph_symlink(handle->data,
+ link_target,
+ new_smb_fname->base_name);
DBG_DEBUG("[CEPH] symlink(...) = %d\n", result);
WRAP_RETURN(result);
}
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 93ff6578553..d339f39aa06 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2418,12 +2418,14 @@ static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
return result;
}
-static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int vfswrap_symlink(vfs_handle_struct *handle,
+ const char *link_target,
+ const struct smb_filename *new_smb_fname)
{
int result;
START_PROFILE(syscall_symlink);
- result = symlink(oldpath, newpath);
+ result = symlink(link_target, new_smb_fname->base_name);
END_PROFILE(syscall_symlink);
return result;
}
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 408f834858c..1267ef3d226 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -1626,14 +1626,15 @@ static bool smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp,
}
static int smb_full_audit_symlink(vfs_handle_struct *handle,
- const char *oldpath, const char *newpath)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
int result;
- result = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ result = SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
do_log(SMB_VFS_OP_SYMLINK, (result >= 0), handle,
- "%s|%s", oldpath, newpath);
+ "%s|%s", link_contents, new_smb_fname->base_name);
return result;
}
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index bf19dd722a8..2528959d968 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -1234,9 +1234,12 @@ static bool vfs_gluster_getlock(struct vfs_handle_struct *handle,
}
static int vfs_gluster_symlink(struct vfs_handle_struct *handle,
- const char *oldpath, const char *newpath)
+ const char *link_target,
+ const struct smb_filename *new_smb_fname)
{
- return glfs_symlink(handle->data, oldpath, newpath);
+ return glfs_symlink(handle->data,
+ link_target,
+ new_smb_fname->base_name);
}
static int vfs_gluster_readlink(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index 13604b36dcf..ca8d6ce1a6d 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -1719,47 +1719,41 @@ out:
* Success: return 0
* Failure: set errno, return -1
*/
+
static int mh_symlink(vfs_handle_struct *handle,
- const char *oldpath,
- const char *newpath)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- int status;
- char *oldClientPath;
- char *newClientPath;
- TALLOC_CTX *ctx;
+ int status = -1;
+ char *client_link_contents = NULL;
+ struct smb_filename *newclientFname = NULL;
DEBUG(MH_INFO_DEBUG, ("Entering mh_symlink\n"));
- if (!is_in_media_files(oldpath) && !is_in_media_files(newpath))
- {
- status = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ if (!is_in_media_files(link_contents) &&
+ !is_in_media_files(new_smb_fname->base_name)) {
+ status = SMB_VFS_NEXT_SYMLINK(handle,
+ link_contents,
+ new_smb_fname);
goto out;
}
- oldClientPath = NULL;
- newClientPath = NULL;
- ctx = talloc_tos();
-
- if ((status = alloc_get_client_path(handle, ctx,
- oldpath,
- &oldClientPath)))
- {
+ if ((status = alloc_get_client_path(handle, talloc_tos(),
+ link_contents,
+ &client_link_contents))) {
goto err;
}
-
- if ((status = alloc_get_client_path(handle, ctx,
- newpath,
- &newClientPath)))
- {
+ if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
+ new_smb_fname,
+ &newclientFname))) {
goto err;
}
status = SMB_VFS_NEXT_SYMLINK(handle,
- oldClientPath,
- newClientPath);
-
+ client_link_contents,
+ newclientFname);
err:
- TALLOC_FREE(newClientPath);
- TALLOC_FREE(oldClientPath);
+ TALLOC_FREE(client_link_contents);
+ TALLOC_FREE(newclientFname);
out:
return status;
}
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 2c7fcaacef7..31ef499527e 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -1150,19 +1150,28 @@ static int shadow_copy2_rename(vfs_handle_struct *handle,
}
static int shadow_copy2_symlink(vfs_handle_struct *handle,
- const char *oldname, const char *newname)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
time_t timestamp_old = 0;
time_t timestamp_new = 0;
char *snappath_old = NULL;
char *snappath_new = NULL;
- if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname,
- &timestamp_old, NULL, &snappath_old)) {
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(),
+ handle,
+ link_contents,
+ &timestamp_old,
+ NULL,
+ &snappath_old)) {
return -1;
}
- if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname,
- &timestamp_new, NULL, &snappath_new)) {
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(),
+ handle,
+ new_smb_fname->base_name,
+ &timestamp_new,
+ NULL,
+ &snappath_new)) {
return -1;
}
if ((timestamp_old != 0) || (timestamp_new != 0)) {
@@ -1176,7 +1185,7 @@ static int shadow_copy2_symlink(vfs_handle_struct *handle,
errno = EROFS;
return -1;
}
- return SMB_VFS_NEXT_SYMLINK(handle, oldname, newname);
+ return SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
}
static int shadow_copy2_link(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index a41397427cc..4c814327feb 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -2037,23 +2037,31 @@ static int snapper_gmt_rename(vfs_handle_struct *handle,
}
static int snapper_gmt_symlink(vfs_handle_struct *handle,
- const char *oldname, const char *newname)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- time_t timestamp_old, timestamp_new;
+ time_t timestamp_old = 0;
+ time_t timestamp_new = 0;
- if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, oldname,
- &timestamp_old, NULL)) {
+ if (!snapper_gmt_strip_snapshot(talloc_tos(),
+ handle,
+ link_contents,
+ &timestamp_old,
+ NULL)) {
return -1;
}
- if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, newname,
- &timestamp_new, NULL)) {
+ if (!snapper_gmt_strip_snapshot(talloc_tos(),
+ handle,
+ new_smb_fname->base_name,
+ &timestamp_new,
+ NULL)) {
return -1;
}
if ((timestamp_old != 0) || (timestamp_new != 0)) {
errno = EROFS;
return -1;
}
- return SMB_VFS_NEXT_SYMLINK(handle, oldname, newname);
+ return SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
}
static int snapper_gmt_link(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_syncops.c b/source3/modules/vfs_syncops.c
index 725bd1072e4..f94588c60ed 100644
--- a/source3/modules/vfs_syncops.c
+++ b/source3/modules/vfs_syncops.c
@@ -111,19 +111,6 @@ static void syncops_two_names(const char *name1, const char *name2)
/*
sync two meta data changes for 1 names
*/
-static void syncops_name(const char *name)
-{
- char *parent;
- parent = parent_dir(NULL, name);
- if (parent) {
- syncops_sync_directory(parent);
- talloc_free(parent);
- }
-}
-
-/*
- sync two meta data changes for 1 names
- */
static void syncops_smb_fname(const struct smb_filename *smb_fname)
{
char *parent;
@@ -158,20 +145,6 @@ static int syncops_rename(vfs_handle_struct *handle,
return ret;
}
-/* handle the rest with a macro */
-#define SYNCOPS_NEXT(op, fname, args) do { \
- int ret; \
- struct syncops_config_data *config; \
- SMB_VFS_HANDLE_GET_DATA(handle, config, \
- struct syncops_config_data, \
- return -1); \
- ret = SMB_VFS_NEXT_ ## op args; \
- if (ret == 0 \
- && config->onmeta && !config->disable \
- && fname) syncops_name(fname); \
- return ret; \
-} while (0)
-
#define SYNCOPS_NEXT_SMB_FNAME(op, fname, args) do { \
int ret; \
struct syncops_config_data *config; \
@@ -186,9 +159,22 @@ static int syncops_rename(vfs_handle_struct *handle,
} while (0)
static int syncops_symlink(vfs_handle_struct *handle,
- const char *oldname, const char *newname)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- SYNCOPS_NEXT(SYMLINK, newname, (handle, oldname, newname));
+ int ret;
+ struct syncops_config_data *config;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct syncops_config_data,
+ return -1);
+
+ ret = SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
+ if (ret == 0 && config->onmeta && !config->disable) {
+ syncops_two_names(link_contents,
+ new_smb_fname->base_name);
+ }
+ return ret;
}
static int syncops_link(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 58c0f796a87..d3992018542 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -1424,19 +1424,21 @@ static bool smb_time_audit_getlock(vfs_handle_struct *handle,
}
static int smb_time_audit_symlink(vfs_handle_struct *handle,
- const char *oldpath, const char *newpath)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
int result;
struct timespec ts1,ts2;
double timediff;
clock_gettime_mono(&ts1);
- result = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ result = SMB_VFS_NEXT_SYMLINK(handle, link_contents, new_smb_fname);
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
if (timediff > audit_timeout) {
- smb_time_audit_log_fname("symlink", timediff, newpath);
+ smb_time_audit_log_fname("symlink", timediff,
+ new_smb_fname->base_name);
}
return result;
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index c9ecc277408..45232e1781c 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -1318,38 +1318,40 @@ err:
}
static int um_symlink(vfs_handle_struct *handle,
- const char *oldpath,
- const char *newpath)
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
int status;
- char *old_client_path = NULL;
- char *new_client_path = NULL;
+ char *client_link_contents = NULL;
+ struct smb_filename *new_client_fname = NULL;
DEBUG(10, ("Entering um_symlink\n"));
- if (!is_in_media_files(oldpath) && !is_in_media_files(newpath)) {
- return SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+ if (!is_in_media_files(link_contents) &&
+ !is_in_media_files(new_smb_fname->base_name)) {
+ return SMB_VFS_NEXT_SYMLINK(handle,
+ link_contents,
+ new_smb_fname);
}
status = alloc_get_client_path(handle, talloc_tos(),
- oldpath, &old_client_path);
+ link_contents, &client_link_contents);
if (status != 0) {
goto err;
}
-
- status = alloc_get_client_path(handle, talloc_tos(),
- newpath, &new_client_path);
+ status = alloc_get_client_smb_fname(handle, talloc_tos(),
+ new_smb_fname, &new_client_fname);
if (status != 0) {
goto err;
}
status = SMB_VFS_NEXT_SYMLINK(handle,
- old_client_path,
- new_client_path);
+ client_link_contents,
+ new_client_fname);
err:
- TALLOC_FREE(new_client_path);
- TALLOC_FREE(old_client_path);
+ TALLOC_FREE(client_link_contents);
+ TALLOC_FREE(new_client_fname);
return status;
}
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index b88538c2ba1..9c25d8ba8fe 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1297,6 +1297,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
int i=0;
bool insert_comma = False;
bool ret = False;
+ struct smb_filename *smb_fname = NULL;
if(!junction_to_local_path(jucn, &path, &conn, &cwd)) {
return False;
@@ -1339,27 +1340,24 @@ bool create_msdfs_link(const struct junction_map *jucn)
DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n",
path, msdfs_link));
- if(SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) {
- if (errno == EEXIST) {
- struct smb_filename *smb_fname;
-
- smb_fname = synthetic_smb_fname(talloc_tos(),
- path,
- NULL,
- NULL,
- 0);
- if (smb_fname == NULL) {
- errno = ENOMEM;
- goto out;
- }
+ smb_fname = synthetic_smb_fname(talloc_tos(),
+ path,
+ NULL,
+ NULL,
+ 0);
+ if (smb_fname == NULL) {
+ errno = ENOMEM;
+ goto out;
+ }
+ if(SMB_VFS_SYMLINK(conn, msdfs_link, smb_fname) < 0) {
+ if (errno == EEXIST) {
if(SMB_VFS_UNLINK(conn, smb_fname)!=0) {
TALLOC_FREE(smb_fname);
goto out;
}
- TALLOC_FREE(smb_fname);
}
- if (SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) {
+ if (SMB_VFS_SYMLINK(conn, msdfs_link, smb_fname) < 0) {
DEBUG(1,("create_msdfs_link: symlink failed "
"%s -> %s\nError: %s\n",
path, msdfs_link, strerror(errno)));
@@ -1370,6 +1368,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
ret = True;
out:
+ TALLOC_FREE(smb_fname);
vfs_ChDir(conn, cwd);
SMB_VFS_DISCONNECT(conn);
conn_free(conn);
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 8615a782f4a..de6073a973f 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -6607,10 +6607,9 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
struct smb_request *req,
const char *pdata,
int total_data,
- const struct smb_filename *smb_fname)
+ const struct smb_filename *new_smb_fname)
{
char *link_target = NULL;
- const char *newname = smb_fname->base_name;
TALLOC_CTX *ctx = talloc_tos();
/* Set a symbolic link. */
@@ -6632,9 +6631,9 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
}
DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
- newname, link_target ));
+ new_smb_fname->base_name, link_target ));
- if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0) {
+ if (SMB_VFS_SYMLINK(conn,link_target,new_smb_fname) != 0) {
return map_nt_error_from_unix(errno);
}
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index bed3d2c1554..5acfb9af38a 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2152,11 +2152,12 @@ int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
}
-int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
- const char *newpath)
+int smb_vfs_call_symlink(struct vfs_handle_struct *handle,
+ const char *link_target,
+ const struct smb_filename *new_smb_fname)
{
VFS_FIND(symlink);
- return handle->fns->symlink_fn(handle, oldpath, newpath);
+ return handle->fns->symlink_fn(handle, link_target, new_smb_fname);
}
int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 47e365a5dac..65a8e258d0d 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -1213,12 +1213,20 @@ static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
+ struct smb_filename *new_smb_fname = NULL;
+
if (argc != 3) {
printf("Usage: symlink <path> <link>\n");
return NT_STATUS_OK;
}
- if (SMB_VFS_SYMLINK(vfs->conn, argv[1], argv[2]) == -1) {
+ new_smb_fname = synthetic_smb_fname_split(mem_ctx,
+ argv[2],
+ lp_posix_pathnames());
+ if (new_smb_fname == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (SMB_VFS_SYMLINK(vfs->conn, argv[1], new_smb_fname) == -1) {
printf("symlink: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}