xref: /onnv-gate/usr/src/lib/libntfs/common/libntfs/dir.c (revision 9663:ace9a2ac3683)
1 /**
2  * dir.c - Directory handling code. Part of the Linux-NTFS project.
3  *
4  * Copyright (c) 2002-2005 Anton Altaparmakov
5  * Copyright (c) 2005-2007 Yura Pakhuchiy
6  * Copyright (c) 2004-2005 Richard Russon
7  *
8  * This program/include file is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as published
10  * by the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program/include file is distributed in the hope that it will be
14  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program (in the main directory of the Linux-NTFS
20  * distribution in the file COPYING); if not, write to the Free Software
21  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #ifdef HAVE_STDLIB_H
29 #include <stdlib.h>
30 #endif
31 #ifdef HAVE_ERRNO_H
32 #include <errno.h>
33 #endif
34 #ifdef HAVE_STRING_H
35 #include <string.h>
36 #endif
37 #ifdef HAVE_SYS_STAT_H
38 #include <sys/stat.h>
39 #endif
40 
41 #ifdef HAVE_SYS_SYSMACROS_H
42 #include <sys/sysmacros.h>
43 #endif
44 
45 #include "compat.h"
46 #include "types.h"
47 #include "debug.h"
48 #include "attrib.h"
49 #include "inode.h"
50 #include "dir.h"
51 #include "volume.h"
52 #include "mft.h"
53 #include "index.h"
54 #include "ntfstime.h"
55 #include "lcnalloc.h"
56 #include "logging.h"
57 
58 /*
59  * The little endian Unicode strings "$I30", "$SII", "$SDH", "$O"
60  *  and "$Q" as global constants.
61  */
62 ntfschar NTFS_INDEX_I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'),
63 		const_cpu_to_le16('3'), const_cpu_to_le16('0'),
64 		const_cpu_to_le16('\0') };
65 ntfschar NTFS_INDEX_SII[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'),
66 		const_cpu_to_le16('I'), const_cpu_to_le16('I'),
67 		const_cpu_to_le16('\0') };
68 ntfschar NTFS_INDEX_SDH[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('S'),
69 		const_cpu_to_le16('D'), const_cpu_to_le16('H'),
70 		const_cpu_to_le16('\0') };
71 ntfschar NTFS_INDEX_O[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('O'),
72 		const_cpu_to_le16('\0') };
73 ntfschar NTFS_INDEX_Q[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('Q'),
74 		const_cpu_to_le16('\0') };
75 ntfschar NTFS_INDEX_R[3] = { const_cpu_to_le16('$'), const_cpu_to_le16('R'),
76 		const_cpu_to_le16('\0') };
77 
78 /**
79  * ntfs_inode_lookup_by_name - find an inode in a directory given its name
80  * @dir_ni:	ntfs inode of the directory in which to search for the name
81  * @uname:	Unicode name for which to search in the directory
82  * @uname_len:	length of the name @uname in Unicode characters
83  *
84  * Look for an inode with name @uname in the directory with inode @dir_ni.
85  * ntfs_inode_lookup_by_name() walks the contents of the directory looking for
86  * the Unicode name. If the name is found in the directory, the corresponding
87  * inode number (>= 0) is returned as a mft reference in cpu format, i.e. it
88  * is a 64-bit number containing the sequence number.
89  *
90  * On error, return -1 with errno set to the error code. If the inode is is not
91  * found errno is ENOENT.
92  *
93  * Note, @uname_len does not include the (optional) terminating NULL character.
94  *
95  * Note, we look for a case sensitive match first but we also look for a case
96  * insensitive match at the same time. If we find a case insensitive match, we
97  * save that for the case that we don't find an exact match, where we return
98  * the mft reference of the case insensitive match.
99  *
100  * If the volume is mounted with the case sensitive flag set, then we only
101  * allow exact matches.
102  */
ntfs_inode_lookup_by_name(ntfs_inode * dir_ni,const ntfschar * uname,const int uname_len)103 u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, const ntfschar *uname,
104 		const int uname_len)
105 {
106 	VCN vcn;
107 	u64 mref = 0;
108 	s64 br;
109 	ntfs_volume *vol = dir_ni->vol;
110 	ntfs_attr_search_ctx *ctx;
111 	INDEX_ROOT *ir;
112 	INDEX_ENTRY *ie;
113 	INDEX_ALLOCATION *ia;
114 	u8 *index_end;
115 	ntfs_attr *ia_na;
116 	int eo, rc;
117 	u32 index_block_size, index_vcn_size;
118 	u8 index_vcn_size_bits;
119 
120 	if (!dir_ni || !dir_ni->mrec || !uname || uname_len <= 0) {
121 		errno = EINVAL;
122 		return -1;
123 	}
124 
125 	ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
126 	if (!ctx)
127 		return -1;
128 
129 	/* Find the index root attribute in the mft record. */
130 	if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE,
131 				0, NULL, 0, ctx)) {
132 		ntfs_log_perror("Index root attribute missing in directory "
133 				"inode 0x%llx", (unsigned long long)dir_ni->
134 				mft_no);
135 		goto put_err_out;
136 	}
137 	/* Get to the index root value. */
138 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
139 			le16_to_cpu(ctx->attr->u.res.value_offset));
140 	index_block_size = le32_to_cpu(ir->index_block_size);
141 	if (index_block_size < NTFS_BLOCK_SIZE ||
142 			index_block_size & (index_block_size - 1)) {
143 		ntfs_log_debug("Index block size %u is invalid.\n",
144 				(unsigned)index_block_size);
145 		goto put_err_out;
146 	}
147 	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
148 	/* The first index entry. */
149 	ie = (INDEX_ENTRY*)((u8*)&ir->index +
150 			le32_to_cpu(ir->index.entries_offset));
151 	/*
152 	 * Loop until we exceed valid memory (corruption case) or until we
153 	 * reach the last entry.
154 	 */
155 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
156 		/* Bounds checks. */
157 		if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
158 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
159 				(u8*)ie + le16_to_cpu(ie->key_length) >
160 				index_end)
161 			goto put_err_out;
162 		/*
163 		 * The last entry cannot contain a name. It can however contain
164 		 * a pointer to a child node in the B+tree so we just break out.
165 		 */
166 		if (ie->flags & INDEX_ENTRY_END)
167 			break;
168 		/*
169 		 * We perform a case sensitive comparison and if that matches
170 		 * we are done and return the mft reference of the inode (i.e.
171 		 * the inode number together with the sequence number for
172 		 * consistency checking). We convert it to cpu format before
173 		 * returning.
174 		 */
175 		if (ntfs_names_are_equal(uname, uname_len,
176 				(ntfschar*)&ie->key.file_name.file_name,
177 				ie->key.file_name.file_name_length,
178 				CASE_SENSITIVE, vol->upcase, vol->upcase_len)) {
179 found_it:
180 			/*
181 			 * We have a perfect match, so we don't need to care
182 			 * about having matched imperfectly before.
183 			 */
184 			mref = le64_to_cpu(ie->u.indexed_file);
185 			ntfs_attr_put_search_ctx(ctx);
186 			return mref;
187 		}
188 		/*
189 		 * For a case insensitive mount, we also perform a case
190 		 * insensitive comparison. If the comparison matches, we cache
191 		 * the mft reference in mref. Use first case insensitive match
192 		 * in case if no name matches case sensitive, but several names
193 		 * matches case insensitive.
194 		 */
195 		if (!mref && !NVolCaseSensitive(vol) &&
196 				ntfs_names_are_equal(uname, uname_len,
197 				(ntfschar*)&ie->key.file_name.file_name,
198 				ie->key.file_name.file_name_length,
199 				IGNORE_CASE, vol->upcase, vol->upcase_len))
200 			mref = le64_to_cpu(ie->u.indexed_file);
201 		/*
202 		 * Not a perfect match, need to do full blown collation so we
203 		 * know which way in the B+tree we have to go.
204 		 */
205 		rc = ntfs_names_collate(uname, uname_len,
206 				(ntfschar*)&ie->key.file_name.file_name,
207 				ie->key.file_name.file_name_length, 1,
208 				IGNORE_CASE, vol->upcase, vol->upcase_len);
209 		/*
210 		 * If uname collates before the name of the current entry, there
211 		 * is definitely no such name in this index but we might need to
212 		 * descend into the B+tree so we just break out of the loop.
213 		 */
214 		if (rc == -1)
215 			break;
216 		/* The names are not equal, continue the search. */
217 		if (rc)
218 			continue;
219 		/*
220 		 * Names match with case insensitive comparison, now try the
221 		 * case sensitive comparison, which is required for proper
222 		 * collation.
223 		 */
224 		rc = ntfs_names_collate(uname, uname_len,
225 				(ntfschar*)&ie->key.file_name.file_name,
226 				ie->key.file_name.file_name_length, 1,
227 				CASE_SENSITIVE, vol->upcase, vol->upcase_len);
228 		if (rc == -1)
229 			break;
230 		if (rc)
231 			continue;
232 		/*
233 		 * Perfect match, this will never happen as the
234 		 * ntfs_are_names_equal() call will have gotten a match but we
235 		 * still treat it correctly.
236 		 */
237 		goto found_it;
238 	}
239 	/*
240 	 * We have finished with this index without success. Check for the
241 	 * presence of a child node and if not present return error code
242 	 * ENOENT, unless we have got the mft reference of a matching name
243 	 * cached in mref in which case return mref.
244 	 */
245 	if (!(ie->flags & INDEX_ENTRY_NODE)) {
246 		ntfs_attr_put_search_ctx(ctx);
247 		if (mref)
248 			return mref;
249 		ntfs_log_debug("Entry not found.\n");
250 		errno = ENOENT;
251 		return -1;
252 	} /* Child node present, descend into it. */
253 
254 	/* Open the index allocation attribute. */
255 	ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
256 	if (!ia_na) {
257 		ntfs_log_perror("Failed to open index allocation attribute. "
258 				"Directory inode 0x%llx is corrupt or driver "
259 				"bug", (unsigned long long)dir_ni->mft_no);
260 		goto put_err_out;
261 	}
262 
263 	/* Allocate a buffer for the current index block. */
264 	ia = (INDEX_ALLOCATION*)malloc(index_block_size);
265 	if (!ia) {
266 		ntfs_log_perror("Failed to allocate buffer for index block");
267 		ntfs_attr_close(ia_na);
268 		goto put_err_out;
269 	}
270 
271 	/* Determine the size of a vcn in the directory index. */
272 	if (vol->cluster_size <= index_block_size) {
273 		index_vcn_size = vol->cluster_size;
274 		index_vcn_size_bits = vol->cluster_size_bits;
275 	} else {
276 		index_vcn_size = vol->sector_size;
277 		index_vcn_size_bits = vol->sector_size_bits;
278 	}
279 
280 	/* Get the starting vcn of the index_block holding the child node. */
281 	vcn = sle64_to_cpup((u8*)ie + le16_to_cpu(ie->length) - 8);
282 
283 descend_into_child_node:
284 
285 	/* Read the index block starting at vcn. */
286 	br = ntfs_attr_mst_pread(ia_na, vcn << index_vcn_size_bits, 1,
287 			index_block_size, ia);
288 	if (br != 1) {
289 		if (br != -1)
290 			errno = EIO;
291 		ntfs_log_perror("Failed to read vcn 0x%llx",
292 			       	(unsigned long long)vcn);
293 		goto close_err_out;
294 	}
295 
296 	if (sle64_to_cpu(ia->index_block_vcn) != vcn) {
297 		ntfs_log_debug("Actual VCN (0x%llx) of index buffer is "
298 				"different from expected VCN (0x%llx).\n",
299 				(long long)sle64_to_cpu(ia->index_block_vcn),
300 				(long long)vcn);
301 		errno = EIO;
302 		goto close_err_out;
303 	}
304 	if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) {
305 		ntfs_log_debug("Index buffer (VCN 0x%llx) of directory inode "
306 				"0x%llx has a size (%u) differing from the "
307 				"directory specified size (%u).\n",
308 				(long long)vcn, (unsigned long long)dir_ni->
309 				mft_no, (unsigned)le32_to_cpu(ia->index.
310 				allocated_size) + 0x18, (unsigned)
311 				index_block_size);
312 		errno = EIO;
313 		goto close_err_out;
314 	}
315 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
316 	if (index_end > (u8*)ia + index_block_size) {
317 		ntfs_log_debug("Size of index buffer (VCN 0x%llx) of directory "
318 				"inode 0x%llx exceeds maximum size.\n",
319 				(long long)vcn, (unsigned long long)dir_ni->
320 				mft_no);
321 		errno = EIO;
322 		goto close_err_out;
323 	}
324 
325 	/* The first index entry. */
326 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
327 			le32_to_cpu(ia->index.entries_offset));
328 	/*
329 	 * Iterate similar to above big loop but applied to index buffer, thus
330 	 * loop until we exceed valid memory (corruption case) or until we
331 	 * reach the last entry.
332 	 */
333 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
334 		/* Bounds check. */
335 		if ((u8*)ie < (u8*)ia || (u8*)ie +
336 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
337 				(u8*)ie + le16_to_cpu(ie->key_length) >
338 				index_end) {
339 			ntfs_log_debug("Index entry out of bounds in directory "
340 					"inode 0x%llx.\n",
341 					(unsigned long long)dir_ni->mft_no);
342 			errno = EIO;
343 			goto close_err_out;
344 		}
345 		/*
346 		 * The last entry cannot contain a name. It can however contain
347 		 * a pointer to a child node in the B+tree so we just break out.
348 		 */
349 		if (ie->flags & INDEX_ENTRY_END)
350 			break;
351 		/*
352 		 * We perform a case sensitive comparison and if that matches
353 		 * we are done and return the mft reference of the inode (i.e.
354 		 * the inode number together with the sequence number for
355 		 * consistency checking). We convert it to cpu format before
356 		 * returning.
357 		 */
358 		if (ntfs_names_are_equal(uname, uname_len,
359 				(ntfschar*)&ie->key.file_name.file_name,
360 				ie->key.file_name.file_name_length,
361 				CASE_SENSITIVE, vol->upcase, vol->upcase_len)) {
362 found_it2:
363 			/*
364 			 * We have a perfect match, so we don't need to care
365 			 * about having matched imperfectly before.
366 			 */
367 			mref = le64_to_cpu(ie->u.indexed_file);
368 			free(ia);
369 			ntfs_attr_close(ia_na);
370 			ntfs_attr_put_search_ctx(ctx);
371 			return mref;
372 		}
373 		/*
374 		 * For a case insensitive mount, we also perform a case
375 		 * insensitive comparison. If the comparison matches, we cache
376 		 * the mft reference in mref. Use first case insensitive match
377 		 * in case if no name matches case sensitive, but several names
378 		 * matches case insensitive.
379 		 */
380 		if (!mref && !NVolCaseSensitive(vol) &&
381 				ntfs_names_are_equal(uname, uname_len,
382 				(ntfschar*)&ie->key.file_name.file_name,
383 				ie->key.file_name.file_name_length,
384 				IGNORE_CASE, vol->upcase, vol->upcase_len))
385 			mref = le64_to_cpu(ie->u.indexed_file);
386 		/*
387 		 * Not a perfect match, need to do full blown collation so we
388 		 * know which way in the B+tree we have to go.
389 		 */
390 		rc = ntfs_names_collate(uname, uname_len,
391 				(ntfschar*)&ie->key.file_name.file_name,
392 				ie->key.file_name.file_name_length, 1,
393 				IGNORE_CASE, vol->upcase, vol->upcase_len);
394 		/*
395 		 * If uname collates before the name of the current entry, there
396 		 * is definitely no such name in this index but we might need to
397 		 * descend into the B+tree so we just break out of the loop.
398 		 */
399 		if (rc == -1)
400 			break;
401 		/* The names are not equal, continue the search. */
402 		if (rc)
403 			continue;
404 		/*
405 		 * Names match with case insensitive comparison, now try the
406 		 * case sensitive comparison, which is required for proper
407 		 * collation.
408 		 */
409 		rc = ntfs_names_collate(uname, uname_len,
410 				(ntfschar*)&ie->key.file_name.file_name,
411 				ie->key.file_name.file_name_length, 1,
412 				CASE_SENSITIVE, vol->upcase, vol->upcase_len);
413 		if (rc == -1)
414 			break;
415 		if (rc)
416 			continue;
417 		/*
418 		 * Perfect match, this will never happen as the
419 		 * ntfs_are_names_equal() call will have gotten a match but we
420 		 * still treat it correctly.
421 		 */
422 		goto found_it2;
423 	}
424 	/*
425 	 * We have finished with this index buffer without success. Check for
426 	 * the presence of a child node.
427 	 */
428 	if (ie->flags & INDEX_ENTRY_NODE) {
429 		if ((ia->index.flags & NODE_MASK) == LEAF_NODE) {
430 			ntfs_log_debug("Index entry with child node found in a "
431 					"leaf node in directory inode "
432 					"0x%llx.\n",
433 					(unsigned long long)dir_ni->mft_no);
434 			errno = EIO;
435 			goto close_err_out;
436 		}
437 		/* Child node present, descend into it. */
438 		vcn = sle64_to_cpup((u8*)ie + le16_to_cpu(ie->length) - 8);
439 		if (vcn >= 0)
440 			goto descend_into_child_node;
441 		ntfs_log_debug("Negative child node vcn in directory inode "
442 				"0x%llx.\n", (unsigned long long)dir_ni->
443 				mft_no);
444 		errno = EIO;
445 		goto close_err_out;
446 	}
447 	free(ia);
448 	ntfs_attr_close(ia_na);
449 	ntfs_attr_put_search_ctx(ctx);
450 	/*
451 	 * No child node present, return error code ENOENT, unless we have got
452 	 * the mft reference of a matching name cached in mref in which case
453 	 * return mref.
454 	 */
455 	if (mref)
456 		return mref;
457 	ntfs_log_debug("Entry not found.\n");
458 	errno = ENOENT;
459 	return -1;
460 put_err_out:
461 	eo = EIO;
462 	ntfs_log_debug("Corrupt directory. Aborting lookup.\n");
463 eo_put_err_out:
464 	ntfs_attr_put_search_ctx(ctx);
465 	errno = eo;
466 	return -1;
467 close_err_out:
468 	eo = errno;
469 	free(ia);
470 	ntfs_attr_close(ia_na);
471 	goto eo_put_err_out;
472 }
473 
474 /**
475  * ntfs_pathname_to_inode_num - find the inode number which represents the
476  * 				given pathname
477  * @vol:       An ntfs volume obtained from ntfs_mount
478  * @parent:    A directory inode to begin the search (may be NULL)
479  * @pathname:  Pathname to be located
480  *
481  * Take an ASCII pathname and find the inode that represents it.  The function
482  * splits the path and then descends the directory tree.  If @parent is NULL,
483  * then the root directory '.' will be used as the base for the search.
484  *
485  * Return:  -1    Error, the pathname was invalid, or some other error occurred
486  *          else  Success, the pathname was valid
487  */
ntfs_pathname_to_inode_num(ntfs_volume * vol,ntfs_inode * parent,const char * pathname)488 u64 ntfs_pathname_to_inode_num(ntfs_volume *vol, ntfs_inode *parent,
489 		const char *pathname)
490 {
491 	u64 inum, result;
492 	int len, err = 0;
493 	char *p, *q;
494 	ntfs_inode *ni = NULL;
495 	ntfschar *unicode = NULL;
496 	char *ascii = NULL;
497 
498 	inum = result = (u64)-1;
499 	if (!vol || !pathname) {
500 		err = EINVAL;
501 		goto close;
502 	}
503 	ntfs_log_trace("Path: '%s'\n", pathname);
504 	if (parent) {
505 		ni = parent;
506 	} else
507 		inum = FILE_root;
508 	unicode = calloc(1, MAX_PATH);
509 	ascii = strdup(pathname);
510 	if (!unicode || !ascii) {
511 		ntfs_log_error("Out of memory.\n");
512 		err = ENOMEM;
513 		goto close;
514 	}
515 	p = ascii;
516 	/* Remove leading /'s. */
517 	while (p && *p == PATH_SEP)
518 		p++;
519 	while (p && *p) {
520 		if (!ni) {
521 			ni = ntfs_inode_open(vol, inum);
522 			if (!ni) {
523 				ntfs_log_debug("Cannot open inode %llu.\n",
524 						(unsigned long long)inum);
525 				err = EIO;
526 				goto close;
527 			}
528 		}
529 		/* Find the end of the first token. */
530 		q = strchr(p, PATH_SEP);
531 		if (q != NULL) {
532 			*q = 0;
533 			q++;
534 		}
535 		len = ntfs_mbstoucs(p, &unicode, MAX_PATH);
536 		if (len < 0) {
537 			ntfs_log_debug("Couldn't convert name to Unicode: "
538 					"%s.\n", p);
539 			err = EILSEQ;
540 			goto close;
541 		}
542 		inum = ntfs_inode_lookup_by_name(ni, unicode, len);
543 		if (inum == (u64)-1) {
544 			ntfs_log_debug("Couldn't find name '%s' in pathname "
545 					"'%s'.\n", p, pathname);
546 			err = ENOENT;
547 			goto close;
548 		}
549 		inum = MREF(inum);
550 		if (ni != parent)
551 			ntfs_inode_close(ni);
552 		ni = NULL;
553 		p = q;
554 		while (p && *p == PATH_SEP)
555 			p++;
556 	}
557 	result = inum;
558 close:
559 	if (ni && (ni != parent))
560 		ntfs_inode_close(ni);
561 	free(ascii);
562 	free(unicode);
563 	if (err)
564 		errno = err;
565 	return result;
566 }
567 
568 /**
569  * ntfs_pathname_to_inode - Find the inode which represents the given pathname
570  * @vol:       An ntfs volume obtained from ntfs_mount
571  * @parent:    A directory inode to begin the search (may be NULL)
572  * @pathname:  Pathname to be located
573  *
574  * Take an ASCII pathname and find the inode that represents it.  The function
575  * splits the path and then descends the directory tree.  If @parent is NULL,
576  * then the root directory '.' will be used as the base for the search.
577  *
578  * Return:  inode  Success, the pathname was valid
579  *	    NULL   Error, the pathname was invalid, or some other error occurred
580  */
ntfs_pathname_to_inode(ntfs_volume * vol,ntfs_inode * parent,const char * pathname)581 ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
582 		const char *pathname)
583 {
584 	u64 inum;
585 
586 	inum = ntfs_pathname_to_inode_num(vol, parent, pathname);
587 	if (inum == (u64)-1)
588 		return NULL;
589 	return ntfs_inode_open(vol, inum);
590 }
591 
592 /*
593  * The little endian Unicode string ".." for ntfs_readdir().
594  */
595 static const ntfschar dotdot[3] = { const_cpu_to_le16('.'),
596 				   const_cpu_to_le16('.'),
597 				   const_cpu_to_le16('\0') };
598 
599 /**
600  * ntfs_filldir - ntfs specific filldir method
601  * @vol:	ntfs volume with wjich we are working
602  * @pos:	current position in directory
603  * @ie:		current index entry
604  * @dirent:	context for filldir callback supplied by the caller
605  * @filldir:	filldir callback supplied by the caller
606  *
607  * Pass information specifying the current directory entry @ie to the @filldir
608  * callback.
609  */
ntfs_filldir(ntfs_volume * vol,s64 * pos,INDEX_ENTRY * ie,void * dirent,ntfs_filldir_t filldir)610 static int ntfs_filldir(ntfs_volume *vol, s64 *pos, INDEX_ENTRY *ie,
611 		void *dirent, ntfs_filldir_t filldir)
612 {
613 	FILE_NAME_ATTR *fn = &ie->key.file_name;
614 	unsigned dt_type;
615 
616 	ntfs_log_trace("Entering.\n");
617 
618 	/* Skip root directory self reference entry. */
619 	if (MREF_LE(ie->u.indexed_file) == FILE_root)
620 		return 0;
621 	if (ie->key.file_name.file_attributes & FILE_ATTR_I30_INDEX_PRESENT)
622 		dt_type = NTFS_DT_DIR;
623 	else {
624 		if (NVolInterix(vol) && fn->file_attributes & FILE_ATTR_SYSTEM)
625 			dt_type = NTFS_DT_UNKNOWN;
626 		else
627 			dt_type = NTFS_DT_REG;
628 	}
629 	return filldir(dirent, fn->file_name, fn->file_name_length,
630 			fn->file_name_type, *pos,
631 			le64_to_cpu(ie->u.indexed_file), dt_type);
632 }
633 
634 /**
635  * ntfs_mft_get_parent_ref - find mft reference of parent directory of an inode
636  * @ni:		ntfs inode whose parent directory to find
637  *
638  * Find the parent directory of the ntfs inode @ni. To do this, find the first
639  * file name attribute in the mft record of @ni and return the parent mft
640  * reference from that.
641  *
642  * Note this only makes sense for directories, since files can be hard linked
643  * from multiple directories and there is no way for us to tell which one is
644  * being looked for.
645  *
646  * Technically directories can have hard links, too, but we consider that as
647  * illegal as Linux/UNIX do not support directory hard links.
648  *
649  * Return the mft reference of the parent directory on success or -1 on error
650  * with errno set to the error code.
651  */
ntfs_mft_get_parent_ref(ntfs_inode * ni)652 static MFT_REF ntfs_mft_get_parent_ref(ntfs_inode *ni)
653 {
654 	MFT_REF mref;
655 	ntfs_attr_search_ctx *ctx;
656 	FILE_NAME_ATTR *fn;
657 	int eo;
658 
659 	ntfs_log_trace("Entering.\n");
660 
661 	if (!ni) {
662 		errno = EINVAL;
663 		return ERR_MREF(-1);
664 	}
665 
666 	ctx = ntfs_attr_get_search_ctx(ni, NULL);
667 	if (!ctx)
668 		return ERR_MREF(-1);
669 	if (ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
670 		ntfs_log_debug("No file name found in inode 0x%llx. Corrupt "
671 				"inode.\n", (unsigned long long)ni->mft_no);
672 		goto err_out;
673 	}
674 	if (ctx->attr->non_resident) {
675 		ntfs_log_debug("File name attribute must be resident. "
676 				"Corrupt inode 0x%llx.\n",
677 				(unsigned long long)ni->mft_no);
678 		goto io_err_out;
679 	}
680 	fn = (FILE_NAME_ATTR*)((u8*)ctx->attr +
681 			le16_to_cpu(ctx->attr->u.res.value_offset));
682 	if ((u8*)fn +	le32_to_cpu(ctx->attr->u.res.value_length) >
683 			(u8*)ctx->attr + le32_to_cpu(ctx->attr->length)) {
684 		ntfs_log_debug("Corrupt file name attribute in inode 0x%llx.\n",
685 				(unsigned long long)ni->mft_no);
686 		goto io_err_out;
687 	}
688 	mref = le64_to_cpu(fn->parent_directory);
689 	ntfs_attr_put_search_ctx(ctx);
690 	return mref;
691 io_err_out:
692 	errno = EIO;
693 err_out:
694 	eo = errno;
695 	ntfs_attr_put_search_ctx(ctx);
696 	errno = eo;
697 	return ERR_MREF(-1);
698 }
699 
700 /**
701  * ntfs_readdir - read the contents of an ntfs directory
702  * @dir_ni:	ntfs inode of current directory
703  * @pos:	current position in directory
704  * @dirent:	context for filldir callback supplied by the caller
705  * @filldir:	filldir callback supplied by the caller
706  *
707  * Parse the index root and the index blocks that are marked in use in the
708  * index bitmap and hand each found directory entry to the @filldir callback
709  * supplied by the caller.
710  *
711  * Return 0 on success or -1 on error with errno set to the error code.
712  *
713  * Note: Index blocks are parsed in ascending vcn order, from which follows
714  * that the directory entries are not returned sorted.
715  */
ntfs_readdir(ntfs_inode * dir_ni,s64 * pos,void * dirent,ntfs_filldir_t filldir)716 int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
717 		void *dirent, ntfs_filldir_t filldir)
718 {
719 	s64 i_size, br, ia_pos, bmp_pos, ia_start;
720 	ntfs_volume *vol;
721 	ntfs_attr *ia_na, *bmp_na = NULL;
722 	ntfs_attr_search_ctx *ctx = NULL;
723 	u8 *index_end, *bmp = NULL;
724 	INDEX_ROOT *ir;
725 	INDEX_ENTRY *ie;
726 	INDEX_ALLOCATION *ia = NULL;
727 	int rc, ir_pos, bmp_buf_size, bmp_buf_pos, eo;
728 	u32 index_block_size, index_vcn_size;
729 	u8 index_block_size_bits, index_vcn_size_bits;
730 
731 	ntfs_log_trace("Entering.\n");
732 
733 	if (!dir_ni || !pos || !filldir) {
734 		errno = EINVAL;
735 		return -1;
736 	}
737 
738 	if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
739 		errno = ENOTDIR;
740 		return -1;
741 	}
742 
743 	vol = dir_ni->vol;
744 
745 	ntfs_log_trace("Entering for inode 0x%llx, *pos 0x%llx.\n",
746 			(unsigned long long)dir_ni->mft_no, (long long)*pos);
747 
748 	/* Open the index allocation attribute. */
749 	ia_na = ntfs_attr_open(dir_ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);
750 	if (!ia_na) {
751 		if (errno != ENOENT) {
752 			ntfs_log_perror("Failed to open index allocation "
753 					"attribute. Directory inode 0x%llx is "
754 					"corrupt or bug", (unsigned long long)
755 					dir_ni->mft_no);
756 			return -1;
757 		}
758 		i_size = 0;
759 	} else
760 		i_size = ia_na->data_size;
761 
762 	rc = 0;
763 
764 	/* Are we at end of dir yet? */
765 	if (*pos >= i_size + vol->mft_record_size)
766 		goto done;
767 
768 	/* Emulate . and .. for all directories. */
769 	if (!*pos) {
770 		rc = filldir(dirent, dotdot, 1, FILE_NAME_POSIX, *pos,
771 				MK_MREF(dir_ni->mft_no,
772 				le16_to_cpu(dir_ni->mrec->sequence_number)),
773 				NTFS_DT_DIR);
774 		if (rc)
775 			goto err_out;
776 		++*pos;
777 	}
778 	if (*pos == 1) {
779 		MFT_REF parent_mref;
780 
781 		parent_mref = ntfs_mft_get_parent_ref(dir_ni);
782 		if (parent_mref == ERR_MREF(-1)) {
783 			ntfs_log_perror("Parent directory not found");
784 			goto dir_err_out;
785 		}
786 
787 		rc = filldir(dirent, dotdot, 2, FILE_NAME_POSIX, *pos,
788 				parent_mref, NTFS_DT_DIR);
789 		if (rc)
790 			goto err_out;
791 		++*pos;
792 	}
793 
794 	ctx = ntfs_attr_get_search_ctx(dir_ni, NULL);
795 	if (!ctx)
796 		goto err_out;
797 
798 	/* Get the offset into the index root attribute. */
799 	ir_pos = (int)*pos;
800 	/* Find the index root attribute in the mft record. */
801 	if (ntfs_attr_lookup(AT_INDEX_ROOT, NTFS_INDEX_I30, 4, CASE_SENSITIVE,
802 				0, NULL, 0, ctx)) {
803 		ntfs_log_debug("Index root attribute missing in directory "
804 				"inode 0x%llx.\n", (unsigned long long)dir_ni->
805 				mft_no);
806 		goto dir_err_out;
807 	}
808 	/* Get to the index root value. */
809 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
810 			le16_to_cpu(ctx->attr->u.res.value_offset));
811 
812 	/* Determine the size of a vcn in the directory index. */
813 	index_block_size = le32_to_cpu(ir->index_block_size);
814 	if (index_block_size < NTFS_BLOCK_SIZE ||
815 			index_block_size & (index_block_size - 1)) {
816 		ntfs_log_debug("Index block size %u is invalid.\n",
817 				(unsigned)index_block_size);
818 		goto dir_err_out;
819 	}
820 	index_block_size_bits = ffs(index_block_size) - 1;
821 	if (vol->cluster_size <= index_block_size) {
822 		index_vcn_size = vol->cluster_size;
823 		index_vcn_size_bits = vol->cluster_size_bits;
824 	} else {
825 		index_vcn_size = vol->sector_size;
826 		index_vcn_size_bits = vol->sector_size_bits;
827 	}
828 
829 	/* Are we jumping straight into the index allocation attribute? */
830 	if (*pos >= vol->mft_record_size) {
831 		ntfs_attr_put_search_ctx(ctx);
832 		ctx = NULL;
833 		goto skip_index_root;
834 	}
835 
836 	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
837 	/* The first index entry. */
838 	ie = (INDEX_ENTRY*)((u8*)&ir->index +
839 			le32_to_cpu(ir->index.entries_offset));
840 	/*
841 	 * Loop until we exceed valid memory (corruption case) or until we
842 	 * reach the last entry or until filldir tells us it has had enough
843 	 * or signals an error (both covered by the rc test).
844 	 */
845 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
846 		ntfs_log_debug("In index root, offset 0x%x.\n",
847 				(u8*)ie - (u8*)ir);
848 		/* Bounds checks. */
849 		if ((u8*)ie < (u8*)ctx->mrec || (u8*)ie +
850 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
851 				(u8*)ie + le16_to_cpu(ie->key_length) >
852 				index_end)
853 			goto dir_err_out;
854 		/* The last entry cannot contain a name. */
855 		if (ie->flags & INDEX_ENTRY_END)
856 			break;
857 		/* Skip index root entry if continuing previous readdir. */
858 		if (ir_pos > (u8*)ie - (u8*)ir)
859 			continue;
860 		/* Advance the position even if going to skip the entry. */
861 		*pos = (u8*)ie - (u8*)ir;
862 		/*
863 		 * Submit the directory entry to ntfs_filldir(), which will
864 		 * invoke the filldir() callback as appropriate.
865 		 */
866 		rc = ntfs_filldir(vol, pos, ie, dirent, filldir);
867 		if (rc)
868 			goto err_out;
869 	}
870 	ntfs_attr_put_search_ctx(ctx);
871 	ctx = NULL;
872 
873 	/* If there is no index allocation attribute we are finished. */
874 	if (!ia_na)
875 		goto EOD;
876 
877 	/* Advance *pos to the beginning of the index allocation. */
878 	*pos = vol->mft_record_size;
879 
880 skip_index_root:
881 
882 	if (!ia_na)
883 		goto done;
884 
885 	/* Allocate a buffer for the current index block. */
886 	ia = (INDEX_ALLOCATION*)malloc(index_block_size);
887 	if (!ia) {
888 		ntfs_log_perror("Failed to allocate buffer for index block");
889 		goto err_out;
890 	}
891 
892 	bmp_na = ntfs_attr_open(dir_ni, AT_BITMAP, NTFS_INDEX_I30, 4);
893 	if (!bmp_na) {
894 		ntfs_log_perror("Failed to open index bitmap attribute");
895 		goto dir_err_out;
896 	}
897 
898 	/* Get the offset into the index allocation attribute. */
899 	ia_pos = *pos - vol->mft_record_size;
900 
901 	bmp_pos = ia_pos >> index_block_size_bits;
902 	if (bmp_pos >> 3 >= bmp_na->data_size) {
903 		ntfs_log_debug("Current index position exceeds index bitmap "
904 				"size.\n");
905 		goto dir_err_out;
906 	}
907 
908 	bmp_buf_size = min(bmp_na->data_size - (bmp_pos >> 3), 4096);
909 	bmp = (u8*)malloc(bmp_buf_size);
910 	if (!bmp) {
911 		ntfs_log_perror("Failed to allocate bitmap buffer");
912 		goto err_out;
913 	}
914 
915 	br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
916 	if (br != bmp_buf_size) {
917 		if (br != -1)
918 			errno = EIO;
919 		ntfs_log_perror("Failed to read from index bitmap attribute");
920 		goto err_out;
921 	}
922 
923 	bmp_buf_pos = 0;
924 	/* If the index block is not in use find the next one that is. */
925 	while (!(bmp[bmp_buf_pos >> 3] & (1 << (bmp_buf_pos & 7)))) {
926 find_next_index_buffer:
927 		bmp_pos++;
928 		bmp_buf_pos++;
929 		/* If we have reached the end of the bitmap, we are done. */
930 		if (bmp_pos >> 3 >= bmp_na->data_size)
931 			goto EOD;
932 		ia_pos = bmp_pos << index_block_size_bits;
933 		if (bmp_buf_pos >> 3 < bmp_buf_size)
934 			continue;
935 		/* Read next chunk from the index bitmap. */
936 		if ((bmp_pos >> 3) + bmp_buf_size > bmp_na->data_size)
937 			bmp_buf_size = bmp_na->data_size - (bmp_pos >> 3);
938 		br = ntfs_attr_pread(bmp_na, bmp_pos >> 3, bmp_buf_size, bmp);
939 		if (br != bmp_buf_size) {
940 			if (br != -1)
941 				errno = EIO;
942 			ntfs_log_perror("Failed to read from index bitmap "
943 					"attribute");
944 			goto err_out;
945 		}
946 	}
947 
948 	ntfs_log_debug("Handling index block 0x%llx.\n", (long long)bmp_pos);
949 
950 	/* Read the index block starting at bmp_pos. */
951 	br = ntfs_attr_mst_pread(ia_na, bmp_pos << index_block_size_bits, 1,
952 			index_block_size, ia);
953 	if (br != 1) {
954 		if (br != -1)
955 			errno = EIO;
956 		ntfs_log_perror("Failed to read index block");
957 		goto err_out;
958 	}
959 
960 	ia_start = ia_pos & ~(s64)(index_block_size - 1);
961 	if (sle64_to_cpu(ia->index_block_vcn) != ia_start >>
962 			index_vcn_size_bits) {
963 		ntfs_log_debug("Actual VCN (0x%llx) of index buffer is "
964 				"different from expected VCN (0x%llx) in "
965 				"inode 0x%llx.\n",
966 				(long long)sle64_to_cpu(ia->index_block_vcn),
967 				(long long)ia_start >> index_vcn_size_bits,
968 				(unsigned long long)dir_ni->mft_no);
969 		goto dir_err_out;
970 	}
971 	if (le32_to_cpu(ia->index.allocated_size) + 0x18 != index_block_size) {
972 		ntfs_log_debug("Index buffer (VCN 0x%llx) of directory inode "
973 				"0x%llx has a size (%u) differing from the "
974 				"directory specified size (%u).\n",
975 				(long long)ia_start >> index_vcn_size_bits,
976 				(unsigned long long)dir_ni->mft_no,
977 				(unsigned) le32_to_cpu(ia->index.allocated_size)
978 				+ 0x18, (unsigned)index_block_size);
979 		goto dir_err_out;
980 	}
981 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
982 	if (index_end > (u8*)ia + index_block_size) {
983 		ntfs_log_debug("Size of index buffer (VCN 0x%llx) of directory "
984 				"inode 0x%llx exceeds maximum size.\n",
985 				(long long)ia_start >> index_vcn_size_bits,
986 				(unsigned long long)dir_ni->mft_no);
987 		goto dir_err_out;
988 	}
989 	/* The first index entry. */
990 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
991 			le32_to_cpu(ia->index.entries_offset));
992 	/*
993 	 * Loop until we exceed valid memory (corruption case) or until we
994 	 * reach the last entry or until ntfs_filldir tells us it has had
995 	 * enough or signals an error (both covered by the rc test).
996 	 */
997 	for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
998 		ntfs_log_debug("In index allocation, offset 0x%llx.\n",
999 				(long long)ia_start + ((u8*)ie - (u8*)ia));
1000 		/* Bounds checks. */
1001 		if ((u8*)ie < (u8*)ia || (u8*)ie +
1002 				sizeof(INDEX_ENTRY_HEADER) > index_end ||
1003 				(u8*)ie + le16_to_cpu(ie->key_length) >
1004 				index_end) {
1005 			ntfs_log_debug("Index entry out of bounds in directory "
1006 					"inode 0x%llx.\n", (unsigned long long)
1007 					dir_ni->mft_no);
1008 			goto dir_err_out;
1009 		}
1010 		/* The last entry cannot contain a name. */
1011 		if (ie->flags & INDEX_ENTRY_END)
1012 			break;
1013 		/* Skip index entry if continuing previous readdir. */
1014 		if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
1015 			continue;
1016 		/* Advance the position even if going to skip the entry. */
1017 		*pos = (u8*)ie - (u8*)ia + (sle64_to_cpu(
1018 				ia->index_block_vcn) << index_vcn_size_bits) +
1019 				dir_ni->vol->mft_record_size;
1020 		/*
1021 		 * Submit the directory entry to ntfs_filldir(), which will
1022 		 * invoke the filldir() callback as appropriate.
1023 		 */
1024 		rc = ntfs_filldir(vol, pos, ie, dirent, filldir);
1025 		if (rc)
1026 			goto err_out;
1027 	}
1028 	goto find_next_index_buffer;
1029 EOD:
1030 	/* We are finished, set *pos to EOD. */
1031 	*pos = i_size + vol->mft_record_size;
1032 done:
1033 	free(ia);
1034 	free(bmp);
1035 	if (bmp_na)
1036 		ntfs_attr_close(bmp_na);
1037 	if (ia_na)
1038 		ntfs_attr_close(ia_na);
1039 	ntfs_log_debug("EOD, *pos 0x%llx, returning 0.\n", (long long)*pos);
1040 	return 0;
1041 dir_err_out:
1042 	errno = EIO;
1043 err_out:
1044 	eo = errno;
1045 	if (rc)
1046 		ntfs_log_trace("filldir returned %i, *pos 0x%llx.", rc,
1047 				(long long)*pos);
1048 	ntfs_log_trace("Failed.\n");
1049 	if (ctx)
1050 		ntfs_attr_put_search_ctx(ctx);
1051 	free(ia);
1052 	free(bmp);
1053 	if (bmp_na)
1054 		ntfs_attr_close(bmp_na);
1055 	if (ia_na)
1056 		ntfs_attr_close(ia_na);
1057 	errno = eo;
1058 	return -1;
1059 }
1060 
1061 /**
1062  * __ntfs_create - create object on ntfs volume
1063  * @dir_ni:	ntfs inode for directory in which create new object
1064  * @name:	unicode name of new object
1065  * @name_len:	length of the name in unicode characters
1066  * @type:	type of the object to create
1067  * @dev:	major and minor device numbers (obtained from makedev())
1068  * @target:	target in unicode (only for symlinks)
1069  * @target_len:	length of target in unicode characters
1070  *
1071  * Internal, use ntfs_create{,_device,_symlink} wrappers instead.
1072  *
1073  * @type can be:
1074  *	S_IFREG		to create regular file
1075  *	S_IFDIR		to create directory
1076  *	S_IFBLK		to create block device
1077  *	S_IFCHR		to create character device
1078  *	S_IFLNK		to create symbolic link
1079  *	S_IFIFO		to create FIFO
1080  *	S_IFSOCK	to create socket
1081  * other values are invalid.
1082  *
1083  * @dev is used only if @type is S_IFBLK or S_IFCHR, in other cases its value
1084  * ignored.
1085  *
1086  * @target and @target_len are used only if @type is S_IFLNK, in other cases
1087  * their value ignored.
1088  *
1089  * Return opened ntfs inode that describes created object on success or NULL
1090  * on error with errno set to the error code.
1091  */
__ntfs_create(ntfs_inode * dir_ni,ntfschar * name,u8 name_len,dev_t type,dev_t dev,ntfschar * target,u8 target_len)1092 static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni,
1093 		ntfschar *name, u8 name_len, dev_t type, dev_t dev,
1094 		ntfschar *target, u8 target_len)
1095 {
1096 	ntfs_inode *ni;
1097 	int rollback_data = 0, rollback_sd = 0;
1098 	FILE_NAME_ATTR *fn = NULL;
1099 	STANDARD_INFORMATION *si = NULL;
1100 	SECURITY_DESCRIPTOR_ATTR *sd = NULL;
1101 	ACL *acl;
1102 	ACCESS_ALLOWED_ACE *ace;
1103 	SID *sid;
1104 	int err, fn_len, si_len, sd_len;
1105 
1106 	ntfs_log_trace("Entering.\n");
1107 
1108 	/* Sanity checks. */
1109 	if (!dir_ni || !name || !name_len) {
1110 		ntfs_log_error("Invalid arguments.\n");
1111 		errno = EINVAL;
1112 		return NULL;
1113 	}
1114 	/* FIXME: Reparse points requires special handling. */
1115 	if (dir_ni->flags & FILE_ATTR_REPARSE_POINT) {
1116 		errno = EOPNOTSUPP;
1117 		return NULL;
1118 	}
1119 	/* Allocate MFT record for new file. */
1120 	ni = ntfs_mft_record_alloc(dir_ni->vol, NULL);
1121 	if (!ni) {
1122 		ntfs_log_error("Failed to allocate new MFT record: %s.\n",
1123 				strerror(errno));
1124 		return NULL;
1125 	}
1126 	/*
1127 	 * Create STANDARD_INFORMATION attribute. Write STANDARD_INFORMATION
1128 	 * version 1.2, windows will upgrade it to version 3 if needed.
1129 	 */
1130 	si_len = offsetof(STANDARD_INFORMATION, u.v12.v1_end);
1131 	si = calloc(1, si_len);
1132 	if (!si) {
1133 		err = errno;
1134 		ntfs_log_error("Not enough memory.\n");
1135 		goto err_out;
1136 	}
1137 	si->creation_time = utc2ntfs(ni->creation_time);
1138 	si->last_data_change_time = utc2ntfs(ni->last_data_change_time);
1139 	si->last_mft_change_time = utc2ntfs(ni->last_mft_change_time);
1140 	si->last_access_time = utc2ntfs(ni->last_access_time);
1141 	if (!S_ISREG(type) && !S_ISDIR(type)) {
1142 		si->file_attributes = FILE_ATTR_SYSTEM;
1143 		ni->flags = FILE_ATTR_SYSTEM;
1144 	}
1145 	/* Add STANDARD_INFORMATION to inode. */
1146 	if (ntfs_attr_add(ni, AT_STANDARD_INFORMATION, AT_UNNAMED, 0,
1147 			(u8*)si, si_len)) {
1148 		err = errno;
1149 		ntfs_log_error("Failed to add STANDARD_INFORMATION "
1150 				"attribute.\n");
1151 		goto err_out;
1152 	}
1153 	/* Create SECURITY_DESCRIPTOR attribute (everyone has full access). */
1154 	/*
1155 	 * Calculate security descriptor length. We have 2 sub-authorities in
1156 	 * owner and group SIDs, but structure SID contain only one, so add
1157 	 * 4 bytes to every SID.
1158 	 */
1159 	sd_len = sizeof(SECURITY_DESCRIPTOR_ATTR) + 2 * (sizeof(SID) + 4) +
1160 		sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
1161 	sd = calloc(1, sd_len);
1162 	if (!sd) {
1163 		err = errno;
1164 		ntfs_log_error("Not enough memory.\n");
1165 		goto err_out;
1166 	}
1167 	sd->revision = 1;
1168 	sd->control = SE_DACL_PRESENT | SE_SELF_RELATIVE;
1169 	sid = (SID*)((u8*)sd + sizeof(SECURITY_DESCRIPTOR_ATTR));
1170 	sd->owner = cpu_to_le32((u8*)sid - (u8*)sd);
1171 	sid->revision = 1;
1172 	sid->sub_authority_count = 2;
1173 	sid->sub_authority[0] = cpu_to_le32(32);
1174 	sid->sub_authority[1] = cpu_to_le32(544);
1175 	sid->identifier_authority.value[5] = 5;
1176 	sid = (SID*)((u8*)sid + sizeof(SID) + 4);
1177 	sd->group = cpu_to_le32((u8*)sid - (u8*)sd);
1178 	sid->revision = 1;
1179 	sid->sub_authority_count = 2;
1180 	sid->sub_authority[0] = cpu_to_le32(32);
1181 	sid->sub_authority[1] = cpu_to_le32(544);
1182 	sid->identifier_authority.value[5] = 5;
1183 	acl = (ACL*)((u8*)sid + sizeof(SID) + 4);
1184 	sd->dacl = cpu_to_le32((u8*)acl - (u8*)sd);
1185 	acl->revision = 2;
1186 	acl->size = cpu_to_le16(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE));
1187 	acl->ace_count = cpu_to_le16(1);
1188 	ace = (ACCESS_ALLOWED_ACE*)((u8*)acl + sizeof(ACL));
1189 	ace->type = ACCESS_ALLOWED_ACE_TYPE;
1190 	ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
1191 	ace->size = cpu_to_le16(sizeof(ACCESS_ALLOWED_ACE));
1192 	ace->mask = cpu_to_le32(0x1f01ff); /* FIXME */
1193 	ace->sid.revision = 1;
1194 	ace->sid.sub_authority_count = 1;
1195 	ace->sid.sub_authority[0] = 0;
1196 	ace->sid.identifier_authority.value[5] = 1;
1197 	/* Add SECURITY_DESCRIPTOR attribute to inode. */
1198 	if (ntfs_attr_add(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0,
1199 			(u8*)sd, sd_len)) {
1200 		err = errno;
1201 		ntfs_log_error("Failed to add SECURITY_DESCRIPTOR "
1202 				"attribute.\n");
1203 		goto err_out;
1204 	}
1205 	rollback_sd = 1;
1206 	/* Add DATA/INDEX_ROOT attribute. */
1207 	if (S_ISDIR(type)) {
1208 		INDEX_ROOT *ir = NULL;
1209 		INDEX_ENTRY *ie;
1210 		int ir_len, index_len;
1211 
1212 		/* Create INDEX_ROOT attribute. */
1213 		index_len = sizeof(INDEX_HEADER) + sizeof(INDEX_ENTRY_HEADER);
1214 		ir_len = offsetof(INDEX_ROOT, index) + index_len;
1215 		ir = calloc(1, ir_len);
1216 		if (!ir) {
1217 			err = errno;
1218 			ntfs_log_error("Not enough memory.\n");
1219 			goto err_out;
1220 		}
1221 		ir->type = AT_FILE_NAME;
1222 		ir->collation_rule = COLLATION_FILE_NAME;
1223 		ir->index_block_size = cpu_to_le32(ni->vol->indx_record_size);
1224 		if (ni->vol->cluster_size <= ni->vol->indx_record_size)
1225 			ir->clusters_per_index_block =
1226 					ni->vol->indx_record_size >>
1227 					ni->vol->cluster_size_bits;
1228 		else
1229 			ir->clusters_per_index_block =
1230 					ni->vol->indx_record_size >>
1231 					ni->vol->sector_size_bits;
1232 		ir->index.entries_offset = cpu_to_le32(sizeof(INDEX_HEADER));
1233 		ir->index.index_length = cpu_to_le32(index_len);
1234 		ir->index.allocated_size = cpu_to_le32(index_len);
1235 		ie = (INDEX_ENTRY*)((u8*)ir + sizeof(INDEX_ROOT));
1236 		ie->length = cpu_to_le16(sizeof(INDEX_ENTRY_HEADER));
1237 		ie->key_length = 0;
1238 		ie->flags = INDEX_ENTRY_END;
1239 		/* Add INDEX_ROOT attribute to inode. */
1240 		if (ntfs_attr_add(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4,
1241 				(u8*)ir, ir_len)) {
1242 			err = errno;
1243 			free(ir);
1244 			ntfs_log_error("Failed to add INDEX_ROOT attribute.\n");
1245 			goto err_out;
1246 		}
1247 		free(ir);
1248 	} else {
1249 		INTX_FILE *data;
1250 		int data_len;
1251 
1252 		switch (type) {
1253 			case S_IFBLK:
1254 			case S_IFCHR:
1255 				data_len = offsetof(INTX_FILE, u.s.device_end);
1256 				data = ntfs_malloc(data_len);
1257 				if (!data) {
1258 					err = errno;
1259 					goto err_out;
1260 				}
1261 				data->u.s.major = cpu_to_le64(major(dev));
1262 				data->u.s.minor = cpu_to_le64(minor(dev));
1263 				if (type == S_IFBLK)
1264 					data->magic = INTX_BLOCK_DEVICE;
1265 				if (type == S_IFCHR)
1266 					data->magic = INTX_CHARACTER_DEVICE;
1267 				break;
1268 			case S_IFLNK:
1269 				data_len = sizeof(INTX_FILE_TYPES) +
1270 						target_len * sizeof(ntfschar);
1271 				data = ntfs_malloc(data_len);
1272 				if (!data) {
1273 					err = errno;
1274 					goto err_out;
1275 				}
1276 				data->magic = INTX_SYMBOLIC_LINK;
1277 				memcpy(data->u.target, target,
1278 						target_len * sizeof(ntfschar));
1279 				break;
1280 			case S_IFSOCK:
1281 				data = NULL;
1282 				data_len = 1;
1283 				break;
1284 			default: /* FIFO or regular file. */
1285 				data = NULL;
1286 				data_len = 0;
1287 				break;
1288 		}
1289 		/* Add DATA attribute to inode. */
1290 		if (ntfs_attr_add(ni, AT_DATA, AT_UNNAMED, 0, (u8*)data,
1291 				data_len)) {
1292 			err = errno;
1293 			free(data);
1294 			ntfs_log_error("Failed to add DATA attribute.\n");
1295 			goto err_out;
1296 		}
1297 		rollback_data = 1;
1298 		free(data);
1299 	}
1300 	/* Create FILE_NAME attribute. */
1301 	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
1302 	fn = ntfs_calloc(fn_len);
1303 	if (!fn) {
1304 		err = errno;
1305 		goto err_out;
1306 	}
1307 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
1308 			le16_to_cpu(dir_ni->mrec->sequence_number));
1309 	fn->file_name_length = name_len;
1310 	fn->file_name_type = FILE_NAME_POSIX;
1311 	if (S_ISDIR(type))
1312 		fn->file_attributes = FILE_ATTR_I30_INDEX_PRESENT;
1313 	if (!S_ISREG(type) && !S_ISDIR(type))
1314 		fn->file_attributes = FILE_ATTR_SYSTEM;
1315 	fn->creation_time = utc2ntfs(ni->creation_time);
1316 	fn->last_data_change_time = utc2ntfs(ni->last_data_change_time);
1317 	fn->last_mft_change_time = utc2ntfs(ni->last_mft_change_time);
1318 	fn->last_access_time = utc2ntfs(ni->last_access_time);
1319 	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
1320 	/* Add FILE_NAME attribute to inode. */
1321 	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
1322 		err = errno;
1323 		ntfs_log_error("Failed to add FILE_NAME attribute.\n");
1324 		goto err_out;
1325 	}
1326 	/* Add FILE_NAME attribute to index. */
1327 	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
1328 			le16_to_cpu(ni->mrec->sequence_number)))) {
1329 		err = errno;
1330 		ntfs_log_perror("Failed to add entry to the index");
1331 		goto err_out;
1332 	}
1333 	/* Set hard links count and directory flag. */
1334 	ni->mrec->link_count = cpu_to_le16(1);
1335 	if (S_ISDIR(type))
1336 		ni->mrec->flags |= MFT_RECORD_IS_DIRECTORY;
1337 	ntfs_inode_mark_dirty(ni);
1338 	/* Done! */
1339 	free(fn);
1340 	free(si);
1341 	free(sd);
1342 	ntfs_log_trace("Done.\n");
1343 	return ni;
1344 err_out:
1345 	ntfs_log_trace("Failed.\n");
1346 	if (rollback_sd) {
1347 		ntfs_attr *na;
1348 
1349 		na = ntfs_attr_open(ni, AT_SECURITY_DESCRIPTOR, AT_UNNAMED, 0);
1350 		if (!na)
1351 			ntfs_log_perror("Failed to open SD (0x50) attribute of "
1352 					" inode 0x%llx. Run chkdsk.\n",
1353 					(unsigned long long)ni->mft_no);
1354 		else if (ntfs_attr_rm(na))
1355 			ntfs_log_perror("Failed to remove SD (0x50) attribute "
1356 					"of inode 0x%llx. Run chkdsk.\n",
1357 					(unsigned long long)ni->mft_no);
1358 	}
1359 	if (rollback_data) {
1360 		ntfs_attr *na;
1361 
1362 		na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
1363 		if (!na)
1364 			ntfs_log_perror("Failed to open data attribute of "
1365 					" inode 0x%llx. Run chkdsk.\n",
1366 					(unsigned long long)ni->mft_no);
1367 		else if (ntfs_attr_rm(na))
1368 			ntfs_log_perror("Failed to remove data attribute of "
1369 					"inode 0x%llx. Run chkdsk.\n",
1370 					(unsigned long long)ni->mft_no);
1371 	}
1372 	/*
1373 	 * Free extent MFT records (should not exist any with current
1374 	 * ntfs_create implementation, but for any case if something will be
1375 	 * changed in the future).
1376 	 */
1377 	while (ni->nr_extents)
1378 		if (ntfs_mft_record_free(ni->vol, *(ni->u.extent_nis))) {
1379 			err = errno;
1380 			ntfs_log_error("Failed to free extent MFT record.  "
1381 					"Leaving inconsistent metadata.\n");
1382 		}
1383 	if (ntfs_mft_record_free(ni->vol, ni))
1384 		ntfs_log_error("Failed to free MFT record.  "
1385 				"Leaving inconsistent metadata. Run chkdsk.\n");
1386 	free(fn);
1387 	free(si);
1388 	free(sd);
1389 	errno = err;
1390 	return NULL;
1391 }
1392 
1393 /**
1394  * Some wrappers around __ntfs_create() ...
1395  */
1396 
ntfs_create(ntfs_inode * dir_ni,ntfschar * name,u8 name_len,dev_t type)1397 ntfs_inode *ntfs_create(ntfs_inode *dir_ni, ntfschar *name, u8 name_len,
1398 		dev_t type)
1399 {
1400 	if (type != S_IFREG && type != S_IFDIR && type != S_IFIFO &&
1401 			type != S_IFSOCK) {
1402 		ntfs_log_error("Invalid arguments.\n");
1403 		return NULL;
1404 	}
1405 	return __ntfs_create(dir_ni, name, name_len, type, 0, NULL, 0);
1406 }
1407 
ntfs_create_device(ntfs_inode * dir_ni,ntfschar * name,u8 name_len,dev_t type,dev_t dev)1408 ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, ntfschar *name, u8 name_len,
1409 		dev_t type, dev_t dev)
1410 {
1411 	if (type != S_IFCHR && type != S_IFBLK) {
1412 		ntfs_log_error("Invalid arguments.\n");
1413 		return NULL;
1414 	}
1415 	return __ntfs_create(dir_ni, name, name_len, type, dev, NULL, 0);
1416 }
1417 
ntfs_create_symlink(ntfs_inode * dir_ni,ntfschar * name,u8 name_len,ntfschar * target,u8 target_len)1418 ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, ntfschar *name, u8 name_len,
1419 		ntfschar *target, u8 target_len)
1420 {
1421 	if (!target || !target_len) {
1422 		ntfs_log_error("Invalid arguments.\n");
1423 		return NULL;
1424 	}
1425 	return __ntfs_create(dir_ni, name, name_len, S_IFLNK, 0,
1426 			target, target_len);
1427 }
1428 
1429 /**
1430  * ntfs_delete - delete file or directory from ntfs volume
1431  * @pni:	ntfs inode for object to delete
1432  * @dir_ni:	ntfs inode for directory in which delete object
1433  * @name:	unicode name of the object to delete
1434  * @name_len:	length of the name in unicode characters
1435  *
1436  * @pni is pointer to pointer to ntfs_inode structure. Upon successful
1437  * completion and if inode is really deleted (there are no more links left to
1438  * it) this function will close @*pni and set it to NULL, in the other cases
1439  * @*pni will stay opened.
1440  *
1441  * Return 0 on success or -1 on error with errno set to the error code.
1442  */
ntfs_delete(ntfs_inode ** pni,ntfs_inode * dir_ni,ntfschar * name,u8 name_len)1443 int ntfs_delete(ntfs_inode **pni, ntfs_inode *dir_ni, ntfschar *name,
1444 		u8 name_len)
1445 {
1446 	ntfs_attr_search_ctx *actx = NULL;
1447 	ntfs_index_context *ictx = NULL;
1448 	ntfs_inode *ni;
1449 	FILE_NAME_ATTR *fn = NULL;
1450 	BOOL looking_for_dos_name = FALSE, looking_for_win32_name = FALSE;
1451 	BOOL case_sensitive_match = TRUE;
1452 	int err = 0;
1453 
1454 	ntfs_log_trace("Entering.\n");
1455 
1456 	if (!pni || !(ni = *pni) || !dir_ni || !name || !name_len ||
1457 			ni->nr_extents == -1 || dir_ni->nr_extents == -1) {
1458 		ntfs_log_error("Invalid arguments.\n");
1459 		errno = EINVAL;
1460 		goto err_out;
1461 	}
1462 	if (ni->nr_references > 1 && le16_to_cpu(ni->mrec->link_count) == 1) {
1463 		ntfs_log_error("Trying to deleting inode with left "
1464 				"references.\n");
1465 		errno = EINVAL;
1466 		goto err_out;
1467 	}
1468 	/*
1469 	 * Search for FILE_NAME attribute with such name. If it's in POSIX or
1470 	 * WIN32_AND_DOS namespace, then simply remove it from index and inode.
1471 	 * If filename in DOS or in WIN32 namespace, then remove DOS name first,
1472 	 * only then remove WIN32 name. Mark WIN32 name as POSIX name to prevent
1473 	 * chkdsk to complain about DOS name absence in case if DOS name had
1474 	 * been successfully deleted, but WIN32 name remove failed.
1475 	 */
1476 	actx = ntfs_attr_get_search_ctx(ni, NULL);
1477 	if (!actx)
1478 		goto err_out;
1479 search:
1480 	while (!ntfs_attr_lookup(AT_FILE_NAME, AT_UNNAMED, 0, CASE_SENSITIVE,
1481 			0, NULL, 0, actx)) {
1482 		errno = 0;
1483 		fn = (FILE_NAME_ATTR*)((u8*)actx->attr +
1484 				le16_to_cpu(actx->attr->u.res.value_offset));
1485 		ntfs_log_trace("Found filename with instance number %d.\n",
1486 				le16_to_cpu(actx->attr->instance));
1487 		if (looking_for_dos_name) {
1488 			if (fn->file_name_type == FILE_NAME_DOS)
1489 				break;
1490 			else
1491 				continue;
1492 		}
1493 		if (looking_for_win32_name) {
1494 			if  (fn->file_name_type == FILE_NAME_WIN32)
1495 				break;
1496 			else
1497 				continue;
1498 		}
1499 		if (dir_ni->mft_no == MREF_LE(fn->parent_directory) &&
1500 				ntfs_names_are_equal(fn->file_name,
1501 				fn->file_name_length, name,
1502 				name_len, case_sensitive_match ?
1503 				CASE_SENSITIVE : IGNORE_CASE, ni->vol->upcase,
1504 				ni->vol->upcase_len)) {
1505 			if (fn->file_name_type == FILE_NAME_WIN32) {
1506 				looking_for_dos_name = TRUE;
1507 				ntfs_attr_reinit_search_ctx(actx);
1508 				ntfs_log_trace("Restart search. "
1509 						"Looking for DOS name.\n");
1510 				continue;
1511 			}
1512 			if (fn->file_name_type == FILE_NAME_DOS)
1513 				looking_for_dos_name = TRUE;
1514 			break;
1515 		}
1516 	}
1517 	if (errno) {
1518 		/*
1519 		 * If case sensitive search failed and volume mounted case
1520 		 * insensitive, then try once again ignoring case.
1521 		 */
1522 		if (errno == ENOENT && !NVolCaseSensitive(ni->vol) &&
1523 				case_sensitive_match) {
1524 			case_sensitive_match = FALSE;
1525 			ntfs_attr_reinit_search_ctx(actx);
1526 			ntfs_log_trace("Restart search. Ignore case.");
1527 			goto search;
1528 		}
1529 		ntfs_log_error("Failed to find requested filename in FILE_NAME "
1530 				"attributes that belong to this inode.\n");
1531 		goto err_out;
1532 	}
1533 	/* If deleting directory check it to be empty. */
1534 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
1535 		ntfs_attr *na;
1536 
1537 		na = ntfs_attr_open(ni, AT_INDEX_ROOT, NTFS_INDEX_I30, 4);
1538 		if (!na) {
1539 			ntfs_log_error("Corrupt directory or library bug.\n");
1540 			errno = EIO;
1541 			goto err_out;
1542 		}
1543 		/*
1544 		 * Do not allow non-empty directory deletion if hard links count
1545 		 * is 1 (always) or 2 (in case if filename in DOS namespace,
1546 		 * because we delete it first in file which have both WIN32 and
1547 		 * DOS names).
1548 		 */
1549 		if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(
1550 				INDEX_ENTRY_HEADER)) && (le16_to_cpu(
1551 				ni->mrec->link_count) == 1 ||
1552 				(le16_to_cpu(ni->mrec->link_count) == 2 &&
1553 				fn->file_name_type == FILE_NAME_DOS))) {
1554 			ntfs_attr_close(na);
1555 			ntfs_log_error("Directory is not empty.\n");
1556 			errno = ENOTEMPTY;
1557 			goto err_out;
1558 		}
1559 		ntfs_attr_close(na);
1560 	}
1561 	/* One more sanity check. */
1562 	if (ni->nr_references > 1 && looking_for_dos_name &&
1563 			le16_to_cpu(ni->mrec->link_count) == 2) {
1564 		ntfs_log_error("Trying to deleting inode with left "
1565 				"references.\n");
1566 		errno = EINVAL;
1567 		goto err_out;
1568 	}
1569 	ntfs_log_trace("Found!\n");
1570 	/* Search for such FILE_NAME in index. */
1571 	ictx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4);
1572 	if (!ictx)
1573 		goto err_out;
1574 	if (ntfs_index_lookup(fn, le32_to_cpu(actx->attr->u.res.value_length), ictx))
1575 		goto err_out;
1576 	/* Set namespace to POSIX for WIN32 name. */
1577 	if (fn->file_name_type == FILE_NAME_WIN32) {
1578 		fn->file_name_type = FILE_NAME_POSIX;
1579 		ntfs_inode_mark_dirty(actx->ntfs_ino);
1580 		((FILE_NAME_ATTR*)ictx->data)->file_name_type = FILE_NAME_POSIX;
1581 		ntfs_index_entry_mark_dirty(ictx);
1582 	}
1583 	/* Do not support reparse point deletion yet. */
1584 	if (((FILE_NAME_ATTR*)ictx->data)->file_attributes &
1585 			FILE_ATTR_REPARSE_POINT) {
1586 		errno = EOPNOTSUPP;
1587 		goto err_out;
1588 	}
1589 	/* Remove FILE_NAME from index. */
1590 	if (ntfs_index_rm(ictx))
1591 		goto err_out;
1592 
1593 	/* Remove FILE_NAME from inode. */
1594 	if (ntfs_attr_record_rm(actx))
1595 		goto err_out;
1596 	/* Decrement hard link count. */
1597 	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
1598 			ni->mrec->link_count) - 1);
1599 	ntfs_inode_mark_dirty(ni);
1600 	if (looking_for_dos_name) {
1601 		looking_for_dos_name = FALSE;
1602 		looking_for_win32_name = TRUE;
1603 		ntfs_attr_reinit_search_ctx(actx);
1604 		ntfs_log_trace("DOS name deleted. "
1605 				"Now search for WIN32 name.\n");
1606 		goto search;
1607 	} else
1608 		ntfs_log_trace("Deleted.\n");
1609 	/* TODO: Update object id, quota and security indexes if required. */
1610 	/*
1611 	 * If hard link count is not equal to zero then we are done. In other
1612 	 * case there are no reference to this inode left, so we should free all
1613 	 * non-resident attributes and mark all MFT record as not in use.
1614 	 */
1615 	if (ni->mrec->link_count)
1616 		goto out;
1617 	ntfs_attr_reinit_search_ctx(actx);
1618 	while (!ntfs_attrs_walk(actx)) {
1619 		if (actx->attr->non_resident) {
1620 			runlist *rl;
1621 
1622 			rl = ntfs_mapping_pairs_decompress(ni->vol, actx->attr,
1623 					NULL);
1624 			if (!rl) {
1625 				err = errno;
1626 				ntfs_log_error("Failed to decompress runlist.  "
1627 						"Leaving inconsistent "
1628 						"metadata.\n");
1629 				continue;
1630 			}
1631 			if (ntfs_cluster_free_from_rl(ni->vol, rl)) {
1632 				err = errno;
1633 				ntfs_log_error("Failed to free clusters.  "
1634 						"Leaving inconsistent "
1635 						"metadata.\n");
1636 				continue;
1637 			}
1638 			free(rl);
1639 		}
1640 	}
1641 	if (errno != ENOENT) {
1642 		err = errno;
1643 		ntfs_log_error("Attribute enumeration failed.  "
1644 				"Probably leaving inconsistent metadata.\n");
1645 	}
1646 	/* All extents should be attached after attribute walk. */
1647 	while (ni->nr_extents)
1648 		if (ntfs_mft_record_free(ni->vol, *(ni->u.extent_nis))) {
1649 			err = errno;
1650 			ntfs_log_error("Failed to free extent MFT record.  "
1651 					"Leaving inconsistent metadata.\n");
1652 		}
1653 	if (ntfs_mft_record_free(ni->vol, ni)) {
1654 		err = errno;
1655 		ntfs_log_error("Failed to free base MFT record.  "
1656 				"Leaving inconsistent metadata.\n");
1657 	}
1658 	*pni = NULL;
1659 out:
1660 	if (actx)
1661 		ntfs_attr_put_search_ctx(actx);
1662 	if (ictx)
1663 		ntfs_index_ctx_put(ictx);
1664 	if (err) {
1665 		ntfs_log_error("%s(): Failed.\n", "ntfs_delete");
1666 		errno = err;
1667 		return -1;
1668 	}
1669 	ntfs_log_trace("Done.\n");
1670 	return 0;
1671 err_out:
1672 	err = errno;
1673 	goto out;
1674 }
1675 
1676 /**
1677  * ntfs_link - create hard link for file or directory
1678  * @ni:		ntfs inode for object to create hard link
1679  * @dir_ni:	ntfs inode for directory in which new link should be placed
1680  * @name:	unicode name of the new link
1681  * @name_len:	length of the name in unicode characters
1682  *
1683  * NOTE: At present we allow creating hard links to directories, we use them
1684  * in a temporary state during rename. But it's definitely bad idea to have
1685  * hard links to directories as a result of operation.
1686  * FIXME: Create internal  __ntfs_link that allows hard links to a directories
1687  * and external ntfs_link that do not. Write ntfs_rename that uses __ntfs_link.
1688  *
1689  * Return 0 on success or -1 on error with errno set to the error code.
1690  */
ntfs_link(ntfs_inode * ni,ntfs_inode * dir_ni,ntfschar * name,u8 name_len)1691 int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name, u8 name_len)
1692 {
1693 	FILE_NAME_ATTR *fn = NULL;
1694 	int fn_len, err;
1695 
1696 	ntfs_log_trace("Entering.\n");
1697 
1698 	if (!ni || !dir_ni || !name || !name_len ||
1699 			ni->mft_no == dir_ni->mft_no) {
1700 		err = EINVAL;
1701 		ntfs_log_error("Invalid arguments.");
1702 		goto err_out;
1703 	}
1704 	/* FIXME: Reparse points requires special handling. */
1705 	if (ni->flags & FILE_ATTR_REPARSE_POINT) {
1706 		err = EOPNOTSUPP;
1707 		goto err_out;
1708 	}
1709 	/* Create FILE_NAME attribute. */
1710 	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);
1711 	fn = ntfs_calloc(fn_len);
1712 	if (!fn) {
1713 		err = errno;
1714 		goto err_out;
1715 	}
1716 	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,
1717 			le16_to_cpu(dir_ni->mrec->sequence_number));
1718 	fn->file_name_length = name_len;
1719 	fn->file_name_type = FILE_NAME_POSIX;
1720 	fn->file_attributes = ni->flags;
1721 	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
1722 		fn->file_attributes |= FILE_ATTR_I30_INDEX_PRESENT;
1723 	fn->allocated_size = cpu_to_sle64(ni->allocated_size);
1724 	fn->data_size = cpu_to_sle64(ni->data_size);
1725 	fn->creation_time = utc2ntfs(ni->creation_time);
1726 	fn->last_data_change_time = utc2ntfs(ni->last_data_change_time);
1727 	fn->last_mft_change_time = utc2ntfs(ni->last_mft_change_time);
1728 	fn->last_access_time = utc2ntfs(ni->last_access_time);
1729 	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
1730 	/* Add FILE_NAME attribute to index. */
1731 	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,
1732 			le16_to_cpu(ni->mrec->sequence_number)))) {
1733 		err = errno;
1734 		ntfs_log_error("Failed to add entry to the index.\n");
1735 		goto err_out;
1736 	}
1737 	/* Add FILE_NAME attribute to inode. */
1738 	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
1739 		ntfs_index_context *ictx;
1740 
1741 		err = errno;
1742 		ntfs_log_error("Failed to add FILE_NAME attribute.\n");
1743 		/* Try to remove just added attribute from index. */
1744 		ictx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4);
1745 		if (!ictx)
1746 			goto rollback_failed;
1747 		if (ntfs_index_lookup(fn, fn_len, ictx)) {
1748 			ntfs_index_ctx_put(ictx);
1749 			goto rollback_failed;
1750 		}
1751 		if (ntfs_index_rm(ictx)) {
1752 			ntfs_index_ctx_put(ictx);
1753 			goto rollback_failed;
1754 		}
1755 		goto err_out;
1756 	}
1757 	/* Increment hard links count. */
1758 	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(
1759 			ni->mrec->link_count) + 1);
1760 	/* Done! */
1761 	ntfs_inode_mark_dirty(ni);
1762 	free(fn);
1763 	ntfs_log_trace("Done.\n");
1764 	return 0;
1765 rollback_failed:
1766 	ntfs_log_error("Rollback failed. Leaving inconsistent metadata.\n");
1767 err_out:
1768 	ntfs_log_error("%s(): Failed.\n", "ntfs_link");
1769 	free(fn);
1770 	errno = err;
1771 	return -1;
1772 }
1773 
1774