2 * ntfs-3g - Third Generation NTFS Driver
4 * Copyright (c) 2005-2007 Yura Pakhuchiy
5 * Copyright (c) 2005 Yuval Fledel
6 * Copyright (c) 2006-2009 Szabolcs Szakacsits
7 * Copyright (c) 2007-2009 Jean-Pierre Andre
8 * Copyright (c) 2009 Erik Larsson
10 * This file is originated from the Linux-NTFS project.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program (in the main directory of the NTFS-3G
24 * distribution in the file COPYING); if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #if !defined(FUSE_VERSION) || (FUSE_VERSION < 26)
33 #error "***********************************************************"
35 #error "* Compilation requires at least FUSE version 2.6.0! *"
37 #error "***********************************************************"
41 #define FUSE_TYPE "integrated FUSE"
43 #define FUSE_TYPE "external FUSE"
76 #include <sys/xattr.h>
79 #ifdef HAVE_SYS_TYPES_H
80 #include <sys/types.h>
82 #ifdef HAVE_SYS_MKDEV_H
83 #include <sys/mkdev.h>
86 #if defined(__APPLE__) || defined(__DARWIN__)
87 #include <sys/dirent.h>
88 #endif /* defined(__APPLE__) || defined(__DARWIN__) */
105 #define set_archive(ni) (ni)->flags |= FILE_ATTR_ARCHIVE
121 fuse_fill_dir_t filler
;
123 } ntfs_fuse_fill_context_t
;
126 NF_STREAMS_INTERFACE_NONE
, /* No access to named data streams. */
127 NF_STREAMS_INTERFACE_XATTR
, /* Map named data streams to xattrs. */
128 NF_STREAMS_INTERFACE_OPENXATTR
, /* Same, not limited to "user." */
129 NF_STREAMS_INTERFACE_WINDOWS
, /* "file:stream" interface. */
130 } ntfs_fuse_streams_interface
;
133 CLOSE_COMPRESSED
= 1,
143 ntfs_fuse_streams_interface streams
;
155 struct fuse_chan
*fc
;
157 unsigned int secure_flags
;
159 struct PERMISSIONS_CACHE
*seccache
;
160 struct SECURITY_CONTEXT security
;
161 } ntfs_fuse_context_t
;
163 static struct options
{
164 char *mnt_point
; /* Mount point */
165 char *options
; /* Mount options */
166 char *device
; /* Device to mount */
169 static const char *EXEC_NAME
= "ntfs-3g";
170 static char def_opts
[] = "silent,allow_other,nonempty,";
171 static ntfs_fuse_context_t
*ctx
;
172 static u32 ntfs_sequence
;
174 static const char *usage_msg
=
176 "%s %s %s %d - Third Generation NTFS Driver\n"
184 "POSIX ACLS are on\n"
186 "POSIX ACLS are off\n"
189 "Copyright (C) 2005-2007 Yura Pakhuchiy\n"
190 "Copyright (C) 2006-2009 Szabolcs Szakacsits\n"
191 "Copyright (C) 2007-2009 Jean-Pierre Andre\n"
192 "Copyright (C) 2009 Erik Larsson\n"
194 "Usage: %s [-o option[,...]] <device|image_file> <mount_point>\n"
196 "Options: ro (read-only mount), remove_hiberfile, uid=, gid=,\n"
197 " umask=, fmask=, dmask=, streams_interface=.\n"
198 " Please see the details in the manual (type: man ntfs-3g).\n"
200 "Example: ntfs-3g /dev/sda1 /mnt/windows\n"
204 static const char ntfs_bad_reparse
[] = "unsupported reparse point";
207 int drop_privs(void);
208 int restore_privs(void);
211 * setuid and setgid root ntfs-3g denies to start with external FUSE,
212 * therefore the below functions are no-op in such case.
214 static int drop_privs(void) { return 0; }
215 static int restore_privs(void) { return 0; }
217 static const char *setuid_msg
=
218 "Mount is denied because setuid and setgid root ntfs-3g is insecure with the\n"
219 "external FUSE library. Either remove the setuid/setgid bit from the binary\n"
220 "or rebuild NTFS-3G with integrated FUSE support and make it setuid root.\n"
221 "Please see more information at http://ntfs-3g.org/support.html#unprivileged\n";
223 static const char *unpriv_fuseblk_msg
=
224 "Unprivileged user can not mount NTFS block devices using the external FUSE\n"
225 "library. Either mount the volume as root, or rebuild NTFS-3G with integrated\n"
226 "FUSE support and make it setuid root. Please see more information at\n"
227 "http://ntfs-3g.org/support.html#unprivileged\n";
232 * ntfs_fuse_is_named_data_stream - check path to be to named data stream
233 * @path: path to check
235 * Returns 1 if path is to named data stream or 0 otherwise.
237 static int ntfs_fuse_is_named_data_stream(const char *path
)
239 if (strchr(path
, ':') && ctx
->streams
== NF_STREAMS_INTERFACE_WINDOWS
)
244 static void ntfs_fuse_update_times(ntfs_inode
*ni
, ntfs_time_update_flags mask
)
246 if (ctx
->atime
== ATIME_DISABLED
)
247 mask
&= ~NTFS_UPDATE_ATIME
;
248 else if (ctx
->atime
== ATIME_RELATIVE
&& mask
== NTFS_UPDATE_ATIME
&&
249 ni
->last_access_time
>= ni
->last_data_change_time
&&
250 ni
->last_access_time
>= ni
->last_mft_change_time
)
252 ntfs_inode_update_times(ni
, mask
);
255 static s64
ntfs_get_nr_free_mft_records(ntfs_volume
*vol
)
257 ntfs_attr
*na
= vol
->mftbmp_na
;
258 s64 nr_free
= ntfs_attr_get_free_bits(na
);
261 nr_free
+= (na
->allocated_size
- na
->data_size
) << 3;
266 * Fill a security context as needed by security functions
267 * returns TRUE if there is a user mapping,
268 * FALSE if there is none
269 * This is not an error and the context is filled anyway,
270 * it is used for implicit Windows-like inheritance
273 static BOOL
ntfs_fuse_fill_security_context(struct SECURITY_CONTEXT
*scx
)
275 struct fuse_context
*fusecontext
;
278 scx
->mapping
[MAPUSERS
] = ctx
->security
.mapping
[MAPUSERS
];
279 scx
->mapping
[MAPGROUPS
] = ctx
->security
.mapping
[MAPGROUPS
];
280 scx
->pseccache
= &ctx
->seccache
;
281 fusecontext
= fuse_get_context();
282 scx
->uid
= fusecontext
->uid
;
283 scx
->gid
= fusecontext
->gid
;
284 scx
->tid
= fusecontext
->pid
;
285 #ifdef FUSE_CAP_DONT_MASK
286 /* the umask can be processed by the file system */
287 scx
->umask
= fusecontext
->umask
;
289 /* the umask if forced by fuse on creation */
293 return (ctx
->security
.mapping
[MAPUSERS
] != (struct MAPPING
*)NULL
);
297 * ntfs_fuse_statfs - return information about mounted NTFS volume
298 * @path: ignored (but fuse requires it)
299 * @sfs: statfs structure in which to return the information
301 * Return information about the mounted NTFS volume @sb in the statfs structure
302 * pointed to by @sfs (this is initialized with zeros before ntfs_statfs is
303 * called). We interpret the values to be correct of the moment in time at
304 * which we are called. Most values are variable otherwise and this isn't just
305 * the free values but the totals as well. For example we can increase the
306 * total number of file nodes if we run out and we can keep doing this until
307 * there is no more space on the volume left at all.
309 * This code based on ntfs_statfs from ntfs kernel driver.
311 * Returns 0 on success or -errno on error.
313 static int ntfs_fuse_statfs(const char *path
__attribute__((unused
)),
325 * File system block size. Used to calculate used/free space by df.
326 * Incorrectly documented as "optimal transfer block size".
328 sfs
->f_bsize
= vol
->cluster_size
;
330 /* Fundamental file system block size, used as the unit. */
331 sfs
->f_frsize
= vol
->cluster_size
;
334 * Total number of blocks on file system in units of f_frsize.
335 * Since inodes are also stored in blocks ($MFT is a file) hence
336 * this is the number of clusters on the volume.
338 sfs
->f_blocks
= vol
->nr_clusters
;
340 /* Free blocks available for all and for non-privileged processes. */
341 size
= vol
->free_clusters
;
344 sfs
->f_bavail
= sfs
->f_bfree
= size
;
346 /* Free inodes on the free space */
347 delta_bits
= vol
->cluster_size_bits
- vol
->mft_record_size_bits
;
351 size
>>= -delta_bits
;
353 /* Number of inodes at this point in time. */
354 sfs
->f_files
= (vol
->mftbmp_na
->allocated_size
<< 3) + size
;
356 /* Free inodes available for all and for non-privileged processes. */
357 size
+= vol
->free_mft_records
;
360 sfs
->f_ffree
= sfs
->f_favail
= size
;
362 /* Maximum length of filenames. */
363 sfs
->f_namemax
= NTFS_MAX_NAME_LEN
;
368 * ntfs_fuse_parse_path - split path to path and stream name.
369 * @org_path: path to split
370 * @path: pointer to buffer in which parsed path saved
371 * @stream_name: pointer to buffer where stream name in unicode saved
373 * This function allocates buffers for @*path and @*stream, user must free them
377 * <0 Error occurred, return -errno;
378 * 0 No stream name, @*stream is not allocated and set to AT_UNNAMED.
379 * >0 Stream name length in unicode characters.
381 static int ntfs_fuse_parse_path(const char *org_path
, char **path
,
382 ntfschar
**stream_name
)
384 char *stream_name_mbs
;
387 stream_name_mbs
= strdup(org_path
);
388 if (!stream_name_mbs
)
390 if (ctx
->streams
== NF_STREAMS_INTERFACE_WINDOWS
) {
391 *path
= strsep(&stream_name_mbs
, ":");
392 if (stream_name_mbs
) {
394 res
= ntfs_mbstoucs(stream_name_mbs
, stream_name
);
400 *path
= stream_name_mbs
;
401 *stream_name
= AT_UNNAMED
;
405 static void set_fuse_error(int *err
)
411 #if defined(__APPLE__) || defined(__DARWIN__)
412 static void *ntfs_macfuse_init(struct fuse_conn_info
*conn
)
414 FUSE_ENABLE_XTIMES(conn
);
418 static int ntfs_macfuse_getxtimes(const char *org_path
,
419 struct timespec
*bkuptime
, struct timespec
*crtime
)
424 ntfschar
*stream_name
;
427 stream_name_len
= ntfs_fuse_parse_path(org_path
, &path
, &stream_name
);
428 if (stream_name_len
< 0)
429 return stream_name_len
;
430 memset(bkuptime
, 0, sizeof(struct timespec
));
431 memset(crtime
, 0, sizeof(struct timespec
));
432 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
438 /* We have no backup timestamp in NTFS. */
439 crtime
->tv_sec
= ni
->creation_time
;
441 if (ntfs_inode_close(ni
))
442 set_fuse_error(&res
);
449 int ntfs_macfuse_setcrtime(const char *path
, const struct timespec
*tv
)
454 if (ntfs_fuse_is_named_data_stream(path
))
455 return -EINVAL
; /* n/a for named data streams. */
456 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
461 ni
->creation_time
= tv
->tv_sec
;
462 ntfs_fuse_update_times(ni
, NTFS_UPDATE_CTIME
);
465 if (ntfs_inode_close(ni
))
466 set_fuse_error(&res
);
470 int ntfs_macfuse_setbkuptime(const char *path
, const struct timespec
*tv
)
475 if (ntfs_fuse_is_named_data_stream(path
))
476 return -EINVAL
; /* n/a for named data streams. */
477 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
482 * Only pretending to set backup time successfully to please the APIs of
483 * Mac OS X. In reality, NTFS has no backup time.
486 if (ntfs_inode_close(ni
))
487 set_fuse_error(&res
);
491 int ntfs_macfuse_setchgtime(const char *path
, const struct timespec
*tv
)
496 if (ntfs_fuse_is_named_data_stream(path
))
497 return -EINVAL
; /* n/a for named data streams. */
498 ni
= ntfs_pathname_to_inode(ctx
->
;vol
, NULL
, path
);
503 ni
->
;last_mft_change_time
= tv
->
;tv_sec
;
504 ntfs_fuse_update_times(ni
, 0);
507 if (ntfs_inode_close(ni
))
508 set_fuse_error(&
;res
);
511 #else /* defined(__APPLE__) || defined(__DARWIN__) */
512 #ifdef FUSE_CAP_DONT_MASK
513 static void *ntfs_init(struct fuse_conn_info
*conn
)
515 /* request umask not to be enforced by fuse */
516 conn
->want
|= FUSE_CAP_DONT_MASK
;
520 #endif /* defined(__APPLE__) || defined(__DARWIN__) */
522 static int ntfs_fuse_getattr(const char *org_path
, struct stat
*stbuf
)
528 ntfschar
*stream_name
;
530 BOOL withusermapping
;
531 struct SECURITY_CONTEXT security
;
533 stream_name_len
= ntfs_fuse_parse_path(org_path
, &path
, &stream_name
);
534 if (stream_name_len
< 0)
535 return stream_name_len
;
536 memset(stbuf
, 0, sizeof(struct stat
));
537 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
542 withusermapping
= ntfs_fuse_fill_security_context(&security
);
545 * make sure the parent directory is searchable
548 && !ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)) {
553 if (((ni
->mrec
->flags
& MFT_RECORD_IS_DIRECTORY
)
554 || (ni
->flags
& FILE_ATTR_REPARSE_POINT
))
555 && !stream_name_len
) {
556 if (ni
->flags
& FILE_ATTR_REPARSE_POINT
) {
561 target
= ntfs_make_symlink(org_path
, ni
, &attr_size
);
563 * If the reparse point is not a valid
564 * directory junction, and there is no error
565 * we still display as a symlink
567 if (target
|| (errno
== EOPNOTSUPP
)) {
568 /* returning attribute size */
570 stbuf
->st_size
= attr_size
;
572 stbuf
->st_size
= sizeof(ntfs_bad_reparse
);
573 stbuf
->st_blocks
= (ni
->allocated_size
+ 511) >> 9;
574 stbuf
->st_nlink
= le16_to_cpu(ni
->mrec
->link_count
);
575 stbuf
->st_mode
= S_IFLNK
;
583 stbuf
->st_mode
= S_IFDIR
| (0777 & ~ctx
->dmask
);
584 na
= ntfs_attr_open(ni
, AT_INDEX_ALLOCATION
, NTFS_INDEX_I30
, 4);
586 stbuf
->st_size
= na
->data_size
;
587 stbuf
->st_blocks
= na
->allocated_size
>> 9;
590 stbuf
->st_nlink
= 1; /* Make find(1) work */
593 /* Regular or Interix (INTX) file. */
594 stbuf
->st_mode
= S_IFREG
;
595 stbuf
->st_size
= ni
->data_size
;
597 * return data size rounded to next 512 byte boundary for
598 * encrypted files to include padding required for decryption
599 * also include 2 bytes for padding info
601 if (ctx
->efs_raw
&& ni
->flags
& FILE_ATTR_ENCRYPTED
)
602 stbuf
->st_size
= ((ni
->data_size
+ 511) & ~511) + 2;
605 * Temporary fix to make ActiveSync work via Samba 3.0.
606 * See more on the ntfs-3g-devel list.
608 stbuf
->st_blocks
= (ni
->allocated_size
+ 511) >> 9;
609 stbuf
->st_nlink
= le16_to_cpu(ni
->mrec
->link_count
);
610 if (ni
->flags
& FILE_ATTR_SYSTEM
|| stream_name_len
) {
611 na
= ntfs_attr_open(ni
, AT_DATA
, stream_name
,
618 if (stream_name_len
) {
619 stbuf
->st_size
= na
->data_size
;
620 stbuf
->st_blocks
= na
->allocated_size
>> 9;
622 /* Check whether it's Interix FIFO or socket. */
623 if (!(ni
->flags
& FILE_ATTR_HIDDEN
) &&
626 if (na
->data_size
== 0)
627 stbuf
->st_mode
= S_IFIFO
;
629 if (na
->data_size
== 1)
630 stbuf
->st_mode
= S_IFSOCK
;
632 /* encrypted named stream */
633 /* round size up to next 512 byte boundary */
634 if (ctx
->efs_raw
&& stream_name_len
&&
635 (na
->data_flags
& ATTR_IS_ENCRYPTED
) &&
636 NAttrNonResident(na
))
637 stbuf
->st_size
= ((na
->data_size
+511) & ~511)+2;
639 * Check whether it's Interix symbolic link, block or
642 if ((size_t)na
->data_size
<= sizeof(INTX_FILE_TYPES
)
643 + sizeof(ntfschar
) * PATH_MAX
644 && (size_t)na
->data_size
>
645 sizeof(INTX_FILE_TYPES
)
646 && !stream_name_len
) {
648 INTX_FILE
*intx_file
;
650 intx_file
= ntfs_malloc(na
->data_size
);
656 if (ntfs_attr_pread(na
, 0, na
->data_size
,
657 intx_file
) != na
->data_size
) {
663 if (intx_file
->magic
== INTX_BLOCK_DEVICE
&&
664 na
->data_size
== offsetof(
665 INTX_FILE
, device_end
)) {
666 stbuf
->st_mode
= S_IFBLK
;
667 stbuf
->st_rdev
= makedev(le64_to_cpu(
672 if (intx_file
->magic
== INTX_CHARACTER_DEVICE
&&
673 na
->data_size
== offsetof(
674 INTX_FILE
, device_end
)) {
675 stbuf
->st_mode
= S_IFCHR
;
676 stbuf
->st_rdev
= makedev(le64_to_cpu(
681 if (intx_file
->magic
== INTX_SYMBOLIC_LINK
)
682 stbuf
->st_mode
= S_IFLNK
;
687 stbuf
->st_mode
|= (0777 & ~ctx
->fmask
);
689 if (withusermapping
) {
690 if (ntfs_get_owner_mode(&security
,path
,ni
,stbuf
) < 0)
691 set_fuse_error(&res
);
693 stbuf
->st_uid
= ctx
->uid
;
694 stbuf
->st_gid
= ctx
->gid
;
696 if (S_ISLNK(stbuf
->st_mode
))
697 stbuf
->st_mode
|= 0777;
698 stbuf
->st_ino
= ni
->mft_no
;
699 stbuf
->st_atime
= ni
->last_access_time
;
700 stbuf
->st_ctime
= ni
->last_mft_change_time
;
701 stbuf
->st_mtime
= ni
->last_data_change_time
;
703 if (ntfs_inode_close(ni
))
704 set_fuse_error(&res
);
711 static int ntfs_fuse_readlink(const char *org_path
, char *buf
, size_t buf_size
)
714 ntfschar
*stream_name
;
715 ntfs_inode
*ni
= NULL
;
716 ntfs_attr
*na
= NULL
;
717 INTX_FILE
*intx_file
= NULL
;
718 int stream_name_len
, res
= 0;
721 stream_name_len
= ntfs_fuse_parse_path(org_path
, &path
, &stream_name
);
722 if (stream_name_len
< 0)
723 return stream_name_len
;
724 if (stream_name_len
> 0) {
728 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
734 * Reparse point : analyze as a junction point
736 if (ni
->flags
& FILE_ATTR_REPARSE_POINT
) {
742 target
= ntfs_make_symlink(org_path
, ni
, &attr_size
);
744 strncpy(buf
,target
,buf_size
);
747 if (errno
== EOPNOTSUPP
)
748 strcpy(buf
,ntfs_bad_reparse
);
754 if (!(ni
->flags
& FILE_ATTR_SYSTEM
)) {
758 na
= ntfs_attr_open(ni
, AT_DATA
, AT_UNNAMED
, 0);
763 if ((size_t)na
->data_size
<= sizeof(INTX_FILE_TYPES
)) {
767 if ((size_t)na
->data_size
> sizeof(INTX_FILE_TYPES
) +
768 sizeof(ntfschar
) * PATH_MAX
) {
772 /* Receive file content. */
773 intx_file
= ntfs_malloc(na
->data_size
);
778 if (ntfs_attr_pread(na
, 0, na
->data_size
, intx_file
) != na
->data_size
) {
783 if (intx_file
->magic
!= INTX_SYMBOLIC_LINK
) {
787 /* Convert link from unicode to local encoding. */
788 if (ntfs_ucstombs(intx_file
->target
, (na
->data_size
-
789 offsetof(INTX_FILE
, target
)) / sizeof(ntfschar
),
790 &buf
, buf_size
) < 0) {
799 if (ntfs_inode_close(ni
))
800 set_fuse_error(&res
);
807 static int ntfs_fuse_filler(ntfs_fuse_fill_context_t
*fill_ctx
,
808 const ntfschar
*name
, const int name_len
, const int name_type
,
809 const s64 pos
__attribute__((unused
)), const MFT_REF mref
,
810 const unsigned dt_type
__attribute__((unused
)))
812 char *filename
= NULL
;
814 int filenamelen
= -1;
816 if (name_type
== FILE_NAME_DOS
)
819 if ((filenamelen
= ntfs_ucstombs(name
, name_len
, &filename
, 0)) < 0) {
820 ntfs_log_perror("Filename decoding failed (inode %llu)",
821 (unsigned long long)MREF(mref
));
825 if (ntfs_fuse_is_named_data_stream(filename
)) {
826 ntfs_log_error("Unable to access '%s' (inode %llu) with "
827 "current named streams access interface.\n",
828 filename
, (unsigned long long)MREF(mref
));
833 if (MREF(mref
) == FILE_root
|| MREF(mref
) >= FILE_first_user
||
834 ctx
->show_sys_files
) {
835 struct stat st
= { .st_ino
= MREF(mref
) };
837 if (dt_type
== NTFS_DT_REG
)
838 st
.st_mode
= S_IFREG
| (0777 & ~ctx
->fmask
);
839 else if (dt_type
== NTFS_DT_DIR
)
840 st
.st_mode
= S_IFDIR
| (0777 & ~ctx
->dmask
);
842 #if defined(__APPLE__) || defined(__DARWIN__)
844 * Returning file names larger than MAXNAMLEN (255) bytes
845 * causes Darwin/Mac OS X to bug out and skip the entry.
847 if (filenamelen
> MAXNAMLEN
) {
848 ntfs_log_debug("Truncating %d byte filename to "
849 "%d bytes.\n", filenamelen
, MAXNAMLEN
);
850 ntfs_log_debug(" before: '%s'\n", filename
);
851 memset(filename
+ MAXNAMLEN
, 0, filenamelen
- MAXNAMLEN
);
852 ntfs_log_debug(" after: '%s'\n", filename
);
854 #endif /* defined(__APPLE__) || defined(__DARWIN__) */
856 ret
= fill_ctx
->filler(fill_ctx
->buf
, filename
, &st
, 0);
865 static int ntfs_fuse_opendir(const char *path
,
866 struct fuse_file_info
*fi
)
871 struct SECURITY_CONTEXT security
;
873 if (ntfs_fuse_is_named_data_stream(path
))
874 return -EINVAL
; /* n/a for named data streams. */
876 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
878 if (ntfs_fuse_fill_security_context(&security
)) {
879 if (fi
->flags
& O_WRONLY
)
880 accesstype
= S_IWRITE
;
882 if (fi
->flags
& O_RDWR
)
883 accesstype
= S_IWRITE
| S_IREAD
;
885 accesstype
= S_IREAD
;
886 /* directory must be searchable */
887 if (!ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)
888 /* check whether requested access is allowed */
889 || !ntfs_allowed_access(&security
,path
,ni
,accesstype
))
892 if (ntfs_inode_close(ni
))
893 set_fuse_error(&res
);
901 static int ntfs_fuse_readdir(const char *path
, void *buf
,
902 fuse_fill_dir_t filler
, off_t offset
__attribute__((unused
)),
903 struct fuse_file_info
*fi
__attribute__((unused
)))
905 ntfs_fuse_fill_context_t fill_ctx
;
910 fill_ctx
.filler
= filler
;
912 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
915 if (ntfs_readdir(ni
, &pos
, &fill_ctx
,
916 (ntfs_filldir_t
)ntfs_fuse_filler
))
918 ntfs_fuse_update_times(ni
, NTFS_UPDATE_ATIME
);
919 if (ntfs_inode_close(ni
))
920 set_fuse_error(&err
);
924 static int ntfs_fuse_open(const char *org_path
,
926 struct fuse_file_info
*fi
)
928 struct fuse_file_info
*fi
__attribute__((unused
)))
935 ntfschar
*stream_name
;
939 struct SECURITY_CONTEXT security
;
942 stream_name_len
= ntfs_fuse_parse_path(org_path
, &path
, &stream_name
);
943 if (stream_name_len
< 0)
944 return stream_name_len
;
945 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
947 na
= ntfs_attr_open(ni
, AT_DATA
, stream_name
, stream_name_len
);
950 if (ntfs_fuse_fill_security_context(&security
)) {
951 if (fi
->flags
& O_WRONLY
)
952 accesstype
= S_IWRITE
;
954 if (fi
->flags
& O_RDWR
)
955 accesstype
= S_IWRITE
| S_IREAD
;
957 accesstype
= S_IREAD
;
958 /* JPA directory must be searchable */
959 if (!ntfs_allowed_dir_access(&security
,
961 /* JPA check whether requested access is allowed */
962 || !ntfs_allowed_access(&security
,
968 && (fi
->flags
& (O_WRONLY
| O_RDWR
))) {
969 /* mark a future need to compress the last chunk */
970 if (na
->data_flags
& ATTR_COMPRESSION_MASK
)
971 fi
->fh
|= CLOSE_COMPRESSED
;
972 /* mark a future need to fixup encrypted inode */
974 && !(na
->data_flags
& ATTR_IS_ENCRYPTED
)
975 && (ni
->flags
& FILE_ATTR_ENCRYPTED
))
976 fi
->fh
|= CLOSE_ENCRYPTED
;
981 if (ntfs_inode_close(ni
))
982 set_fuse_error(&res
);
991 static int ntfs_fuse_read(const char *org_path
, char *buf
, size_t size
,
992 off_t offset
, struct fuse_file_info
*fi
__attribute__((unused
)))
994 ntfs_inode
*ni
= NULL
;
995 ntfs_attr
*na
= NULL
;
997 ntfschar
*stream_name
;
998 int stream_name_len
, res
;
1005 stream_name_len
= ntfs_fuse_parse_path(org_path
, &path
, &stream_name
);
1006 if (stream_name_len
< 0)
1007 return stream_name_len
;
1008 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1013 na
= ntfs_attr_open(ni
, AT_DATA
, stream_name
, stream_name_len
);
1018 /* limit reads at next 512 byte boundary for encrypted attributes */
1019 max_read
= na
->data_size
;
1020 if (ctx
->efs_raw
&& (na
->data_flags
& ATTR_IS_ENCRYPTED
) &&
1021 NAttrNonResident(na
)) {
1022 max_read
= ((na
->data_size
+511) & ~511) + 2;
1024 if (offset
+ (off_t
)size
> max_read
) {
1025 if (max_read
< offset
)
1027 size
= max_read
- offset
;
1030 s64 ret
= ntfs_attr_pread(na
, offset
, size
, buf
+ total
);
1031 if (ret
!= (s64
)size
)
1032 ntfs_log_perror("ntfs_attr_pread error reading '%s' at "
1033 "offset %lld: %lld <> %lld", org_path
,
1034 (long long)offset
, (long long)size
, (long long)ret
);
1035 if (ret
<= 0 || ret
> (s64
)size
) {
1036 res
= (ret
< 0) ? -errno
: -EIO
;
1044 ntfs_fuse_update_times(na
->ni
, NTFS_UPDATE_ATIME
);
1048 ntfs_attr_close(na
);
1049 if (ntfs_inode_close(ni
))
1050 set_fuse_error(&res
);
1052 if (stream_name_len
)
1057 static int ntfs_fuse_write(const char *org_path
, const char *buf
, size_t size
,
1058 off_t offset
, struct fuse_file_info
*fi
__attribute__((unused
)))
1060 ntfs_inode
*ni
= NULL
;
1061 ntfs_attr
*na
= NULL
;
1063 ntfschar
*stream_name
;
1064 int stream_name_len
, res
, total
= 0;
1066 stream_name_len
= ntfs_fuse_parse_path(org_path
, &path
, &stream_name
);
1067 if (stream_name_len
< 0) {
1068 res
= stream_name_len
;
1071 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1076 na
= ntfs_attr_open(ni
, AT_DATA
, stream_name
, stream_name_len
);
1082 s64 ret
= ntfs_attr_pwrite(na
, offset
, size
, buf
+ total
);
1093 ntfs_fuse_update_times(na
->ni
, NTFS_UPDATE_MCTIME
);
1096 ntfs_attr_close(na
);
1099 if (ntfs_inode_close(ni
))
1100 set_fuse_error(&res
);
1102 if (stream_name_len
)
1108 static int ntfs_fuse_release(const char *org_path
,
1109 struct fuse_file_info
*fi
)
1111 ntfs_inode
*ni
= NULL
;
1112 ntfs_attr
*na
= NULL
;
1114 ntfschar
*stream_name
;
1115 int stream_name_len
, res
;
1117 /* Only for marked descriptors there is something to do */
1118 if (!(fi
->fh
& (CLOSE_COMPRESSED
| CLOSE_ENCRYPTED
))) {
1122 stream_name_len
= ntfs_fuse_parse_path(org_path
, &path
, &stream_name
);
1123 if (stream_name_len
< 0) {
1124 res
= stream_name_len
;
1127 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1132 na
= ntfs_attr_open(ni
, AT_DATA
, stream_name
, stream_name_len
);
1138 if (fi
->fh
& CLOSE_COMPRESSED
)
1139 res
= ntfs_attr_pclose(na
);
1140 if (fi
->fh
& CLOSE_ENCRYPTED
)
1141 res
= ntfs_efs_fixup_attribute(NULL
, na
);
1144 ntfs_attr_close(na
);
1145 if (ntfs_inode_close(ni
))
1146 set_fuse_error(&res
);
1148 if (stream_name_len
)
1155 * Common part for truncate() and ftruncate()
1158 static int ntfs_fuse_trunc(const char *org_path
, off_t size
,
1162 BOOL chkwrite
__attribute__((unused
)))
1165 ntfs_inode
*ni
= NULL
;
1166 ntfs_attr
*na
= NULL
;
1169 ntfschar
*stream_name
;
1170 int stream_name_len
;
1173 struct SECURITY_CONTEXT security
;
1176 stream_name_len
= ntfs_fuse_parse_path(org_path
, &path
, &stream_name
);
1177 if (stream_name_len
< 0)
1178 return stream_name_len
;
1179 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1183 na
= ntfs_attr_open(ni
, AT_DATA
, stream_name
, stream_name_len
);
1188 * JPA deny truncation if cannot search in parent directory
1189 * or cannot write to file (already checked for ftruncate())
1191 if (ntfs_fuse_fill_security_context(&security
)
1192 && (!ntfs_allowed_dir_access(&security
, path
, S_IEXEC
)
1194 && !ntfs_allowed_access(&security
, path
, ni
, S_IWRITE
)))) {
1200 * for compressed files, only deleting contents and expanding
1201 * are implemented. Expanding is done by inserting a final
1202 * zero, which is optimized as creating a hole when possible.
1204 if ((na
->data_flags
& ATTR_COMPRESSION_MASK
)
1206 && (size
< na
->initialized_size
)) {
1210 oldsize
= na
->data_size
;
1211 if ((na
->data_flags
& ATTR_COMPRESSION_MASK
)
1212 && (size
> na
->initialized_size
)) {
1214 if (ntfs_attr_pwrite(na
, size
- 1, 1, &zero
) <= 0)
1217 if (ntfs_attr_truncate(na
, size
))
1219 if (oldsize
!= size
)
1222 ntfs_fuse_update_times(na
->ni
, NTFS_UPDATE_MCTIME
);
1226 ntfs_attr_close(na
);
1227 if (ntfs_inode_close(ni
))
1228 set_fuse_error(&res
);
1230 if (stream_name_len
)
1235 static int ntfs_fuse_truncate(const char *org_path
, off_t size
)
1237 return ntfs_fuse_trunc(org_path
, size
, TRUE
);
1240 static int ntfs_fuse_ftruncate(const char *org_path
, off_t size
,
1241 struct fuse_file_info
*fi
__attribute__((unused
)))
1244 * in ->ftruncate() the file handle is guaranteed
1245 * to have been opened for write.
1247 return (ntfs_fuse_trunc(org_path
, size
, FALSE
));
1250 static int ntfs_fuse_chmod(const char *path
,
1255 struct SECURITY_CONTEXT security
;
1257 if (ntfs_fuse_is_named_data_stream(path
))
1258 return -EINVAL
; /* n/a for named data streams. */
1260 /* JPA return unsupported if no user mapping has been defined */
1261 if (!ntfs_fuse_fill_security_context(&security
)) {
1268 /* parent directory must be executable */
1269 if (ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)) {
1271 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1275 if (ntfs_set_mode(&security
,path
,ni
,mode
))
1278 ntfs_fuse_update_times(ni
, NTFS_UPDATE_CTIME
);
1280 if (ntfs_inode_close(ni
))
1281 set_fuse_error(&res
);
1291 static int ntfs_fuse_chown(const char *path
, uid_t uid
, gid_t gid
)
1295 struct SECURITY_CONTEXT security
;
1297 if (ntfs_fuse_is_named_data_stream(path
))
1298 return -EINVAL
; /* n/a for named data streams. */
1299 if (!ntfs_fuse_fill_security_context(&security
)) {
1302 if (uid
== ctx
->uid
&& gid
== ctx
->gid
)
1307 if (((int)uid
!= -1) || ((int)gid
!= -1)) {
1309 /* parent directory must be executable */
1311 if (ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)) {
1313 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1317 if (ntfs_set_owner(&security
,
1321 ntfs_fuse_update_times(ni
, NTFS_UPDATE_CTIME
);
1322 if (ntfs_inode_close(ni
))
1323 set_fuse_error(&res
);
1336 static int ntfs_fuse_access(const char *path
, int type
)
1341 struct SECURITY_CONTEXT security
;
1343 if (ntfs_fuse_is_named_data_stream(path
))
1344 return -EINVAL
; /* n/a for named data streams. */
1346 /* JPA return unsupported if no user mapping has been defined */
1347 if (!ntfs_fuse_fill_security_context(&security
)) {
1353 /* parent directory must be readable */
1354 if (ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)) {
1355 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1360 if (type
& (X_OK
| W_OK
| R_OK
)) {
1361 if (type
& X_OK
) mode
+= S_IEXEC
;
1362 if (type
& W_OK
) mode
+= S_IWRITE
;
1363 if (type
& R_OK
) mode
+= S_IREAD
;
1364 if (!ntfs_allowed_access(&security
,
1368 if (ntfs_inode_close(ni
))
1369 set_fuse_error(&res
);
1379 static int ntfs_fuse_create(const char *org_path
, mode_t typemode
, dev_t dev
,
1380 const char *target
, struct fuse_file_info
*fi
)
1383 ntfschar
*uname
= NULL
, *utarget
= NULL
;
1384 ntfs_inode
*dir_ni
= NULL
, *ni
;
1388 ntfschar
*stream_name
;
1389 int stream_name_len
;
1390 mode_t type
= typemode
& ~07777;
1392 struct SECURITY_CONTEXT security
;
1393 int res
= 0, uname_len
, utarget_len
;
1395 dir_path
= strdup(org_path
);
1398 /* Generate unicode filename. */
1399 name
= strrchr(dir_path
, '/');
1401 uname_len
= ntfs_mbstoucs(name
, &uname
);
1402 if (uname_len
< 0) {
1406 stream_name_len
= ntfs_fuse_parse_path(org_path
,
1407 &path
, &stream_name
);
1408 if (stream_name_len
< 0) {
1409 res
= stream_name_len
;
1412 /* Open parent directory. */
1414 dir_ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, dir_path
);
1421 /* make sure parent directory is writeable and executable */
1422 if (!ntfs_fuse_fill_security_context(&security
)
1423 || ntfs_allowed_access(&security
,dir_path
,
1424 dir_ni
,S_IWRITE
+ S_IEXEC
)) {
1426 ntfs_fuse_fill_security_context(&security
);
1429 perm
= typemode
& ~ctx
->dmask
& 0777;
1431 perm
= typemode
& ~ctx
->fmask
& 0777;
1433 * Try to get a security id available for
1434 * file creation (from inheritance or argument).
1435 * This is not possible for NTFS 1.x, and we will
1436 * have to build a security attribute later.
1438 if (!ctx
->security
.mapping
[MAPUSERS
])
1442 securid
= ntfs_inherited_id(&security
, dir_path
,
1443 dir_ni
, S_ISDIR(type
));
1446 securid
= ntfs_alloc_securid(&security
,
1447 security
.uid
, security
.gid
,
1448 dir_path
, dir_ni
, perm
, S_ISDIR(type
));
1450 securid
= ntfs_alloc_securid(&security
,
1451 security
.uid
, security
.gid
,
1452 perm
& ~security
.umask
, S_ISDIR(type
));
1454 /* Create object specified in @type. */
1458 ni
= ntfs_create_device(dir_ni
, securid
,
1459 uname
, uname_len
, type
, dev
);
1462 utarget_len
= ntfs_mbstoucs(target
, &utarget
);
1463 if (utarget_len
< 0) {
1467 ni
= ntfs_create_symlink(dir_ni
, securid
,
1469 utarget
, utarget_len
);
1472 ni
= ntfs_create(dir_ni
, securid
, uname
,
1478 * set the security attribute if a security id
1479 * could not be allocated (eg NTFS 1.x)
1481 if (ctx
->security
.mapping
[MAPUSERS
]) {
1484 && ntfs_set_inherited_posix(&security
, ni
,
1485 security
.uid
, security
.gid
,
1486 dir_path
, dir_ni
, perm
) < 0)
1487 set_fuse_error(&res
);
1490 && ntfs_set_owner_mode(&security
, ni
,
1491 security
.uid
, security
.gid
,
1492 perm
& ~security
.umask
) < 0)
1493 set_fuse_error(&res
);
1497 /* mark a need to compress the end of file */
1498 if (fi
&& (ni
->flags
& FILE_ATTR_COMPRESSED
)) {
1499 fi
->fh
|= CLOSE_COMPRESSED
;
1501 /* mark a future need to fixup encrypted inode */
1504 && (ni
->flags
& FILE_ATTR_ENCRYPTED
))
1505 fi
->fh
|= CLOSE_ENCRYPTED
;
1508 * closing ni will necessitate to open dir_ni to
1509 * synchronize the index.
1510 * Better avoid a dangerous double opening.
1512 ntfs_fuse_update_times(dir_ni
, NTFS_UPDATE_MCTIME
);
1513 if (ntfs_inode_close(dir_ni
))
1514 set_fuse_error(&res
);
1515 dir_ni
= (ntfs_inode
*)NULL
;
1516 if (ntfs_inode_close(ni
))
1517 set_fuse_error(&res
);
1528 if (ntfs_inode_close(dir_ni
))
1529 set_fuse_error(&res
);
1536 static int ntfs_fuse_create_stream(const char *path
,
1537 ntfschar
*stream_name
, const int stream_name_len
,
1538 struct fuse_file_info
*fi
)
1543 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1546 if (res
== -ENOENT
) {
1548 * If such file does not exist, create it and try once
1549 * again to add stream to it.
1550 * Note : no fuse_file_info for creation of main file
1552 res
= ntfs_fuse_create(path
, S_IFREG
, 0, NULL
,
1553 (struct fuse_file_info
*)NULL
);
1555 return ntfs_fuse_create_stream(path
,
1556 stream_name
, stream_name_len
,fi
);
1562 if (ntfs_attr_add(ni
, AT_DATA
, stream_name
, stream_name_len
, NULL
, 0))
1566 && (fi
->flags
& (O_WRONLY
| O_RDWR
))) {
1568 /* mark a future need to compress the last block */
1569 if (ni
->flags
& FILE_ATTR_COMPRESSED
)
1570 fi
->fh
|= CLOSE_COMPRESSED
;
1571 /* mark a future need to fixup encrypted inode */
1573 && (ni
->flags
& FILE_ATTR_ENCRYPTED
))
1574 fi
->fh
|= CLOSE_ENCRYPTED
;
1577 if (ntfs_inode_close(ni
))
1578 set_fuse_error(&res
);
1582 static int ntfs_fuse_mknod_common(const char *org_path
, mode_t mode
, dev_t dev
,
1583 struct fuse_file_info
*fi
)
1586 ntfschar
*stream_name
;
1587 int stream_name_len
;
1590 stream_name_len
= ntfs_fuse_parse_path(org_path
, &path
, &stream_name
);
1591 if (stream_name_len
< 0)
1592 return stream_name_len
;
1593 if (stream_name_len
&& !S_ISREG(mode
)) {
1597 if (!stream_name_len
)
1598 res
= ntfs_fuse_create(path
, mode
& (S_IFMT
| 07777), dev
,
1601 res
= ntfs_fuse_create_stream(path
, stream_name
,
1602 stream_name_len
,fi
);
1605 if (stream_name_len
)
1610 static int ntfs_fuse_mknod(const char *path
, mode_t mode
, dev_t dev
)
1612 return ntfs_fuse_mknod_common(path
, mode
, dev
,
1613 (struct fuse_file_info
*)NULL
);
1616 static int ntfs_fuse_create_file(const char *path
, mode_t mode
,
1617 struct fuse_file_info
*fi
)
1619 return ntfs_fuse_mknod_common(path
, mode
, 0, fi
);
1622 static int ntfs_fuse_symlink(const char *to
, const char *from
)
1624 if (ntfs_fuse_is_named_data_stream(from
))
1625 return -EINVAL
; /* n/a for named data streams. */
1626 return ntfs_fuse_create(from
, S_IFLNK
, 0, to
,
1627 (struct fuse_file_info
*)NULL
);
1630 static int ntfs_fuse_link(const char *old_path
, const char *new_path
)
1633 ntfschar
*uname
= NULL
;
1634 ntfs_inode
*dir_ni
= NULL
, *ni
;
1636 int res
= 0, uname_len
;
1638 struct SECURITY_CONTEXT security
;
1641 if (ntfs_fuse_is_named_data_stream(old_path
))
1642 return -EINVAL
; /* n/a for named data streams. */
1643 if (ntfs_fuse_is_named_data_stream(new_path
))
1644 return -EINVAL
; /* n/a for named data streams. */
1645 path
= strdup(new_path
);
1648 /* Open file for which create hard link. */
1649 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, old_path
);
1655 /* Generate unicode filename. */
1656 name
= strrchr(path
, '/');
1658 uname_len
= ntfs_mbstoucs(name
, &uname
);
1659 if (uname_len
< 0) {
1663 /* Open parent directory. */
1665 dir_ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1672 /* JPA make sure the parent directories are writeable */
1673 if (ntfs_fuse_fill_security_context(&security
)
1674 && (!ntfs_allowed_dir_access(&security
,old_path
,S_IWRITE
+ S_IEXEC
)
1675 || !ntfs_allowed_access(&security
,path
,dir_ni
,S_IWRITE
+ S_IEXEC
)))
1680 if (ntfs_link(ni
, dir_ni
, uname
, uname_len
)) {
1686 ntfs_fuse_update_times(ni
, NTFS_UPDATE_CTIME
);
1687 ntfs_fuse_update_times(dir_ni
, NTFS_UPDATE_MCTIME
);
1691 * Must close dir_ni first otherwise ntfs_inode_sync_file_name(ni)
1692 * may fail because ni may not be in parent's index on the disk yet.
1694 if (ntfs_inode_close(dir_ni
))
1695 set_fuse_error(&res
);
1696 if (ntfs_inode_close(ni
))
1697 set_fuse_error(&res
);
1703 static int ntfs_fuse_rm(const char *org_path
)
1706 ntfschar
*uname
= NULL
;
1707 ntfs_inode
*dir_ni
= NULL
, *ni
;
1709 int res
= 0, uname_len
;
1711 struct SECURITY_CONTEXT security
;
1714 path
= strdup(org_path
);
1717 /* Open object for delete. */
1718 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1723 /* Generate unicode filename. */
1724 name
= strrchr(path
, '/');
1726 uname_len
= ntfs_mbstoucs(name
, &uname
);
1727 if (uname_len
< 0) {
1731 /* Open parent directory. */
1733 dir_ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1740 /* JPA deny unlinking if directory is not writable and executable */
1741 if (!ntfs_fuse_fill_security_context(&security
)
1742 || ntfs_allowed_dir_access(&security
, org_path
,
1743 S_IEXEC
+ S_IWRITE
+ S_ISVTX
)) {
1745 if (ntfs_delete(ctx
->vol
, org_path
, ni
, dir_ni
,
1748 /* ntfs_delete() always closes ni and dir_ni */
1755 if (ntfs_inode_close(dir_ni
))
1756 set_fuse_error(&res
);
1757 if (ntfs_inode_close(ni
))
1758 set_fuse_error(&res
);
1764 static int ntfs_fuse_rm_stream(const char *path
, ntfschar
*stream_name
,
1765 const int stream_name_len
)
1770 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1774 if (ntfs_attr_remove(ni
, AT_DATA
, stream_name
, stream_name_len
))
1777 if (ntfs_inode_close(ni
))
1778 set_fuse_error(&res
);
1782 static int ntfs_fuse_unlink(const char *org_path
)
1785 ntfschar
*stream_name
;
1786 int stream_name_len
;
1789 struct SECURITY_CONTEXT security
;
1792 stream_name_len
= ntfs_fuse_parse_path(org_path
, &path
, &stream_name
);
1793 if (stream_name_len
< 0)
1794 return stream_name_len
;
1795 if (!stream_name_len
)
1796 res
= ntfs_fuse_rm(path
);
1800 * JPA deny unlinking stream if directory is not
1801 * writable and executable (debatable)
1803 if (!ntfs_fuse_fill_security_context(&security
)
1804 || ntfs_allowed_dir_access(&security
, path
,
1805 S_IEXEC
+ S_IWRITE
+ S_ISVTX
))
1806 res
= ntfs_fuse_rm_stream(path
, stream_name
, stream_name_len
);
1810 res
= ntfs_fuse_rm_stream(path
, stream_name
, stream_name_len
);
1814 if (stream_name_len
)
1819 static int ntfs_fuse_safe_rename(const char *old_path
,
1820 const char *new_path
,
1825 ntfs_log_trace("Entering\n");
1827 ret
= ntfs_fuse_link(new_path
, tmp
);
1831 ret
= ntfs_fuse_unlink(new_path
);
1834 ret
= ntfs_fuse_link(old_path
, new_path
);
1838 ret
= ntfs_fuse_unlink(old_path
);
1840 if (ntfs_fuse_unlink(new_path
))
1848 if (ntfs_fuse_link(tmp
, new_path
)) {
1850 ntfs_log_perror("Rename failed. Existing file '%s' was renamed "
1851 "to '%s'", new_path
, tmp
);
1855 * Condition for this unlink has already been checked in
1856 * "ntfs_fuse_rename_existing_dest()", so it should never
1857 * fail (unless concurrent access to directories when fuse
1860 if (ntfs_fuse_unlink(tmp
) < 0)
1861 ntfs_log_perror("Rename failed. Existing file '%s' still present "
1862 "as '%s'", new_path
, tmp
);
1867 static int ntfs_fuse_rename_existing_dest(const char *old_path
, const char *new_path
)
1871 const char *ext
= ".ntfs-3g-";
1873 struct SECURITY_CONTEXT security
;
1876 ntfs_log_trace("Entering\n");
1878 len
= strlen(new_path
) + strlen(ext
) + 10 + 1; /* wc(str(2^32)) + \0 */
1879 tmp
= ntfs_malloc(len
);
1883 ret
= snprintf(tmp
, len
, "%s%s%010d", new_path
, ext
, ++ntfs_sequence
);
1884 if (ret
!= len
- 1) {
1885 ntfs_log_error("snprintf failed: %d != %d\n", ret
, len
- 1);
1890 * Make sure existing dest can be removed.
1891 * This is only needed if parent directory is
1892 * sticky, because in this situation condition
1893 * for unlinking is different from condition for
1896 if (!ntfs_fuse_fill_security_context(&security
)
1897 || ntfs_allowed_dir_access(&security
, new_path
,
1898 S_IEXEC
+ S_IWRITE
+ S_ISVTX
))
1899 ret
= ntfs_fuse_safe_rename(old_path
, new_path
, tmp
);
1903 ret
= ntfs_fuse_safe_rename(old_path
, new_path
, tmp
);
1910 static int ntfs_fuse_rename(const char *old_path
, const char *new_path
)
1912 int ret
, stream_name_len
;
1914 ntfschar
*stream_name
;
1917 ntfs_log_debug("rename: old: '%s' new: '%s'\n", old_path
, new_path
);
1920 * FIXME: Rename should be atomic.
1922 stream_name_len
= ntfs_fuse_parse_path(new_path
, &path
, &stream_name
);
1923 if (stream_name_len
< 0)
1924 return stream_name_len
;
1926 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1928 ret
= ntfs_check_empty_dir(ni
);
1931 ntfs_inode_close(ni
);
1935 if (ntfs_inode_close(ni
)) {
1936 set_fuse_error(&ret
);
1940 ret
= ntfs_fuse_rename_existing_dest(old_path
, new_path
);
1944 ret
= ntfs_fuse_link(old_path
, new_path
);
1948 ret
= ntfs_fuse_unlink(old_path
);
1950 ntfs_fuse_unlink(new_path
);
1953 if (stream_name_len
)
1958 static int ntfs_fuse_mkdir(const char *path
,
1961 if (ntfs_fuse_is_named_data_stream(path
))
1962 return -EINVAL
; /* n/a for named data streams. */
1963 return ntfs_fuse_create(path
, S_IFDIR
| (mode
& 07777), 0, NULL
,
1964 (struct fuse_file_info
*)NULL
);
1967 static int ntfs_fuse_rmdir(const char *path
)
1969 if (ntfs_fuse_is_named_data_stream(path
))
1970 return -EINVAL
; /* n/a for named data streams. */
1971 return ntfs_fuse_rm(path
);
1974 static int ntfs_fuse_utime(const char *path
, struct utimbuf
*buf
)
1981 struct SECURITY_CONTEXT security
;
1984 if (ntfs_fuse_is_named_data_stream(path
))
1985 return -EINVAL
; /* n/a for named data streams. */
1987 /* parent directory must be executable */
1988 if (ntfs_fuse_fill_security_context(&security
)
1989 && !ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)) {
1993 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
1997 ownerok
= ntfs_allowed_as_owner(&security
, path
, ni
);
2000 * fuse never calls with a NULL buf and we do not
2001 * know whether the specific condition can be applied
2002 * So we have to accept updating by a non-owner having
2006 && (buf
->actime
== buf
->modtime
)
2007 && ntfs_allowed_access(&security
, path
, ni
, S_IWRITE
);
2009 if (!ownerok
&& !writeok
)
2010 res
= (buf
->actime
== buf
->modtime
? -EACCES
: -EPERM
);
2012 ni
->last_access_time
= buf
->actime
;
2013 ni
->last_data_change_time
= buf
->modtime
;
2014 ntfs_fuse_update_times(ni
, NTFS_UPDATE_CTIME
);
2017 /* Must be owner or have write access */
2019 && ntfs_allowed_access(&security
, path
, ni
, S_IWRITE
);
2020 if (!ownerok
&& !writeok
)
2023 ntfs_inode_update_times(ni
, NTFS_UPDATE_AMCTIME
);
2027 ni
->last_access_time
= buf
->actime
;
2028 ni
->last_data_change_time
= buf
->modtime
;
2029 ntfs_fuse_update_times(ni
, NTFS_UPDATE_CTIME
);
2031 ntfs_inode_update_times(ni
, NTFS_UPDATE_AMCTIME
);
2034 if (ntfs_inode_close(ni
))
2035 set_fuse_error(&res
);
2039 static int ntfs_fuse_bmap(const char *path
, size_t blocksize
, uint64_t *idx
)
2045 int cl_per_bl
= ctx
->vol
->cluster_size
/ blocksize
;
2047 if (blocksize
> ctx
->vol
->cluster_size
)
2050 if (ntfs_fuse_is_named_data_stream(path
))
2053 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
2057 na
= ntfs_attr_open(ni
, AT_DATA
, AT_UNNAMED
, 0);
2063 if ((na
->data_flags
& (ATTR_COMPRESSION_MASK
| ATTR_IS_ENCRYPTED
))
2064 || !NAttrNonResident(na
)) {
2069 if (ntfs_attr_map_whole_runlist(na
)) {
2074 lcn
= ntfs_rl_vcn_to_lcn(na
->rl
, *idx
/ cl_per_bl
);
2075 *idx
= (lcn
> 0) ? lcn
* cl_per_bl
+ *idx
% cl_per_bl
: 0;
2078 ntfs_attr_close(na
);
2080 if (ntfs_inode_close(ni
))
2081 set_fuse_error(&ret
);
2085 #ifdef HAVE_SETXATTR
2088 * Name space identifications and prefixes
2091 enum { XATTRNS_NONE
,
2098 static const char nf_ns_user_prefix
[] = "user.";
2099 static const int nf_ns_user_prefix_len
= sizeof(nf_ns_user_prefix
) - 1;
2100 static const char nf_ns_system_prefix
[] = "system.";
2101 static const int nf_ns_system_prefix_len
= sizeof(nf_ns_system_prefix
) - 1;
2102 static const char nf_ns_security_prefix
[] = "security.";
2103 static const int nf_ns_security_prefix_len
= sizeof(nf_ns_security_prefix
) - 1;
2104 static const char nf_ns_trusted_prefix
[] = "trusted.";
2105 static const int nf_ns_trusted_prefix_len
= sizeof(nf_ns_trusted_prefix
) - 1;
2107 static const char xattr_ntfs_3g
[] = "ntfs-3g.";
2110 * Identification of data mapped to the system name space
2113 enum { XATTR_UNMAPPED
,
2117 XATTR_NTFS_REPARSE_DATA
,
2118 XATTR_NTFS_DOS_NAME
,
2123 static const char nf_ns_xattr_ntfs_acl
[] = "system.ntfs_acl";
2124 static const char nf_ns_xattr_attrib
[] = "system.ntfs_attrib";
2125 static const char nf_ns_xattr_efsinfo
[] = "user.ntfs.efsinfo";
2126 static const char nf_ns_xattr_reparse
[] = "system.ntfs_reparse_data";
2127 static const char nf_ns_xattr_dos_name
[] = "system.ntfs_dos_name";
2128 static const char nf_ns_xattr_times
[] = "system.ntfs_times";
2129 static const char nf_ns_xattr_posix_access
[] = "system.posix_acl_access";
2130 static const char nf_ns_xattr_posix_default
[] = "system.posix_acl_default";
2137 static struct XATTRNAME nf_ns_xattr_names
[] = {
2138 { XATTR_NTFS_ACL
, nf_ns_xattr_ntfs_acl
},
2139 { XATTR_NTFS_ATTRIB
, nf_ns_xattr_attrib
},
2140 { XATTR_NTFS_EFSINFO
, nf_ns_xattr_efsinfo
},
2141 { XATTR_NTFS_REPARSE_DATA
, nf_ns_xattr_reparse
},
2142 { XATTR_NTFS_DOS_NAME
, nf_ns_xattr_dos_name
},
2143 { XATTR_NTFS_TIMES
, nf_ns_xattr_times
},
2144 { XATTR_POSIX_ACC
, nf_ns_xattr_posix_access
},
2145 { XATTR_POSIX_DEF
, nf_ns_xattr_posix_default
},
2146 { XATTR_UNMAPPED
, (char*)NULL
} /* terminator */
2150 * Check whether access to internal data as an extended
2151 * attribute in system name space is allowed
2153 * Returns pointer to inode if allowed,
2154 * NULL and errno set if not allowed
2157 static ntfs_inode
*ntfs_check_access_xattr(struct SECURITY_CONTEXT
*security
,
2158 const char *path
, int attr
, BOOL setting
)
2164 ni
= (ntfs_inode
*)NULL
;
2165 if (ntfs_fuse_is_named_data_stream(path
))
2166 errno
= EINVAL
; /* n/a for named data streams. */
2168 foracl
= (attr
== XATTR_POSIX_ACC
)
2169 || (attr
== XATTR_POSIX_DEF
);
2171 * When accessing Posix ACL, return unsupported if ACL
2172 * were disabled or no user mapping has been defined.
2173 * However no error will be returned to getfacl
2175 if ((!ntfs_fuse_fill_security_context(security
)
2176 || (ctx
->secure_flags
2177 & ((1 << SECURITY_DEFAULT
) | (1 << SECURITY_RAW
))))
2182 * parent directory must be executable, and
2183 * for setting a DOS name it must be writeable
2185 if (setting
&& (attr
== XATTR_NTFS_DOS_NAME
))
2186 acctype
= S_IEXEC
| S_IWRITE
;
2189 if (ntfs_allowed_dir_access(security
,path
,acctype
)) {
2190 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
2198 * Determine whether an extended attribute is in the system
2199 * name space and mapped to internal data
2202 static int mapped_xattr_system(const char *name
)
2204 struct XATTRNAME
*p
;
2206 p
= nf_ns_xattr_names
;
2207 while (p
->name
&& strcmp(p
->name
,name
))
2213 * Determine the name space of an extended attribute
2216 static int xattr_namespace(const char *name
)
2220 if (ctx
->streams
== NF_STREAMS_INTERFACE_XATTR
) {
2221 namespace = XATTRNS_NONE
;
2222 if (!strncmp(name
, nf_ns_user_prefix
,
2223 nf_ns_user_prefix_len
)
2224 && (strlen(name
) != (size_t)nf_ns_user_prefix_len
))
2225 namespace = XATTRNS_USER
;
2226 else if (!strncmp(name
, nf_ns_system_prefix
,
2227 nf_ns_system_prefix_len
)
2228 && (strlen(name
) != (size_t)nf_ns_system_prefix_len
))
2229 namespace = XATTRNS_SYSTEM
;
2230 else if (!strncmp(name
, nf_ns_security_prefix
,
2231 nf_ns_security_prefix_len
)
2232 && (strlen(name
) != (size_t)nf_ns_security_prefix_len
))
2233 namespace = XATTRNS_SECURITY
;
2234 else if (!strncmp(name
, nf_ns_trusted_prefix
,
2235 nf_ns_trusted_prefix_len
)
2236 && (strlen(name
) != (size_t)nf_ns_trusted_prefix_len
))
2237 namespace = XATTRNS_TRUSTED
;
2239 namespace = XATTRNS_OPEN
;
2244 * Fix the prefix of an extended attribute
2247 static int fix_xattr_prefix(const char *name
, int namespace, ntfschar
**lename
)
2252 *lename
= (ntfschar
*)NULL
;
2253 switch (namespace) {
2256 * user name space : remove user prefix
2258 len
= ntfs_mbstoucs(name
+ nf_ns_user_prefix_len
, lename
);
2260 case XATTRNS_SYSTEM
:
2261 case XATTRNS_SECURITY
:
2262 case XATTRNS_TRUSTED
:
2264 * security, trusted and unmapped system name spaces :
2265 * insert ntfs-3g prefix
2267 prefixed
= ntfs_malloc(strlen(xattr_ntfs_3g
)
2268 + strlen(name
) + 1);
2270 strcpy(prefixed
,xattr_ntfs_3g
);
2271 strcat(prefixed
,name
);
2272 len
= ntfs_mbstoucs(prefixed
, lename
);
2279 * in open name space mode : do no fix prefix
2281 len
= ntfs_mbstoucs(name
, lename
);
2289 static int ntfs_fuse_listxattr(const char *path
, char *list
, size_t size
)
2291 ntfs_attr_search_ctx
*actx
= NULL
;
2296 struct SECURITY_CONTEXT security
;
2299 /* parent directory must be executable */
2300 if (ntfs_fuse_fill_security_context(&security
)
2301 && !ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)) {
2305 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
2309 /* file must be readable */
2310 if (!ntfs_allowed_access(&security
,path
,ni
,S_IREAD
)) {
2315 actx
= ntfs_attr_get_search_ctx(ni
, NULL
);
2321 if ((ctx
->streams
== NF_STREAMS_INTERFACE_XATTR
)
2322 || (ctx
->streams
== NF_STREAMS_INTERFACE_OPENXATTR
)) {
2323 while (!ntfs_attr_lookup(AT_DATA
, NULL
, 0, CASE_SENSITIVE
,
2324 0, NULL
, 0, actx
)) {
2325 char *tmp_name
= NULL
;
2328 if (!actx
->attr
->name_length
)
2330 tmp_name_len
= ntfs_ucstombs(
2331 (ntfschar
*)((u8
*)actx
->attr
+
2332 le16_to_cpu(actx
->attr
->name_offset
)),
2333 actx
->attr
->name_length
, &tmp_name
, 0);
2334 if (tmp_name_len
< 0) {
2339 * When using name spaces, do not return
2340 * security, trusted nor system attributes
2341 * (filtered elsewhere anyway)
2342 * otherwise insert "user." prefix
2344 if (ctx
->streams
== NF_STREAMS_INTERFACE_XATTR
) {
2345 if ((strlen(tmp_name
) > sizeof(xattr_ntfs_3g
))
2346 && !strncmp(tmp_name
,xattr_ntfs_3g
,
2347 sizeof(xattr_ntfs_3g
)-1))
2351 + nf_ns_user_prefix_len
+ 1;
2353 ret
+= tmp_name_len
+ 1;
2354 if (size
&& tmp_name_len
) {
2355 if ((size_t)ret
<= size
) {
2357 == NF_STREAMS_INTERFACE_XATTR
) {
2358 strcpy(to
, nf_ns_user_prefix
);
2359 to
+= nf_ns_user_prefix_len
;
2361 strncpy(to
, tmp_name
, tmp_name_len
);
2375 /* List efs info xattr for encrypted files */
2376 if (ctx
->efs_raw
&& (ni
->flags
& FILE_ATTR_ENCRYPTED
)) {
2377 ret
+= sizeof(nf_ns_xattr_efsinfo
);
2378 if ((size_t)ret
<= size
) {
2379 memcpy(to
, nf_ns_xattr_efsinfo
,
2380 sizeof(nf_ns_xattr_efsinfo
));
2381 to
+= sizeof(nf_ns_xattr_efsinfo
);
2385 if (errno
!= ENOENT
)
2389 ntfs_attr_put_search_ctx(actx
);
2390 if (ntfs_inode_close(ni
))
2391 set_fuse_error(&ret
);
2395 static int ntfs_fuse_getxattr_windows(const char *path
, const char *name
,
2396 char *value
, size_t size
)
2398 ntfs_attr_search_ctx
*actx
= NULL
;
2403 struct SECURITY_CONTEXT security
;
2406 if (strcmp(name
, "ntfs.streams.list"))
2409 /* parent directory must be executable */
2410 if (ntfs_fuse_fill_security_context(&security
)
2411 && !ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)) {
2415 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
2419 if (!ntfs_allowed_access(&security
,path
,ni
,S_IREAD
)) {
2424 actx
= ntfs_attr_get_search_ctx(ni
, NULL
);
2429 while (!ntfs_attr_lookup(AT_DATA
, NULL
, 0, CASE_SENSITIVE
,
2430 0, NULL
, 0, actx
)) {
2431 char *tmp_name
= NULL
;
2434 if (!actx
->attr
->name_length
)
2436 tmp_name_len
= ntfs_ucstombs((ntfschar
*)((u8
*)actx
->attr
+
2437 le16_to_cpu(actx
->attr
->name_offset
)),
2438 actx
->attr
->name_length
, &tmp_name
, 0);
2439 if (tmp_name_len
< 0) {
2444 ret
++; /* For space delimiter. */
2445 ret
+= tmp_name_len
;
2447 if ((size_t)ret
<= size
) {
2448 /* Don't add space to the beginning of line. */
2453 strncpy(to
, tmp_name
, tmp_name_len
);
2463 if (errno
!= ENOENT
)
2467 ntfs_attr_put_search_ctx(actx
);
2468 if (ntfs_inode_close(ni
))
2469 set_fuse_error(&ret
);
2473 static int ntfs_fuse_getxattr(const char *path
, const char *name
,
2474 char *value
, size_t size
)
2477 ntfs_attr
*na
= NULL
;
2478 ntfschar
*lename
= NULL
;
2479 int res
, lename_len
;
2483 struct SECURITY_CONTEXT security
;
2485 attr
= mapped_xattr_system(name
);
2486 if (attr
!= XATTR_UNMAPPED
) {
2489 * hijack internal data and ACL retrieval, whatever
2490 * mode was selected for xattr (from the user's
2491 * point of view, ACLs are not xattr)
2493 ni
= ntfs_check_access_xattr(&security
,path
,attr
,FALSE
);
2495 if (ntfs_allowed_access(&security
,path
,ni
,S_IREAD
)) {
2497 * the returned value is the needed
2498 * size. If it is too small, no copy
2499 * is done, and the caller has to
2500 * issue a new call with correct size.
2503 case XATTR_NTFS_ACL
:
2504 res
= ntfs_get_ntfs_acl(&security
,path
,
2505 name
,value
,size
,ni
);
2507 case XATTR_POSIX_ACC
:
2508 case XATTR_POSIX_DEF
:
2509 res
= ntfs_get_posix_acl(&security
,path
,
2510 name
,value
,size
,ni
);
2512 case XATTR_NTFS_ATTRIB
:
2513 res
= ntfs_get_ntfs_attrib(path
,
2516 case XATTR_NTFS_EFSINFO
:
2518 res
= ntfs_get_efs_info(path
,
2523 case XATTR_NTFS_REPARSE_DATA
:
2524 res
= ntfs_get_ntfs_reparse_data(path
,
2527 case XATTR_NTFS_DOS_NAME
:
2528 res
= ntfs_get_ntfs_dos_name(path
,
2531 case XATTR_NTFS_TIMES
:
2532 res
= ntfs_inode_get_times(path
,
2535 default : /* not possible */
2541 if (ntfs_inode_close(ni
))
2542 set_fuse_error(&res
);
2547 * Only hijack NTFS ACL retrieval if POSIX ACLS
2548 * option is not selected
2549 * Access control is done by fuse
2551 if (ntfs_fuse_is_named_data_stream(path
))
2552 res
= -EINVAL
; /* n/a for named data streams. */
2554 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
2556 /* user mapping not mandatory */
2557 ntfs_fuse_fill_security_context(&security
);
2559 * the returned value is the needed
2560 * size. If it is too small, no copy
2561 * is done, and the caller has to
2562 * issue a new call with correct size.
2565 case XATTR_NTFS_ACL
:
2566 res
= ntfs_get_ntfs_acl(&security
,path
,
2567 name
,value
,size
,ni
);
2569 case XATTR_NTFS_ATTRIB
:
2570 res
= ntfs_get_ntfs_attrib(path
,
2573 case XATTR_NTFS_EFSINFO
:
2575 res
= ntfs_get_efs_info(path
,
2580 case XATTR_NTFS_REPARSE_DATA
:
2581 res
= ntfs_get_ntfs_reparse_data(path
,
2584 case XATTR_NTFS_DOS_NAME
:
2585 res
= ntfs_get_ntfs_dos_name(path
,
2588 case XATTR_NTFS_TIMES
:
2589 res
= ntfs_inode_get_times(path
,
2594 * make sure applications do not see
2595 * Posix ACL not consistent with mode
2601 if (ntfs_inode_close(ni
))
2602 set_fuse_error(&res
);
2609 if (ctx
->streams
== NF_STREAMS_INTERFACE_WINDOWS
)
2610 return ntfs_fuse_getxattr_windows(path
, name
, value
, size
);
2611 if (ctx
->streams
== NF_STREAMS_INTERFACE_NONE
)
2613 namespace = xattr_namespace(name
);
2614 if (namespace == XATTRNS_NONE
)
2617 /* parent directory must be executable */
2618 if (ntfs_fuse_fill_security_context(&security
)
2619 && !ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)) {
2622 /* trusted only readable by root */
2623 if ((namespace == XATTRNS_TRUSTED
)
2627 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
2631 /* file must be readable */
2632 if (!ntfs_allowed_access(&security
, path
, ni
, S_IREAD
)) {
2637 lename_len
= fix_xattr_prefix(name
, namespace, &lename
);
2638 if (lename_len
== -1) {
2642 na
= ntfs_attr_open(ni
, AT_DATA
, lename
, lename_len
);
2647 rsize
= na
->data_size
;
2649 (na
->data_flags
& ATTR_IS_ENCRYPTED
) &&
2650 NAttrNonResident(na
))
2651 rsize
= ((na
->data_size
+ 511) & ~511)+2;
2653 if (size
>= (size_t)rsize
) {
2654 res
= ntfs_attr_pread(na
, 0, rsize
, value
);
2663 ntfs_attr_close(na
);
2665 if (ntfs_inode_close(ni
))
2666 set_fuse_error(&res
);
2670 static int ntfs_fuse_setxattr(const char *path
, const char *name
,
2671 const char *value
, size_t size
, int flags
)
2674 ntfs_attr
*na
= NULL
;
2675 ntfschar
*lename
= NULL
;
2676 int res
, lename_len
;
2680 struct SECURITY_CONTEXT security
;
2682 attr
= mapped_xattr_system(name
);
2683 if (attr
!= XATTR_UNMAPPED
) {
2686 * hijack internal data and ACL setting, whatever
2687 * mode was selected for xattr (from the user's
2688 * point of view, ACLs are not xattr)
2689 * Note : updating an ACL does not set ctime
2691 ni
= ntfs_check_access_xattr(&security
,path
,attr
,TRUE
);
2693 if (ntfs_allowed_as_owner(&security
,path
,ni
)) {
2695 case XATTR_NTFS_ACL
:
2696 res
= ntfs_set_ntfs_acl(&security
,path
,
2697 name
,value
,size
,flags
,ni
);
2699 case XATTR_POSIX_ACC
:
2700 case XATTR_POSIX_DEF
:
2701 res
= ntfs_set_posix_acl(&security
,path
,
2702 name
,value
,size
,flags
,ni
);
2704 case XATTR_NTFS_ATTRIB
:
2705 res
= ntfs_set_ntfs_attrib(path
,
2706 value
,size
,flags
,ni
);
2708 case XATTR_NTFS_EFSINFO
:
2710 res
= ntfs_set_efs_info(path
,
2711 value
,size
,flags
,ni
);
2715 case XATTR_NTFS_REPARSE_DATA
:
2716 res
= ntfs_set_ntfs_reparse_data(path
,
2717 value
,size
,flags
,ni
);
2719 case XATTR_NTFS_DOS_NAME
:
2720 /* warning : this closes the inode */
2721 res
= ntfs_set_ntfs_dos_name(path
,
2722 value
,size
,flags
,ni
);
2724 case XATTR_NTFS_TIMES
:
2725 res
= ntfs_inode_set_times(path
,
2726 value
,size
,flags
,ni
);
2728 default : /* not possible */
2735 if ((attr
!= XATTR_NTFS_DOS_NAME
)
2736 && ntfs_inode_close(ni
))
2737 set_fuse_error(&res
);
2742 * Only hijack NTFS ACL setting if POSIX ACLS
2743 * option is not selected
2744 * Access control is partially done by fuse
2746 if (ntfs_fuse_is_named_data_stream(path
))
2747 res
= -EINVAL
; /* n/a for named data streams. */
2749 /* creation of a new name is not controlled by fuse */
2750 if (attr
== XATTR_NTFS_DOS_NAME
)
2751 ni
= ntfs_check_access_xattr(&security
,path
,attr
,TRUE
);
2753 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
2756 * user mapping is not mandatory
2757 * if defined, only owner is allowed
2759 if (!ntfs_fuse_fill_security_context(&security
)
2760 || ntfs_allowed_as_owner(&security
,path
,ni
)) {
2762 case XATTR_NTFS_ACL
:
2763 res
= ntfs_set_ntfs_acl(&security
,path
,
2764 name
,value
,size
,flags
,ni
);
2766 case XATTR_NTFS_ATTRIB
:
2767 res
= ntfs_set_ntfs_attrib(path
,
2768 value
,size
,flags
,ni
);
2770 case XATTR_NTFS_EFSINFO
:
2772 res
= ntfs_set_efs_info(path
,
2773 value
,size
,flags
,ni
);
2777 case XATTR_NTFS_REPARSE_DATA
:
2778 res
= ntfs_set_ntfs_reparse_data(path
,
2779 value
,size
,flags
,ni
);
2781 case XATTR_NTFS_DOS_NAME
:
2782 /* warning : this closes the inode */
2783 res
= ntfs_set_ntfs_dos_name(path
,
2784 value
,size
,flags
,ni
);
2786 case XATTR_NTFS_TIMES
:
2787 res
= ntfs_inode_set_times(path
,
2788 value
,size
,flags
,ni
);
2792 * make sure applications do not see
2793 * Posix ACL not consistent with mode
2803 if ((attr
!= XATTR_NTFS_DOS_NAME
)
2804 && ntfs_inode_close(ni
))
2805 set_fuse_error(&res
);
2812 if ((ctx
->streams
!= NF_STREAMS_INTERFACE_XATTR
)
2813 && (ctx
->streams
!= NF_STREAMS_INTERFACE_OPENXATTR
))
2815 namespace = xattr_namespace(name
);
2816 if (namespace == XATTRNS_NONE
)
2819 /* parent directory must be executable */
2820 if (ntfs_fuse_fill_security_context(&security
)
2821 && !ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)) {
2824 /* security and trusted only settable by root */
2825 if (((namespace == XATTRNS_SECURITY
)
2826 || (namespace == XATTRNS_TRUSTED
))
2830 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
2834 switch (namespace) {
2835 case XATTRNS_SECURITY
:
2836 case XATTRNS_TRUSTED
:
2842 case XATTRNS_SYSTEM
:
2843 if (!ntfs_allowed_as_owner(&security
,path
,ni
)) {
2849 if (!ntfs_allowed_access(&security
,path
,ni
,S_IWRITE
)) {
2856 lename_len
= fix_xattr_prefix(name
, namespace, &lename
);
2857 if (lename_len
== -1) {
2861 na
= ntfs_attr_open(ni
, AT_DATA
, lename
, lename_len
);
2862 if (na
&& flags
== XATTR_CREATE
) {
2867 if (flags
== XATTR_REPLACE
) {
2871 if (ntfs_attr_add(ni
, AT_DATA
, lename
, lename_len
, NULL
, 0)) {
2876 na
= ntfs_attr_open(ni
, AT_DATA
, lename
, lename_len
);
2882 /* currently compressed streams can only be wiped out */
2883 if (ntfs_attr_truncate(na
, (s64
)0 /* size */)) {
2891 part
= ntfs_attr_pwrite(na
, total
, size
- total
,
2895 } while ((part
> 0) && (total
< size
));
2899 if (!(res
= ntfs_attr_pclose(na
)))
2901 && (ni
->flags
& FILE_ATTR_ENCRYPTED
))
2902 res
= ntfs_efs_fixup_attribute(NULL
,
2910 ntfs_attr_close(na
);
2912 if (ntfs_inode_close(ni
))
2913 set_fuse_error(&res
);
2917 static int ntfs_fuse_removexattr(const char *path
, const char *name
)
2920 ntfschar
*lename
= NULL
;
2921 int res
= 0, lename_len
;
2924 struct SECURITY_CONTEXT security
;
2926 attr
= mapped_xattr_system(name
);
2927 if (attr
!= XATTR_UNMAPPED
) {
2931 * hijack internal data and ACL removal, whatever
2932 * mode was selected for xattr (from the user's
2933 * point of view, ACLs are not xattr)
2934 * Note : updating an ACL does not set ctime
2939 * Removal of NTFS ACL, ATTRIB, EFSINFO or TIMES
2942 case XATTR_NTFS_ACL
:
2943 case XATTR_NTFS_ATTRIB
:
2944 case XATTR_NTFS_EFSINFO
:
2945 case XATTR_NTFS_TIMES
:
2948 case XATTR_POSIX_ACC
:
2949 case XATTR_POSIX_DEF
:
2950 ni
= ntfs_check_access_xattr(&security
,path
,attr
,TRUE
);
2952 if (!ntfs_allowed_as_owner(&security
,path
,ni
)
2953 || ntfs_remove_posix_acl(&security
,path
,
2956 if (ntfs_inode_close(ni
))
2957 set_fuse_error(&res
);
2961 case XATTR_NTFS_REPARSE_DATA
:
2962 ni
= ntfs_check_access_xattr(&security
,path
,attr
,TRUE
);
2964 if (!ntfs_allowed_as_owner(&security
,path
,ni
)
2965 || ntfs_remove_ntfs_reparse_data(path
,ni
))
2967 if (ntfs_inode_close(ni
))
2968 set_fuse_error(&res
);
2972 case XATTR_NTFS_DOS_NAME
:
2973 ni
= ntfs_check_access_xattr(&security
,path
,attr
,TRUE
);
2975 if (ntfs_remove_ntfs_dos_name(path
,ni
))
2988 * Only hijack NTFS ACL and ATTRIB removal if POSIX ACLS
2989 * option is not selected
2990 * Access control is partially done by fuse
2992 if (ntfs_fuse_is_named_data_stream(path
))
2993 res
= -EINVAL
; /* n/a for named data streams. */
2997 * Removal of NTFS ACL, ATTRIB, EFSINFO or TIMES
3000 case XATTR_NTFS_ACL
:
3001 case XATTR_NTFS_ATTRIB
:
3002 case XATTR_NTFS_EFSINFO
:
3003 case XATTR_NTFS_TIMES
:
3006 case XATTR_NTFS_REPARSE_DATA
:
3007 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
3010 * user mapping is not mandatory
3011 * if defined, only owner is allowed
3013 if ((ntfs_fuse_fill_security_context(&security
)
3014 && !ntfs_allowed_as_owner(&security
,path
,ni
))
3015 || ntfs_remove_ntfs_reparse_data(path
,ni
))
3017 if (ntfs_inode_close(ni
))
3018 set_fuse_error(&res
);
3022 case XATTR_NTFS_DOS_NAME
:
3023 ni
= ntfs_check_access_xattr(&security
,path
,attr
,TRUE
);
3025 if (ntfs_remove_ntfs_dos_name(path
,ni
))
3032 * make sure applications do not see
3033 * Posix ACL not consistent with mode
3043 if ((ctx
->streams
!= NF_STREAMS_INTERFACE_XATTR
)
3044 && (ctx
->streams
!= NF_STREAMS_INTERFACE_OPENXATTR
))
3046 namespace = xattr_namespace(name
);
3047 if (namespace == XATTRNS_NONE
)
3050 /* parent directory must be executable */
3051 if (ntfs_fuse_fill_security_context(&security
)
3052 && !ntfs_allowed_dir_access(&security
,path
,S_IEXEC
)) {
3055 /* security and trusted only settable by root */
3056 if (((namespace == XATTRNS_SECURITY
)
3057 || (namespace == XATTRNS_TRUSTED
))
3061 ni
= ntfs_pathname_to_inode(ctx
->vol
, NULL
, path
);
3065 switch (namespace) {
3066 case XATTRNS_SECURITY
:
3067 case XATTRNS_TRUSTED
:
3073 case XATTRNS_SYSTEM
:
3074 if (!ntfs_allowed_as_owner(&security
,path
,ni
)) {
3080 if (!ntfs_allowed_access(&security
,path
,ni
,S_IWRITE
)) {
3087 lename_len
= fix_xattr_prefix(name
, namespace, &lename
);
3088 if (lename_len
== -1) {
3092 if (ntfs_attr_remove(ni
, AT_DATA
, lename
, lename_len
)) {
3093 if (errno
== ENOENT
)
3100 if (ntfs_inode_close(ni
))
3101 set_fuse_error(&res
);
3107 #error "Option inconsistency : POSIXACLS requires SETXATTR"
3109 #endif /* HAVE_SETXATTR */
3111 static void ntfs_close(void)
3113 struct SECURITY_CONTEXT security
;
3122 ntfs_log_info("Unmounting %s (%s)\n", opts
.device
,
3123 ctx
->vol
->vol_name
);
3124 if (ntfs_fuse_fill_security_context(&security
)) {
3125 if (ctx
->seccache
&& ctx
->seccache
->head
.p_reads
) {
3126 ntfs_log_info("Permissions cache : %lu writes, "
3127 "%lu reads, %lu.%1lu%% hits\n",
3128 ctx
->seccache
->head
.p_writes
,
3129 ctx
->seccache
->head
.p_reads
,
3130 100 * ctx
->seccache
->head
.p_hits
3131 / ctx
->seccache
->head
.p_reads
,
3132 1000 * ctx
->seccache
->head
.p_hits
3133 / ctx
->seccache
->head
.p_reads
% 10);
3136 ntfs_close_secure(&security
);
3139 if (ntfs_umount(ctx
->vol
, FALSE
))
3140 ntfs_log_perror("Failed to close volume %s", opts
.device
);
3145 static void ntfs_fuse_destroy2(void *unused
__attribute__((unused
)))
3150 static struct fuse_operations ntfs_3g_ops
= {
3151 .getattr
= ntfs_fuse_getattr
,
3152 .readlink
= ntfs_fuse_readlink
,
3153 .readdir
= ntfs_fuse_readdir
,
3154 .open
= ntfs_fuse_open
,
3155 .release
= ntfs_fuse_release
,
3156 .read
= ntfs_fuse_read
,
3157 .write
= ntfs_fuse_write
,
3158 .truncate
= ntfs_fuse_truncate
,
3159 .ftruncate
= ntfs_fuse_ftruncate
,
3160 .statfs
= ntfs_fuse_statfs
,
3161 .chmod
= ntfs_fuse_chmod
,
3162 .chown
= ntfs_fuse_chown
,
3163 .create
= ntfs_fuse_create_file
,
3164 .mknod
= ntfs_fuse_mknod
,
3165 .symlink
= ntfs_fuse_symlink
,
3166 .link
= ntfs_fuse_link
,
3167 .unlink
= ntfs_fuse_unlink
,
3168 .rename
= ntfs_fuse_rename
,
3169 .mkdir
= ntfs_fuse_mkdir
,
3170 .rmdir
= ntfs_fuse_rmdir
,
3171 .utime
= ntfs_fuse_utime
,
3172 .bmap
= ntfs_fuse_bmap
,
3173 .destroy
= ntfs_fuse_destroy2
,
3175 .access
= ntfs_fuse_access
,
3176 .opendir
= ntfs_fuse_opendir
,
3178 #ifdef HAVE_SETXATTR
3179 .getxattr
= ntfs_fuse_getxattr
,
3180 .setxattr
= ntfs_fuse_setxattr
,
3181 .removexattr
= ntfs_fuse_removexattr
,
3182 .listxattr
= ntfs_fuse_listxattr
,
3183 #endif /* HAVE_SETXATTR */
3184 #if defined(__APPLE__) || defined(__DARWIN__)
3185 .init
= ntfs_macfuse_init
,
3186 /* MacFUSE extensions. */
3187 .getxtimes
= ntfs_macfuse_getxtimes
,
3188 .setcrtime
= ntfs_macfuse_setcrtime
,
3189 .setbkuptime
= ntfs_macfuse_setbkuptime
,
3190 .setchgtime
= ntfs_macfuse_setchgtime
,
3191 #else /* defined(__APPLE__) || defined(__DARWIN__) */
3192 #ifdef FUSE_CAP_DONT_MASK
3195 #endif /* defined(__APPLE__) || defined(__DARWIN__) */
3198 static int ntfs_fuse_init(void)
3200 ctx
= ntfs_calloc(sizeof(ntfs_fuse_context_t
));
3204 *ctx
= (ntfs_fuse_context_t
) {
3208 .streams
= NF_STREAMS_INTERFACE_XATTR
,
3210 .streams
= NF_STREAMS_INTERFACE_NONE
,
3212 .atime
= ATIME_RELATIVE
,
3219 static int ntfs_open(const char *device
)
3221 unsigned long flags
= 0;
3224 flags
|= MS_EXCLUSIVE
;
3228 flags
|= MS_RECOVER
;
3230 flags
|= MS_IGNORE_HIBERFILE
;
3232 ctx
->vol
= ntfs_mount(device
, flags
);
3234 ntfs_log_perror("Failed to mount '%s'", device
);
3238 ctx
->vol
->free_clusters
= ntfs_attr_get_free_bits(ctx
->vol
->lcnbmp_na
);
3239 if (ctx
->vol
->free_clusters
< 0) {
3240 ntfs_log_perror("Failed to read NTFS $Bitmap");
3244 ctx
->vol
->free_mft_records
= ntfs_get_nr_free_mft_records(ctx
->vol
);
3245 if (ctx
->vol
->free_mft_records
< 0) {
3246 ntfs_log_perror("Failed to calculate free MFT records");
3250 if (ctx
->hiberfile
&& ntfs_volume_check_hiberfile(ctx
->vol
, 0)) {
3253 if (ntfs_fuse_rm("/hiberfil.sys"))
3259 return ntfs_volume_error(errno
);
3263 #define STRAPPEND_MAX_INSIZE 8192
3264 #define strappend_is_large(x) ((x) > STRAPPEND_MAX_INSIZE)
3266 static int strappend(char **dest
, const char *append
)
3269 size_t size_append
, size_dest
= 0;
3276 size_append
= strlen(append
);
3278 size_dest
= strlen(*dest
);
3280 if (strappend_is_large(size_dest
) || strappend_is_large(size_append
)) {
3282 ntfs_log_perror("%s: Too large input buffer", EXEC_NAME
);
3286 p
= realloc(*dest
, size_dest
+ size_append
+ 1);
3288 ntfs_log_perror("%s: Memory realloction failed", EXEC_NAME
);
3293 strcpy(*dest
+ size_dest
, append
);
3298 static int bogus_option_value(char *val
, const char *s
)
3301 ntfs_log_error("'%s' option shouldn't have value.\n", s
);
3307 static int missing_option_value(char *val
, const char *s
)
3310 ntfs_log_error("'%s' option should have a value.\n", s
);
3316 static char *parse_mount_options(const char *orig_opts
)
3318 char *options
, *s
, *opt
, *val
, *ret
= NULL
;
3319 BOOL no_def_opts
= FALSE
;
3320 int default_permissions
= 0;
3321 int want_permissions
= 0;
3323 ctx
->secure_flags
= 0;
3324 ctx
->efs_raw
= FALSE
;
3325 options
= strdup(orig_opts
? orig_opts
: "");
3327 ntfs_log_perror("%s: strdup failed", EXEC_NAME
);
3332 while (s
&& *s
&& (val
= strsep(&s
, ","))) {
3333 opt
= strsep(&val
, "=");
3334 if (!strcmp(opt
, "ro")) { /* Read-only mount. */
3335 if (bogus_option_value(val
, "ro"))
3338 if (strappend(&ret
, "ro,"))
3340 } else if (!strcmp(opt
, "noatime")) {
3341 if (bogus_option_value(val
, "noatime"))
3343 ctx
->atime
= ATIME_DISABLED
;
3344 } else if (!strcmp(opt
, "atime")) {
3345 if (bogus_option_value(val
, "atime"))
3347 ctx
->atime
= ATIME_ENABLED
;
3348 } else if (!strcmp(opt
, "relatime")) {
3349 if (bogus_option_value(val
, "relatime"))
3351 ctx
->atime
= ATIME_RELATIVE
;
3352 } else if (!strcmp(opt
, "fake_rw")) {
3353 if (bogus_option_value(val
, "fake_rw"))
3356 } else if (!strcmp(opt
, "fsname")) { /* Filesystem name. */
3358 * We need this to be able to check whether filesystem
3361 ntfs_log_error("'fsname' is unsupported option.\n");
3363 } else if (!strcmp(opt
, "no_def_opts")) {
3364 if (bogus_option_value(val
, "no_def_opts"))
3366 no_def_opts
= TRUE
; /* Don't add default options. */
3367 } else if (!strcmp(opt
, "default_permissions")) {
3368 default_permissions
= 1;
3369 } else if (!strcmp(opt
, "umask")) {
3370 if (missing_option_value(val
, "umask"))
3372 sscanf(val
, "%o", &ctx
->fmask
);
3373 ctx
->dmask
= ctx
->fmask
;
3375 default_permissions
= 1;
3377 } else if (!strcmp(opt
, "fmask")) {
3378 if (missing_option_value(val
, "fmask"))
3380 sscanf(val
, "%o", &ctx
->fmask
);
3381 want_permissions
= 1;
3382 } else if (!strcmp(opt
, "dmask")) {
3383 if (missing_option_value(val
, "dmask"))
3385 sscanf(val
, "%o", &ctx
->dmask
);
3386 want_permissions
= 1;
3387 } else if (!strcmp(opt
, "uid")) {
3388 if (missing_option_value(val
, "uid"))
3390 sscanf(val
, "%i", &ctx
->uid
);
3391 want_permissions
= 1;
3392 } else if (!strcmp(opt
, "gid")) {
3393 if (missing_option_value(val
, "gid"))
3395 sscanf(val
, "%i", &ctx
->gid
);
3396 want_permissions
= 1;
3397 } else if (!strcmp(opt
, "show_sys_files")) {
3398 if (bogus_option_value(val
, "show_sys_files"))
3400 ctx
->show_sys_files
= TRUE
;
3401 } else if (!strcmp(opt
, "silent")) {
3402 if (bogus_option_value(val
, "silent"))
3405 } else if (!strcmp(opt
, "recover")) {
3406 if (bogus_option_value(val
, "recover"))
3408 ctx
->recover
= TRUE
;
3409 } else if (!strcmp(opt
, "norecover")) {
3410 if (bogus_option_value(val
, "norecover"))
3412 ctx
->recover
= FALSE
;
3413 } else if (!strcmp(opt
, "remove_hiberfile")) {
3414 if (bogus_option_value(val
, "remove_hiberfile"))
3416 ctx
->hiberfile
= TRUE
;
3417 } else if (!strcmp(opt
, "locale")) {
3418 if (missing_option_value(val
, "locale"))
3420 ntfs_set_char_encoding(val
);
3421 #if defined(__APPLE__) || defined(__DARWIN__)
3422 #ifdef ENABLE_NFCONV
3423 } else if (!strcmp(opt
, "nfconv")) {
3424 if (bogus_option_value(val
, "nfconv"))
3426 if (ntfs_macosx_normalize_filenames(1)) {
3427 ntfs_log_error("ntfs_macosx_normalize_filenames(1) failed!\n");
3430 } else if (!strcmp(opt
, "nonfconv")) {
3431 if (bogus_option_value(val
, "nonfconv"))
3433 if (ntfs_macosx_normalize_filenames(0)) {
3434 ntfs_log_error("ntfs_macosx_normalize_filenames(0) failed!\n");
3437 #endif /* ENABLE_NFCONV */
3438 #endif /* defined(__APPLE__) || defined(__DARWIN__) */
3439 } else if (!strcmp(opt
, "streams_interface")) {
3440 if (missing_option_value(val
, "streams_interface"))
3442 if (!strcmp(val
, "none"))
3443 ctx
->streams
= NF_STREAMS_INTERFACE_NONE
;
3444 else if (!strcmp(val
, "xattr"))
3445 ctx
->streams
= NF_STREAMS_INTERFACE_XATTR
;
3446 else if (!strcmp(val
, "openxattr"))
3447 ctx
->streams
= NF_STREAMS_INTERFACE_OPENXATTR
;
3448 else if (!strcmp(val
, "windows"))
3449 ctx
->streams
= NF_STREAMS_INTERFACE_WINDOWS
;
3451 ntfs_log_error("Invalid named data streams "
3452 "access interface.\n");
3455 } else if (!strcmp(opt
, "user_xattr")) {
3456 ctx
->streams
= NF_STREAMS_INTERFACE_XATTR
;
3457 } else if (!strcmp(opt
, "noauto")) {
3458 /* Don't pass noauto option to fuse. */
3459 } else if (!strcmp(opt
, "debug")) {
3460 if (bogus_option_value(val
, "debug"))
3463 ntfs_log_set_levels(NTFS_LOG_LEVEL_DEBUG
);
3464 ntfs_log_set_levels(NTFS_LOG_LEVEL_TRACE
);
3465 } else if (!strcmp(opt
, "no_detach")) {
3466 if (bogus_option_value(val
, "no_detach"))
3468 ctx
->no_detach
= TRUE
;
3469 } else if (!strcmp(opt
, "remount")) {
3470 ntfs_log_error("Remounting is not supported at present."
3471 " You have to umount volume and then "
3472 "mount it once again.\n");
3474 } else if (!strcmp(opt
, "blksize")) {
3475 ntfs_log_info("WARNING: blksize option is ignored "
3476 "because ntfs-3g must calculate it.\n");
3477 } else if (!strcmp(opt
, "inherit")) {
3479 * JPA do not overwrite inherited permissions
3482 ctx
->inherit
= TRUE
;
3483 } else if (!strcmp(opt
, "addsecurids")) {
3485 * JPA create security ids for files being read
3486 * with an individual security attribute
3488 ctx
->secure_flags
|= (1 << SECURITY_ADDSECURIDS
);
3489 } else if (!strcmp(opt
, "staticgrps")) {
3491 * JPA use static definition of groups
3492 * for file access control
3494 ctx
->secure_flags
|= (1 << SECURITY_STATICGRPS
);
3495 } else if (!strcmp(opt
, "usermapping")) {
3497 ntfs_log_error("'usermapping' option should have "
3501 ctx
->usermap_path
= strdup(val
);
3502 if (!ctx
->usermap_path
) {
3503 ntfs_log_error("no more memory to store "
3504 "'usermapping' option.\n");
3507 } else if (!strcmp(opt
, "efs_raw")) {
3508 if (bogus_option_value(val
, "efs_raw"))
3510 ctx
->efs_raw
= TRUE
;
3511 } else { /* Probably FUSE option. */
3512 if (strappend(&ret
, opt
))
3515 if (strappend(&ret
, "="))
3517 if (strappend(&ret
, val
))
3520 if (strappend(&ret
, ","))
3524 if (!no_def_opts
&& strappend(&ret
, def_opts
))
3526 if (default_permissions
&& strappend(&ret
, "default_permissions,"))
3529 if (ctx
->atime
== ATIME_RELATIVE
&& strappend(&ret
, "relatime,"))
3531 else if (ctx
->atime
== ATIME_ENABLED
&& strappend(&ret
, "atime,"))
3533 else if (ctx
->atime
== ATIME_DISABLED
&& strappend(&ret
, "noatime,"))
3536 if (strappend(&ret
, "fsname="))
3538 if (strappend(&ret
, opts
.device
))
3540 if (default_permissions
)
3541 ctx
->secure_flags
|= (1 << SECURITY_DEFAULT
);
3542 if (want_permissions
)
3543 ctx
->secure_flags
|= (1 << SECURITY_WANTED
);
3545 ctx
->secure_flags
&= ~(1 << SECURITY_ADDSECURIDS
);
3555 static void usage(void)
3557 ntfs_log_info(usage_msg
, EXEC_NAME
, VERSION
, FUSE_TYPE
, fuse_version(),
3558 EXEC_NAME
, ntfs_home
);
3561 #ifndef HAVE_REALPATH
3562 /* If there is no realpath() on the system, provide a dummy one. */
3563 static char *realpath(const char *path
, char *resolved_path
)
3565 strncpy(resolved_path
, path
, PATH_MAX
);
3566 resolved_path
[PATH_MAX
] = '\0';
3567 return resolved_path
;
3572 * parse_options - Read and validate the programs command line
3573 * Read the command line, verify the syntax and parse the options.
3575 * Return: 0 success, -1 error.
3577 static int parse_options(int argc
, char *argv
[])
3581 static const char *sopt
= "-o:hvV";
3582 static const struct option lopt
[] = {
3583 { "options", required_argument
, NULL
, 'o' },
3584 { "help", no_argument
, NULL
, 'h' },
3585 { "verbose", no_argument
, NULL
, 'v' },
3586 { "version", no_argument
, NULL
, 'V' },
3587 { NULL
, 0, NULL
, 0 }
3590 opterr
= 0; /* We'll handle the errors, thank you. */
3592 while ((c
= getopt_long(argc
, argv
, sopt
, lopt
, NULL
)) != -1) {
3594 case 1: /* A non-option argument */
3596 opts
.device
= ntfs_malloc(PATH_MAX
+ 1);
3600 /* Canonicalize device name (mtab, etc) */
3601 if (!realpath(optarg
, opts
.device
)) {
3602 ntfs_log_perror("%s: Failed to access "
3603 "volume '%s'", EXEC_NAME
, optarg
);
3608 } else if (!opts
.mnt_point
) {
3609 opts
.mnt_point
= optarg
;
3611 ntfs_log_error("%s: You must specify exactly one "
3612 "device and exactly one mount "
3613 "point.\n", EXEC_NAME
);
3619 if (strappend(&opts
.options
, ","))
3621 if (strappend(&opts
.options
, optarg
))
3629 * We must handle the 'verbose' option even if
3630 * we don't use it because mount(8) passes it.
3634 ntfs_log_info("%s %s %s %d\n", EXEC_NAME
, VERSION
,
3635 FUSE_TYPE
, fuse_version());
3638 ntfs_log_error("%s: Unknown option '%s'.\n", EXEC_NAME
,
3645 ntfs_log_error("%s: No device is specified.\n", EXEC_NAME
);
3648 if (!opts
.mnt_point
) {
3649 ntfs_log_error("%s: No mountpoint is specified.\n", EXEC_NAME
);
3656 #if defined(linux) || defined(__uClinux__)
3658 static const char *dev_fuse_msg
=
3659 "HINT: You should be root, or make ntfs-3g setuid root, or load the FUSE\n"
3660 " kernel module as root ('modprobe fuse' or 'insmod <path_to>/fuse.ko'"
3661 " or insmod <path_to>/fuse.o'). Make also sure that the fuse device"
3662 " exists. It's usually either /dev/fuse or /dev/misc/fuse.";
3664 static const char *fuse26_kmod_msg
=
3665 "WARNING: Deficient Linux kernel detected. Some driver features are\n"
3666 " not available (swap file on NTFS, boot from NTFS by LILO), and\n"
3667 " unmount is not safe unless it's made sure the ntfs-3g process\n"
3668 " naturally terminates after calling 'umount'. If you wish this\n"
3669 " message to disappear then you should upgrade to at least kernel\n"
3670 " version 2.6.20, or request help from your distribution to fix\n"
3671 " the kernel problem. The below web page has more information:\n"
3672 " http://ntfs-3g.org/support.html#fuse26\n"
3675 static void mknod_dev_fuse(const char *dev
)
3679 if (stat(dev
, &st
) && (errno
== ENOENT
)) {
3680 mode_t mask
= umask(0);
3681 if (mknod(dev
, S_IFCHR
| 0666, makedev(10, 229))) {
3682 ntfs_log_perror("Failed to create '%s'", dev
);
3684 ntfs_log_error("%s", dev_fuse_msg
);
3690 static void create_dev_fuse(void)
3692 mknod_dev_fuse("/dev/fuse");
3697 /* The fuse device is under /dev/misc using devfs. */
3698 if (stat("/dev/misc", &st
) && (errno
== ENOENT
)) {
3699 mode_t mask
= umask(0);
3700 mkdir("/dev/misc", 0775);
3703 mknod_dev_fuse("/dev/misc/fuse");
3708 static fuse_fstype
get_fuse_fstype(void)
3711 fuse_fstype fstype
= FSTYPE_NONE
;
3713 FILE *f
= fopen("/proc/filesystems", "r");
3715 ntfs_log_perror("Failed to open /proc/filesystems");
3716 return FSTYPE_UNKNOWN
;
3719 while (fgets(buf
, sizeof(buf
), f
)) {
3720 if (strstr(buf
, "fuseblk\n")) {
3721 fstype
= FSTYPE_FUSEBLK
;
3724 if (strstr(buf
, "fuse\n"))
3725 fstype
= FSTYPE_FUSE
;
3732 static fuse_fstype
load_fuse_module(void)
3737 const char *cmd
= "/sbin/modprobe";
3738 struct timespec req
= { 0, 100000000 }; /* 100 msec */
3741 if (!stat(cmd
, &st
) && !geteuid()) {
3744 execl(cmd
, cmd
, "fuse", NULL
);
3746 } else if (pid
!= -1)
3747 waitpid(pid
, NULL
, 0);
3750 for (i
= 0; i
< 10; i
++) {
3752 * We sleep first because despite the detection of the loaded
3753 * FUSE kernel module, fuse_mount() can still fail if it's not
3754 * fully functional/initialized. Note, of course this is still
3755 * unreliable but usually helps.
3757 nanosleep(&req
, NULL
);
3758 fstype
= get_fuse_fstype();
3759 if (fstype
!= FSTYPE_NONE
)
3767 static struct fuse_chan
*try_fuse_mount(char *parsed_options
)
3769 struct fuse_chan
*fc
= NULL
;
3770 struct fuse_args margs
= FUSE_ARGS_INIT(0, NULL
);
3772 /* The fuse_mount() options get modified, so we always rebuild it */
3773 if ((fuse_opt_add_arg(&margs
, EXEC_NAME
) == -1 ||
3774 fuse_opt_add_arg(&margs
, "-o") == -1 ||
3775 fuse_opt_add_arg(&margs
, parsed_options
) == -1)) {
3776 ntfs_log_error("Failed to set FUSE options.\n");
3780 fc
= fuse_mount(opts
.mnt_point
, &margs
);
3782 fuse_opt_free_args(&margs
);
3787 static int set_fuseblk_options(char **parsed_options
)
3791 u32 blksize
= ctx
->vol
->cluster_size
;
3793 pagesize
= sysconf(_SC_PAGESIZE
);
3797 if (blksize
> (u32
)pagesize
)
3800 snprintf(options
, sizeof(options
), ",blkdev,blksize=%u", blksize
);
3801 if (strappend(parsed_options
, options
))
3806 static struct fuse
*mount_fuse(char *parsed_options
)
3808 struct fuse
*fh
= NULL
;
3809 struct fuse_args args
= FUSE_ARGS_INIT(0, NULL
);
3811 ctx
->fc
= try_fuse_mount(parsed_options
);
3815 if (fuse_opt_add_arg(&args
, "") == -1)
3817 if (fuse_opt_add_arg(&args
, "-ouse_ino,kernel_cache,attr_timeout=0") == -1)
3820 if (fuse_opt_add_arg(&args
, "-odebug") == -1)
3823 fh
= fuse_new(ctx
->fc
, &args
, &ntfs_3g_ops
, sizeof(ntfs_3g_ops
), NULL
);
3827 if (fuse_set_signal_handlers(fuse_get_session(fh
)))
3830 fuse_opt_free_args(&args
);
3836 fuse_unmount(opts
.mnt_point
, ctx
->fc
);
3840 static void setup_logging(char *parsed_options
)
3842 if (!ctx
->no_detach
) {
3843 if (daemon(0, ctx
->debug
))
3844 ntfs_log_error("Failed to daemonize.\n");
3845 else if (!ctx
->debug
) {
3847 ntfs_log_set_handler(ntfs_log_handler_syslog
);
3848 /* Override default libntfs identify. */
3849 openlog(EXEC_NAME
, LOG_PID
, LOG_DAEMON
);
3854 ctx
->seccache
= (struct PERMISSIONS_CACHE
*)NULL
;
3856 ntfs_log_info("Version %s %s %d\n", VERSION
, FUSE_TYPE
, fuse_version());
3857 ntfs_log_info("Mounted %s (%s, label \"%s\", NTFS %d.%d)\n",
3858 opts
.device
, (ctx
->ro
) ? "Read-Only" : "Read-Write",
3859 ctx
->vol
->vol_name
, ctx
->vol
->major_ver
,
3860 ctx
->vol
->minor_ver
);
3861 ntfs_log_info("Cmdline options: %s\n", opts
.options
? opts
.options
: "");
3862 ntfs_log_info("Mount options: %s\n", parsed_options
);
3865 int main(int argc
, char *argv
[])
3867 char *parsed_options
= NULL
;
3869 fuse_fstype fstype
= FSTYPE_UNKNOWN
;
3870 const char *permissions_mode
= (const char*)NULL
;
3871 const char *failed_secure
= (const char*)NULL
;
3876 * Make sure file descriptors 0, 1 and 2 are open,
3877 * otherwise chaos would ensue.
3880 fd
= open("/dev/null", O_RDWR
);
3883 } while (fd
>= 0 && fd
<= 2);
3885 #ifndef FUSE_INTERNAL
3886 if ((getuid() != geteuid()) || (getgid() != getegid())) {
3887 fprintf(stderr
, "%s", setuid_msg
);
3888 return NTFS_VOLUME_INSECURE
;
3892 return NTFS_VOLUME_NO_PRIVILEGE
;
3895 ntfs_log_set_handler(ntfs_log_handler_stderr
);
3897 if (parse_options(argc
, argv
)) {
3899 return NTFS_VOLUME_SYNTAX_ERROR
;
3902 if (ntfs_fuse_init()) {
3903 err
= NTFS_VOLUME_OUT_OF_MEMORY
;
3907 parsed_options
= parse_mount_options(opts
.options
);
3908 if (!parsed_options
) {
3909 err
= NTFS_VOLUME_SYNTAX_ERROR
;
3913 ctx
->security
.uid
= 0;
3914 ctx
->security
.gid
= 0;
3915 if ((opts
.mnt_point
[0] == '/')
3916 && !stat(opts
.mnt_point
,&sbuf
)) {
3917 /* collect owner of mount point, useful for default mapping */
3918 ctx
->security
.uid
= sbuf
.st_uid
;
3919 ctx
->security
.gid
= sbuf
.st_gid
;
3922 #if defined(linux) || defined(__uClinux__)
3923 fstype
= get_fuse_fstype();
3925 err
= NTFS_VOLUME_NO_PRIVILEGE
;
3926 if (restore_privs())
3929 if (fstype
== FSTYPE_NONE
|| fstype
== FSTYPE_UNKNOWN
)
3930 fstype
= load_fuse_module();
3937 if (stat(opts
.device
, &sbuf
)) {
3938 ntfs_log_perror("Failed to access '%s'", opts
.device
);
3939 err
= NTFS_VOLUME_NO_PRIVILEGE
;
3943 #if !(defined(__sun) && defined (__SVR4))
3944 /* Always use fuseblk for block devices unless it's surely missing. */
3945 if (S_ISBLK(sbuf
.st_mode
) && (fstype
!= FSTYPE_FUSE
))
3949 #ifndef FUSE_INTERNAL
3950 if (getuid() && ctx
->blkdev
) {
3951 ntfs_log_error("%s", unpriv_fuseblk_msg
);
3955 err
= ntfs_open(opts
.device
);
3959 /* We must do this after ntfs_open() to be able to set the blksize */
3960 if (ctx
->blkdev
&& set_fuseblk_options(&parsed_options
))
3963 ctx
->security
.vol
= ctx
->vol
;
3964 ctx
->vol
->secure_flags
= ctx
->secure_flags
;
3965 ctx
->vol
->efs_raw
= ctx
->efs_raw
;
3966 /* JPA open $Secure, (whatever NTFS version !) */
3967 /* to initialize security data */
3968 if (ntfs_open_secure(ctx
->vol
) && (ctx
->vol
->major_ver
>= 3))
3969 failed_secure
= "Could not open file $Secure";
3970 if (!ntfs_build_mapping(&ctx
->security
,ctx
->usermap_path
)) {
3972 if (ctx
->vol
->secure_flags
& (1 << SECURITY_DEFAULT
))
3973 permissions_mode
= "User mapping built, Posix ACLs not used";
3975 permissions_mode
= "User mapping built, Posix ACLs in use";
3977 if (!(ctx
->vol
->secure_flags
& (1 << SECURITY_DEFAULT
))) {
3979 * No explicit option but user mapping found
3980 * force default security
3982 ctx
->vol
->secure_flags
|= (1 << SECURITY_DEFAULT
);
3983 if (strappend(&parsed_options
, ",default_permissions")) {
3984 err
= NTFS_VOLUME_SYNTAX_ERROR
;
3988 permissions_mode
= "User mapping built";
3991 ctx
->security
.uid
= ctx
->uid
;
3992 ctx
->security
.gid
= ctx
->gid
;
3993 /* same ownership/permissions for all files */
3994 ctx
->security
.mapping
[MAPUSERS
] = (struct MAPPING
*)NULL
;
3995 ctx
->security
.mapping
[MAPGROUPS
] = (struct MAPPING
*)NULL
;
3996 if (ctx
->secure_flags
& (1 << SECURITY_WANTED
))
3997 ctx
->secure_flags
|= (1 << SECURITY_DEFAULT
);
3998 if (ctx
->secure_flags
& (1 << SECURITY_DEFAULT
)) {
3999 ctx
->secure_flags
|= (1 << SECURITY_RAW
);
4000 permissions_mode
= "Global ownership and permissions enforced";
4002 ctx
->secure_flags
&= ~(1 << SECURITY_RAW
);
4003 permissions_mode
= "Ownership and permissions disabled";
4006 if (ctx
->usermap_path
)
4007 free (ctx
->usermap_path
);
4009 fh
= mount_fuse(parsed_options
);
4011 err
= NTFS_VOLUME_FUSE_ERROR
;
4015 ctx
->mounted
= TRUE
;
4017 #if defined(linux) || defined(__uClinux__)
4018 if (S_ISBLK(sbuf
.st_mode
) && (fstype
== FSTYPE_FUSE
))
4019 ntfs_log_info("%s", fuse26_kmod_msg
);
4021 setup_logging(parsed_options
);
4023 ntfs_log_info("%s\n",failed_secure
);
4024 if (permissions_mode
)
4025 ntfs_log_info("%s\n",permissions_mode
);
4031 fuse_unmount(opts
.mnt_point
, ctx
->fc
);
4034 ntfs_mount_error(opts
.device
, opts
.mnt_point
, err
);
4038 free(parsed_options
);