From 7cd46f95dfa3872536fe98a4e158fdc6ab212b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Sun, 8 Mar 2020 10:03:23 +0100 Subject: [PATCH] Fixed object types returned in readdir() for reparse points The types of reparse point objects cannot be decided upon the data available in a directory, so we must delegate their determination to a specific plugin when available, and be consistent if there is none. --- include/ntfs-3g/dir.h | 1 + libntfs-3g/dir.c | 8 ++++---- src/lowntfs-3g.c | 27 +++++++++++++++++++++++++-- src/ntfs-3g.c | 27 +++++++++++++++++++++++++-- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/include/ntfs-3g/dir.h b/include/ntfs-3g/dir.h index e6a2c3b1..ced83f43 100644 --- a/include/ntfs-3g/dir.h +++ b/include/ntfs-3g/dir.h @@ -94,6 +94,7 @@ extern int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name, #define NTFS_DT_LNK 10 #define NTFS_DT_SOCK 12 #define NTFS_DT_WHT 14 +#define NTFS_DT_REPARSE 32 /* * This is the "ntfs_filldir" function type, used by ntfs_readdir() to let diff --git a/libntfs-3g/dir.c b/libntfs-3g/dir.c index a66f807f..0721e782 100644 --- a/libntfs-3g/dir.c +++ b/libntfs-3g/dir.c @@ -5,7 +5,7 @@ * Copyright (c) 2004-2005 Richard Russon * Copyright (c) 2004-2008 Szabolcs Szakacsits * Copyright (c) 2005-2007 Yura Pakhuchiy - * Copyright (c) 2008-2014 Jean-Pierre Andre + * Copyright (c) 2008-2020 Jean-Pierre Andre * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -934,9 +934,9 @@ static u32 ntfs_dir_entry_type(ntfs_inode *dir_ni, MFT_REF mref, dt_type = NTFS_DT_UNKNOWN; ni = ntfs_inode_open(dir_ni->vol, mref); if (ni) { - if ((attributes & FILE_ATTR_REPARSE_POINT) - && ntfs_possible_symlink(ni)) - dt_type = NTFS_DT_LNK; + if (attributes & FILE_ATTR_REPARSE_POINT) + dt_type = (ntfs_possible_symlink(ni) + ? NTFS_DT_LNK : NTFS_DT_REPARSE); else if ((attributes & FILE_ATTR_SYSTEM) && !(attributes & FILE_ATTR_I30_INDEX_PRESENT)) diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c index 78d6e29c..b0ef839d 100644 --- a/src/lowntfs-3g.c +++ b/src/lowntfs-3g.c @@ -4,7 +4,7 @@ * Copyright (c) 2005-2007 Yura Pakhuchiy * Copyright (c) 2005 Yuval Fledel * Copyright (c) 2006-2009 Szabolcs Szakacsits - * Copyright (c) 2007-2019 Jean-Pierre Andre + * Copyright (c) 2007-2020 Jean-Pierre Andre * Copyright (c) 2009 Erik Larsson * * This file is originated from the Linux-NTFS project. @@ -259,7 +259,7 @@ static const char *usage_msg = "\n" "Copyright (C) 2005-2007 Yura Pakhuchiy\n" "Copyright (C) 2006-2009 Szabolcs Szakacsits\n" -"Copyright (C) 2007-2019 Jean-Pierre Andre\n" +"Copyright (C) 2007-2020 Jean-Pierre Andre\n" "Copyright (C) 2009 Erik Larsson\n" "\n" "Usage: %s [-o option[,...]] \n" @@ -1167,6 +1167,9 @@ static int ntfs_fuse_filler(ntfs_fuse_fill_context_t *fill_ctx, /* never return inodes 0 and 1 */ if (MREF(mref) > 1) { struct stat st = { .st_ino = MREF(mref) }; +#ifndef DISABLE_PLUGINS + ntfs_inode *ni; +#endif /* DISABLE_PLUGINS */ switch (dt_type) { case NTFS_DT_DIR : @@ -1187,6 +1190,26 @@ static int ntfs_fuse_filler(ntfs_fuse_fill_context_t *fill_ctx, case NTFS_DT_CHR : st.st_mode = S_IFCHR; break; + case NTFS_DT_REPARSE : + st.st_mode = S_IFLNK | 0777; /* default */ +#ifndef DISABLE_PLUGINS + /* get emulated type from plugin if available */ + ni = ntfs_inode_open(ctx->vol, mref); + if (ni && (ni->flags & FILE_ATTR_REPARSE_POINT)) { + const plugin_operations_t *ops; + REPARSE_POINT *reparse; + int res; + + res = CALL_REPARSE_PLUGIN(ni, getattr, &st); + if (!res) + apply_umask(&st); + else + st.st_mode = S_IFLNK; + } + if (ni) + ntfs_inode_close(ni); +#endif /* DISABLE_PLUGINS */ + break; default : /* unexpected types shown as plain files */ case NTFS_DT_REG : st.st_mode = S_IFREG | (0777 & ~ctx->fmask); diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index 5b3cfc8d..cacb1b92 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -4,7 +4,7 @@ * Copyright (c) 2005-2007 Yura Pakhuchiy * Copyright (c) 2005 Yuval Fledel * Copyright (c) 2006-2009 Szabolcs Szakacsits - * Copyright (c) 2007-2019 Jean-Pierre Andre + * Copyright (c) 2007-2020 Jean-Pierre Andre * Copyright (c) 2009 Erik Larsson * * This file is originated from the Linux-NTFS project. @@ -196,7 +196,7 @@ static const char *usage_msg = "\n" "Copyright (C) 2005-2007 Yura Pakhuchiy\n" "Copyright (C) 2006-2009 Szabolcs Szakacsits\n" -"Copyright (C) 2007-2019 Jean-Pierre Andre\n" +"Copyright (C) 2007-2020 Jean-Pierre Andre\n" "Copyright (C) 2009 Erik Larsson\n" "\n" "Usage: %s [-o option[,...]] \n" @@ -1199,6 +1199,9 @@ static int ntfs_fuse_filler(ntfs_fuse_fill_context_t *fill_ctx, return 0; } else { struct stat st = { .st_ino = MREF(mref) }; +#ifndef DISABLE_PLUGINS + ntfs_inode *ni; +#endif /* DISABLE_PLUGINS */ switch (dt_type) { case NTFS_DT_DIR : @@ -1219,6 +1222,26 @@ static int ntfs_fuse_filler(ntfs_fuse_fill_context_t *fill_ctx, case NTFS_DT_CHR : st.st_mode = S_IFCHR; break; + case NTFS_DT_REPARSE : + st.st_mode = S_IFLNK | 0777; /* default */ +#ifndef DISABLE_PLUGINS + /* get emulated type from plugin if available */ + ni = ntfs_inode_open(ctx->vol, mref); + if (ni && (ni->flags & FILE_ATTR_REPARSE_POINT)) { + const plugin_operations_t *ops; + REPARSE_POINT *reparse; + int res; + + res = CALL_REPARSE_PLUGIN(ni, getattr, &st); + if (!res) + apply_umask(&st); + else + st.st_mode = S_IFLNK; + } + if (ni) + ntfs_inode_close(ni); +#endif /* DISABLE_PLUGINS */ + break; default : /* unexpected types shown as plain files */ case NTFS_DT_REG : st.st_mode = S_IFREG | (0777 & ~ctx->fmask);