1 /**
2  * ntfs-3g - Third Generation NTFS Driver
3  *
4  * Copyright (c) 2005-2007 Yura Pakhuchiy
5  * Copyright (c) 2005 Yuval Fledel
6  * Copyright (c) 2006-2009 Szabolcs Szakacsits
7  * Copyright (c) 2007-2017 Jean-Pierre Andre
8  * Copyright (c) 2009 Erik Larsson
9  *
10  * This file is originated from the Linux-NTFS project.
11  *
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.
16  *
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.
21  *
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
26  */
27 
28 #include "config.h"
29 
30 #include <fuse.h>
31 #include <fuse_lowlevel.h>
32 
33 #if !defined(FUSE_VERSION) || (FUSE_VERSION < 26)
34 #error "***********************************************************"
35 #error "*                                                         *"
36 #error "*     Compilation requires at least FUSE version 2.6.0!   *"
37 #error "*                                                         *"
38 #error "***********************************************************"
39 #endif
40 
41 #ifdef HAVE_STDIO_H
42 #include <stdio.h>
43 #endif
44 #ifdef HAVE_STRING_H
45 #include <string.h>
46 #endif
47 #ifdef HAVE_ERRNO_H
48 #include <errno.h>
49 #endif
50 #ifdef HAVE_FCNTL_H
51 #include <fcntl.h>
52 #endif
53 #ifdef HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
56 #ifdef HAVE_STDLIB_H
57 #include <stdlib.h>
58 #endif
59 #ifdef HAVE_LOCALE_H
60 #include <locale.h>
61 #endif
62 #include <signal.h>
63 #ifdef HAVE_LIMITS_H
64 #include <limits.h>
65 #endif
66 #include <syslog.h>
67 #include <sys/wait.h>
68 
69 #ifdef HAVE_SETXATTR
70 #include <sys/xattr.h>
71 #endif
72 
73 #ifdef HAVE_SYS_TYPES_H
74 #include <sys/types.h>
75 #endif
76 #ifdef MAJOR_IN_MKDEV
77 #include <sys/mkdev.h>
78 #endif
79 #ifdef MAJOR_IN_SYSMACROS
80 #include <sys/sysmacros.h>
81 #endif
82 
83 #if defined(__APPLE__) || defined(__DARWIN__)
84 #include <sys/dirent.h>
85 #elif defined(__sun) && defined (__SVR4)
86 #include <sys/param.h>
87 #endif /* defined(__APPLE__) || defined(__DARWIN__), ... */
88 
89 #ifdef HAVE_LINUX_FS_H
90 #include <linux/fs.h>
91 #endif
92 
93 #ifndef FUSE_CAP_POSIX_ACL  /* until defined in <fuse/fuse_common.h> */
94 #define FUSE_CAP_POSIX_ACL (1 << 18)
95 #endif /* FUSE_CAP_POSIX_ACL */
96 
97 #include "compat.h"
98 #include "bitmap.h"
99 #include "attrib.h"
100 #include "inode.h"
101 #include "volume.h"
102 #include "dir.h"
103 #include "unistr.h"
104 #include "layout.h"
105 #include "index.h"
106 #include "ntfstime.h"
107 #include "security.h"
108 #include "reparse.h"
109 #include "object_id.h"
110 #include "efs.h"
111 #include "logging.h"
112 #include "xattrs.h"
113 #include "misc.h"
114 #include "ioctl.h"
115 #include "plugin.h"
116 
117 #include "ntfs-3g_common.h"
118 
119 /*
120  *	The following permission checking modes are governed by
121  *	the LPERMSCONFIG value in param.h
122  */
123 
124 /*	ACLS may be checked by kernel (requires a fuse patch) or here */
125 #define KERNELACLS ((LPERMSCONFIG > 6) & (LPERMSCONFIG < 10))
126 /*	basic permissions may be checked by kernel or here */
127 #define KERNELPERMS (((LPERMSCONFIG - 1) % 6) < 3)
128 /*	may want to use fuse/kernel cacheing */
129 #define CACHEING (!(LPERMSCONFIG % 3))
130 
131 #if KERNELACLS & !KERNELPERMS
132 #error "Incompatible options KERNELACLS and KERNELPERMS"
133 #endif
134 
135 #if !CACHEING
136 #define ATTR_TIMEOUT 0.0
137 #define ENTRY_TIMEOUT 0.0
138 #else
139 #if defined(__sun) && defined (__SVR4)
140 #define ATTR_TIMEOUT 10.0
141 #define ENTRY_TIMEOUT 10.0
142 #else /* defined(__sun) && defined (__SVR4) */
143 	/*
144 	 * FUSE cacheing is only usable with basic permissions
145 	 * checked by the kernel with external fuse >= 2.8
146 	 */
147 #if !KERNELPERMS
148 #warning "Fuse cacheing is only usable with basic permissions checked by kernel"
149 #endif
150 #if KERNELACLS
151 #define ATTR_TIMEOUT 10.0
152 #define ENTRY_TIMEOUT 10.0
153 #else /* KERNELACLS */
154 #define ATTR_TIMEOUT (ctx->vol->secure_flags & (1 << SECURITY_DEFAULT) ? 10.0 : 0.0)
155 #define ENTRY_TIMEOUT (ctx->vol->secure_flags & (1 << SECURITY_DEFAULT) ? 10.0 : 0.0)
156 #endif /* KERNELACLS */
157 #endif /* defined(__sun) && defined (__SVR4) */
158 #endif /* !CACHEING */
159 #define GHOSTLTH 40 /* max length of a ghost file name - see ghostformat */
160 
161 		/* sometimes the kernel cannot check access */
162 #define ntfs_real_allowed_access(scx, ni, type) ntfs_allowed_access(scx, ni, type)
163 #if POSIXACLS & KERNELPERMS & !KERNELACLS
164 		/* short-circuit if PERMS checked by kernel and ACLs by fs */
165 #define ntfs_allowed_access(scx, ni, type) \
166 	((scx)->vol->secure_flags & (1 << SECURITY_DEFAULT) \
167 	    ? 1 : ntfs_allowed_access(scx, ni, type))
168 #endif
169 
170 #define set_archive(ni) (ni)->flags |= FILE_ATTR_ARCHIVE
171 #define INODE(ino) ((ino) == 1 ? (MFT_REF)FILE_root : (MFT_REF)(ino))
172 
173 /*
174  *		Call a function from a reparse plugin (variable arguments)
175  *	Requires "reparse" and "ops" to have been defined
176  *
177  *	Returns a non-negative value if successful,
178  *		and a negative error code if something fails.
179  */
180 #define CALL_REPARSE_PLUGIN(ni, op_name, ...)			\
181 	 (reparse = (REPARSE_POINT*)NULL,			 \
182 	 ops = select_reparse_plugin(ctx, ni, &reparse),	 \
183 	 (!ops ? -errno						 \
184 		 : (ops->op_name ?				 \
185 			 ops->op_name(ni, reparse, __VA_ARGS__)  \
186 			 : -EOPNOTSUPP))),			 \
187 		 free(reparse)
188 
189 typedef enum {
190 	FSTYPE_NONE,
191 	FSTYPE_UNKNOWN,
192 	FSTYPE_FUSE,
193 	FSTYPE_FUSEBLK
194 } fuse_fstype;
195 
196 typedef struct fill_item {
197 	struct fill_item *next;
198 	size_t bufsize;
199 	size_t off;
200 	char buf[0];
201 } ntfs_fuse_fill_item_t;
202 
203 typedef struct fill_context {
204 	struct fill_item *first;
205 	struct fill_item *last;
206 	off_t off;
207 	fuse_req_t req;
208 	fuse_ino_t ino;
209 	BOOL filled;
210 } ntfs_fuse_fill_context_t;
211 
212 struct open_file {
213 	struct open_file *next;
214 	struct open_file *previous;
215 	long long ghost;
216 	fuse_ino_t ino;
217 	fuse_ino_t parent;
218 	int state;
219 #ifndef DISABLE_PLUGINS
220 	struct fuse_file_info fi;
221 #endif /* DISABLE_PLUGINS */
222 } ;
223 
224 enum {
225 	CLOSE_GHOST = 1,
226 	CLOSE_COMPRESSED = 2,
227 	CLOSE_ENCRYPTED = 4,
228 	CLOSE_DMTIME = 8,
229 	CLOSE_REPARSE = 16
230 };
231 
232 enum RM_TYPES {
233 	RM_LINK,
234 	RM_DIR,
235 	RM_ANY,
236 } ;
237 
238 static struct ntfs_options opts;
239 
240 const char *EXEC_NAME = "lowntfs-3g";
241 
242 static ntfs_fuse_context_t *ctx;
243 static u32 ntfs_sequence;
244 static const char ghostformat[] = ".ghost-ntfs-3g-%020llu";
245 
246 static const char *usage_msg =
247 "\n"
248 "%s %s %s %d - Third Generation NTFS Driver\n"
249 "\t\tConfiguration type %d, "
250 #ifdef HAVE_SETXATTR
251 "XATTRS are on, "
252 #else
253 "XATTRS are off, "
254 #endif
255 #if POSIXACLS
256 "POSIX ACLS are on\n"
257 #else
258 "POSIX ACLS are off\n"
259 #endif
260 "\n"
261 "Copyright (C) 2005-2007 Yura Pakhuchiy\n"
262 "Copyright (C) 2006-2009 Szabolcs Szakacsits\n"
263 "Copyright (C) 2007-2017 Jean-Pierre Andre\n"
264 "Copyright (C) 2009 Erik Larsson\n"
265 "\n"
266 "Usage:    %s [-o option[,...]] <device|image_file> <mount_point>\n"
267 "\n"
268 "Options:  ro (read-only mount), windows_names, uid=, gid=,\n"
269 "          umask=, fmask=, dmask=, streams_interface=.\n"
270 "          Please see the details in the manual (type: man ntfs-3g).\n"
271 "\n"
272 "Example: ntfs-3g /dev/sda1 /mnt/windows\n"
273 "\n"
274 "%s";
275 
276 static const char ntfs_bad_reparse[] = "unsupported reparse point";
277 
278 #ifdef FUSE_INTERNAL
279 int drop_privs(void);
280 int restore_privs(void);
281 #else
282 /*
283  * setuid and setgid root ntfs-3g denies to start with external FUSE,
284  * therefore the below functions are no-op in such case.
285  */
drop_privs(void)286 static int drop_privs(void)    { return 0; }
287 #if defined(linux) || defined(__uClinux__)
restore_privs(void)288 static int restore_privs(void) { return 0; }
289 #endif
290 
291 static const char *setuid_msg =
292 "Mount is denied because setuid and setgid root ntfs-3g is insecure with the\n"
293 "external FUSE library. Either remove the setuid/setgid bit from the binary\n"
294 "or rebuild NTFS-3G with integrated FUSE support and make it setuid root.\n"
295 "Please see more information at\n"
296 "http://tuxera.com/community/ntfs-3g-faq/#unprivileged\n";
297 
298 static const char *unpriv_fuseblk_msg =
299 "Unprivileged user can not mount NTFS block devices using the external FUSE\n"
300 "library. Either mount the volume as root, or rebuild NTFS-3G with integrated\n"
301 "FUSE support and make it setuid root. Please see more information at\n"
302 "http://tuxera.com/community/ntfs-3g-faq/#unprivileged\n";
303 #endif
304 
305 
ntfs_fuse_update_times(ntfs_inode * ni,ntfs_time_update_flags mask)306 static void ntfs_fuse_update_times(ntfs_inode *ni, ntfs_time_update_flags mask)
307 {
308 	if (ctx->atime == ATIME_DISABLED)
309 		mask &= ~NTFS_UPDATE_ATIME;
310 	else if (ctx->atime == ATIME_RELATIVE && mask == NTFS_UPDATE_ATIME &&
311 			(sle64_to_cpu(ni->last_access_time)
312 				>= sle64_to_cpu(ni->last_data_change_time)) &&
313 			(sle64_to_cpu(ni->last_access_time)
314 				>= sle64_to_cpu(ni->last_mft_change_time)))
315 		return;
316 	ntfs_inode_update_times(ni, mask);
317 }
318 
ntfs_get_nr_free_mft_records(ntfs_volume * vol)319 static s64 ntfs_get_nr_free_mft_records(ntfs_volume *vol)
320 {
321 	ntfs_attr *na = vol->mftbmp_na;
322 	s64 nr_free = ntfs_attr_get_free_bits(na);
323 
324 	if (nr_free >= 0)
325 		nr_free += (na->allocated_size - na->data_size) << 3;
326 	return nr_free;
327 }
328 
329 /*
330  *	Fill a security context as needed by security functions
331  *	returns TRUE if there is a user mapping,
332  *		FALSE if there is none
333  *			This is not an error and the context is filled anyway,
334  *			it is used for implicit Windows-like inheritance
335  */
336 
ntfs_fuse_fill_security_context(fuse_req_t req,struct SECURITY_CONTEXT * scx)337 static BOOL ntfs_fuse_fill_security_context(fuse_req_t req,
338 			struct SECURITY_CONTEXT *scx)
339 {
340 	const struct fuse_ctx *fusecontext;
341 
342 	scx->vol = ctx->vol;
343 	scx->mapping[MAPUSERS] = ctx->security.mapping[MAPUSERS];
344 	scx->mapping[MAPGROUPS] = ctx->security.mapping[MAPGROUPS];
345 	scx->pseccache = &ctx->seccache;
346 	if (req) {
347 		fusecontext = fuse_req_ctx(req);
348 		scx->uid = fusecontext->uid;
349 		scx->gid = fusecontext->gid;
350 		scx->tid = fusecontext->pid;
351 #ifdef FUSE_CAP_DONT_MASK
352 			/* the umask can be processed by the file system */
353 		scx->umask = fusecontext->umask;
354 #else
355 			/* the umask if forced by fuse on creation */
356 		scx->umask = 0;
357 #endif
358 
359 	} else {
360 		scx->uid = 0;
361 		scx->gid = 0;
362 		scx->tid = 0;
363 		scx->umask = 0;
364 	}
365 	return (ctx->security.mapping[MAPUSERS] != (struct MAPPING*)NULL);
366 }
367 
ntfs_fuse_inode_lookup(fuse_ino_t parent,const char * name)368 static u64 ntfs_fuse_inode_lookup(fuse_ino_t parent, const char *name)
369 {
370 	u64 ino = (u64)-1;
371 	u64 inum;
372 	ntfs_inode *dir_ni;
373 
374 	/* Open target directory. */
375 	dir_ni = ntfs_inode_open(ctx->vol, INODE(parent));
376 	if (dir_ni) {
377 		/* Lookup file */
378 		inum = ntfs_inode_lookup_by_mbsname(dir_ni, name);
379 			/* never return inodes 0 and 1 */
380 		if (MREF(inum) <= 1) {
381 			inum = (u64)-1;
382 			errno = ENOENT;
383 		}
384 		if (ntfs_inode_close(dir_ni)
385 		    || (inum == (u64)-1))
386 			ino = (u64)-1;
387 		else
388 			ino = MREF(inum);
389 	}
390 	return (ino);
391 }
392 
393 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
394 
395 /*
396  *		Check access to parent directory
397  *
398  *	file inode is only opened when not fed in and S_ISVTX is requested,
399  *	when already open and S_ISVTX, it *HAS TO* be fed in.
400  *
401  *	returns 1 if allowed,
402  *		0 if not allowed or some error occurred (errno tells why)
403  */
404 
ntfs_allowed_dir_access(struct SECURITY_CONTEXT * scx,ntfs_inode * dir_ni,fuse_ino_t ino,ntfs_inode * ni,mode_t accesstype)405 static int ntfs_allowed_dir_access(struct SECURITY_CONTEXT *scx,
406 			ntfs_inode *dir_ni, fuse_ino_t ino,
407 			ntfs_inode *ni, mode_t accesstype)
408 {
409 	int allowed;
410 	ntfs_inode *ni2;
411 	struct stat stbuf;
412 
413 	allowed = ntfs_allowed_access(scx, dir_ni, accesstype);
414 		/*
415 		 * for an not-owned sticky directory, have to
416 		 * check whether file itself is owned
417 		 */
418 	if ((accesstype == (S_IWRITE + S_IEXEC + S_ISVTX))
419 	   && (allowed == 2)) {
420 		if (ni)
421 			ni2 = ni;
422 		else
423 			ni2 = ntfs_inode_open(ctx->vol, INODE(ino));
424 		allowed = 0;
425 		if (ni2) {
426 			allowed = (ntfs_get_owner_mode(scx,ni2,&stbuf) >= 0)
427 				&& (stbuf.st_uid == scx->uid);
428 			if (!ni)
429 				ntfs_inode_close(ni2);
430 		}
431 	}
432 	return (allowed);
433 }
434 
435 #endif /* !KERNELPERMS | (POSIXACLS & !KERNELACLS) */
436 
437 /**
438  * ntfs_fuse_statfs - return information about mounted NTFS volume
439  * @path:	ignored (but fuse requires it)
440  * @sfs:	statfs structure in which to return the information
441  *
442  * Return information about the mounted NTFS volume @sb in the statfs structure
443  * pointed to by @sfs (this is initialized with zeros before ntfs_statfs is
444  * called). We interpret the values to be correct of the moment in time at
445  * which we are called. Most values are variable otherwise and this isn't just
446  * the free values but the totals as well. For example we can increase the
447  * total number of file nodes if we run out and we can keep doing this until
448  * there is no more space on the volume left at all.
449  *
450  * This code based on ntfs_statfs from ntfs kernel driver.
451  *
452  * Returns 0 on success or -errno on error.
453  */
454 
ntfs_fuse_statfs(fuse_req_t req,fuse_ino_t ino)455 static void ntfs_fuse_statfs(fuse_req_t req,
456 			fuse_ino_t ino __attribute__((unused)))
457 {
458 	struct statvfs sfs;
459 	s64 size;
460 	int delta_bits;
461 	ntfs_volume *vol;
462 
463 	vol = ctx->vol;
464 	if (vol) {
465 	/*
466 	 * File system block size. Used to calculate used/free space by df.
467 	 * Incorrectly documented as "optimal transfer block size".
468 	 */
469 		sfs.f_bsize = vol->cluster_size;
470 
471 	/* Fundamental file system block size, used as the unit. */
472 		sfs.f_frsize = vol->cluster_size;
473 
474 	/*
475 	 * Total number of blocks on file system in units of f_frsize.
476 	 * Since inodes are also stored in blocks ($MFT is a file) hence
477 	 * this is the number of clusters on the volume.
478 	 */
479 		sfs.f_blocks = vol->nr_clusters;
480 
481 	/* Free blocks available for all and for non-privileged processes. */
482 		size = vol->free_clusters;
483 		if (size < 0)
484 			size = 0;
485 		sfs.f_bavail = sfs.f_bfree = size;
486 
487 	/* Free inodes on the free space */
488 		delta_bits = vol->cluster_size_bits - vol->mft_record_size_bits;
489 		if (delta_bits >= 0)
490 			size <<= delta_bits;
491 		else
492 			size >>= -delta_bits;
493 
494 	/* Number of inodes at this point in time. */
495 		sfs.f_files = (vol->mftbmp_na->allocated_size << 3) + size;
496 
497 	/* Free inodes available for all and for non-privileged processes. */
498 		size += vol->free_mft_records;
499 		if (size < 0)
500 			size = 0;
501 		sfs.f_ffree = sfs.f_favail = size;
502 
503 	/* Maximum length of filenames. */
504 		sfs.f_namemax = NTFS_MAX_NAME_LEN;
505 		fuse_reply_statfs(req, &sfs);
506 	} else
507 		fuse_reply_err(req, ENODEV);
508 
509 }
510 
set_fuse_error(int * err)511 static void set_fuse_error(int *err)
512 {
513 	if (!*err)
514 		*err = -errno;
515 }
516 
517 #if 0 && (defined(__APPLE__) || defined(__DARWIN__)) /* Unfinished. */
518 static int ntfs_macfuse_getxtimes(const char *org_path,
519 		struct timespec *bkuptime, struct timespec *crtime)
520 {
521 	int res = 0;
522 	ntfs_inode *ni;
523 	char *path = NULL;
524 	ntfschar *stream_name;
525 	int stream_name_len;
526 
527 	stream_name_len = ntfs_fuse_parse_path(org_path, &path, &stream_name);
528 	if (stream_name_len < 0)
529 		return stream_name_len;
530 	memset(bkuptime, 0, sizeof(struct timespec));
531 	memset(crtime, 0, sizeof(struct timespec));
532 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
533 	if (!ni) {
534 		res = -errno;
535 		goto exit;
536 	}
537 
538 	/* We have no backup timestamp in NTFS. */
539 	crtime->tv_sec = ni->creation_time;
540 exit:
541 	if (ntfs_inode_close(ni))
542 		set_fuse_error(&res);
543 	free(path);
544 	if (stream_name_len)
545 		free(stream_name);
546 	return res;
547 }
548 
549 int ntfs_macfuse_setcrtime(const char *path, const struct timespec *tv)
550 {
551 	ntfs_inode *ni;
552 	int res = 0;
553 
554 	if (ntfs_fuse_is_named_data_stream(path))
555 		return -EINVAL; /* n/a for named data streams. */
556 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
557 	if (!ni)
558 		return -errno;
559 
560 	if (tv) {
561 		ni->creation_time = tv->tv_sec;
562 		ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
563 	}
564 
565 	if (ntfs_inode_close(ni))
566 		set_fuse_error(&res);
567 	return res;
568 }
569 
570 int ntfs_macfuse_setbkuptime(const char *path, const struct timespec *tv)
571 {
572 	ntfs_inode *ni;
573 	int res = 0;
574 
575 	if (ntfs_fuse_is_named_data_stream(path))
576 		return -EINVAL; /* n/a for named data streams. */
577 	ni = ntfs_pathname_to_inode(ctx->vol, NULL, path);
578 	if (!ni)
579 		return -errno;
580 
581 	/*
582 	 * Only pretending to set backup time successfully to please the APIs of
583 	 * Mac OS X. In reality, NTFS has no backup time.
584 	 */
585 
586 	if (ntfs_inode_close(ni))
587 		set_fuse_error(&res);
588 	return res;
589 }
590 
591 int ntfs_macfuse_setchgtime(const char *path, const struct timespec *tv)
592 {
593 	ntfs_inode *ni;
594 	int res = 0;
595 
596 	if (ntfs_fuse_is_named_data_stream(path))
597 		return -EINVAL; /* n/a for named data streams. */
598 	ni = ntfs_pathname_to_inode(ctx-&gt;vol, NULL, path);
599 	if (!ni)
600 		return -errno;
601 
602 	if (tv) {
603 		ni-&gt;last_mft_change_time = tv-&gt;tv_sec;
604 		ntfs_fuse_update_times(ni, 0);
605 	}
606 
607 	if (ntfs_inode_close(ni))
608 		set_fuse_error(&amp;res);
609 	return res;
610 }
611 #endif /* defined(__APPLE__) || defined(__DARWIN__) */
612 
ntfs_init(void * userdata,struct fuse_conn_info * conn)613 static void ntfs_init(void *userdata __attribute__((unused)),
614 			struct fuse_conn_info *conn)
615 {
616 #if defined(__APPLE__) || defined(__DARWIN__)
617 	FUSE_ENABLE_XTIMES(conn);
618 #endif
619 #ifdef FUSE_CAP_DONT_MASK
620 		/* request umask not to be enforced by fuse */
621 	conn->want |= FUSE_CAP_DONT_MASK;
622 #endif /* defined FUSE_CAP_DONT_MASK */
623 #if POSIXACLS & KERNELACLS
624 		/* request ACLs to be checked by kernel */
625 	conn->want |= FUSE_CAP_POSIX_ACL;
626 #endif /* POSIXACLS & KERNELACLS */
627 #ifdef FUSE_CAP_BIG_WRITES
628 	if (ctx->big_writes
629 	    && ((ctx->vol->nr_clusters << ctx->vol->cluster_size_bits)
630 			>= SAFE_CAPACITY_FOR_BIG_WRITES))
631 		conn->want |= FUSE_CAP_BIG_WRITES;
632 #endif
633 #ifdef FUSE_CAP_IOCTL_DIR
634 	conn->want |= FUSE_CAP_IOCTL_DIR;
635 #endif /* defined(FUSE_CAP_IOCTL_DIR) */
636 }
637 
638 #ifndef DISABLE_PLUGINS
639 
640 /*
641  *		Define attributes for a junction or symlink
642  *		(internal plugin)
643  */
644 
junction_getstat(ntfs_inode * ni,const REPARSE_POINT * reparse,struct stat * stbuf)645 static int junction_getstat(ntfs_inode *ni,
646 			const REPARSE_POINT *reparse __attribute__((unused)),
647 			struct stat *stbuf)
648 {
649 	char *target;
650 	int res;
651 
652 	errno = 0;
653 	target = ntfs_make_symlink(ni, ctx->abs_mnt_point);
654 		/*
655 		 * If the reparse point is not a valid
656 		 * directory junction, and there is no error
657 		 * we still display as a symlink
658 		 */
659 	if (target || (errno == EOPNOTSUPP)) {
660 		if (target)
661 			stbuf->st_size = strlen(target);
662 		else
663 			stbuf->st_size = sizeof(ntfs_bad_reparse) - 1;
664 		stbuf->st_blocks = (ni->allocated_size + 511) >> 9;
665 		stbuf->st_mode = S_IFLNK;
666 		free(target);
667 		res = 0;
668 	} else {
669 		res = -errno;
670 	}
671 	return (res);
672 }
673 
674 /*
675  *		Apply permission masks to st_mode returned by reparse handler
676  */
677 
apply_umask(struct stat * stbuf)678 static void apply_umask(struct stat *stbuf)
679 {
680 	switch (stbuf->st_mode & S_IFMT) {
681 	case S_IFREG :
682 		stbuf->st_mode &= ~ctx->fmask;
683 		break;
684 	case S_IFDIR :
685 		stbuf->st_mode &= ~ctx->dmask;
686 		break;
687 	case S_IFLNK :
688 		stbuf->st_mode = (stbuf->st_mode & S_IFMT) | 0777;
689 		break;
690 	default :
691 		break;
692 	}
693 }
694 
695 #endif /* DISABLE_PLUGINS */
696 
ntfs_fuse_getstat(struct SECURITY_CONTEXT * scx,ntfs_inode * ni,struct stat * stbuf)697 static int ntfs_fuse_getstat(struct SECURITY_CONTEXT *scx,
698 				ntfs_inode *ni, struct stat *stbuf)
699 {
700 	int res = 0;
701 	ntfs_attr *na;
702 	BOOL withusermapping;
703 
704 	memset(stbuf, 0, sizeof(struct stat));
705 	withusermapping = (scx->mapping[MAPUSERS] != (struct MAPPING*)NULL);
706 	stbuf->st_nlink = le16_to_cpu(ni->mrec->link_count);
707 	if ((ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
708 	    || (ni->flags & FILE_ATTR_REPARSE_POINT)) {
709 		if (ni->flags & FILE_ATTR_REPARSE_POINT) {
710 #ifndef DISABLE_PLUGINS
711 			const plugin_operations_t *ops;
712 			REPARSE_POINT *reparse;
713 
714 			res = CALL_REPARSE_PLUGIN(ni, getattr, stbuf);
715 			if (!res) {
716 				apply_umask(stbuf);
717 			} else {
718 				stbuf->st_size =
719 					sizeof(ntfs_bad_reparse) - 1;
720 				stbuf->st_blocks =
721 					(ni->allocated_size + 511) >> 9;
722 				stbuf->st_mode = S_IFLNK;
723 				res = 0;
724 			}
725 			goto ok;
726 #else /* DISABLE_PLUGINS */
727 			char *target;
728 
729 			errno = 0;
730 			target = ntfs_make_symlink(ni, ctx->abs_mnt_point);
731 				/*
732 				 * If the reparse point is not a valid
733 				 * directory junction, and there is no error
734 				 * we still display as a symlink
735 				 */
736 			if (target || (errno == EOPNOTSUPP)) {
737 				if (target)
738 					stbuf->st_size = strlen(target);
739 				else
740 					stbuf->st_size =
741 						sizeof(ntfs_bad_reparse) - 1;
742 				stbuf->st_blocks =
743 					(ni->allocated_size + 511) >> 9;
744 				stbuf->st_nlink =
745 					le16_to_cpu(ni->mrec->link_count);
746 				stbuf->st_mode = S_IFLNK;
747 				free(target);
748 			} else {
749 				res = -errno;
750 				goto exit;
751 			}
752 #endif /* DISABLE_PLUGINS */
753 		} else {
754 			/* Directory. */
755 			stbuf->st_mode = S_IFDIR | (0777 & ~ctx->dmask);
756 			/* get index size, if not known */
757 			if (!test_nino_flag(ni, KnownSize)) {
758 				na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION,
759 						NTFS_INDEX_I30, 4);
760 				if (na) {
761 					ni->data_size = na->data_size;
762 					ni->allocated_size = na->allocated_size;
763 					set_nino_flag(ni, KnownSize);
764 					ntfs_attr_close(na);
765 				}
766 			}
767 			stbuf->st_size = ni->data_size;
768 			stbuf->st_blocks = ni->allocated_size >> 9;
769 			stbuf->st_nlink = 1;	/* Make find(1) work */
770 		}
771 	} else {
772 		/* Regular or Interix (INTX) file. */
773 		stbuf->st_mode = S_IFREG;
774 		stbuf->st_size = ni->data_size;
775 #ifdef HAVE_SETXATTR	/* extended attributes interface required */
776 		/*
777 		 * return data size rounded to next 512 byte boundary for
778 		 * encrypted files to include padding required for decryption
779 		 * also include 2 bytes for padding info
780 		*/
781 		if (ctx->efs_raw
782 		    && (ni->flags & FILE_ATTR_ENCRYPTED)
783 		    && ni->data_size)
784 			stbuf->st_size = ((ni->data_size + 511) & ~511) + 2;
785 #endif /* HAVE_SETXATTR */
786 		/*
787 		 * Temporary fix to make ActiveSync work via Samba 3.0.
788 		 * See more on the ntfs-3g-devel list.
789 		 */
790 		stbuf->st_blocks = (ni->allocated_size + 511) >> 9;
791 		if (ni->flags & FILE_ATTR_SYSTEM) {
792 			na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
793 			if (!na) {
794 				stbuf->st_ino = ni->mft_no;
795 				goto nodata;
796 			}
797 			/* Check whether it's Interix FIFO or socket. */
798 			if (!(ni->flags & FILE_ATTR_HIDDEN)) {
799 				/* FIFO. */
800 				if (na->data_size == 0)
801 					stbuf->st_mode = S_IFIFO;
802 				/* Socket link. */
803 				if (na->data_size == 1)
804 					stbuf->st_mode = S_IFSOCK;
805 			}
806 			/*
807 			 * Check whether it's Interix symbolic link, block or
808 			 * character device.
809 			 */
810 			if ((u64)na->data_size <= sizeof(INTX_FILE_TYPES)
811 					+ sizeof(ntfschar) * PATH_MAX
812 				&& (u64)na->data_size >
813 					sizeof(INTX_FILE_TYPES)) {
814 				INTX_FILE *intx_file;
815 
816 				intx_file =
817 					(INTX_FILE*)ntfs_malloc(na->data_size);
818 				if (!intx_file) {
819 					res = -errno;
820 					ntfs_attr_close(na);
821 					goto exit;
822 				}
823 				if (ntfs_attr_pread(na, 0, na->data_size,
824 						intx_file) != na->data_size) {
825 					res = -errno;
826 					free(intx_file);
827 					ntfs_attr_close(na);
828 					goto exit;
829 				}
830 				if (intx_file->magic == INTX_BLOCK_DEVICE &&
831 						na->data_size == (s64)offsetof(
832 						INTX_FILE, device_end)) {
833 					stbuf->st_mode = S_IFBLK;
834 					stbuf->st_rdev = makedev(le64_to_cpu(
835 							intx_file->major),
836 							le64_to_cpu(
837 							intx_file->minor));
838 				}
839 				if (intx_file->magic == INTX_CHARACTER_DEVICE &&
840 						na->data_size == (s64)offsetof(
841 						INTX_FILE, device_end)) {
842 					stbuf->st_mode = S_IFCHR;
843 					stbuf->st_rdev = makedev(le64_to_cpu(
844 							intx_file->major),
845 							le64_to_cpu(
846 							intx_file->minor));
847 				}
848 				if (intx_file->magic == INTX_SYMBOLIC_LINK) {
849 					char *target = NULL;
850 					int len;
851 
852 					/* st_size should be set to length of
853 					 * symlink target as multibyte string */
854 					len = ntfs_ucstombs(
855 							intx_file->target,
856 							(na->data_size -
857 							    offsetof(INTX_FILE,
858 								     target)) /
859 							       sizeof(ntfschar),
860 							     &target, 0);
861 					if (len < 0) {
862 						res = -errno;
863 						free(intx_file);
864 						ntfs_attr_close(na);
865 						goto exit;
866 					}
867 					free(target);
868 					stbuf->st_mode = S_IFLNK;
869 					stbuf->st_size = len;
870 				}
871 				free(intx_file);
872 			}
873 			ntfs_attr_close(na);
874 		}
875 		stbuf->st_mode |= (0777 & ~ctx->fmask);
876 	}
877 #ifndef DISABLE_PLUGINS
878 ok:
879 #endif /* DISABLE_PLUGINS */
880 	if (withusermapping) {
881 		if (ntfs_get_owner_mode(scx,ni,stbuf) < 0)
882 			set_fuse_error(&res);
883 	} else {
884 		stbuf->st_uid = ctx->uid;
885 		stbuf->st_gid = ctx->gid;
886 	}
887 	if (S_ISLNK(stbuf->st_mode))
888 		stbuf->st_mode |= 0777;
889 nodata :
890 	stbuf->st_ino = ni->mft_no;
891 #ifdef HAVE_STRUCT_STAT_ST_ATIMESPEC
892 	stbuf->st_atimespec = ntfs2timespec(ni->last_access_time);
893 	stbuf->st_ctimespec = ntfs2timespec(ni->last_mft_change_time);
894 	stbuf->st_mtimespec = ntfs2timespec(ni->last_data_change_time);
895 #elif defined(HAVE_STRUCT_STAT_ST_ATIM)
896 	stbuf->st_atim = ntfs2timespec(ni->last_access_time);
897 	stbuf->st_ctim = ntfs2timespec(ni->last_mft_change_time);
898 	stbuf->st_mtim = ntfs2timespec(ni->last_data_change_time);
899 #elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC)
900 	{
901 	struct timespec ts;
902 
903 	ts = ntfs2timespec(ni->last_access_time);
904 	stbuf->st_atime = ts.tv_sec;
905 	stbuf->st_atimensec = ts.tv_nsec;
906 	ts = ntfs2timespec(ni->last_mft_change_time);
907 	stbuf->st_ctime = ts.tv_sec;
908 	stbuf->st_ctimensec = ts.tv_nsec;
909 	ts = ntfs2timespec(ni->last_data_change_time);
910 	stbuf->st_mtime = ts.tv_sec;
911 	stbuf->st_mtimensec = ts.tv_nsec;
912 	}
913 #else
914 #warning "No known way to set nanoseconds in struct stat !"
915 	{
916 	struct timespec ts;
917 
918 	ts = ntfs2timespec(ni->last_access_time);
919 	stbuf->st_atime = ts.tv_sec;
920 	ts = ntfs2timespec(ni->last_mft_change_time);
921 	stbuf->st_ctime = ts.tv_sec;
922 	ts = ntfs2timespec(ni->last_data_change_time);
923 	stbuf->st_mtime = ts.tv_sec;
924 	}
925 #endif
926 exit:
927 	return (res);
928 }
929 
ntfs_fuse_getattr(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)930 static void ntfs_fuse_getattr(fuse_req_t req, fuse_ino_t ino,
931 			struct fuse_file_info *fi __attribute__((unused)))
932 {
933 	int res;
934 	ntfs_inode *ni;
935 	struct stat stbuf;
936 	struct SECURITY_CONTEXT security;
937 
938 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
939 	if (!ni)
940 		res = -errno;
941 	else {
942 		ntfs_fuse_fill_security_context(req, &security);
943 		res = ntfs_fuse_getstat(&security, ni, &stbuf);
944 		if (ntfs_inode_close(ni))
945 			set_fuse_error(&res);
946 	}
947 	if (!res)
948 		fuse_reply_attr(req, &stbuf, ATTR_TIMEOUT);
949 	else
950 		fuse_reply_err(req, -res);
951 }
952 
ntfs_fuse_fillstat(struct SECURITY_CONTEXT * scx,struct fuse_entry_param * pentry,u64 iref)953 static __inline__ BOOL ntfs_fuse_fillstat(struct SECURITY_CONTEXT *scx,
954 			struct fuse_entry_param *pentry, u64 iref)
955 {
956 	ntfs_inode *ni;
957 	BOOL ok = FALSE;
958 
959 	pentry->ino = MREF(iref);
960 	ni = ntfs_inode_open(ctx->vol, pentry->ino);
961 	if (ni) {
962 		if (!ntfs_fuse_getstat(scx, ni, &pentry->attr)) {
963 			pentry->generation = 1;
964 			pentry->attr_timeout = ATTR_TIMEOUT;
965 			pentry->entry_timeout = ENTRY_TIMEOUT;
966 			ok = TRUE;
967 		}
968 		if (ntfs_inode_close(ni))
969 		       ok = FALSE;
970 	}
971 	return (ok);
972 }
973 
974 
ntfs_fuse_lookup(fuse_req_t req,fuse_ino_t parent,const char * name)975 static void ntfs_fuse_lookup(fuse_req_t req, fuse_ino_t parent,
976 			const char *name)
977 {
978 	struct SECURITY_CONTEXT security;
979 	struct fuse_entry_param entry;
980 	ntfs_inode *dir_ni;
981 	u64 iref;
982 	BOOL ok = FALSE;
983 
984 	if (strlen(name) < 256) {
985 		dir_ni = ntfs_inode_open(ctx->vol, INODE(parent));
986 		if (dir_ni) {
987 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
988 			/*
989 			 * make sure the parent directory is searchable
990 			 */
991 			if (ntfs_fuse_fill_security_context(req, &security)
992 			    && !ntfs_allowed_access(&security,dir_ni,S_IEXEC)) {
993 				ntfs_inode_close(dir_ni);
994 				errno = EACCES;
995 			} else {
996 #else
997 				ntfs_fuse_fill_security_context(req, &security);
998 #endif
999 				iref = ntfs_inode_lookup_by_mbsname(dir_ni,
1000 								name);
1001 					/* never return inodes 0 and 1 */
1002 				if (MREF(iref) <= 1) {
1003 					iref = (u64)-1;
1004 					errno = ENOENT;
1005 				}
1006 				ok = !ntfs_inode_close(dir_ni)
1007 					&& (iref != (u64)-1)
1008 					&& ntfs_fuse_fillstat(
1009 						&security,&entry,iref);
1010 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
1011 			}
1012 #endif
1013 		}
1014 	} else
1015 		errno = ENAMETOOLONG;
1016 	if (!ok)
1017 		fuse_reply_err(req, errno);
1018 	else
1019 		fuse_reply_entry(req, &entry);
1020 }
1021 
1022 #ifndef DISABLE_PLUGINS
1023 
1024 /*
1025  *		Get the link defined by a junction or symlink
1026  *		(internal plugin)
1027  */
1028 
junction_readlink(ntfs_inode * ni,const REPARSE_POINT * reparse,char ** pbuf)1029 static int junction_readlink(ntfs_inode *ni,
1030 			const REPARSE_POINT *reparse __attribute__((unused)),
1031 			char **pbuf)
1032 {
1033 	int res;
1034 
1035 	errno = 0;
1036 	res = 0;
1037 	*pbuf = ntfs_make_symlink(ni, ctx->abs_mnt_point);
1038 	if (!*pbuf) {
1039 		if (errno == EOPNOTSUPP) {
1040 			*pbuf = strdup(ntfs_bad_reparse);
1041 			if (!*pbuf)
1042 				res = -errno;
1043 		} else
1044 			res = -errno;
1045 	}
1046 	return (res);
1047 }
1048 
1049 #endif /* DISABLE_PLUGINS */
1050 
ntfs_fuse_readlink(fuse_req_t req,fuse_ino_t ino)1051 static void ntfs_fuse_readlink(fuse_req_t req, fuse_ino_t ino)
1052 {
1053 	ntfs_inode *ni = NULL;
1054 	ntfs_attr *na = NULL;
1055 	INTX_FILE *intx_file = NULL;
1056 	char *buf = (char*)NULL;
1057 	int res = 0;
1058 
1059 	/* Get inode. */
1060 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
1061 	if (!ni) {
1062 		res = -errno;
1063 		goto exit;
1064 	}
1065 		/*
1066 		 * Reparse point : analyze as a junction point
1067 		 */
1068 	if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1069 #ifndef DISABLE_PLUGINS
1070 		const plugin_operations_t *ops;
1071 		REPARSE_POINT *reparse;
1072 
1073 		res = CALL_REPARSE_PLUGIN(ni, readlink, &buf);
1074 		if (res) {
1075 			buf = strdup(ntfs_bad_reparse);
1076 			if (!buf)
1077 				res = -errno;
1078 		}
1079 #else /* DISABLE_PLUGINS */
1080 		errno = 0;
1081 		res = 0;
1082 		buf = ntfs_make_symlink(ni, ctx->abs_mnt_point);
1083 		if (!buf) {
1084 			if (errno == EOPNOTSUPP)
1085 				buf = strdup(ntfs_bad_reparse);
1086 			if (!buf)
1087 				res = -errno;
1088 		}
1089 #endif /* DISABLE_PLUGINS */
1090  		goto exit;
1091 	}
1092 	/* Sanity checks. */
1093 	if (!(ni->flags & FILE_ATTR_SYSTEM)) {
1094 		res = -EINVAL;
1095 		goto exit;
1096 	}
1097 	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1098 	if (!na) {
1099 		res = -errno;
1100 		goto exit;
1101 	}
1102 	if ((size_t)na->data_size <= sizeof(INTX_FILE_TYPES)) {
1103 		res = -EINVAL;
1104 		goto exit;
1105 	}
1106 	if ((size_t)na->data_size > sizeof(INTX_FILE_TYPES) +
1107 			sizeof(ntfschar) * PATH_MAX) {
1108 		res = -ENAMETOOLONG;
1109 		goto exit;
1110 	}
1111 	/* Receive file content. */
1112 	intx_file = (INTX_FILE*)ntfs_malloc(na->data_size);
1113 	if (!intx_file) {
1114 		res = -errno;
1115 		goto exit;
1116 	}
1117 	if (ntfs_attr_pread(na, 0, na->data_size, intx_file) != na->data_size) {
1118 		res = -errno;
1119 		goto exit;
1120 	}
1121 	/* Sanity check. */
1122 	if (intx_file->magic != INTX_SYMBOLIC_LINK) {
1123 		res = -EINVAL;
1124 		goto exit;
1125 	}
1126 	/* Convert link from unicode to local encoding. */
1127 	if (ntfs_ucstombs(intx_file->target, (na->data_size -
1128 			offsetof(INTX_FILE, target)) / sizeof(ntfschar),
1129 			&buf, 0) < 0) {
1130 		res = -errno;
1131 		goto exit;
1132 	}
1133 exit:
1134 	if (intx_file)
1135 		free(intx_file);
1136 	if (na)
1137 		ntfs_attr_close(na);
1138 	if (ntfs_inode_close(ni))
1139 		set_fuse_error(&res);
1140 
1141 	if (res < 0)
1142 		fuse_reply_err(req, -res);
1143 	else
1144 		fuse_reply_readlink(req, buf);
1145 	if (buf != ntfs_bad_reparse)
1146 		free(buf);
1147 }
1148 
ntfs_fuse_filler(ntfs_fuse_fill_context_t * fill_ctx,const ntfschar * name,const int name_len,const int name_type,const s64 pos,const MFT_REF mref,const unsigned dt_type)1149 static int ntfs_fuse_filler(ntfs_fuse_fill_context_t *fill_ctx,
1150 		const ntfschar *name, const int name_len, const int name_type,
1151 		const s64 pos __attribute__((unused)), const MFT_REF mref,
1152 		const unsigned dt_type __attribute__((unused)))
1153 {
1154 	char *filename = NULL;
1155 	int ret = 0;
1156 	int filenamelen = -1;
1157 	size_t sz;
1158 	ntfs_fuse_fill_item_t *current;
1159 	ntfs_fuse_fill_item_t *newone;
1160 
1161 	if (name_type == FILE_NAME_DOS)
1162 		return 0;
1163 
1164 	if ((filenamelen = ntfs_ucstombs(name, name_len, &filename, 0)) < 0) {
1165 		ntfs_log_perror("Filename decoding failed (inode %llu)",
1166 				(unsigned long long)MREF(mref));
1167 		return -1;
1168 	}
1169 		/* never return inodes 0 and 1 */
1170 	if (MREF(mref) > 1) {
1171 		struct stat st = { .st_ino = MREF(mref) };
1172 
1173 		switch (dt_type) {
1174 		case NTFS_DT_DIR :
1175 			st.st_mode = S_IFDIR | (0777 & ~ctx->dmask);
1176 			break;
1177 		case NTFS_DT_LNK :
1178 			st.st_mode = S_IFLNK | 0777;
1179 			break;
1180 		case NTFS_DT_FIFO :
1181 			st.st_mode = S_IFIFO;
1182 			break;
1183 		case NTFS_DT_SOCK :
1184 			st.st_mode = S_IFSOCK;
1185 			break;
1186 		case NTFS_DT_BLK :
1187 			st.st_mode = S_IFBLK;
1188 			break;
1189 		case NTFS_DT_CHR :
1190 			st.st_mode = S_IFCHR;
1191 			break;
1192 		default : /* unexpected types shown as plain files */
1193 		case NTFS_DT_REG :
1194 			st.st_mode = S_IFREG | (0777 & ~ctx->fmask);
1195 			break;
1196 		}
1197 
1198 #if defined(__APPLE__) || defined(__DARWIN__)
1199 		/*
1200 		 * Returning file names larger than MAXNAMLEN (255) bytes
1201 		 * causes Darwin/Mac OS X to bug out and skip the entry.
1202 		 */
1203 		if (filenamelen > MAXNAMLEN) {
1204 			ntfs_log_debug("Truncating %d byte filename to "
1205 				       "%d bytes.\n", filenamelen, MAXNAMLEN);
1206 			ntfs_log_debug("  before: '%s'\n", filename);
1207 			memset(filename + MAXNAMLEN, 0, filenamelen - MAXNAMLEN);
1208 			ntfs_log_debug("   after: '%s'\n", filename);
1209 		}
1210 #elif defined(__sun) && defined (__SVR4)
1211 		/*
1212 		 * Returning file names larger than MAXNAMELEN (256) bytes
1213 		 * causes Solaris/Illumos to return an I/O error from the system
1214 		 * call.
1215 		 * However we also need space for a terminating NULL, or user
1216 		 * space tools will bug out since they expect a NULL terminator.
1217 		 * Effectively the maximum length of a file name is MAXNAMELEN -
1218 		 * 1 (255).
1219 		 */
1220 		if (filenamelen > (MAXNAMELEN - 1)) {
1221 			ntfs_log_debug("Truncating %d byte filename to %d "
1222 				"bytes.\n", filenamelen, MAXNAMELEN - 1);
1223 			ntfs_log_debug("  before: '%s'\n", filename);
1224 			memset(&filename[MAXNAMELEN - 1], 0,
1225 				filenamelen - (MAXNAMELEN - 1));
1226 			ntfs_log_debug("   after: '%s'\n", filename);
1227 		}
1228 #endif /* defined(__APPLE__) || defined(__DARWIN__), ... */
1229 
1230 		current = fill_ctx->last;
1231 		sz = fuse_add_direntry(fill_ctx->req,
1232 				&current->buf[current->off],
1233 				current->bufsize - current->off,
1234 				filename, &st, current->off + fill_ctx->off);
1235 		if (!sz || ((current->off + sz) > current->bufsize)) {
1236 			newone = (ntfs_fuse_fill_item_t*)ntfs_malloc
1237 				(sizeof(ntfs_fuse_fill_item_t)
1238 				     + current->bufsize);
1239 			if (newone) {
1240 				newone->off = 0;
1241 				newone->bufsize = current->bufsize;
1242 				newone->next = (ntfs_fuse_fill_item_t*)NULL;
1243 				current->next = newone;
1244 				fill_ctx->last = newone;
1245 				fill_ctx->off += current->off;
1246 				current = newone;
1247 				sz = fuse_add_direntry(fill_ctx->req,
1248 					current->buf,
1249 					current->bufsize - current->off,
1250 					filename, &st, fill_ctx->off);
1251 				if (!sz) {
1252 					errno = EIO;
1253 					ntfs_log_error("Could not add a"
1254 						" directory entry (inode %lld)\n",
1255 						(unsigned long long)MREF(mref));
1256 				}
1257 			} else {
1258 				sz = 0;
1259 				errno = ENOMEM;
1260 			}
1261 		}
1262 		if (sz) {
1263 			current->off += sz;
1264 		} else {
1265 			ret = -1;
1266 		}
1267 	}
1268 
1269 	free(filename);
1270 	return ret;
1271 }
1272 
ntfs_fuse_opendir(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)1273 static void ntfs_fuse_opendir(fuse_req_t req, fuse_ino_t ino,
1274 			 struct fuse_file_info *fi)
1275 {
1276 	int res = 0;
1277 	ntfs_inode *ni;
1278 	int accesstype;
1279 	ntfs_fuse_fill_context_t *fill;
1280 	struct SECURITY_CONTEXT security;
1281 
1282 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
1283 	if (ni) {
1284 		if (ntfs_fuse_fill_security_context(req, &security)) {
1285 			if (fi->flags & O_WRONLY)
1286 				accesstype = S_IWRITE;
1287 			else
1288 				if (fi->flags & O_RDWR)
1289 					accesstype = S_IWRITE | S_IREAD;
1290 				else
1291 					accesstype = S_IREAD;
1292 			if (!ntfs_allowed_access(&security,ni,accesstype))
1293 				res = -EACCES;
1294 		}
1295 		if (ntfs_inode_close(ni))
1296 			set_fuse_error(&res);
1297 		if (!res) {
1298 			fill = (ntfs_fuse_fill_context_t*)
1299 				ntfs_malloc(sizeof(ntfs_fuse_fill_context_t));
1300 			if (!fill)
1301 				res = -errno;
1302 			else {
1303 				fill->first = fill->last
1304 					= (ntfs_fuse_fill_item_t*)NULL;
1305 				fill->filled = FALSE;
1306 				fill->ino = ino;
1307 				fill->off = 0;
1308 			}
1309 			fi->fh = (long)fill;
1310 		}
1311 	} else
1312 		res = -errno;
1313 	if (!res)
1314 		fuse_reply_open(req, fi);
1315 	else
1316 		fuse_reply_err(req, -res);
1317 }
1318 
1319 
ntfs_fuse_releasedir(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)1320 static void ntfs_fuse_releasedir(fuse_req_t req,
1321 			fuse_ino_t ino __attribute__((unused)),
1322 			struct fuse_file_info *fi)
1323 {
1324 	ntfs_fuse_fill_context_t *fill;
1325 	ntfs_fuse_fill_item_t *current;
1326 
1327 	fill = (ntfs_fuse_fill_context_t*)(long)fi->fh;
1328 	if (fill && (fill->ino == ino)) {
1329 			/* make sure to clear results */
1330 		current = fill->first;
1331 		while (current) {
1332 			current = current->next;
1333 			free(fill->first);
1334 			fill->first = current;
1335 		}
1336 		fill->ino = 0;
1337 		free(fill);
1338 	}
1339 	fuse_reply_err(req, 0);
1340 }
1341 
ntfs_fuse_readdir(fuse_req_t req,fuse_ino_t ino,size_t size,off_t off,struct fuse_file_info * fi)1342 static void ntfs_fuse_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
1343 			off_t off __attribute__((unused)),
1344 			struct fuse_file_info *fi __attribute__((unused)))
1345 {
1346 	ntfs_fuse_fill_item_t *first;
1347 	ntfs_fuse_fill_item_t *current;
1348 	ntfs_fuse_fill_context_t *fill;
1349 	ntfs_inode *ni;
1350 	s64 pos = 0;
1351 	int err = 0;
1352 
1353 	fill = (ntfs_fuse_fill_context_t*)(long)fi->fh;
1354 	if (fill && (fill->ino == ino)) {
1355 		if (fill->filled && !off) {
1356 			/* Rewinding : make sure to clear existing results */
1357 			current = fill->first;
1358 			while (current) {
1359 				current = current->next;
1360 				free(fill->first);
1361 				fill->first = current;
1362 			}
1363 			fill->filled = FALSE;
1364 		}
1365 		if (!fill->filled) {
1366 				/* initial call : build the full list */
1367 			current = (ntfs_fuse_fill_item_t*)NULL;
1368 			first = (ntfs_fuse_fill_item_t*)ntfs_malloc
1369 				(sizeof(ntfs_fuse_fill_item_t) + size);
1370 			if (first) {
1371 				first->bufsize = size;
1372 				first->off = 0;
1373 				first->next = (ntfs_fuse_fill_item_t*)NULL;
1374 				fill->req = req;
1375 				fill->first = first;
1376 				fill->last = first;
1377 				fill->off = 0;
1378 				ni = ntfs_inode_open(ctx->vol,INODE(ino));
1379 				if (!ni)
1380 					err = -errno;
1381 				else {
1382 					if (ntfs_readdir(ni, &pos, fill,
1383 						(ntfs_filldir_t)
1384 							ntfs_fuse_filler))
1385 						err = -errno;
1386 					fill->filled = TRUE;
1387 					ntfs_fuse_update_times(ni,
1388 						NTFS_UPDATE_ATIME);
1389 					if (ntfs_inode_close(ni))
1390 						set_fuse_error(&err);
1391 				}
1392 				if (!err) {
1393 					off_t loc = 0;
1394 				/*
1395 				 * In some circumstances, the queue gets
1396 				 * reinitialized by releasedir() + opendir(),
1397 				 * apparently always on end of partial buffer.
1398 				 * Files may be missing or duplicated.
1399 				 */
1400 					while (first
1401 					    && ((loc < off) || !first->off)) {
1402 						loc += first->off;
1403 						fill->first = first->next;
1404 						free(first);
1405 						first = fill->first;
1406 					}
1407 					current = first;
1408 				}
1409 			} else
1410 				err = -errno;
1411 		} else {
1412 			/* subsequent call : return next non-empty buffer */
1413 			current = fill->first;
1414 			while (current && !current->off) {
1415 				current = current->next;
1416 				free(fill->first);
1417 				fill->first = current;
1418 			}
1419 		}
1420 		if (!err) {
1421 			if (current) {
1422 				fuse_reply_buf(req, current->buf, current->off);
1423 				fill->first = current->next;
1424 				free(current);
1425 			} else {
1426 				fuse_reply_buf(req, (char*)NULL, 0);
1427 				/* reply sent, now must exit with no error */
1428 			}
1429 		}
1430 	} else {
1431 		errno = EIO;
1432 		err = -errno;
1433 		ntfs_log_error("Uninitialized fuse_readdir()\n");
1434 	}
1435 	if (err)
1436 		fuse_reply_err(req, -err);
1437 }
1438 
ntfs_fuse_open(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)1439 static void ntfs_fuse_open(fuse_req_t req, fuse_ino_t ino,
1440 		      struct fuse_file_info *fi)
1441 {
1442 	ntfs_inode *ni;
1443 	ntfs_attr *na = NULL;
1444 	struct open_file *of;
1445 	int state = 0;
1446 	int res = 0;
1447 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
1448 	int accesstype;
1449 	struct SECURITY_CONTEXT security;
1450 #endif
1451 
1452 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
1453 	if (ni) {
1454 		if (!(ni->flags & FILE_ATTR_REPARSE_POINT)) {
1455 			na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1456 			if (!na) {
1457 				res = -errno;
1458 				goto close;
1459 			}
1460 		}
1461 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
1462 		if (ntfs_fuse_fill_security_context(req, &security)) {
1463 			if (fi->flags & O_WRONLY)
1464 				accesstype = S_IWRITE;
1465 			else
1466 				if (fi->flags & O_RDWR)
1467 					accesstype = S_IWRITE | S_IREAD;
1468 				else
1469 					accesstype = S_IREAD;
1470 		     /* check whether requested access is allowed */
1471 			if (!ntfs_allowed_access(&security,
1472 					ni,accesstype))
1473 				res = -EACCES;
1474 		}
1475 #endif
1476 		if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1477 #ifndef DISABLE_PLUGINS
1478 			const plugin_operations_t *ops;
1479 			REPARSE_POINT *reparse;
1480 
1481 			fi->fh = 0;
1482 			res = CALL_REPARSE_PLUGIN(ni, open, fi);
1483 			if (!res && fi->fh) {
1484 				state = CLOSE_REPARSE;
1485 			}
1486 #else /* DISABLE_PLUGINS */
1487 			res = -EOPNOTSUPP;
1488 #endif /* DISABLE_PLUGINS */
1489 			goto close;
1490 		}
1491 		if ((res >= 0)
1492 		    && (fi->flags & (O_WRONLY | O_RDWR))) {
1493 		/* mark a future need to compress the last chunk */
1494 			if (na->data_flags & ATTR_COMPRESSION_MASK)
1495 				state |= CLOSE_COMPRESSED;
1496 #ifdef HAVE_SETXATTR	/* extended attributes interface required */
1497 		/* mark a future need to fixup encrypted inode */
1498 			if (ctx->efs_raw
1499 			    && !(na->data_flags & ATTR_IS_ENCRYPTED)
1500 			    && (ni->flags & FILE_ATTR_ENCRYPTED))
1501 				state |= CLOSE_ENCRYPTED;
1502 #endif /* HAVE_SETXATTR */
1503 		/* mark a future need to update the mtime */
1504 			if (ctx->dmtime)
1505 				state |= CLOSE_DMTIME;
1506 			/* deny opening metadata files for writing */
1507 			if (ino < FILE_first_user)
1508 				res = -EPERM;
1509 		}
1510 		ntfs_attr_close(na);
1511 close:
1512 		if (ntfs_inode_close(ni))
1513 			set_fuse_error(&res);
1514 	} else
1515 		res = -errno;
1516 	if (res >= 0) {
1517 		of = (struct open_file*)malloc(sizeof(struct open_file));
1518 		if (of) {
1519 			of->parent = 0;
1520 			of->ino = ino;
1521 			of->state = state;
1522 #ifndef DISABLE_PLUGINS
1523 			memcpy(&of->fi, fi, sizeof(struct fuse_file_info));
1524 #endif /* DISABLE_PLUGINS */
1525 			of->next = ctx->open_files;
1526 			of->previous = (struct open_file*)NULL;
1527 			if (ctx->open_files)
1528 				ctx->open_files->previous = of;
1529 			ctx->open_files = of;
1530 			fi->fh = (long)of;
1531 		}
1532 	}
1533 	if (res)
1534 		fuse_reply_err(req, -res);
1535 	else
1536 		fuse_reply_open(req, fi);
1537 }
1538 
ntfs_fuse_read(fuse_req_t req,fuse_ino_t ino,size_t size,off_t offset,struct fuse_file_info * fi)1539 static void ntfs_fuse_read(fuse_req_t req, fuse_ino_t ino, size_t size,
1540 			off_t offset,
1541 			struct fuse_file_info *fi __attribute__((unused)))
1542 {
1543 	ntfs_inode *ni = NULL;
1544 	ntfs_attr *na = NULL;
1545 	int res;
1546 	char *buf = (char*)NULL;
1547 	s64 total = 0;
1548 	s64 max_read;
1549 
1550 	if (!size) {
1551 		res = 0;
1552 		goto exit;
1553 	}
1554 	buf = (char*)ntfs_malloc(size);
1555 	if (!buf) {
1556 		res = -errno;
1557 		goto exit;
1558 	}
1559 
1560 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
1561 	if (!ni) {
1562 		res = -errno;
1563 		goto exit;
1564 	}
1565 	if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1566 #ifndef DISABLE_PLUGINS
1567 		const plugin_operations_t *ops;
1568 		REPARSE_POINT *reparse;
1569 		struct open_file *of;
1570 
1571 		of = (struct open_file*)(long)fi->fh;
1572 		res = CALL_REPARSE_PLUGIN(ni, read, buf, size, offset, &of->fi);
1573 		if (res >= 0) {
1574 			goto stamps;
1575 		}
1576 #else /* DISABLE_PLUGINS */
1577 		res = -EOPNOTSUPP;
1578 #endif /* DISABLE_PLUGINS */
1579 		goto exit;
1580 	}
1581 	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1582 	if (!na) {
1583 		res = -errno;
1584 		goto exit;
1585 	}
1586 	max_read = na->data_size;
1587 #ifdef HAVE_SETXATTR	/* extended attributes interface required */
1588 	/* limit reads at next 512 byte boundary for encrypted attributes */
1589 	if (ctx->efs_raw
1590 	    && max_read
1591 	    && (na->data_flags & ATTR_IS_ENCRYPTED)
1592 	    && NAttrNonResident(na)) {
1593 		max_read = ((na->data_size+511) & ~511) + 2;
1594 	}
1595 #endif /* HAVE_SETXATTR */
1596 	if (offset + (off_t)size > max_read) {
1597 		if (max_read < offset)
1598 			goto ok;
1599 		size = max_read - offset;
1600 	}
1601 	while (size > 0) {
1602 		s64 ret = ntfs_attr_pread(na, offset, size, buf + total);
1603 		if (ret != (s64)size)
1604 			ntfs_log_perror("ntfs_attr_pread error reading inode %lld at "
1605 				"offset %lld: %lld <> %lld", (long long)ni->mft_no,
1606 				(long long)offset, (long long)size, (long long)ret);
1607 		if (ret <= 0 || ret > (s64)size) {
1608 			res = (ret < 0) ? -errno : -EIO;
1609 			goto exit;
1610 		}
1611 		size -= ret;
1612 		offset += ret;
1613 		total += ret;
1614 	}
1615 ok:
1616 	res = total;
1617 #ifndef DISABLE_PLUGINS
1618 stamps :
1619 #endif /* DISABLE_PLUGINS */
1620 	ntfs_fuse_update_times(ni, NTFS_UPDATE_ATIME);
1621 exit:
1622 	if (na)
1623 		ntfs_attr_close(na);
1624 	if (ntfs_inode_close(ni))
1625 		set_fuse_error(&res);
1626 	if (res < 0)
1627 		fuse_reply_err(req, -res);
1628 	else
1629 		fuse_reply_buf(req, buf, res);
1630 	free(buf);
1631 }
1632 
ntfs_fuse_write(fuse_req_t req,fuse_ino_t ino,const char * buf,size_t size,off_t offset,struct fuse_file_info * fi)1633 static void ntfs_fuse_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
1634 			size_t size, off_t offset,
1635 			struct fuse_file_info *fi __attribute__((unused)))
1636 {
1637 	ntfs_inode *ni = NULL;
1638 	ntfs_attr *na = NULL;
1639 	int res, total = 0;
1640 
1641 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
1642 	if (!ni) {
1643 		res = -errno;
1644 		goto exit;
1645 	}
1646 	if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1647 #ifndef DISABLE_PLUGINS
1648 		const plugin_operations_t *ops;
1649 		REPARSE_POINT *reparse;
1650 		struct open_file *of;
1651 
1652 		of = (struct open_file*)(long)fi->fh;
1653 		res = CALL_REPARSE_PLUGIN(ni, write, buf, size, offset,
1654 								&of->fi);
1655 		if (res >= 0) {
1656 			goto stamps;
1657 		}
1658 #else /* DISABLE_PLUGINS */
1659 		res = -EOPNOTSUPP;
1660 #endif /* DISABLE_PLUGINS */
1661 		goto exit;
1662 	}
1663 	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1664 	if (!na) {
1665 		res = -errno;
1666 		goto exit;
1667 	}
1668 	while (size) {
1669 		s64 ret = ntfs_attr_pwrite(na, offset, size, buf + total);
1670 		if (ret <= 0) {
1671 			res = -errno;
1672 			goto exit;
1673 		}
1674 		size   -= ret;
1675 		offset += ret;
1676 		total  += ret;
1677 	}
1678 	res = total;
1679 #ifndef DISABLE_PLUGINS
1680 stamps :
1681 #endif /* DISABLE_PLUGINS */
1682 	if ((res > 0)
1683 	    && (!ctx->dmtime
1684 		|| (sle64_to_cpu(ntfs_current_time())
1685 		     - sle64_to_cpu(ni->last_data_change_time)) > ctx->dmtime))
1686 		ntfs_fuse_update_times(ni, NTFS_UPDATE_MCTIME);
1687 exit:
1688 	if (na)
1689 		ntfs_attr_close(na);
1690 	if (res > 0)
1691 		set_archive(ni);
1692 	if (ntfs_inode_close(ni))
1693 		set_fuse_error(&res);
1694 	if (res < 0)
1695 		fuse_reply_err(req, -res);
1696 	else
1697 		fuse_reply_write(req, res);
1698 }
1699 
ntfs_fuse_chmod(struct SECURITY_CONTEXT * scx,fuse_ino_t ino,mode_t mode,struct stat * stbuf)1700 static int ntfs_fuse_chmod(struct SECURITY_CONTEXT *scx, fuse_ino_t ino,
1701 		mode_t mode, struct stat *stbuf)
1702 {
1703 	int res = 0;
1704 	ntfs_inode *ni;
1705 
1706 	  /* Unsupported if inherit or no user mapping has been defined */
1707 	if ((!scx->mapping[MAPUSERS] || ctx->inherit)
1708 	    && !ctx->silent) {
1709 		res = -EOPNOTSUPP;
1710 	} else {
1711 		ni = ntfs_inode_open(ctx->vol, INODE(ino));
1712 		if (!ni)
1713 			res = -errno;
1714 		else {
1715 			/* ignore if Windows inheritance is forced */
1716 			if (scx->mapping[MAPUSERS] && !ctx->inherit) {
1717 				if (ntfs_set_mode(scx, ni, mode))
1718 					res = -errno;
1719 				else {
1720 					ntfs_fuse_update_times(ni,
1721 							NTFS_UPDATE_CTIME);
1722 					/*
1723 					 * Must return updated times, and
1724 					 * inode has been updated, so hope
1725 					 * we get no further errors
1726 					 */
1727 					res = ntfs_fuse_getstat(scx, ni, stbuf);
1728 				}
1729 				NInoSetDirty(ni);
1730 			} else
1731 				res = ntfs_fuse_getstat(scx, ni, stbuf);
1732 			if (ntfs_inode_close(ni))
1733 				set_fuse_error(&res);
1734 		}
1735 	}
1736 	return res;
1737 }
1738 
ntfs_fuse_chown(struct SECURITY_CONTEXT * scx,fuse_ino_t ino,uid_t uid,gid_t gid,struct stat * stbuf)1739 static int ntfs_fuse_chown(struct SECURITY_CONTEXT *scx, fuse_ino_t ino,
1740 			uid_t uid, gid_t gid, struct stat *stbuf)
1741 {
1742 	ntfs_inode *ni;
1743 	int res;
1744 
1745 	  /* Unsupported if inherit or no user mapping has been defined */
1746 	if ((!scx->mapping[MAPUSERS] || ctx->inherit)
1747 			&& !ctx->silent
1748 			&& ((uid != ctx->uid) || (gid != ctx->gid)))
1749 		res = -EOPNOTSUPP;
1750 	else {
1751 		res = 0;
1752 		ni = ntfs_inode_open(ctx->vol, INODE(ino));
1753 		if (!ni)
1754 			res = -errno;
1755 		else {
1756 			/* ignore if Windows inheritance is forced */
1757 			if (scx->mapping[MAPUSERS]
1758 			  && !ctx->inherit
1759 			  && (((int)uid != -1) || ((int)gid != -1))) {
1760 				if (ntfs_set_owner(scx, ni, uid, gid))
1761 					res = -errno;
1762 				else {
1763 					ntfs_fuse_update_times(ni,
1764 							NTFS_UPDATE_CTIME);
1765 				/*
1766 				 * Must return updated times, and
1767 				 * inode has been updated, so hope
1768 				 * we get no further errors
1769 				 */
1770 					res = ntfs_fuse_getstat(scx, ni, stbuf);
1771 				}
1772 			} else
1773 				res = ntfs_fuse_getstat(scx, ni, stbuf);
1774 			if (ntfs_inode_close(ni))
1775 				set_fuse_error(&res);
1776 		}
1777 	}
1778 	return (res);
1779 }
1780 
ntfs_fuse_chownmod(struct SECURITY_CONTEXT * scx,fuse_ino_t ino,uid_t uid,gid_t gid,mode_t mode,struct stat * stbuf)1781 static int ntfs_fuse_chownmod(struct SECURITY_CONTEXT *scx, fuse_ino_t ino,
1782 			uid_t uid, gid_t gid, mode_t mode, struct stat *stbuf)
1783 {
1784 	ntfs_inode *ni;
1785 	int res;
1786 
1787 	  /* Unsupported if inherit or no user mapping has been defined */
1788 	if ((!scx->mapping[MAPUSERS] || ctx->inherit)
1789 			&& !ctx->silent
1790 			&& ((uid != ctx->uid) || (gid != ctx->gid)))
1791 		res = -EOPNOTSUPP;
1792 	else {
1793 		res = 0;
1794 		ni = ntfs_inode_open(ctx->vol, INODE(ino));
1795 		if (!ni)
1796 			res = -errno;
1797 		else {
1798 			/* ignore if Windows inheritance is forced */
1799 			if (scx->mapping[MAPUSERS] && !ctx->inherit) {
1800 				if (ntfs_set_ownmod(scx, ni, uid, gid, mode))
1801 					res = -errno;
1802 				else {
1803 					ntfs_fuse_update_times(ni,
1804 							NTFS_UPDATE_CTIME);
1805 					/*
1806 					 * Must return updated times, and
1807 					 * inode has been updated, so hope
1808 					 * we get no further errors
1809 					 */
1810 					res = ntfs_fuse_getstat(scx, ni, stbuf);
1811 				}
1812 			} else
1813 				res = ntfs_fuse_getstat(scx, ni, stbuf);
1814 			if (ntfs_inode_close(ni))
1815 				set_fuse_error(&res);
1816 		}
1817 	}
1818 	return (res);
1819 }
1820 
ntfs_fuse_trunc(struct SECURITY_CONTEXT * scx,fuse_ino_t ino,off_t size,BOOL chkwrite,struct stat * stbuf)1821 static int ntfs_fuse_trunc(struct SECURITY_CONTEXT *scx, fuse_ino_t ino,
1822 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
1823 		off_t size, BOOL chkwrite, struct stat *stbuf)
1824 #else
1825 		off_t size, BOOL chkwrite __attribute__((unused)),
1826 		struct stat *stbuf)
1827 #endif
1828 {
1829 	ntfs_inode *ni = NULL;
1830 	ntfs_attr *na = NULL;
1831 	int res;
1832 	s64 oldsize;
1833 
1834 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
1835 	if (!ni)
1836 		goto exit;
1837 
1838 	/* deny truncating metadata files */
1839 	if (ino < FILE_first_user) {
1840 		errno = EPERM;
1841 		goto exit;
1842 	}
1843 	if (!(ni->flags & FILE_ATTR_REPARSE_POINT)) {
1844 		na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1845 		if (!na)
1846 			goto exit;
1847 	}
1848 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
1849 	/*
1850 	 * deny truncation if cannot write to file
1851 	 * (already checked for ftruncate())
1852 	 */
1853 	if (scx->mapping[MAPUSERS]
1854 	    && chkwrite
1855 	    && !ntfs_allowed_access(scx, ni, S_IWRITE)) {
1856 		errno = EACCES;
1857 		goto exit;
1858 	}
1859 #endif
1860 	if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1861 #ifndef DISABLE_PLUGINS
1862 		const plugin_operations_t *ops;
1863 		REPARSE_POINT *reparse;
1864 
1865 		res = CALL_REPARSE_PLUGIN(ni, truncate, size);
1866 		if (!res) {
1867 			set_archive(ni);
1868 			goto stamps;
1869 		}
1870 #else /* DISABLE_PLUGINS */
1871 		res = -EOPNOTSUPP;
1872 #endif /* DISABLE_PLUGINS */
1873 		goto exit;
1874 	}
1875 		/*
1876 		 * for compressed files, upsizing is done by inserting a final
1877 		 * zero, which is optimized as creating a hole when possible.
1878 		 */
1879 	oldsize = na->data_size;
1880 	if ((na->data_flags & ATTR_COMPRESSION_MASK)
1881 	    && (size > na->initialized_size)) {
1882 		char zero = 0;
1883 		if (ntfs_attr_pwrite(na, size - 1, 1, &zero) <= 0)
1884 			goto exit;
1885 	} else
1886 		if (ntfs_attr_truncate(na, size))
1887 			goto exit;
1888 	if (oldsize != size)
1889 		set_archive(ni);
1890 
1891 #ifndef DISABLE_PLUGINS
1892 stamps :
1893 #endif /* DISABLE_PLUGINS */
1894 	ntfs_fuse_update_times(ni, NTFS_UPDATE_MCTIME);
1895 	res = ntfs_fuse_getstat(scx, ni, stbuf);
1896 	errno = (res ? -res : 0);
1897 exit:
1898 	res = -errno;
1899 	ntfs_attr_close(na);
1900 	if (ntfs_inode_close(ni))
1901 		set_fuse_error(&res);
1902 	return res;
1903 }
1904 
1905 #if defined(HAVE_UTIMENSAT) & defined(FUSE_SET_ATTR_ATIME_NOW)
1906 
ntfs_fuse_utimens(struct SECURITY_CONTEXT * scx,fuse_ino_t ino,struct stat * stin,struct stat * stbuf,int to_set)1907 static int ntfs_fuse_utimens(struct SECURITY_CONTEXT *scx, fuse_ino_t ino,
1908 		struct stat *stin, struct stat *stbuf, int to_set)
1909 {
1910 	ntfs_inode *ni;
1911 	int res = 0;
1912 
1913 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
1914 	if (!ni)
1915 		return -errno;
1916 
1917 			/* no check or update if both UTIME_OMIT */
1918 	if (to_set & (FUSE_SET_ATTR_ATIME + FUSE_SET_ATTR_MTIME)) {
1919 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
1920 		if (ntfs_allowed_as_owner(scx, ni)
1921 		    || ((to_set & FUSE_SET_ATTR_ATIME_NOW)
1922 			&& (to_set & FUSE_SET_ATTR_MTIME_NOW)
1923 			&& ntfs_allowed_access(scx, ni, S_IWRITE))) {
1924 #endif
1925 			ntfs_time_update_flags mask = NTFS_UPDATE_CTIME;
1926 
1927 			if (to_set & FUSE_SET_ATTR_ATIME_NOW)
1928 				mask |= NTFS_UPDATE_ATIME;
1929 			else
1930 				if (to_set & FUSE_SET_ATTR_ATIME)
1931 					ni->last_access_time
1932 						= timespec2ntfs(stin->st_atim);
1933 			if (to_set & FUSE_SET_ATTR_MTIME_NOW)
1934 				mask |= NTFS_UPDATE_MTIME;
1935 			else
1936 				if (to_set & FUSE_SET_ATTR_MTIME)
1937 					ni->last_data_change_time
1938 						= timespec2ntfs(stin->st_mtim);
1939 			ntfs_inode_update_times(ni, mask);
1940 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
1941 		} else
1942 			res = -errno;
1943 #endif
1944 	}
1945 	if (!res)
1946 		res = ntfs_fuse_getstat(scx, ni, stbuf);
1947 	if (ntfs_inode_close(ni))
1948 		set_fuse_error(&res);
1949 	return res;
1950 }
1951 
1952 #else /* defined(HAVE_UTIMENSAT) & defined(FUSE_SET_ATTR_ATIME_NOW) */
1953 
ntfs_fuse_utime(struct SECURITY_CONTEXT * scx,fuse_ino_t ino,struct stat * stin,struct stat * stbuf)1954 static int ntfs_fuse_utime(struct SECURITY_CONTEXT *scx, fuse_ino_t ino,
1955 		struct stat *stin, struct stat *stbuf)
1956 {
1957 	ntfs_inode *ni;
1958 	int res = 0;
1959 	struct timespec actime;
1960 	struct timespec modtime;
1961 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
1962 	BOOL ownerok;
1963 	BOOL writeok;
1964 #endif
1965 
1966 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
1967 	if (!ni)
1968 		return -errno;
1969 
1970 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
1971 	ownerok = ntfs_allowed_as_owner(scx, ni);
1972 	if (stin) {
1973 		/*
1974 		 * fuse never calls with a NULL buf and we do not
1975 		 * know whether the specific condition can be applied
1976 		 * So we have to accept updating by a non-owner having
1977 		 * write access.
1978 		 */
1979 		writeok = !ownerok
1980 			&& (stin->st_atime == stin->st_mtime)
1981 			&& ntfs_allowed_access(scx, ni, S_IWRITE);
1982 			/* Must be owner */
1983 		if (!ownerok && !writeok)
1984 			res = (stin->st_atime == stin->st_mtime
1985 					? -EACCES : -EPERM);
1986 		else {
1987 			actime.tv_sec = stin->st_atime;
1988 			actime.tv_nsec = 0;
1989 			modtime.tv_sec = stin->st_mtime;
1990 			modtime.tv_nsec = 0;
1991 			ni->last_access_time = timespec2ntfs(actime);
1992 			ni->last_data_change_time = timespec2ntfs(modtime);
1993 			ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
1994 		}
1995 	} else {
1996 			/* Must be owner or have write access */
1997 		writeok = !ownerok
1998 			&& ntfs_allowed_access(scx, ni, S_IWRITE);
1999 		if (!ownerok && !writeok)
2000 			res = -EACCES;
2001 		else
2002 			ntfs_inode_update_times(ni, NTFS_UPDATE_AMCTIME);
2003 	}
2004 #else
2005 	if (stin) {
2006 		actime.tv_sec = stin->st_atime;
2007 		actime.tv_nsec = 0;
2008 		modtime.tv_sec = stin->st_mtime;
2009 		modtime.tv_nsec = 0;
2010 		ni->last_access_time = timespec2ntfs(actime);
2011 		ni->last_data_change_time = timespec2ntfs(modtime);
2012 		ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
2013 	} else
2014 		ntfs_inode_update_times(ni, NTFS_UPDATE_AMCTIME);
2015 #endif
2016 
2017 	res = ntfs_fuse_getstat(scx, ni, stbuf);
2018 	if (ntfs_inode_close(ni))
2019 		set_fuse_error(&res);
2020 	return res;
2021 }
2022 
2023 #endif /* defined(HAVE_UTIMENSAT) & defined(FUSE_SET_ATTR_ATIME_NOW) */
2024 
ntfs_fuse_setattr(fuse_req_t req,fuse_ino_t ino,struct stat * attr,int to_set,struct fuse_file_info * fi)2025 static void ntfs_fuse_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
2026 			 int to_set, struct fuse_file_info *fi __attribute__((unused)))
2027 {
2028 	struct stat stbuf;
2029 	ntfs_inode *ni;
2030 	int res;
2031 	struct SECURITY_CONTEXT security;
2032 
2033 	res = 0;
2034 	ntfs_fuse_fill_security_context(req, &security);
2035 						/* no flags */
2036 	if (!(to_set
2037 		    & (FUSE_SET_ATTR_MODE
2038 			| FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID
2039 			| FUSE_SET_ATTR_SIZE
2040 			| FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
2041 		ni = ntfs_inode_open(ctx->vol, INODE(ino));
2042 		if (!ni)
2043 			res = -errno;
2044 		else {
2045 			res = ntfs_fuse_getstat(&security, ni, &stbuf);
2046 			if (ntfs_inode_close(ni))
2047 				set_fuse_error(&res);
2048 		}
2049 	}
2050 						/* some set of uid/gid/mode */
2051 	if (to_set
2052 		    & (FUSE_SET_ATTR_MODE
2053 			| FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID)) {
2054 		switch (to_set
2055 			    & (FUSE_SET_ATTR_MODE
2056 				| FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID)) {
2057 		case FUSE_SET_ATTR_MODE :
2058 			res = ntfs_fuse_chmod(&security, ino,
2059 						attr->st_mode & 07777, &stbuf);
2060 			break;
2061 		case FUSE_SET_ATTR_UID :
2062 			res = ntfs_fuse_chown(&security, ino, attr->st_uid,
2063 						(gid_t)-1, &stbuf);
2064 			break;
2065 		case FUSE_SET_ATTR_GID :
2066 			res = ntfs_fuse_chown(&security, ino, (uid_t)-1,
2067 						attr->st_gid, &stbuf);
2068 			break;
2069 		case FUSE_SET_ATTR_UID + FUSE_SET_ATTR_GID :
2070 			res = ntfs_fuse_chown(&security, ino, attr->st_uid,
2071 						attr->st_gid, &stbuf);
2072 			break;
2073 		case FUSE_SET_ATTR_UID + FUSE_SET_ATTR_MODE:
2074 			res = ntfs_fuse_chownmod(&security, ino, attr->st_uid,
2075 						(gid_t)-1,attr->st_mode,
2076 						&stbuf);
2077 			break;
2078 		case FUSE_SET_ATTR_GID + FUSE_SET_ATTR_MODE:
2079 			res = ntfs_fuse_chownmod(&security, ino, (uid_t)-1,
2080 						attr->st_gid,attr->st_mode,
2081 						&stbuf);
2082 			break;
2083 		case FUSE_SET_ATTR_UID + FUSE_SET_ATTR_GID + FUSE_SET_ATTR_MODE:
2084 			res = ntfs_fuse_chownmod(&security, ino, attr->st_uid,
2085 					attr->st_gid,attr->st_mode, &stbuf);
2086 			break;
2087 		default :
2088 			break;
2089 		}
2090 	}
2091 						/* size */
2092 	if (!res && (to_set & FUSE_SET_ATTR_SIZE)) {
2093 		res = ntfs_fuse_trunc(&security, ino, attr->st_size,
2094 					!fi, &stbuf);
2095 	}
2096 						/* some set of atime/mtime */
2097 	if (!res && (to_set & (FUSE_SET_ATTR_ATIME + FUSE_SET_ATTR_MTIME))) {
2098 #if defined(HAVE_UTIMENSAT) & defined(FUSE_SET_ATTR_ATIME_NOW)
2099 		res = ntfs_fuse_utimens(&security, ino, attr, &stbuf, to_set);
2100 #else /* defined(HAVE_UTIMENSAT) & defined(FUSE_SET_ATTR_ATIME_NOW) */
2101 		res = ntfs_fuse_utime(&security, ino, attr, &stbuf);
2102 #endif /* defined(HAVE_UTIMENSAT) & defined(FUSE_SET_ATTR_ATIME_NOW) */
2103 	}
2104 	if (res)
2105 		fuse_reply_err(req, -res);
2106 	else
2107 		fuse_reply_attr(req, &stbuf, ATTR_TIMEOUT);
2108 }
2109 
2110 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
2111 
ntfs_fuse_access(fuse_req_t req,fuse_ino_t ino,int mask)2112 static void ntfs_fuse_access(fuse_req_t req, fuse_ino_t ino, int mask)
2113 {
2114 	int res = 0;
2115 	int mode;
2116 	ntfs_inode *ni;
2117 	struct SECURITY_CONTEXT security;
2118 
2119 	  /* JPA return unsupported if no user mapping has been defined */
2120 	if (!ntfs_fuse_fill_security_context(req, &security)) {
2121 		if (ctx->silent)
2122 			res = 0;
2123 		else
2124 			res = -EOPNOTSUPP;
2125 	} else {
2126 		ni = ntfs_inode_open(ctx->vol, INODE(ino));
2127 		if (!ni) {
2128 			res = -errno;
2129 		} else {
2130 			mode = 0;
2131 			if (mask & (X_OK | W_OK | R_OK)) {
2132 				if (mask & X_OK) mode += S_IEXEC;
2133 				if (mask & W_OK) mode += S_IWRITE;
2134 				if (mask & R_OK) mode += S_IREAD;
2135 				if (!ntfs_allowed_access(&security,
2136 						ni, mode))
2137 					res = -errno;
2138 			}
2139 			if (ntfs_inode_close(ni))
2140 				set_fuse_error(&res);
2141 		}
2142 	}
2143 	if (res < 0)
2144 		fuse_reply_err(req, -res);
2145 	else
2146 		fuse_reply_err(req, 0);
2147 }
2148 
2149 #endif /* !KERNELPERMS | (POSIXACLS & !KERNELACLS) */
2150 
ntfs_fuse_create(fuse_req_t req,fuse_ino_t parent,const char * name,mode_t typemode,dev_t dev,struct fuse_entry_param * e,const char * target,struct fuse_file_info * fi)2151 static int ntfs_fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name,
2152 		mode_t typemode, dev_t dev,
2153 		struct fuse_entry_param *e,
2154 		const char *target, struct fuse_file_info *fi)
2155 {
2156 	ntfschar *uname = NULL, *utarget = NULL;
2157 	ntfs_inode *dir_ni = NULL, *ni;
2158 	struct open_file *of;
2159 	int state = 0;
2160 	le32 securid;
2161 	gid_t gid;
2162 	mode_t dsetgid;
2163 	mode_t type = typemode & ~07777;
2164 	mode_t perm;
2165 	struct SECURITY_CONTEXT security;
2166 	int res = 0, uname_len, utarget_len;
2167 
2168 	/* Generate unicode filename. */
2169 	uname_len = ntfs_mbstoucs(name, &uname);
2170 	if ((uname_len < 0)
2171 	    || (ctx->windows_names
2172 		&& ntfs_forbidden_names(ctx->vol,uname,uname_len,TRUE))) {
2173 		res = -errno;
2174 		goto exit;
2175 	}
2176 	/* Deny creating into $Extend */
2177 	if (parent == FILE_Extend) {
2178 		res = -EPERM;
2179 		goto exit;
2180 	}
2181 	/* Open parent directory. */
2182 	dir_ni = ntfs_inode_open(ctx->vol, INODE(parent));
2183 	if (!dir_ni) {
2184 		res = -errno;
2185 		goto exit;
2186 	}
2187 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
2188 		/* make sure parent directory is writeable and executable */
2189 	if (!ntfs_fuse_fill_security_context(req, &security)
2190 	       || ntfs_allowed_create(&security,
2191 				dir_ni, &gid, &dsetgid)) {
2192 #else
2193 		ntfs_fuse_fill_security_context(req, &security);
2194 		ntfs_allowed_create(&security, dir_ni, &gid, &dsetgid);
2195 #endif
2196 		if (S_ISDIR(type))
2197 			perm = (typemode & ~ctx->dmask & 0777)
2198 				| (dsetgid & S_ISGID);
2199 		else
2200 			perm = typemode & ~ctx->fmask & 0777;
2201 			/*
2202 			 * Try to get a security id available for
2203 			 * file creation (from inheritance or argument).
2204 			 * This is not possible for NTFS 1.x, and we will
2205 			 * have to build a security attribute later.
2206 			 */
2207 		if (!ctx->security.mapping[MAPUSERS])
2208 			securid = const_cpu_to_le32(0);
2209 		else
2210 			if (ctx->inherit)
2211 				securid = ntfs_inherited_id(&security,
2212 					dir_ni, S_ISDIR(type));
2213 			else
2214 #if POSIXACLS
2215 				securid = ntfs_alloc_securid(&security,
2216 					security.uid, gid,
2217 					dir_ni, perm, S_ISDIR(type));
2218 #else
2219 				securid = ntfs_alloc_securid(&security,
2220 					security.uid, gid,
2221 					perm & ~security.umask, S_ISDIR(type));
2222 #endif
2223 		/* Create object specified in @type. */
2224 		switch (type) {
2225 			case S_IFCHR:
2226 			case S_IFBLK:
2227 				ni = ntfs_create_device(dir_ni, securid,
2228 						uname, uname_len, type, dev);
2229 				break;
2230 			case S_IFLNK:
2231 				utarget_len = ntfs_mbstoucs(target, &utarget);
2232 				if (utarget_len < 0) {
2233 					res = -errno;
2234 					goto exit;
2235 				}
2236 				ni = ntfs_create_symlink(dir_ni, securid,
2237 						uname, uname_len,
2238 						utarget, utarget_len);
2239 				break;
2240 			default:
2241 				ni = ntfs_create(dir_ni, securid, uname,
2242 						uname_len, type);
2243 				break;
2244 		}
2245 		if (ni) {
2246 				/*
2247 				 * set the security attribute if a security id
2248 				 * could not be allocated (eg NTFS 1.x)
2249 				 */
2250 			if (ctx->security.mapping[MAPUSERS]) {
2251 #if POSIXACLS
2252 				if (!securid
2253 				   && ntfs_set_inherited_posix(&security, ni,
2254 					security.uid, gid,
2255 					dir_ni, perm) < 0)
2256 					set_fuse_error(&res);
2257 #else
2258 				if (!securid
2259 				   && ntfs_set_owner_mode(&security, ni,
2260 					security.uid, gid,
2261 					perm & ~security.umask) < 0)
2262 					set_fuse_error(&res);
2263 #endif
2264 			}
2265 			set_archive(ni);
2266 			/* mark a need to compress the end of file */
2267 			if (fi && (ni->flags & FILE_ATTR_COMPRESSED)) {
2268 				state |= CLOSE_COMPRESSED;
2269 			}
2270 #ifdef HAVE_SETXATTR	/* extended attributes interface required */
2271 			/* mark a future need to fixup encrypted inode */
2272 			if (fi
2273 			    && ctx->efs_raw
2274 			    && (ni->flags & FILE_ATTR_ENCRYPTED))
2275 				state |= CLOSE_ENCRYPTED;
2276 #endif /* HAVE_SETXATTR */
2277 			if (fi && ctx->dmtime)
2278 				state |= CLOSE_DMTIME;
2279 			ntfs_inode_update_mbsname(dir_ni, name, ni->mft_no);
2280 			NInoSetDirty(ni);
2281 			e->ino = ni->mft_no;
2282 			e->generation = 1;
2283 			e->attr_timeout = ATTR_TIMEOUT;
2284 			e->entry_timeout = ENTRY_TIMEOUT;
2285 			res = ntfs_fuse_getstat(&security, ni, &e->attr);
2286 			/*
2287 			 * closing ni requires access to dir_ni to
2288 			 * synchronize the index, avoid double opening.
2289 			 */
2290 			if (ntfs_inode_close_in_dir(ni, dir_ni))
2291 				set_fuse_error(&res);
2292 			ntfs_fuse_update_times(dir_ni, NTFS_UPDATE_MCTIME);
2293 		} else
2294 			res = -errno;
2295 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
2296 	} else
2297 		res = -errno;
2298 #endif
2299 
2300 exit:
2301 	free(uname);
2302 	if (ntfs_inode_close(dir_ni))
2303 		set_fuse_error(&res);
2304 	if (utarget)
2305 		free(utarget);
2306 	if ((res >= 0) && fi) {
2307 		of = (struct open_file*)malloc(sizeof(struct open_file));
2308 		if (of) {
2309 			of->parent = 0;
2310 			of->ino = e->ino;
2311 			of->state = state;
2312 			of->next = ctx->open_files;
2313 			of->previous = (struct open_file*)NULL;
2314 			if (ctx->open_files)
2315 				ctx->open_files->previous = of;
2316 			ctx->open_files = of;
2317 			fi->fh = (long)of;
2318 		}
2319 	}
2320 	return res;
2321 }
2322 
ntfs_fuse_create_file(fuse_req_t req,fuse_ino_t parent,const char * name,mode_t mode,struct fuse_file_info * fi)2323 static void ntfs_fuse_create_file(fuse_req_t req, fuse_ino_t parent,
2324 			const char *name, mode_t mode,
2325 			struct fuse_file_info *fi)
2326 {
2327 	int res;
2328 	struct fuse_entry_param entry;
2329 
2330 	res = ntfs_fuse_create(req, parent, name, mode & (S_IFMT | 07777),
2331 				0, &entry, NULL, fi);
2332 	if (res < 0)
2333 		fuse_reply_err(req, -res);
2334 	else
2335 		fuse_reply_create(req, &entry, fi);
2336 }
2337 
ntfs_fuse_mknod(fuse_req_t req,fuse_ino_t parent,const char * name,mode_t mode,dev_t rdev)2338 static void ntfs_fuse_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
2339 		       mode_t mode, dev_t rdev)
2340 {
2341 	int res;
2342 	struct fuse_entry_param e;
2343 
2344 	res = ntfs_fuse_create(req, parent, name, mode & (S_IFMT | 07777),
2345 				rdev, &e,NULL,(struct fuse_file_info*)NULL);
2346 	if (res < 0)
2347 		fuse_reply_err(req, -res);
2348 	else
2349 		fuse_reply_entry(req, &e);
2350 }
2351 
ntfs_fuse_symlink(fuse_req_t req,const char * target,fuse_ino_t parent,const char * name)2352 static void ntfs_fuse_symlink(fuse_req_t req, const char *target,
2353 			fuse_ino_t parent, const char *name)
2354 {
2355 	int res;
2356 	struct fuse_entry_param entry;
2357 
2358 	res = ntfs_fuse_create(req, parent, name, S_IFLNK, 0,
2359 			&entry, target, (struct fuse_file_info*)NULL);
2360 	if (res < 0)
2361 		fuse_reply_err(req, -res);
2362 	else
2363 		fuse_reply_entry(req, &entry);
2364 }
2365 
2366 
ntfs_fuse_newlink(fuse_req_t req,fuse_ino_t ino,fuse_ino_t newparent,const char * newname,struct fuse_entry_param * e)2367 static int ntfs_fuse_newlink(fuse_req_t req __attribute__((unused)),
2368 			fuse_ino_t ino, fuse_ino_t newparent,
2369 			const char *newname, struct fuse_entry_param *e)
2370 {
2371 	ntfschar *uname = NULL;
2372 	ntfs_inode *dir_ni = NULL, *ni;
2373 	int res = 0, uname_len;
2374 	struct SECURITY_CONTEXT security;
2375 
2376 	/* Open file for which create hard link. */
2377 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
2378 	if (!ni) {
2379 		res = -errno;
2380 		goto exit;
2381 	}
2382 
2383 	/* Do not accept linking to a directory (except for renaming) */
2384 	if (e && (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
2385 		errno = EPERM;
2386 		res = -errno;
2387 		goto exit;
2388 	}
2389 	/* Generate unicode filename. */
2390 	uname_len = ntfs_mbstoucs(newname, &uname);
2391 	if ((uname_len < 0)
2392             || (ctx->windows_names
2393                 && ntfs_forbidden_names(ctx->vol,uname,uname_len,TRUE))) {
2394 		res = -errno;
2395 		goto exit;
2396 	}
2397 	/* Open parent directory. */
2398 	dir_ni = ntfs_inode_open(ctx->vol, INODE(newparent));
2399 	if (!dir_ni) {
2400 		res = -errno;
2401 		goto exit;
2402 	}
2403 
2404 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
2405 		/* make sure the target parent directory is writeable */
2406 	if (ntfs_fuse_fill_security_context(req, &security)
2407 	    && !ntfs_allowed_access(&security,dir_ni,S_IWRITE + S_IEXEC))
2408 		res = -EACCES;
2409 	else
2410 #else
2411 	ntfs_fuse_fill_security_context(req, &security);
2412 #endif
2413 	{
2414 		if (ntfs_link(ni, dir_ni, uname, uname_len)) {
2415 			res = -errno;
2416 			goto exit;
2417 		}
2418 		ntfs_inode_update_mbsname(dir_ni, newname, ni->mft_no);
2419 		if (e) {
2420 			e->ino = ni->mft_no;
2421 			e->generation = 1;
2422 			e->attr_timeout = ATTR_TIMEOUT;
2423 			e->entry_timeout = ENTRY_TIMEOUT;
2424 			res = ntfs_fuse_getstat(&security, ni, &e->attr);
2425 		}
2426 		set_archive(ni);
2427 		ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
2428 		ntfs_fuse_update_times(dir_ni, NTFS_UPDATE_MCTIME);
2429 	}
2430 exit:
2431 	/*
2432 	 * Must close dir_ni first otherwise ntfs_inode_sync_file_name(ni)
2433 	 * may fail because ni may not be in parent's index on the disk yet.
2434 	 */
2435 	if (ntfs_inode_close(dir_ni))
2436 		set_fuse_error(&res);
2437 	if (ntfs_inode_close(ni))
2438 		set_fuse_error(&res);
2439 	free(uname);
2440 	return (res);
2441 }
2442 
ntfs_fuse_link(fuse_req_t req,fuse_ino_t ino,fuse_ino_t newparent,const char * newname)2443 static void ntfs_fuse_link(fuse_req_t req, fuse_ino_t ino,
2444 			fuse_ino_t newparent, const char *newname)
2445 {
2446 	struct fuse_entry_param entry;
2447 	int res;
2448 
2449 	res = ntfs_fuse_newlink(req, ino, newparent, newname, &entry);
2450 	if (res)
2451 		fuse_reply_err(req, -res);
2452 	else
2453 		fuse_reply_entry(req, &entry);
2454 }
2455 
ntfs_fuse_rm(fuse_req_t req,fuse_ino_t parent,const char * name,enum RM_TYPES rm_type)2456 static int ntfs_fuse_rm(fuse_req_t req, fuse_ino_t parent, const char *name,
2457 			enum RM_TYPES rm_type __attribute__((unused)))
2458 {
2459 	ntfschar *uname = NULL;
2460 	ntfschar *ugname;
2461 	ntfs_inode *dir_ni = NULL, *ni = NULL;
2462 	int res = 0, uname_len;
2463 	int ugname_len;
2464 	u64 iref;
2465 	fuse_ino_t ino;
2466 	struct open_file *of;
2467 	char ghostname[GHOSTLTH];
2468 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
2469 	struct SECURITY_CONTEXT security;
2470 #endif
2471 
2472 	/* Deny removing from $Extend */
2473 	if (parent == FILE_Extend) {
2474 		res = -EPERM;
2475 		goto exit;
2476 	}
2477 	/* Open parent directory. */
2478 	dir_ni = ntfs_inode_open(ctx->vol, INODE(parent));
2479 	if (!dir_ni) {
2480 		res = -errno;
2481 		goto exit;
2482 	}
2483 	/* Generate unicode filename. */
2484 	uname_len = ntfs_mbstoucs(name, &uname);
2485 	if (uname_len < 0) {
2486 		res = -errno;
2487 		goto exit;
2488 	}
2489 	/* Open object for delete. */
2490 	iref = ntfs_inode_lookup_by_mbsname(dir_ni, name);
2491 	if (iref == (u64)-1) {
2492 		res = -errno;
2493 		goto exit;
2494 	}
2495 	ino = (fuse_ino_t)MREF(iref);
2496 	/* deny unlinking metadata files */
2497 	if (ino < FILE_first_user) {
2498 		res = -EPERM;
2499 		goto exit;
2500 	}
2501 
2502 	ni = ntfs_inode_open(ctx->vol, ino);
2503 	if (!ni) {
2504 		res = -errno;
2505 		goto exit;
2506 	}
2507 
2508 #if defined(__sun) && defined (__SVR4)
2509 	/* on Solaris : deny unlinking directories */
2510 	if (rm_type
2511 	    == (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ? RM_LINK : RM_DIR)) {
2512 		errno = EPERM;
2513 		res = -errno;
2514 		goto exit;
2515 	}
2516 #endif /* defined(__sun) && defined (__SVR4) */
2517 
2518 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
2519 	/* JPA deny unlinking if directory is not writable and executable */
2520 	if (ntfs_fuse_fill_security_context(req, &security)
2521 	    && !ntfs_allowed_dir_access(&security, dir_ni, ino, ni,
2522 				   S_IEXEC + S_IWRITE + S_ISVTX)) {
2523 		errno = EACCES;
2524 		res = -errno;
2525 		goto exit;
2526 	}
2527 #endif
2528 		/*
2529 		 * We keep one open_file record per opening, to avoid
2530 		 * having to check the list of open files when opening
2531 		 * and closing (which are more frequent than unlinking).
2532 		 * As a consequence, we may have to create several
2533 		 * ghosts names for the same file.
2534 		 * The file may have been opened with a different name
2535 		 * in a different parent directory. The ghost is
2536 		 * nevertheless created in the parent directory of the
2537 		 * name being unlinked, and permissions to do so are the
2538 		 * same as required for unlinking.
2539 		 */
2540 	for (of=ctx->open_files; of; of = of->next) {
2541 		if ((of->ino == ino) && !(of->state & CLOSE_GHOST)) {
2542 			/* file was open, create a ghost in unlink parent */
2543 			ntfs_inode *gni;
2544 			u64 gref;
2545 
2546 			/* ni has to be closed for linking ghost */
2547 			if (ni) {
2548 				if (ntfs_inode_close(ni)) {
2549 					res = -errno;
2550 					goto exit;
2551 				}
2552 				ni = (ntfs_inode*)NULL;
2553 			}
2554 			of->state |= CLOSE_GHOST;
2555 			of->parent = parent;
2556 			of->ghost = ++ctx->latest_ghost;
2557 			sprintf(ghostname,ghostformat,of->ghost);
2558 				/* Generate unicode filename. */
2559 			ugname = (ntfschar*)NULL;
2560 			ugname_len = ntfs_mbstoucs(ghostname, &ugname);
2561 			if (ugname_len < 0) {
2562 				res = -errno;
2563 				goto exit;
2564 			}
2565 			/* sweep existing ghost if any, ignoring errors */
2566 			gref = ntfs_inode_lookup_by_mbsname(dir_ni, ghostname);
2567 			if (gref != (u64)-1) {
2568 				gni = ntfs_inode_open(ctx->vol, MREF(gref));
2569 				ntfs_delete(ctx->vol, (char*)NULL, gni, dir_ni,
2570 					 ugname, ugname_len);
2571 				/* ntfs_delete() always closes gni and dir_ni */
2572 				dir_ni = (ntfs_inode*)NULL;
2573 			} else {
2574 				if (ntfs_inode_close(dir_ni)) {
2575 					res = -errno;
2576 					goto out;
2577 				}
2578 				dir_ni = (ntfs_inode*)NULL;
2579 			}
2580 			free(ugname);
2581 			res = ntfs_fuse_newlink(req, of->ino, parent, ghostname,
2582 					(struct fuse_entry_param*)NULL);
2583 			if (res)
2584 				goto out;
2585 				/* now reopen then parent directory */
2586 			dir_ni = ntfs_inode_open(ctx->vol, INODE(parent));
2587 			if (!dir_ni) {
2588 				res = -errno;
2589 				goto exit;
2590 			}
2591 		}
2592 	}
2593 	if (!ni) {
2594 		ni = ntfs_inode_open(ctx->vol, ino);
2595 		if (!ni) {
2596 			res = -errno;
2597 			goto exit;
2598 		}
2599 	}
2600 	if (ntfs_delete(ctx->vol, (char*)NULL, ni, dir_ni,
2601 				 uname, uname_len))
2602 		res = -errno;
2603 		/* ntfs_delete() always closes ni and dir_ni */
2604 	ni = dir_ni = NULL;
2605 exit:
2606 	if (ntfs_inode_close(ni) && !res)
2607 		res = -errno;
2608 	if (ntfs_inode_close(dir_ni) && !res)
2609 		res = -errno;
2610 out :
2611 	free(uname);
2612 	return res;
2613 }
2614 
ntfs_fuse_unlink(fuse_req_t req,fuse_ino_t parent,const char * name)2615 static void ntfs_fuse_unlink(fuse_req_t req, fuse_ino_t parent,
2616 				const char *name)
2617 {
2618 	int res;
2619 
2620 	res = ntfs_fuse_rm(req, parent, name, RM_LINK);
2621 	if (res)
2622 		fuse_reply_err(req, -res);
2623 	else
2624 		fuse_reply_err(req, 0);
2625 }
2626 
ntfs_fuse_safe_rename(fuse_req_t req,fuse_ino_t ino,fuse_ino_t parent,const char * name,fuse_ino_t xino,fuse_ino_t newparent,const char * newname,const char * tmp)2627 static int ntfs_fuse_safe_rename(fuse_req_t req, fuse_ino_t ino,
2628 			fuse_ino_t parent, const char *name, fuse_ino_t xino,
2629 			fuse_ino_t newparent, const char *newname,
2630 			const char *tmp)
2631 {
2632 	int ret;
2633 
2634 	ntfs_log_trace("Entering\n");
2635 
2636 	ret = ntfs_fuse_newlink(req, xino, newparent, tmp,
2637 				(struct fuse_entry_param*)NULL);
2638 	if (ret)
2639 		return ret;
2640 
2641 	ret = ntfs_fuse_rm(req, newparent, newname, RM_ANY);
2642 	if (!ret) {
2643 
2644 		ret = ntfs_fuse_newlink(req, ino, newparent, newname,
2645 					(struct fuse_entry_param*)NULL);
2646 		if (ret)
2647 			goto restore;
2648 
2649 		ret = ntfs_fuse_rm(req, parent, name, RM_ANY);
2650 		if (ret) {
2651 			if (ntfs_fuse_rm(req, newparent, newname, RM_ANY))
2652 				goto err;
2653 			goto restore;
2654 		}
2655 	}
2656 
2657 	goto cleanup;
2658 restore:
2659 	if (ntfs_fuse_newlink(req, xino, newparent, newname,
2660 				(struct fuse_entry_param*)NULL)) {
2661 err:
2662 		ntfs_log_perror("Rename failed. Existing file '%s' was renamed "
2663 				"to '%s'", newname, tmp);
2664 	} else {
2665 cleanup:
2666 		/*
2667 		 * Condition for this unlink has already been checked in
2668 		 * "ntfs_fuse_rename_existing_dest()", so it should never
2669 		 * fail (unless concurrent access to directories when fuse
2670 		 * is multithreaded)
2671 		 */
2672 		if (ntfs_fuse_rm(req, newparent, tmp, RM_ANY) < 0)
2673 			ntfs_log_perror("Rename failed. Existing file '%s' still present "
2674 				"as '%s'", newname, tmp);
2675 	}
2676 	return	ret;
2677 }
2678 
ntfs_fuse_rename_existing_dest(fuse_req_t req,fuse_ino_t ino,fuse_ino_t parent,const char * name,fuse_ino_t xino,fuse_ino_t newparent,const char * newname)2679 static int ntfs_fuse_rename_existing_dest(fuse_req_t req, fuse_ino_t ino,
2680 			fuse_ino_t parent, const char *name,
2681 			fuse_ino_t xino, fuse_ino_t newparent,
2682 			const char *newname)
2683 {
2684 	int ret, len;
2685 	char *tmp;
2686 	const char *ext = ".ntfs-3g-";
2687 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
2688 	ntfs_inode *newdir_ni;
2689 	struct SECURITY_CONTEXT security;
2690 #endif
2691 
2692 	ntfs_log_trace("Entering\n");
2693 
2694 	len = strlen(newname) + strlen(ext) + 10 + 1; /* wc(str(2^32)) + \0 */
2695 	tmp = (char*)ntfs_malloc(len);
2696 	if (!tmp)
2697 		return -errno;
2698 
2699 	ret = snprintf(tmp, len, "%s%s%010d", newname, ext, ++ntfs_sequence);
2700 	if (ret != len - 1) {
2701 		ntfs_log_error("snprintf failed: %d != %d\n", ret, len - 1);
2702 		ret = -EOVERFLOW;
2703 	} else {
2704 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
2705 			/*
2706 			 * Make sure existing dest can be removed.
2707 			 * This is only needed if parent directory is
2708 			 * sticky, because in this situation condition
2709 			 * for unlinking is different from condition for
2710 			 * linking
2711 			 */
2712 		newdir_ni = ntfs_inode_open(ctx->vol, INODE(newparent));
2713 		if (newdir_ni) {
2714 			if (!ntfs_fuse_fill_security_context(req,&security)
2715 			    || ntfs_allowed_dir_access(&security, newdir_ni,
2716 					xino, (ntfs_inode*)NULL,
2717 					S_IEXEC + S_IWRITE + S_ISVTX)) {
2718 				if (ntfs_inode_close(newdir_ni))
2719 					ret = -errno;
2720 				else
2721 					ret = ntfs_fuse_safe_rename(req, ino,
2722 							parent, name, xino,
2723 							newparent, newname,
2724 							tmp);
2725 			} else {
2726 				ntfs_inode_close(newdir_ni);
2727 				ret = -EACCES;
2728 			}
2729 		} else
2730 			ret = -errno;
2731 #else
2732 		ret = ntfs_fuse_safe_rename(req, ino, parent, name,
2733 					xino, newparent, newname, tmp);
2734 #endif
2735 	}
2736 	free(tmp);
2737 	return	ret;
2738 }
2739 
ntfs_fuse_rename(fuse_req_t req,fuse_ino_t parent,const char * name,fuse_ino_t newparent,const char * newname)2740 static void ntfs_fuse_rename(fuse_req_t req, fuse_ino_t parent,
2741 			const char *name, fuse_ino_t newparent,
2742 			const char *newname)
2743 {
2744 	int ret;
2745 	fuse_ino_t ino;
2746 	fuse_ino_t xino;
2747 	ntfs_inode *ni;
2748 
2749 	ntfs_log_debug("rename: old: '%s'  new: '%s'\n", name, newname);
2750 
2751 	/*
2752 	 *  FIXME: Rename should be atomic.
2753 	 */
2754 
2755 	ino = ntfs_fuse_inode_lookup(parent, name);
2756 	if (ino == (fuse_ino_t)-1) {
2757 		ret = -errno;
2758 		goto out;
2759 	}
2760 	/* Check whether target is present */
2761 	xino = ntfs_fuse_inode_lookup(newparent, newname);
2762 	if (xino != (fuse_ino_t)-1) {
2763 			/*
2764 			 * Target exists : no need to check whether it
2765 			 * designates the same inode, this has already
2766 			 * been checked (by fuse ?)
2767 			 */
2768 		ni = ntfs_inode_open(ctx->vol, INODE(xino));
2769 		if (!ni)
2770 			ret = -errno;
2771 		else {
2772 			ret = ntfs_check_empty_dir(ni);
2773 			if (ret < 0) {
2774 				ret = -errno;
2775 				ntfs_inode_close(ni);
2776 				goto out;
2777 			}
2778 
2779 			if (ntfs_inode_close(ni)) {
2780 				set_fuse_error(&ret);
2781 				goto out;
2782 			}
2783 			ret = ntfs_fuse_rename_existing_dest(req, ino, parent,
2784 						name, xino, newparent, newname);
2785 		}
2786 	} else {
2787 			/* target does not exist */
2788 		ret = ntfs_fuse_newlink(req, ino, newparent, newname,
2789 					(struct fuse_entry_param*)NULL);
2790 		if (ret)
2791 			goto out;
2792 
2793 		ret = ntfs_fuse_rm(req, parent, name, RM_ANY);
2794 		if (ret)
2795 			ntfs_fuse_rm(req, newparent, newname, RM_ANY);
2796 	}
2797 out:
2798 	if (ret)
2799 		fuse_reply_err(req, -ret);
2800 	else
2801 		fuse_reply_err(req, 0);
2802 }
2803 
ntfs_fuse_release(fuse_req_t req,fuse_ino_t ino,struct fuse_file_info * fi)2804 static void ntfs_fuse_release(fuse_req_t req, fuse_ino_t ino,
2805 			 struct fuse_file_info *fi)
2806 {
2807 	ntfs_inode *ni = NULL;
2808 	ntfs_attr *na = NULL;
2809 	struct open_file *of;
2810 	char ghostname[GHOSTLTH];
2811 	int res;
2812 
2813 	of = (struct open_file*)(long)fi->fh;
2814 	/* Only for marked descriptors there is something to do */
2815 	if (!of
2816 	    || !(of->state & (CLOSE_COMPRESSED | CLOSE_ENCRYPTED
2817 				| CLOSE_DMTIME | CLOSE_REPARSE))) {
2818 		res = 0;
2819 		goto out;
2820 	}
2821 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
2822 	if (!ni) {
2823 		res = -errno;
2824 		goto exit;
2825 	}
2826 	if (ni->flags & FILE_ATTR_REPARSE_POINT) {
2827 #ifndef DISABLE_PLUGINS
2828 		const plugin_operations_t *ops;
2829 		REPARSE_POINT *reparse;
2830 
2831 		res = CALL_REPARSE_PLUGIN(ni, release, &of->fi);
2832 		if (!res) {
2833 			goto stamps;
2834 		}
2835 #else /* DISABLE_PLUGINS */
2836 			/* Assume release() was not needed */
2837 		res = 0;
2838 #endif /* DISABLE_PLUGINS */
2839 		goto exit;
2840 	}
2841 	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
2842 	if (!na) {
2843 		res = -errno;
2844 		goto exit;
2845 	}
2846 	res = 0;
2847 	if (of->state & CLOSE_COMPRESSED)
2848 		res = ntfs_attr_pclose(na);
2849 #ifdef HAVE_SETXATTR	/* extended attributes interface required */
2850 	if (of->state & CLOSE_ENCRYPTED)
2851 		res = ntfs_efs_fixup_attribute(NULL, na);
2852 #endif /* HAVE_SETXATTR */
2853 #ifndef DISABLE_PLUGINS
2854 stamps :
2855 #endif /* DISABLE_PLUGINS */
2856 	if (of->state & CLOSE_DMTIME)
2857 		ntfs_inode_update_times(ni,NTFS_UPDATE_MCTIME);
2858 exit:
2859 	if (na)
2860 		ntfs_attr_close(na);
2861 	if (ntfs_inode_close(ni))
2862 		set_fuse_error(&res);
2863 out:
2864 		/* remove the associate ghost file (even if release failed) */
2865 	if (of) {
2866 		if (of->state & CLOSE_GHOST) {
2867 			sprintf(ghostname,ghostformat,of->ghost);
2868 			ntfs_fuse_rm(req, of->parent, ghostname, RM_ANY);
2869 		}
2870 			/* remove from open files list */
2871 		if (of->next)
2872 			of->next->previous = of->previous;
2873 		if (of->previous)
2874 			of->previous->next = of->next;
2875 		else
2876 			ctx->open_files = of->next;
2877 		free(of);
2878 	}
2879 	if (res)
2880 		fuse_reply_err(req, -res);
2881 	else
2882 		fuse_reply_err(req, 0);
2883 }
2884 
ntfs_fuse_mkdir(fuse_req_t req,fuse_ino_t parent,const char * name,mode_t mode)2885 static void ntfs_fuse_mkdir(fuse_req_t req, fuse_ino_t parent,
2886 		       const char *name, mode_t mode)
2887 {
2888 	int res;
2889 	struct fuse_entry_param entry;
2890 
2891 	res = ntfs_fuse_create(req, parent, name, S_IFDIR | (mode & 07777),
2892 			0, &entry, (char*)NULL, (struct fuse_file_info*)NULL);
2893 	if (res < 0)
2894 		fuse_reply_err(req, -res);
2895 	else
2896 		fuse_reply_entry(req, &entry);
2897 }
2898 
ntfs_fuse_rmdir(fuse_req_t req,fuse_ino_t parent,const char * name)2899 static void ntfs_fuse_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
2900 {
2901 	int res;
2902 
2903 	res = ntfs_fuse_rm(req, parent, name, RM_DIR);
2904 	if (res)
2905 		fuse_reply_err(req, -res);
2906 	else
2907 		fuse_reply_err(req, 0);
2908 }
2909 
ntfs_fuse_fsync(fuse_req_t req,fuse_ino_t ino,int type,struct fuse_file_info * fi)2910 static void ntfs_fuse_fsync(fuse_req_t req,
2911 			fuse_ino_t ino __attribute__((unused)),
2912 			int type __attribute__((unused)),
2913 			struct fuse_file_info *fi __attribute__((unused)))
2914 {
2915 		/* sync the full device */
2916 	if (ntfs_device_sync(ctx->vol->dev))
2917 		fuse_reply_err(req, errno);
2918 	else
2919 		fuse_reply_err(req, 0);
2920 }
2921 
2922 #if defined(FUSE_INTERNAL) || (FUSE_VERSION >= 28)
ntfs_fuse_ioctl(fuse_req_t req,fuse_ino_t ino,int cmd,void * arg,struct fuse_file_info * fi,unsigned flags,const void * data,size_t in_bufsz,size_t out_bufsz)2923 static void ntfs_fuse_ioctl(fuse_req_t req __attribute__((unused)),
2924 			fuse_ino_t ino __attribute__((unused)),
2925 			int cmd, void *arg,
2926 			struct fuse_file_info *fi __attribute__((unused)),
2927 			unsigned flags, const void *data,
2928 			size_t in_bufsz, size_t out_bufsz)
2929 {
2930 	ntfs_inode *ni;
2931 	char *buf = (char*)NULL;
2932 	int bufsz;
2933 	int ret = 0;
2934 
2935 	if (flags & FUSE_IOCTL_COMPAT) {
2936 		ret = -ENOSYS;
2937 	} else {
2938 		ni = ntfs_inode_open(ctx->vol, INODE(ino));
2939 		if (!ni) {
2940 			ret = -errno;
2941 			goto fail;
2942 		}
2943 		bufsz = (in_bufsz > out_bufsz ? in_bufsz : out_bufsz);
2944 		if (bufsz) {
2945 			buf = ntfs_malloc(bufsz);
2946 			if (!buf) {
2947 				ret = ENOMEM;
2948 				goto fail;
2949 			}
2950 			memcpy(buf, data, in_bufsz);
2951 		}
2952 		ret = ntfs_ioctl(ni, cmd, arg, flags, buf);
2953 		if (ntfs_inode_close (ni))
2954 			set_fuse_error(&ret);
2955 	}
2956 	if (ret)
2957 fail :
2958 		fuse_reply_err(req, -ret);
2959 	else
2960 		fuse_reply_ioctl(req, 0, buf, out_bufsz);
2961 	if (buf)
2962 		free(buf);
2963 }
2964 #endif /* defined(FUSE_INTERNAL) || (FUSE_VERSION >= 28) */
2965 
ntfs_fuse_bmap(fuse_req_t req,fuse_ino_t ino,size_t blocksize,uint64_t vidx)2966 static void ntfs_fuse_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
2967 		      uint64_t vidx)
2968 {
2969 	ntfs_inode *ni;
2970 	ntfs_attr *na;
2971 	LCN lcn;
2972 	uint64_t lidx = 0;
2973 	int ret = 0;
2974 	int cl_per_bl = ctx->vol->cluster_size / blocksize;
2975 
2976 	if (blocksize > ctx->vol->cluster_size) {
2977 		ret = -EINVAL;
2978 		goto done;
2979 	}
2980 
2981 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
2982 	if (!ni) {
2983 		ret = -errno;
2984 		goto done;
2985 	}
2986 
2987 	na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
2988 	if (!na) {
2989 		ret = -errno;
2990 		goto close_inode;
2991 	}
2992 
2993 	if ((na->data_flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED))
2994 			 || !NAttrNonResident(na)) {
2995 		ret = -EINVAL;
2996 		goto close_attr;
2997 	}
2998 
2999 	if (ntfs_attr_map_whole_runlist(na)) {
3000 		ret = -errno;
3001 		goto close_attr;
3002 	}
3003 
3004 	lcn = ntfs_rl_vcn_to_lcn(na->rl, vidx / cl_per_bl);
3005 	lidx = (lcn > 0) ? lcn * cl_per_bl + vidx % cl_per_bl : 0;
3006 
3007 close_attr:
3008 	ntfs_attr_close(na);
3009 close_inode:
3010 	if (ntfs_inode_close(ni))
3011 		set_fuse_error(&ret);
3012 done :
3013 #ifndef __FreeBSD__
3014 	if (ret < 0)
3015 		fuse_reply_err(req, -ret);
3016 	else
3017 		fuse_reply_bmap(req, lidx);
3018 #else
3019 	;
3020 #endif
3021 }
3022 
3023 #ifdef HAVE_SETXATTR
3024 
3025 /*
3026  *		  Name space identifications and prefixes
3027  */
3028 
3029 enum {
3030 	XATTRNS_NONE,
3031 	XATTRNS_USER,
3032 	XATTRNS_SYSTEM,
3033 	XATTRNS_SECURITY,
3034 	XATTRNS_TRUSTED,
3035 	XATTRNS_OPEN
3036 } ;
3037 
3038 /*
3039  *		Check whether access to internal data as an extended
3040  *	attribute in system name space is allowed
3041  *
3042  *	Returns pointer to inode if allowed,
3043  *		NULL and errno set if not allowed
3044  */
3045 
ntfs_check_access_xattr(fuse_req_t req,struct SECURITY_CONTEXT * security,fuse_ino_t ino,int attr,BOOL setting)3046 static ntfs_inode *ntfs_check_access_xattr(fuse_req_t req,
3047 			struct SECURITY_CONTEXT *security,
3048 			fuse_ino_t ino, int attr, BOOL setting)
3049 {
3050 	ntfs_inode *dir_ni;
3051 	ntfs_inode *ni;
3052 	BOOL foracl;
3053 	BOOL bad;
3054 	mode_t acctype;
3055 
3056 	ni = (ntfs_inode*)NULL;
3057 	foracl = (attr == XATTR_POSIX_ACC)
3058 		 || (attr == XATTR_POSIX_DEF);
3059 	/*
3060 	 * When accessing Posix ACL, return unsupported if ACL
3061 	 * were disabled or no user mapping has been defined,
3062 	 * or trying to change a Windows-inherited ACL.
3063 	 * However no error will be returned to getfacl
3064 	 */
3065 	if (((!ntfs_fuse_fill_security_context(req, security)
3066 		|| (ctx->secure_flags
3067 		    & ((1 << SECURITY_DEFAULT) | (1 << SECURITY_RAW))))
3068 		|| !(ctx->secure_flags & (1 << SECURITY_ACL))
3069 		|| (setting && ctx->inherit))
3070 	    && foracl) {
3071 		if (ctx->silent)
3072 			errno = 0;
3073 		else
3074 			errno = EOPNOTSUPP;
3075 	} else {
3076 			/*
3077 			 * parent directory must be executable, and
3078 			 * for setting a DOS name it must be writeable
3079 			 */
3080 		if (setting && (attr == XATTR_NTFS_DOS_NAME))
3081 			acctype = S_IEXEC | S_IWRITE;
3082 		else
3083 			acctype = S_IEXEC;
3084 		ni = ntfs_inode_open(ctx->vol, INODE(ino));
3085 			/* basic access was checked previously in a lookup */
3086 		if (ni && (acctype != S_IEXEC)) {
3087 			bad = FALSE;
3088 				/* do not reopen root */
3089 			if (ni->mft_no == FILE_root) {
3090 				/* forbid getting/setting names on root */
3091 				if ((attr == XATTR_NTFS_DOS_NAME)
3092 				    || !ntfs_real_allowed_access(security,
3093 						ni, acctype))
3094 					bad = TRUE;
3095 			} else {
3096 				dir_ni = ntfs_dir_parent_inode(ni);
3097 				if (dir_ni) {
3098 					if (!ntfs_real_allowed_access(security,
3099 							dir_ni, acctype))
3100 						bad = TRUE;
3101 					if (ntfs_inode_close(dir_ni))
3102 						bad = TRUE;
3103 				} else
3104 					bad = TRUE;
3105 			}
3106 			if (bad) {
3107 				ntfs_inode_close(ni);
3108 				ni = (ntfs_inode*)NULL;
3109 			}
3110 		}
3111 	}
3112 	return (ni);
3113 }
3114 
3115 /*
3116  *		Determine the name space of an extended attribute
3117  */
3118 
xattr_namespace(const char * name)3119 static int xattr_namespace(const char *name)
3120 {
3121 	int namespace;
3122 
3123 	if (ctx->streams == NF_STREAMS_INTERFACE_XATTR) {
3124 		namespace = XATTRNS_NONE;
3125 		if (!strncmp(name, nf_ns_user_prefix,
3126 			nf_ns_user_prefix_len)
3127 		    && (strlen(name) != (size_t)nf_ns_user_prefix_len))
3128 			namespace = XATTRNS_USER;
3129 		else if (!strncmp(name, nf_ns_system_prefix,
3130 			nf_ns_system_prefix_len)
3131 		    && (strlen(name) != (size_t)nf_ns_system_prefix_len))
3132 			namespace = XATTRNS_SYSTEM;
3133 		else if (!strncmp(name, nf_ns_security_prefix,
3134 			nf_ns_security_prefix_len)
3135 		    && (strlen(name) != (size_t)nf_ns_security_prefix_len))
3136 			namespace = XATTRNS_SECURITY;
3137 		else if (!strncmp(name, nf_ns_trusted_prefix,
3138 			nf_ns_trusted_prefix_len)
3139 		    && (strlen(name) != (size_t)nf_ns_trusted_prefix_len))
3140 			namespace = XATTRNS_TRUSTED;
3141 	} else
3142 		namespace = XATTRNS_OPEN;
3143 	return (namespace);
3144 }
3145 
3146 /*
3147  *		Fix the prefix of an extended attribute
3148  */
3149 
fix_xattr_prefix(const char * name,int namespace,ntfschar ** lename)3150 static int fix_xattr_prefix(const char *name, int namespace, ntfschar **lename)
3151 {
3152 	int len;
3153 	char *prefixed;
3154 
3155 	*lename = (ntfschar*)NULL;
3156 	switch (namespace) {
3157 	case XATTRNS_USER :
3158 		/*
3159 		 * user name space : remove user prefix
3160 		 */
3161 		len = ntfs_mbstoucs(name + nf_ns_user_prefix_len, lename);
3162 		break;
3163 	case XATTRNS_SYSTEM :
3164 	case XATTRNS_SECURITY :
3165 	case XATTRNS_TRUSTED :
3166 		/*
3167 		 * security, trusted and unmapped system name spaces :
3168 		 * insert ntfs-3g prefix
3169 		 */
3170 		prefixed = (char*)ntfs_malloc(strlen(xattr_ntfs_3g)
3171 			 + strlen(name) + 1);
3172 		if (prefixed) {
3173 			strcpy(prefixed,xattr_ntfs_3g);
3174 			strcat(prefixed,name);
3175 			len = ntfs_mbstoucs(prefixed, lename);
3176 			free(prefixed);
3177 		} else
3178 			len = -1;
3179 		break;
3180 	case XATTRNS_OPEN :
3181 		/*
3182 		 * in open name space mode : do no fix prefix
3183 		 */
3184 		len = ntfs_mbstoucs(name, lename);
3185 		break;
3186 	default :
3187 		len = -1;
3188 	}
3189 	return (len);
3190 }
3191 
ntfs_fuse_listxattr(fuse_req_t req,fuse_ino_t ino,size_t size)3192 static void ntfs_fuse_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
3193 {
3194 	ntfs_attr_search_ctx *actx = NULL;
3195 	ntfs_inode *ni;
3196 	char *list = (char*)NULL;
3197 	int ret = 0;
3198 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3199 	struct SECURITY_CONTEXT security;
3200 #endif
3201 
3202 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3203 	ntfs_fuse_fill_security_context(req, &security);
3204 #endif
3205 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
3206 	if (!ni) {
3207 		ret = -errno;
3208 		goto out;
3209 	}
3210 		/* Return with no result for symlinks, fifo, etc. */
3211 	if (!user_xattrs_allowed(ctx, ni))
3212 		goto exit;
3213 		/* otherwise file must be readable */
3214 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3215 	if (!ntfs_allowed_access(&security,ni,S_IREAD)) {
3216 		ret = -EACCES;
3217 		goto exit;
3218 	}
3219 #endif
3220 	actx = ntfs_attr_get_search_ctx(ni, NULL);
3221 	if (!actx) {
3222 		ret = -errno;
3223 		goto exit;
3224 	}
3225 	if (size) {
3226 		list = (char*)malloc(size);
3227 		if (!list) {
3228 			ret = -errno;
3229 			goto exit;
3230 		}
3231 	}
3232 
3233 	if ((ctx->streams == NF_STREAMS_INTERFACE_XATTR)
3234 	    || (ctx->streams == NF_STREAMS_INTERFACE_OPENXATTR)) {
3235 		ret = ntfs_fuse_listxattr_common(ni, actx, list, size,
3236 				ctx->streams == NF_STREAMS_INTERFACE_XATTR);
3237 		if (ret < 0)
3238 			goto exit;
3239 	}
3240 	if (errno != ENOENT)
3241 		ret = -errno;
3242 exit:
3243 	if (actx)
3244 		ntfs_attr_put_search_ctx(actx);
3245 	if (ntfs_inode_close(ni))
3246 		set_fuse_error(&ret);
3247 out :
3248 	if (ret < 0)
3249 		fuse_reply_err(req, -ret);
3250 	else
3251 		if (size)
3252 			fuse_reply_buf(req, list, ret);
3253 		else
3254 			fuse_reply_xattr(req, ret);
3255 	free(list);
3256 }
3257 
ntfs_fuse_getxattr(fuse_req_t req,fuse_ino_t ino,const char * name,size_t size)3258 static void ntfs_fuse_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3259 			  size_t size)
3260 {
3261 	ntfs_inode *ni;
3262 	ntfs_inode *dir_ni;
3263 	ntfs_attr *na = NULL;
3264 	char *value = (char*)NULL;
3265 	ntfschar *lename = (ntfschar*)NULL;
3266 	int lename_len;
3267 	int res;
3268 	s64 rsize;
3269 	enum SYSTEMXATTRS attr;
3270 	int namespace;
3271 	struct SECURITY_CONTEXT security;
3272 
3273 	attr = ntfs_xattr_system_type(name,ctx->vol);
3274 	if (attr != XATTR_UNMAPPED) {
3275 		/*
3276 		 * hijack internal data and ACL retrieval, whatever
3277 		 * mode was selected for xattr (from the user's
3278 		 * point of view, ACLs are not xattr)
3279 		 */
3280 		if (size)
3281 			value = (char*)ntfs_malloc(size);
3282 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3283 		if (!size || value) {
3284 			ni = ntfs_check_access_xattr(req, &security, ino,
3285 					attr, FALSE);
3286 			if (ni) {
3287 				if (ntfs_allowed_access(&security,ni,S_IREAD)) {
3288 					if (attr == XATTR_NTFS_DOS_NAME)
3289 						dir_ni = ntfs_dir_parent_inode(ni);
3290 					else
3291 						dir_ni = (ntfs_inode*)NULL;
3292 					res = ntfs_xattr_system_getxattr(&security,
3293 						attr, ni, dir_ni, value, size);
3294 					if (dir_ni && ntfs_inode_close(dir_ni))
3295 						set_fuse_error(&res);
3296 				} else
3297 					res = -errno;
3298 				if (ntfs_inode_close(ni))
3299 					set_fuse_error(&res);
3300 			} else
3301 				res = -errno;
3302 #else
3303 			/*
3304 			 * Standard access control has been done by fuse/kernel
3305 			 */
3306 		if (!size || value) {
3307 			ni = ntfs_inode_open(ctx->vol, INODE(ino));
3308 			if (ni) {
3309 					/* user mapping not mandatory */
3310 				ntfs_fuse_fill_security_context(req, &security);
3311 				if (attr == XATTR_NTFS_DOS_NAME)
3312 					dir_ni = ntfs_dir_parent_inode(ni);
3313 				else
3314 					dir_ni = (ntfs_inode*)NULL;
3315 				res = ntfs_xattr_system_getxattr(&security,
3316 					attr, ni, dir_ni, value, size);
3317 				if (dir_ni && ntfs_inode_close(dir_ni))
3318 					set_fuse_error(&res);
3319 				if (ntfs_inode_close(ni))
3320 					set_fuse_error(&res);
3321 			} else
3322 				res = -errno;
3323 #endif
3324 		} else
3325 			res = -errno;
3326 		if (res < 0)
3327 			fuse_reply_err(req, -res);
3328 		else
3329 			if (size)
3330 				fuse_reply_buf(req, value, res);
3331 			else
3332 				fuse_reply_xattr(req, res);
3333 		free(value);
3334 		return;
3335 	}
3336 	if (ctx->streams == NF_STREAMS_INTERFACE_NONE) {
3337 		res = -EOPNOTSUPP;
3338 		goto out;
3339 	}
3340 	namespace = xattr_namespace(name);
3341 	if (namespace == XATTRNS_NONE) {
3342 		res = -EOPNOTSUPP;
3343 		goto out;
3344 	}
3345 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3346 	ntfs_fuse_fill_security_context(req,&security);
3347 		/* trusted only readable by root */
3348 	if ((namespace == XATTRNS_TRUSTED)
3349 	    && security.uid) {
3350 		res = -ENODATA;
3351 		goto out;
3352 	}
3353 #endif
3354 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
3355 	if (!ni) {
3356 		res = -errno;
3357 		goto out;
3358 	}
3359 		/* Return with no result for symlinks, fifo, etc. */
3360 	if (!user_xattrs_allowed(ctx, ni)) {
3361 		res = -ENODATA;
3362 		goto exit;
3363 	}
3364 		/* otherwise file must be readable */
3365 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3366 	if (!ntfs_allowed_access(&security, ni, S_IREAD)) {
3367 		res = -errno;
3368 		goto exit;
3369 	}
3370 #endif
3371 	lename_len = fix_xattr_prefix(name, namespace, &lename);
3372 	if (lename_len == -1) {
3373 		res = -errno;
3374 		goto exit;
3375 	}
3376 	na = ntfs_attr_open(ni, AT_DATA, lename, lename_len);
3377 	if (!na) {
3378 		res = -ENODATA;
3379 		goto exit;
3380 	}
3381 	rsize = na->data_size;
3382 	if (ctx->efs_raw
3383 	    && rsize
3384 	    && (na->data_flags & ATTR_IS_ENCRYPTED)
3385 	    && NAttrNonResident(na))
3386 		rsize = ((na->data_size + 511) & ~511) + 2;
3387 	if (size) {
3388 		if (size >= (size_t)rsize) {
3389 			value = (char*)ntfs_malloc(rsize);
3390 			if (value)
3391 				res = ntfs_attr_pread(na, 0, rsize, value);
3392 			if (!value || (res != rsize))
3393 				res = -errno;
3394 		} else
3395 			res = -ERANGE;
3396 	} else
3397 		res = rsize;
3398 exit:
3399 	if (na)
3400 		ntfs_attr_close(na);
3401 	free(lename);
3402 	if (ntfs_inode_close(ni))
3403 		set_fuse_error(&res);
3404 
3405 out :
3406 	if (res < 0)
3407 		fuse_reply_err(req, -res);
3408 	else
3409 		if (size)
3410 			fuse_reply_buf(req, value, res);
3411 		else
3412 			fuse_reply_xattr(req, res);
3413 	free(value);
3414 }
3415 
3416 static void ntfs_fuse_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
3417 			  const char *value, size_t size, int flags)
3418 {
3419 	ntfs_inode *ni;
3420 	ntfs_inode *dir_ni;
3421 	ntfs_attr *na = NULL;
3422 	ntfschar *lename = NULL;
3423 	int res, lename_len;
3424 	size_t total;
3425 	s64 part;
3426 	enum SYSTEMXATTRS attr;
3427 	int namespace;
3428 	struct SECURITY_CONTEXT security;
3429 
3430 	attr = ntfs_xattr_system_type(name,ctx->vol);
3431 	if (attr != XATTR_UNMAPPED) {
3432 		/*
3433 		 * hijack internal data and ACL setting, whatever
3434 		 * mode was selected for xattr (from the user's
3435 		 * point of view, ACLs are not xattr)
3436 		 * Note : ctime updated on successful settings
3437 		 */
3438 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3439 		ni = ntfs_check_access_xattr(req,&security,ino,attr,TRUE);
3440 		if (ni) {
3441 			if (ntfs_allowed_as_owner(&security, ni)) {
3442 				if (attr == XATTR_NTFS_DOS_NAME)
3443 					dir_ni = ntfs_dir_parent_inode(ni);
3444 				else
3445 					dir_ni = (ntfs_inode*)NULL;
3446 				res = ntfs_xattr_system_setxattr(&security,
3447 					attr, ni, dir_ni, value, size, flags);
3448 				/* never have to close dir_ni */
3449 				if (res)
3450 					res = -errno;
3451 			} else
3452 				res = -errno;
3453 			if (attr != XATTR_NTFS_DOS_NAME) {
3454 				if (!res)
3455 					ntfs_fuse_update_times(ni,
3456 							NTFS_UPDATE_CTIME);
3457 				if (ntfs_inode_close(ni))
3458 					set_fuse_error(&res);
3459 			}
3460 		} else
3461 			res = -errno;
3462 #else
3463 		/* creation of a new name is not controlled by fuse */
3464 		if (attr == XATTR_NTFS_DOS_NAME)
3465 			ni = ntfs_check_access_xattr(req, &security,
3466 					ino, attr, TRUE);
3467 		else
3468 			ni = ntfs_inode_open(ctx->vol, INODE(ino));
3469 		if (ni) {
3470 				/*
3471 				 * user mapping is not mandatory
3472 				 * if defined, only owner is allowed
3473 				 */
3474 			if (!ntfs_fuse_fill_security_context(req, &security)
3475 			   || ntfs_allowed_as_owner(&security, ni)) {
3476 				if (attr == XATTR_NTFS_DOS_NAME)
3477 					dir_ni = ntfs_dir_parent_inode(ni);
3478 				else
3479 					dir_ni = (ntfs_inode*)NULL;
3480 				res = ntfs_xattr_system_setxattr(&security,
3481 					attr, ni, dir_ni, value, size, flags);
3482 				/* never have to close dir_ni */
3483 				if (res)
3484 					res = -errno;
3485 			} else
3486 				res = -errno;
3487 			if (attr != XATTR_NTFS_DOS_NAME) {
3488 				if (!res)
3489 					ntfs_fuse_update_times(ni,
3490 							NTFS_UPDATE_CTIME);
3491 				if (ntfs_inode_close(ni))
3492 					set_fuse_error(&res);
3493 			}
3494 		} else
3495 			res = -errno;
3496 #endif
3497 #if CACHEING && !defined(FUSE_INTERNAL)
3498 		/*
3499 		 * Most of system xattr settings cause changes to some
3500 		 * file attribute (st_mode, st_nlink, st_mtime, etc.),
3501 		 * so we must invalidate cached data when cacheing is
3502 		 * in use (not possible with internal fuse or external
3503 		 * fuse before 2.8)
3504 		 */
3505 		if ((res >= 0)
3506 		    && fuse_lowlevel_notify_inval_inode(ctx->fc, ino, -1, 0))
3507 			res = -errno;
3508 #endif
3509 		if (res < 0)
3510 			fuse_reply_err(req, -res);
3511 		else
3512 			fuse_reply_err(req, 0);
3513 		return;
3514 	}
3515 	if ((ctx->streams != NF_STREAMS_INTERFACE_XATTR)
3516 	    && (ctx->streams != NF_STREAMS_INTERFACE_OPENXATTR)) {
3517 		res = -EOPNOTSUPP;
3518 		goto out;
3519 		}
3520 	namespace = xattr_namespace(name);
3521 	if (namespace == XATTRNS_NONE) {
3522 		res = -EOPNOTSUPP;
3523 		goto out;
3524 	}
3525 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3526 	ntfs_fuse_fill_security_context(req,&security);
3527 		/* security and trusted only settable by root */
3528 	if (((namespace == XATTRNS_SECURITY)
3529 	   || (namespace == XATTRNS_TRUSTED))
3530 		&& security.uid) {
3531 			res = -EPERM;
3532 			goto out;
3533 		}
3534 #endif
3535 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
3536 	if (!ni) {
3537 		res = -errno;
3538 		goto out;
3539 	}
3540 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3541 	switch (namespace) {
3542 	case XATTRNS_SECURITY :
3543 	case XATTRNS_TRUSTED :
3544 		if (security.uid) {
3545 			res = -EPERM;
3546 			goto exit;
3547 		}
3548 		break;
3549 	case XATTRNS_SYSTEM :
3550 		if (!ntfs_allowed_as_owner(&security, ni)) {
3551 			res = -EACCES;
3552 			goto exit;
3553 		}
3554 		break;
3555 	default :
3556 		/* User xattr not allowed for symlinks, fifo, etc. */
3557 		if (!user_xattrs_allowed(ctx, ni)) {
3558 			res = -EPERM;
3559 			goto exit;
3560 		}
3561 		if (!ntfs_allowed_access(&security,ni,S_IWRITE)) {
3562 			res = -EACCES;
3563 			goto exit;
3564 		}
3565 		break;
3566 	}
3567 #else
3568 		/* User xattr not allowed for symlinks, fifo, etc. */
3569 	if ((namespace == XATTRNS_USER)
3570 	    && !user_xattrs_allowed(ctx, ni)) {
3571 		res = -EPERM;
3572 		goto exit;
3573 	}
3574 #endif
3575 	lename_len = fix_xattr_prefix(name, namespace, &lename);
3576 	if ((lename_len == -1)
3577 	    || (ctx->windows_names
3578 		&& ntfs_forbidden_chars(lename,lename_len,TRUE))) {
3579 		res = -errno;
3580 		goto exit;
3581 	}
3582 	na = ntfs_attr_open(ni, AT_DATA, lename, lename_len);
3583 	if (na && flags == XATTR_CREATE) {
3584 		res = -EEXIST;
3585 		goto exit;
3586 	}
3587 	if (!na) {
3588 		if (flags == XATTR_REPLACE) {
3589 			res = -ENODATA;
3590 			goto exit;
3591 		}
3592 		if (ntfs_attr_add(ni, AT_DATA, lename, lename_len, NULL, 0)) {
3593 			res = -errno;
3594 			goto exit;
3595 		}
3596 		if (!(ni->flags & FILE_ATTR_ARCHIVE)) {
3597 			set_archive(ni);
3598 			NInoFileNameSetDirty(ni);
3599 		}
3600 		na = ntfs_attr_open(ni, AT_DATA, lename, lename_len);
3601 		if (!na) {
3602 			res = -errno;
3603 			goto exit;
3604 		}
3605 	} else {
3606 			/* currently compressed streams can only be wiped out */
3607 		if (ntfs_attr_truncate(na, (s64)0 /* size */)) {
3608 			res = -errno;
3609 			goto exit;
3610 		}
3611 	}
3612 	total = 0;
3613 	res = 0;
3614 	if (size) {
3615 		do {
3616 			part = ntfs_attr_pwrite(na, total, size - total,
3617 					 &value[total]);
3618 			if (part > 0)
3619 				total += part;
3620 		} while ((part > 0) && (total < size));
3621 	}
3622 	if ((total != size) || ntfs_attr_pclose(na))
3623 		res = -errno;
3624 	else {
3625 		if (ctx->efs_raw
3626 		   && (ni->flags & FILE_ATTR_ENCRYPTED)) {
3627 			if (ntfs_efs_fixup_attribute(NULL,na))
3628 				res = -errno;
3629 		}
3630 	}
3631 	if (!res) {
3632 		ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
3633 		if (!(ni->flags & FILE_ATTR_ARCHIVE)) {
3634 			set_archive(ni);
3635 			NInoFileNameSetDirty(ni);
3636 		}
3637 	}
3638 exit:
3639 	if (na)
3640 		ntfs_attr_close(na);
3641 	free(lename);
3642 	if (ntfs_inode_close(ni))
3643 		set_fuse_error(&res);
3644 out :
3645 	if (res < 0)
3646 		fuse_reply_err(req, -res);
3647 	else
3648 		fuse_reply_err(req, 0);
3649 }
3650 
3651 static void ntfs_fuse_removexattr(fuse_req_t req, fuse_ino_t ino, const char *name)
3652 {
3653 	ntfs_inode *ni;
3654 	ntfs_inode *dir_ni;
3655 	ntfschar *lename = NULL;
3656 	int res = 0, lename_len;
3657 	enum SYSTEMXATTRS attr;
3658 	int namespace;
3659 	struct SECURITY_CONTEXT security;
3660 
3661 	attr = ntfs_xattr_system_type(name,ctx->vol);
3662 	if (attr != XATTR_UNMAPPED) {
3663 		switch (attr) {
3664 			/*
3665 			 * Removal of NTFS ACL, ATTRIB, EFSINFO or TIMES
3666 			 * is never allowed
3667 			 */
3668 		case XATTR_NTFS_ACL :
3669 		case XATTR_NTFS_ATTRIB :
3670 		case XATTR_NTFS_ATTRIB_BE :
3671 		case XATTR_NTFS_EFSINFO :
3672 		case XATTR_NTFS_TIMES :
3673 		case XATTR_NTFS_TIMES_BE :
3674 		case XATTR_NTFS_CRTIME :
3675 		case XATTR_NTFS_CRTIME_BE :
3676 			res = -EPERM;
3677 			break;
3678 		default :
3679 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3680 			ni = ntfs_check_access_xattr(req, &security, ino,
3681 					attr,TRUE);
3682 			if (ni) {
3683 				if (ntfs_allowed_as_owner(&security, ni)) {
3684 					if (attr == XATTR_NTFS_DOS_NAME)
3685 						dir_ni = ntfs_dir_parent_inode(ni);
3686 					else
3687 						dir_ni = (ntfs_inode*)NULL;
3688 					res = ntfs_xattr_system_removexattr(&security,
3689 							attr, ni, dir_ni);
3690 					if (res)
3691 						res = -errno;
3692 					/* never have to close dir_ni */
3693 				} else
3694 					res = -errno;
3695 				if (attr != XATTR_NTFS_DOS_NAME) {
3696 					if (!res)
3697 						ntfs_fuse_update_times(ni,
3698 							NTFS_UPDATE_CTIME);
3699 					if (ntfs_inode_close(ni))
3700 						set_fuse_error(&res);
3701 				}
3702 			} else
3703 				res = -errno;
3704 #else
3705 			/* creation of a new name is not controlled by fuse */
3706 			if (attr == XATTR_NTFS_DOS_NAME)
3707 				ni = ntfs_check_access_xattr(req, &security,
3708 						ino, attr, TRUE);
3709 			else
3710 				ni = ntfs_inode_open(ctx->vol, INODE(ino));
3711 			if (ni) {
3712 				/*
3713 				 * user mapping is not mandatory
3714 				 * if defined, only owner is allowed
3715 				 */
3716 				if (!ntfs_fuse_fill_security_context(req, &security)
3717 				   || ntfs_allowed_as_owner(&security, ni)) {
3718 					if (attr == XATTR_NTFS_DOS_NAME)
3719 						dir_ni = ntfs_dir_parent_inode(ni);
3720 					else
3721 						dir_ni = (ntfs_inode*)NULL;
3722 					res = ntfs_xattr_system_removexattr(&security,
3723 						attr, ni, dir_ni);
3724 					/* never have to close dir_ni */
3725 					if (res)
3726 						res = -errno;
3727 				} else
3728 					res = -errno;
3729 				if (attr != XATTR_NTFS_DOS_NAME) {
3730 					if (!res)
3731 						ntfs_fuse_update_times(ni,
3732 							NTFS_UPDATE_CTIME);
3733 					if (ntfs_inode_close(ni))
3734 						set_fuse_error(&res);
3735 				}
3736 			} else
3737 				res = -errno;
3738 #endif
3739 #if CACHEING && !defined(FUSE_INTERNAL)
3740 		/*
3741 		 * Some allowed system xattr removals cause changes to
3742 		 * some file attribute (st_mode, st_nlink, etc.),
3743 		 * so we must invalidate cached data when cacheing is
3744 		 * in use (not possible with internal fuse or external
3745 		 * fuse before 2.8)
3746 		 */
3747 			if ((res >= 0)
3748 			    && fuse_lowlevel_notify_inval_inode(ctx->fc,
3749 						ino, -1, 0))
3750 				res = -errno;
3751 #endif
3752 			break;
3753 		}
3754 		if (res < 0)
3755 			fuse_reply_err(req, -res);
3756 		else
3757 			fuse_reply_err(req, 0);
3758 		return;
3759 	}
3760 	if ((ctx->streams != NF_STREAMS_INTERFACE_XATTR)
3761 	    && (ctx->streams != NF_STREAMS_INTERFACE_OPENXATTR)) {
3762 		res = -EOPNOTSUPP;
3763 		goto out;
3764 	}
3765 	namespace = xattr_namespace(name);
3766 	if (namespace == XATTRNS_NONE) {
3767 		res = -EOPNOTSUPP;
3768 		goto out;
3769 	}
3770 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3771 	ntfs_fuse_fill_security_context(req,&security);
3772 		/* security and trusted only settable by root */
3773 	if (((namespace == XATTRNS_SECURITY)
3774 	   || (namespace == XATTRNS_TRUSTED))
3775 		&& security.uid) {
3776 			res = -EACCES;
3777 			goto out;
3778 		}
3779 #endif
3780 	ni = ntfs_inode_open(ctx->vol, INODE(ino));
3781 	if (!ni) {
3782 		res = -errno;
3783 		goto out;
3784 	}
3785 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3786 	switch (namespace) {
3787 	case XATTRNS_SECURITY :
3788 	case XATTRNS_TRUSTED :
3789 		if (security.uid) {
3790 			res = -EPERM;
3791 			goto exit;
3792 		}
3793 		break;
3794 	case XATTRNS_SYSTEM :
3795 		if (!ntfs_allowed_as_owner(&security, ni)) {
3796 			res = -EACCES;
3797 			goto exit;
3798 		}
3799 		break;
3800 	default :
3801 		/* User xattr not allowed for symlinks, fifo, etc. */
3802 		if (!user_xattrs_allowed(ctx, ni)) {
3803 			res = -EPERM;
3804 			goto exit;
3805 		}
3806 		if (!ntfs_allowed_access(&security,ni,S_IWRITE)) {
3807 			res = -EACCES;
3808 			goto exit;
3809 		}
3810 		break;
3811 	}
3812 #else
3813 		/* User xattr not allowed for symlinks, fifo, etc. */
3814 	if ((namespace == XATTRNS_USER)
3815 	    && !user_xattrs_allowed(ctx, ni)) {
3816 		res = -EPERM;
3817 		goto exit;
3818 	}
3819 #endif
3820 	lename_len = fix_xattr_prefix(name, namespace, &lename);
3821 	if (lename_len == -1) {
3822 		res = -errno;
3823 		goto exit;
3824 	}
3825 	if (ntfs_attr_remove(ni, AT_DATA, lename, lename_len)) {
3826 		if (errno == ENOENT)
3827 			errno = ENODATA;
3828 		res = -errno;
3829 	}
3830 	if (!res) {
3831 		ntfs_fuse_update_times(ni, NTFS_UPDATE_CTIME);
3832 		if (!(ni->flags & FILE_ATTR_ARCHIVE)) {
3833 			set_archive(ni);
3834 			NInoFileNameSetDirty(ni);
3835 		}
3836 	}
3837 exit:
3838 	free(lename);
3839 	if (ntfs_inode_close(ni))
3840 		set_fuse_error(&res);
3841 out :
3842 	if (res < 0)
3843 		fuse_reply_err(req, -res);
3844 	else
3845 		fuse_reply_err(req, 0);
3846 	return;
3847 
3848 }
3849 
3850 #else
3851 #if POSIXACLS
3852 #error "Option inconsistency : POSIXACLS requires SETXATTR"
3853 #endif
3854 #endif /* HAVE_SETXATTR */
3855 
3856 #ifndef DISABLE_PLUGINS
3857 static void register_internal_reparse_plugins(void)
3858 {
3859 	static const plugin_operations_t ops = {
3860 		.getattr = junction_getstat,
3861 		.readlink = junction_readlink,
3862 	} ;
3863 	register_reparse_plugin(ctx, IO_REPARSE_TAG_MOUNT_POINT,
3864 					&ops, (void*)NULL);
3865 	register_reparse_plugin(ctx, IO_REPARSE_TAG_SYMLINK,
3866 					&ops, (void*)NULL);
3867 }
3868 #endif /* DISABLE_PLUGINS */
3869 
3870 static void ntfs_close(void)
3871 {
3872 	struct SECURITY_CONTEXT security;
3873 
3874 	if (!ctx)
3875 		return;
3876 
3877 	if (!ctx->vol)
3878 		return;
3879 
3880 	if (ctx->mounted) {
3881 		ntfs_log_info("Unmounting %s (%s)\n", opts.device,
3882 			      ctx->vol->vol_name);
3883 		if (ntfs_fuse_fill_security_context((fuse_req_t)NULL, &security)) {
3884 			if (ctx->seccache && ctx->seccache->head.p_reads) {
3885 				ntfs_log_info("Permissions cache : %lu writes, "
3886 				"%lu reads, %lu.%1lu%% hits\n",
3887 			      ctx->seccache->head.p_writes,
3888 			      ctx->seccache->head.p_reads,
3889 			      100 * ctx->seccache->head.p_hits
3890 				 / ctx->seccache->head.p_reads,
3891 			      1000 * ctx->seccache->head.p_hits
3892 				 / ctx->seccache->head.p_reads % 10);
3893 			}
3894 		}
3895 		ntfs_destroy_security_context(&security);
3896 	}
3897 
3898 	if (ntfs_umount(ctx->vol, FALSE))
3899 		ntfs_log_perror("Failed to close volume %s", opts.device);
3900 
3901 	ctx->vol = NULL;
3902 }
3903 
3904 static void ntfs_fuse_destroy2(void *notused __attribute__((unused)))
3905 {
3906 	ntfs_close();
3907 }
3908 
3909 static struct fuse_lowlevel_ops ntfs_3g_ops = {
3910 	.lookup 	= ntfs_fuse_lookup,
3911 	.getattr	= ntfs_fuse_getattr,
3912 	.readlink	= ntfs_fuse_readlink,
3913 	.opendir	= ntfs_fuse_opendir,
3914 	.readdir	= ntfs_fuse_readdir,
3915 	.releasedir	= ntfs_fuse_releasedir,
3916 	.open		= ntfs_fuse_open,
3917 	.release	= ntfs_fuse_release,
3918 	.read		= ntfs_fuse_read,
3919 	.write		= ntfs_fuse_write,
3920 	.setattr	= ntfs_fuse_setattr,
3921 	.statfs 	= ntfs_fuse_statfs,
3922 	.create 	= ntfs_fuse_create_file,
3923 	.mknod		= ntfs_fuse_mknod,
3924 	.symlink	= ntfs_fuse_symlink,
3925 	.link		= ntfs_fuse_link,
3926 	.unlink 	= ntfs_fuse_unlink,
3927 	.rename 	= ntfs_fuse_rename,
3928 	.mkdir		= ntfs_fuse_mkdir,
3929 	.rmdir		= ntfs_fuse_rmdir,
3930 	.fsync		= ntfs_fuse_fsync,
3931 	.fsyncdir	= ntfs_fuse_fsync,
3932 	.bmap		= ntfs_fuse_bmap,
3933 	.destroy	= ntfs_fuse_destroy2,
3934 #if defined(FUSE_INTERNAL) || (FUSE_VERSION >= 28)
3935 	.ioctl		= ntfs_fuse_ioctl,
3936 #endif /* defined(FUSE_INTERNAL) || (FUSE_VERSION >= 28) */
3937 #if !KERNELPERMS | (POSIXACLS & !KERNELACLS)
3938 	.access 	= ntfs_fuse_access,
3939 #endif
3940 #ifdef HAVE_SETXATTR
3941 	.getxattr	= ntfs_fuse_getxattr,
3942 	.setxattr	= ntfs_fuse_setxattr,
3943 	.removexattr	= ntfs_fuse_removexattr,
3944 	.listxattr	= ntfs_fuse_listxattr,
3945 #endif /* HAVE_SETXATTR */
3946 #if 0 && (defined(__APPLE__) || defined(__DARWIN__)) /* Unfinished. */
3947 	/* MacFUSE extensions. */
3948 	.getxtimes	= ntfs_macfuse_getxtimes,
3949 	.setcrtime	= ntfs_macfuse_setcrtime,
3950 	.setbkuptime	= ntfs_macfuse_setbkuptime,
3951 	.setchgtime	= ntfs_macfuse_setchgtime,
3952 #endif /* defined(__APPLE__) || defined(__DARWIN__) */
3953 	.init		= ntfs_init
3954 };
3955 
3956 static int ntfs_fuse_init(void)
3957 {
3958 	ctx = (ntfs_fuse_context_t*)ntfs_calloc(sizeof(ntfs_fuse_context_t));
3959 	if (!ctx)
3960 		return -1;
3961 
3962 	*ctx = (ntfs_fuse_context_t) {
3963 		.uid	 = getuid(),
3964 		.gid	 = getgid(),
3965 #if defined(linux)
3966 		.streams = NF_STREAMS_INTERFACE_XATTR,
3967 #else
3968 		.streams = NF_STREAMS_INTERFACE_NONE,
3969 #endif
3970 		.atime	 = ATIME_RELATIVE,
3971 		.silent  = TRUE,
3972 		.recover = TRUE
3973 	};
3974 	return 0;
3975 }
3976 
3977 static int ntfs_open(const char *device)
3978 {
3979 	unsigned long flags = 0;
3980 	ntfs_volume *vol;
3981 
3982 	if (!ctx->blkdev)
3983 		flags |= NTFS_MNT_EXCLUSIVE;
3984 	if (ctx->ro)
3985 		flags |= NTFS_MNT_RDONLY;
3986 	else
3987 		if (!ctx->hiberfile)
3988 			flags |= NTFS_MNT_MAY_RDONLY;
3989 	if (ctx->recover)
3990 		flags |= NTFS_MNT_RECOVER;
3991 	if (ctx->hiberfile)
3992 		flags |= NTFS_MNT_IGNORE_HIBERFILE;
3993 
3994 	ctx->vol = vol = ntfs_mount(device, flags);
3995 	if (!vol) {
3996 		ntfs_log_perror("Failed to mount '%s'", device);
3997 		goto err_out;
3998 	}
3999 	if (ctx->sync && ctx->vol->dev)
4000 		NDevSetSync(ctx->vol->dev);
4001 	if (ctx->compression)
4002 		NVolSetCompression(ctx->vol);
4003 	else
4004 		NVolClearCompression(ctx->vol);
4005 #ifdef HAVE_SETXATTR
4006 			/* archivers must see hidden files */
4007 	if (ctx->efs_raw)
4008 		ctx->hide_hid_files = FALSE;
4009 #endif
4010 	if (ntfs_set_shown_files(ctx->vol, ctx->show_sys_files,
4011 				!ctx->hide_hid_files, ctx->hide_dot_files))
4012 		goto err_out;
4013 
4014 	if (ctx->ignore_case && ntfs_set_ignore_case(vol))
4015 		goto err_out;
4016 
4017 	vol->free_clusters = ntfs_attr_get_free_bits(vol->lcnbmp_na);
4018 	if (vol->free_clusters < 0) {
4019 		ntfs_log_perror("Failed to read NTFS $Bitmap");
4020 		goto err_out;
4021 	}
4022 
4023 	vol->free_mft_records = ntfs_get_nr_free_mft_records(vol);
4024 	if (vol->free_mft_records < 0) {
4025 		ntfs_log_perror("Failed to calculate free MFT records");
4026 		goto err_out;
4027 	}
4028 
4029 	if (ctx->hiberfile && ntfs_volume_check_hiberfile(vol, 0)) {
4030 		if (errno != EPERM)
4031 			goto err_out;
4032 		if (ntfs_fuse_rm((fuse_req_t)NULL,FILE_root,"hiberfil.sys",
4033 					RM_LINK))
4034 			goto err_out;
4035 	}
4036 
4037 	errno = 0;
4038 err_out:
4039 	return ntfs_volume_error(errno);
4040 
4041 }
4042 
4043 static void usage(void)
4044 {
4045 	ntfs_log_info(usage_msg, EXEC_NAME, VERSION, FUSE_TYPE, fuse_version(),
4046 			5 + POSIXACLS*6 - KERNELPERMS*3 + CACHEING,
4047 			EXEC_NAME, ntfs_home);
4048 }
4049 
4050 #if defined(linux) || defined(__uClinux__)
4051 
4052 static const char *dev_fuse_msg =
4053 "HINT: You should be root, or make ntfs-3g setuid root, or load the FUSE\n"
4054 "      kernel module as root ('modprobe fuse' or 'insmod <path_to>/fuse.ko'"
4055 "      or insmod <path_to>/fuse.o'). Make also sure that the fuse device"
4056 "      exists. It's usually either /dev/fuse or /dev/misc/fuse.";
4057 
4058 static const char *fuse26_kmod_msg =
4059 "WARNING: Deficient Linux kernel detected. Some driver features are\n"
4060 "         not available (swap file on NTFS, boot from NTFS by LILO), and\n"
4061 "         unmount is not safe unless it's made sure the ntfs-3g process\n"
4062 "         naturally terminates after calling 'umount'. If you wish this\n"
4063 "         message to disappear then you should upgrade to at least kernel\n"
4064 "         version 2.6.20, or request help from your distribution to fix\n"
4065 "         the kernel problem. The below web page has more information:\n"
4066 "         http://tuxera.com/community/ntfs-3g-faq/#fuse26\n"
4067 "\n";
4068 
4069 static void mknod_dev_fuse(const char *dev)
4070 {
4071 	struct stat st;
4072 
4073 	if (stat(dev, &st) && (errno == ENOENT)) {
4074 		mode_t mask = umask(0);
4075 		if (mknod(dev, S_IFCHR | 0666, makedev(10, 229))) {
4076 			ntfs_log_perror("Failed to create '%s'", dev);
4077 			if (errno == EPERM)
4078 				ntfs_log_error("%s", dev_fuse_msg);
4079 		}
4080 		umask(mask);
4081 	}
4082 }
4083 
4084 static void create_dev_fuse(void)
4085 {
4086 	mknod_dev_fuse("/dev/fuse");
4087 
4088 #ifdef __UCLIBC__
4089 	{
4090 		struct stat st;
4091 		/* The fuse device is under /dev/misc using devfs. */
4092 		if (stat("/dev/misc", &st) && (errno == ENOENT)) {
4093 			mode_t mask = umask(0);
4094 			mkdir("/dev/misc", 0775);
4095 			umask(mask);
4096 		}
4097 		mknod_dev_fuse("/dev/misc/fuse");
4098 	}
4099 #endif
4100 }
4101 
4102 static fuse_fstype get_fuse_fstype(void)
4103 {
4104 	char buf[256];
4105 	fuse_fstype fstype = FSTYPE_NONE;
4106 
4107 	FILE *f = fopen("/proc/filesystems", "r");
4108 	if (!f) {
4109 		ntfs_log_perror("Failed to open /proc/filesystems");
4110 		return FSTYPE_UNKNOWN;
4111 	}
4112 
4113 	while (fgets(buf, sizeof(buf), f)) {
4114 		if (strstr(buf, "fuseblk\n")) {
4115 			fstype = FSTYPE_FUSEBLK;
4116 			break;
4117 		}
4118 		if (strstr(buf, "fuse\n"))
4119 			fstype = FSTYPE_FUSE;
4120 	}
4121 
4122 	fclose(f);
4123 	return fstype;
4124 }
4125 
4126 static fuse_fstype load_fuse_module(void)
4127 {
4128 	int i;
4129 	struct stat st;
4130 	pid_t pid;
4131 	const char *cmd = "/sbin/modprobe";
4132 	char *env = (char*)NULL;
4133 	struct timespec req = { 0, 100000000 };   /* 100 msec */
4134 	fuse_fstype fstype;
4135 
4136 	if (!stat(cmd, &st) && !geteuid()) {
4137 		pid = fork();
4138 		if (!pid) {
4139 			execle(cmd, cmd, "fuse", (char*)NULL, &env);
4140 			_exit(1);
4141 		} else if (pid != -1)
4142 			waitpid(pid, NULL, 0);
4143 	}
4144 
4145 	for (i = 0; i < 10; i++) {
4146 		/*
4147 		 * We sleep first because despite the detection of the loaded
4148 		 * FUSE kernel module, fuse_mount() can still fail if it's not
4149 		 * fully functional/initialized. Note, of course this is still
4150 		 * unreliable but usually helps.
4151 		 */
4152 		nanosleep(&req, NULL);
4153 		fstype = get_fuse_fstype();
4154 		if (fstype != FSTYPE_NONE)
4155 			break;
4156 	}
4157 	return fstype;
4158 }
4159 
4160 #endif
4161 
4162 static struct fuse_chan *try_fuse_mount(char *parsed_options)
4163 {
4164 	struct fuse_chan *fc = NULL;
4165 	struct fuse_args margs = FUSE_ARGS_INIT(0, NULL);
4166 
4167 	/* The fuse_mount() options get modified, so we always rebuild it */
4168 	if ((fuse_opt_add_arg(&margs, EXEC_NAME) == -1 ||
4169 	     fuse_opt_add_arg(&margs, "-o") == -1 ||
4170 	     fuse_opt_add_arg(&margs, parsed_options) == -1)) {
4171 		ntfs_log_error("Failed to set FUSE options.\n");
4172 		goto free_args;
4173 	}
4174 
4175 	fc = fuse_mount(opts.mnt_point, &margs);
4176 free_args:
4177 	fuse_opt_free_args(&margs);
4178 	return fc;
4179 
4180 }
4181 
4182 static int set_fuseblk_options(char **parsed_options)
4183 {
4184 	char options[64];
4185 	long pagesize;
4186 	u32 blksize = ctx->vol->cluster_size;
4187 
4188 	pagesize = sysconf(_SC_PAGESIZE);
4189 	if (pagesize < 1)
4190 		pagesize = 4096;
4191 
4192 	if (blksize > (u32)pagesize)
4193 		blksize = pagesize;
4194 
4195 	snprintf(options, sizeof(options), ",blkdev,blksize=%u", blksize);
4196 	if (ntfs_strappend(parsed_options, options))
4197 		return -1;
4198 	return 0;
4199 }
4200 
4201 static struct fuse_session *mount_fuse(char *parsed_options)
4202 {
4203 	struct fuse_session *se = NULL;
4204 	struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
4205 
4206 	ctx->fc = try_fuse_mount(parsed_options);
4207 	if (!ctx->fc)
4208 		return NULL;
4209 
4210 	if (fuse_opt_add_arg(&args, "") == -1)
4211 		goto err;
4212 	if (ctx->debug)
4213 		if (fuse_opt_add_arg(&args, "-odebug") == -1)
4214 			goto err;
4215 
4216 	se = fuse_lowlevel_new(&args , &ntfs_3g_ops, sizeof(ntfs_3g_ops), NULL);
4217 	if (!se)
4218 		goto err;
4219 
4220 
4221 	if (fuse_set_signal_handlers(se))
4222 		goto err_destroy;
4223 	fuse_session_add_chan(se, ctx->fc);
4224 out:
4225 	fuse_opt_free_args(&args);
4226 	return se;
4227 err_destroy:
4228 	fuse_session_destroy(se);
4229 	se = NULL;
4230 err:
4231 	fuse_unmount(opts.mnt_point, ctx->fc);
4232 	goto out;
4233 }
4234 
4235 static void setup_logging(char *parsed_options)
4236 {
4237 	if (!ctx->no_detach) {
4238 		if (daemon(0, ctx->debug))
4239 			ntfs_log_error("Failed to daemonize.\n");
4240 		else if (!ctx->debug) {
4241 #ifndef DEBUG
4242 			ntfs_log_set_handler(ntfs_log_handler_syslog);
4243 			/* Override default libntfs identify. */
4244 			openlog(EXEC_NAME, LOG_PID, LOG_DAEMON);
4245 #endif
4246 		}
4247 	}
4248 
4249 	ctx->seccache = (struct PERMISSIONS_CACHE*)NULL;
4250 
4251 	ntfs_log_info("Version %s %s %d\n", VERSION, FUSE_TYPE, fuse_version());
4252 	if (strcmp(opts.arg_device,opts.device))
4253 		ntfs_log_info("Requested device %s canonicalized as %s\n",
4254 				opts.arg_device,opts.device);
4255 	ntfs_log_info("Mounted %s (%s, label \"%s\", NTFS %d.%d)\n",
4256 			opts.device, (ctx->ro) ? "Read-Only" : "Read-Write",
4257 			ctx->vol->vol_name, ctx->vol->major_ver,
4258 			ctx->vol->minor_ver);
4259 	ntfs_log_info("Cmdline options: %s\n", opts.options ? opts.options : "");
4260 	ntfs_log_info("Mount options: %s\n", parsed_options);
4261 }
4262 
4263 int main(int argc, char *argv[])
4264 {
4265 	char *parsed_options = NULL;
4266 	struct fuse_session *se;
4267 #if !(defined(__sun) && defined (__SVR4))
4268 	fuse_fstype fstype = FSTYPE_UNKNOWN;
4269 #endif
4270 	const char *permissions_mode = (const char*)NULL;
4271 	const char *failed_secure = (const char*)NULL;
4272 #if defined(HAVE_SETXATTR) && defined(XATTR_MAPPINGS)
4273 	struct XATTRMAPPING *xattr_mapping = (struct XATTRMAPPING*)NULL;
4274 #endif /* defined(HAVE_SETXATTR) && defined(XATTR_MAPPINGS) */
4275 	struct stat sbuf;
4276 	unsigned long existing_mount;
4277 	int err, fd;
4278 
4279 	/*
4280 	 * Make sure file descriptors 0, 1 and 2 are open,
4281 	 * otherwise chaos would ensue.
4282 	 */
4283 	do {
4284 		fd = open("/dev/null", O_RDWR);
4285 		if (fd > 2)
4286 			close(fd);
4287 	} while (fd >= 0 && fd <= 2);
4288 
4289 #ifndef FUSE_INTERNAL
4290 	if ((getuid() != geteuid()) || (getgid() != getegid())) {
4291 		fprintf(stderr, "%s", setuid_msg);
4292 		return NTFS_VOLUME_INSECURE;
4293 	}
4294 #endif
4295 	if (drop_privs())
4296 		return NTFS_VOLUME_NO_PRIVILEGE;
4297 
4298 	ntfs_set_locale();
4299 	ntfs_log_set_handler(ntfs_log_handler_stderr);
4300 
4301 	if (ntfs_parse_options(&opts, usage, argc, argv)) {
4302 		usage();
4303 		return NTFS_VOLUME_SYNTAX_ERROR;
4304 	}
4305 
4306 	if (ntfs_fuse_init()) {
4307 		err = NTFS_VOLUME_OUT_OF_MEMORY;
4308 		goto err2;
4309 	}
4310 
4311 	parsed_options = parse_mount_options(ctx, &opts, TRUE);
4312 	if (!parsed_options) {
4313 		err = NTFS_VOLUME_SYNTAX_ERROR;
4314 		goto err_out;
4315 	}
4316 	if (!ntfs_check_if_mounted(opts.device,&existing_mount)
4317 	    && (existing_mount & NTFS_MF_MOUNTED)
4318 		/* accept multiple read-only mounts */
4319 	    && (!(existing_mount & NTFS_MF_READONLY) || !ctx->ro)) {
4320 		err = NTFS_VOLUME_LOCKED;
4321 		goto err_out;
4322 	}
4323 
4324 			/* need absolute mount point for junctions */
4325 	if (opts.mnt_point[0] == '/')
4326 		ctx->abs_mnt_point = strdup(opts.mnt_point);
4327 	else {
4328 		ctx->abs_mnt_point = (char*)ntfs_malloc(PATH_MAX);
4329 		if (ctx->abs_mnt_point) {
4330 			if (getcwd(ctx->abs_mnt_point,
4331 				     PATH_MAX - strlen(opts.mnt_point) - 1)) {
4332 				strcat(ctx->abs_mnt_point, "/");
4333 				strcat(ctx->abs_mnt_point, opts.mnt_point);
4334 #if defined(__sun) && defined (__SVR4)
4335 			/* Solaris also wants the absolute mount point */
4336 				opts.mnt_point = ctx->abs_mnt_point;
4337 #endif /* defined(__sun) && defined (__SVR4) */
4338 			}
4339 		}
4340 	}
4341 	if (!ctx->abs_mnt_point) {
4342 		err = NTFS_VOLUME_OUT_OF_MEMORY;
4343 		goto err_out;
4344 	}
4345 
4346 	ctx->security.uid = 0;
4347 	ctx->security.gid = 0;
4348 	if ((opts.mnt_point[0] == '/')
4349 	   && !stat(opts.mnt_point,&sbuf)) {
4350 		/* collect owner of mount point, useful for default mapping */
4351 		ctx->security.uid = sbuf.st_uid;
4352 		ctx->security.gid = sbuf.st_gid;
4353 	}
4354 
4355 #if defined(linux) || defined(__uClinux__)
4356 	fstype = get_fuse_fstype();
4357 
4358 	err = NTFS_VOLUME_NO_PRIVILEGE;
4359 	if (restore_privs())
4360 		goto err_out;
4361 
4362 	if (fstype == FSTYPE_NONE || fstype == FSTYPE_UNKNOWN)
4363 		fstype = load_fuse_module();
4364 	create_dev_fuse();
4365 
4366 	if (drop_privs())
4367 		goto err_out;
4368 #endif
4369 	if (stat(opts.device, &sbuf)) {
4370 		ntfs_log_perror("Failed to access '%s'", opts.device);
4371 		err = NTFS_VOLUME_NO_PRIVILEGE;
4372 		goto err_out;
4373 	}
4374 
4375 #if !(defined(__sun) && defined (__SVR4))
4376 	/* Always use fuseblk for block devices unless it's surely missing. */
4377 	if (S_ISBLK(sbuf.st_mode) && (fstype != FSTYPE_FUSE))
4378 		ctx->blkdev = TRUE;
4379 #endif
4380 
4381 #ifndef FUSE_INTERNAL
4382 	if (getuid() && ctx->blkdev) {
4383 		ntfs_log_error("%s", unpriv_fuseblk_msg);
4384 		err = NTFS_VOLUME_NO_PRIVILEGE;
4385 		goto err2;
4386 	}
4387 #endif
4388 	err = ntfs_open(opts.device);
4389 	if (err)
4390 		goto err_out;
4391 
4392 	/* Force read-only mount if the device was found read-only */
4393 	if (!ctx->ro && NVolReadOnly(ctx->vol)) {
4394 		ctx->ro = TRUE;
4395 		if (ntfs_strinsert(&parsed_options, ",ro"))
4396                 	goto err_out;
4397 	}
4398 	/* We must do this after ntfs_open() to be able to set the blksize */
4399 	if (ctx->blkdev && set_fuseblk_options(&parsed_options))
4400 		goto err_out;
4401 
4402 	ctx->security.vol = ctx->vol;
4403 	ctx->vol->secure_flags = ctx->secure_flags;
4404 #ifdef HAVE_SETXATTR	/* extended attributes interface required */
4405 	ctx->vol->efs_raw = ctx->efs_raw;
4406 #endif /* HAVE_SETXATTR */
4407 	if (!ntfs_build_mapping(&ctx->security,ctx->usermap_path,
4408 		(ctx->vol->secure_flags
4409 			& ((1 << SECURITY_DEFAULT) | (1 << SECURITY_ACL)))
4410 		&& !ctx->inherit
4411 		&& !(ctx->vol->secure_flags & (1 << SECURITY_WANTED)))) {
4412 #if POSIXACLS
4413 		/* use basic permissions if requested */
4414 		if (ctx->vol->secure_flags & (1 << SECURITY_DEFAULT))
4415 			permissions_mode = "User mapping built, Posix ACLs not used";
4416 		else {
4417 			permissions_mode = "User mapping built, Posix ACLs in use";
4418 #if KERNELACLS
4419 			if (ntfs_strinsert(&parsed_options,
4420 					",default_permissions,acl")) {
4421 				err = NTFS_VOLUME_SYNTAX_ERROR;
4422 				goto err_out;
4423 			}
4424 #endif /* KERNELACLS */
4425 		}
4426 #else /* POSIXACLS */
4427 		if (!(ctx->vol->secure_flags
4428 			& ((1 << SECURITY_DEFAULT) | (1 << SECURITY_ACL)))) {
4429 			/*
4430 			 * No explicit option but user mapping found
4431 			 * force default security
4432 			 */
4433 #if KERNELPERMS
4434 			ctx->vol->secure_flags |= (1 << SECURITY_DEFAULT);
4435 			if (ntfs_strinsert(&parsed_options, ",default_permissions")) {
4436 				err = NTFS_VOLUME_SYNTAX_ERROR;
4437 				goto err_out;
4438 			}
4439 #endif /* KERNELPERMS */
4440 		}
4441 		permissions_mode = "User mapping built";
4442 #endif /* POSIXACLS */
4443 		ctx->dmask = ctx->fmask = 0;
4444 	} else {
4445 		ctx->security.uid = ctx->uid;
4446 		ctx->security.gid = ctx->gid;
4447 		/* same ownership/permissions for all files */
4448 		ctx->security.mapping[MAPUSERS] = (struct MAPPING*)NULL;
4449 		ctx->security.mapping[MAPGROUPS] = (struct MAPPING*)NULL;
4450 		if ((ctx->vol->secure_flags & (1 << SECURITY_WANTED))
4451 		   && !(ctx->vol->secure_flags & (1 << SECURITY_DEFAULT))) {
4452 			ctx->vol->secure_flags |= (1 << SECURITY_DEFAULT);
4453 			if (ntfs_strinsert(&parsed_options, ",default_permissions")) {
4454 				err = NTFS_VOLUME_SYNTAX_ERROR;
4455 				goto err_out;
4456 			}
4457 		}
4458 		if (ctx->vol->secure_flags & (1 << SECURITY_DEFAULT)) {
4459 			ctx->vol->secure_flags |= (1 << SECURITY_RAW);
4460 			permissions_mode = "Global ownership and permissions enforced";
4461 		} else {
4462 			ctx->vol->secure_flags &= ~(1 << SECURITY_RAW);
4463 			permissions_mode = "Ownership and permissions disabled";
4464 		}
4465 	}
4466 	if (ctx->usermap_path)
4467 		free (ctx->usermap_path);
4468 
4469 #if defined(HAVE_SETXATTR) && defined(XATTR_MAPPINGS)
4470 	xattr_mapping = ntfs_xattr_build_mapping(ctx->vol,
4471 				ctx->xattrmap_path);
4472 	ctx->vol->xattr_mapping = xattr_mapping;
4473 	/*
4474 	 * Errors are logged, do not refuse mounting, it would be
4475 	 * too difficult to fix the unmountable mapping file.
4476 	 */
4477 	if (ctx->xattrmap_path)
4478 		free(ctx->xattrmap_path);
4479 #endif /* defined(HAVE_SETXATTR) && defined(XATTR_MAPPINGS) */
4480 
4481 #ifndef DISABLE_PLUGINS
4482 	register_internal_reparse_plugins();
4483 #endif /* DISABLE_PLUGINS */
4484 
4485 	se = mount_fuse(parsed_options);
4486 	if (!se) {
4487 		err = NTFS_VOLUME_FUSE_ERROR;
4488 		goto err_out;
4489 	}
4490 
4491 	ctx->mounted = TRUE;
4492 
4493 #if defined(linux) || defined(__uClinux__)
4494 	if (S_ISBLK(sbuf.st_mode) && (fstype == FSTYPE_FUSE))
4495 		ntfs_log_info("%s", fuse26_kmod_msg);
4496 #endif
4497 	setup_logging(parsed_options);
4498 	if (failed_secure)
4499 		ntfs_log_info("%s\n",failed_secure);
4500 	if (permissions_mode)
4501 		ntfs_log_info("%s, configuration type %d\n",permissions_mode,
4502 			5 + POSIXACLS*6 - KERNELPERMS*3 + CACHEING);
4503 
4504 	fuse_session_loop(se);
4505 	fuse_remove_signal_handlers(se);
4506 
4507 	err = 0;
4508 
4509 	fuse_unmount(opts.mnt_point, ctx->fc);
4510 	fuse_session_destroy(se);
4511 err_out:
4512 	ntfs_mount_error(opts.device, opts.mnt_point, err);
4513 	if (ctx->abs_mnt_point)
4514 		free(ctx->abs_mnt_point);
4515 #if defined(HAVE_SETXATTR) && defined(XATTR_MAPPINGS)
4516 	ntfs_xattr_free_mapping(xattr_mapping);
4517 #endif /* defined(HAVE_SETXATTR) && defined(XATTR_MAPPINGS) */
4518 err2:
4519 	ntfs_close();
4520 #ifndef DISABLE_PLUGINS
4521 	close_reparse_plugins(ctx);
4522 #endif /* DISABLE_PLUGINS */
4523 	free(ctx);
4524 	free(parsed_options);
4525 	free(opts.options);
4526 	free(opts.device);
4527 	return err;
4528 }
4529 
4530