From 2b788aa6ce41c5c0a6892cb412cf40a7cbc73f2a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Nov 2010 16:29:26 -0800 Subject: [PATCH] Move the uglyness of #ifdef REALPATH_TAKES_NULL into the vfs_default module, change the signature of VFS_REALPATH to always return a malloc'ed string. Needed to make some privileges work I plan on doing shortly easier to code. Jeremy. Autobuild-User: Jeremy Allison Autobuild-Date: Sat Nov 20 02:15:50 CET 2010 on sn-devel-104 --- examples/VFS/skel_opaque.c | 2 +- examples/VFS/skel_transparent.c | 4 +- source3/include/vfs.h | 7 ++-- source3/include/vfs_macros.h | 8 ++-- source3/modules/vfs_cap.c | 4 +- source3/modules/vfs_catia.c | 5 +-- source3/modules/vfs_default.c | 17 +++++++- source3/modules/vfs_full_audit.c | 4 +- source3/modules/vfs_onefs_shadow_copy.c | 5 +-- source3/modules/vfs_shadow_copy2.c | 6 +-- source3/modules/vfs_time_audit.c | 4 +- source3/smbd/service.c | 11 +----- source3/smbd/vfs.c | 52 +++++-------------------- source3/torture/cmd_vfs.c | 4 +- 14 files changed, 51 insertions(+), 82 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index a7814957de0..42f4e48cd90 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -356,7 +356,7 @@ static int skel_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, return -1; } -static char *skel_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path) +static char *skel_realpath(vfs_handle_struct *handle, const char *path) { errno = ENOSYS; return NULL; diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 3be5cf93369..42e54a8871d 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -332,9 +332,9 @@ static int skel_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, return SMB_VFS_NEXT_MKNOD(handle, path, mode, dev); } -static char *skel_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path) +static char *skel_realpath(vfs_handle_struct *handle, const char *path) { - return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path); + return SMB_VFS_NEXT_REALPATH(handle, path); } static NTSTATUS skel_notify_watch(struct vfs_handle_struct *handle, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 9ec4c3ec69c..9121069a276 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -126,6 +126,8 @@ /* Leave at 27 - not yet released. Add translate_name VFS call to convert UNIX names to Windows supported names -- asrinivasan. */ /* Changed to version 28 - Add private_flags uint32_t to CREATE call. */ +/* Leave at 28 - not yet released. Change realpath to assume NULL and return a + malloc'ed path. JRA. */ #define SMB_VFS_INTERFACE_VERSION 28 @@ -257,7 +259,7 @@ struct vfs_fn_pointers { int (*vfs_readlink)(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz); int (*link)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath); int (*mknod)(struct vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev); - char *(*realpath)(struct vfs_handle_struct *handle, const char *path, char *resolved_path); + char *(*realpath)(struct vfs_handle_struct *handle, const char *path); NTSTATUS (*notify_watch)(struct vfs_handle_struct *handle, struct sys_notify_context *ctx, struct notify_entry *e, @@ -619,8 +621,7 @@ int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath); int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev); -char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, - const char *path, char *resolved_path); +char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path); NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle, struct sys_notify_context *ctx, struct notify_entry *e, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 4472e3a52ab..5b38e64cbfd 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -289,10 +289,10 @@ #define SMB_VFS_NEXT_MKNOD(handle, path, mode, dev) \ smb_vfs_call_mknod((handle)->next, (path), (mode), (dev)) -#define SMB_VFS_REALPATH(conn, path, resolved_path) \ - smb_vfs_call_realpath((conn)->vfs_handles, (path), (resolved_path)) -#define SMB_VFS_NEXT_REALPATH(handle, path, resolved_path) \ - smb_vfs_call_realpath((handle)->next, (path), (resolved_path)) +#define SMB_VFS_REALPATH(conn, path) \ + smb_vfs_call_realpath((conn)->vfs_handles, (path)) +#define SMB_VFS_NEXT_REALPATH(handle, path) \ + smb_vfs_call_realpath((handle)->next, (path)) #define SMB_VFS_NOTIFY_WATCH(conn, ctx, e, callback, private_data, handle_p) \ smb_vfs_call_notify_watch((conn)->vfs_handles, (ctx), (e), (callback), (private_data), (handle_p)) diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 35fa740dd09..89f16891a9b 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -384,7 +384,7 @@ static int cap_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, S return SMB_VFS_NEXT_MKNOD(handle, cappath, mode, dev); } -static char *cap_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path) +static char *cap_realpath(vfs_handle_struct *handle, const char *path) { /* monyo need capencode'ed and capdecode'ed? */ char *cappath = capencode(talloc_tos(), path); @@ -393,7 +393,7 @@ static char *cap_realpath(vfs_handle_struct *handle, const char *path, char *res errno = ENOMEM; return NULL; } - return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path); + return SMB_VFS_NEXT_REALPATH(handle, cappath); } static int cap_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode) diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index 177458bce28..af6efd28df7 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -634,8 +634,7 @@ static int catia_ntimes(vfs_handle_struct *handle, } static char * -catia_realpath(vfs_handle_struct *handle, const char *path, - char *resolved_path) +catia_realpath(vfs_handle_struct *handle, const char *path) { char *mapped_name = NULL; NTSTATUS status; @@ -648,7 +647,7 @@ catia_realpath(vfs_handle_struct *handle, const char *path, return NULL; } - ret = SMB_VFS_NEXT_REALPATH(handle, mapped_name, resolved_path); + ret = SMB_VFS_NEXT_REALPATH(handle, mapped_name); TALLOC_FREE(mapped_name); return ret; diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 6f5b09a5a9c..eb0e0b95a64 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1064,12 +1064,25 @@ static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_ return result; } -static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path) +static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path) { char *result; START_PROFILE(syscall_realpath); - result = realpath(path, resolved_path); +#ifdef REALPATH_TAKES_NULL + result = realpath(path, NULL); +#else + result = SMB_MALLOC_ARRAY(char, PATH_MAX+1); + if (result) { + char *resolved_path = realpath(path, result); + if (!resolved_path) { + SAFE_FREE(result); + } else { + /* SMB_ASSERT(result == resovled_path) ? */ + result = resolved_path; + } + } +#endif END_PROFILE(syscall_realpath); return result; } diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 23ca1496bf8..3328128d861 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -1324,11 +1324,11 @@ static int smb_full_audit_mknod(vfs_handle_struct *handle, } static char *smb_full_audit_realpath(vfs_handle_struct *handle, - const char *path, char *resolved_path) + const char *path) { char *result; - result = SMB_VFS_NEXT_REALPATH(handle, path, resolved_path); + result = SMB_VFS_NEXT_REALPATH(handle, path); do_log(SMB_VFS_OP_REALPATH, (result != NULL), handle, "%s", path); diff --git a/source3/modules/vfs_onefs_shadow_copy.c b/source3/modules/vfs_onefs_shadow_copy.c index cf84e581713..bcc40f0d9fa 100644 --- a/source3/modules/vfs_onefs_shadow_copy.c +++ b/source3/modules/vfs_onefs_shadow_copy.c @@ -471,11 +471,10 @@ onefs_shadow_copy_mknod(vfs_handle_struct *handle, const char *path, } static char * -onefs_shadow_copy_realpath(vfs_handle_struct *handle, const char *path, - char *resolved_path) +onefs_shadow_copy_realpath(vfs_handle_struct *handle, const char *path) { SHADOW_NEXT(REALPATH, - (handle, cpath ?: path, resolved_path), + (handle, cpath ?: path), char *); } diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 502f815235c..ba6b3441b86 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -653,7 +653,7 @@ static int shadow_copy2_mknod(vfs_handle_struct *handle, } static char *shadow_copy2_realpath(vfs_handle_struct *handle, - const char *fname, char *resolved_path) + const char *fname) { const char *gmt; @@ -671,10 +671,10 @@ static char *shadow_copy2_realpath(vfs_handle_struct *handle, copy[gmt - fname + 1] = '\0'; DEBUG(10, ("calling NEXT_REALPATH with %s\n", copy)); - SHADOW2_NEXT(REALPATH, (handle, name, resolved_path), char *, + SHADOW2_NEXT(REALPATH, (handle, copy), char *, NULL); } - SHADOW2_NEXT(REALPATH, (handle, name, resolved_path), char *, NULL); + SHADOW2_NEXT(REALPATH, (handle, name), char *, NULL); } static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle, diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 84e41753ed9..af4fd3313a2 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -1066,14 +1066,14 @@ static int smb_time_audit_mknod(vfs_handle_struct *handle, } static char *smb_time_audit_realpath(vfs_handle_struct *handle, - const char *path, char *resolved_path) + const char *path) { char *result; struct timespec ts1,ts2; double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_REALPATH(handle, path, resolved_path); + result = SMB_VFS_NEXT_REALPATH(handle, path); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 5b6d9087a3b..a58f17c0703 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -26,23 +26,14 @@ extern userdom_struct current_user_info; static bool canonicalize_connect_path(connection_struct *conn) { -#ifdef REALPATH_TAKES_NULL bool ret; - char *resolved_name = SMB_VFS_REALPATH(conn,conn->connectpath,NULL); + char *resolved_name = SMB_VFS_REALPATH(conn,conn->connectpath); if (!resolved_name) { return false; } ret = set_conn_connectpath(conn,resolved_name); SAFE_FREE(resolved_name); return ret; -#else - char resolved_name_buf[PATH_MAX+1]; - char *resolved_name = SMB_VFS_REALPATH(conn,conn->connectpath,resolved_name_buf); - if (!resolved_name) { - return false; - } - return set_conn_connectpath(conn,resolved_name); -#endif /* REALPATH_TAKES_NULL */ } /**************************************************************************** diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index d516456f8db..7042518ce20 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -841,22 +841,12 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn) NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) { -#ifdef REALPATH_TAKES_NULL - bool free_resolved_name = True; -#else - char resolved_name_buf[PATH_MAX+1]; - bool free_resolved_name = False; -#endif char *resolved_name = NULL; char *p = NULL; DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath)); -#ifdef REALPATH_TAKES_NULL - resolved_name = SMB_VFS_REALPATH(conn,fname,NULL); -#else - resolved_name = SMB_VFS_REALPATH(conn,fname,resolved_name_buf); -#endif + resolved_name = SMB_VFS_REALPATH(conn,fname); if (!resolved_name) { switch (errno) { @@ -889,11 +879,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) } } -#ifdef REALPATH_TAKES_NULL - resolved_name = SMB_VFS_REALPATH(conn,tmp_fname,NULL); -#else - resolved_name = SMB_VFS_REALPATH(conn,tmp_fname,resolved_name_buf); -#endif + resolved_name = SMB_VFS_REALPATH(conn,tmp_fname); if (!resolved_name) { NTSTATUS status = map_nt_error_from_unix(errno); @@ -915,7 +901,6 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) if (!tmp_fname) { return NT_STATUS_NO_MEMORY; } -#ifdef REALPATH_TAKES_NULL SAFE_FREE(resolved_name); resolved_name = SMB_STRDUP(tmp_fname); if (!resolved_name) { @@ -923,10 +908,6 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) "fail for %s\n", tmp_fname)); return NT_STATUS_NO_MEMORY; } -#else - safe_strcpy(resolved_name_buf, tmp_fname, PATH_MAX); - resolved_name = resolved_name_buf; -#endif break; } default: @@ -942,9 +923,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) if (*resolved_name != '/') { DEBUG(0,("check_reduced_name: realpath doesn't return " "absolute paths !\n")); - if (free_resolved_name) { - SAFE_FREE(resolved_name); - } + SAFE_FREE(resolved_name); return NT_STATUS_OBJECT_NAME_INVALID; } @@ -956,9 +935,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) if (conn_rootdir == NULL) { DEBUG(2, ("check_reduced_name: Could not get " "conn_rootdir\n")); - if (free_resolved_name) { - SAFE_FREE(resolved_name); - } + SAFE_FREE(resolved_name); return NT_STATUS_ACCESS_DENIED; } @@ -967,9 +944,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) DEBUG(2, ("check_reduced_name: Bad access " "attempt: %s is a symlink outside the " "share path\n", fname)); - if (free_resolved_name) { - SAFE_FREE(resolved_name); - } + SAFE_FREE(resolved_name); return NT_STATUS_ACCESS_DENIED; } } @@ -986,17 +961,13 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { - if (free_resolved_name) { - SAFE_FREE(resolved_name); - } + SAFE_FREE(resolved_name); return status; } if ( (SMB_VFS_LSTAT(conn, smb_fname) != -1) && (S_ISLNK(smb_fname->st.st_ex_mode)) ) { - if (free_resolved_name) { - SAFE_FREE(resolved_name); - } + SAFE_FREE(resolved_name); DEBUG(3,("check_reduced_name: denied: file path name " "%s is a symlink\n",resolved_name)); TALLOC_FREE(smb_fname); @@ -1008,9 +979,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname, resolved_name)); - if (free_resolved_name) { - SAFE_FREE(resolved_name); - } + SAFE_FREE(resolved_name); return NT_STATUS_OK; } @@ -1486,11 +1455,10 @@ int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path, return handle->fns->mknod(handle, path, mode, dev); } -char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, - const char *path, char *resolved_path) +char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path) { VFS_FIND(realpath); - return handle->fns->realpath(handle, path, resolved_path); + return handle->fns->realpath(handle, path); } NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle, diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index cd550a4f484..ea5004ce639 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -1128,14 +1128,12 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, static NTSTATUS cmd_realpath(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - char respath[PATH_MAX]; - if (argc != 2) { printf("Usage: realpath \n"); return NT_STATUS_OK; } - if (SMB_VFS_REALPATH(vfs->conn, argv[1], respath) == NULL) { + if (SMB_VFS_REALPATH(vfs->conn, argv[1]) == NULL) { printf("realpath: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } -- 2.34.1