1 /**
2  * dir.c - Directory handling code. Originated from the Linux-NTFS project.
3  *
4  * Copyright (c) 2002-2005 Anton Altaparmakov
5  * Copyright (c) 2004-2005 Richard Russon
6  * Copyright (c) 2004-2008 Szabolcs Szakacsits
7  * Copyright (c) 2005-2007 Yura Pakhuchiy
8  * Copyright (c) 2008-2014 Jean-Pierre Andre
9  *
10  * This program/include file is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as published
12  * by the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program/include file is distributed in the hope that it will be
16  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
17  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program (in the main directory of the NTFS-3G
22  * distribution in the file COPYING); if not, write to the Free Software
23  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29 
30 #ifdef HAVE_STDLIB_H
31 #include <stdlib.h>
32 #endif
33 #ifdef HAVE_ERRNO_H
34 #include <errno.h>
35 #endif
36 #ifdef HAVE_STRING_H
37 #include <string.h>
38 #endif
39 #ifdef HAVE_SYS_STAT_H
40 #include <sys/stat.h>
41 #endif
42 
43 #ifdef HAVE_SYS_TYPES_H
44 #include <sys/types.h>
45 #endif
46 #ifdef MAJOR_IN_MKDEV
47 #include <sys/mkdev.h>
48 #endif
49 #ifdef MAJOR_IN_SYSMACROS
50 #include <sys/sysmacros.h>
51 #endif
52 
53 #include "param.h"
54 #include "types.h"
55 #include "debug.h"
56 #include "attrib.h"
57 #include "inode.h"
58 #include "dir.h"
59 #include "volume.h"
60 #include "mft.h"
61 #include "index.h"
62 #include "ntfstime.h"
63 #include "lcnalloc.h"
64 #include "logging.h"
65 #include "cache.h"
66 #include "misc.h"
67 #include "security.h"
68 #include "reparse.h"
69 #include "object_id.h"
70 #include "xattrs.h"
71 
72 /*
73  * The little endian Unicode strings "$I30", "$SII", "$SDH", "$O"
74  *  and "$Q" as global constants.
75  */
76 ntfschar NTFS_INDEX_I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'),
77 		const_cpu_to_le16('3'), const_cpu_to_le16('0'),
78 		const_cpu_to_le16('\0') };
79 ntfschar NTFS_INDEX_SII[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'),
80 		const_cpu_to_le16('I'), const_cpu_to_le16('I'),
81 		const_cpu_to_le16('\0') };
82 ntfschar NTFS_INDEX_SDH[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'),
83 		const_cpu_to_le16('D'), const_cpu_to_le16('H'),
84 		const_cpu_to_le16('\0') };
85 ntfschar NTFS_INDEX_O[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('O'),
86 		const_cpu_to_le16('\0') };
87 ntfschar NTFS_INDEX_Q[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('Q'),
88 		const_cpu_to_le16('\0') };
89 ntfschar NTFS_INDEX_R[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('R'),
90 		const_cpu_to_le16('\0') };
91 
92 #if CACHE_INODE_SIZE
93 
94 /*
95  *		Pathname hashing
96  *
97  *	Based on first char and second char (which may be '\0')
98  */
99 
ntfs_dir_inode_hash(const struct CACHED_GENERIC * cached)100 int ntfs_dir_inode_hash(const struct CACHED_GENERIC *cached)
101 {
102 	const char *path;
103 	const unsigned char *name;
104 
105 	path = (const char*)cached->variable;
106 	if (!path) {
107 		ntfs_log_error("Bad inode cache entry\n");
108 		return (-1);
109 	}
110 	name = (const unsigned char*)strrchr(path,'/');
111 	if (!name)
112 		name = (const unsigned char*)path;
113 	return (((name[0] << 1) + name[1] + strlen((const char*)name))
114 				% (2*CACHE_INODE_SIZE));
115 }
116 
117 /*
118  *		Pathname comparing for entering/fetching from cache
119  */
120 
inode_cache_compare(const struct CACHED_GENERIC * cached,const struct CACHED_GENERIC * wanted)121 static int inode_cache_compare(const struct CACHED_GENERIC *cached,
122 			const struct CACHED_GENERIC *wanted)
123 {
124 	return (!cached->variable
125 		    || strcmp(cached->variable, wanted->variable));
126 }
127 
128 /*
129  *		Pathname comparing for invalidating entries in cache
130  *
131  *	A partial path is compared in order to invalidate all paths
132  *	related to a renamed directory
133  *	inode numbers are also checked, as deleting a long name may
134  *	imply deleting a short name and conversely
135  *
136  *	Only use associated with a CACHE_NOHASH flag
137  */
138 
inode_cache_inv_compare(const struct CACHED_GENERIC * cached,const struct CACHED_GENERIC * wanted)139 static int inode_cache_inv_compare(const struct CACHED_GENERIC *cached,
140 			const struct CACHED_GENERIC *wanted)
141 {
142 	int len;
143 	BOOL different;
144 	const struct CACHED_INODE *w;
145 	const struct CACHED_INODE *c;
146 
147 	w = (const struct CACHED_INODE*)wanted;
148 	c = (const struct CACHED_INODE*)cached;
149 	if (w->pathname) {
150 		len = strlen(w->pathname);
151 		different = !cached->variable
152 			|| ((w->inum != MREF(c->inum))
153 			   && (strncmp(c->pathname, w->pathname, len)
154 				|| ((c->pathname[len] != '\0')
155 				   && (c->pathname[len] != '/'))));
156 	} else
157 		different = !c->pathname
158 			|| (w->inum != MREF(c->inum));
159 	return (different);
160 }
161 
162 #endif
163 
164 #if CACHE_LOOKUP_SIZE
165 
166 /*
167  *		File name comparing for entering/fetching from lookup cache
168  */
169 
lookup_cache_compare(const struct CACHED_GENERIC * cached,const struct CACHED_GENERIC * wanted)170 static int lookup_cache_compare(const struct CACHED_GENERIC *cached,
171 			const struct CACHED_GENERIC *wanted)
172 {
173 	const struct CACHED_LOOKUP *c = (const struct CACHED_LOOKUP*) cached;
174 	const struct CACHED_LOOKUP *w = (const struct CACHED_LOOKUP*) wanted;
175 	return (!c->name
176 		    || (c->parent != w->parent)
177 		    || (c->namesize != w->namesize)
178 		    || memcmp(c->name, w->name, c->namesize));
179 }
180 
181 /*
182  *		Inode number comparing for invalidating lookup cache
183  *
184  *	All entries with designated inode number are invalidated
185  *
186  *	Only use associated with a CACHE_NOHASH flag
187  */
188 
lookup_cache_inv_compare(const struct CACHED_GENERIC * cached,const struct CACHED_GENERIC * wanted)189 static int lookup_cache_inv_compare(const struct CACHED_GENERIC *cached,
190 			const struct CACHED_GENERIC *wanted)
191 {
192 	const struct CACHED_LOOKUP *c = (const struct CACHED_LOOKUP*) cached;
193 	const struct CACHED_LOOKUP *w = (const struct CACHED_LOOKUP*) wanted;
194 	return (!c->name
195 		    || (c->parent != w->parent)
196 		    || (MREF(c->inum) != MREF(w->inum)));
197 }
198 
199 /*
200  *		Lookup hashing
201  *
202  *	Based on first, second and and last char
203  */
204 
ntfs_dir_lookup_hash(const struct CACHED_GENERIC * cached)205 int ntfs_dir_lookup_hash(const struct CACHED_GENERIC *cached)
206 {
207 	const unsigned char *name;
208 	int count;
209 	unsigned int val;
210 
211 	name = (const unsigned char*)cached->variable;
212 	count = cached->varsize;
213 	if (!name || !count) {
214 		ntfs_log_error("Bad lookup cache entry\n");
215 		return (-1);
216 	}
217 	val = (name[0] << 2) + (name[1] << 1) + name[count - 1] + count;
218 	return (val % (2*CACHE_LOOKUP_SIZE));
219 }
220 
221 #endif
222 
223 /**
224  * ntfs_inode_lookup_by_name - find an inode in a directory given its name
225  * @dir_ni:	ntfs inode of the directory in which to search for the name
226  * @uname:	Unicode name for which to search in the directory
227  * @uname_len:	length of the name @uname in Unicode characters
228  *
229  * Look for an inode with name @uname in the directory with inode @dir_ni.
230  * ntfs_inode_lookup_by_name() walks the contents of the directory looking for
231  * the Unicode name. If the name is found in the directory, the corresponding
232  * inode number (>= 0) is returned as a mft reference in cpu format, i.e. it
233  * is a 64-bit number containing the sequence number.
234  *
235  * On error, return -1 with errno set to the error code. If the inode is is not
236  * found errno is ENOENT.
237  *
238  * Note, @uname_len does not include the (optional) terminating NULL character.
239  *
240  * Note, we look for a case sensitive match first but we also look for a case
241  * insensitive match at the same time. If we find a case insensitive match, we
242  * save that for the case that we don't find an exact match, where we return
243  * the mft reference of the case insensitive match.
244  *
245  * If the volume is mounted with the case sensitive flag set, then we only
246  * allow exact matches.
247  */
ntfs_inode_lookup_by_name(ntfs_inode * dir_ni,const ntfschar * uname,const int uname_len)248 u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni,
249 		const ntfschar *uname, const int uname_len)
250 {
251 	VCN vcn;
252 	u64 mref = 0;
253 	s64 br;
254 	ntfs_volume *vol = dir_ni->vol;
255 	ntfs_attr_search_ctx *ctx;
256 	INDEX_ROOT *ir;
257 	INDEX_ENTRY *ie;
258 	INDEX_ALLOCATION *ia;
259 	IGNORE_CASE_BOOL case_sensitivity;
260 	u8 *index_end;
261 	ntfs_attr *ia_na;
262 	int eo, rc;
263 	u32 index_block_size;
264 	u8 index_vcn_size_bits;
265 
266 	ntfs_log_trace("Entering\n");
267 
268 	if (!dir_ni || !dir_ni->mrec || !uname || uname_len <= 0) {
269 		errno = EINVAL;
270 		return -1;
271 	}
272 
273 	ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
274 	if (!ctx)
275 		return -1;
276 
277 	/* Find the index root attribute in the mft record. */
278 	if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL,
279 			0, ctx)) {
280 		ntfs_log_perror("Index root attribute missing in directory inode "
281 				"%lld", (unsigned long long)dir_ni->mft_no);
282 		goto put_err_out;
283 	}
284 	case_sensitivity = (NVolCaseSensitive(vol) ? CASE_SENSITIVE : IGNORE_CASE);
285 	/* Get to the index root value. */
286 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
287 			le16_to_cpu(ctx->attr->value_offset));
288 	index_block_size = le32_to_cpu(ir->index_block_size);
289 	if (index_block_size < NTFS_BLOCK_SIZE ||
290 			index_block_size & (index_block_size - 1)) {
291 		ntfs_log_error("Index block size %u is invalid.\n",
292 				(unsigned)index_block_size);
293 		goto put_err_out;
294 	}
295 	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
296 	/* The first index entry. */
297 	ie = (INDEX_ENTRY*)((u8*)&ir->index +
298 			le32_to_cpu(ir->index.entries_offset));
299 	/*
300 	 * Loop until we exceed valid memory (corruption case) or until we
301 	 * reach the last entry.
302 	 */
303 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
304 		/* Bounds checks. */
305 		if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
306 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
307 				(u8*)ie + le16_to_cpu(ie->key_length) >
308 				index_end) {
309 			ntfs_log_error("Index entry out of bounds in inode %lld"
310 				       "\n", (unsigned long long)dir_ni->mft_no);
311 			goto put_err_out;
312 		}
313 		/*
314 		 * The last entry cannot contain a name. It can however contain
315 		 * a pointer to a child node in the B+tree so we just break out.
316 		 */
317 		if (ie->ie_flags & INDEX_ENTRY_END)
318 			break;
319 
320 		if (!le16_to_cpu(ie->length)) {
321 			ntfs_log_error("Zero length index entry in inode %lld"
322 				       "\n", (unsigned long long)dir_ni->mft_no);
323 			goto put_err_out;
324 		}
325 		/*
326 		 * Not a perfect match, need to do full blown collation so we
327 		 * know which way in the B+tree we have to go.
328 		 */
329 		rc = ntfs_names_full_collate(uname, uname_len,
330 				(ntfschar*)&ie->key.file_name.file_name,
331 				ie->key.file_name.file_name_length,
332 				case_sensitivity, vol->upcase, vol->upcase_len);
333 		/*
334 		 * If uname collates before the name of the current entry, there
335 		 * is definitely no such name in this index but we might need to
336 		 * descend into the B+tree so we just break out of the loop.
337 		 */
338 		if (rc == -1)
339 			break;
340 		/* The names are not equal, continue the search. */
341 		if (rc)
342 			continue;
343 		/*
344 		 * Perfect match, this will never happen as the
345 		 * ntfs_are_names_equal() call will have gotten a match but we
346 		 * still treat it correctly.
347 		 */
348 		mref = le64_to_cpu(ie->indexed_file);
349 		ntfs_attr_put_search_ctx(ctx);
350 		return mref;
351 	}
352 	/*
353 	 * We have finished with this index without success. Check for the
354 	 * presence of a child node and if not present return error code
355 	 * ENOENT, unless we have got the mft reference of a matching name
356 	 * cached in mref in which case return mref.
357 	 */
358 	if (!(ie->ie_flags & INDEX_ENTRY_NODE)) {
359 		ntfs_attr_put_search_ctx(ctx);
360 		if (mref)
361 			return mref;
362 		ntfs_log_debug("Entry not found - between root entries.\n");
363 		errno = ENOENT;
364 		return -1;
365 	} /* Child node present, descend into it. */
366 
367 	/* Open the index allocation attribute. */
368 	ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
369 	if (!ia_na) {
370 		ntfs_log_perror("Failed to open index allocation (inode %lld)",
371 				(unsigned long long)dir_ni->mft_no);
372 		goto put_err_out;
373 	}
374 
375 	/* Allocate a buffer for the current index block. */
376 	ia = ntfs_malloc(index_block_size);
377 	if (!ia) {
378 		ntfs_attr_close(ia_na);
379 		goto put_err_out;
380 	}
381 
382 	/* Determine the size of a vcn in the directory index. */
383 	if (vol->cluster_size <= index_block_size) {
384 		index_vcn_size_bits = vol->cluster_size_bits;
385 	} else {
386 		index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS;
387 	}
388 
389 	/* Get the starting vcn of the index_block holding the child node. */
390 	vcn = sle64_to_cpup((sle64*)((u8*)ie + le16_to_cpu(ie->length) - 8));
391 
392 descend_into_child_node:
393 
394 	/* Read the index block starting at vcn. */
395 	br = ntfs_attr_mst_pread(ia_na, vcn << index_vcn_size_bits, 1,
396 			index_block_size, ia);
397 	if (br != 1) {
398 		if (br != -1)
399 			errno = EIO;
400 		ntfs_log_perror("Failed to read vcn 0x%llx",
401 			       	(unsigned long long)vcn);
402 		goto close_err_out;
403 	}
404 
405 	if (sle64_to_cpu(ia->index_block_vcn) != vcn) {
406 		ntfs_log_error("Actual VCN (0x%llx) of index buffer is different "
407 				"from expected VCN (0x%llx).\n",
408 				(long long)sle64_to_cpu(ia->index_block_vcn),
409 				(long long)vcn);
410 		errno = EIO;
411 		goto close_err_out;
412 	}
413 	if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) {
414 		ntfs_log_error("Index buffer (VCN 0x%llx) of directory inode 0x%llx "
415 				"has a size (%u) differing from the directory "
416 				"specified size (%u).\n", (long long)vcn,
417 				(unsigned long long)dir_ni->mft_no,
418 				(unsigned) le32_to_cpu(ia->index.allocated_size) + 0x18,
419 				(unsigned)index_block_size);
420 		errno = EIO;
421 		goto close_err_out;
422 	}
423 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
424 	if (index_end > (u8*)ia + index_block_size) {
425 		ntfs_log_error("Size of index buffer (VCN 0x%llx) of directory inode "
426 				"0x%llx exceeds maximum size.\n",
427 				(long long)vcn, (unsigned long long)dir_ni->mft_no);
428 		errno = EIO;
429 		goto close_err_out;
430 	}
431 
432 	/* The first index entry. */
433 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
434 			le32_to_cpu(ia->index.entries_offset));
435 	/*
436 	 * Iterate similar to above big loop but applied to index buffer, thus
437 	 * loop until we exceed valid memory (corruption case) or until we
438 	 * reach the last entry.
439 	 */
440 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
441 		/* Bounds check. */
442 		if ((u8*)ie < (u8*)ia || (u8*)ie +
443 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
444 				(u8*)ie + le16_to_cpu(ie->key_length) >
445 				index_end) {
446 			ntfs_log_error("Index entry out of bounds in directory "
447 				       "inode %lld.\n",
448 				       (unsigned long long)dir_ni->mft_no);
449 			errno = EIO;
450 			goto close_err_out;
451 		}
452 		/*
453 		 * The last entry cannot contain a name. It can however contain
454 		 * a pointer to a child node in the B+tree so we just break out.
455 		 */
456 		if (ie->ie_flags & INDEX_ENTRY_END)
457 			break;
458 
459 		if (!le16_to_cpu(ie->length)) {
460 			errno = EIO;
461 			ntfs_log_error("Zero length index entry in inode %lld"
462 				       "\n", (unsigned long long)dir_ni->mft_no);
463 			goto close_err_out;
464 		}
465 		/*
466 		 * Not a perfect match, need to do full blown collation so we
467 		 * know which way in the B+tree we have to go.
468 		 */
469 		rc = ntfs_names_full_collate(uname, uname_len,
470 				(ntfschar*)&ie->key.file_name.file_name,
471 				ie->key.file_name.file_name_length,
472 				case_sensitivity, vol->upcase, vol->upcase_len);
473 		/*
474 		 * If uname collates before the name of the current entry, there
475 		 * is definitely no such name in this index but we might need to
476 		 * descend into the B+tree so we just break out of the loop.
477 		 */
478 		if (rc == -1)
479 			break;
480 		/* The names are not equal, continue the search. */
481 		if (rc)
482 			continue;
483 		mref = le64_to_cpu(ie->indexed_file);
484 		free(ia);
485 		ntfs_attr_close(ia_na);
486 		ntfs_attr_put_search_ctx(ctx);
487 		return mref;
488 	}
489 	/*
490 	 * We have finished with this index buffer without success. Check for
491 	 * the presence of a child node.
492 	 */
493 	if (ie->ie_flags & INDEX_ENTRY_NODE) {
494 		if ((ia->index.ih_flags & NODE_MASK) == LEAF_NODE) {
495 			ntfs_log_error("Index entry with child node found in a leaf "
496 					"node in directory inode %lld.\n",
497 					(unsigned long long)dir_ni->mft_no);
498 			errno = EIO;
499 			goto close_err_out;
500 		}
501 		/* Child node present, descend into it. */
502 		vcn = sle64_to_cpup((sle64*)((u8*)ie + le16_to_cpu(ie->length) - 8));
503 		if (vcn >= 0)
504 			goto descend_into_child_node;
505 		ntfs_log_error("Negative child node vcn in directory inode "
506 			       "0x%llx.\n", (unsigned long long)dir_ni->mft_no);
507 		errno = EIO;
508 		goto close_err_out;
509 	}
510 	free(ia);
511 	ntfs_attr_close(ia_na);
512 	ntfs_attr_put_search_ctx(ctx);
513 	/*
514 	 * No child node present, return error code ENOENT, unless we have got
515 	 * the mft reference of a matching name cached in mref in which case
516 	 * return mref.
517 	 */
518 	if (mref)
519 		return mref;
520 	ntfs_log_debug("Entry not found.\n");
521 	errno = ENOENT;
522 	return -1;
523 put_err_out:
524 	eo = EIO;
525 	ntfs_log_debug("Corrupt directory. Aborting lookup.\n");
526 eo_put_err_out:
527 	ntfs_attr_put_search_ctx(ctx);
528 	errno = eo;
529 	return -1;
530 close_err_out:
531 	eo = errno;
532 	free(ia);
533 	ntfs_attr_close(ia_na);
534 	goto eo_put_err_out;
535 }
536 
537 /*
538  *		Lookup a file in a directory from its UTF-8 name
539  *
540  *	The name is first fetched from cache if one is defined
541  *
542  *	Returns the inode number
543  *		or -1 if not possible (errno tells why)
544  */
545 
ntfs_inode_lookup_by_mbsname(ntfs_inode * dir_ni,const char * name)546 u64 ntfs_inode_lookup_by_mbsname(ntfs_inode *dir_ni, const char *name)
547 {
548 	int uname_len;
549 	ntfschar *uname = (ntfschar*)NULL;
550 	u64 inum;
551 	char *cached_name;
552 	const char *const_name;
553 
554 	if (!NVolCaseSensitive(dir_ni->vol)) {
555 		cached_name = ntfs_uppercase_mbs(name,
556 			dir_ni->vol->upcase, dir_ni->vol->upcase_len);
557 		const_name = cached_name;
558 	} else {
559 		cached_name = (char*)NULL;
560 		const_name = name;
561 	}
562 	if (const_name) {
563 #if CACHE_LOOKUP_SIZE
564 
565 		/*
566 		 * fetch inode from cache
567 		 */
568 
569 		if (dir_ni->vol->lookup_cache) {
570 			struct CACHED_LOOKUP item;
571 			struct CACHED_LOOKUP *cached;
572 
573 			item.name = const_name;
574 			item.namesize = strlen(const_name) + 1;
575 			item.parent = dir_ni->mft_no;
576 			cached = (struct CACHED_LOOKUP*)ntfs_fetch_cache(
577 					dir_ni->vol->lookup_cache,
578 					GENERIC(&item), lookup_cache_compare);
579 			if (cached) {
580 				inum = cached->inum;
581 				if (inum == (u64)-1)
582 					errno = ENOENT;
583 			} else {
584 				/* Generate unicode name. */
585 				uname_len = ntfs_mbstoucs(name, &uname);
586 				if (uname_len >= 0) {
587 					inum = ntfs_inode_lookup_by_name(dir_ni,
588 							uname, uname_len);
589 					item.inum = inum;
590 				/* enter into cache, even if not found */
591 					ntfs_enter_cache(dir_ni->vol->lookup_cache,
592 							GENERIC(&item),
593 							lookup_cache_compare);
594 					free(uname);
595 				} else
596 					inum = (s64)-1;
597 			}
598 		} else
599 #endif
600 			{
601 				/* Generate unicode name. */
602 			uname_len = ntfs_mbstoucs(cached_name, &uname);
603 			if (uname_len >= 0)
604 				inum = ntfs_inode_lookup_by_name(dir_ni,
605 						uname, uname_len);
606 			else
607 				inum = (s64)-1;
608 		}
609 		if (cached_name)
610 			free(cached_name);
611 	} else
612 		inum = (s64)-1;
613 	return (inum);
614 }
615 
616 /*
617  *		Update a cache lookup record when a name has been defined
618  *
619  *	The UTF-8 name is required
620  */
621 
ntfs_inode_update_mbsname(ntfs_inode * dir_ni,const char * name,u64 inum)622 void ntfs_inode_update_mbsname(ntfs_inode *dir_ni, const char *name, u64 inum)
623 {
624 #if CACHE_LOOKUP_SIZE
625 	struct CACHED_LOOKUP item;
626 	struct CACHED_LOOKUP *cached;
627 	char *cached_name;
628 
629 	if (dir_ni->vol->lookup_cache) {
630 		if (!NVolCaseSensitive(dir_ni->vol)) {
631 			cached_name = ntfs_uppercase_mbs(name,
632 				dir_ni->vol->upcase, dir_ni->vol->upcase_len);
633 			item.name = cached_name;
634 		} else {
635 			cached_name = (char*)NULL;
636 			item.name = name;
637 		}
638 		if (item.name) {
639 			item.namesize = strlen(item.name) + 1;
640 			item.parent = dir_ni->mft_no;
641 			item.inum = inum;
642 			cached = (struct CACHED_LOOKUP*)ntfs_enter_cache(
643 					dir_ni->vol->lookup_cache,
644 					GENERIC(&item), lookup_cache_compare);
645 			if (cached)
646 				cached->inum = inum;
647 			if (cached_name)
648 				free(cached_name);
649 		}
650 	}
651 #endif
652 }
653 
654 /**
655  * ntfs_pathname_to_inode - Find the inode which represents the given pathname
656  * @vol:       An ntfs volume obtained from ntfs_mount
657  * @parent:    A directory inode to begin the search (may be NULL)
658  * @pathname:  Pathname to be located
659  *
660  * Take an ASCII pathname and find the inode that represents it.  The function
661  * splits the path and then descends the directory tree.  If @parent is NULL,
662  * then the root directory '.' will be used as the base for the search.
663  *
664  * Return:  inode  Success, the pathname was valid
665  *	    NULL   Error, the pathname was invalid, or some other error occurred
666  */
ntfs_pathname_to_inode(ntfs_volume * vol,ntfs_inode * parent,const char * pathname)667 ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
668 		const char *pathname)
669 {
670 	u64 inum;
671 	int len, err = 0;
672 	char *p, *q;
673 	ntfs_inode *ni;
674 	ntfs_inode *result = NULL;
675 	ntfschar *unicode = NULL;
676 	char *ascii = NULL;
677 #if CACHE_INODE_SIZE
678 	struct CACHED_INODE item;
679 	struct CACHED_INODE *cached;
680 	char *fullname;
681 #endif
682 
683 	if (!vol || !pathname) {
684 		errno = EINVAL;
685 		return NULL;
686 	}
687 
688 	ntfs_log_trace("path: '%s'\n", pathname);
689 
690 	ascii = strdup(pathname);
691 	if (!ascii) {
692 		ntfs_log_error("Out of memory.\n");
693 		err = ENOMEM;
694 		goto out;
695 	}
696 
697 	p = ascii;
698 	/* Remove leading /'s. */
699 	while (p && *p && *p == PATH_SEP)
700 		p++;
701 #if CACHE_INODE_SIZE
702 	fullname = p;
703 	if (p[0] && (p[strlen(p)-1] == PATH_SEP))
704 		ntfs_log_error("Unnormalized path %s\n",ascii);
705 #endif
706 	if (parent) {
707 		ni = parent;
708 	} else {
709 #if CACHE_INODE_SIZE
710 			/*
711 			 * fetch inode for full path from cache
712 			 */
713 		if (*fullname) {
714 			item.pathname = fullname;
715 			item.varsize = strlen(fullname) + 1;
716 			cached = (struct CACHED_INODE*)ntfs_fetch_cache(
717 				vol->xinode_cache, GENERIC(&item),
718 				inode_cache_compare);
719 		} else
720 			cached = (struct CACHED_INODE*)NULL;
721 		if (cached) {
722 			/*
723 			 * return opened inode if found in cache
724 			 */
725 			inum = MREF(cached->inum);
726 			ni = ntfs_inode_open(vol, inum);
727 			if (!ni) {
728 				ntfs_log_debug("Cannot open inode %llu: %s.\n",
729 						(unsigned long long)inum, p);
730 				err = EIO;
731 			}
732 			result = ni;
733 			goto out;
734 		}
735 #endif
736 		ni = ntfs_inode_open(vol, FILE_root);
737 		if (!ni) {
738 			ntfs_log_debug("Couldn't open the inode of the root "
739 					"directory.\n");
740 			err = EIO;
741 			result = (ntfs_inode*)NULL;
742 			goto out;
743 		}
744 	}
745 
746 	while (p && *p) {
747 		/* Find the end of the first token. */
748 		q = strchr(p, PATH_SEP);
749 		if (q != NULL) {
750 			*q = '\0';
751 		}
752 #if CACHE_INODE_SIZE
753 			/*
754 			 * fetch inode for partial path from cache
755 			 */
756 		cached = (struct CACHED_INODE*)NULL;
757 		if (!parent) {
758 			item.pathname = fullname;
759 			item.varsize = strlen(fullname) + 1;
760 			cached = (struct CACHED_INODE*)ntfs_fetch_cache(
761 					vol->xinode_cache, GENERIC(&item),
762 					inode_cache_compare);
763 			if (cached) {
764 				inum = cached->inum;
765 			}
766 		}
767 			/*
768 			 * if not in cache, translate, search, then
769 			 * insert into cache if found
770 			 */
771 		if (!cached) {
772 			len = ntfs_mbstoucs(p, &unicode);
773 			if (len < 0) {
774 				ntfs_log_perror("Could not convert filename to Unicode:"
775 					" '%s'", p);
776 				err = errno;
777 				goto close;
778 			} else if (len > NTFS_MAX_NAME_LEN) {
779 				err = ENAMETOOLONG;
780 				goto close;
781 			}
782 			inum = ntfs_inode_lookup_by_name(ni, unicode, len);
783 			if (!parent && (inum != (u64) -1)) {
784 				item.inum = inum;
785 				ntfs_enter_cache(vol->xinode_cache,
786 						GENERIC(&item),
787 						inode_cache_compare);
788 			}
789 		}
790 #else
791 		len = ntfs_mbstoucs(p, &unicode);
792 		if (len < 0) {
793 			ntfs_log_perror("Could not convert filename to Unicode:"
794 					" '%s'", p);
795 			err = errno;
796 			goto close;
797 		} else if (len > NTFS_MAX_NAME_LEN) {
798 			err = ENAMETOOLONG;
799 			goto close;
800 		}
801 		inum = ntfs_inode_lookup_by_name(ni, unicode, len);
802 #endif
803 		if (inum == (u64) -1) {
804 			ntfs_log_debug("Couldn't find name '%s' in pathname "
805 					"'%s'.\n", p, pathname);
806 			err = ENOENT;
807 			goto close;
808 		}
809 
810 		if (ni != parent)
811 			if (ntfs_inode_close(ni)) {
812 				err = errno;
813 				goto out;
814 			}
815 
816 		inum = MREF(inum);
817 		ni = ntfs_inode_open(vol, inum);
818 		if (!ni) {
819 			ntfs_log_debug("Cannot open inode %llu: %s.\n",
820 					(unsigned long long)inum, p);
821 			err = EIO;
822 			goto close;
823 		}
824 
825 		free(unicode);
826 		unicode = NULL;
827 
828 		if (q) *q++ = PATH_SEP; /* JPA */
829 		p = q;
830 		while (p && *p && *p == PATH_SEP)
831 			p++;
832 	}
833 
834 	result = ni;
835 	ni = NULL;
836 close:
837 	if (ni && (ni != parent))
838 		if (ntfs_inode_close(ni) && !err)
839 			err = errno;
840 out:
841 	free(ascii);
842 	free(unicode);
843 	if (err)
844 		errno = err;
845 	return result;
846 }
847 
848 /*
849  * The little endian Unicode string ".." for ntfs_readdir().
850  */
851 static const ntfschar dotdot[3] = { const_cpu_to_le16('.'),
852 				   const_cpu_to_le16('.'),
853 				   const_cpu_to_le16('\0') };
854 
855 /*
856  * union index_union -
857  * More helpers for ntfs_readdir().
858  */
859 typedef union {
860 	INDEX_ROOT *ir;
861 	INDEX_ALLOCATION *ia;
862 } index_union __attribute__((__transparent_union__));
863 
864 /**
865  * enum INDEX_TYPE -
866  * More helpers for ntfs_readdir().
867  */
868 typedef enum {
869 	INDEX_TYPE_ROOT,	/* index root */
870 	INDEX_TYPE_ALLOCATION,	/* index allocation */
871 } INDEX_TYPE;
872 
873 /*
874  *		Decode Interix file types
875  *
876  *	Non-Interix types are returned as plain files, because a
877  *	Windows user may force patterns very similar to Interix,
878  *	and most metadata files have such similar patters.
879  */
880 
ntfs_interix_types(ntfs_inode * ni)881 u32 ntfs_interix_types(ntfs_inode *ni)
882 {
883 	ntfs_attr *na;
884 	u32 dt_type;
885 	le64 magic;
886 
887 	dt_type = NTFS_DT_UNKNOWN;
888 	na = ntfs_attr_open(ni, AT_DATA, NULL, 0);
889 	if (na) {
890 		/*
891 		 * Unrecognized patterns (eg HID + SYST for metadata)
892 		 * are plain files or directories
893 		 */
894 		if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
895 			dt_type = NTFS_DT_DIR;
896 		else
897 			dt_type = NTFS_DT_REG;
898 		if (na->data_size <= 1) {
899 			if (!(ni->flags & FILE_ATTR_HIDDEN))
900 				dt_type = (na->data_size ?
901 						NTFS_DT_SOCK : NTFS_DT_FIFO);
902 		} else {
903 			if ((na->data_size >= (s64)sizeof(magic))
904 			    && (ntfs_attr_pread(na, 0, sizeof(magic), &magic)
905 				== sizeof(magic))) {
906 				if (magic == INTX_SYMBOLIC_LINK)
907 					dt_type = NTFS_DT_LNK;
908 				else if (magic == INTX_BLOCK_DEVICE)
909 					dt_type = NTFS_DT_BLK;
910 				else if (magic == INTX_CHARACTER_DEVICE)
911 					dt_type = NTFS_DT_CHR;
912 			}
913 		}
914 		ntfs_attr_close(na);
915 	}
916 	return (dt_type);
917 }
918 
919 /*
920  *		Decode file types
921  *
922  *	Better only use for Interix types and junctions,
923  *	unneeded complexity when used for plain files or directories
924  *
925  *	Error cases are logged and returned as unknown.
926  */
927 
ntfs_dir_entry_type(ntfs_inode * dir_ni,MFT_REF mref,FILE_ATTR_FLAGS attributes)928 static u32 ntfs_dir_entry_type(ntfs_inode *dir_ni, MFT_REF mref,
929 					FILE_ATTR_FLAGS attributes)
930 {
931 	ntfs_inode *ni;
932 	u32 dt_type;
933 
934 	dt_type = NTFS_DT_UNKNOWN;
935 	ni = ntfs_inode_open(dir_ni->vol, mref);
936 	if (ni) {
937 		if ((attributes & FILE_ATTR_REPARSE_POINT)
938 		    && ntfs_possible_symlink(ni))
939 			dt_type = NTFS_DT_LNK;
940 		else
941 			if ((attributes & FILE_ATTR_SYSTEM)
942 			   && !(attributes & FILE_ATTR_I30_INDEX_PRESENT))
943 				dt_type = ntfs_interix_types(ni);
944 			else
945 				dt_type = (attributes
946 						& FILE_ATTR_I30_INDEX_PRESENT
947 					? NTFS_DT_DIR : NTFS_DT_REG);
948 		if (ntfs_inode_close(ni)) {
949 				 /* anything special worth doing ? */
950 			ntfs_log_error("Failed to close inode %lld\n",
951 				(long long)MREF(mref));
952 		}
953 	}
954 	if (dt_type == NTFS_DT_UNKNOWN)
955 		ntfs_log_error("Could not decode the type of inode %lld\n",
956 				(long long)MREF(mref));
957 	return (dt_type);
958 }
959 
960 /**
961  * ntfs_filldir - ntfs specific filldir method
962  * @dir_ni:	ntfs inode of current directory
963  * @pos:	current position in directory
964  * @ivcn_bits:	log(2) of index vcn size
965  * @index_type:	specifies whether @iu is an index root or an index allocation
966  * @iu:		index root or index block to which @ie belongs
967  * @ie:		current index entry
968  * @dirent:	context for filldir callback supplied by the caller
969  * @filldir:	filldir callback supplied by the caller
970  *
971  * Pass information specifying the current directory entry @ie to the @filldir
972  * callback.
973  */
ntfs_filldir(ntfs_inode * dir_ni,s64 * pos,u8 ivcn_bits,const INDEX_TYPE index_type,index_union iu,INDEX_ENTRY * ie,void * dirent,ntfs_filldir_t filldir)974 static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits,
975 		const INDEX_TYPE index_type, index_union iu, INDEX_ENTRY *ie,
976 		void *dirent, ntfs_filldir_t filldir)
977 {
978 	FILE_NAME_ATTR *fn = &ie->key.file_name;
979 	unsigned dt_type;
980 	BOOL metadata;
981 	ntfschar *loname;
982 	int res;
983 	MFT_REF mref;
984 
985 	ntfs_log_trace("Entering.\n");
986 
987 	/* Advance the position even if going to skip the entry. */
988 	if (index_type == INDEX_TYPE_ALLOCATION)
989 		*pos = (u8*)ie - (u8*)iu.ia + (sle64_to_cpu(
990 				iu.ia->index_block_vcn) << ivcn_bits) +
991 				dir_ni->vol->mft_record_size;
992 	else /* if (index_type == INDEX_TYPE_ROOT) */
993 		*pos = (u8*)ie - (u8*)iu.ir;
994 	mref = le64_to_cpu(ie->indexed_file);
995 	metadata = (MREF(mref) != FILE_root) && (MREF(mref) < FILE_first_user);
996 	/* Skip root directory self reference entry. */
997 	if (MREF_LE(ie->indexed_file) == FILE_root)
998 		return 0;
999 	if ((ie->key.file_name.file_attributes
1000 		     & (FILE_ATTR_REPARSE_POINT | FILE_ATTR_SYSTEM))
1001 	    && !metadata)
1002 		dt_type = ntfs_dir_entry_type(dir_ni, mref,
1003 					ie->key.file_name.file_attributes);
1004 	else if (ie->key.file_name.file_attributes
1005 		     & FILE_ATTR_I30_INDEX_PRESENT)
1006 		dt_type = NTFS_DT_DIR;
1007 	else
1008 		dt_type = NTFS_DT_REG;
1009 
1010 		/* return metadata files and hidden files if requested */
1011         if ((!metadata && (NVolShowHidFiles(dir_ni->vol)
1012 				|| !(fn->file_attributes & FILE_ATTR_HIDDEN)))
1013             || (NVolShowSysFiles(dir_ni->vol) && (NVolShowHidFiles(dir_ni->vol)
1014 				|| metadata))) {
1015 		if (NVolCaseSensitive(dir_ni->vol)) {
1016 			res = filldir(dirent, fn->file_name,
1017 					fn->file_name_length,
1018 					fn->file_name_type, *pos,
1019 					mref, dt_type);
1020 		} else {
1021 			loname = (ntfschar*)ntfs_malloc(2*fn->file_name_length);
1022 			if (loname) {
1023 				memcpy(loname, fn->file_name,
1024 					2*fn->file_name_length);
1025 				ntfs_name_locase(loname, fn->file_name_length,
1026 					dir_ni->vol->locase,
1027 					dir_ni->vol->upcase_len);
1028 				res = filldir(dirent, loname,
1029 					fn->file_name_length,
1030 					fn->file_name_type, *pos,
1031 					mref, dt_type);
1032 				free(loname);
1033 			} else
1034 				res = -1;
1035 		}
1036 	} else
1037 		res = 0;
1038 	return (res);
1039 }
1040 
1041 /**
1042  * ntfs_mft_get_parent_ref - find mft reference of parent directory of an inode
1043  * @ni:		ntfs inode whose parent directory to find
1044  *
1045  * Find the parent directory of the ntfs inode @ni. To do this, find the first
1046  * file name attribute in the mft record of @ni and return the parent mft
1047  * reference from that.
1048  *
1049  * Note this only makes sense for directories, since files can be hard linked
1050  * from multiple directories and there is no way for us to tell which one is
1051  * being looked for.
1052  *
1053  * Technically directories can have hard links, too, but we consider that as
1054  * illegal as Linux/UNIX do not support directory hard links.
1055  *
1056  * Return the mft reference of the parent directory on success or -1 on error
1057  * with errno set to the error code.
1058  */
ntfs_mft_get_parent_ref(ntfs_inode * ni)1059 static MFT_REF ntfs_mft_get_parent_ref(ntfs_inode *ni)
1060 {
1061 	MFT_REF mref;
1062 	ntfs_attr_search_ctx *ctx;
1063 	FILE_NAME_ATTR *fn;
1064 	int eo;
1065 
1066 	ntfs_log_trace("Entering.\n");
1067 
1068 	if (!ni) {
1069 		errno = EINVAL;
1070 		return ERR_MREF(-1);
1071 	}
1072 
1073 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
1074 	if (!ctx)
1075 		return ERR_MREF(-1);
1076 	if (ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
1077 		ntfs_log_error("No file name found in inode %lld\n",
1078 			       (unsigned long long)ni->mft_no);
1079 		goto err_out;
1080 	}
1081 	if (ctx->attr->non_resident) {
1082 		ntfs_log_error("File name attribute must be resident (inode "
1083 			       "%lld)\n", (unsigned long long)ni->mft_no);
1084 		goto io_err_out;
1085 	}
1086 	fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
1087 			le16_to_cpu(ctx->attr->value_offset));
1088 	if ((u8*)fn +	le32_to_cpu(ctx->attr->value_length) >
1089 			(u8*)ctx->attr + le32_to_cpu(ctx->attr->length)) {
1090 		ntfs_log_error("Corrupt file name attribute in inode %lld.\n",
1091 			       (unsigned long long)ni->mft_no);
1092 		goto io_err_out;
1093 	}
1094 	mref = le64_to_cpu(fn->parent_directory);
1095 	ntfs_attr_put_search_ctx(ctx);
1096 	return mref;
1097 io_err_out:
1098 	errno = EIO;
1099 err_out:
1100 	eo = errno;
1101 	ntfs_attr_put_search_ctx(ctx);
1102 	errno = eo;
1103 	return ERR_MREF(-1);
1104 }
1105 
1106 /**
1107  * ntfs_readdir - read the contents of an ntfs directory
1108  * @dir_ni:	ntfs inode of current directory
1109  * @pos:	current position in directory
1110  * @dirent:	context for filldir callback supplied by the caller
1111  * @filldir:	filldir callback supplied by the caller
1112  *
1113  * Parse the index root and the index blocks that are marked in use in the
1114  * index bitmap and hand each found directory entry to the @filldir callback
1115  * supplied by the caller.
1116  *
1117  * Return 0 on success or -1 on error with errno set to the error code.
1118  *
1119  * Note: Index blocks are parsed in ascending vcn order, from which follows
1120  * that the directory entries are not returned sorted.
1121  */
ntfs_readdir(ntfs_inode * dir_ni,s64 * pos,void * dirent,ntfs_filldir_t filldir)1122 int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
1123 		void *dirent, ntfs_filldir_t filldir)
1124 {
1125 	s64 i_size, br, ia_pos, bmp_pos, ia_start;
1126 	ntfs_volume *vol;
1127 	ntfs_attr *ia_na, *bmp_na = NULL;
1128 	ntfs_attr_search_ctx *ctx = NULL;
1129 	u8 *index_end, *bmp = NULL;
1130 	INDEX_ROOT *ir;
1131 	INDEX_ENTRY *ie;
1132 	INDEX_ALLOCATION *ia = NULL;
1133 	int rc, ir_pos, bmp_buf_size, bmp_buf_pos, eo;
1134 	u32 index_block_size;
1135 	u8 index_block_size_bits, index_vcn_size_bits;
1136 
1137 	ntfs_log_trace("Entering.\n");
1138 
1139 	if (!dir_ni || !pos || !filldir) {
1140 		errno = EINVAL;
1141 		return -1;
1142 	}
1143 
1144 	if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
1145 		errno = ENOTDIR;
1146 		return -1;
1147 	}
1148 
1149 	vol = dir_ni->vol;
1150 
1151 	ntfs_log_trace("Entering for inode %lld, *pos 0x%llx.\n",
1152 			(unsigned long long)dir_ni->mft_no, (long long)*pos);
1153 
1154 	/* Open the index allocation attribute. */
1155 	ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
1156 	if (!ia_na) {
1157 		if (errno != ENOENT) {
1158 			ntfs_log_perror("Failed to open index allocation attribute. "
1159 				"Directory inode %lld is corrupt or bug",
1160 				(unsigned long long)dir_ni->mft_no);
1161 			return -1;
1162 		}
1163 		i_size = 0;
1164 	} else
1165 		i_size = ia_na->data_size;
1166 
1167 	rc = 0;
1168 
1169 	/* Are we at end of dir yet? */
1170 	if (*pos >= i_size + vol->mft_record_size)
1171 		goto done;
1172 
1173 	/* Emulate . and .. for all directories. */
1174 	if (!*pos) {
1175 		rc = filldir(dirent, dotdot, 1, FILE_NAME_POSIX, *pos,
1176 				MK_MREF(dir_ni->mft_no,
1177 				le16_to_cpu(dir_ni->mrec->sequence_number)),
1178 				NTFS_DT_DIR);
1179 		if (rc)
1180 			goto err_out;
1181 		++*pos;
1182 	}
1183 	if (*pos == 1) {
1184 		MFT_REF parent_mref;
1185 
1186 		parent_mref = ntfs_mft_get_parent_ref(dir_ni);
1187 		if (parent_mref == ERR_MREF(-1)) {
1188 			ntfs_log_perror("Parent directory not found");
1189 			goto dir_err_out;
1190 		}
1191 
1192 		rc = filldir(dirent, dotdot, 2, FILE_NAME_POSIX, *pos,
1193 				parent_mref, NTFS_DT_DIR);
1194 		if (rc)
1195 			goto err_out;
1196 		++*pos;
1197 	}
1198 
1199 	ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
1200 	if (!ctx)
1201 		goto err_out;
1202 
1203 	/* Get the offset into the index root attribute. */
1204 	ir_pos = (int)*pos;
1205 	/* Find the index root attribute in the mft record. */
1206 	if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE, 0, NULL,
1207 			0, ctx)) {
1208 		ntfs_log_perror("Index root attribute missing in directory inode "
1209 				"%lld", (unsigned long long)dir_ni->mft_no);
1210 		goto dir_err_out;
1211 	}
1212 	/* Get to the index root value. */
1213 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
1214 			le16_to_cpu(ctx->attr->value_offset));
1215 
1216 	/* Determine the size of a vcn in the directory index. */
1217 	index_block_size = le32_to_cpu(ir->index_block_size);
1218 	if (index_block_size < NTFS_BLOCK_SIZE ||
1219 			index_block_size & (index_block_size - 1)) {
1220 		ntfs_log_error("Index block size %u is invalid.\n",
1221 				(unsigned)index_block_size);
1222 		goto dir_err_out;
1223 	}
1224 	index_block_size_bits = ffs(index_block_size) - 1;
1225 	if (vol->cluster_size <= index_block_size) {
1226 		index_vcn_size_bits = vol->cluster_size_bits;
1227 	} else {
1228 		index_vcn_size_bits = NTFS_BLOCK_SIZE_BITS;
1229 	}
1230 
1231 	/* Are we jumping straight into the index allocation attribute? */
1232 	if (*pos >= vol->mft_record_size) {
1233 		ntfs_attr_put_search_ctx(ctx);
1234 		ctx = NULL;
1235 		goto skip_index_root;
1236 	}
1237 
1238 	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
1239 	/* The first index entry. */
1240 	ie = (INDEX_ENTRY*)((u8*)&ir->index +
1241 			le32_to_cpu(ir->index.entries_offset));
1242 	/*
1243 	 * Loop until we exceed valid memory (corruption case) or until we
1244 	 * reach the last entry or until filldir tells us it has had enough
1245 	 * or signals an error (both covered by the rc test).
1246 	 */
1247 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
1248 		ntfs_log_debug("In index root, offset %d.\n", (int)((u8*)ie - (u8*)ir));
1249 		/* Bounds checks. */
1250 		if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
1251 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
1252 				(u8*)ie + le16_to_cpu(ie->key_length) >
1253 				index_end)
1254 			goto dir_err_out;
1255 		/* The last entry cannot contain a name. */
1256 		if (ie->ie_flags & INDEX_ENTRY_END)
1257 			break;
1258 
1259 		if (!le16_to_cpu(ie->length))
1260 			goto dir_err_out;
1261 
1262 		/* Skip index root entry if continuing previous readdir. */
1263 		if (ir_pos > (u8*)ie - (u8*)ir)
1264 			continue;
1265 		/*
1266 		 * Submit the directory entry to ntfs_filldir(), which will
1267 		 * invoke the filldir() callback as appropriate.
1268 		 */
1269 		rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits,
1270 				INDEX_TYPE_ROOT, ir, ie, dirent, filldir);
1271 		if (rc) {
1272 			ntfs_attr_put_search_ctx(ctx);
1273 			ctx = NULL;
1274 			goto err_out;
1275 		}
1276 	}
1277 	ntfs_attr_put_search_ctx(ctx);
1278 	ctx = NULL;
1279 
1280 	/* If there is no index allocation attribute we are finished. */
1281 	if (!ia_na)
1282 		goto EOD;
1283 
1284 	/* Advance *pos to the beginning of the index allocation. */
1285 	*pos = vol->mft_record_size;
1286 
1287 skip_index_root:
1288 
1289 	if (!ia_na)
1290 		goto done;
1291 
1292 	/* Allocate a buffer for the current index block. */
1293 	ia = ntfs_malloc(index_block_size);
1294 	if (!ia)
1295 		goto err_out;
1296 
1297 	bmp_na = ntfs_attr_open(dir_ni, AT_BITMAP, NTFS_INDEX_I30, 4);
1298 	if (!bmp_na) {
1299 		ntfs_log_perror("Failed to open index bitmap attribute");
1300 		goto dir_err_out;
1301 	}
1302 
1303 	/* Get the offset into the index allocation attribute. */
1304 	ia_pos = *pos - vol->mft_record_size;
1305 
1306 	bmp_pos = ia_pos >> index_block_size_bits;
1307 	if (bmp_pos >> 3 >= bmp_na->data_size) {
1308 		ntfs_log_error("Current index position exceeds index bitmap "
1309 				"size.\n");
1310 		goto dir_err_out;
1311 	}
1312 
1313 	bmp_buf_size = min(bmp_na->data_size - (bmp_pos >> 3), 4096);
1314 	bmp = ntfs_malloc(bmp_buf_size);
1315 	if (!bmp)
1316 		goto err_out;
1317 
1318 	br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
1319 	if (br != bmp_buf_size) {
1320 		if (br != -1)
1321 			errno = EIO;
1322 		ntfs_log_perror("Failed to read from index bitmap attribute");
1323 		goto err_out;
1324 	}
1325 
1326 	bmp_buf_pos = 0;
1327 	/* If the index block is not in use find the next one that is. */
1328 	while (!(bmp[bmp_buf_pos >> 3] & (1 << (bmp_buf_pos & 7)))) {
1329 find_next_index_buffer:
1330 		bmp_pos++;
1331 		bmp_buf_pos++;
1332 		/* If we have reached the end of the bitmap, we are done. */
1333 		if (bmp_pos >> 3 >= bmp_na->data_size)
1334 			goto EOD;
1335 		ia_pos = bmp_pos << index_block_size_bits;
1336 		if (bmp_buf_pos >> 3 < bmp_buf_size)
1337 			continue;
1338 		/* Read next chunk from the index bitmap. */
1339 		bmp_buf_pos = 0;
1340 		if ((bmp_pos >> 3) + bmp_buf_size > bmp_na->data_size)
1341 			bmp_buf_size = bmp_na->data_size - (bmp_pos >> 3);
1342 		br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
1343 		if (br != bmp_buf_size) {
1344 			if (br != -1)
1345 				errno = EIO;
1346 			ntfs_log_perror("Failed to read from index bitmap attribute");
1347 			goto err_out;
1348 		}
1349 	}
1350 
1351 	ntfs_log_debug("Handling index block 0x%llx.\n", (long long)bmp_pos);
1352 
1353 	/* Read the index block starting at bmp_pos. */
1354 	br = ntfs_attr_mst_pread(ia_na, bmp_pos << index_block_size_bits, 1,
1355 			index_block_size, ia);
1356 	if (br != 1) {
1357 		if (br != -1)
1358 			errno = EIO;
1359 		ntfs_log_perror("Failed to read index block");
1360 		goto err_out;
1361 	}
1362 
1363 	ia_start = ia_pos & ~(s64)(index_block_size - 1);
1364 	if (sle64_to_cpu(ia->index_block_vcn) != ia_start >>
1365 			index_vcn_size_bits) {
1366 		ntfs_log_error("Actual VCN (0x%llx) of index buffer is different "
1367 				"from expected VCN (0x%llx) in inode 0x%llx.\n",
1368 				(long long)sle64_to_cpu(ia->index_block_vcn),
1369 				(long long)ia_start >> index_vcn_size_bits,
1370 				(unsigned long long)dir_ni->mft_no);
1371 		goto dir_err_out;
1372 	}
1373 	if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) {
1374 		ntfs_log_error("Index buffer (VCN 0x%llx) of directory inode %lld "
1375 				"has a size (%u) differing from the directory "
1376 				"specified size (%u).\n", (long long)ia_start >>
1377 				index_vcn_size_bits,
1378 				(unsigned long long)dir_ni->mft_no,
1379 				(unsigned) le32_to_cpu(ia->index.allocated_size)
1380 				+ 0x18, (unsigned)index_block_size);
1381 		goto dir_err_out;
1382 	}
1383 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
1384 	if (index_end > (u8*)ia + index_block_size) {
1385 		ntfs_log_error("Size of index buffer (VCN 0x%llx) of directory inode "
1386 				"%lld exceeds maximum size.\n",
1387 				(long long)ia_start >> index_vcn_size_bits,
1388 				(unsigned long long)dir_ni->mft_no);
1389 		goto dir_err_out;
1390 	}
1391 	/* The first index entry. */
1392 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
1393 			le32_to_cpu(ia->index.entries_offset));
1394 	/*
1395 	 * Loop until we exceed valid memory (corruption case) or until we
1396 	 * reach the last entry or until ntfs_filldir tells us it has had
1397 	 * enough or signals an error (both covered by the rc test).
1398 	 */
1399 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
1400 		ntfs_log_debug("In index allocation, offset 0x%llx.\n",
1401 				(long long)ia_start + ((u8*)ie - (u8*)ia));
1402 		/* Bounds checks. */
1403 		if ((u8*)ie < (u8*)ia || (u8*)ie +
1404 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
1405 				(u8*)ie + le16_to_cpu(ie->key_length) >
1406 				index_end) {
1407 			ntfs_log_error("Index entry out of bounds in directory inode "
1408 				"%lld.\n", (unsigned long long)dir_ni->mft_no);
1409 			goto dir_err_out;
1410 		}
1411 		/* The last entry cannot contain a name. */
1412 		if (ie->ie_flags & INDEX_ENTRY_END)
1413 			break;
1414 
1415 		if (!le16_to_cpu(ie->length))
1416 			goto dir_err_out;
1417 
1418 		/* Skip index entry if continuing previous readdir. */
1419 		if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
1420 			continue;
1421 		/*
1422 		 * Submit the directory entry to ntfs_filldir(), which will
1423 		 * invoke the filldir() callback as appropriate.
1424 		 */
1425 		rc = ntfs_filldir(dir_ni, pos, index_vcn_size_bits,
1426 				INDEX_TYPE_ALLOCATION, ia, ie, dirent, filldir);
1427 		if (rc)
1428 			goto err_out;
1429 	}
1430 	goto find_next_index_buffer;
1431 EOD:
1432 	/* We are finished, set *pos to EOD. */
1433 	*pos = i_size + vol->mft_record_size;
1434 done:
1435 	free(ia);
1436 	free(bmp);
1437 	if (bmp_na)
1438 		ntfs_attr_close(bmp_na);
1439 	if (ia_na)
1440 		ntfs_attr_close(ia_na);
1441 	ntfs_log_debug("EOD, *pos 0x%llx, returning 0.\n", (long long)*pos);
1442 	return 0;
1443 dir_err_out:
1444 	errno = EIO;
1445 err_out:
1446 	eo = errno;
1447 	ntfs_log_trace("failed.\n");
1448 	if (ctx)
1449 		ntfs_attr_put_search_ctx(ctx);
1450 	free(ia);
1451 	free(bmp);
1452 	if (bmp_na)
1453 		ntfs_attr_close(bmp_na);
1454 	if (ia_na)
1455 		ntfs_attr_close(ia_na);
1456 	errno = eo;
1457 	return -1;
1458 }
1459 
1460 
1461 /**
1462  * __ntfs_create - create object on ntfs volume
1463  * @dir_ni:	ntfs inode for directory in which create new object
1464  * @securid:	id of inheritable security descriptor, 0 if none
1465  * @name:	unicode name of new object
1466  * @name_len:	length of the name in unicode characters
1467  * @type:	type of the object to create
1468  * @dev:	major and minor device numbers (obtained from makedev())
1469  * @target:	target in unicode (only for symlinks)
1470  * @target_len:	length of target in unicode characters
1471  *
1472  * Internal, use ntfs_create{,_device,_symlink} wrappers instead.
1473  *
1474  * @type can be:
1475  *	S_IFREG		to create regular file
1476  *	S_IFDIR		to create directory
1477  *	S_IFBLK		to create block device
1478  *	S_IFCHR		to create character device
1479  *	S_IFLNK		to create symbolic link
1480  *	S_IFIFO		to create FIFO
1481  *	S_IFSOCK	to create socket
1482  * other values are invalid.
1483  *
1484  * @dev is used only if @type is S_IFBLK or S_IFCHR, in other cases its value
1485  * ignored.
1486  *
1487  * @target and @target_len are used only if @type is S_IFLNK, in other cases
1488  * their value ignored.
1489  *
1490  * Return opened ntfs inode that describes created object on success or NULL
1491  * on error with errno set to the error code.
1492  */
__ntfs_create(ntfs_inode * dir_ni,le32 securid,const ntfschar * name,u8 name_len,mode_t type,dev_t dev,const ntfschar * target,int target_len)1493 static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
1494 		const ntfschar *name, u8 name_len, mode_t type, dev_t dev,
1495 		const ntfschar *target, int target_len)
1496 {
1497 	ntfs_inode *ni;
1498 	int rollback_data = 0, rollback_sd = 0;
1499 	FILE_NAME_ATTR *fn = NULL;
1500 	STANDARD_INFORMATION *si = NULL;
1501 	int err, fn_len, si_len;
1502 
1503 	ntfs_log_trace("Entering.\n");
1504 
1505 	/* Sanity checks. */
1506 	if (!dir_ni || !name || !name_len) {
1507 		ntfs_log_error("Invalid arguments.\n");
1508 		errno = EINVAL;
1509 		return NULL;
1510 	}
1511 
1512 	if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
1513 		errno = EOPNOTSUPP;
1514 		return NULL;
1515 	}
1516 
1517 	ni = ntfs_mft_record_alloc(dir_ni->vol, NULL);
1518 	if (!ni)
1519 		return NULL;
1520 #if CACHE_NIDATA_SIZE
1521 	ntfs_inode_invalidate(dir_ni->vol, ni->mft_no);
1522 #endif
1523 	/*
1524 	 * Create STANDARD_INFORMATION attribute.
1525 	 * JPA Depending on available inherited security descriptor,
1526 	 * Write STANDARD_INFORMATION v1.2 (no inheritance) or v3
1527 	 */
1528 	if (securid)
1529 		si_len = sizeof(STANDARD_INFORMATION);
1530 	else
1531 		si_len = offsetof(STANDARD_INFORMATION, v1_end);
1532 	si = ntfs_calloc(si_len);
1533 	if (!si) {
1534 		err = errno;
1535 		goto err_out;
1536 	}
1537 	si->creation_time = ni->creation_time;
1538 	si->last_data_change_time = ni->last_data_change_time;
1539 	si->last_mft_change_time = ni->last_mft_change_time;
1540 	si->last_access_time = ni->last_access_time;
1541 	if (securid) {
1542 		set_nino_flag(ni, v3_Extensions);
1543 		ni->owner_id = si->owner_id = const_cpu_to_le32(0);
1544 		ni->security_id = si->security_id = securid;
1545 		ni->quota_charged = si->quota_charged = const_cpu_to_le64(0);
1546 		ni->usn = si->usn = const_cpu_to_le64(0);
1547 	} else
1548 		clear_nino_flag(ni, v3_Extensions);
1549 	if (!S_ISREG(type) && !S_ISDIR(type)) {
1550 		si->file_attributes = FILE_ATTR_SYSTEM;
1551 		ni->flags = FILE_ATTR_SYSTEM;
1552 	}
1553 	ni->flags |= FILE_ATTR_ARCHIVE;
1554 	if (NVolHideDotFiles(dir_ni->vol)
1555 	    && (name_len > 1)
1556 	    && (name[0] == const_cpu_to_le16('.'))
1557 	    && (name[1] != const_cpu_to_le16('.')))
1558 		ni->flags |= FILE_ATTR_HIDDEN;
1559 		/*
1560 		 * Set compression flag according to parent directory
1561 		 * unless NTFS version < 3.0 or cluster size > 4K
1562 		 * or compression has been disabled
1563 		 */
1564 	if ((dir_ni->flags & FILE_ATTR_COMPRESSED)
1565 	   && (dir_ni->vol->major_ver >= 3)
1566 	   && NVolCompression(dir_ni->vol)
1567 	   && (dir_ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE)
1568 	   && (S_ISREG(type) || S_ISDIR(type)))
1569 		ni->flags |= FILE_ATTR_COMPRESSED;
1570 	/* Add STANDARD_INFORMATION to inode. */
1571 	if (ntfs_attr_add(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0,
1572 			(u8*)si, si_len)) {
1573 		err = errno;
1574 		ntfs_log_error("Failed to add STANDARD_INFORMATION "
1575 				"attribute.\n");
1576 		goto err_out;
1577 	}
1578 
1579 	if (!securid) {
1580 		if (ntfs_sd_add_everyone(ni)) {
1581 			err = errno;
1582 			goto err_out;
1583 		}
1584 	}
1585 	rollback_sd = 1;
1586 
1587 	if (S_ISDIR(type)) {
1588 		INDEX_ROOT *ir = NULL;
1589 		INDEX_ENTRY *ie;
1590 		int ir_len, index_len;
1591 
1592 		/* Create INDEX_ROOT attribute. */
1593 		index_len = sizeof(INDEX_HEADER) + sizeof(INDEX_ENTRY_HEADER);
1594 		ir_len = offsetof(INDEX_ROOT, index) + index_len;
1595 		ir = ntfs_calloc(ir_len);
1596 		if (!ir) {
1597 			err = errno;
1598 			goto err_out;
1599 		}
1600 		ir->type = AT_FILE_NAME;
1601 		ir->collation_rule = COLLATION_FILE_NAME;
1602 		ir->index_block_size = cpu_to_le32(ni->vol->indx_record_size);
1603 		if (ni->vol->cluster_size <= ni->vol->indx_record_size)
1604 			ir->clusters_per_index_block =
1605 					ni->vol->indx_record_size >>
1606 					ni->vol->cluster_size_bits;
1607 		else
1608 			ir->clusters_per_index_block =
1609 					ni->vol->indx_record_size >>
1610 					NTFS_BLOCK_SIZE_BITS;
1611 		ir->index.entries_offset = const_cpu_to_le32(sizeof(INDEX_HEADER));
1612 		ir->index.index_length = cpu_to_le32(index_len);
1613 		ir->index.allocated_size = cpu_to_le32(index_len);
1614 		ie = (INDEX_ENTRY*)((u8*)ir + sizeof(INDEX_ROOT));
1615 		ie->length = const_cpu_to_le16(sizeof(INDEX_ENTRY_HEADER));
1616 		ie->key_length = const_cpu_to_le16(0);
1617 		ie->ie_flags = INDEX_ENTRY_END;
1618 		/* Add INDEX_ROOT attribute to inode. */
1619 		if (ntfs_attr_add(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4,
1620 				(u8*)ir, ir_len)) {
1621 			err = errno;
1622 			free(ir);
1623 			ntfs_log_error("Failed to add INDEX_ROOT attribute.\n");
1624 			goto err_out;
1625 		}
1626 		free(ir);
1627 	} else {
1628 		INTX_FILE *data;
1629 		int data_len;
1630 
1631 		switch (type) {
1632 			case S_IFBLK:
1633 			case S_IFCHR:
1634 				data_len = offsetof(INTX_FILE, device_end);
1635 				data = ntfs_malloc(data_len);
1636 				if (!data) {
1637 					err = errno;
1638 					goto err_out;
1639 				}
1640 				data->major = cpu_to_le64(major(dev));
1641 				data->minor = cpu_to_le64(minor(dev));
1642 				if (type == S_IFBLK)
1643 					data->magic = INTX_BLOCK_DEVICE;
1644 				if (type == S_IFCHR)
1645 					data->magic = INTX_CHARACTER_DEVICE;
1646 				break;
1647 			case S_IFLNK:
1648 				data_len = sizeof(INTX_FILE_TYPES) +
1649 						target_len * sizeof(ntfschar);
1650 				data = ntfs_malloc(data_len);
1651 				if (!data) {
1652 					err = errno;
1653 					goto err_out;
1654 				}
1655 				data->magic = INTX_SYMBOLIC_LINK;
1656 				memcpy(data->target, target,
1657 						target_len * sizeof(ntfschar));
1658 				break;
1659 			case S_IFSOCK:
1660 				data = NULL;
1661 				data_len = 1;
1662 				break;
1663 			default: /* FIFO or regular file. */
1664 				data = NULL;
1665 				data_len = 0;
1666 				break;
1667 		}
1668 		/* Add DATA attribute to inode. */
1669 		if (ntfs_attr_add(ni, AT_DATA, AT_UNNAMED, 0, (u8*)data,
1670 				data_len)) {
1671 			err = errno;
1672 			ntfs_log_error("Failed to add DATA attribute.\n");
1673 			free(data);
1674 			goto err_out;
1675 		}
1676 		rollback_data = 1;
1677 		free(data);
1678 	}
1679 	/* Create FILE_NAME attribute. */
1680 	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
1681 	fn = ntfs_calloc(fn_len);
1682 	if (!fn) {
1683 		err = errno;
1684 		goto err_out;
1685 	}
1686 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
1687 			le16_to_cpu(dir_ni->mrec->sequence_number));
1688 	fn->file_name_length = name_len;
1689 	fn->file_name_type = FILE_NAME_POSIX;
1690 	if (S_ISDIR(type))
1691 		fn->file_attributes = FILE_ATTR_I30_INDEX_PRESENT;
1692 	if (!S_ISREG(type) && !S_ISDIR(type))
1693 		fn->file_attributes = FILE_ATTR_SYSTEM;
1694 	else
1695 		fn->file_attributes |= ni->flags & FILE_ATTR_COMPRESSED;
1696 	fn->file_attributes |= FILE_ATTR_ARCHIVE;
1697 	fn->file_attributes |= ni->flags & FILE_ATTR_HIDDEN;
1698 	fn->creation_time = ni->creation_time;
1699 	fn->last_data_change_time = ni->last_data_change_time;
1700 	fn->last_mft_change_time = ni->last_mft_change_time;
1701 	fn->last_access_time = ni->last_access_time;
1702 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
1703 		fn->data_size = fn->allocated_size = const_cpu_to_sle64(0);
1704 	else {
1705 		fn->data_size = cpu_to_sle64(ni->data_size);
1706 		fn->allocated_size = cpu_to_sle64(ni->allocated_size);
1707 	}
1708 	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
1709 	/* Add FILE_NAME attribute to inode. */
1710 	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
1711 		err = errno;
1712 		ntfs_log_error("Failed to add FILE_NAME attribute.\n");
1713 		goto err_out;
1714 	}
1715 	/* Add FILE_NAME attribute to index. */
1716 	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
1717 			le16_to_cpu(ni->mrec->sequence_number)))) {
1718 		err = errno;
1719 		ntfs_log_perror("Failed to add entry to the index");
1720 		goto err_out;
1721 	}
1722 	/* Set hard links count and directory flag. */
1723 	ni->mrec->link_count = const_cpu_to_le16(1);
1724 	if (S_ISDIR(type))
1725 		ni->mrec->flags |= MFT_RECORD_IS_DIRECTORY;
1726 	ntfs_inode_mark_dirty(ni);
1727 	/* Done! */
1728 	free(fn);
1729 	free(si);
1730 	ntfs_log_trace("Done.\n");
1731 	return ni;
1732 err_out:
1733 	ntfs_log_trace("Failed.\n");
1734 
1735 	if (rollback_sd)
1736 		ntfs_attr_remove(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0);
1737 
1738 	if (rollback_data)
1739 		ntfs_attr_remove(ni, AT_DATA, AT_UNNAMED, 0);
1740 	/*
1741 	 * Free extent MFT records (should not exist any with current
1742 	 * ntfs_create implementation, but for any case if something will be
1743 	 * changed in the future).
1744 	 */
1745 	while (ni->nr_extents)
1746 		if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) {
1747 			err = errno;
1748 			ntfs_log_error("Failed to free extent MFT record.  "
1749 					"Leaving inconsistent metadata.\n");
1750 		}
1751 	if (ntfs_mft_record_free(ni->vol, ni))
1752 		ntfs_log_error("Failed to free MFT record.  "
1753 				"Leaving inconsistent metadata. Run chkdsk.\n");
1754 	free(fn);
1755 	free(si);
1756 	errno = err;
1757 	return NULL;
1758 }
1759 
1760 /**
1761  * Some wrappers around __ntfs_create() ...
1762  */
1763 
ntfs_create(ntfs_inode * dir_ni,le32 securid,const ntfschar * name,u8 name_len,mode_t type)1764 ntfs_inode *ntfs_create(ntfs_inode *dir_ni, le32 securid, const ntfschar *name,
1765 		u8 name_len, mode_t type)
1766 {
1767 	if (type != S_IFREG && type != S_IFDIR && type != S_IFIFO &&
1768 			type != S_IFSOCK) {
1769 		ntfs_log_error("Invalid arguments.\n");
1770 		return NULL;
1771 	}
1772 	return __ntfs_create(dir_ni, securid, name, name_len, type, 0, NULL, 0);
1773 }
1774 
ntfs_create_device(ntfs_inode * dir_ni,le32 securid,const ntfschar * name,u8 name_len,mode_t type,dev_t dev)1775 ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, le32 securid,
1776 		const ntfschar *name, u8 name_len, mode_t type, dev_t dev)
1777 {
1778 	if (type != S_IFCHR && type != S_IFBLK) {
1779 		ntfs_log_error("Invalid arguments.\n");
1780 		return NULL;
1781 	}
1782 	return __ntfs_create(dir_ni, securid, name, name_len, type, dev, NULL, 0);
1783 }
1784 
ntfs_create_symlink(ntfs_inode * dir_ni,le32 securid,const ntfschar * name,u8 name_len,const ntfschar * target,int target_len)1785 ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, le32 securid,
1786 		const ntfschar *name, u8 name_len, const ntfschar *target,
1787 		int target_len)
1788 {
1789 	if (!target || !target_len) {
1790 		ntfs_log_error("%s: Invalid argument (%p, %d)\n", __FUNCTION__,
1791 			       target, target_len);
1792 		return NULL;
1793 	}
1794 	return __ntfs_create(dir_ni, securid, name, name_len, S_IFLNK, 0,
1795 			target, target_len);
1796 }
1797 
ntfs_check_empty_dir(ntfs_inode * ni)1798 int ntfs_check_empty_dir(ntfs_inode *ni)
1799 {
1800 	ntfs_attr *na;
1801 	int ret = 0;
1802 
1803 	if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY))
1804 		return 0;
1805 
1806 	na = ntfs_attr_open(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4);
1807 	if (!na) {
1808 		errno = EIO;
1809 		ntfs_log_perror("Failed to open directory");
1810 		return -1;
1811 	}
1812 
1813 	/* Non-empty directory? */
1814 	if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER))){
1815 		/* Both ENOTEMPTY and EEXIST are ok. We use the more common. */
1816 		errno = ENOTEMPTY;
1817 		ntfs_log_debug("Directory is not empty\n");
1818 		ret = -1;
1819 	}
1820 
1821 	ntfs_attr_close(na);
1822 	return ret;
1823 }
1824 
ntfs_check_unlinkable_dir(ntfs_inode * ni,FILE_NAME_ATTR * fn)1825 static int ntfs_check_unlinkable_dir(ntfs_inode *ni, FILE_NAME_ATTR *fn)
1826 {
1827 	int link_count = le16_to_cpu(ni->mrec->link_count);
1828 	int ret;
1829 
1830 	ret = ntfs_check_empty_dir(ni);
1831 	if (!ret || errno != ENOTEMPTY)
1832 		return ret;
1833 	/*
1834 	 * Directory is non-empty, so we can unlink only if there is more than
1835 	 * one "real" hard link, i.e. links aren't different DOS and WIN32 names
1836 	 */
1837 	if ((link_count == 1) ||
1838 	    (link_count == 2 && fn->file_name_type == FILE_NAME_DOS)) {
1839 		errno = ENOTEMPTY;
1840 		ntfs_log_debug("Non-empty directory without hard links\n");
1841 		goto no_hardlink;
1842 	}
1843 
1844 	ret = 0;
1845 no_hardlink:
1846 	return ret;
1847 }
1848 
1849 /**
1850  * ntfs_delete - delete file or directory from ntfs volume
1851  * @ni:		ntfs inode for object to delte
1852  * @dir_ni:	ntfs inode for directory in which delete object
1853  * @name:	unicode name of the object to delete
1854  * @name_len:	length of the name in unicode characters
1855  *
1856  * @ni is always closed after the call to this function (even if it failed),
1857  * user does not need to call ntfs_inode_close himself.
1858  *
1859  * Return 0 on success or -1 on error with errno set to the error code.
1860  */
ntfs_delete(ntfs_volume * vol,const char * pathname,ntfs_inode * ni,ntfs_inode * dir_ni,const ntfschar * name,u8 name_len)1861 int ntfs_delete(ntfs_volume *vol, const char *pathname,
1862 		ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
1863 		u8 name_len)
1864 {
1865 	ntfs_attr_search_ctx *actx = NULL;
1866 	FILE_NAME_ATTR *fn = NULL;
1867 	BOOL looking_for_dos_name = FALSE, looking_for_win32_name = FALSE;
1868 	BOOL case_sensitive_match = TRUE;
1869 	int err = 0;
1870 #if CACHE_NIDATA_SIZE
1871 	int i;
1872 #endif
1873 #if CACHE_INODE_SIZE
1874 	struct CACHED_INODE item;
1875 	const char *p;
1876 	u64 inum = (u64)-1;
1877 	int count;
1878 #endif
1879 #if CACHE_LOOKUP_SIZE
1880 	struct CACHED_LOOKUP lkitem;
1881 #endif
1882 
1883 	ntfs_log_trace("Entering.\n");
1884 
1885 	if (!ni || !dir_ni || !name || !name_len) {
1886 		ntfs_log_error("Invalid arguments.\n");
1887 		errno = EINVAL;
1888 		goto err_out;
1889 	}
1890 	if (ni->nr_extents == -1)
1891 		ni = ni->base_ni;
1892 	if (dir_ni->nr_extents == -1)
1893 		dir_ni = dir_ni->base_ni;
1894 	/*
1895 	 * Search for FILE_NAME attribute with such name. If it's in POSIX or
1896 	 * WIN32_AND_DOS namespace, then simply remove it from index and inode.
1897 	 * If filename in DOS or in WIN32 namespace, then remove DOS name first,
1898 	 * only then remove WIN32 name.
1899 	 */
1900 	actx = ntfs_attr_get_search_ctx(ni, NULL);
1901 	if (!actx)
1902 		goto err_out;
1903 search:
1904 	while (!(err = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
1905 					CASE_SENSITIVE, 0, NULL, 0, actx))) {
1906 	#ifdef DEBUG
1907 		char *s;
1908 	#endif
1909 		IGNORE_CASE_BOOL case_sensitive = IGNORE_CASE;
1910 
1911 		fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
1912 				le16_to_cpu(actx->attr->value_offset));
1913 	#ifdef DEBUG
1914 		s = ntfs_attr_name_get(fn->file_name, fn->file_name_length);
1915 		ntfs_log_trace("name: '%s'  type: %d  dos: %d  win32: %d  "
1916 			       "case: %d\n", s, fn->file_name_type,
1917 			       looking_for_dos_name, looking_for_win32_name,
1918 			       case_sensitive_match);
1919 		ntfs_attr_name_free(&s);
1920 	#endif
1921 		if (looking_for_dos_name) {
1922 			if (fn->file_name_type == FILE_NAME_DOS)
1923 				break;
1924 			else
1925 				continue;
1926 		}
1927 		if (looking_for_win32_name) {
1928 			if  (fn->file_name_type == FILE_NAME_WIN32)
1929 				break;
1930 			else
1931 				continue;
1932 		}
1933 
1934 		/* Ignore hard links from other directories */
1935 		if (dir_ni->mft_no != MREF_LE(fn->parent_directory)) {
1936 			ntfs_log_debug("MFT record numbers don't match "
1937 				       "(%llu != %llu)\n",
1938 				       (long long unsigned)dir_ni->mft_no,
1939 				       (long long unsigned)MREF_LE(fn->parent_directory));
1940 			continue;
1941 		}
1942 		if (case_sensitive_match
1943 		    || ((fn->file_name_type == FILE_NAME_POSIX)
1944 			&& NVolCaseSensitive(ni->vol)))
1945 			case_sensitive = CASE_SENSITIVE;
1946 
1947 		if (ntfs_names_are_equal(fn->file_name, fn->file_name_length,
1948 					 name, name_len, case_sensitive,
1949 					 ni->vol->upcase, ni->vol->upcase_len)){
1950 
1951 			if (fn->file_name_type == FILE_NAME_WIN32) {
1952 				looking_for_dos_name = TRUE;
1953 				ntfs_attr_reinit_search_ctx(actx);
1954 				continue;
1955 			}
1956 			if (fn->file_name_type == FILE_NAME_DOS)
1957 				looking_for_dos_name = TRUE;
1958 			break;
1959 		}
1960 	}
1961 	if (err) {
1962 		/*
1963 		 * If case sensitive search failed, then try once again
1964 		 * ignoring case.
1965 		 */
1966 		if (errno == ENOENT && case_sensitive_match) {
1967 			case_sensitive_match = FALSE;
1968 			ntfs_attr_reinit_search_ctx(actx);
1969 			goto search;
1970 		}
1971 		goto err_out;
1972 	}
1973 
1974 	if (ntfs_check_unlinkable_dir(ni, fn) < 0)
1975 		goto err_out;
1976 
1977 	if (ntfs_index_remove(dir_ni, ni, fn, le32_to_cpu(actx->attr->value_length)))
1978 		goto err_out;
1979 
1980 	/*
1981 	 * Keep the last name in place, this is useful for undeletion
1982 	 * (Windows also does so), however delete the name if it were
1983 	 * in an extent, to avoid leaving an attribute list.
1984 	 */
1985 	if ((ni->mrec->link_count == const_cpu_to_le16(1)) && !actx->base_ntfs_ino) {
1986 			/* make sure to not loop to another search */
1987 		looking_for_dos_name = FALSE;
1988 	} else {
1989 		if (ntfs_attr_record_rm(actx))
1990 			goto err_out;
1991 	}
1992 
1993 	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
1994 			ni->mrec->link_count) - 1);
1995 
1996 	ntfs_inode_mark_dirty(ni);
1997 	if (looking_for_dos_name) {
1998 		looking_for_dos_name = FALSE;
1999 		looking_for_win32_name = TRUE;
2000 		ntfs_attr_reinit_search_ctx(actx);
2001 		goto search;
2002 	}
2003 	/* TODO: Update object id, quota and securiry indexes if required. */
2004 	/*
2005 	 * If hard link count is not equal to zero then we are done. In other
2006 	 * case there are no reference to this inode left, so we should free all
2007 	 * non-resident attributes and mark all MFT record as not in use.
2008 	 */
2009 #if CACHE_LOOKUP_SIZE
2010 			/* invalidate entry in lookup cache */
2011 	lkitem.name = (const char*)NULL;
2012 	lkitem.namesize = 0;
2013 	lkitem.inum = ni->mft_no;
2014 	lkitem.parent = dir_ni->mft_no;
2015 	ntfs_invalidate_cache(vol->lookup_cache, GENERIC(&lkitem),
2016 			lookup_cache_inv_compare, CACHE_NOHASH);
2017 #endif
2018 #if CACHE_INODE_SIZE
2019 	inum = ni->mft_no;
2020 	if (pathname) {
2021 			/* invalide cache entry, even if there was an error */
2022 		/* Remove leading /'s. */
2023 		p = pathname;
2024 		while (*p == PATH_SEP)
2025 			p++;
2026 		if (p[0] && (p[strlen(p)-1] == PATH_SEP))
2027 			ntfs_log_error("Unnormalized path %s\n",pathname);
2028 		item.pathname = p;
2029 		item.varsize = strlen(p);
2030 	} else {
2031 		item.pathname = (const char*)NULL;
2032 		item.varsize = 0;
2033 	}
2034 	item.inum = inum;
2035 	count = ntfs_invalidate_cache(vol->xinode_cache, GENERIC(&item),
2036 				inode_cache_inv_compare, CACHE_NOHASH);
2037 	if (pathname && !count)
2038 		ntfs_log_error("Could not delete inode cache entry for %s\n",
2039 			pathname);
2040 #endif
2041 	if (ni->mrec->link_count) {
2042 		ntfs_inode_update_times(ni, NTFS_UPDATE_CTIME);
2043 		goto ok;
2044 	}
2045 	if (ntfs_delete_reparse_index(ni)) {
2046 		/*
2047 		 * Failed to remove the reparse index : proceed anyway
2048 		 * This is not a critical error, the entry is useless
2049 		 * because of sequence_number, and stopping file deletion
2050 		 * would be much worse as the file is not referenced now.
2051 		 */
2052 		err = errno;
2053 	}
2054 	if (ntfs_delete_object_id_index(ni)) {
2055 		/*
2056 		 * Failed to remove the object id index : proceed anyway
2057 		 * This is not a critical error.
2058 		 */
2059 		err = errno;
2060 	}
2061 	ntfs_attr_reinit_search_ctx(actx);
2062 	while (!ntfs_attrs_walk(actx)) {
2063 		if (actx->attr->non_resident) {
2064 			runlist *rl;
2065 
2066 			rl = ntfs_mapping_pairs_decompress(ni->vol, actx->attr,
2067 					NULL);
2068 			if (!rl) {
2069 				err = errno;
2070 				ntfs_log_error("Failed to decompress runlist.  "
2071 						"Leaving inconsistent metadata.\n");
2072 				continue;
2073 			}
2074 			if (ntfs_cluster_free_from_rl(ni->vol, rl)) {
2075 				err = errno;
2076 				ntfs_log_error("Failed to free clusters.  "
2077 						"Leaving inconsistent metadata.\n");
2078 				continue;
2079 			}
2080 			free(rl);
2081 		}
2082 	}
2083 	if (errno != ENOENT) {
2084 		err = errno;
2085 		ntfs_log_error("Attribute enumeration failed.  "
2086 				"Probably leaving inconsistent metadata.\n");
2087 	}
2088 	/* All extents should be attached after attribute walk. */
2089 #if CACHE_NIDATA_SIZE
2090 		/*
2091 		 * Disconnect extents before deleting them, so they are
2092 		 * not wrongly moved to cache through the chainings
2093 		 */
2094 	for (i=ni->nr_extents-1; i>=0; i--) {
2095 		ni->extent_nis[i]->base_ni = (ntfs_inode*)NULL;
2096 		ni->extent_nis[i]->nr_extents = 0;
2097 		if (ntfs_mft_record_free(ni->vol, ni->extent_nis[i])) {
2098 			err = errno;
2099 			ntfs_log_error("Failed to free extent MFT record.  "
2100 					"Leaving inconsistent metadata.\n");
2101 		}
2102 	}
2103 	free(ni->extent_nis);
2104 	ni->nr_extents = 0;
2105 	ni->extent_nis = (ntfs_inode**)NULL;
2106 #else
2107 	while (ni->nr_extents)
2108 		if (ntfs_mft_record_free(ni->vol, *(ni->extent_nis))) {
2109 			err = errno;
2110 			ntfs_log_error("Failed to free extent MFT record.  "
2111 					"Leaving inconsistent metadata.\n");
2112 		}
2113 #endif
2114 	debug_double_inode(ni->mft_no,0);
2115 	if (ntfs_mft_record_free(ni->vol, ni)) {
2116 		err = errno;
2117 		ntfs_log_error("Failed to free base MFT record.  "
2118 				"Leaving inconsistent metadata.\n");
2119 	}
2120 	ni = NULL;
2121 ok:
2122 	ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME);
2123 out:
2124 	if (actx)
2125 		ntfs_attr_put_search_ctx(actx);
2126 	if (ntfs_inode_close(dir_ni) && !err)
2127 		err = errno;
2128 	if (ntfs_inode_close(ni) && !err)
2129 		err = errno;
2130 	if (err) {
2131 		errno = err;
2132 		ntfs_log_debug("Could not delete file: %s\n", strerror(errno));
2133 		return -1;
2134 	}
2135 	ntfs_log_trace("Done.\n");
2136 	return 0;
2137 err_out:
2138 	err = errno;
2139 	goto out;
2140 }
2141 
2142 /**
2143  * ntfs_link - create hard link for file or directory
2144  * @ni:		ntfs inode for object to create hard link
2145  * @dir_ni:	ntfs inode for directory in which new link should be placed
2146  * @name:	unicode name of the new link
2147  * @name_len:	length of the name in unicode characters
2148  *
2149  * NOTE: At present we allow creating hardlinks to directories, we use them
2150  * in a temporary state during rename. But it's defenitely bad idea to have
2151  * hard links to directories as a result of operation.
2152  * FIXME: Create internal  __ntfs_link that allows hard links to a directories
2153  * and external ntfs_link that do not. Write ntfs_rename that uses __ntfs_link.
2154  *
2155  * Return 0 on success or -1 on error with errno set to the error code.
2156  */
ntfs_link_i(ntfs_inode * ni,ntfs_inode * dir_ni,const ntfschar * name,u8 name_len,FILE_NAME_TYPE_FLAGS nametype)2157 static int ntfs_link_i(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
2158 			 u8 name_len, FILE_NAME_TYPE_FLAGS nametype)
2159 {
2160 	FILE_NAME_ATTR *fn = NULL;
2161 	int fn_len, err;
2162 
2163 	ntfs_log_trace("Entering.\n");
2164 
2165 	if (!ni || !dir_ni || !name || !name_len ||
2166 			ni->mft_no == dir_ni->mft_no) {
2167 		err = EINVAL;
2168 		ntfs_log_perror("ntfs_link wrong arguments");
2169 		goto err_out;
2170 	}
2171 
2172 	if (NVolHideDotFiles(dir_ni->vol)) {
2173 		/* Set hidden flag according to the latest name */
2174 		if ((name_len > 1)
2175 		    && (name[0] == const_cpu_to_le16('.'))
2176 		    && (name[1] != const_cpu_to_le16('.')))
2177 			ni->flags |= FILE_ATTR_HIDDEN;
2178 		else
2179 			ni->flags &= ~FILE_ATTR_HIDDEN;
2180 	}
2181 
2182 	/* Create FILE_NAME attribute. */
2183 	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
2184 	fn = ntfs_calloc(fn_len);
2185 	if (!fn) {
2186 		err = errno;
2187 		goto err_out;
2188 	}
2189 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
2190 			le16_to_cpu(dir_ni->mrec->sequence_number));
2191 	fn->file_name_length = name_len;
2192 	fn->file_name_type = nametype;
2193 	fn->file_attributes = ni->flags;
2194 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
2195 		fn->file_attributes |= FILE_ATTR_I30_INDEX_PRESENT;
2196 		fn->data_size = fn->allocated_size = const_cpu_to_sle64(0);
2197 	} else {
2198 		fn->allocated_size = cpu_to_sle64(ni->allocated_size);
2199 		fn->data_size = cpu_to_sle64(ni->data_size);
2200 	}
2201 	fn->creation_time = ni->creation_time;
2202 	fn->last_data_change_time = ni->last_data_change_time;
2203 	fn->last_mft_change_time = ni->last_mft_change_time;
2204 	fn->last_access_time = ni->last_access_time;
2205 	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
2206 	/* Add FILE_NAME attribute to index. */
2207 	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
2208 			le16_to_cpu(ni->mrec->sequence_number)))) {
2209 		err = errno;
2210 		ntfs_log_perror("Failed to add filename to the index");
2211 		goto err_out;
2212 	}
2213 	/* Add FILE_NAME attribute to inode. */
2214 	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
2215 		ntfs_log_error("Failed to add FILE_NAME attribute.\n");
2216 		err = errno;
2217 		/* Try to remove just added attribute from index. */
2218 		if (ntfs_index_remove(dir_ni, ni, fn, fn_len))
2219 			goto rollback_failed;
2220 		goto err_out;
2221 	}
2222 	/* Increment hard links count. */
2223 	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
2224 			ni->mrec->link_count) + 1);
2225 	/* Done! */
2226 	ntfs_inode_mark_dirty(ni);
2227 	free(fn);
2228 	ntfs_log_trace("Done.\n");
2229 	return 0;
2230 rollback_failed:
2231 	ntfs_log_error("Rollback failed. Leaving inconsistent metadata.\n");
2232 err_out:
2233 	free(fn);
2234 	errno = err;
2235 	return -1;
2236 }
2237 
ntfs_link(ntfs_inode * ni,ntfs_inode * dir_ni,const ntfschar * name,u8 name_len)2238 int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, const ntfschar *name,
2239 		u8 name_len)
2240 {
2241 	return (ntfs_link_i(ni, dir_ni, name, name_len, FILE_NAME_POSIX));
2242 }
2243 
2244 /*
2245  *		Get a parent directory from an inode entry
2246  *
2247  *	This is only used in situations where the path used to access
2248  *	the current file is not known for sure. The result may be different
2249  *	from the path when the file is linked in several parent directories.
2250  *
2251  *	Currently this is only used for translating ".." in the target
2252  *	of a Vista relative symbolic link
2253  */
2254 
ntfs_dir_parent_inode(ntfs_inode * ni)2255 ntfs_inode *ntfs_dir_parent_inode(ntfs_inode *ni)
2256 {
2257 	ntfs_inode *dir_ni = (ntfs_inode*)NULL;
2258 	u64 inum;
2259 	FILE_NAME_ATTR *fn;
2260 	ntfs_attr_search_ctx *ctx;
2261 
2262 	if (ni->mft_no != FILE_root) {
2263 			/* find the name in the attributes */
2264 		ctx = ntfs_attr_get_search_ctx(ni, NULL);
2265 		if (!ctx)
2266 			return ((ntfs_inode*)NULL);
2267 
2268 		if (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
2269 				CASE_SENSITIVE,	0, NULL, 0, ctx)) {
2270 			/* We know this will always be resident. */
2271 			fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2272 					le16_to_cpu(ctx->attr->value_offset));
2273 			inum = le64_to_cpu(fn->parent_directory);
2274 			if (inum != (u64)-1) {
2275 				dir_ni = ntfs_inode_open(ni->vol, MREF(inum));
2276 			}
2277 		}
2278 		ntfs_attr_put_search_ctx(ctx);
2279 	}
2280 	return (dir_ni);
2281 }
2282 
2283 #define MAX_DOS_NAME_LENGTH	 12
2284 
2285 /*
2286  *		Get a DOS name for a file in designated directory
2287  *
2288  *	Not allowed if there are several non-dos names (EMLINK)
2289  *
2290  *	Returns size if found
2291  *		0 if not found
2292  *		-1 if there was an error (described by errno)
2293  */
2294 
get_dos_name(ntfs_inode * ni,u64 dnum,ntfschar * dosname)2295 static int get_dos_name(ntfs_inode *ni, u64 dnum, ntfschar *dosname)
2296 {
2297 	size_t outsize = 0;
2298 	int namecount = 0;
2299 	FILE_NAME_ATTR *fn;
2300 	ntfs_attr_search_ctx *ctx;
2301 
2302 		/* find the name in the attributes */
2303 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
2304 	if (!ctx)
2305 		return -1;
2306 
2307 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2308 			0, NULL, 0, ctx)) {
2309 		/* We know this will always be resident. */
2310 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2311 				le16_to_cpu(ctx->attr->value_offset));
2312 
2313 		if (fn->file_name_type != FILE_NAME_DOS)
2314 			namecount++;
2315 		if ((fn->file_name_type & FILE_NAME_DOS)
2316 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2317 				/*
2318 				 * Found a DOS or WIN32+DOS name for the entry
2319 				 * copy name, after truncation for safety
2320 				 */
2321 			outsize = fn->file_name_length;
2322 /* TODO : reject if name is too long ? */
2323 			if (outsize > MAX_DOS_NAME_LENGTH)
2324 				outsize = MAX_DOS_NAME_LENGTH;
2325 			memcpy(dosname,fn->file_name,outsize*sizeof(ntfschar));
2326 		}
2327 	}
2328 	ntfs_attr_put_search_ctx(ctx);
2329 	if ((outsize > 0) && (namecount > 1)) {
2330 		outsize = -1;
2331 		errno = EMLINK; /* this error implies there is a dos name */
2332 	}
2333 	return (outsize);
2334 }
2335 
2336 
2337 /*
2338  *		Get a long name for a file in designated directory
2339  *
2340  *	Not allowed if there are several non-dos names (EMLINK)
2341  *
2342  *	Returns size if found
2343  *		0 if not found
2344  *		-1 if there was an error (described by errno)
2345  */
2346 
get_long_name(ntfs_inode * ni,u64 dnum,ntfschar * longname)2347 static int get_long_name(ntfs_inode *ni, u64 dnum, ntfschar *longname)
2348 {
2349 	size_t outsize = 0;
2350 	int namecount = 0;
2351 	FILE_NAME_ATTR *fn;
2352 	ntfs_attr_search_ctx *ctx;
2353 
2354 		/* find the name in the attributes */
2355 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
2356 	if (!ctx)
2357 		return -1;
2358 
2359 		/* first search for WIN32 or DOS+WIN32 names */
2360 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2361 			0, NULL, 0, ctx)) {
2362 		/* We know this will always be resident. */
2363 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2364 				le16_to_cpu(ctx->attr->value_offset));
2365 
2366 		if (fn->file_name_type != FILE_NAME_DOS)
2367 			namecount++;
2368 		if ((fn->file_name_type & FILE_NAME_WIN32)
2369 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2370 				/*
2371 				 * Found a WIN32 or WIN32+DOS name for the entry
2372 				 * copy name
2373 				 */
2374 			outsize = fn->file_name_length;
2375 			memcpy(longname,fn->file_name,outsize*sizeof(ntfschar));
2376 		}
2377 	}
2378 	if (namecount > 1) {
2379 		ntfs_attr_put_search_ctx(ctx);
2380 		errno = EMLINK;
2381 		return -1;
2382 	}
2383 		/* if not found search for POSIX names */
2384 	if (!outsize) {
2385 		ntfs_attr_reinit_search_ctx(ctx);
2386 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
2387 			0, NULL, 0, ctx)) {
2388 		/* We know this will always be resident. */
2389 		fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
2390 				le16_to_cpu(ctx->attr->value_offset));
2391 
2392 		if ((fn->file_name_type == FILE_NAME_POSIX)
2393 		    && (MREF_LE(fn->parent_directory) == dnum)) {
2394 				/*
2395 				 * Found a POSIX name for the entry
2396 				 * copy name
2397 				 */
2398 			outsize = fn->file_name_length;
2399 			memcpy(longname,fn->file_name,outsize*sizeof(ntfschar));
2400 		}
2401 	}
2402 	}
2403 	ntfs_attr_put_search_ctx(ctx);
2404 	return (outsize);
2405 }
2406 
2407 
2408 /*
2409  *		Get the ntfs DOS name into an extended attribute
2410  */
2411 
ntfs_get_ntfs_dos_name(ntfs_inode * ni,ntfs_inode * dir_ni,char * value,size_t size)2412 int ntfs_get_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2413 			char *value, size_t size)
2414 {
2415 	int outsize = 0;
2416 	char *outname = (char*)NULL;
2417 	u64 dnum;
2418 	int doslen;
2419 	ntfschar dosname[MAX_DOS_NAME_LENGTH];
2420 
2421 	dnum = dir_ni->mft_no;
2422 	doslen = get_dos_name(ni, dnum, dosname);
2423 	if (doslen > 0) {
2424 			/*
2425 			 * Found a DOS name for the entry, make
2426 			 * uppercase and encode into the buffer
2427 			 * if there is enough space
2428 			 */
2429 		ntfs_name_upcase(dosname, doslen,
2430 				ni->vol->upcase, ni->vol->upcase_len);
2431 		outsize = ntfs_ucstombs(dosname, doslen, &outname, 0);
2432 		if (outsize < 0) {
2433 			ntfs_log_error("Cannot represent dosname in current locale.\n");
2434 			outsize = -errno;
2435 		} else {
2436 			if (value && (outsize <= (int)size))
2437 				memcpy(value, outname, outsize);
2438 			else
2439 				if (size && (outsize > (int)size))
2440 					outsize = -ERANGE;
2441 			free(outname);
2442 		}
2443 	} else {
2444 		if (doslen == 0)
2445 			errno = ENODATA;
2446 		outsize = -errno;
2447 	}
2448 	return (outsize);
2449 }
2450 
2451 /*
2452  *		Change the name space of an existing file or directory
2453  *
2454  *	Returns the old namespace if successful
2455  *		-1 if an error occurred (described by errno)
2456  */
2457 
set_namespace(ntfs_inode * ni,ntfs_inode * dir_ni,const ntfschar * name,int len,FILE_NAME_TYPE_FLAGS nametype)2458 static int set_namespace(ntfs_inode *ni, ntfs_inode *dir_ni,
2459 			const ntfschar *name, int len,
2460 			FILE_NAME_TYPE_FLAGS nametype)
2461 {
2462 	ntfs_attr_search_ctx *actx;
2463 	ntfs_index_context *icx;
2464 	FILE_NAME_ATTR *fnx;
2465 	FILE_NAME_ATTR *fn = NULL;
2466 	BOOL found;
2467 	int lkup;
2468 	int ret;
2469 
2470 	ret = -1;
2471 	actx = ntfs_attr_get_search_ctx(ni, NULL);
2472 	if (actx) {
2473 		found = FALSE;
2474 		do {
2475 			lkup = ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0,
2476 	                        CASE_SENSITIVE, 0, NULL, 0, actx);
2477 			if (!lkup) {
2478 				fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
2479 				     le16_to_cpu(actx->attr->value_offset));
2480 				found = (MREF_LE(fn->parent_directory)
2481 						== dir_ni->mft_no)
2482 					&& !memcmp(fn->file_name, name,
2483 						len*sizeof(ntfschar));
2484 			}
2485 		} while (!lkup && !found);
2486 		if (found) {
2487 			icx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4);
2488 			if (icx) {
2489 				lkup = ntfs_index_lookup((char*)fn, len, icx);
2490 				if (!lkup && icx->data && icx->data_len) {
2491 					fnx = (FILE_NAME_ATTR*)icx->data;
2492 					ret = fn->file_name_type;
2493 					fn->file_name_type = nametype;
2494 					fnx->file_name_type = nametype;
2495 					ntfs_inode_mark_dirty(ni);
2496 					ntfs_index_entry_mark_dirty(icx);
2497 				}
2498 			ntfs_index_ctx_put(icx);
2499 			}
2500 		}
2501 		ntfs_attr_put_search_ctx(actx);
2502 	}
2503 	return (ret);
2504 }
2505 
2506 /*
2507  *		Set a DOS name to a file and adjust name spaces
2508  *
2509  *	If the new names are collapsible (same uppercased chars) :
2510  *
2511  * - the existing DOS name or DOS+Win32 name is made Posix
2512  * - if it was a real DOS name, the existing long name is made DOS+Win32
2513  *        and the existing DOS name is deleted
2514  * - finally the existing long name is made DOS+Win32 unless already done
2515  *
2516  *	If the new names are not collapsible :
2517  *
2518  * - insert the short name as a DOS name
2519  * - delete the old long name or existing short name
2520  * - insert the new long name (as a Win32 or DOS+Win32 name)
2521  *
2522  * Deleting the old long name will not delete the file
2523  * provided the old name was in the Posix name space,
2524  * because the alternate name has been set before.
2525  *
2526  * The inodes of file and parent directory are always closed
2527  *
2528  * Returns 0 if successful
2529  *	   -1 if failed
2530  */
2531 
set_dos_name(ntfs_inode * ni,ntfs_inode * dir_ni,const ntfschar * shortname,int shortlen,const ntfschar * longname,int longlen,const ntfschar * deletename,int deletelen,BOOL existed)2532 static int set_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2533 			const ntfschar *shortname, int shortlen,
2534 			const ntfschar *longname, int longlen,
2535 			const ntfschar *deletename, int deletelen, BOOL existed)
2536 {
2537 	unsigned int linkcount;
2538 	ntfs_volume *vol;
2539 	BOOL collapsible;
2540 	BOOL deleted;
2541 	BOOL done;
2542 	FILE_NAME_TYPE_FLAGS oldnametype;
2543 	u64 dnum;
2544 	u64 fnum;
2545 	int res;
2546 
2547 	res = -1;
2548 	vol = ni->vol;
2549 	dnum = dir_ni->mft_no;
2550 	fnum = ni->mft_no;
2551 				/* save initial link count */
2552 	linkcount = le16_to_cpu(ni->mrec->link_count);
2553 
2554 		/* check whether the same name may be used as DOS and WIN32 */
2555 	collapsible = ntfs_collapsible_chars(ni->vol, shortname, shortlen,
2556 						longname, longlen);
2557 	if (collapsible) {
2558 		deleted = FALSE;
2559 		done = FALSE;
2560 		if (existed) {
2561 			oldnametype = set_namespace(ni, dir_ni, deletename,
2562 					deletelen, FILE_NAME_POSIX);
2563 			if (oldnametype == FILE_NAME_DOS) {
2564 				if (set_namespace(ni, dir_ni, longname, longlen,
2565 						FILE_NAME_WIN32_AND_DOS) >= 0) {
2566 					if (!ntfs_delete(vol,
2567 						(const char*)NULL, ni, dir_ni,
2568 						deletename, deletelen))
2569 						res = 0;
2570 					deleted = TRUE;
2571 				} else
2572 					done = TRUE;
2573 			}
2574 		}
2575 		if (!deleted) {
2576 			if (!done && (set_namespace(ni, dir_ni,
2577 					longname, longlen,
2578 					FILE_NAME_WIN32_AND_DOS) >= 0))
2579 				res = 0;
2580 			ntfs_inode_update_times(ni, NTFS_UPDATE_CTIME);
2581 			ntfs_inode_update_times(dir_ni, NTFS_UPDATE_MCTIME);
2582 			if (ntfs_inode_close_in_dir(ni,dir_ni) && !res)
2583 				res = -1;
2584 			if (ntfs_inode_close(dir_ni) && !res)
2585 				res = -1;
2586 		}
2587 	} else {
2588 		if (!ntfs_link_i(ni, dir_ni, shortname, shortlen,
2589 				FILE_NAME_DOS)
2590 			/* make sure a new link was recorded */
2591 		    && (le16_to_cpu(ni->mrec->link_count) > linkcount)) {
2592 			/* delete the existing long name or short name */
2593 // is it ok to not provide the path ?
2594 			if (!ntfs_delete(vol, (char*)NULL, ni, dir_ni,
2595 				 deletename, deletelen)) {
2596 			/* delete closes the inodes, so have to open again */
2597 				dir_ni = ntfs_inode_open(vol, dnum);
2598 				if (dir_ni) {
2599 					ni = ntfs_inode_open(vol, fnum);
2600 					if (ni) {
2601 						if (!ntfs_link_i(ni, dir_ni,
2602 							longname, longlen,
2603 							FILE_NAME_WIN32))
2604 							res = 0;
2605 						if (ntfs_inode_close_in_dir(ni,
2606 							dir_ni)
2607 						    && !res)
2608 							res = -1;
2609 					}
2610 				if (ntfs_inode_close(dir_ni) && !res)
2611 					res = -1;
2612 				}
2613 			}
2614 		} else {
2615 			ntfs_inode_close_in_dir(ni,dir_ni);
2616 			ntfs_inode_close(dir_ni);
2617 		}
2618 	}
2619 	return (res);
2620 }
2621 
2622 
2623 /*
2624  *		Set the ntfs DOS name into an extended attribute
2625  *
2626  *  The DOS name will be added as another file name attribute
2627  *  using the existing file name information from the original
2628  *  name or overwriting the DOS Name if one exists.
2629  *
2630  *  	The inode of the file is always closed
2631  */
2632 
ntfs_set_ntfs_dos_name(ntfs_inode * ni,ntfs_inode * dir_ni,const char * value,size_t size,int flags)2633 int ntfs_set_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
2634 			const char *value, size_t size,	int flags)
2635 {
2636 	int res = 0;
2637 	int longlen = 0;
2638 	int shortlen = 0;
2639 	char newname[3*MAX_DOS_NAME_LENGTH + 1];
2640 	ntfschar oldname[MAX_DOS_NAME_LENGTH];
2641 	int oldlen;
2642 	u64 dnum;
2643 	BOOL closed = FALSE;
2644 	ntfschar *shortname = NULL;
2645 	ntfschar longname[NTFS_MAX_NAME_LEN];
2646 
2647 		/* copy the string to insert a null char, and truncate */
2648 	if (size > 3*MAX_DOS_NAME_LENGTH)
2649 		size = 3*MAX_DOS_NAME_LENGTH;
2650 	strncpy(newname, value, size);
2651 		/* a long name may be truncated badly and be untranslatable */
2652 	newname[size] = 0;
2653 		/* convert the string to the NTFS wide chars, and truncate */
2654 	shortlen = ntfs_mbstoucs(newname, &shortname);
2655 	if (shortlen > MAX_DOS_NAME_LENGTH)
2656 		shortlen = MAX_DOS_NAME_LENGTH;
2657 
2658 	/* Make sure the short name has valid chars.
2659 	 * Note: the short name cannot end with dot or space, but the
2660 	 * corresponding long name can. */
2661 	if ((shortlen < 0)
2662 	    || ntfs_forbidden_names(ni->vol,shortname,shortlen,TRUE)) {
2663 		ntfs_inode_close_in_dir(ni,dir_ni);
2664 		ntfs_inode_close(dir_ni);
2665 		res = -errno;
2666 		return res;
2667 	}
2668 	dnum = dir_ni->mft_no;
2669 	longlen = get_long_name(ni, dnum, longname);
2670 	if (longlen > 0) {
2671 		oldlen = get_dos_name(ni, dnum, oldname);
2672 		if ((oldlen >= 0)
2673 		    && !ntfs_forbidden_names(ni->vol, longname, longlen,
2674 					     FALSE)) {
2675 			if (oldlen > 0) {
2676 				if (flags & XATTR_CREATE) {
2677 					res = -1;
2678 					errno = EEXIST;
2679 				} else
2680 					if ((shortlen == oldlen)
2681 					    && !memcmp(shortname,oldname,
2682 						     oldlen*sizeof(ntfschar)))
2683 						/* already set, done */
2684 						res = 0;
2685 					else {
2686 						res = set_dos_name(ni, dir_ni,
2687 							shortname, shortlen,
2688 							longname, longlen,
2689 							oldname, oldlen, TRUE);
2690 						closed = TRUE;
2691 					}
2692 			} else {
2693 				if (flags & XATTR_REPLACE) {
2694 					res = -1;
2695 					errno = ENODATA;
2696 				} else {
2697 					res = set_dos_name(ni, dir_ni,
2698 						shortname, shortlen,
2699 						longname, longlen,
2700 						longname, longlen, FALSE);
2701 					closed = TRUE;
2702 				}
2703 			}
2704 		} else
2705 			res = -1;
2706 	} else {
2707 		res = -1;
2708 		if (!longlen)
2709 			errno = ENOENT;
2710 	}
2711 	free(shortname);
2712 	if (!closed) {
2713 		ntfs_inode_close_in_dir(ni,dir_ni);
2714 		ntfs_inode_close(dir_ni);
2715 	}
2716 	return (res ? -1 : 0);
2717 }
2718 
2719 /*
2720  *		Delete the ntfs DOS name
2721  */
2722 
ntfs_remove_ntfs_dos_name(ntfs_inode * ni,ntfs_inode * dir_ni)2723 int ntfs_remove_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni)
2724 {
2725 	int res;
2726 	int oldnametype;
2727 	int longlen = 0;
2728 	int shortlen;
2729 	u64 dnum;
2730 	ntfs_volume *vol;
2731 	BOOL deleted = FALSE;
2732 	ntfschar shortname[MAX_DOS_NAME_LENGTH];
2733 	ntfschar longname[NTFS_MAX_NAME_LEN];
2734 
2735 	res = -1;
2736 	vol = ni->vol;
2737 	dnum = dir_ni->mft_no;
2738 	longlen = get_long_name(ni, dnum, longname);
2739 	if (longlen > 0) {
2740 		shortlen = get_dos_name(ni, dnum, shortname);
2741 		if (shortlen >= 0) {
2742 				/* migrate the long name as Posix */
2743 			oldnametype = set_namespace(ni,dir_ni,longname,longlen,
2744 					FILE_NAME_POSIX);
2745 			switch (oldnametype) {
2746 			case FILE_NAME_WIN32_AND_DOS :
2747 				/* name was Win32+DOS : done */
2748 				res = 0;
2749 				break;
2750 			case FILE_NAME_DOS :
2751 				/* name was DOS, make it back to DOS */
2752 				set_namespace(ni,dir_ni,longname,longlen,
2753 						FILE_NAME_DOS);
2754 				errno = ENOENT;
2755 				break;
2756 			case FILE_NAME_WIN32 :
2757 				/* name was Win32, make it Posix and delete */
2758 				if (set_namespace(ni,dir_ni,shortname,shortlen,
2759 						FILE_NAME_POSIX) >= 0) {
2760 					if (!ntfs_delete(vol,
2761 							(const char*)NULL, ni,
2762 							dir_ni, shortname,
2763 							shortlen))
2764 						res = 0;
2765 					deleted = TRUE;
2766 				} else {
2767 					/*
2768 					 * DOS name has been found, but cannot
2769 					 * migrate to Posix : something bad
2770 					 * has happened
2771 					 */
2772 					errno = EIO;
2773 					ntfs_log_error("Could not change"
2774 						" DOS name of inode %lld to Posix\n",
2775 						(long long)ni->mft_no);
2776 				}
2777 				break;
2778 			default :
2779 				/* name was Posix or not found : error */
2780 				errno = ENOENT;
2781 				break;
2782 			}
2783 		}
2784 	} else {
2785 		if (!longlen)
2786 			errno = ENOENT;
2787 		res = -1;
2788 	}
2789 	if (!deleted) {
2790 		ntfs_inode_close_in_dir(ni,dir_ni);
2791 		ntfs_inode_close(dir_ni);
2792 	}
2793 	return (res);
2794 }
2795