s3: VFS: Change SMB_VFS_READLINK to use const struct smb_filename * instead of const...
authorJeremy Allison <jra@samba.org>
Wed, 7 Jun 2017 22:03:37 +0000 (15:03 -0700)
committerJeremy Allison <jra@samba.org>
Sun, 18 Jun 2017 00:49:25 +0000 (02:49 +0200)
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>
21 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_cap.c
source3/modules/vfs_ceph.c
source3/modules/vfs_default.c
source3/modules/vfs_expand_msdfs.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_glusterfs.c
source3/modules/vfs_media_harmony.c
source3/modules/vfs_shadow_copy2.c
source3/modules/vfs_snapper.c
source3/modules/vfs_time_audit.c
source3/modules/vfs_unityed_media.c
source3/smbd/msdfs.c
source3/smbd/open.c
source3/smbd/proto.h
source3/smbd/trans2.c
source3/smbd/vfs.c
source3/torture/cmd_vfs.c

index ec81bdc..792f728 100644 (file)
@@ -483,8 +483,10 @@ static int skel_symlink(vfs_handle_struct *handle, const char *oldpath,
        return -1;
 }
 
-static int skel_vfs_readlink(vfs_handle_struct *handle, const char *path,
-                            char *buf, size_t bufsiz)
+static int skel_vfs_readlink(vfs_handle_struct *handle,
+                       const struct smb_filename *smb_fname,
+                       char *buf,
+                       size_t bufsiz)
 {
        errno = ENOSYS;
        return -1;
index db3ec35..11512e3 100644 (file)
@@ -576,10 +576,12 @@ static int skel_symlink(vfs_handle_struct *handle, const char *oldpath,
        return SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
 }
 
-static int skel_vfs_readlink(vfs_handle_struct *handle, const char *path,
-                            char *buf, size_t bufsiz)
+static int skel_vfs_readlink(vfs_handle_struct *handle,
+                       const struct smb_filename *smb_fname,
+                       char *buf,
+                       size_t bufsiz)
 {
-       return SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
+       return SMB_VFS_NEXT_READLINK(handle, smb_fname, buf, bufsiz);
 }
 
 static int skel_link(vfs_handle_struct *handle,
index 2f434ba..115a9dc 100644 (file)
                to const struct smb_filename * */
 /* Version 37 - Change statvfs from const char *
                to const struct smb_filename * */
+/* Version 37 - Change readlink from const char *
+               to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -744,7 +746,10 @@ struct vfs_fn_pointers {
        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 (*readlink_fn)(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz);
+       int (*readlink_fn)(struct vfs_handle_struct *handle,
+                               const struct smb_filename *smb_fname,
+                               char *buf,
+                               size_t bufsiz);
        int (*link_fn)(struct vfs_handle_struct *handle,
                                const struct smb_filename *old_smb_fname,
                                const struct smb_filename *new_smb_fname);
@@ -1249,7 +1254,9 @@ bool smb_vfs_call_getlock(struct vfs_handle_struct *handle,
 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
                         const char *newpath);
 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
-                         const char *path, char *buf, size_t bufsiz);
+                       const struct smb_filename *smb_fname,
+                       char *buf,
+                       size_t bufsiz);
 int smb_vfs_call_link(struct vfs_handle_struct *handle,
                        const struct smb_filename *old_smb_fname,
                        const struct smb_filename *new_smb_fname);
index 3404c8c..77646b4 100644 (file)
 #define SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath) \
        smb_vfs_call_symlink((handle)->next, (oldpath), (newpath))
 
-#define SMB_VFS_READLINK(conn, path, buf, bufsiz) \
-       smb_vfs_call_readlink((conn)->vfs_handles, (path), (buf), (bufsiz))
-#define SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz) \
-       smb_vfs_call_readlink((handle)->next, (path), (buf), (bufsiz))
+#define SMB_VFS_READLINK(conn, smb_fname, buf, bufsiz) \
+       smb_vfs_call_readlink((conn)->vfs_handles, (smb_fname), (buf), (bufsiz))
+#define SMB_VFS_NEXT_READLINK(handle, smb_fname, buf, bufsiz) \
+       smb_vfs_call_readlink((handle)->next, (smb_fname), (buf), (bufsiz))
 
 #define SMB_VFS_LINK(conn, oldpath, newpath) \
        smb_vfs_call_link((conn)->vfs_handles, (oldpath), (newpath))
index 7e89c09..2c21ab1 100644 (file)
@@ -492,16 +492,40 @@ static int cap_symlink(vfs_handle_struct *handle, const char *oldpath,
        return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew);
 }
 
-static int cap_readlink(vfs_handle_struct *handle, const char *path,
-                       char *buf, size_t bufsiz)
+static int cap_readlink(vfs_handle_struct *handle,
+                       const struct smb_filename *smb_fname,
+                       char *buf,
+                       size_t bufsiz)
 {
-       char *cappath = capencode(talloc_tos(), path);
+       char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+       struct smb_filename *cap_smb_fname = NULL;
+       int saved_errno = 0;
+       int ret;
 
        if (!cappath) {
                errno = ENOMEM;
                return -1;
        }
-       return SMB_VFS_NEXT_READLINK(handle, cappath, buf, bufsiz);
+       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_READLINK(handle, cap_smb_fname, buf, bufsiz);
+       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_link(vfs_handle_struct *handle,
index 638118b..3c38165 100644 (file)
@@ -1134,11 +1134,15 @@ static int cephwrap_symlink(struct vfs_handle_struct *handle,  const char *oldpa
        WRAP_RETURN(result);
 }
 
-static int cephwrap_readlink(struct vfs_handle_struct *handle,  const char *path, char *buf, size_t bufsiz)
+static int cephwrap_readlink(struct vfs_handle_struct *handle,
+               const struct smb_filename *smb_fname,
+               char *buf,
+               size_t bufsiz)
 {
        int result = -1;
-       DBG_DEBUG("[CEPH] readlink(%p, %s, %p, %llu)\n", handle, path, buf, llu(bufsiz));
-       result = ceph_readlink(handle->data, path, buf, bufsiz);
+       DBG_DEBUG("[CEPH] readlink(%p, %s, %p, %llu)\n", handle,
+                       smb_fname->base_name, buf, llu(bufsiz));
+       result = ceph_readlink(handle->data, smb_fname->base_name, buf, bufsiz);
        DBG_DEBUG("[CEPH] readlink(...) = %d\n", result);
        WRAP_RETURN(result);
 }
index 4f86537..93ff657 100644 (file)
@@ -2428,12 +2428,15 @@ static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const
        return result;
 }
 
-static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
+static int vfswrap_readlink(vfs_handle_struct *handle,
+                       const struct smb_filename *smb_fname,
+                       char *buf,
+                       size_t bufsiz)
 {
        int result;
 
        START_PROFILE(syscall_readlink);
-       result = readlink(path, buf, bufsiz);
+       result = readlink(smb_fname->base_name, buf, bufsiz);
        END_PROFILE(syscall_readlink);
        return result;
 }
index b0e5198..4cabc8f 100644 (file)
@@ -181,7 +181,9 @@ static char *expand_msdfs_target(TALLOC_CTX *ctx,
 }
 
 static int expand_msdfs_readlink(struct vfs_handle_struct *handle,
-                                const char *path, char *buf, size_t bufsiz)
+                               const struct smb_filename *smb_fname,
+                               char *buf,
+                               size_t bufsiz)
 {
        TALLOC_CTX *ctx = talloc_tos();
        int result;
@@ -197,7 +199,7 @@ static int expand_msdfs_readlink(struct vfs_handle_struct *handle,
                return -1;
        }
 
-       result = SMB_VFS_NEXT_READLINK(handle, path, target,
+       result = SMB_VFS_NEXT_READLINK(handle, smb_fname, target,
                                       PATH_MAX);
 
        if (result <= 0)
index 609ef37..408f834 100644 (file)
@@ -1639,13 +1639,16 @@ static int smb_full_audit_symlink(vfs_handle_struct *handle,
 }
 
 static int smb_full_audit_readlink(vfs_handle_struct *handle,
-                         const char *path, char *buf, size_t bufsiz)
+                       const struct smb_filename *smb_fname,
+                       char *buf,
+                       size_t bufsiz)
 {
        int result;
 
-       result = SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
+       result = SMB_VFS_NEXT_READLINK(handle, smb_fname, buf, bufsiz);
 
-       do_log(SMB_VFS_OP_READLINK, (result >= 0), handle, "%s", path);
+       do_log(SMB_VFS_OP_READLINK, (result >= 0), handle, "%s",
+                       smb_fname->base_name);
 
        return result;
 }
index 7a42d86..bf19dd7 100644 (file)
@@ -1240,9 +1240,11 @@ static int vfs_gluster_symlink(struct vfs_handle_struct *handle,
 }
 
 static int vfs_gluster_readlink(struct vfs_handle_struct *handle,
-                               const char *path, char *buf, size_t bufsiz)
+                               const struct smb_filename *smb_fname,
+                               char *buf,
+                               size_t bufsiz)
 {
-       return glfs_readlink(handle->data, path, buf, bufsiz);
+       return glfs_readlink(handle->data, smb_fname->base_name, buf, bufsiz);
 }
 
 static int vfs_gluster_link(struct vfs_handle_struct *handle,
index 420b51f..13604b3 100644 (file)
@@ -1769,34 +1769,28 @@ out:
  * Failure: set errno, return -1
  */
 static int mh_readlink(vfs_handle_struct *handle,
-               const char *path,
+               const struct smb_filename *smb_fname,
                char *buf,
                size_t bufsiz)
 {
        int status;
-       char *clientPath;
-       TALLOC_CTX *ctx;
+       struct smb_filename *clientFname = NULL;
 
        DEBUG(MH_INFO_DEBUG, ("Entering mh_readlink\n"));
-       if (!is_in_media_files(path))
-       {
-               status = SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
+       if (!is_in_media_files(smb_fname->base_name)) {
+               status = SMB_VFS_NEXT_READLINK(handle, smb_fname, buf, bufsiz);
                goto out;
        }
 
-       clientPath = NULL;
-       ctx = talloc_tos();
-
-       if ((status = alloc_get_client_path(handle, ctx,
-                               path,
-                               &clientPath)))
-       {
+       if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
+                               smb_fname,
+                               &clientFname))) {
                goto err;
        }
 
-       status = SMB_VFS_NEXT_READLINK(handle, clientPath, buf, bufsiz);
+       status = SMB_VFS_NEXT_READLINK(handle, clientFname, buf, bufsiz);
 err:
-       TALLOC_FREE(clientPath);
+       TALLOC_FREE(clientFname);
 out:
        return status;
 }
index 5481eda..2c7fcaa 100644 (file)
@@ -1633,24 +1633,34 @@ static int shadow_copy2_ntimes(vfs_handle_struct *handle,
 }
 
 static int shadow_copy2_readlink(vfs_handle_struct *handle,
-                                const char *fname, char *buf, size_t bufsiz)
+                               const struct smb_filename *smb_fname,
+                               char *buf,
+                               size_t bufsiz)
 {
        time_t timestamp = 0;
        char *stripped = NULL;
        int saved_errno = 0;
        int ret;
-       char *conv;
+       struct smb_filename *conv = NULL;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
+       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
+                                        smb_fname->base_name,
                                         &timestamp, &stripped)) {
                return -1;
        }
        if (timestamp == 0) {
-               return SMB_VFS_NEXT_READLINK(handle, fname, buf, bufsiz);
+               return SMB_VFS_NEXT_READLINK(handle, smb_fname, buf, bufsiz);
        }
-       conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
-       TALLOC_FREE(stripped);
+       conv = cp_smb_filename(talloc_tos(), smb_fname);
        if (conv == NULL) {
+               TALLOC_FREE(stripped);
+               errno = ENOMEM;
+               return -1;
+       }
+       conv->base_name = shadow_copy2_convert(
+               conv, handle, stripped, timestamp);
+       TALLOC_FREE(stripped);
+       if (conv->base_name == NULL) {
                return -1;
        }
        ret = SMB_VFS_NEXT_READLINK(handle, conv, buf, bufsiz);
index ec0c680..a413974 100644 (file)
@@ -2398,29 +2398,44 @@ static int snapper_gmt_ntimes(vfs_handle_struct *handle,
 }
 
 static int snapper_gmt_readlink(vfs_handle_struct *handle,
-                               const char *fname, char *buf, size_t bufsiz)
+                               const struct smb_filename *smb_fname,
+                               char *buf,
+                               size_t bufsiz)
 {
-       time_t timestamp;
-       char *stripped;
-       int ret, saved_errno;
-       char *conv;
+       time_t timestamp = 0;
+       char *stripped = NULL;
+       int ret;
+       int saved_errno = 0;
+       struct smb_filename *conv = NULL;
 
-       if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname,
+       if (!snapper_gmt_strip_snapshot(talloc_tos(), handle,
+                                       smb_fname->base_name,
                                        &timestamp, &stripped)) {
                return -1;
        }
        if (timestamp == 0) {
-               return SMB_VFS_NEXT_READLINK(handle, fname, buf, bufsiz);
+               return SMB_VFS_NEXT_READLINK(handle, smb_fname, buf, bufsiz);
        }
-       conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
-       TALLOC_FREE(stripped);
+       conv = cp_smb_filename(talloc_tos(), smb_fname);
        if (conv == NULL) {
+               TALLOC_FREE(stripped);
+               errno = ENOMEM;
+               return -1;
+       }
+       conv->base_name = snapper_gmt_convert(conv, handle,
+                                             stripped, timestamp);
+       TALLOC_FREE(stripped);
+       if (conv->base_name == NULL) {
                return -1;
        }
        ret = SMB_VFS_NEXT_READLINK(handle, conv, buf, bufsiz);
-       saved_errno = errno;
+       if (ret == -1) {
+               saved_errno = errno;
+       }
        TALLOC_FREE(conv);
-       errno = saved_errno;
+       if (saved_errno != 0) {
+               errno = saved_errno;
+       }
        return ret;
 }
 
index b1bf59e..58c0f79 100644 (file)
@@ -1443,19 +1443,23 @@ static int smb_time_audit_symlink(vfs_handle_struct *handle,
 }
 
 static int smb_time_audit_readlink(vfs_handle_struct *handle,
-                         const char *path, char *buf, size_t bufsiz)
+                               const struct smb_filename *smb_fname,
+                               char *buf,
+                               size_t bufsiz)
 {
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
+       result = SMB_VFS_NEXT_READLINK(handle, smb_fname,
+                               buf, bufsiz);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("readlink", timediff, path);
+               smb_time_audit_log_fname("readlink", timediff,
+                               smb_fname->base_name);
        }
 
        return result;
index b1c459a..c9ecc27 100644 (file)
@@ -1354,29 +1354,30 @@ err:
 }
 
 static int um_readlink(vfs_handle_struct *handle,
-                      const char *path,
-                      char *buf,
-                      size_t bufsiz)
+                       const struct smb_filename *smb_fname,
+                       char *buf,
+                       size_t bufsiz)
 {
        int status;
-       char *client_path = NULL;
+       struct smb_filename *client_fname = NULL;
 
        DEBUG(10, ("Entering um_readlink\n"));
 
-       if (!is_in_media_files(path)) {
-               return SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
+       if (!is_in_media_files(smb_fname->base_name)) {
+               return SMB_VFS_NEXT_READLINK(handle, smb_fname,
+                               buf, bufsiz);
        }
 
-       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_READLINK(handle, client_path, buf, bufsiz);
+       status = SMB_VFS_NEXT_READLINK(handle, client_fname, buf, bufsiz);
 
 err:
-       TALLOC_FREE(client_path);
+       TALLOC_FREE(client_fname);
        return status;
 }
 
index acb45fd..b88538c 100644 (file)
@@ -567,9 +567,8 @@ static bool parse_msdfs_symlink(TALLOC_CTX *ctx,
 
 static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
                        connection_struct *conn,
-                       const char *path,
-                       char **pp_link_target,
-                       SMB_STRUCT_STAT *sbufp)
+                       struct smb_filename *smb_fname,
+                       char **pp_link_target)
 {
        int referral_len = 0;
 #if defined(HAVE_BROKEN_READLINK)
@@ -579,7 +578,6 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
 #endif
        size_t bufsize = 0;
        char *link_target = NULL;
-       struct smb_filename smb_fname;
 
        if (pp_link_target) {
                bufsize = 1024;
@@ -593,33 +591,28 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
                link_target = link_target_buf;
        }
 
-       ZERO_STRUCT(smb_fname);
-       smb_fname.base_name = discard_const_p(char, path);
-
-       if (SMB_VFS_LSTAT(conn, &smb_fname) != 0) {
+       if (SMB_VFS_LSTAT(conn, smb_fname) != 0) {
                DEBUG(5,("is_msdfs_link_read_target: %s does not exist.\n",
-                       path));
+                       smb_fname->base_name));
                goto err;
        }
-       if (!S_ISLNK(smb_fname.st.st_ex_mode)) {
+       if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
                DEBUG(5,("is_msdfs_link_read_target: %s is not a link.\n",
-                                       path));
+                       smb_fname->base_name));
                goto err;
        }
-       if (sbufp != NULL) {
-               *sbufp = smb_fname.st;
-       }
 
-       referral_len = SMB_VFS_READLINK(conn, path, link_target, bufsize - 1);
+       referral_len = SMB_VFS_READLINK(conn, smb_fname,
+                               link_target, bufsize - 1);
        if (referral_len == -1) {
                DEBUG(0,("is_msdfs_link_read_target: Error reading "
                        "msdfs link %s: %s\n",
-                       path, strerror(errno)));
+                       smb_fname->base_name, strerror(errno)));
                goto err;
        }
        link_target[referral_len] = '\0';
 
-       DEBUG(5,("is_msdfs_link_internal: %s -> %s\n",path,
+       DEBUG(5,("is_msdfs_link_internal: %s -> %s\n", smb_fname->base_name,
                                link_target));
 
        if (!strnequal(link_target, "msdfs:", 6)) {
@@ -640,14 +633,12 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
 **********************************************************************/
 
 bool is_msdfs_link(connection_struct *conn,
-               const char *path,
-               SMB_STRUCT_STAT *sbufp)
+               struct smb_filename *smb_fname)
 {
        return is_msdfs_link_internal(talloc_tos(),
                                        conn,
-                                       path,
-                                       NULL,
-                                       sbufp);
+                                       smb_fname,
+                                       NULL);
 }
 
 /*****************************************************************
@@ -706,8 +697,7 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx,
 
        /* Optimization - check if we can redirect the whole path. */
 
-       if (is_msdfs_link_internal(ctx, conn, smb_fname->base_name,
-                                  pp_targetpath, NULL)) {
+       if (is_msdfs_link_internal(ctx, conn, smb_fname, pp_targetpath)) {
                /* XX_ALLOW_WCARD_XXX is called from search functions. */
                if (ucf_flags &
                                (UCF_COND_ALLOW_WCARD_LCOMP|
@@ -770,8 +760,7 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx,
                }
 
                if (is_msdfs_link_internal(ctx, conn,
-                                          smb_fname->base_name, pp_targetpath,
-                                          NULL)) {
+                                          smb_fname, pp_targetpath)) {
                        DEBUG(4, ("dfs_path_lookup: Redirecting %s because "
                                  "parent %s is dfs link\n", dfspath,
                                  smb_fname_str_dbg(smb_fname)));
@@ -1481,12 +1470,20 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 
        while ((dname = vfs_readdirname(conn, dirp, NULL, &talloced))
               != NULL) {
-               if (is_msdfs_link(conn,
-                               dname,
-                               NULL)) {
+               struct smb_filename *smb_dname =
+                       synthetic_smb_fname(talloc_tos(),
+                                       dname,
+                                       NULL,
+                                       NULL,
+                                       0);
+               if (smb_dname == NULL) {
+                       goto out;
+               }
+               if (is_msdfs_link(conn, smb_dname)) {
                        cnt++;
                }
                TALLOC_FREE(talloced);
+               TALLOC_FREE(smb_dname);
        }
 
        SMB_VFS_CLOSEDIR(conn,dirp);
@@ -1600,16 +1597,26 @@ static int form_junctions(TALLOC_CTX *ctx,
        while ((dname = vfs_readdirname(conn, dirp, NULL, &talloced))
               != NULL) {
                char *link_target = NULL;
+               struct smb_filename *smb_dname = NULL;
+
                if (cnt >= jn_remain) {
                        DEBUG(2, ("form_junctions: ran out of MSDFS "
                                "junction slots"));
                        TALLOC_FREE(talloced);
                        goto out;
                }
+               smb_dname = synthetic_smb_fname(talloc_tos(),
+                               dname,
+                               NULL,
+                               NULL,
+                               0);
+               if (smb_dname == NULL) {
+                       TALLOC_FREE(talloced);
+                       goto out;
+               }
                if (is_msdfs_link_internal(ctx,
                                        conn,
-                                       dname, &link_target,
-                                       NULL)) {
+                                       smb_dname, &link_target)) {
                        if (parse_msdfs_symlink(ctx, snum,
                                        link_target,
                                        &jucn[cnt].referral_list,
@@ -1630,6 +1637,7 @@ static int form_junctions(TALLOC_CTX *ctx,
                        TALLOC_FREE(link_target);
                }
                TALLOC_FREE(talloced);
+               TALLOC_FREE(smb_dname);
        }
 
 out:
index 8fdc963..e68e2ac 100644 (file)
@@ -435,7 +435,7 @@ static int process_symlink_open(struct connection_struct *conn,
 
        /* Read the link target. */
        link_len = SMB_VFS_READLINK(conn,
-                               smb_fname->base_name,
+                               smb_fname,
                                link_target,
                                PATH_MAX - 1);
        if (link_len == -1) {
index 8979729..722edf3 100644 (file)
@@ -468,8 +468,7 @@ void reply_sendend(struct smb_request *req);
 /* The following definitions come from smbd/msdfs.c  */
 
 bool is_msdfs_link(connection_struct *conn,
-               const char *path,
-               SMB_STRUCT_STAT *sbufp);
+               struct smb_filename *smb_fname);
 struct junction_map;
 NTSTATUS get_referred_path(TALLOC_CTX *ctx,
                           const char *dfs_path,
index ae41f19..8615a78 100644 (file)
@@ -1577,18 +1577,18 @@ static NTSTATUS unix_perms_from_wire( connection_struct *conn,
 ****************************************************************************/
 
 static bool check_msdfs_link(connection_struct *conn,
-                               const char *pathname,
-                               SMB_STRUCT_STAT *psbuf)
+                               struct smb_filename *smb_fname)
 {
        int saved_errno = errno;
        if(lp_host_msdfs() &&
                lp_msdfs_root(SNUM(conn)) &&
-               is_msdfs_link(conn, pathname, psbuf)) {
+               is_msdfs_link(conn, smb_fname)) {
 
                DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
                        "as a directory\n",
-                       pathname));
-               psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR;
+                       smb_fname->base_name));
+               smb_fname->st.st_ex_mode =
+                       (smb_fname->st.st_ex_mode & 0xFFF) | S_IFDIR;
                errno = saved_errno;
                return true;
        }
@@ -1729,8 +1729,7 @@ static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX *ctx,
                 * directories */
 
                ms_dfs_link = check_msdfs_link(state->conn,
-                                              smb_fname->base_name,
-                                              &smb_fname->st);
+                                              smb_fname);
                if (!ms_dfs_link) {
                        DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
                                 "Couldn't stat [%s] (%s)\n",
@@ -5483,7 +5482,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                                return NT_STATUS_DOS(ERRDOS, ERRbadlink);
 #endif
                                link_len = SMB_VFS_READLINK(conn,
-                                                      smb_fname->base_name,
+                                                      smb_fname,
                                                       buffer, PATH_MAX);
                                if (link_len == -1) {
                                        return map_nt_error_from_unix(errno);
index acfc705..bed3d2c 100644 (file)
@@ -2160,10 +2160,12 @@ int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
 }
 
 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
-                             const char *path, char *buf, size_t bufsiz)
+                       const struct smb_filename *smb_fname,
+                       char *buf,
+                       size_t bufsiz)
 {
        VFS_FIND(readlink);
-       return handle->fns->readlink_fn(handle, path, buf, bufsiz);
+       return handle->fns->readlink_fn(handle, smb_fname, buf, bufsiz);
 }
 
 int smb_vfs_call_link(struct vfs_handle_struct *handle,
index 38d8746..47e365a 100644 (file)
@@ -1231,6 +1231,7 @@ static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
 static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        char buffer[PATH_MAX];
+       struct smb_filename *smb_fname = NULL;
        int size;
 
        if (argc != 2) {
@@ -1238,7 +1239,14 @@ static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
                return NT_STATUS_OK;
        }
 
-       if ((size = SMB_VFS_READLINK(vfs->conn, argv[1], buffer, PATH_MAX)) == -1) {
+       smb_fname = synthetic_smb_fname_split(mem_ctx,
+                                       argv[1],
+                                       lp_posix_pathnames());
+       if (smb_fname == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       if ((size = SMB_VFS_READLINK(vfs->conn, smb_fname,
+                               buffer, PATH_MAX)) == -1) {
                printf("readlink: error=%d (%s)\n", errno, strerror(errno));
                return NT_STATUS_UNSUCCESSFUL;
        }