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;
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,
/* 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
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,
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,
#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))
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);
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)
}
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;
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;
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;
}
}
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);
}
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 *);
}
}
static char *shadow_copy2_realpath(vfs_handle_struct *handle,
- const char *fname, char *resolved_path)
+ const char *fname)
{
const char *gmt;
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,
}
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;
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 */
}
/****************************************************************************
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) {
}
}
-#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);
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) {
"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:
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;
}
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;
}
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;
}
}
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);
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;
}
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,
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 <path>\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;
}