xref: /haiku/src/add-ons/kernel/file_systems/ntfs/libntfs/acls.c (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 /**
2  * acls.c - General function to process NTFS ACLs
3  *
4  *	This module is part of ntfs-3g library, but may also be
5  *	integrated in tools running over Linux or Windows
6  *
7  * Copyright (c) 2007-2017 Jean-Pierre Andre
8  *
9  * This program/include file is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as published
11  * by the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program/include file is distributed in the hope that it will be
15  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program (in the main directory of the NTFS-3G
21  * distribution in the file COPYING); if not, write to the Free Software
22  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24 
25 #include "config.h"
26 
27 #ifdef HAVE_STDIO_H
28 #include <stdio.h>
29 #endif
30 #ifdef HAVE_STDLIB_H
31 #include <stdlib.h>
32 #endif
33 #ifdef HAVE_STRING_H
34 #include <string.h>
35 #endif
36 #ifdef HAVE_ERRNO_H
37 #include <errno.h>
38 #endif
39 #ifdef HAVE_SYS_STAT_H
40 #include <sys/stat.h>
41 #endif
42 #ifdef HAVE_FCNTL_H
43 #include <fcntl.h>
44 #endif
45 #ifdef HAVE_SYSLOG_H
46 #include <syslog.h>
47 #endif
48 #include <unistd.h>
49 #include <pwd.h>
50 #include <grp.h>
51 
52 #ifdef __HAIKU__
53 #define getgrgid(a) NULL
54 #define getpwuid(a) NULL
55 #define getgrnam(x) NULL
56 #define getpwnam(x) NULL
57 #endif
58 
59 #include "types.h"
60 #include "layout.h"
61 #include "security.h"
62 #include "acls.h"
63 #include "misc.h"
64 
65 /*
66  *	A few useful constants
67  */
68 
69 /*
70  *		null SID (S-1-0-0)
71  */
72 
73 static const char nullsidbytes[] = {
74 		1,		/* revision */
75 		1,		/* auth count */
76 		0, 0, 0, 0, 0, 0,	/* base */
77 		0, 0, 0, 0 	/* 1st level */
78 	};
79 
80 static const SID *nullsid = (const SID*)nullsidbytes;
81 
82 /*
83  *		SID for world  (S-1-1-0)
84  */
85 
86 static const char worldsidbytes[] = {
87 		1,		/* revision */
88 		1,		/* auth count */
89 		0, 0, 0, 0, 0, 1,	/* base */
90 		0, 0, 0, 0	/* 1st level */
91 } ;
92 
93 const SID *worldsid = (const SID*)worldsidbytes;
94 
95 /*
96  *		SID for authenticated user (S-1-5-11)
97  */
98 
99 static const char authsidbytes[] = {
100 		1,		/* revision */
101 		1,		/* auth count */
102 		0, 0, 0, 0, 0, 5,	/* base */
103 		11, 0, 0, 0	/* 1st level */
104 };
105 
106 static const SID *authsid = (const SID*)authsidbytes;
107 
108 /*
109  *		SID for administrator
110  */
111 
112 static const char adminsidbytes[] = {
113 		1,		/* revision */
114 		2,		/* auth count */
115 		0, 0, 0, 0, 0, 5,	/* base */
116 		32, 0, 0, 0,	/* 1st level */
117 		32, 2, 0, 0	/* 2nd level */
118 };
119 
120 const SID *adminsid = (const SID*)adminsidbytes;
121 
122 /*
123  *		SID for system
124  */
125 
126 static const char systemsidbytes[] = {
127 		1,		/* revision */
128 		1,		/* auth count */
129 		0, 0, 0, 0, 0, 5,	/* base */
130 		18, 0, 0, 0 	/* 1st level */
131 	};
132 
133 static const SID *systemsid = (const SID*)systemsidbytes;
134 
135 /*
136  *		SID for generic creator-owner
137  *		S-1-3-0
138  */
139 
140 static const char ownersidbytes[] = {
141 		1,		/* revision */
142 		1,		/* auth count */
143 		0, 0, 0, 0, 0, 3,	/* base */
144 		0, 0, 0, 0	/* 1st level */
145 } ;
146 
147 static const SID *ownersid = (const SID*)ownersidbytes;
148 
149 /*
150  *		SID for generic creator-group
151  *		S-1-3-1
152  */
153 
154 static const char groupsidbytes[] = {
155 		1,		/* revision */
156 		1,		/* auth count */
157 		0, 0, 0, 0, 0, 3,	/* base */
158 		1, 0, 0, 0	/* 1st level */
159 } ;
160 
161 static const SID *groupsid = (const SID*)groupsidbytes;
162 
163 /*
164  *		Determine the size of a SID
165  */
166 
167 int ntfs_sid_size(const SID * sid)
168 {
169 	return (sid->sub_authority_count * 4 + 8);
170 }
171 
172 /*
173  *		Test whether two SID are equal
174  */
175 
176 BOOL ntfs_same_sid(const SID *first, const SID *second)
177 {
178 	int size;
179 
180 	size = ntfs_sid_size(first);
181 	return ((ntfs_sid_size(second) == size)
182 		&& !memcmp(first, second, size));
183 }
184 
185 /*
186  *		Test whether a SID means "world user"
187  *	Local users group recognized as world
188  *	Also interactive users so that /Users/Public is world accessible,
189  *	but only if Posix ACLs are not enabled (if Posix ACLs are enabled,
190  *	access to /Users/Public should be done by defining interactive users
191  *	as a mapped group.)
192  */
193 
194 static int is_world_sid(const SID * usid)
195 {
196 	return (
197 	     /* check whether S-1-1-0 : world */
198 	       ((usid->sub_authority_count == 1)
199 	    && (usid->identifier_authority.high_part ==  const_cpu_to_be16(0))
200 	    && (usid->identifier_authority.low_part ==  const_cpu_to_be32(1))
201 	    && (usid->sub_authority[0] == const_cpu_to_le32(0)))
202 
203 	     /* check whether S-1-5-32-545 : local user */
204 	  ||   ((usid->sub_authority_count == 2)
205 	    && (usid->identifier_authority.high_part ==  const_cpu_to_be16(0))
206 	    && (usid->identifier_authority.low_part ==  const_cpu_to_be32(5))
207 	    && (usid->sub_authority[0] == const_cpu_to_le32(32))
208 	    && (usid->sub_authority[1] == const_cpu_to_le32(545)))
209 
210 	     /* check whether S-1-5-11 : authenticated user */
211 	  ||   ((usid->sub_authority_count == 1)
212 	    && (usid->identifier_authority.high_part ==  const_cpu_to_be16(0))
213 	    && (usid->identifier_authority.low_part ==  const_cpu_to_be32(5))
214 	    && (usid->sub_authority[0] == const_cpu_to_le32(11)))
215 
216 #if !POSIXACLS
217 	     /* check whether S-1-5-4 : interactive user */
218 	  ||   ((usid->sub_authority_count == 1)
219 	    && (usid->identifier_authority.high_part ==  const_cpu_to_be16(0))
220 	    && (usid->identifier_authority.low_part ==  const_cpu_to_be32(5))
221 	    && (usid->sub_authority[0] == const_cpu_to_le32(4)))
222 #endif /* !POSIXACLS */
223 		);
224 }
225 
226 /*
227  *		Test whether a SID means "some user (or group)"
228  *	Currently we only check for S-1-5-21... but we should
229  *	probably test for other configurations
230  */
231 
232 BOOL ntfs_is_user_sid(const SID *usid)
233 {
234 	return ((usid->sub_authority_count == 5)
235 	    && (usid->identifier_authority.high_part ==  const_cpu_to_be16(0))
236 	    && (usid->identifier_authority.low_part ==  const_cpu_to_be32(5))
237 	    && (usid->sub_authority[0] ==  const_cpu_to_le32(21)));
238 }
239 
240 /*
241  *		Test whether a SID means "some special group"
242  *	Currently we only check for a few S-1-5-n but we should
243  *	probably test for other configurations.
244  *
245  *	This is useful for granting access to /Users/Public for
246  *	specific users when the Posix ACLs are enabled.
247  */
248 
249 static BOOL ntfs_known_group_sid(const SID *usid)
250 {
251 			/* count == 1 excludes S-1-5-5-X-Y (logon) */
252 	return ((usid->sub_authority_count == 1)
253 	    && (usid->identifier_authority.high_part ==  const_cpu_to_be16(0))
254 	    && (usid->identifier_authority.low_part ==  const_cpu_to_be32(5))
255 	    && (le32_to_cpu(usid->sub_authority[0]) >=  1)
256 	    && (le32_to_cpu(usid->sub_authority[0]) <=  6));
257 }
258 
259 /*
260  *		Determine the size of a security attribute
261  *	whatever the order of fields
262  */
263 
264 unsigned int ntfs_attr_size(const char *attr)
265 {
266 	const SECURITY_DESCRIPTOR_RELATIVE *phead;
267 	const ACL *pdacl;
268 	const ACL *psacl;
269 	const SID *psid;
270 	unsigned int offdacl;
271 	unsigned int offsacl;
272 	unsigned int offowner;
273 	unsigned int offgroup;
274 	unsigned int endsid;
275 	unsigned int endacl;
276 	unsigned int attrsz;
277 
278 	phead = (const SECURITY_DESCRIPTOR_RELATIVE*)attr;
279 		/*
280 		 * First check group, which is the last field in all descriptors
281 		 * we build, and in most descriptors built by Windows
282 		 */
283 	attrsz = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
284 	offgroup = le32_to_cpu(phead->group);
285 	if (offgroup >= attrsz) {
286 			/* find end of GSID */
287 		psid = (const SID*)&attr[offgroup];
288 		endsid = offgroup + ntfs_sid_size(psid);
289 		if (endsid > attrsz) attrsz = endsid;
290 	}
291 	offowner = le32_to_cpu(phead->owner);
292 	if (offowner >= attrsz) {
293 			/* find end of USID */
294 		psid = (const SID*)&attr[offowner];
295 		endsid = offowner + ntfs_sid_size(psid);
296 		attrsz = endsid;
297 	}
298 	offsacl = le32_to_cpu(phead->sacl);
299 	if (offsacl >= attrsz) {
300 			/* find end of SACL */
301 		psacl = (const ACL*)&attr[offsacl];
302 		endacl = offsacl + le16_to_cpu(psacl->size);
303 		if (endacl > attrsz)
304 			attrsz = endacl;
305 	}
306 
307 
308 		/* find end of DACL */
309 	offdacl = le32_to_cpu(phead->dacl);
310 	if (offdacl >= attrsz) {
311 		pdacl = (const ACL*)&attr[offdacl];
312 		endacl = offdacl + le16_to_cpu(pdacl->size);
313 		if (endacl > attrsz)
314 			attrsz = endacl;
315 	}
316 	return (attrsz);
317 }
318 
319 /**
320  * ntfs_valid_sid - determine if a SID is valid
321  * @sid:	SID for which to determine if it is valid
322  *
323  * Determine if the SID pointed to by @sid is valid.
324  *
325  * Return TRUE if it is valid and FALSE otherwise.
326  */
327 BOOL ntfs_valid_sid(const SID *sid)
328 {
329 	return sid && sid->revision == SID_REVISION &&
330 		sid->sub_authority_count <= SID_MAX_SUB_AUTHORITIES;
331 }
332 
333 /*
334  *		Check whether a SID is acceptable for an implicit
335  *	mapping pattern.
336  *	It should have been already checked it is a valid user SID.
337  *
338  *	The last authority reference has to be >= 1000 (Windows usage)
339  *	and <= 0x7fffffff, so that 30 bits from a uid and 30 more bits
340  *      from a gid an be inserted with no overflow.
341  */
342 
343 BOOL ntfs_valid_pattern(const SID *sid)
344 {
345 	int cnt;
346 	u32 auth;
347 	le32 leauth;
348 
349 	cnt = sid->sub_authority_count;
350 	leauth = sid->sub_authority[cnt-1];
351 	auth = le32_to_cpu(leauth);
352 	return ((auth >= 1000) && (auth <= 0x7fffffff));
353 }
354 
355 /*
356  *		Compute the uid or gid associated to a SID
357  *	through an implicit mapping
358  *
359  *	Returns 0 (root) if it does not match pattern
360  */
361 
362 static u32 findimplicit(const SID *xsid, const SID *pattern, int parity)
363 {
364 	BIGSID defsid;
365 	SID *psid;
366 	u32 xid; /* uid or gid */
367 	int cnt;
368 	u32 carry;
369 	le32 leauth;
370 	u32 uauth;
371 	u32 xlast;
372 	u32 rlast;
373 
374 	memcpy(&defsid,pattern,ntfs_sid_size(pattern));
375 	psid = (SID*)&defsid;
376 	cnt = psid->sub_authority_count;
377 	xid = 0;
378 	if (xsid->sub_authority_count == cnt) {
379 		psid->sub_authority[cnt-1] = xsid->sub_authority[cnt-1];
380 		leauth = xsid->sub_authority[cnt-1];
381 		xlast = le32_to_cpu(leauth);
382 		leauth = pattern->sub_authority[cnt-1];
383 		rlast = le32_to_cpu(leauth);
384 
385 		if ((xlast > rlast) && !((xlast ^ rlast ^ parity) & 1)) {
386 			/* direct check for basic situation */
387 			if (ntfs_same_sid(psid,xsid))
388 				xid = ((xlast - rlast) >> 1) & 0x3fffffff;
389 			else {
390 				/*
391 				 * check whether part of mapping had to be
392 				 * recorded in a higher level authority
393 			 	 */
394 				carry = 1;
395 				do {
396 					leauth = psid->sub_authority[cnt-2];
397 					uauth = le32_to_cpu(leauth) + 1;
398 					psid->sub_authority[cnt-2]
399 						= cpu_to_le32(uauth);
400 				} while (!ntfs_same_sid(psid,xsid)
401 					 && (++carry < 4));
402 				if (carry < 4)
403 					xid = (((xlast - rlast) >> 1)
404 						& 0x3fffffff) | (carry << 30);
405 			}
406 		}
407 	}
408 	return (xid);
409 }
410 
411 /*
412  *		Find usid mapped to a Linux user
413  *	Returns NULL if not found
414  */
415 
416 const SID *ntfs_find_usid(const struct MAPPING* usermapping,
417 		uid_t uid, SID *defusid)
418 {
419 	const struct MAPPING *p;
420 	const SID *sid;
421 	le32 leauth;
422 	u32 uauth;
423 	int cnt;
424 
425 	if (!uid)
426 		sid = adminsid;
427 	else {
428 		p = usermapping;
429 		while (p && p->xid && ((uid_t)p->xid != uid))
430 			p = p->next;
431 		if (p && !p->xid) {
432 			/*
433 			 * default pattern has been reached :
434 			 * build an implicit SID according to pattern
435 			 * (the pattern format was checked while reading
436 			 * the mapping file)
437 			 */
438 			memcpy(defusid, p->sid, ntfs_sid_size(p->sid));
439 			cnt = defusid->sub_authority_count;
440 			leauth = defusid->sub_authority[cnt-1];
441 			uauth = le32_to_cpu(leauth) + 2*(uid & 0x3fffffff);
442 			defusid->sub_authority[cnt-1] = cpu_to_le32(uauth);
443 			if (uid & 0xc0000000) {
444 				leauth = defusid->sub_authority[cnt-2];
445 				uauth = le32_to_cpu(leauth) + ((uid >> 30) & 3);
446 				defusid->sub_authority[cnt-2] = cpu_to_le32(uauth);
447 			}
448 			sid = defusid;
449 		} else
450 			sid = (p ? p->sid : (const SID*)NULL);
451 	}
452 	return (sid);
453 }
454 
455 /*
456  *		Find Linux group mapped to a gsid
457  *	Returns 0 (root) if not found
458  */
459 
460 const SID *ntfs_find_gsid(const struct MAPPING* groupmapping,
461 		gid_t gid, SID *defgsid)
462 {
463 	const struct MAPPING *p;
464 	const SID *sid;
465 	le32 leauth;
466 	u32 uauth;
467 	int cnt;
468 
469 	if (!gid)
470 		sid = adminsid;
471 	else {
472 		p = groupmapping;
473 		while (p && p->xid && ((gid_t)p->xid != gid))
474 			p = p->next;
475 		if (p && !p->xid) {
476 			/*
477 			 * default pattern has been reached :
478 			 * build an implicit SID according to pattern
479 			 * (the pattern format was checked while reading
480 			 * the mapping file)
481 			 */
482 			memcpy(defgsid, p->sid, ntfs_sid_size(p->sid));
483 			cnt = defgsid->sub_authority_count;
484 			leauth = defgsid->sub_authority[cnt-1];
485 			uauth = le32_to_cpu(leauth) + 2*(gid & 0x3fffffff) + 1;
486 			defgsid->sub_authority[cnt-1] = cpu_to_le32(uauth);
487 			if (gid & 0xc0000000) {
488 				leauth = defgsid->sub_authority[cnt-2];
489 				uauth = le32_to_cpu(leauth) + ((gid >> 30) & 3);
490 				defgsid->sub_authority[cnt-2] = cpu_to_le32(uauth);
491 			}
492 			sid = defgsid;
493 		} else
494 			sid = (p ? p->sid : (const SID*)NULL);
495 	}
496 	return (sid);
497 }
498 
499 /*
500  *		Find Linux owner mapped to a usid
501  *	Returns 0 (root) if not found
502  */
503 
504 uid_t ntfs_find_user(const struct MAPPING* usermapping, const SID *usid)
505 {
506 	uid_t uid;
507 	const struct MAPPING *p;
508 
509 	p = usermapping;
510 	while (p && p->xid && !ntfs_same_sid(usid, p->sid))
511 		p = p->next;
512 	if (p && !p->xid)
513 		/*
514 		 * No explicit mapping found, try implicit mapping
515 		 */
516 		uid = findimplicit(usid,p->sid,0);
517 	else
518 		uid = (p ? p->xid : 0);
519 	return (uid);
520 }
521 
522 /*
523  *		Find Linux group mapped to a gsid
524  *	Returns 0 (root) if not found
525  */
526 
527 gid_t ntfs_find_group(const struct MAPPING* groupmapping, const SID * gsid)
528 {
529 	gid_t gid;
530 	const struct MAPPING *p;
531 
532 	p = groupmapping;
533 	while (p && p->xid && !ntfs_same_sid(gsid, p->sid))
534 		p = p->next;
535 	if (p && !p->xid)
536 		/*
537 		 * No explicit mapping found, try implicit mapping
538 		 */
539 		gid = findimplicit(gsid,p->sid,1);
540 	else
541 		gid = (p ? p->xid : 0);
542 	return (gid);
543 }
544 
545 /*
546  *		Check the validity of the ACEs in a DACL or SACL
547  */
548 
549 static BOOL valid_acl(const ACL *pacl, unsigned int end)
550 {
551 	const ACCESS_ALLOWED_ACE *pace;
552 	unsigned int offace;
553 	unsigned int acecnt;
554 	unsigned int acesz;
555 	unsigned int nace;
556 	unsigned int wantsz;
557 	BOOL ok;
558 
559 	ok = TRUE;
560 	acecnt = le16_to_cpu(pacl->ace_count);
561 	offace = sizeof(ACL);
562 	for (nace = 0; (nace < acecnt) && ok; nace++) {
563 		/* be sure the beginning is within range */
564 		if ((offace + sizeof(ACCESS_ALLOWED_ACE)) > end)
565 			ok = FALSE;
566 		else {
567 			pace = (const ACCESS_ALLOWED_ACE*)
568 				&((const char*)pacl)[offace];
569 			acesz = le16_to_cpu(pace->size);
570 			switch (pace->type) {
571 			case ACCESS_ALLOWED_ACE_TYPE :
572 			case ACCESS_DENIED_ACE_TYPE :
573 				wantsz = ntfs_sid_size(&pace->sid) + 8;
574 				if (((offace + acesz) > end)
575 				    || !ntfs_valid_sid(&pace->sid)
576 				    || (wantsz != acesz))
577 					ok = FALSE;
578 				break;
579 			case SYSTEM_AUDIT_ACE_TYPE :
580 			case ACCESS_ALLOWED_CALLBACK_ACE_TYPE :
581 			case ACCESS_DENIED_CALLBACK_ACE_TYPE :
582 			case SYSTEM_AUDIT_CALLBACK_ACE_TYPE :
583 			case SYSTEM_MANDATORY_LABEL_ACE_TYPE :
584 			case SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE :
585 			case SYSTEM_SCOPED_POLICY_ID_ACE_TYPE :
586 				/* Extra data after the SID */
587 				wantsz = ntfs_sid_size(&pace->sid) + 8;
588 				if (((offace + acesz) > end)
589 				    || !ntfs_valid_sid(&pace->sid)
590 				    || (wantsz > acesz))
591 					ok = FALSE;
592 				break;
593 			default :
594 				/* SID at a different location */
595 				if ((offace + acesz) > end)
596 					ok = FALSE;
597 				break;
598 			}
599 			offace += acesz;
600 		}
601 	}
602 	return (ok);
603 }
604 
605 /*
606  *		Do sanity checks on security descriptors read from storage
607  *	basically, we make sure that every field holds within
608  *	allocated storage
609  *	Should not be called with a NULL argument
610  *	returns TRUE if considered safe
611  *		if not, error should be logged by caller
612  */
613 
614 BOOL ntfs_valid_descr(const char *securattr, unsigned int attrsz)
615 {
616 	const SECURITY_DESCRIPTOR_RELATIVE *phead;
617 	const ACL *pdacl;
618 	const ACL *psacl;
619 	unsigned int offdacl;
620 	unsigned int offsacl;
621 	unsigned int offowner;
622 	unsigned int offgroup;
623 	BOOL ok;
624 
625 	ok = TRUE;
626 
627 	/*
628 	 * first check overall size if within allocation range
629 	 * and a DACL is present
630 	 * and owner and group SID are valid
631 	 */
632 
633 	phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr;
634 	offdacl = le32_to_cpu(phead->dacl);
635 	offsacl = le32_to_cpu(phead->sacl);
636 	offowner = le32_to_cpu(phead->owner);
637 	offgroup = le32_to_cpu(phead->group);
638 	pdacl = (const ACL*)&securattr[offdacl];
639 	psacl = (const ACL*)&securattr[offsacl];
640 
641 		/*
642 		 * size check occurs before the above pointers are used
643 		 *
644 		 * "DR Watson" standard directory on WinXP has an
645 		 * old revision and no DACL though SE_DACL_PRESENT is set
646 		 */
647 	if ((attrsz >= sizeof(SECURITY_DESCRIPTOR_RELATIVE))
648 		&& (phead->revision == SECURITY_DESCRIPTOR_REVISION)
649 		&& (offowner >= sizeof(SECURITY_DESCRIPTOR_RELATIVE))
650 		&& ((offowner + 2) < attrsz)
651 		&& (offgroup >= sizeof(SECURITY_DESCRIPTOR_RELATIVE))
652 		&& ((offgroup + 2) < attrsz)
653 		&& (!offdacl
654 			|| ((offdacl >= sizeof(SECURITY_DESCRIPTOR_RELATIVE))
655 			    && (offdacl+sizeof(ACL) <= attrsz)))
656 		&& (!offsacl
657 			|| ((offsacl >= sizeof(SECURITY_DESCRIPTOR_RELATIVE))
658 			    && (offsacl+sizeof(ACL) <= attrsz)))
659 		&& !(phead->owner & const_cpu_to_le32(3))
660 		&& !(phead->group & const_cpu_to_le32(3))
661 		&& !(phead->dacl & const_cpu_to_le32(3))
662 		&& !(phead->sacl & const_cpu_to_le32(3))
663 		&& (ntfs_attr_size(securattr) <= attrsz)
664 		&& ntfs_valid_sid((const SID*)&securattr[offowner])
665 		&& ntfs_valid_sid((const SID*)&securattr[offgroup])
666 			/*
667 			 * if there is an ACL, as indicated by offdacl,
668 			 * require SE_DACL_PRESENT
669 			 * but "Dr Watson" has SE_DACL_PRESENT though no DACL
670 			 */
671 		&& (!offdacl
672 		    || ((phead->control & SE_DACL_PRESENT)
673 			&& ((pdacl->revision == ACL_REVISION)
674 			   || (pdacl->revision == ACL_REVISION_DS))))
675 			/* same for SACL */
676 		&& (!offsacl
677 		    || ((phead->control & SE_SACL_PRESENT)
678 			&& ((psacl->revision == ACL_REVISION)
679 			    || (psacl->revision == ACL_REVISION_DS))))) {
680 			/*
681 			 *  Check the DACL and SACL if present
682 			 */
683 		if ((offdacl && !valid_acl(pdacl,attrsz - offdacl))
684 		   || (offsacl && !valid_acl(psacl,attrsz - offsacl)))
685 			ok = FALSE;
686 	} else
687 		ok = FALSE;
688 	return (ok);
689 }
690 
691 /*
692  *		Copy the inheritable parts of an ACL
693  *
694  *	Returns the size of the new ACL
695  *		or zero if nothing is inheritable
696  */
697 
698 int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl,
699 			const SID *usid, const SID *gsid, BOOL fordir,
700 			le16 inherited)
701 {
702 	unsigned int src;
703 	unsigned int dst;
704 	int oldcnt;
705 	int newcnt;
706 	unsigned int selection;
707 	int nace;
708 	int acesz;
709 	int usidsz;
710 	int gsidsz;
711 	BOOL acceptable;
712 	const ACCESS_ALLOWED_ACE *poldace;
713 	ACCESS_ALLOWED_ACE *pnewace;
714 	ACCESS_ALLOWED_ACE *pauthace;
715 	ACCESS_ALLOWED_ACE *pownerace;
716 
717 	pauthace = (ACCESS_ALLOWED_ACE*)NULL;
718 	pownerace = (ACCESS_ALLOWED_ACE*)NULL;
719 	usidsz = ntfs_sid_size(usid);
720 	gsidsz = ntfs_sid_size(gsid);
721 
722 	/* ACL header */
723 
724 	newacl->revision = ACL_REVISION;
725 	newacl->alignment1 = 0;
726 	newacl->alignment2 = const_cpu_to_le16(0);
727 	src = dst = sizeof(ACL);
728 
729 	selection = (fordir ? CONTAINER_INHERIT_ACE : OBJECT_INHERIT_ACE);
730 	newcnt = 0;
731 	oldcnt = le16_to_cpu(oldacl->ace_count);
732 	for (nace = 0; nace < oldcnt; nace++) {
733 		poldace = (const ACCESS_ALLOWED_ACE*)((const char*)oldacl + src);
734 		acesz = le16_to_cpu(poldace->size);
735 		src += acesz;
736 		/*
737 		 * Currently only ACE for file or directory access are
738 		 * processed. More information needed about what to do
739 		 * for other types (whose SID may be at a different location)
740 		 */
741 		switch (poldace->type) {
742 		case ACCESS_ALLOWED_ACE_TYPE :
743 		case ACCESS_DENIED_ACE_TYPE :
744 			acceptable = TRUE;
745 			break;
746 		default :
747 			acceptable = FALSE;
748 			break;
749 		}
750 		/*
751 		 * Extract inheritance for access, including inheritance for
752 		 * access from an ACE with is both applied and inheritable.
753 		 *
754 		 * must not output OBJECT_INHERIT_ACE or CONTAINER_INHERIT_ACE
755 		 *
756 		 *	According to MSDN :
757 		 * "For a case in which a container object inherits an ACE
758 		 * "that is both effective on the container and inheritable
759 		 * "by its descendants, the container may inherit two ACEs.
760 		 * "This occurs if the inheritable ACE contains generic
761 		 * "information."
762 		 */
763 		if ((poldace->flags & selection)
764 		    && acceptable
765 		    && (!fordir
766 			|| (poldace->flags & NO_PROPAGATE_INHERIT_ACE)
767 			|| (poldace->mask & (GENERIC_ALL | GENERIC_READ
768 					| GENERIC_WRITE | GENERIC_EXECUTE)))
769 		    && !ntfs_same_sid(&poldace->sid, ownersid)
770 		    && !ntfs_same_sid(&poldace->sid, groupsid)) {
771 			pnewace = (ACCESS_ALLOWED_ACE*)
772 					((char*)newacl + dst);
773 			memcpy(pnewace,poldace,acesz);
774 				/* reencode GENERIC_ALL */
775 			if (pnewace->mask & GENERIC_ALL) {
776 				pnewace->mask &= ~GENERIC_ALL;
777 				if (fordir)
778 					pnewace->mask |= OWNER_RIGHTS
779 							| DIR_READ
780 							| DIR_WRITE
781 							| DIR_EXEC;
782 				else
783 			/*
784 			 * The last flag is not defined for a file,
785 			 * however Windows sets it, so do the same
786 			 */
787 					pnewace->mask |= OWNER_RIGHTS
788 							| FILE_READ
789 							| FILE_WRITE
790 							| FILE_EXEC
791 							| const_cpu_to_le32(0x40);
792 			}
793 				/* reencode GENERIC_READ (+ EXECUTE) */
794 			if (pnewace->mask & GENERIC_READ) {
795 				if (fordir)
796 					pnewace->mask |= OWNER_RIGHTS
797 							| DIR_READ
798 							| DIR_EXEC;
799 				else
800 					pnewace->mask |= OWNER_RIGHTS
801 							| FILE_READ
802 							| FILE_EXEC;
803 				pnewace->mask &= ~(GENERIC_READ
804 						| GENERIC_EXECUTE
805 						| WRITE_DAC
806 						| WRITE_OWNER
807 						| DELETE | FILE_WRITE_EA
808 						| FILE_WRITE_ATTRIBUTES);
809 			}
810 				/* reencode GENERIC_WRITE */
811 			if (pnewace->mask & GENERIC_WRITE) {
812 				if (fordir)
813 					pnewace->mask |= OWNER_RIGHTS
814 							| DIR_WRITE;
815 				else
816 					pnewace->mask |= OWNER_RIGHTS
817 							| FILE_WRITE;
818 				pnewace->mask &= ~(GENERIC_WRITE
819 							| WRITE_DAC
820 							| WRITE_OWNER
821 							| FILE_DELETE_CHILD);
822 			}
823 				/* remove inheritance flags */
824 			pnewace->flags &= ~(OBJECT_INHERIT_ACE
825 						| CONTAINER_INHERIT_ACE
826 						| INHERIT_ONLY_ACE);
827 			/*
828 			 * Group similar ACE for authenticated users
829 			 * (should probably be done for other SIDs)
830 			 */
831 			if ((poldace->type == ACCESS_ALLOWED_ACE_TYPE)
832 			    && ntfs_same_sid(&poldace->sid, authsid)) {
833 				if (pauthace) {
834 					pauthace->flags |= pnewace->flags;
835 					pauthace->mask |= pnewace->mask;
836 				} else {
837 					pauthace = pnewace;
838 					if (inherited)
839 						pnewace->flags |= INHERITED_ACE;
840 					dst += acesz;
841 					newcnt++;
842 				}
843 			} else {
844 				if (inherited)
845 					pnewace->flags |= INHERITED_ACE;
846 				dst += acesz;
847 				newcnt++;
848 			}
849 		}
850 			/*
851 			 * Inheritance for access, specific to
852 			 * creator-owner (and creator-group)
853 			 */
854 		if ((fordir || !inherited
855 			|| (poldace->flags
856 			   & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)))
857 		    && acceptable) {
858 			pnewace = (ACCESS_ALLOWED_ACE*)
859 					((char*)newacl + dst);
860 			memcpy(pnewace,poldace,acesz);
861 				/*
862 				 * Replace generic creator-owner and
863 				 * creator-group by owner and group
864 				 * (but keep for further inheritance)
865 				 */
866 			if (ntfs_same_sid(&pnewace->sid, ownersid)) {
867 				memcpy(&pnewace->sid, usid, usidsz);
868 				pnewace->size = cpu_to_le16(usidsz + 8);
869 					/* remove inheritance flags */
870 				pnewace->flags &= ~(OBJECT_INHERIT_ACE
871 						| CONTAINER_INHERIT_ACE
872 						| INHERIT_ONLY_ACE);
873 				if (inherited)
874 					pnewace->flags |= INHERITED_ACE;
875 				if ((pnewace->type == ACCESS_ALLOWED_ACE_TYPE)
876 				    && pownerace
877 				    && !(pnewace->flags & ~pownerace->flags)) {
878 					pownerace->mask |= pnewace->mask;
879 				} else {
880 					dst += usidsz + 8;
881 					newcnt++;
882 				}
883 			}
884 			if (ntfs_same_sid(&pnewace->sid, groupsid)) {
885 				memcpy(&pnewace->sid, gsid, gsidsz);
886 				pnewace->size = cpu_to_le16(gsidsz + 8);
887 					/* remove inheritance flags */
888 				pnewace->flags &= ~(OBJECT_INHERIT_ACE
889 						| CONTAINER_INHERIT_ACE
890 						| INHERIT_ONLY_ACE);
891 				if (inherited)
892 					pnewace->flags |= INHERITED_ACE;
893 				dst += gsidsz + 8;
894 				newcnt++;
895 			}
896 		}
897 
898 			/*
899 			 * inheritance for further inheritance
900 			 *
901 			 * Situations leading to output CONTAINER_INHERIT_ACE
902 			 * 	or OBJECT_INHERIT_ACE
903 			 */
904 		if (fordir
905 		   && (poldace->flags
906 			   & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE))) {
907 			pnewace = (ACCESS_ALLOWED_ACE*)
908 					((char*)newacl + dst);
909 			memcpy(pnewace,poldace,acesz);
910 			if ((poldace->flags & OBJECT_INHERIT_ACE)
911 			   && !(poldace->flags & (CONTAINER_INHERIT_ACE
912 					| NO_PROPAGATE_INHERIT_ACE)))
913 				pnewace->flags |= INHERIT_ONLY_ACE;
914 			if (acceptable
915 			    && (poldace->flags & CONTAINER_INHERIT_ACE)
916 			    && !(poldace->flags & NO_PROPAGATE_INHERIT_ACE)
917 			    && !ntfs_same_sid(&poldace->sid, ownersid)
918 			    && !ntfs_same_sid(&poldace->sid, groupsid)) {
919 				if ((poldace->mask & (GENERIC_ALL | GENERIC_READ
920 					| GENERIC_WRITE | GENERIC_EXECUTE)))
921 					pnewace->flags |= INHERIT_ONLY_ACE;
922 				else
923 					pnewace->flags &= ~INHERIT_ONLY_ACE;
924 			}
925 			if (inherited)
926 				pnewace->flags |= INHERITED_ACE;
927 			/*
928 			 * Prepare grouping similar ACE for authenticated users
929 			 */
930 			if ((poldace->type == ACCESS_ALLOWED_ACE_TYPE)
931 			    && !pauthace
932 			    && !(pnewace->flags & INHERIT_ONLY_ACE)
933 			    && ntfs_same_sid(&poldace->sid, authsid)) {
934 				pauthace = pnewace;
935 			}
936 			/*
937 			 * Prepare grouping similar ACE for owner
938 			 */
939 			if ((poldace->type == ACCESS_ALLOWED_ACE_TYPE)
940 			    && !pownerace
941 			    && !(pnewace->flags & INHERIT_ONLY_ACE)
942 			    && ntfs_same_sid(&poldace->sid, usid)) {
943 				pownerace = pnewace;
944 			}
945 			dst += acesz;
946 			newcnt++;
947 		}
948 	}
949 		/*
950 		 * Adjust header if something was inherited
951 		 */
952 	if (dst > sizeof(ACL)) {
953 		newacl->ace_count = cpu_to_le16(newcnt);
954 		newacl->size = cpu_to_le16(dst);
955 	} else
956 		dst = 0;
957 	return (dst);
958 }
959 
960 #if POSIXACLS
961 
962 /*
963  *		Do sanity checks on a Posix descriptor
964  *	Should not be called with a NULL argument
965  *	returns TRUE if considered safe
966  *		if not, error should be logged by caller
967  */
968 
969 BOOL ntfs_valid_posix(const struct POSIX_SECURITY *pxdesc)
970 {
971 	const struct POSIX_ACL *pacl;
972 	int i;
973 	BOOL ok;
974 	u16 tag;
975 	u32 id;
976 	int perms;
977 	struct {
978 		u16 previous;
979 		u32 previousid;
980 		u16 tagsset;
981 		mode_t mode;
982 		int owners;
983 		int groups;
984 		int others;
985 	} checks[2], *pchk;
986 
987 	for (i=0; i<2; i++) {
988 		checks[i].mode = 0;
989 		checks[i].tagsset = 0;
990 		checks[i].owners = 0;
991 		checks[i].groups = 0;
992 		checks[i].others = 0;
993 		checks[i].previous = 0;
994 		checks[i].previousid = 0;
995 	}
996 	ok = TRUE;
997 	pacl = &pxdesc->acl;
998 			/*
999 			 * header (strict for now)
1000 			 */
1001 	if ((pacl->version != POSIX_VERSION)
1002 	    || (pacl->flags != 0)
1003 	    || (pacl->filler != 0))
1004 		ok = FALSE;
1005 			/*
1006 			 * Reject multiple owner, group or other
1007 			 * but do not require them to be present
1008 			 * Also check the ACEs are in correct order
1009 			 * which implies there is no duplicates
1010 			 */
1011 	for (i=0; i<pxdesc->acccnt + pxdesc->defcnt; i++) {
1012 		if (i >= pxdesc->firstdef)
1013 			pchk = &checks[1];
1014 		else
1015 			pchk = &checks[0];
1016 		perms = pacl->ace[i].perms;
1017 		tag = pacl->ace[i].tag;
1018 		pchk->tagsset |= tag;
1019 		id = pacl->ace[i].id;
1020 		if (perms & ~7) ok = FALSE;
1021 		if ((tag < pchk->previous)
1022 			|| ((tag == pchk->previous)
1023 			 && (id <= pchk->previousid)))
1024 				ok = FALSE;
1025 		pchk->previous = tag;
1026 		pchk->previousid = id;
1027 		switch (tag) {
1028 		case POSIX_ACL_USER_OBJ :
1029 			if (pchk->owners++)
1030 				ok = FALSE;
1031 			if (id != (u32)-1)
1032 				ok = FALSE;
1033 			pchk->mode |= perms << 6;
1034 			break;
1035 		case POSIX_ACL_GROUP_OBJ :
1036 			if (pchk->groups++)
1037 				ok = FALSE;
1038 			if (id != (u32)-1)
1039 				ok = FALSE;
1040 			pchk->mode = (pchk->mode & 07707) | (perms << 3);
1041 			break;
1042 		case POSIX_ACL_OTHER :
1043 			if (pchk->others++)
1044 				ok = FALSE;
1045 			if (id != (u32)-1)
1046 				ok = FALSE;
1047 			pchk->mode |= perms;
1048 			break;
1049 		case POSIX_ACL_USER :
1050 		case POSIX_ACL_GROUP :
1051 			if (id == (u32)-1)
1052 				ok = FALSE;
1053 			break;
1054 		case POSIX_ACL_MASK :
1055 			if (id != (u32)-1)
1056 				ok = FALSE;
1057 			pchk->mode = (pchk->mode & 07707) | (perms << 3);
1058 			break;
1059 		default :
1060 			ok = FALSE;
1061 			break;
1062 		}
1063 	}
1064 	if ((pxdesc->acccnt > 0)
1065 	   && ((checks[0].owners != 1) || (checks[0].groups != 1)
1066 		|| (checks[0].others != 1)))
1067 		ok = FALSE;
1068 		/* do not check owner, group or other are present in */
1069 		/* the default ACL, Windows does not necessarily set them */
1070 			/* descriptor */
1071 	if (pxdesc->defcnt && (pxdesc->acccnt > pxdesc->firstdef))
1072 		ok = FALSE;
1073 	if ((pxdesc->acccnt < 0) || (pxdesc->defcnt < 0))
1074 		ok = FALSE;
1075 			/* check mode, unless null or no tag set */
1076 	if (pxdesc->mode
1077 	    && checks[0].tagsset
1078 	    && (checks[0].mode != (pxdesc->mode & 0777)))
1079 		ok = FALSE;
1080 			/* check tagsset */
1081 	if (pxdesc->tagsset != checks[0].tagsset)
1082 		ok = FALSE;
1083 	return (ok);
1084 }
1085 
1086 /*
1087  *		Set standard header data into a Posix ACL
1088  *	The mode argument should provide the 3 upper bits of target mode
1089  */
1090 
1091 static mode_t posix_header(struct POSIX_SECURITY *pxdesc, mode_t basemode)
1092 {
1093 	mode_t mode;
1094 	u16 tagsset;
1095 	struct POSIX_ACE *pace;
1096 	int i;
1097 
1098 	mode = basemode & 07000;
1099 	tagsset = 0;
1100 	for (i=0; i<pxdesc->acccnt; i++) {
1101 		pace = &pxdesc->acl.ace[i];
1102 		tagsset |= pace->tag;
1103 		switch(pace->tag) {
1104 		case POSIX_ACL_USER_OBJ :
1105 			mode |= (pace->perms & 7) << 6;
1106 			break;
1107 		case POSIX_ACL_GROUP_OBJ :
1108 		case POSIX_ACL_MASK :
1109 			mode = (mode & 07707) | ((pace->perms & 7) << 3);
1110 			break;
1111 		case POSIX_ACL_OTHER :
1112 			mode |= pace->perms & 7;
1113 			break;
1114 		default :
1115 			break;
1116 		}
1117 	}
1118 	pxdesc->tagsset = tagsset;
1119 	pxdesc->mode = mode;
1120 	pxdesc->acl.version = POSIX_VERSION;
1121 	pxdesc->acl.flags = 0;
1122 	pxdesc->acl.filler = 0;
1123 	return (mode);
1124 }
1125 
1126 /*
1127  *		Sort ACEs in a Posix ACL
1128  *	This is useful for always getting reusable converted ACLs,
1129  *	it also helps in merging ACEs.
1130  *	Repeated tag+id are allowed and not merged here.
1131  *
1132  *	Tags should be in ascending sequence and for a repeatable tag
1133  *	ids should be in ascending sequence.
1134  */
1135 
1136 void ntfs_sort_posix(struct POSIX_SECURITY *pxdesc)
1137 {
1138 	struct POSIX_ACL *pacl;
1139 	struct POSIX_ACE ace;
1140 	int i;
1141 	int offs;
1142 	BOOL done;
1143 	u16 tag;
1144 	u16 previous;
1145 	u32 id;
1146 	u32 previousid;
1147 
1148 
1149 			/*
1150 			 * Check sequencing of tag+id in access ACE's
1151 			 */
1152 	pacl = &pxdesc->acl;
1153 	do {
1154 		done = TRUE;
1155 		previous = pacl->ace[0].tag;
1156 		previousid = pacl->ace[0].id;
1157 		for (i=1; i<pxdesc->acccnt; i++) {
1158 			tag = pacl->ace[i].tag;
1159 			id = pacl->ace[i].id;
1160 
1161 			if ((tag < previous)
1162 			   || ((tag == previous) && (id < previousid))) {
1163 				done = FALSE;
1164 				memcpy(&ace,&pacl->ace[i-1],sizeof(struct POSIX_ACE));
1165 				memcpy(&pacl->ace[i-1],&pacl->ace[i],sizeof(struct POSIX_ACE));
1166 				memcpy(&pacl->ace[i],&ace,sizeof(struct POSIX_ACE));
1167 			} else {
1168 				previous = tag;
1169 				previousid = id;
1170 			}
1171 		}
1172 	} while (!done);
1173 				/*
1174 				 * Same for default ACEs
1175 				 */
1176 	do {
1177 		done = TRUE;
1178 		if ((pxdesc->defcnt) > 1) {
1179 			offs = pxdesc->firstdef;
1180 			previous = pacl->ace[offs].tag;
1181 			previousid = pacl->ace[offs].id;
1182 			for (i=offs+1; i<offs+pxdesc->defcnt; i++) {
1183 				tag = pacl->ace[i].tag;
1184 				id = pacl->ace[i].id;
1185 
1186 				if ((tag < previous)
1187 				   || ((tag == previous) && (id < previousid))) {
1188 					done = FALSE;
1189 					memcpy(&ace,&pacl->ace[i-1],sizeof(struct POSIX_ACE));
1190 					memcpy(&pacl->ace[i-1],&pacl->ace[i],sizeof(struct POSIX_ACE));
1191 					memcpy(&pacl->ace[i],&ace,sizeof(struct POSIX_ACE));
1192 				} else {
1193 					previous = tag;
1194 					previousid = id;
1195 				}
1196 			}
1197 		}
1198 	} while (!done);
1199 }
1200 
1201 /*
1202  *		Merge a new mode into a Posix descriptor
1203  *	The Posix descriptor is not reallocated, its size is unchanged
1204  *
1205  *	returns 0 if ok
1206  */
1207 
1208 int ntfs_merge_mode_posix(struct POSIX_SECURITY *pxdesc, mode_t mode)
1209 {
1210 	int i;
1211 	BOOL maskfound;
1212 	struct POSIX_ACE *pace;
1213 	int todo;
1214 
1215 	maskfound = FALSE;
1216 	todo = POSIX_ACL_USER_OBJ | POSIX_ACL_GROUP_OBJ | POSIX_ACL_OTHER;
1217 	for (i=pxdesc->acccnt-1; i>=0; i--) {
1218 		pace = &pxdesc->acl.ace[i];
1219 		switch(pace->tag) {
1220 		case POSIX_ACL_USER_OBJ :
1221 			pace->perms = (mode >> 6) & 7;
1222 			todo &= ~POSIX_ACL_USER_OBJ;
1223 			break;
1224 		case POSIX_ACL_GROUP_OBJ :
1225 			if (!maskfound)
1226 				pace->perms = (mode >> 3) & 7;
1227 			todo &= ~POSIX_ACL_GROUP_OBJ;
1228 			break;
1229 		case POSIX_ACL_MASK :
1230 			pace->perms = (mode >> 3) & 7;
1231 			maskfound = TRUE;
1232 			break;
1233 		case POSIX_ACL_OTHER :
1234 			pace->perms = mode & 7;
1235 			todo &= ~POSIX_ACL_OTHER;
1236 			break;
1237 		default :
1238 			break;
1239 		}
1240 	}
1241 	pxdesc->mode = mode;
1242 	return (todo ? -1 : 0);
1243 }
1244 
1245 /*
1246  *		Replace an access or default Posix ACL
1247  *	The resulting ACL is checked for validity
1248  *
1249  *	Returns a new ACL or NULL if there is a problem
1250  */
1251 
1252 struct POSIX_SECURITY *ntfs_replace_acl(const struct POSIX_SECURITY *oldpxdesc,
1253 		const struct POSIX_ACL *newacl, int count, BOOL deflt)
1254 {
1255 	struct POSIX_SECURITY *newpxdesc;
1256 	size_t newsize;
1257 	int offset;
1258 	int oldoffset;
1259 	int i;
1260 
1261 	if (deflt)
1262 		newsize = sizeof(struct POSIX_SECURITY)
1263 			+ (oldpxdesc->acccnt + count)*sizeof(struct POSIX_ACE);
1264 	else
1265 		newsize = sizeof(struct POSIX_SECURITY)
1266 			+ (oldpxdesc->defcnt + count)*sizeof(struct POSIX_ACE);
1267 	newpxdesc = (struct POSIX_SECURITY*)malloc(newsize);
1268 	if (newpxdesc) {
1269 		if (deflt) {
1270 			offset = oldpxdesc->acccnt;
1271 			newpxdesc->acccnt = oldpxdesc->acccnt;
1272 			newpxdesc->defcnt = count;
1273 			newpxdesc->firstdef = offset;
1274 					/* copy access ACEs */
1275 			for (i=0; i<newpxdesc->acccnt; i++)
1276 				newpxdesc->acl.ace[i] = oldpxdesc->acl.ace[i];
1277 					/* copy default ACEs */
1278 			for (i=0; i<count; i++)
1279 				newpxdesc->acl.ace[i + offset] = newacl->ace[i];
1280 		} else {
1281 			offset = count;
1282 			newpxdesc->acccnt = count;
1283 			newpxdesc->defcnt = oldpxdesc->defcnt;
1284 			newpxdesc->firstdef = count;
1285 					/* copy access ACEs */
1286 			for (i=0; i<count; i++)
1287 				newpxdesc->acl.ace[i] = newacl->ace[i];
1288 					/* copy default ACEs */
1289 			oldoffset = oldpxdesc->firstdef;
1290 			for (i=0; i<newpxdesc->defcnt; i++)
1291 				newpxdesc->acl.ace[i + offset] = oldpxdesc->acl.ace[i + oldoffset];
1292 		}
1293 			/* assume special flags unchanged */
1294 		posix_header(newpxdesc, oldpxdesc->mode);
1295 		if (!ntfs_valid_posix(newpxdesc)) {
1296 			/* do not log, this is an application error */
1297 			free(newpxdesc);
1298 			newpxdesc = (struct POSIX_SECURITY*)NULL;
1299 			errno = EINVAL;
1300 		}
1301 	} else
1302 		errno = ENOMEM;
1303 	return (newpxdesc);
1304 }
1305 
1306 /*
1307  *		Build a basic Posix ACL from a mode and umask,
1308  *	ignoring inheritance from the parent directory
1309  */
1310 
1311 struct POSIX_SECURITY *ntfs_build_basic_posix(
1312 		const struct POSIX_SECURITY *pxdesc __attribute__((unused)),
1313 		mode_t mode, mode_t mask, BOOL isdir __attribute__((unused)))
1314 {
1315 	struct POSIX_SECURITY *pydesc;
1316 	struct POSIX_ACE *pyace;
1317 
1318 	pydesc = (struct POSIX_SECURITY*)malloc(
1319 		sizeof(struct POSIX_SECURITY) + 3*sizeof(struct POSIX_ACE));
1320 	if (pydesc) {
1321 		pyace = &pydesc->acl.ace[0];
1322 		pyace->tag = POSIX_ACL_USER_OBJ;
1323 		pyace->perms = ((mode & ~mask) >> 6) & 7;
1324 		pyace->id = -1;
1325 		pyace = &pydesc->acl.ace[1];
1326 		pyace->tag = POSIX_ACL_GROUP_OBJ;
1327 		pyace->perms = ((mode & ~mask) >> 3) & 7;
1328 		pyace->id = -1;
1329 		pyace = &pydesc->acl.ace[2];
1330 		pyace->tag = POSIX_ACL_OTHER;
1331 		pyace->perms = (mode & ~mask) & 7;
1332 		pyace->id = -1;
1333 		pydesc->mode = mode;
1334 		pydesc->tagsset = POSIX_ACL_USER_OBJ
1335 				| POSIX_ACL_GROUP_OBJ
1336 				| POSIX_ACL_OTHER;
1337 		pydesc->acccnt = 3;
1338 		pydesc->defcnt = 0;
1339 		pydesc->firstdef = 6;
1340 		pydesc->filler = 0;
1341 		pydesc->acl.version = POSIX_VERSION;
1342 		pydesc->acl.flags = 0;
1343 		pydesc->acl.filler = 0;
1344 	} else
1345 		errno = ENOMEM;
1346 	return (pydesc);
1347 }
1348 
1349 /*
1350  *		Build an inherited Posix descriptor from parent
1351  *	descriptor (if any) restricted to creation mode
1352  *
1353  *	Returns the inherited descriptor or NULL if there is a problem
1354  */
1355 
1356 struct POSIX_SECURITY *ntfs_build_inherited_posix(
1357 		const struct POSIX_SECURITY *pxdesc, mode_t mode,
1358 		mode_t mask, BOOL isdir)
1359 {
1360 	struct POSIX_SECURITY *pydesc;
1361 	struct POSIX_ACE *pyace;
1362 	int count;
1363 	int defcnt;
1364 	int size;
1365 	int i;
1366 	s16 tagsset;
1367 
1368 	if (pxdesc && pxdesc->defcnt) {
1369 		if (isdir)
1370 			count = 2*pxdesc->defcnt + 3;
1371 		else
1372 			count = pxdesc->defcnt + 3;
1373 	} else
1374 		count = 3;
1375 	pydesc = (struct POSIX_SECURITY*)malloc(
1376 		sizeof(struct POSIX_SECURITY) + count*sizeof(struct POSIX_ACE));
1377 	if (pydesc) {
1378 			/*
1379 			 * Copy inherited tags and adapt perms
1380 			 * Use requested mode, ignoring umask
1381 			 * (not possible with older versions of fuse)
1382 			 */
1383 		tagsset = 0;
1384 		defcnt = (pxdesc ? pxdesc->defcnt : 0);
1385 		for (i=defcnt-1; i>=0; i--) {
1386 			pyace = &pydesc->acl.ace[i];
1387 			*pyace = pxdesc->acl.ace[pxdesc->firstdef + i];
1388 			switch (pyace->tag) {
1389 			case POSIX_ACL_USER_OBJ :
1390 				pyace->perms &= (mode >> 6) & 7;
1391 				break;
1392 			case POSIX_ACL_GROUP_OBJ :
1393 				if (!(tagsset & POSIX_ACL_MASK))
1394 					pyace->perms &= (mode >> 3) & 7;
1395 				break;
1396 			case POSIX_ACL_OTHER :
1397 				pyace->perms &= mode & 7;
1398 				break;
1399 			case POSIX_ACL_MASK :
1400 				pyace->perms &= (mode >> 3) & 7;
1401 				break;
1402 			default :
1403 				break;
1404 			}
1405 			tagsset |= pyace->tag;
1406 		}
1407 		pydesc->acccnt = defcnt;
1408 		/*
1409 		 * If some standard tags were missing, append them from mode
1410 		 * and sort the list
1411 		 * Here we have to use the umask'ed mode
1412 		 */
1413 		if (~tagsset & (POSIX_ACL_USER_OBJ
1414 				 | POSIX_ACL_GROUP_OBJ | POSIX_ACL_OTHER)) {
1415 			i = defcnt;
1416 				/* owner was missing */
1417 			if (!(tagsset & POSIX_ACL_USER_OBJ)) {
1418 				pyace = &pydesc->acl.ace[i];
1419 				pyace->tag = POSIX_ACL_USER_OBJ;
1420 				pyace->id = -1;
1421 				pyace->perms = ((mode & ~mask) >> 6) & 7;
1422 				tagsset |= POSIX_ACL_USER_OBJ;
1423 				i++;
1424 			}
1425 				/* owning group was missing */
1426 			if (!(tagsset & POSIX_ACL_GROUP_OBJ)) {
1427 				pyace = &pydesc->acl.ace[i];
1428 				pyace->tag = POSIX_ACL_GROUP_OBJ;
1429 				pyace->id = -1;
1430 				pyace->perms = ((mode & ~mask) >> 3) & 7;
1431 				tagsset |= POSIX_ACL_GROUP_OBJ;
1432 				i++;
1433 			}
1434 				/* other was missing */
1435 			if (!(tagsset & POSIX_ACL_OTHER)) {
1436 				pyace = &pydesc->acl.ace[i];
1437 				pyace->tag = POSIX_ACL_OTHER;
1438 				pyace->id = -1;
1439 				pyace->perms = mode & ~mask & 7;
1440 				tagsset |= POSIX_ACL_OTHER;
1441 				i++;
1442 			}
1443 			pydesc->acccnt = i;
1444 			pydesc->firstdef = i;
1445 			pydesc->defcnt = 0;
1446 			ntfs_sort_posix(pydesc);
1447 		}
1448 
1449 		/*
1450 		 * append as a default ACL if a directory
1451 		 */
1452 		pydesc->firstdef = pydesc->acccnt;
1453 		if (defcnt && isdir) {
1454 			size = sizeof(struct POSIX_ACE)*defcnt;
1455 			memcpy(&pydesc->acl.ace[pydesc->firstdef],
1456 				 &pxdesc->acl.ace[pxdesc->firstdef],size);
1457 			pydesc->defcnt = defcnt;
1458 		} else {
1459 			pydesc->defcnt = 0;
1460 		}
1461 			/* assume special bits are not inherited */
1462 		posix_header(pydesc, mode & 07000);
1463 		if (!ntfs_valid_posix(pydesc)) {
1464 			ntfs_log_error("Error building an inherited Posix desc\n");
1465 			errno = EIO;
1466 			free(pydesc);
1467 			pydesc = (struct POSIX_SECURITY*)NULL;
1468 		}
1469 	} else
1470 		errno = ENOMEM;
1471 	return (pydesc);
1472 }
1473 
1474 static int merge_lists_posix(struct POSIX_ACE *targetace,
1475 		const struct POSIX_ACE *firstace,
1476 		const struct POSIX_ACE *secondace,
1477 		int firstcnt, int secondcnt)
1478 {
1479 	int k;
1480 
1481 	k = 0;
1482 		/*
1483 		 * No list is exhausted :
1484 		 *    if same tag+id in both list :
1485 		 *       ignore ACE from second list
1486 		 *    else take the one with smaller tag+id
1487 		 */
1488 	while ((firstcnt > 0) && (secondcnt > 0))
1489 		if ((firstace->tag == secondace->tag)
1490 		    && (firstace->id == secondace->id)) {
1491 			secondace++;
1492 			secondcnt--;
1493 		} else
1494 			if ((firstace->tag < secondace->tag)
1495 			   || ((firstace->tag == secondace->tag)
1496 				&& (firstace->id < secondace->id))) {
1497 				targetace->tag = firstace->tag;
1498 				targetace->id = firstace->id;
1499 				targetace->perms = firstace->perms;
1500 				firstace++;
1501 				targetace++;
1502 				firstcnt--;
1503 				k++;
1504 			} else {
1505 				targetace->tag = secondace->tag;
1506 				targetace->id = secondace->id;
1507 				targetace->perms = secondace->perms;
1508 				secondace++;
1509 				targetace++;
1510 				secondcnt--;
1511 				k++;
1512 			}
1513 		/*
1514 		 * One list is exhausted, copy the other one
1515 		 */
1516 	while (firstcnt > 0) {
1517 		targetace->tag = firstace->tag;
1518 		targetace->id = firstace->id;
1519 		targetace->perms = firstace->perms;
1520 		firstace++;
1521 		targetace++;
1522 		firstcnt--;
1523 		k++;
1524 	}
1525 	while (secondcnt > 0) {
1526 		targetace->tag = secondace->tag;
1527 		targetace->id = secondace->id;
1528 		targetace->perms = secondace->perms;
1529 		secondace++;
1530 		targetace++;
1531 		secondcnt--;
1532 		k++;
1533 	}
1534 	return (k);
1535 }
1536 
1537 /*
1538  *		Merge two Posix ACLs
1539  *	The input ACLs have to be adequately sorted
1540  *
1541  *	Returns the merged ACL, which is allocated and has to be freed by caller,
1542  *	or NULL if failed
1543  */
1544 
1545 struct POSIX_SECURITY *ntfs_merge_descr_posix(const struct POSIX_SECURITY *first,
1546 			const struct POSIX_SECURITY *second)
1547 {
1548 	struct POSIX_SECURITY *pxdesc;
1549 	struct POSIX_ACE *targetace;
1550 	const struct POSIX_ACE *firstace;
1551 	const struct POSIX_ACE *secondace;
1552 	size_t size;
1553 	int k;
1554 
1555 	size = sizeof(struct POSIX_SECURITY)
1556 		+ (first->acccnt + first->defcnt
1557 			+ second->acccnt + second->defcnt)*sizeof(struct POSIX_ACE);
1558 	pxdesc = (struct POSIX_SECURITY*)malloc(size);
1559 	if (pxdesc) {
1560 			/*
1561 			 * merge access ACEs
1562 			 */
1563 		firstace = first->acl.ace;
1564 		secondace = second->acl.ace;
1565 		targetace = pxdesc->acl.ace;
1566 		k = merge_lists_posix(targetace,firstace,secondace,
1567 			first->acccnt,second->acccnt);
1568 		pxdesc->acccnt = k;
1569 			/*
1570 			 * merge default ACEs
1571 			 */
1572 		pxdesc->firstdef = k;
1573 		firstace = &first->acl.ace[first->firstdef];
1574 		secondace = &second->acl.ace[second->firstdef];
1575 		targetace = &pxdesc->acl.ace[k];
1576 		k = merge_lists_posix(targetace,firstace,secondace,
1577 			first->defcnt,second->defcnt);
1578 		pxdesc->defcnt = k;
1579 			/*
1580 			 * build header
1581 			 */
1582 		pxdesc->acl.version = POSIX_VERSION;
1583 		pxdesc->acl.flags = 0;
1584 		pxdesc->acl.filler = 0;
1585 		pxdesc->mode = 0;
1586 		pxdesc->tagsset = 0;
1587 	} else
1588 		errno = ENOMEM;
1589 	return (pxdesc);
1590 }
1591 
1592 struct BUILD_CONTEXT {
1593 	BOOL isdir;
1594 	BOOL adminowns;
1595 	BOOL groupowns;
1596 	u16 selfuserperms;
1597 	u16 selfgrpperms;
1598 	u16 grpperms;
1599 	u16 othperms;
1600 	u16 mask;
1601 	u16 designates;
1602 	u16 withmask;
1603 	u16 rootspecial;
1604 } ;
1605 
1606 
1607 
1608 static BOOL build_user_denials(ACL *pacl,
1609 		const SID *usid, struct MAPPING* const mapping[],
1610 		ACE_FLAGS flags, const struct POSIX_ACE *pxace,
1611 		struct BUILD_CONTEXT *pset)
1612 {
1613 	BIGSID defsid;
1614 	ACCESS_ALLOWED_ACE *pdace;
1615 	const SID *sid;
1616 	int sidsz;
1617 	int pos;
1618 	int acecnt;
1619 	le32 grants;
1620 	le32 denials;
1621 	u16 perms;
1622 	u16 mixperms;
1623 	u16 tag;
1624 	BOOL rejected;
1625 	BOOL rootuser;
1626 	BOOL avoidmask;
1627 
1628 	rejected = FALSE;
1629 	tag = pxace->tag;
1630 	perms = pxace->perms;
1631 	rootuser = FALSE;
1632 	pos = le16_to_cpu(pacl->size);
1633 	acecnt = le16_to_cpu(pacl->ace_count);
1634 	avoidmask = (pset->mask == (POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X))
1635 			&& ((pset->designates && pset->withmask)
1636 			   || (!pset->designates && !pset->withmask));
1637 	if (tag == POSIX_ACL_USER_OBJ) {
1638 		sid = usid;
1639 		sidsz = ntfs_sid_size(sid);
1640 		grants = OWNER_RIGHTS;
1641 	} else {
1642 		if (pxace->id) {
1643 			sid = ntfs_find_usid(mapping[MAPUSERS],
1644 				pxace->id, (SID*)&defsid);
1645 			grants = WORLD_RIGHTS;
1646 		} else {
1647 			sid = adminsid;
1648 			rootuser = TRUE;
1649 			grants = WORLD_RIGHTS & ~ROOT_OWNER_UNMARK;
1650 		}
1651 		if (sid) {
1652 			sidsz = ntfs_sid_size(sid);
1653 			/*
1654 			 * Insert denial of complement of mask for
1655 			 * each designated user (except root)
1656 			 * WRITE_OWNER is inserted so that
1657 			 * the mask can be identified
1658 			 */
1659 			if (!avoidmask && !rootuser) {
1660 				denials = WRITE_OWNER;
1661 				pdace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos];
1662 				if (pset->isdir) {
1663 					if (!(pset->mask & POSIX_PERM_X))
1664 						denials |= DIR_EXEC;
1665 					if (!(pset->mask & POSIX_PERM_W))
1666 						denials |= DIR_WRITE;
1667 					if (!(pset->mask & POSIX_PERM_R))
1668 						denials |= DIR_READ;
1669 				} else {
1670 					if (!(pset->mask & POSIX_PERM_X))
1671 						denials |= FILE_EXEC;
1672 					if (!(pset->mask & POSIX_PERM_W))
1673 						denials |= FILE_WRITE;
1674 					if (!(pset->mask & POSIX_PERM_R))
1675 						denials |= FILE_READ;
1676 				}
1677 				if (rootuser)
1678 					grants &= ~ROOT_OWNER_UNMARK;
1679 				pdace->type = ACCESS_DENIED_ACE_TYPE;
1680 				pdace->flags = flags;
1681 				pdace->size = cpu_to_le16(sidsz + 8);
1682 				pdace->mask = denials;
1683 				memcpy((char*)&pdace->sid, sid, sidsz);
1684 				pos += sidsz + 8;
1685 				acecnt++;
1686 			}
1687 		} else
1688 			rejected = TRUE;
1689 	}
1690 	if (!rejected) {
1691 		if (pset->isdir) {
1692 			if (perms & POSIX_PERM_X)
1693 				grants |= DIR_EXEC;
1694 			if (perms & POSIX_PERM_W)
1695 				grants |= DIR_WRITE;
1696 			if (perms & POSIX_PERM_R)
1697 				grants |= DIR_READ;
1698 		} else {
1699 			if (perms & POSIX_PERM_X)
1700 				grants |= FILE_EXEC;
1701 			if (perms & POSIX_PERM_W)
1702 				grants |= FILE_WRITE;
1703 			if (perms & POSIX_PERM_R)
1704 				grants |= FILE_READ;
1705 		}
1706 
1707 		/* a possible ACE to deny owner what he/she would */
1708 		/* induely get from administrator, group or world */
1709 		/* unless owner is administrator or group */
1710 
1711 		denials = const_cpu_to_le32(0);
1712 		pdace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos];
1713 		if (!pset->adminowns && !rootuser) {
1714 			if (!pset->groupowns) {
1715 				mixperms = pset->grpperms | pset->othperms;
1716 				if (tag == POSIX_ACL_USER_OBJ)
1717 					mixperms |= pset->selfuserperms;
1718 				if (pset->isdir) {
1719 					if (mixperms & POSIX_PERM_X)
1720 						denials |= DIR_EXEC;
1721 					if (mixperms & POSIX_PERM_W)
1722 						denials |= DIR_WRITE;
1723 					if (mixperms & POSIX_PERM_R)
1724 						denials |= DIR_READ;
1725 				} else {
1726 					if (mixperms & POSIX_PERM_X)
1727 						denials |= FILE_EXEC;
1728 					if (mixperms & POSIX_PERM_W)
1729 						denials |= FILE_WRITE;
1730 					if (mixperms & POSIX_PERM_R)
1731 						denials |= FILE_READ;
1732 				}
1733 			} else {
1734 				mixperms = ~pset->grpperms & pset->othperms;
1735 				if (tag == POSIX_ACL_USER_OBJ)
1736 					mixperms |= pset->selfuserperms;
1737 				if (pset->isdir) {
1738 					if (mixperms & POSIX_PERM_X)
1739 						denials |= DIR_EXEC;
1740 					if (mixperms & POSIX_PERM_W)
1741 						denials |= DIR_WRITE;
1742 					if (mixperms & POSIX_PERM_R)
1743 						denials |= DIR_READ;
1744 				} else {
1745 					if (mixperms & POSIX_PERM_X)
1746 						denials |= FILE_EXEC;
1747 					if (mixperms & POSIX_PERM_W)
1748 						denials |= FILE_WRITE;
1749 					if (mixperms & POSIX_PERM_R)
1750 						denials |= FILE_READ;
1751 				}
1752 			}
1753 			denials &= ~grants;
1754 			if (denials) {
1755 				pdace->type = ACCESS_DENIED_ACE_TYPE;
1756 				pdace->flags = flags;
1757 				pdace->size = cpu_to_le16(sidsz + 8);
1758 				pdace->mask = denials;
1759 				memcpy((char*)&pdace->sid, sid, sidsz);
1760 				pos += sidsz + 8;
1761 				acecnt++;
1762 			}
1763 		}
1764 	}
1765 	pacl->size = cpu_to_le16(pos);
1766 	pacl->ace_count = cpu_to_le16(acecnt);
1767 	return (!rejected);
1768 }
1769 
1770 static BOOL build_user_grants(ACL *pacl,
1771 		const SID *usid, struct MAPPING* const mapping[],
1772 		ACE_FLAGS flags, const struct POSIX_ACE *pxace,
1773 		struct BUILD_CONTEXT *pset)
1774 {
1775 	BIGSID defsid;
1776 	ACCESS_ALLOWED_ACE *pgace;
1777 	const SID *sid;
1778 	int sidsz;
1779 	int pos;
1780 	int acecnt;
1781 	le32 grants;
1782 	u16 perms;
1783 	u16 tag;
1784 	BOOL rejected;
1785 	BOOL rootuser;
1786 
1787 	rejected = FALSE;
1788 	tag = pxace->tag;
1789 	perms = pxace->perms;
1790 	rootuser = FALSE;
1791 	pos = le16_to_cpu(pacl->size);
1792 	acecnt = le16_to_cpu(pacl->ace_count);
1793 	if (tag == POSIX_ACL_USER_OBJ) {
1794 		sid = usid;
1795 		sidsz = ntfs_sid_size(sid);
1796 		grants = OWNER_RIGHTS;
1797 	} else {
1798 		if (pxace->id) {
1799 			sid = ntfs_find_usid(mapping[MAPUSERS],
1800 				pxace->id, (SID*)&defsid);
1801 			if (sid)
1802 				sidsz = ntfs_sid_size(sid);
1803 			else
1804 				rejected = TRUE;
1805 			grants = WORLD_RIGHTS;
1806 		} else {
1807 			sid = adminsid;
1808 			sidsz = ntfs_sid_size(sid);
1809 			rootuser = TRUE;
1810 			grants = WORLD_RIGHTS & ~ROOT_OWNER_UNMARK;
1811 		}
1812 	}
1813 	if (!rejected) {
1814 		if (pset->isdir) {
1815 			if (perms & POSIX_PERM_X)
1816 				grants |= DIR_EXEC;
1817 			if (perms & POSIX_PERM_W)
1818 				grants |= DIR_WRITE;
1819 			if (perms & POSIX_PERM_R)
1820 				grants |= DIR_READ;
1821 		} else {
1822 			if (perms & POSIX_PERM_X)
1823 				grants |= FILE_EXEC;
1824 			if (perms & POSIX_PERM_W)
1825 				grants |= FILE_WRITE;
1826 			if (perms & POSIX_PERM_R)
1827 				grants |= FILE_READ;
1828 		}
1829 		if (rootuser)
1830 			grants &= ~ROOT_OWNER_UNMARK;
1831 		pgace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos];
1832 		pgace->type = ACCESS_ALLOWED_ACE_TYPE;
1833 		pgace->size = cpu_to_le16(sidsz + 8);
1834 		pgace->flags = flags;
1835 		pgace->mask = grants;
1836 		memcpy((char*)&pgace->sid, sid, sidsz);
1837 		pos += sidsz + 8;
1838 		acecnt = le16_to_cpu(pacl->ace_count) + 1;
1839 		pacl->ace_count = cpu_to_le16(acecnt);
1840 		pacl->size = cpu_to_le16(pos);
1841 	}
1842 	return (!rejected);
1843 }
1844 
1845 
1846 			/* a grant ACE for group */
1847 			/* unless group-obj has the same rights as world */
1848 			/* but present if group is owner or owner is administrator */
1849 			/* this ACE will be inserted after denials for group */
1850 
1851 static BOOL build_group_denials_grant(ACL *pacl,
1852 		const SID *gsid, struct MAPPING* const mapping[],
1853 		ACE_FLAGS flags, const struct POSIX_ACE *pxace,
1854 		struct BUILD_CONTEXT *pset)
1855 {
1856 	BIGSID defsid;
1857 	ACCESS_ALLOWED_ACE *pdace;
1858 	ACCESS_ALLOWED_ACE *pgace;
1859 	const SID *sid;
1860 	int sidsz;
1861 	int pos;
1862 	int acecnt;
1863 	le32 grants;
1864 	le32 denials;
1865 	u16 perms;
1866 	u16 mixperms;
1867 	u16 tag;
1868 	BOOL avoidmask;
1869 	BOOL rootgroup;
1870 	BOOL rejected;
1871 
1872 	rejected = FALSE;
1873 	tag = pxace->tag;
1874 	perms = pxace->perms;
1875 	pos = le16_to_cpu(pacl->size);
1876 	acecnt = le16_to_cpu(pacl->ace_count);
1877 	rootgroup = FALSE;
1878 	avoidmask = (pset->mask == (POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X))
1879 			&& ((pset->designates && pset->withmask)
1880 			   || (!pset->designates && !pset->withmask));
1881 	if (tag == POSIX_ACL_GROUP_OBJ)
1882 		sid = gsid;
1883 	else
1884 		if (pxace->id)
1885 			sid = ntfs_find_gsid(mapping[MAPGROUPS],
1886 				pxace->id, (SID*)&defsid);
1887 		else {
1888 			sid = adminsid;
1889 			rootgroup = TRUE;
1890 		}
1891 	if (sid) {
1892 		sidsz = ntfs_sid_size(sid);
1893 		/*
1894 		 * Insert denial of complement of mask for
1895 		 * each group
1896 		 * WRITE_OWNER is inserted so that
1897 		 * the mask can be identified
1898 		 * Note : this mask may lead on Windows to
1899 		 * deny rights to administrators belonging
1900 		 * to some user group
1901 		 */
1902 		if ((!avoidmask && !rootgroup)
1903 		    || (pset->rootspecial
1904 			&& (tag == POSIX_ACL_GROUP_OBJ))) {
1905 			denials = WRITE_OWNER;
1906 			pdace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos];
1907 			if (pset->isdir) {
1908 				if (!(pset->mask & POSIX_PERM_X))
1909 					denials |= DIR_EXEC;
1910 				if (!(pset->mask & POSIX_PERM_W))
1911 					denials |= DIR_WRITE;
1912 				if (!(pset->mask & POSIX_PERM_R))
1913 					denials |= DIR_READ;
1914 			} else {
1915 				if (!(pset->mask & POSIX_PERM_X))
1916 					denials |= FILE_EXEC;
1917 				if (!(pset->mask & POSIX_PERM_W))
1918 					denials |= FILE_WRITE;
1919 				if (!(pset->mask & POSIX_PERM_R))
1920 					denials |= FILE_READ;
1921 			}
1922 			pdace->type = ACCESS_DENIED_ACE_TYPE;
1923 			pdace->flags = flags;
1924 			pdace->size = cpu_to_le16(sidsz + 8);
1925 			pdace->mask = denials;
1926 			memcpy((char*)&pdace->sid, sid, sidsz);
1927 			pos += sidsz + 8;
1928 			acecnt++;
1929 		}
1930 	} else
1931 		rejected = TRUE;
1932 	if (!rejected
1933 	    && (pset->adminowns
1934 		|| pset->groupowns
1935 		|| avoidmask
1936 		|| rootgroup
1937 		|| (perms != pset->othperms))) {
1938 		grants = WORLD_RIGHTS;
1939 		if (rootgroup)
1940 			grants &= ~ROOT_GROUP_UNMARK;
1941 		if (pset->isdir) {
1942 			if (perms & POSIX_PERM_X)
1943 				grants |= DIR_EXEC;
1944 			if (perms & POSIX_PERM_W)
1945 				grants |= DIR_WRITE;
1946 			if (perms & POSIX_PERM_R)
1947 				grants |= DIR_READ;
1948 		} else {
1949 			if (perms & POSIX_PERM_X)
1950 				grants |= FILE_EXEC;
1951 			if (perms & POSIX_PERM_W)
1952 				grants |= FILE_WRITE;
1953 			if (perms & POSIX_PERM_R)
1954 				grants |= FILE_READ;
1955 		}
1956 
1957 		/* a possible ACE to deny group what it would get from world */
1958 		/* or administrator, unless owner is administrator or group */
1959 
1960 		denials = const_cpu_to_le32(0);
1961 		pdace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos];
1962 		if (!pset->adminowns
1963 		    && !pset->groupowns
1964 		    && !rootgroup) {
1965 			mixperms = pset->othperms;
1966 			if (tag == POSIX_ACL_GROUP_OBJ)
1967 				mixperms |= pset->selfgrpperms;
1968 			if (pset->isdir) {
1969 				if (mixperms & POSIX_PERM_X)
1970 					denials |= DIR_EXEC;
1971 				if (mixperms & POSIX_PERM_W)
1972 					denials |= DIR_WRITE;
1973 				if (mixperms & POSIX_PERM_R)
1974 					denials |= DIR_READ;
1975 			} else {
1976 				if (mixperms & POSIX_PERM_X)
1977 					denials |= FILE_EXEC;
1978 				if (mixperms & POSIX_PERM_W)
1979 					denials |= FILE_WRITE;
1980 				if (mixperms & POSIX_PERM_R)
1981 					denials |= FILE_READ;
1982 			}
1983 			denials &= ~(grants | OWNER_RIGHTS);
1984 			if (denials) {
1985 				pdace->type = ACCESS_DENIED_ACE_TYPE;
1986 				pdace->flags = flags;
1987 				pdace->size = cpu_to_le16(sidsz + 8);
1988 				pdace->mask = denials;
1989 				memcpy((char*)&pdace->sid, sid, sidsz);
1990 				pos += sidsz + 8;
1991 				acecnt++;
1992 			}
1993 		}
1994 
1995 			/* now insert grants to group if more than world */
1996 		if (pset->adminowns
1997 			|| pset->groupowns
1998 			|| (avoidmask && (pset->designates || pset->withmask))
1999 			|| (perms & ~pset->othperms)
2000 			|| (pset->rootspecial
2001 			   && (tag == POSIX_ACL_GROUP_OBJ))
2002 			|| (tag == POSIX_ACL_GROUP)) {
2003 			if (rootgroup)
2004 				grants &= ~ROOT_GROUP_UNMARK;
2005 			pgace = (ACCESS_DENIED_ACE*)&((char*)pacl)[pos];
2006 			pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2007 			pgace->flags = flags;
2008 			pgace->size = cpu_to_le16(sidsz + 8);
2009 			pgace->mask = grants;
2010 			memcpy((char*)&pgace->sid, sid, sidsz);
2011 			pos += sidsz + 8;
2012 			acecnt++;
2013 		}
2014 	}
2015 	pacl->size = cpu_to_le16(pos);
2016 	pacl->ace_count = cpu_to_le16(acecnt);
2017 	return (!rejected);
2018 }
2019 
2020 
2021 /*
2022  *		Build an ACL composed of several ACE's
2023  *	returns size of ACL or zero if failed
2024  *
2025  *	Three schemes are defined :
2026  *
2027  *	1) if root is neither owner nor group up to 7 ACE's are set up :
2028  *	- denials to owner (preventing grants to world or group to apply)
2029  *        + mask denials to designated user (unless mask allows all)
2030  *        + denials to designated user
2031  *	- grants to owner (always present - first grant)
2032  *        + grants to designated user
2033  *        + mask denial to group (unless mask allows all)
2034  *	- denials to group (preventing grants to world to apply)
2035  *	- grants to group (unless group has no more than world rights)
2036  *        + mask denials to designated group (unless mask allows all)
2037  *        + grants to designated group
2038  *        + denials to designated group
2039  *	- grants to world (unless none)
2040  *	- full privileges to administrator, always present
2041  *	- full privileges to system, always present
2042  *
2043  *	The same scheme is applied for Posix ACLs, with the mask represented
2044  *	as denials prepended to grants for designated users and groups
2045  *
2046  *	This is inspired by an Internet Draft from Marius Aamodt Eriksen
2047  *	for mapping NFSv4 ACLs to Posix ACLs (draft-ietf-nfsv4-acl-mapping-00.txt)
2048  *	More recent versions of the draft (draft-ietf-nfsv4-acl-mapping-05.txt)
2049  *	are not followed, as they ignore the Posix mask and lead to
2050  *	loss of compatibility with Linux implementations on other fs.
2051  *
2052  *	Note that denials to group are located after grants to owner.
2053  *	This only occurs in the unfrequent situation where world
2054  *	has more rights than group and cannot be avoided if owner and other
2055  *	have some common right which is denied to group (eg for mode 745
2056  *	executing has to be denied to group, but not to owner or world).
2057  *	This rare situation is processed by Windows correctly, but
2058  *	Windows utilities may want to change the order, with a
2059  *	consequence of applying the group denials to the Windows owner.
2060  *	The interpretation on Linux is not affected by the order change.
2061  *
2062  *	2) if root is either owner or group, two problems arise :
2063  *	- granting full rights to administrator (as needed to transpose
2064  *	  to Windows rights bypassing granting to root) would imply
2065  *	  Linux permissions to always be seen as rwx, no matter the chmod
2066  *	- there is no different SID to separate an administrator owner
2067  *	  from an administrator group. Hence Linux permissions for owner
2068  *	  would always be similar to permissions to group.
2069  *
2070  *	as a work-around, up to 5 ACE's are set up if owner or group :
2071  *	- grants to owner, always present at first position
2072  *	- grants to group, always present
2073  *	- grants to world, unless none
2074  *	- full privileges to administrator, always present
2075  *	- full privileges to system, always present
2076  *
2077  *	On Windows, these ACE's are processed normally, though they
2078  *	are redundant (owner, group and administrator are the same,
2079  *	as a consequence any denials would damage administrator rights)
2080  *	but on Linux, privileges to administrator are ignored (they
2081  *	are not needed as root has always full privileges), and
2082  *	neither grants to group are applied to owner, nor grants to
2083  *	world are applied to owner or group.
2084  *
2085  *	3) finally a similar situation arises when group is owner (they
2086  *	 have the same SID), but is not root.
2087  *	 In this situation up to 6 ACE's are set up :
2088  *
2089  *	- denials to owner (preventing grants to world to apply)
2090  *	- grants to owner (always present)
2091  *	- grants to group (unless groups has same rights as world)
2092  *	- grants to world (unless none)
2093  *	- full privileges to administrator, always present
2094  *	- full privileges to system, always present
2095  *
2096  *	On Windows, these ACE's are processed normally, though they
2097  *	are redundant (as owner and group are the same), but this has
2098  *	no impact on administrator rights
2099  *
2100  *	Special flags (S_ISVTX, S_ISGID, S_ISUID) :
2101  *	an extra null ACE is inserted to hold these flags, using
2102  *	the same conventions as cygwin.
2103  *
2104  */
2105 
2106 static int buildacls_posix(struct MAPPING* const mapping[],
2107 		char *secattr, int offs, const struct POSIX_SECURITY *pxdesc,
2108 		int isdir, const SID *usid, const SID *gsid)
2109 {
2110         struct BUILD_CONTEXT aceset[2], *pset;
2111 	BOOL adminowns;
2112 	BOOL groupowns;
2113 	ACL *pacl;
2114 	ACCESS_ALLOWED_ACE *pgace;
2115 	ACCESS_ALLOWED_ACE *pdace;
2116 	const struct POSIX_ACE *pxace;
2117 	BOOL ok;
2118 	mode_t mode;
2119 	u16 tag;
2120 	u16 perms;
2121 	ACE_FLAGS flags;
2122 	int pos;
2123 	int i;
2124 	int k;
2125 	BIGSID defsid;
2126 	const SID *sid;
2127 	int acecnt;
2128 	int usidsz;
2129 	int wsidsz;
2130 	int asidsz;
2131 	int ssidsz;
2132 	int nsidsz;
2133 	le32 grants;
2134 
2135 	usidsz = ntfs_sid_size(usid);
2136 	wsidsz = ntfs_sid_size(worldsid);
2137 	asidsz = ntfs_sid_size(adminsid);
2138 	ssidsz = ntfs_sid_size(systemsid);
2139 	mode = pxdesc->mode;
2140 		/* adminowns and groupowns are used for both lists */
2141 	adminowns = ntfs_same_sid(usid, adminsid)
2142 		 || ntfs_same_sid(gsid, adminsid);
2143 	groupowns = !adminowns && ntfs_same_sid(usid, gsid);
2144 
2145 	ok = TRUE;
2146 
2147 	/* ACL header */
2148 	pacl = (ACL*)&secattr[offs];
2149 	pacl->revision = ACL_REVISION;
2150 	pacl->alignment1 = 0;
2151 	pacl->size = cpu_to_le16(sizeof(ACL) + usidsz + 8);
2152 	pacl->ace_count = const_cpu_to_le16(0);
2153 	pacl->alignment2 = const_cpu_to_le16(0);
2154 
2155 		/*
2156 		 * Determine what is allowed to some group or world
2157 		 * to prevent designated users or other groups to get
2158 		 * rights from groups or world
2159 		 * Do the same if owner and group appear as designated
2160 		 * user or group
2161 		 * Also get global mask
2162 		 */
2163 	for (k=0; k<2; k++) {
2164 		pset = &aceset[k];
2165 		pset->selfuserperms = 0;
2166 		pset->selfgrpperms = 0;
2167 		pset->grpperms = 0;
2168 		pset->othperms = 0;
2169 		pset->mask = (POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X);
2170 		pset->designates = 0;
2171 		pset->withmask = 0;
2172 		pset->rootspecial = 0;
2173 		pset->adminowns = adminowns;
2174 		pset->groupowns = groupowns;
2175 		pset->isdir = isdir;
2176 	}
2177 
2178 	for (i=pxdesc->acccnt+pxdesc->defcnt-1; i>=0; i--) {
2179 		if (i >= pxdesc->acccnt) {
2180 			pset = &aceset[1];
2181 			pxace = &pxdesc->acl.ace[i + pxdesc->firstdef - pxdesc->acccnt];
2182 		} else {
2183 			pset = &aceset[0];
2184 			pxace = &pxdesc->acl.ace[i];
2185 		}
2186 		switch (pxace->tag) {
2187 		case POSIX_ACL_USER :
2188 			pset->designates++;
2189 			if (pxace->id) {
2190 				sid = ntfs_find_usid(mapping[MAPUSERS],
2191 					pxace->id, (SID*)&defsid);
2192 				if (sid && ntfs_same_sid(sid,usid))
2193 					pset->selfuserperms |= pxace->perms;
2194 			} else
2195 				/* root as designated user is processed apart */
2196 				pset->rootspecial = TRUE;
2197 			break;
2198 		case POSIX_ACL_GROUP :
2199 			pset->designates++;
2200 			if (pxace->id) {
2201 				sid = ntfs_find_gsid(mapping[MAPUSERS],
2202 					pxace->id, (SID*)&defsid);
2203 				if (sid && ntfs_same_sid(sid,gsid))
2204 					pset->selfgrpperms |= pxace->perms;
2205 			} else
2206 				/* root as designated group is processed apart */
2207 				pset->rootspecial = TRUE;
2208 			/* fall through */
2209 		case POSIX_ACL_GROUP_OBJ :
2210 			pset->grpperms |= pxace->perms;
2211 			break;
2212 		case POSIX_ACL_OTHER :
2213 			pset->othperms = pxace->perms;
2214 			break;
2215 		case POSIX_ACL_MASK :
2216 			pset->withmask++;
2217 			pset->mask = pxace->perms;
2218 		default :
2219 			break;
2220 		}
2221 	}
2222 
2223 if (pxdesc->defcnt && (pxdesc->firstdef != pxdesc->acccnt)) {
2224 ntfs_log_error("** error : access and default not consecutive\n");
2225 return (0);
2226 }
2227 			/*
2228 			 * First insert all denials for owner and each
2229 			 * designated user (with mask if needed)
2230 			 */
2231 
2232 	pacl->ace_count = const_cpu_to_le16(0);
2233 	pacl->size = const_cpu_to_le16(sizeof(ACL));
2234 	for (i=0; (i<(pxdesc->acccnt + pxdesc->defcnt)) && ok; i++) {
2235 		if (i >= pxdesc->acccnt) {
2236 			flags = INHERIT_ONLY_ACE
2237 				| OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
2238 			pset = &aceset[1];
2239 			pxace = &pxdesc->acl.ace[i + pxdesc->firstdef - pxdesc->acccnt];
2240 		} else {
2241 			if (pxdesc->defcnt)
2242 				flags = NO_PROPAGATE_INHERIT_ACE;
2243 			else
2244 				flags = (isdir ? DIR_INHERITANCE
2245 					   : FILE_INHERITANCE);
2246 			pset = &aceset[0];
2247 			pxace = &pxdesc->acl.ace[i];
2248 		}
2249 		tag = pxace->tag;
2250 		perms = pxace->perms;
2251 		switch (tag) {
2252 
2253 			/* insert denial ACEs for each owner or allowed user */
2254 
2255 		case POSIX_ACL_USER :
2256 		case POSIX_ACL_USER_OBJ :
2257 
2258 			ok = build_user_denials(pacl,
2259 				usid, mapping, flags, pxace, pset);
2260 			break;
2261 		default :
2262 			break;
2263 		}
2264 	}
2265 
2266 		/*
2267 		 * for directories, insert a world execution denial
2268 		 * inherited to plain files.
2269 		 * This is to prevent Windows from granting execution
2270 		 * of files through inheritance from parent directory
2271 		 */
2272 
2273 	if (isdir && ok) {
2274 		pos = le16_to_cpu(pacl->size);
2275 		pdace = (ACCESS_DENIED_ACE*) &secattr[offs + pos];
2276 		pdace->type = ACCESS_DENIED_ACE_TYPE;
2277 		pdace->flags = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
2278 		pdace->size = cpu_to_le16(wsidsz + 8);
2279 		pdace->mask = FILE_EXEC;
2280 		memcpy((char*)&pdace->sid, worldsid, wsidsz);
2281 		pos += wsidsz + 8;
2282 		acecnt = le16_to_cpu(pacl->ace_count) + 1;
2283 		pacl->ace_count = cpu_to_le16(acecnt);
2284 		pacl->size = cpu_to_le16(pos);
2285 	}
2286 
2287 			/*
2288 			 * now insert (if needed)
2289 			 * - grants to owner and designated users
2290 			 * - mask and denials for all groups
2291 			 * - grants to other
2292 			 */
2293 
2294 	for (i=0; (i<(pxdesc->acccnt + pxdesc->defcnt)) && ok; i++) {
2295 		if (i >= pxdesc->acccnt) {
2296 			flags = INHERIT_ONLY_ACE
2297 				| OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
2298 			pset = &aceset[1];
2299 			pxace = &pxdesc->acl.ace[i + pxdesc->firstdef - pxdesc->acccnt];
2300 		} else {
2301 			if (pxdesc->defcnt)
2302 				flags = NO_PROPAGATE_INHERIT_ACE;
2303 			else
2304 				flags = (isdir ? DIR_INHERITANCE
2305 					   : FILE_INHERITANCE);
2306 			pset = &aceset[0];
2307 			pxace = &pxdesc->acl.ace[i];
2308 		}
2309 		tag = pxace->tag;
2310 		perms = pxace->perms;
2311 		switch (tag) {
2312 
2313 			/* ACE for each owner or allowed user */
2314 
2315 		case POSIX_ACL_USER :
2316 		case POSIX_ACL_USER_OBJ :
2317 			ok = build_user_grants(pacl,usid,
2318 					mapping,flags,pxace,pset);
2319 			break;
2320 
2321 		case POSIX_ACL_GROUP_OBJ :
2322 			/* denials and grants for group when needed */
2323 			if (pset->groupowns && !pset->adminowns
2324 			    && (pset->grpperms == pset->othperms)
2325 			    && !pset->designates && !pset->withmask) {
2326 				ok = TRUE;
2327 			} else {
2328 				ok = build_group_denials_grant(pacl,gsid,
2329 						mapping,flags,pxace,pset);
2330 			}
2331 			break;
2332 
2333 		case POSIX_ACL_GROUP :
2334 
2335 			/* denials and grants for designated groups */
2336 
2337 			ok = build_group_denials_grant(pacl,gsid,
2338 					mapping,flags,pxace,pset);
2339 			break;
2340 
2341 		case POSIX_ACL_OTHER :
2342 
2343 			/* grants for other users */
2344 
2345 			pos = le16_to_cpu(pacl->size);
2346 			pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos];
2347 			grants = WORLD_RIGHTS;
2348 			if (isdir) {
2349 				if (perms & POSIX_PERM_X)
2350 					grants |= DIR_EXEC;
2351 				if (perms & POSIX_PERM_W)
2352 					grants |= DIR_WRITE;
2353 				if (perms & POSIX_PERM_R)
2354 					grants |= DIR_READ;
2355 			} else {
2356 				if (perms & POSIX_PERM_X)
2357 					grants |= FILE_EXEC;
2358 				if (perms & POSIX_PERM_W)
2359 					grants |= FILE_WRITE;
2360 				if (perms & POSIX_PERM_R)
2361 					grants |= FILE_READ;
2362 			}
2363 			pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2364 			pgace->flags = flags;
2365 			pgace->size = cpu_to_le16(wsidsz + 8);
2366 			pgace->mask = grants;
2367 			memcpy((char*)&pgace->sid, worldsid, wsidsz);
2368 			pos += wsidsz + 8;
2369 			acecnt = le16_to_cpu(pacl->ace_count) + 1;
2370 			pacl->ace_count = cpu_to_le16(acecnt);
2371 			pacl->size = cpu_to_le16(pos);
2372 			break;
2373 		}
2374 	}
2375 
2376 	if (!ok) {
2377 		errno = EINVAL;
2378 		pos = 0;
2379 	} else {
2380 		/* an ACE for administrators */
2381 		/* always full access */
2382 
2383 		pos = le16_to_cpu(pacl->size);
2384 		acecnt = le16_to_cpu(pacl->ace_count);
2385 		if (isdir)
2386 			flags = OBJECT_INHERIT_ACE
2387 				| CONTAINER_INHERIT_ACE;
2388 		else
2389 			flags = NO_PROPAGATE_INHERIT_ACE;
2390 		pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos];
2391 		pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2392 		pgace->flags = flags;
2393 		pgace->size = cpu_to_le16(asidsz + 8);
2394 		grants = OWNER_RIGHTS | FILE_READ | FILE_WRITE | FILE_EXEC;
2395 		pgace->mask = grants;
2396 		memcpy((char*)&pgace->sid, adminsid, asidsz);
2397 		pos += asidsz + 8;
2398 		acecnt++;
2399 
2400 		/* an ACE for system (needed ?) */
2401 		/* always full access */
2402 
2403 		pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos];
2404 		pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2405 		pgace->flags = flags;
2406 		pgace->size = cpu_to_le16(ssidsz + 8);
2407 		grants = OWNER_RIGHTS | FILE_READ | FILE_WRITE | FILE_EXEC;
2408 		pgace->mask = grants;
2409 		memcpy((char*)&pgace->sid, systemsid, ssidsz);
2410 		pos += ssidsz + 8;
2411 		acecnt++;
2412 
2413 		/* a null ACE to hold special flags */
2414 		/* using the same representation as cygwin */
2415 
2416 		if (mode & (S_ISVTX | S_ISGID | S_ISUID)) {
2417 			nsidsz = ntfs_sid_size(nullsid);
2418 			pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos];
2419 			pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2420 			pgace->flags = NO_PROPAGATE_INHERIT_ACE;
2421 			pgace->size = cpu_to_le16(nsidsz + 8);
2422 			grants = const_cpu_to_le32(0);
2423 			if (mode & S_ISUID)
2424 				grants |= FILE_APPEND_DATA;
2425 			if (mode & S_ISGID)
2426 				grants |= FILE_WRITE_DATA;
2427 			if (mode & S_ISVTX)
2428 				grants |= FILE_READ_DATA;
2429 			pgace->mask = grants;
2430 			memcpy((char*)&pgace->sid, nullsid, nsidsz);
2431 			pos += nsidsz + 8;
2432 			acecnt++;
2433 		}
2434 
2435 		/* fix ACL header */
2436 		pacl->size = cpu_to_le16(pos);
2437 		pacl->ace_count = cpu_to_le16(acecnt);
2438 	}
2439 	return (ok ? pos : 0);
2440 }
2441 
2442 #endif /* POSIXACLS */
2443 
2444 static int buildacls(char *secattr, int offs, mode_t mode, int isdir,
2445 	       const SID * usid, const SID * gsid)
2446 {
2447 	ACL *pacl;
2448 	ACCESS_ALLOWED_ACE *pgace;
2449 	ACCESS_ALLOWED_ACE *pdace;
2450 	BOOL adminowns;
2451 	BOOL groupowns;
2452 	ACE_FLAGS gflags;
2453 	int pos;
2454 	int acecnt;
2455 	int usidsz;
2456 	int gsidsz;
2457 	int wsidsz;
2458 	int asidsz;
2459 	int ssidsz;
2460 	int nsidsz;
2461 	le32 grants;
2462 	le32 denials;
2463 
2464 	usidsz = ntfs_sid_size(usid);
2465 	gsidsz = ntfs_sid_size(gsid);
2466 	wsidsz = ntfs_sid_size(worldsid);
2467 	asidsz = ntfs_sid_size(adminsid);
2468 	ssidsz = ntfs_sid_size(systemsid);
2469 	adminowns = ntfs_same_sid(usid, adminsid)
2470 	         || ntfs_same_sid(gsid, adminsid);
2471 	groupowns = !adminowns && ntfs_same_sid(usid, gsid);
2472 
2473 	/* ACL header */
2474 	pacl = (ACL*)&secattr[offs];
2475 	pacl->revision = ACL_REVISION;
2476 	pacl->alignment1 = 0;
2477 	pacl->size = cpu_to_le16(sizeof(ACL) + usidsz + 8);
2478 	pacl->ace_count = const_cpu_to_le16(1);
2479 	pacl->alignment2 = const_cpu_to_le16(0);
2480 	pos = sizeof(ACL);
2481 	acecnt = 0;
2482 
2483 	/* compute a grant ACE for owner */
2484 	/* this ACE will be inserted after denial for owner */
2485 
2486 	grants = OWNER_RIGHTS;
2487 	if (isdir) {
2488 		gflags = DIR_INHERITANCE;
2489 		if (mode & S_IXUSR)
2490 			grants |= DIR_EXEC;
2491 		if (mode & S_IWUSR)
2492 			grants |= DIR_WRITE;
2493 		if (mode & S_IRUSR)
2494 			grants |= DIR_READ;
2495 	} else {
2496 		gflags = FILE_INHERITANCE;
2497 		if (mode & S_IXUSR)
2498 			grants |= FILE_EXEC;
2499 		if (mode & S_IWUSR)
2500 			grants |= FILE_WRITE;
2501 		if (mode & S_IRUSR)
2502 			grants |= FILE_READ;
2503 	}
2504 
2505 	/* a possible ACE to deny owner what he/she would */
2506 	/* induely get from administrator, group or world */
2507         /* unless owner is administrator or group */
2508 
2509 	denials = const_cpu_to_le32(0);
2510 	pdace = (ACCESS_DENIED_ACE*) &secattr[offs + pos];
2511 	if (!adminowns) {
2512 		if (!groupowns) {
2513 			if (isdir) {
2514 				pdace->flags = DIR_INHERITANCE;
2515 				if (mode & (S_IXGRP | S_IXOTH))
2516 					denials |= DIR_EXEC;
2517 				if (mode & (S_IWGRP | S_IWOTH))
2518 					denials |= DIR_WRITE;
2519 				if (mode & (S_IRGRP | S_IROTH))
2520 					denials |= DIR_READ;
2521 			} else {
2522 				pdace->flags = FILE_INHERITANCE;
2523 				if (mode & (S_IXGRP | S_IXOTH))
2524 					denials |= FILE_EXEC;
2525 				if (mode & (S_IWGRP | S_IWOTH))
2526 					denials |= FILE_WRITE;
2527 				if (mode & (S_IRGRP | S_IROTH))
2528 					denials |= FILE_READ;
2529 			}
2530 		} else {
2531 			if (isdir) {
2532 				pdace->flags = DIR_INHERITANCE;
2533 				if ((mode & S_IXOTH) && !(mode & S_IXGRP))
2534 					denials |= DIR_EXEC;
2535 				if ((mode & S_IWOTH) && !(mode & S_IWGRP))
2536 					denials |= DIR_WRITE;
2537 				if ((mode & S_IROTH) && !(mode & S_IRGRP))
2538 					denials |= DIR_READ;
2539 			} else {
2540 				pdace->flags = FILE_INHERITANCE;
2541 				if ((mode & S_IXOTH) && !(mode & S_IXGRP))
2542 					denials |= FILE_EXEC;
2543 				if ((mode & S_IWOTH) && !(mode & S_IWGRP))
2544 					denials |= FILE_WRITE;
2545 				if ((mode & S_IROTH) && !(mode & S_IRGRP))
2546 					denials |= FILE_READ;
2547 			}
2548 		}
2549 		denials &= ~grants;
2550 		if (denials) {
2551 			pdace->type = ACCESS_DENIED_ACE_TYPE;
2552 			pdace->size = cpu_to_le16(usidsz + 8);
2553 			pdace->mask = denials;
2554 			memcpy((char*)&pdace->sid, usid, usidsz);
2555 			pos += usidsz + 8;
2556 			acecnt++;
2557 		}
2558 	}
2559 		/*
2560 		 * for directories, a world execution denial
2561 		 * inherited to plain files
2562 		 */
2563 
2564 	if (isdir) {
2565 		pdace = (ACCESS_DENIED_ACE*) &secattr[offs + pos];
2566 			pdace->type = ACCESS_DENIED_ACE_TYPE;
2567 			pdace->flags = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
2568 			pdace->size = cpu_to_le16(wsidsz + 8);
2569 			pdace->mask = FILE_EXEC;
2570 			memcpy((char*)&pdace->sid, worldsid, wsidsz);
2571 			pos += wsidsz + 8;
2572 			acecnt++;
2573 	}
2574 
2575 
2576 		/* now insert grants to owner */
2577 	pgace = (ACCESS_ALLOWED_ACE*) &secattr[offs + pos];
2578 	pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2579 	pgace->size = cpu_to_le16(usidsz + 8);
2580 	pgace->flags = gflags;
2581 	pgace->mask = grants;
2582 	memcpy((char*)&pgace->sid, usid, usidsz);
2583 	pos += usidsz + 8;
2584 	acecnt++;
2585 
2586 	/* a grant ACE for group */
2587 	/* unless group has the same rights as world */
2588 	/* but present if group is owner or owner is administrator */
2589 	/* this ACE will be inserted after denials for group */
2590 
2591 	if (adminowns
2592 	    || (((mode >> 3) ^ mode) & 7)) {
2593 		grants = WORLD_RIGHTS;
2594 		if (isdir) {
2595 			gflags = DIR_INHERITANCE;
2596 			if (mode & S_IXGRP)
2597 				grants |= DIR_EXEC;
2598 			if (mode & S_IWGRP)
2599 				grants |= DIR_WRITE;
2600 			if (mode & S_IRGRP)
2601 				grants |= DIR_READ;
2602 		} else {
2603 			gflags = FILE_INHERITANCE;
2604 			if (mode & S_IXGRP)
2605 				grants |= FILE_EXEC;
2606 			if (mode & S_IWGRP)
2607 				grants |= FILE_WRITE;
2608 			if (mode & S_IRGRP)
2609 				grants |= FILE_READ;
2610 		}
2611 
2612 		/* a possible ACE to deny group what it would get from world */
2613 		/* or administrator, unless owner is administrator or group */
2614 
2615 		denials = const_cpu_to_le32(0);
2616 		pdace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos];
2617 		if (!adminowns && !groupowns) {
2618 			if (isdir) {
2619 				pdace->flags = DIR_INHERITANCE;
2620 				if (mode & S_IXOTH)
2621 					denials |= DIR_EXEC;
2622 				if (mode & S_IWOTH)
2623 					denials |= DIR_WRITE;
2624 				if (mode & S_IROTH)
2625 					denials |= DIR_READ;
2626 			} else {
2627 				pdace->flags = FILE_INHERITANCE;
2628 				if (mode & S_IXOTH)
2629 					denials |= FILE_EXEC;
2630 				if (mode & S_IWOTH)
2631 					denials |= FILE_WRITE;
2632 				if (mode & S_IROTH)
2633 					denials |= FILE_READ;
2634 			}
2635 			denials &= ~(grants | OWNER_RIGHTS);
2636 			if (denials) {
2637 				pdace->type = ACCESS_DENIED_ACE_TYPE;
2638 				pdace->size = cpu_to_le16(gsidsz + 8);
2639 				pdace->mask = denials;
2640 				memcpy((char*)&pdace->sid, gsid, gsidsz);
2641 				pos += gsidsz + 8;
2642 				acecnt++;
2643 			}
2644 		}
2645 
2646 		if (adminowns
2647 		   || groupowns
2648 		   || ((mode >> 3) & ~mode & 7)) {
2649 				/* now insert grants to group */
2650 				/* if more rights than other */
2651 			pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos];
2652 			pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2653 			pgace->flags = gflags;
2654 			pgace->size = cpu_to_le16(gsidsz + 8);
2655 			pgace->mask = grants;
2656 			memcpy((char*)&pgace->sid, gsid, gsidsz);
2657 			pos += gsidsz + 8;
2658 			acecnt++;
2659 		}
2660 	}
2661 
2662 	/* an ACE for world users */
2663 
2664 	pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos];
2665 	pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2666 	grants = WORLD_RIGHTS;
2667 	if (isdir) {
2668 		pgace->flags = DIR_INHERITANCE;
2669 		if (mode & S_IXOTH)
2670 			grants |= DIR_EXEC;
2671 		if (mode & S_IWOTH)
2672 			grants |= DIR_WRITE;
2673 		if (mode & S_IROTH)
2674 			grants |= DIR_READ;
2675 	} else {
2676 		pgace->flags = FILE_INHERITANCE;
2677 		if (mode & S_IXOTH)
2678 			grants |= FILE_EXEC;
2679 		if (mode & S_IWOTH)
2680 			grants |= FILE_WRITE;
2681 		if (mode & S_IROTH)
2682 			grants |= FILE_READ;
2683 	}
2684 	pgace->size = cpu_to_le16(wsidsz + 8);
2685 	pgace->mask = grants;
2686 	memcpy((char*)&pgace->sid, worldsid, wsidsz);
2687 	pos += wsidsz + 8;
2688 	acecnt++;
2689 
2690 	/* an ACE for administrators */
2691 	/* always full access */
2692 
2693 	pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos];
2694 	pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2695 	if (isdir)
2696 		pgace->flags = DIR_INHERITANCE;
2697 	else
2698 		pgace->flags = FILE_INHERITANCE;
2699 	pgace->size = cpu_to_le16(asidsz + 8);
2700 	grants = OWNER_RIGHTS | FILE_READ | FILE_WRITE | FILE_EXEC;
2701 	pgace->mask = grants;
2702 	memcpy((char*)&pgace->sid, adminsid, asidsz);
2703 	pos += asidsz + 8;
2704 	acecnt++;
2705 
2706 	/* an ACE for system (needed ?) */
2707 	/* always full access */
2708 
2709 	pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos];
2710 	pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2711 	if (isdir)
2712 		pgace->flags = DIR_INHERITANCE;
2713 	else
2714 		pgace->flags = FILE_INHERITANCE;
2715 	pgace->size = cpu_to_le16(ssidsz + 8);
2716 	grants = OWNER_RIGHTS | FILE_READ | FILE_WRITE | FILE_EXEC;
2717 	pgace->mask = grants;
2718 	memcpy((char*)&pgace->sid, systemsid, ssidsz);
2719 	pos += ssidsz + 8;
2720 	acecnt++;
2721 
2722 	/* a null ACE to hold special flags */
2723 	/* using the same representation as cygwin */
2724 
2725 	if (mode & (S_ISVTX | S_ISGID | S_ISUID)) {
2726 		nsidsz = ntfs_sid_size(nullsid);
2727 		pgace = (ACCESS_ALLOWED_ACE*)&secattr[offs + pos];
2728 		pgace->type = ACCESS_ALLOWED_ACE_TYPE;
2729 		pgace->flags = NO_PROPAGATE_INHERIT_ACE;
2730 		pgace->size = cpu_to_le16(nsidsz + 8);
2731 		grants = const_cpu_to_le32(0);
2732 		if (mode & S_ISUID)
2733 			grants |= FILE_APPEND_DATA;
2734 		if (mode & S_ISGID)
2735 			grants |= FILE_WRITE_DATA;
2736 		if (mode & S_ISVTX)
2737 			grants |= FILE_READ_DATA;
2738 		pgace->mask = grants;
2739 		memcpy((char*)&pgace->sid, nullsid, nsidsz);
2740 		pos += nsidsz + 8;
2741 		acecnt++;
2742 	}
2743 
2744 	/* fix ACL header */
2745 	pacl->size = cpu_to_le16(pos);
2746 	pacl->ace_count = cpu_to_le16(acecnt);
2747 	return (pos);
2748 }
2749 
2750 #if POSIXACLS
2751 
2752 /*
2753  *		Build a full security descriptor from a Posix ACL
2754  *	returns descriptor in allocated memory, must free() after use
2755  */
2756 
2757 char *ntfs_build_descr_posix(struct MAPPING* const mapping[],
2758 			struct POSIX_SECURITY *pxdesc,
2759 			int isdir, const SID *usid, const SID *gsid)
2760 {
2761 	int newattrsz;
2762 	SECURITY_DESCRIPTOR_RELATIVE *pnhead;
2763 	char *newattr;
2764 	int aclsz;
2765 	int usidsz;
2766 	int gsidsz;
2767 	int wsidsz;
2768 	int asidsz;
2769 	int ssidsz;
2770 	int k;
2771 
2772 	usidsz = ntfs_sid_size(usid);
2773 	gsidsz = ntfs_sid_size(gsid);
2774 	wsidsz = ntfs_sid_size(worldsid);
2775 	asidsz = ntfs_sid_size(adminsid);
2776 	ssidsz = ntfs_sid_size(systemsid);
2777 
2778 	/* allocate enough space for the new security attribute */
2779 	newattrsz = sizeof(SECURITY_DESCRIPTOR_RELATIVE)	/* header */
2780 	    + usidsz + gsidsz	/* usid and gsid */
2781 	    + sizeof(ACL)	/* acl header */
2782 	    + 2*(8 + usidsz)	/* two possible ACE for user */
2783 	    + 3*(8 + gsidsz)	/* three possible ACE for group and mask */
2784 	    + 8 + wsidsz	/* one ACE for world */
2785 	    + 8 + asidsz	/* one ACE for admin */
2786 	    + 8 + ssidsz;	/* one ACE for system */
2787 	if (isdir)			/* a world denial for directories */
2788 		newattrsz += 8 + wsidsz;
2789 	if (pxdesc->mode & 07000)	/* a NULL ACE for special modes */
2790 		newattrsz += 8 + ntfs_sid_size(nullsid);
2791 				/* account for non-owning users and groups */
2792 	for (k=0; k<pxdesc->acccnt; k++) {
2793 		if ((pxdesc->acl.ace[k].tag == POSIX_ACL_USER)
2794 		    || (pxdesc->acl.ace[k].tag == POSIX_ACL_GROUP))
2795 			newattrsz += 3*MAX_SID_SIZE;
2796 	}
2797 				/* account for default ACE's */
2798 	newattrsz += 2*MAX_SID_SIZE*pxdesc->defcnt;
2799 	newattr = (char*)ntfs_malloc(newattrsz);
2800 	if (newattr) {
2801 		/* build the main header part */
2802 		pnhead = (SECURITY_DESCRIPTOR_RELATIVE*)newattr;
2803 		pnhead->revision = SECURITY_DESCRIPTOR_REVISION;
2804 		pnhead->alignment = 0;
2805 			/*
2806 			 * The flag SE_DACL_PROTECTED prevents the ACL
2807 			 * to be changed in an inheritance after creation
2808 			 */
2809 		pnhead->control = SE_DACL_PRESENT | SE_DACL_PROTECTED
2810 				    | SE_SELF_RELATIVE;
2811 			/*
2812 			 * Windows prefers ACL first, do the same to
2813 			 * get the same hash value and avoid duplication
2814 			 */
2815 		/* build permissions */
2816 		aclsz = buildacls_posix(mapping,newattr,
2817 			  sizeof(SECURITY_DESCRIPTOR_RELATIVE),
2818 			  pxdesc, isdir, usid, gsid);
2819 		if (aclsz && ((int)(sizeof(SECURITY_DESCRIPTOR_RELATIVE)
2820 				+ aclsz + usidsz + gsidsz) <= newattrsz)) {
2821 			/* append usid and gsid */
2822 			memcpy(&newattr[sizeof(SECURITY_DESCRIPTOR_RELATIVE)
2823 				 + aclsz], usid, usidsz);
2824 			memcpy(&newattr[sizeof(SECURITY_DESCRIPTOR_RELATIVE)
2825 				+ aclsz + usidsz], gsid, gsidsz);
2826 			/* positions of ACL, USID and GSID into header */
2827 			pnhead->owner =
2828 			    cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE)
2829 				 + aclsz);
2830 			pnhead->group =
2831 			    cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE)
2832 				 + aclsz + usidsz);
2833 			pnhead->sacl = const_cpu_to_le32(0);
2834 			pnhead->dacl =
2835 			    const_cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE));
2836 		} else {
2837 			/* ACL failure (errno set) or overflow */
2838 			free(newattr);
2839 			newattr = (char*)NULL;
2840 			if (aclsz) {
2841 				/* hope error was detected before overflowing */
2842 				ntfs_log_error("Security descriptor is longer than expected\n");
2843 				errno = EIO;
2844 			}
2845 		}
2846 	} else
2847 		errno = ENOMEM;
2848 	return (newattr);
2849 }
2850 
2851 #endif /* POSIXACLS */
2852 
2853 /*
2854  *		Build a full security descriptor
2855  *	returns descriptor in allocated memory, must free() after use
2856  */
2857 
2858 char *ntfs_build_descr(mode_t mode,
2859 			int isdir, const SID * usid, const SID * gsid)
2860 {
2861 	int newattrsz;
2862 	SECURITY_DESCRIPTOR_RELATIVE *pnhead;
2863 	char *newattr;
2864 	int aclsz;
2865 	int usidsz;
2866 	int gsidsz;
2867 	int wsidsz;
2868 	int asidsz;
2869 	int ssidsz;
2870 
2871 	usidsz = ntfs_sid_size(usid);
2872 	gsidsz = ntfs_sid_size(gsid);
2873 	wsidsz = ntfs_sid_size(worldsid);
2874 	asidsz = ntfs_sid_size(adminsid);
2875 	ssidsz = ntfs_sid_size(systemsid);
2876 
2877 	/* allocate enough space for the new security attribute */
2878 	newattrsz = sizeof(SECURITY_DESCRIPTOR_RELATIVE)	/* header */
2879 	    + usidsz + gsidsz	/* usid and gsid */
2880 	    + sizeof(ACL)	/* acl header */
2881 	    + 2*(8 + usidsz)	/* two possible ACE for user */
2882 	    + 2*(8 + gsidsz)	/* two possible ACE for group */
2883 	    + 8 + wsidsz	/* one ACE for world */
2884 	    + 8 + asidsz 	/* one ACE for admin */
2885 	    + 8 + ssidsz;	/* one ACE for system */
2886 	if (isdir)			/* a world denial for directories */
2887 		newattrsz += 8 + wsidsz;
2888 	if (mode & 07000)	/* a NULL ACE for special modes */
2889 		newattrsz += 8 + ntfs_sid_size(nullsid);
2890 	newattr = (char*)ntfs_malloc(newattrsz);
2891 	if (newattr) {
2892 		/* build the main header part */
2893 		pnhead = (SECURITY_DESCRIPTOR_RELATIVE*) newattr;
2894 		pnhead->revision = SECURITY_DESCRIPTOR_REVISION;
2895 		pnhead->alignment = 0;
2896 			/*
2897 			 * The flag SE_DACL_PROTECTED prevents the ACL
2898 			 * to be changed in an inheritance after creation
2899 			 */
2900 		pnhead->control = SE_DACL_PRESENT | SE_DACL_PROTECTED
2901 				    | SE_SELF_RELATIVE;
2902 			/*
2903 			 * Windows prefers ACL first, do the same to
2904 			 * get the same hash value and avoid duplication
2905 			 */
2906 		/* build permissions */
2907 		aclsz = buildacls(newattr,
2908 			  sizeof(SECURITY_DESCRIPTOR_RELATIVE),
2909 			  mode, isdir, usid, gsid);
2910 		if (((int)sizeof(SECURITY_DESCRIPTOR_RELATIVE)
2911 				+ aclsz + usidsz + gsidsz) <= newattrsz) {
2912 			/* append usid and gsid */
2913 			memcpy(&newattr[sizeof(SECURITY_DESCRIPTOR_RELATIVE)
2914 				 + aclsz], usid, usidsz);
2915 			memcpy(&newattr[sizeof(SECURITY_DESCRIPTOR_RELATIVE)
2916 				+ aclsz + usidsz], gsid, gsidsz);
2917 			/* positions of ACL, USID and GSID into header */
2918 			pnhead->owner =
2919 			    cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE)
2920 				 + aclsz);
2921 			pnhead->group =
2922 			    cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE)
2923 				 + aclsz + usidsz);
2924 			pnhead->sacl = const_cpu_to_le32(0);
2925 			pnhead->dacl =
2926 			    const_cpu_to_le32(sizeof(SECURITY_DESCRIPTOR_RELATIVE));
2927 		} else {
2928 			/* hope error was detected before overflowing */
2929 			free(newattr);
2930 			newattr = (char*)NULL;
2931 			ntfs_log_error("Security descriptor is longer than expected\n");
2932 			errno = EIO;
2933 		}
2934 	} else
2935 		errno = ENOMEM;
2936 	return (newattr);
2937 }
2938 
2939 /*
2940  *		Create a mode_t permission set
2941  *	from owner, group and world grants as represented in ACEs
2942  */
2943 
2944 static int merge_permissions(BOOL isdir,
2945 		le32 owner, le32 group, le32 world, le32 special)
2946 
2947 {
2948 	int perm;
2949 
2950 	perm = 0;
2951 	/* build owner permission */
2952 	if (owner) {
2953 		if (isdir) {
2954 			/* exec if any of list, traverse */
2955 			if (owner & DIR_GEXEC)
2956 				perm |= S_IXUSR;
2957 			/* write if any of addfile, adddir, delchild */
2958 			if (owner & DIR_GWRITE)
2959 				perm |= S_IWUSR;
2960 			/* read if any of list */
2961 			if (owner & DIR_GREAD)
2962 				perm |= S_IRUSR;
2963 		} else {
2964 			/* exec if execute or generic execute */
2965 			if (owner & FILE_GEXEC)
2966 				perm |= S_IXUSR;
2967 			/* write if any of writedata or generic write */
2968 			if (owner & FILE_GWRITE)
2969 				perm |= S_IWUSR;
2970 			/* read if any of readdata or generic read */
2971 			if (owner & FILE_GREAD)
2972 				perm |= S_IRUSR;
2973 		}
2974 	}
2975 	/* build group permission */
2976 	if (group) {
2977 		if (isdir) {
2978 			/* exec if any of list, traverse */
2979 			if (group & DIR_GEXEC)
2980 				perm |= S_IXGRP;
2981 			/* write if any of addfile, adddir, delchild */
2982 			if (group & DIR_GWRITE)
2983 				perm |= S_IWGRP;
2984 			/* read if any of list */
2985 			if (group & DIR_GREAD)
2986 				perm |= S_IRGRP;
2987 		} else {
2988 			/* exec if execute */
2989 			if (group & FILE_GEXEC)
2990 				perm |= S_IXGRP;
2991 			/* write if any of writedata, appenddata */
2992 			if (group & FILE_GWRITE)
2993 				perm |= S_IWGRP;
2994 			/* read if any of readdata */
2995 			if (group & FILE_GREAD)
2996 				perm |= S_IRGRP;
2997 		}
2998 	}
2999 	/* build world permission */
3000 	if (world) {
3001 		if (isdir) {
3002 			/* exec if any of list, traverse */
3003 			if (world & DIR_GEXEC)
3004 				perm |= S_IXOTH;
3005 			/* write if any of addfile, adddir, delchild */
3006 			if (world & DIR_GWRITE)
3007 				perm |= S_IWOTH;
3008 			/* read if any of list */
3009 			if (world & DIR_GREAD)
3010 				perm |= S_IROTH;
3011 		} else {
3012 			/* exec if execute */
3013 			if (world & FILE_GEXEC)
3014 				perm |= S_IXOTH;
3015 			/* write if any of writedata, appenddata */
3016 			if (world & FILE_GWRITE)
3017 				perm |= S_IWOTH;
3018 			/* read if any of readdata */
3019 			if (world & FILE_GREAD)
3020 				perm |= S_IROTH;
3021 		}
3022 	}
3023 	/* build special permission flags */
3024 	if (special) {
3025 		if (special & FILE_APPEND_DATA)
3026 			perm |= S_ISUID;
3027 		if (special & FILE_WRITE_DATA)
3028 			perm |= S_ISGID;
3029 		if (special & FILE_READ_DATA)
3030 			perm |= S_ISVTX;
3031 	}
3032 	return (perm);
3033 }
3034 
3035 #if POSIXACLS
3036 
3037 /*
3038  *		Normalize a Posix ACL either from a sorted raw set of
3039  *		access ACEs or default ACEs
3040  *		(standard case : different owner, group and administrator)
3041  */
3042 
3043 static int norm_std_permissions_posix(struct POSIX_SECURITY *posix_desc,
3044 		BOOL groupowns, int start, int count, int target)
3045 {
3046 	int j,k;
3047 	s32 id;
3048 	u16 tag;
3049 	u16 tagsset;
3050 	struct POSIX_ACE *pxace;
3051 	mode_t grantgrps;
3052 	mode_t grantwrld;
3053 	mode_t denywrld;
3054 	mode_t allow;
3055 	mode_t deny;
3056 	mode_t perms;
3057 	mode_t mode;
3058 
3059 	mode = 0;
3060 	tagsset = 0;
3061 		/*
3062 		 * Determine what is granted to some group or world
3063 		 * Also get denials to world which are meant to prevent
3064 		 * execution flags to be inherited by plain files
3065 		 */
3066 	pxace = posix_desc->acl.ace;
3067 	grantgrps = 0;
3068 	grantwrld = 0;
3069 	denywrld = 0;
3070 	for (j=start; j<(start + count); j++) {
3071 		if (pxace[j].perms & POSIX_PERM_DENIAL) {
3072 				/* deny world exec unless for default */
3073 			if ((pxace[j].tag == POSIX_ACL_OTHER)
3074 			&& !start)
3075 				denywrld = pxace[j].perms;
3076 		} else {
3077 			switch (pxace[j].tag) {
3078 			case POSIX_ACL_GROUP_OBJ :
3079 				grantgrps |= pxace[j].perms;
3080 				break;
3081 			case POSIX_ACL_GROUP :
3082 				if (pxace[j].id)
3083 					grantgrps |= pxace[j].perms;
3084 				break;
3085 			case POSIX_ACL_OTHER :
3086 				grantwrld = pxace[j].perms;
3087 				break;
3088 			default :
3089 				break;
3090 			}
3091 		}
3092 	}
3093 		/*
3094 		 * Collect groups of ACEs related to the same id
3095 		 * and determine what is granted and what is denied.
3096 		 * It is important the ACEs have been sorted
3097 		 */
3098 	j = start;
3099 	k = target;
3100 	while (j < (start + count)) {
3101 		tag = pxace[j].tag;
3102 		id = pxace[j].id;
3103 		if (pxace[j].perms & POSIX_PERM_DENIAL) {
3104 			deny = pxace[j].perms | denywrld;
3105 			allow = 0;
3106 		} else {
3107 			deny = denywrld;
3108 			allow = pxace[j].perms;
3109 		}
3110 		j++;
3111 		while ((j < (start + count))
3112 		    && (pxace[j].tag == tag)
3113 		    && (pxace[j].id == id)) {
3114 			if (pxace[j].perms & POSIX_PERM_DENIAL)
3115 				deny |= pxace[j].perms;
3116 			else
3117 				allow |= pxace[j].perms;
3118 			j++;
3119 		}
3120 			/*
3121 			 * Build the permissions equivalent to grants and denials
3122 			 */
3123 		if (groupowns) {
3124 			if (tag == POSIX_ACL_MASK)
3125 				perms = ~deny;
3126 			else
3127 				perms = allow & ~deny;
3128 		} else
3129 			switch (tag) {
3130 			case POSIX_ACL_USER_OBJ :
3131 				perms = (allow | grantgrps | grantwrld) & ~deny;
3132 				break;
3133 			case POSIX_ACL_USER :
3134 				if (id)
3135 					perms = (allow | grantgrps | grantwrld)
3136 						& ~deny;
3137 				else
3138 					perms = allow;
3139 				break;
3140 			case POSIX_ACL_GROUP_OBJ :
3141 				perms = (allow | grantwrld) & ~deny;
3142 				break;
3143 			case POSIX_ACL_GROUP :
3144 				if (id)
3145 					perms = (allow | grantwrld) & ~deny;
3146 				else
3147 					perms = allow;
3148 				break;
3149 			case POSIX_ACL_MASK :
3150 				perms = ~deny;
3151 				break;
3152 			default :
3153 				perms = allow & ~deny;
3154 				break;
3155 			}
3156 			/*
3157 			 * Store into a Posix ACE
3158 			 */
3159 		if (tag != POSIX_ACL_SPECIAL) {
3160 			pxace[k].tag = tag;
3161 			pxace[k].id = id;
3162 			pxace[k].perms = perms
3163 				 & (POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X);
3164 			tagsset |= tag;
3165 			k++;
3166 		}
3167 		switch (tag) {
3168 		case POSIX_ACL_USER_OBJ :
3169 			mode |= ((perms & 7) << 6);
3170 			break;
3171 		case POSIX_ACL_GROUP_OBJ :
3172 		case POSIX_ACL_MASK :
3173 			mode = (mode & 07707) | ((perms & 7) << 3);
3174 			break;
3175 		case POSIX_ACL_OTHER :
3176 			mode |= perms & 7;
3177 			break;
3178 		case POSIX_ACL_SPECIAL :
3179 			mode |= (perms & (S_ISVTX | S_ISUID | S_ISGID));
3180 			break;
3181 		default :
3182 			break;
3183 		}
3184 	}
3185 	if (!start) { /* not satisfactory */
3186 		posix_desc->mode = mode;
3187 		posix_desc->tagsset = tagsset;
3188 	}
3189 	return (k - target);
3190 }
3191 
3192 #endif /* POSIXACLS */
3193 
3194 /*
3195  *		Interpret an ACL and extract meaningful grants
3196  *		(standard case : different owner, group and administrator)
3197  */
3198 
3199 static int build_std_permissions(const char *securattr,
3200 		const SID *usid, const SID *gsid, BOOL isdir)
3201 {
3202 	const SECURITY_DESCRIPTOR_RELATIVE *phead;
3203 	const ACL *pacl;
3204 	const ACCESS_ALLOWED_ACE *pace;
3205 	int offdacl;
3206 	int offace;
3207 	int acecnt;
3208 	int nace;
3209 	BOOL noown;
3210 	le32 special;
3211 	le32 allowown, allowgrp, allowall;
3212 	le32 denyown, denygrp, denyall;
3213 
3214 	phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr;
3215 	offdacl = le32_to_cpu(phead->dacl);
3216 	pacl = (const ACL*)&securattr[offdacl];
3217 	special = const_cpu_to_le32(0);
3218 	allowown = allowgrp = allowall = const_cpu_to_le32(0);
3219 	denyown = denygrp = denyall = const_cpu_to_le32(0);
3220 	noown = TRUE;
3221 	if (offdacl) {
3222 		acecnt = le16_to_cpu(pacl->ace_count);
3223 		offace = offdacl + sizeof(ACL);
3224 	} else {
3225 		acecnt = 0;
3226 		offace = 0;
3227 	}
3228 	for (nace = 0; nace < acecnt; nace++) {
3229 		pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace];
3230 		if (!(pace->flags & INHERIT_ONLY_ACE)) {
3231 			if (ntfs_same_sid(usid, &pace->sid)
3232 			  || ntfs_same_sid(ownersid, &pace->sid)) {
3233 				noown = FALSE;
3234 				if (pace->type == ACCESS_ALLOWED_ACE_TYPE)
3235 					allowown |= pace->mask;
3236 				else if (pace->type == ACCESS_DENIED_ACE_TYPE)
3237 					denyown |= pace->mask;
3238 				} else
3239 				if (ntfs_same_sid(gsid, &pace->sid)
3240 				    && !(pace->mask & WRITE_OWNER)) {
3241 					if (pace->type == ACCESS_ALLOWED_ACE_TYPE)
3242 						allowgrp |= pace->mask;
3243 					else if (pace->type == ACCESS_DENIED_ACE_TYPE)
3244 						denygrp |= pace->mask;
3245 				} else
3246 					if (is_world_sid((const SID*)&pace->sid)) {
3247 						if (pace->type == ACCESS_ALLOWED_ACE_TYPE)
3248 							allowall |= pace->mask;
3249 						else
3250 							if (pace->type == ACCESS_DENIED_ACE_TYPE)
3251 								denyall |= pace->mask;
3252 					} else
3253 					if ((ntfs_same_sid((const SID*)&pace->sid,nullsid))
3254 					   && (pace->type == ACCESS_ALLOWED_ACE_TYPE))
3255 						special |= pace->mask;
3256 			}
3257 			offace += le16_to_cpu(pace->size);
3258 		}
3259 		/*
3260 		 * No indication about owner's rights : grant basic rights
3261 		 * This happens for files created by Windows in directories
3262 		 * created by Linux and owned by root, because Windows
3263 		 * merges the admin ACEs
3264 		 */
3265 	if (noown)
3266 		allowown = (FILE_READ_DATA | FILE_WRITE_DATA | FILE_EXECUTE);
3267 		/*
3268 		 *  Add to owner rights granted to group or world
3269 		 * unless denied personaly, and add to group rights
3270 		 * granted to world unless denied specifically
3271 		 */
3272 	allowown |= (allowgrp | allowall);
3273 	allowgrp |= allowall;
3274 	return (merge_permissions(isdir,
3275 				allowown & ~(denyown | denyall),
3276 				allowgrp & ~(denygrp | denyall),
3277 				allowall & ~denyall,
3278 				special));
3279 }
3280 
3281 /*
3282  *		Interpret an ACL and extract meaningful grants
3283  *		(special case : owner and group are the same,
3284  *		and not administrator)
3285  */
3286 
3287 static int build_owngrp_permissions(const char *securattr,
3288 			const SID *usid, BOOL isdir)
3289 {
3290 	const SECURITY_DESCRIPTOR_RELATIVE *phead;
3291 	const ACL *pacl;
3292 	const ACCESS_ALLOWED_ACE *pace;
3293 	int offdacl;
3294 	int offace;
3295 	int acecnt;
3296 	int nace;
3297 	le32 special;
3298 	BOOL grppresent;
3299 	BOOL ownpresent;
3300 	le32 allowown, allowgrp, allowall;
3301 	le32 denyown, denygrp, denyall;
3302 
3303 	phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr;
3304 	offdacl = le32_to_cpu(phead->dacl);
3305 	pacl = (const ACL*)&securattr[offdacl];
3306 	special = const_cpu_to_le32(0);
3307 	allowown = allowgrp = allowall = const_cpu_to_le32(0);
3308 	denyown = denygrp = denyall = const_cpu_to_le32(0);
3309 	ownpresent = FALSE;
3310 	grppresent = FALSE;
3311 	if (offdacl) {
3312 		acecnt = le16_to_cpu(pacl->ace_count);
3313 		offace = offdacl + sizeof(ACL);
3314 	} else {
3315 		acecnt = 0;
3316 		offace = 0;
3317 	}
3318 	for (nace = 0; nace < acecnt; nace++) {
3319 		pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace];
3320 		if (!(pace->flags & INHERIT_ONLY_ACE)) {
3321 			if ((ntfs_same_sid(usid, &pace->sid)
3322 			   || ntfs_same_sid(ownersid, &pace->sid))
3323 			    && (pace->mask & WRITE_OWNER)) {
3324 				if (pace->type == ACCESS_ALLOWED_ACE_TYPE) {
3325 					allowown |= pace->mask;
3326 					ownpresent = TRUE;
3327 				}
3328 			} else
3329 				if (ntfs_same_sid(usid, &pace->sid)
3330 				   && (!(pace->mask & WRITE_OWNER))) {
3331 					if (pace->type == ACCESS_ALLOWED_ACE_TYPE) {
3332 						allowgrp |= pace->mask;
3333 						grppresent = TRUE;
3334 					}
3335 				} else
3336 					if (is_world_sid((const SID*)&pace->sid)) {
3337 						if (pace->type == ACCESS_ALLOWED_ACE_TYPE)
3338 							allowall |= pace->mask;
3339 						else
3340 							if (pace->type == ACCESS_DENIED_ACE_TYPE)
3341 								denyall |= pace->mask;
3342 					} else
3343 					if ((ntfs_same_sid((const SID*)&pace->sid,nullsid))
3344 					   && (pace->type == ACCESS_ALLOWED_ACE_TYPE))
3345 						special |= pace->mask;
3346 			}
3347 			offace += le16_to_cpu(pace->size);
3348 		}
3349 	if (!ownpresent)
3350 		allowown = allowall;
3351 	if (!grppresent)
3352 		allowgrp = allowall;
3353 	return (merge_permissions(isdir,
3354 				allowown & ~(denyown | denyall),
3355 				allowgrp & ~(denygrp | denyall),
3356 				allowall & ~denyall,
3357 				special));
3358 }
3359 
3360 #if POSIXACLS
3361 
3362 /*
3363  *		Normalize a Posix ACL either from a sorted raw set of
3364  *		access ACEs or default ACEs
3365  *		(special case : owner or/and group is administrator)
3366  */
3367 
3368 static int norm_ownadmin_permissions_posix(struct POSIX_SECURITY *posix_desc,
3369 		int start, int count, int target)
3370 {
3371 	int j,k;
3372 	s32 id;
3373 	u16 tag;
3374 	u16 tagsset;
3375 	struct POSIX_ACE *pxace;
3376 	mode_t denywrld;
3377 	mode_t allow;
3378 	mode_t deny;
3379 	mode_t perms;
3380 	mode_t mode;
3381 
3382 	mode = 0;
3383 	pxace = posix_desc->acl.ace;
3384 	tagsset = 0;
3385 	denywrld = 0;
3386 		/*
3387 		 * Get denials to world which are meant to prevent
3388 		 * execution flags to be inherited by plain files
3389 		 */
3390 	for (j=start; j<(start + count); j++) {
3391 		if (pxace[j].perms & POSIX_PERM_DENIAL) {
3392 				/* deny world exec not for default */
3393 			if ((pxace[j].tag == POSIX_ACL_OTHER)
3394 			&& !start)
3395 				denywrld = pxace[j].perms;
3396 		}
3397 	}
3398 		/*
3399 		 * Collect groups of ACEs related to the same id
3400 		 * and determine what is granted (denials are ignored)
3401 		 * It is important the ACEs have been sorted
3402 		 */
3403 	j = start;
3404 	k = target;
3405 	deny = 0;
3406 	while (j < (start + count)) {
3407 		allow = 0;
3408 		tag = pxace[j].tag;
3409 		id = pxace[j].id;
3410 		if (tag == POSIX_ACL_MASK) {
3411 			deny = pxace[j].perms;
3412 			j++;
3413 			while ((j < (start + count))
3414 			    && (pxace[j].tag == POSIX_ACL_MASK))
3415 				j++;
3416 		} else {
3417 			if (!(pxace[j].perms & POSIX_PERM_DENIAL))
3418 				allow = pxace[j].perms;
3419 			j++;
3420 			while ((j < (start + count))
3421 			    && (pxace[j].tag == tag)
3422 			    && (pxace[j].id == id)) {
3423 				if (!(pxace[j].perms & POSIX_PERM_DENIAL))
3424 					allow |= pxace[j].perms;
3425 				j++;
3426 			}
3427 		}
3428 
3429 			/*
3430 			 * Store the grants into a Posix ACE
3431 			 */
3432 		if (tag == POSIX_ACL_MASK)
3433 			perms = ~deny;
3434 		else
3435 			perms = allow & ~denywrld;
3436 		if (tag != POSIX_ACL_SPECIAL) {
3437 			pxace[k].tag = tag;
3438 			pxace[k].id = id;
3439 			pxace[k].perms = perms
3440 				 & (POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X);
3441 			tagsset |= tag;
3442 			k++;
3443 		}
3444 		switch (tag) {
3445 		case POSIX_ACL_USER_OBJ :
3446 			mode |= ((perms & 7) << 6);
3447 			break;
3448 		case POSIX_ACL_GROUP_OBJ :
3449 		case POSIX_ACL_MASK :
3450 			mode = (mode & 07707) | ((perms & 7) << 3);
3451 			break;
3452 		case POSIX_ACL_OTHER :
3453 			mode |= perms & 7;
3454 			break;
3455 		case POSIX_ACL_SPECIAL :
3456 			mode |= perms & (S_ISVTX | S_ISUID | S_ISGID);
3457 			break;
3458 		default :
3459 			break;
3460 		}
3461 	}
3462 	if (!start) { /* not satisfactory */
3463 		posix_desc->mode = mode;
3464 		posix_desc->tagsset = tagsset;
3465 	}
3466 	return (k - target);
3467 }
3468 
3469 #endif /* POSIXACLS */
3470 
3471 /*
3472  *		Interpret an ACL and extract meaningful grants
3473  *		(special case : owner or/and group is administrator)
3474  */
3475 
3476 
3477 static int build_ownadmin_permissions(const char *securattr,
3478 			const SID *usid, const SID *gsid, BOOL isdir)
3479 {
3480 	const SECURITY_DESCRIPTOR_RELATIVE *phead;
3481 	const ACL *pacl;
3482 	const ACCESS_ALLOWED_ACE *pace;
3483 	int offdacl;
3484 	int offace;
3485 	int acecnt;
3486 	int nace;
3487 	BOOL firstapply;
3488 	int isforeign;
3489 	le32 special;
3490 	le32 allowown, allowgrp, allowall;
3491 	le32 denyown, denygrp, denyall;
3492 
3493 	phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr;
3494 	offdacl = le32_to_cpu(phead->dacl);
3495 	pacl = (const ACL*)&securattr[offdacl];
3496 	special = const_cpu_to_le32(0);
3497 	allowown = allowgrp = allowall = const_cpu_to_le32(0);
3498 	denyown = denygrp = denyall = const_cpu_to_le32(0);
3499 	if (offdacl) {
3500 		acecnt = le16_to_cpu(pacl->ace_count);
3501 		offace = offdacl + sizeof(ACL);
3502 	} else {
3503 		acecnt = 0;
3504 		offace = 0;
3505 	}
3506 	firstapply = TRUE;
3507 	isforeign = 3;
3508 	for (nace = 0; nace < acecnt; nace++) {
3509 		pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace];
3510 		if (!(pace->flags & INHERIT_ONLY_ACE)
3511 		   && !(~pace->mask & (ROOT_OWNER_UNMARK | ROOT_GROUP_UNMARK))) {
3512 			if ((ntfs_same_sid(usid, &pace->sid)
3513 			   || ntfs_same_sid(ownersid, &pace->sid))
3514 			     && (((pace->mask & WRITE_OWNER) && firstapply))) {
3515 				if (pace->type == ACCESS_ALLOWED_ACE_TYPE) {
3516 					allowown |= pace->mask;
3517 					isforeign &= ~1;
3518 				} else
3519 					if (pace->type == ACCESS_DENIED_ACE_TYPE)
3520 						denyown |= pace->mask;
3521 				} else
3522 				    if (ntfs_same_sid(gsid, &pace->sid)
3523 					&& (!(pace->mask & WRITE_OWNER))) {
3524 						if (pace->type == ACCESS_ALLOWED_ACE_TYPE) {
3525 							allowgrp |= pace->mask;
3526 							isforeign &= ~2;
3527 						} else
3528 							if (pace->type == ACCESS_DENIED_ACE_TYPE)
3529 								denygrp |= pace->mask;
3530 					} else if (is_world_sid((const SID*)&pace->sid)) {
3531 						if (pace->type == ACCESS_ALLOWED_ACE_TYPE)
3532 							allowall |= pace->mask;
3533 						else
3534 							if (pace->type == ACCESS_DENIED_ACE_TYPE)
3535 								denyall |= pace->mask;
3536 					}
3537 			firstapply = FALSE;
3538 			} else
3539 				if (!(pace->flags & INHERIT_ONLY_ACE))
3540 					if ((ntfs_same_sid((const SID*)&pace->sid,nullsid))
3541 					   && (pace->type == ACCESS_ALLOWED_ACE_TYPE))
3542 						special |= pace->mask;
3543 			offace += le16_to_cpu(pace->size);
3544 		}
3545 	if (isforeign) {
3546 		allowown |= (allowgrp | allowall);
3547 		allowgrp |= allowall;
3548 	}
3549 	return (merge_permissions(isdir,
3550 				allowown & ~(denyown | denyall),
3551 				allowgrp & ~(denygrp | denyall),
3552 				allowall & ~denyall,
3553 				special));
3554 }
3555 
3556 #if OWNERFROMACL
3557 
3558 /*
3559  *		Define the owner of a file as the first user allowed
3560  *	to change the owner, instead of the user defined as owner.
3561  *
3562  *	This produces better approximations for files written by a
3563  *	Windows user in an inheritable directory owned by another user,
3564  *	as the access rights are inheritable but the ownership is not.
3565  *
3566  *	An important case is the directories "Documents and Settings/user"
3567  *	which the users must have access to, though Windows considers them
3568  *	as owned by administrator.
3569  */
3570 
3571 const SID *ntfs_acl_owner(const char *securattr)
3572 {
3573 	const SECURITY_DESCRIPTOR_RELATIVE *phead;
3574 	const SID *usid;
3575 	const ACL *pacl;
3576 	const ACCESS_ALLOWED_ACE *pace;
3577 	int offdacl;
3578 	int offace;
3579 	int acecnt;
3580 	int nace;
3581 	BOOL found;
3582 
3583 	found = FALSE;
3584 	phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr;
3585 	offdacl = le32_to_cpu(phead->dacl);
3586 	if (offdacl) {
3587 		pacl = (const ACL*)&securattr[offdacl];
3588 		acecnt = le16_to_cpu(pacl->ace_count);
3589 		offace = offdacl + sizeof(ACL);
3590 		nace = 0;
3591 		do {
3592 			pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace];
3593 			if ((pace->mask & WRITE_OWNER)
3594 			   && (pace->type == ACCESS_ALLOWED_ACE_TYPE)
3595 			   && ntfs_is_user_sid(&pace->sid))
3596 				found = TRUE;
3597 			offace += le16_to_cpu(pace->size);
3598 		} while (!found && (++nace < acecnt));
3599 	}
3600 	if (found)
3601 		usid = &pace->sid;
3602 	else
3603 		usid = (const SID*)&securattr[le32_to_cpu(phead->owner)];
3604 	return (usid);
3605 }
3606 
3607 #else
3608 
3609 /*
3610  *		Special case for files owned by administrator with full
3611  *	access granted to a mapped user : consider this user as the tenant
3612  *	of the file.
3613  *
3614  *	This situation cannot be represented with Linux concepts and can
3615  *	only be found for files or directories created by Windows.
3616  *	Typical situation : directory "Documents and Settings/user" which
3617  *	is on the path to user's files and must be given access to user
3618  *	only.
3619  *
3620  *	Check file is owned by administrator and no user has rights before
3621  *	calling.
3622  *	Returns the uid of tenant or zero if none
3623  */
3624 
3625 
3626 static uid_t find_tenant(struct MAPPING *const mapping[],
3627 			const char *securattr)
3628 {
3629 	const SECURITY_DESCRIPTOR_RELATIVE *phead;
3630 	const ACL *pacl;
3631 	const ACCESS_ALLOWED_ACE *pace;
3632 	int offdacl;
3633 	int offace;
3634 	int acecnt;
3635 	int nace;
3636 	uid_t tid;
3637 	uid_t xid;
3638 
3639 	phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr;
3640 	offdacl = le32_to_cpu(phead->dacl);
3641 	pacl = (const ACL*)&securattr[offdacl];
3642 	tid = 0;
3643 	if (offdacl) {
3644 		acecnt = le16_to_cpu(pacl->ace_count);
3645 		offace = offdacl + sizeof(ACL);
3646 	} else
3647 		acecnt = 0;
3648 	for (nace = 0; nace < acecnt; nace++) {
3649 		pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace];
3650 		if ((pace->type == ACCESS_ALLOWED_ACE_TYPE)
3651 		   && (pace->mask & DIR_WRITE)) {
3652 			xid = ntfs_find_user(mapping[MAPUSERS], &pace->sid);
3653 			if (xid) tid = xid;
3654 		}
3655 		offace += le16_to_cpu(pace->size);
3656 	}
3657 	return (tid);
3658 }
3659 
3660 #endif /* OWNERFROMACL */
3661 
3662 #if POSIXACLS
3663 
3664 /*
3665  *		Build Posix permissions from an ACL
3666  *	returns a pointer to the requested permissions
3667  *	or a null pointer (with errno set) if there is a problem
3668  *
3669  *	If the NTFS ACL was created according to our rules, the retrieved
3670  *	Posix ACL should be the exact ACL which was set. However if
3671  *	the NTFS ACL was built by a different tool, the result could
3672  *	be a a poor approximation of what was expected
3673  */
3674 
3675 struct POSIX_SECURITY *ntfs_build_permissions_posix(
3676 			struct MAPPING *const mapping[],
3677 			const char *securattr,
3678 			const SID *usid, const SID *gsid, BOOL isdir)
3679 {
3680 	const SECURITY_DESCRIPTOR_RELATIVE *phead;
3681 	struct POSIX_SECURITY *pxdesc;
3682 	const ACL *pacl;
3683 	const ACCESS_ALLOWED_ACE *pace;
3684 	struct POSIX_ACE *pxace;
3685 	struct {
3686 		uid_t prevuid;
3687 		gid_t prevgid;
3688 		int groupmasks;
3689 		s16 tagsset;
3690 		BOOL gotowner;
3691 		BOOL gotownermask;
3692 		BOOL gotgroup;
3693 		mode_t permswrld;
3694 	} ctx[2], *pctx;
3695 	int offdacl;
3696 	int offace;
3697 	int alloccnt;
3698 	int acecnt;
3699 	uid_t uid;
3700 	gid_t gid;
3701 	int i,j;
3702 	int k,l;
3703 	BOOL ignore;
3704 	BOOL adminowns;
3705 	BOOL groupowns;
3706 	BOOL firstinh;
3707 	BOOL genericinh;
3708 
3709 	phead = (const SECURITY_DESCRIPTOR_RELATIVE*)securattr;
3710 	offdacl = le32_to_cpu(phead->dacl);
3711 	if (offdacl) {
3712 		pacl = (const ACL*)&securattr[offdacl];
3713 		acecnt = le16_to_cpu(pacl->ace_count);
3714 		offace = offdacl + sizeof(ACL);
3715 	} else {
3716 		acecnt = 0;
3717 		offace = 0;
3718 	}
3719 	adminowns = FALSE;
3720 	groupowns = ntfs_same_sid(gsid,usid);
3721 	firstinh = FALSE;
3722 	genericinh = FALSE;
3723 		/*
3724 		 * Build a raw posix security descriptor
3725 		 * by just translating permissions and ids
3726 		 * Add 2 to the count of ACE to be able to insert
3727 		 * a group ACE later in access and default ACLs
3728 		 * and add 2 more to be able to insert ACEs for owner
3729 		 * and 2 more for other
3730 		 */
3731 	alloccnt = acecnt + 6;
3732 	pxdesc = (struct POSIX_SECURITY*)malloc(
3733 				sizeof(struct POSIX_SECURITY)
3734 				+ alloccnt*sizeof(struct POSIX_ACE));
3735 	k = 0;
3736 	l = alloccnt;
3737 	for (i=0; i<2; i++) {
3738 		pctx = &ctx[i];
3739 		pctx->permswrld = 0;
3740 		pctx->prevuid = -1;
3741 		pctx->prevgid = -1;
3742 		pctx->groupmasks = 0;
3743 		pctx->tagsset = 0;
3744 		pctx->gotowner = FALSE;
3745 		pctx->gotgroup = FALSE;
3746 		pctx->gotownermask = FALSE;
3747 	}
3748 	for (j=0; j<acecnt; j++) {
3749 		pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace];
3750 		if (pace->flags & INHERIT_ONLY_ACE) {
3751 			pxace = &pxdesc->acl.ace[l - 1];
3752 			pctx = &ctx[1];
3753 		} else {
3754 			pxace = &pxdesc->acl.ace[k];
3755 			pctx = &ctx[0];
3756 		}
3757 		ignore = FALSE;
3758 			/*
3759 			 * grants for root as a designated user or group
3760 			 */
3761 		if ((~pace->mask & (ROOT_OWNER_UNMARK | ROOT_GROUP_UNMARK))
3762 		   && (pace->type == ACCESS_ALLOWED_ACE_TYPE)
3763 		   && ntfs_same_sid(&pace->sid, adminsid)) {
3764 			pxace->tag = (pace->mask & ROOT_OWNER_UNMARK ? POSIX_ACL_GROUP : POSIX_ACL_USER);
3765 			pxace->id = 0;
3766 			if ((pace->mask & (GENERIC_ALL | WRITE_OWNER))
3767 			   && (pace->flags & INHERIT_ONLY_ACE))
3768 				ignore = genericinh = TRUE;
3769 		} else
3770 		if (ntfs_same_sid(usid, &pace->sid)) {
3771 			pxace->id = -1;
3772 				/*
3773 				 * Owner has no write-owner right :
3774 				 * a group was defined same as owner
3775 				 * or admin was owner or group :
3776 				 * denials are meant to owner
3777 				 * and grants are meant to group
3778 				 */
3779 			if (!(pace->mask & (WRITE_OWNER | GENERIC_ALL))
3780 			    && (pace->type == ACCESS_ALLOWED_ACE_TYPE)) {
3781 				if (ntfs_same_sid(gsid,usid)) {
3782 					pxace->tag = POSIX_ACL_GROUP_OBJ;
3783 					pxace->id = -1;
3784 				} else {
3785 					if (ntfs_same_sid(&pace->sid,usid))
3786 						groupowns = TRUE;
3787 					gid = ntfs_find_group(mapping[MAPGROUPS],&pace->sid);
3788 					if (gid) {
3789 						pxace->tag = POSIX_ACL_GROUP;
3790 						pxace->id = gid;
3791 						pctx->prevgid = gid;
3792 					} else {
3793 					uid = ntfs_find_user(mapping[MAPUSERS],&pace->sid);
3794 					if (uid) {
3795 						pxace->tag = POSIX_ACL_USER;
3796 						pxace->id = uid;
3797 					} else
3798 						ignore = TRUE;
3799 					}
3800 				}
3801 			} else {
3802 				/*
3803 				 * when group owns, late denials for owner
3804 				 * mean group mask
3805 				 */
3806 				if ((pace->type == ACCESS_DENIED_ACE_TYPE)
3807 				    && (pace->mask & WRITE_OWNER)) {
3808 					pxace->tag = POSIX_ACL_MASK;
3809 					pctx->gotownermask = TRUE;
3810 					if (pctx->gotowner)
3811 						pctx->groupmasks++;
3812 				} else {
3813 					if (pace->type == ACCESS_ALLOWED_ACE_TYPE)
3814 						pctx->gotowner = TRUE;
3815 					if (pctx->gotownermask && !pctx->gotowner) {
3816 						uid = ntfs_find_user(mapping[MAPUSERS],&pace->sid);
3817 						pxace->id = uid;
3818 						pxace->tag = POSIX_ACL_USER;
3819 					} else
3820 						pxace->tag = POSIX_ACL_USER_OBJ;
3821 						/* system ignored, and admin */
3822 						/* ignored at first position */
3823 					if (pace->flags & INHERIT_ONLY_ACE) {
3824 						if ((firstinh && ntfs_same_sid(&pace->sid,adminsid))
3825 						   || ntfs_same_sid(&pace->sid,systemsid))
3826 							ignore = TRUE;
3827 						if (!firstinh) {
3828 							firstinh = TRUE;
3829 						}
3830 					} else {
3831 						if ((adminowns && ntfs_same_sid(&pace->sid,adminsid))
3832 						   || ntfs_same_sid(&pace->sid,systemsid))
3833 							ignore = TRUE;
3834 						if (ntfs_same_sid(usid,adminsid))
3835 							adminowns = TRUE;
3836 					}
3837 				}
3838 			}
3839 		} else if (ntfs_same_sid(gsid, &pace->sid)) {
3840 			if ((pace->type == ACCESS_DENIED_ACE_TYPE)
3841 			    && (pace->mask & WRITE_OWNER)) {
3842 				pxace->tag = POSIX_ACL_MASK;
3843 				pxace->id = -1;
3844 				if (pctx->gotowner)
3845 					pctx->groupmasks++;
3846 			} else {
3847 				if (pctx->gotgroup || (pctx->groupmasks > 1)) {
3848 					gid = ntfs_find_group(mapping[MAPGROUPS],&pace->sid);
3849 					if (gid) {
3850 						pxace->id = gid;
3851 						pxace->tag = POSIX_ACL_GROUP;
3852 						pctx->prevgid = gid;
3853 					} else
3854 						ignore = TRUE;
3855 				} else {
3856 					pxace->id = -1;
3857 					pxace->tag = POSIX_ACL_GROUP_OBJ;
3858 					if (pace->type == ACCESS_ALLOWED_ACE_TYPE)
3859 						pctx->gotgroup = TRUE;
3860 				}
3861 
3862 				if (ntfs_same_sid(gsid,adminsid)
3863 				    || ntfs_same_sid(gsid,systemsid)) {
3864 					if (pace->mask & (WRITE_OWNER | GENERIC_ALL))
3865 						ignore = TRUE;
3866 					if (ntfs_same_sid(gsid,adminsid))
3867 						adminowns = TRUE;
3868 					else
3869 						genericinh = ignore;
3870 				}
3871 			}
3872 		} else if (is_world_sid((const SID*)&pace->sid)) {
3873 			pxace->id = -1;
3874 			pxace->tag = POSIX_ACL_OTHER;
3875 			if ((pace->type == ACCESS_DENIED_ACE_TYPE)
3876 			   && (pace->flags & INHERIT_ONLY_ACE))
3877 				ignore = TRUE;
3878 		} else if (ntfs_same_sid((const SID*)&pace->sid,nullsid)) {
3879 			pxace->id = -1;
3880 			pxace->tag = POSIX_ACL_SPECIAL;
3881 		} else {
3882 			uid = ntfs_find_user(mapping[MAPUSERS],&pace->sid);
3883 			if (uid) {
3884 				if ((pace->type == ACCESS_DENIED_ACE_TYPE)
3885 				    && (pace->mask & WRITE_OWNER)
3886 				    && (pctx->prevuid != uid)) {
3887 					pxace->id = -1;
3888 					pxace->tag = POSIX_ACL_MASK;
3889 				} else {
3890 					pxace->id = uid;
3891 					pxace->tag = POSIX_ACL_USER;
3892 				}
3893 				pctx->prevuid = uid;
3894 			} else {
3895 				gid = ntfs_find_group(mapping[MAPGROUPS],&pace->sid);
3896 				if (gid) {
3897 					if ((pace->type == ACCESS_DENIED_ACE_TYPE)
3898 					    && (pace->mask & WRITE_OWNER)
3899 					    && (pctx->prevgid != gid)) {
3900 						pxace->tag = POSIX_ACL_MASK;
3901 						pctx->groupmasks++;
3902 					} else {
3903 						pxace->tag = POSIX_ACL_GROUP;
3904 					}
3905 					pxace->id = gid;
3906 					pctx->prevgid = gid;
3907 				} else {
3908 					/*
3909 					 * do not grant rights to unknown
3910 					 * people and do not define root as a
3911 					 * designated user or group
3912 					 */
3913 					ignore = TRUE;
3914 				}
3915 			}
3916 		}
3917 		if (((pace->type == ACCESS_ALLOWED_ACE_TYPE)
3918 			|| (pace->type == ACCESS_DENIED_ACE_TYPE))
3919 		    && !ignore) {
3920 			pxace->perms = 0;
3921 				/* specific decoding for vtx/uid/gid */
3922 			if (pxace->tag == POSIX_ACL_SPECIAL) {
3923 				if (pace->mask & FILE_APPEND_DATA)
3924 					pxace->perms |= S_ISUID;
3925 				if (pace->mask & FILE_WRITE_DATA)
3926 					pxace->perms |= S_ISGID;
3927 				if (pace->mask & FILE_READ_DATA)
3928 					pxace->perms |= S_ISVTX;
3929 			} else
3930 				if (isdir) {
3931 					if (pace->mask & DIR_GEXEC)
3932 						pxace->perms |= POSIX_PERM_X;
3933 					if (pace->mask & DIR_GWRITE)
3934 						pxace->perms |= POSIX_PERM_W;
3935 					if (pace->mask & DIR_GREAD)
3936 						pxace->perms |= POSIX_PERM_R;
3937 					if ((pace->mask & GENERIC_ALL)
3938 					   && (pace->flags & INHERIT_ONLY_ACE))
3939 						pxace->perms |= POSIX_PERM_X
3940 								| POSIX_PERM_W
3941 								| POSIX_PERM_R;
3942 				} else {
3943 					if (pace->mask & FILE_GEXEC)
3944 						pxace->perms |= POSIX_PERM_X;
3945 					if (pace->mask & FILE_GWRITE)
3946 						pxace->perms |= POSIX_PERM_W;
3947 					if (pace->mask & FILE_GREAD)
3948 						pxace->perms |= POSIX_PERM_R;
3949 				}
3950 
3951 			if (pace->type != ACCESS_ALLOWED_ACE_TYPE)
3952 				pxace->perms |= POSIX_PERM_DENIAL;
3953 			else
3954 				if (pxace->tag == POSIX_ACL_OTHER)
3955 					pctx->permswrld |= pxace->perms;
3956 			pctx->tagsset |= pxace->tag;
3957 			if (pace->flags & INHERIT_ONLY_ACE) {
3958 				l--;
3959 			} else {
3960 				k++;
3961 			}
3962 		}
3963 		offace += le16_to_cpu(pace->size);
3964 	}
3965 		/*
3966 		 * Create world perms if none (both lists)
3967 		 */
3968 	for (i=0; i<2; i++)
3969 		if ((genericinh || !i)
3970 		    && !(ctx[i].tagsset & POSIX_ACL_OTHER)) {
3971 			if (i)
3972 				pxace = &pxdesc->acl.ace[--l];
3973 			else
3974 				pxace = &pxdesc->acl.ace[k++];
3975 			pxace->tag = POSIX_ACL_OTHER;
3976 			pxace->id = -1;
3977 			pxace->perms = 0;
3978 			ctx[i].tagsset |= POSIX_ACL_OTHER;
3979 			ctx[i].permswrld = 0;
3980 		}
3981 		/*
3982 		 * Set basic owner perms if none (both lists)
3983 		 * This happens for files created by Windows in directories
3984 		 * created by Linux and owned by root, because Windows
3985 		 * merges the admin ACEs
3986 		 */
3987 	for (i=0; i<2; i++)
3988 		if (!(ctx[i].tagsset & POSIX_ACL_USER_OBJ)
3989 		  && (ctx[i].tagsset & POSIX_ACL_OTHER)) {
3990 			if (i)
3991 				pxace = &pxdesc->acl.ace[--l];
3992 			else
3993 				pxace = &pxdesc->acl.ace[k++];
3994 			pxace->tag = POSIX_ACL_USER_OBJ;
3995 			pxace->id = -1;
3996 			pxace->perms = POSIX_PERM_R | POSIX_PERM_W | POSIX_PERM_X;
3997 			ctx[i].tagsset |= POSIX_ACL_USER_OBJ;
3998 		}
3999 		/*
4000 		 * Duplicate world perms as group_obj perms if none
4001 		 */
4002 	for (i=0; i<2; i++)
4003 		if ((ctx[i].tagsset & POSIX_ACL_OTHER)
4004 		    && !(ctx[i].tagsset & POSIX_ACL_GROUP_OBJ)) {
4005 			if (i)
4006 				pxace = &pxdesc->acl.ace[--l];
4007 			else
4008 				pxace = &pxdesc->acl.ace[k++];
4009 			pxace->tag = POSIX_ACL_GROUP_OBJ;
4010 			pxace->id = -1;
4011 			pxace->perms = ctx[i].permswrld;
4012 			ctx[i].tagsset |= POSIX_ACL_GROUP_OBJ;
4013 		}
4014 		/*
4015 		 * Also duplicate world perms as group perms if they
4016 		 * were converted to mask and not followed by a group entry
4017 		 */
4018 	if (ctx[0].groupmasks) {
4019 		for (j=k-2; j>=0; j--) {
4020 			if ((pxdesc->acl.ace[j].tag == POSIX_ACL_MASK)
4021 			   && (pxdesc->acl.ace[j].id != -1)
4022 			   && ((pxdesc->acl.ace[j+1].tag != POSIX_ACL_GROUP)
4023 			     || (pxdesc->acl.ace[j+1].id
4024 				!= pxdesc->acl.ace[j].id))) {
4025 				pxace = &pxdesc->acl.ace[k];
4026 				pxace->tag = POSIX_ACL_GROUP;
4027 				pxace->id = pxdesc->acl.ace[j].id;
4028 				pxace->perms = ctx[0].permswrld;
4029 				ctx[0].tagsset |= POSIX_ACL_GROUP;
4030 				k++;
4031 			}
4032 			if (pxdesc->acl.ace[j].tag == POSIX_ACL_MASK)
4033 				pxdesc->acl.ace[j].id = -1;
4034 		}
4035 	}
4036 	if (ctx[1].groupmasks) {
4037 		for (j=l; j<(alloccnt-1); j++) {
4038 			if ((pxdesc->acl.ace[j].tag == POSIX_ACL_MASK)
4039 			   && (pxdesc->acl.ace[j].id != -1)
4040 			   && ((pxdesc->acl.ace[j+1].tag != POSIX_ACL_GROUP)
4041 			     || (pxdesc->acl.ace[j+1].id
4042 				!= pxdesc->acl.ace[j].id))) {
4043 				pxace = &pxdesc->acl.ace[l - 1];
4044 				pxace->tag = POSIX_ACL_GROUP;
4045 				pxace->id = pxdesc->acl.ace[j].id;
4046 				pxace->perms = ctx[1].permswrld;
4047 				ctx[1].tagsset |= POSIX_ACL_GROUP;
4048 				l--;
4049 			}
4050 			if (pxdesc->acl.ace[j].tag == POSIX_ACL_MASK)
4051 				pxdesc->acl.ace[j].id = -1;
4052 		}
4053 	}
4054 
4055 		/*
4056 		 * Insert default mask if none present and
4057 		 * there are designated users or groups
4058 		 * (the space for it has not beed used)
4059 		 */
4060 	for (i=0; i<2; i++)
4061 		if ((ctx[i].tagsset & (POSIX_ACL_USER | POSIX_ACL_GROUP))
4062 		    && !(ctx[i].tagsset & POSIX_ACL_MASK)) {
4063 			if (i)
4064 				pxace = &pxdesc->acl.ace[--l];
4065 			else
4066 				pxace = &pxdesc->acl.ace[k++];
4067 			pxace->tag = POSIX_ACL_MASK;
4068 			pxace->id = -1;
4069 			pxace->perms = POSIX_PERM_DENIAL;
4070 			ctx[i].tagsset |= POSIX_ACL_MASK;
4071 		}
4072 
4073 	if (k > l) {
4074 		ntfs_log_error("Posix descriptor is longer than expected\n");
4075 		errno = EIO;
4076 		free(pxdesc);
4077 		pxdesc = (struct POSIX_SECURITY*)NULL;
4078 	} else {
4079 		pxdesc->acccnt = k;
4080 		pxdesc->defcnt = alloccnt - l;
4081 		pxdesc->firstdef = l;
4082 		pxdesc->tagsset = ctx[0].tagsset;
4083 		pxdesc->acl.version = POSIX_VERSION;
4084 		pxdesc->acl.flags = 0;
4085 		pxdesc->acl.filler = 0;
4086 		ntfs_sort_posix(pxdesc);
4087 		if (adminowns) {
4088 			k = norm_ownadmin_permissions_posix(pxdesc,
4089 					0, pxdesc->acccnt, 0);
4090 			pxdesc->acccnt = k;
4091 			l = norm_ownadmin_permissions_posix(pxdesc,
4092 					pxdesc->firstdef, pxdesc->defcnt, k);
4093 			pxdesc->firstdef = k;
4094 			pxdesc->defcnt = l;
4095 		} else {
4096 			k = norm_std_permissions_posix(pxdesc,groupowns,
4097 					0, pxdesc->acccnt, 0);
4098 			pxdesc->acccnt = k;
4099 			l = norm_std_permissions_posix(pxdesc,groupowns,
4100 					pxdesc->firstdef, pxdesc->defcnt, k);
4101 			pxdesc->firstdef = k;
4102 			pxdesc->defcnt = l;
4103 		}
4104 	}
4105 	if (pxdesc && !ntfs_valid_posix(pxdesc)) {
4106 		ntfs_log_error("Invalid Posix descriptor built\n");
4107                 errno = EIO;
4108                 free(pxdesc);
4109                 pxdesc = (struct POSIX_SECURITY*)NULL;
4110 	}
4111 	return (pxdesc);
4112 }
4113 
4114 #endif /* POSIXACLS */
4115 
4116 /*
4117  *		Build unix-style (mode_t) permissions from an ACL
4118  *	returns the requested permissions
4119  *	or a negative result (with errno set) if there is a problem
4120  */
4121 
4122 int ntfs_build_permissions(const char *securattr,
4123 			const SID *usid, const SID *gsid, BOOL isdir)
4124 {
4125 	int perm;
4126 	BOOL adminowns;
4127 	BOOL groupowns;
4128 
4129 	adminowns = ntfs_same_sid(usid,adminsid)
4130 	         || ntfs_same_sid(gsid,adminsid);
4131 	groupowns = !adminowns && ntfs_same_sid(gsid,usid);
4132 	if (adminowns)
4133 		perm = build_ownadmin_permissions(securattr, usid, gsid, isdir);
4134 	else
4135 		if (groupowns)
4136 			perm = build_owngrp_permissions(securattr, usid, isdir);
4137 		else
4138 			perm = build_std_permissions(securattr, usid, gsid, isdir);
4139 	return (perm);
4140 }
4141 
4142 #ifndef __HAIKU__
4143 /*
4144  *		The following must be in some library...
4145  */
4146 
4147 static unsigned long atoul(const char *p)
4148 {				/* must be somewhere ! */
4149 	unsigned long v;
4150 
4151 	v = 0;
4152 	while ((*p >= '0') && (*p <= '9'))
4153 		v = v * 10 + (*p++) - '0';
4154 	return (v);
4155 }
4156 #endif
4157 
4158 /*
4159  *		Build an internal representation of a SID
4160  *	Returns a copy in allocated memory if it succeeds
4161  *	The SID is checked to be a valid user one.
4162  */
4163 
4164 static SID *encodesid(const char *sidstr)
4165 {
4166 	SID *sid;
4167 	int cnt;
4168 	BIGSID bigsid;
4169 	SID *bsid;
4170 	u32 auth;
4171 	const char *p;
4172 
4173 	sid = (SID*) NULL;
4174 	if (!strncmp(sidstr, "S-1-", 4)) {
4175 		bsid = (SID*)&bigsid;
4176 		bsid->revision = SID_REVISION;
4177 		p = &sidstr[4];
4178 		auth = atoul(p);
4179 		bsid->identifier_authority.high_part = const_cpu_to_be16(0);
4180 		bsid->identifier_authority.low_part = cpu_to_be32(auth);
4181 		cnt = 0;
4182 		p = strchr(p, '-');
4183 		while (p && (cnt < 8)) {
4184 			p++;
4185 			auth = atoul(p);
4186 			bsid->sub_authority[cnt] = cpu_to_le32(auth);
4187 			p = strchr(p, '-');
4188 			cnt++;
4189 		}
4190 		bsid->sub_authority_count = cnt;
4191 		if ((cnt > 0) && ntfs_valid_sid(bsid)
4192 		    && (ntfs_is_user_sid(bsid) || ntfs_known_group_sid(bsid))) {
4193 			sid = (SID*) ntfs_malloc(4 * cnt + 8);
4194 			if (sid)
4195 				memcpy(sid, bsid, 4 * cnt + 8);
4196 		}
4197 	}
4198 	return (sid);
4199 }
4200 
4201 /*
4202  *		Get a single mapping item from buffer
4203  *
4204  *	Always reads a full line, truncating long lines
4205  *	Refills buffer when exhausted
4206  *	Returns pointer to item, or NULL when there is no more
4207  */
4208 
4209 static struct MAPLIST *getmappingitem(FILEREADER reader, void *fileid,
4210 		off_t *poffs, char *buf, int *psrc, s64 *psize)
4211 {
4212 	int src;
4213 	int dst;
4214 	char *q;
4215 	char *pu;
4216 	char *pg;
4217 	int gotend;
4218 	struct MAPLIST *item;
4219 
4220 	src = *psrc;
4221 	dst = 0;
4222 			/* allocate and get a full line */
4223 	item = (struct MAPLIST*)ntfs_malloc(sizeof(struct MAPLIST));
4224 	if (item) {
4225 		do {
4226 			gotend = 0;
4227 			while ((src < *psize)
4228 			       && (buf[src] != '\n')) {
4229 				if (dst < LINESZ)
4230 					item->maptext[dst++] = buf[src];
4231 				src++;
4232 			}
4233 			if (src >= *psize) {
4234 				*poffs += *psize;
4235 				*psize = reader(fileid, buf, (size_t)BUFSZ, *poffs);
4236 				src = 0;
4237 			} else {
4238 				gotend = 1;
4239 				src++;
4240 				item->maptext[dst] = '\0';
4241 				dst = 0;
4242 			}
4243 		} while (*psize && ((item->maptext[0] == '#') || !gotend));
4244 		if (gotend) {
4245 			pu = pg = (char*)NULL;
4246 			/* decompose into uid, gid and sid */
4247 			item->uidstr = item->maptext;
4248 			item->gidstr = strchr(item->uidstr, ':');
4249 			if (item->gidstr) {
4250 				pu = item->gidstr++;
4251 				item->sidstr = strchr(item->gidstr, ':');
4252 				if (item->sidstr) {
4253 					pg = item->sidstr++;
4254 					q = strchr(item->sidstr, ':');
4255 					if (q) *q = 0;
4256 				}
4257 			}
4258 			if (pu && pg)
4259 				*pu = *pg = '\0';
4260 			else {
4261 				ntfs_log_early_error("Bad mapping item \"%s\"\n",
4262 					item->maptext);
4263 				free(item);
4264 				item = (struct MAPLIST*)NULL;
4265 			}
4266 		} else {
4267 			free(item);	/* free unused item */
4268 			item = (struct MAPLIST*)NULL;
4269 		}
4270 	}
4271 	*psrc = src;
4272 	return (item);
4273 }
4274 
4275 /*
4276  *		Read user mapping file and split into their attribute.
4277  *	Parameters are kept as text in a chained list until logins
4278  *	are converted to uid.
4279  *	Returns the head of list, if any
4280  *
4281  *	If an absolute path is provided, the mapping file is assumed
4282  *	to be located in another mounted file system, and plain read()
4283  *	are used to get its contents.
4284  *	If a relative path is provided, the mapping file is assumed
4285  *	to be located on the current file system, and internal IO
4286  *	have to be used since we are still mounting and we have not
4287  *	entered the fuse loop yet.
4288  */
4289 
4290 struct MAPLIST *ntfs_read_mapping(FILEREADER reader, void *fileid)
4291 {
4292 	char buf[BUFSZ];
4293 	struct MAPLIST *item;
4294 	struct MAPLIST *firstitem;
4295 	struct MAPLIST *lastitem;
4296 	int src;
4297 	off_t offs;
4298 	s64 size;
4299 
4300 	firstitem = (struct MAPLIST*)NULL;
4301 	lastitem = (struct MAPLIST*)NULL;
4302 	offs = 0;
4303 	size = reader(fileid, buf, (size_t)BUFSZ, (off_t)0);
4304 	if (size > 0) {
4305 		src = 0;
4306 		do {
4307 			item = getmappingitem(reader, fileid, &offs,
4308 				buf, &src, &size);
4309 			if (item) {
4310 				item->next = (struct MAPLIST*)NULL;
4311 				if (lastitem)
4312 					lastitem->next = item;
4313 				else
4314 					firstitem = item;
4315 				lastitem = item;
4316 			}
4317 		} while (item);
4318 	}
4319 	return (firstitem);
4320 }
4321 
4322 /*
4323  *		Free memory used to store the user mapping
4324  *	The only purpose is to facilitate the detection of memory leaks
4325  */
4326 
4327 void ntfs_free_mapping(struct MAPPING *mapping[])
4328 {
4329 	struct MAPPING *user;
4330 	struct MAPPING *group;
4331 
4332 		/* free user mappings */
4333 	while (mapping[MAPUSERS]) {
4334 		user = mapping[MAPUSERS];
4335 		/* do not free SIDs used for group mappings */
4336 		group = mapping[MAPGROUPS];
4337 		while (group && (group->sid != user->sid))
4338 			group = group->next;
4339 		if (!group)
4340 			free(user->sid);
4341 			/* free group list if any */
4342 		if (user->grcnt)
4343 			free(user->groups);
4344 			/* unchain item and free */
4345 		mapping[MAPUSERS] = user->next;
4346 		free(user);
4347 	}
4348 		/* free group mappings */
4349 	while (mapping[MAPGROUPS]) {
4350 		group = mapping[MAPGROUPS];
4351 		free(group->sid);
4352 			/* unchain item and free */
4353 		mapping[MAPGROUPS] = group->next;
4354 		free(group);
4355 	}
4356 }
4357 
4358 
4359 /*
4360  *		Build the user mapping list
4361  *	user identification may be given in symbolic or numeric format
4362  *
4363  *	! Note ! : does getpwnam() read /etc/passwd or some other file ?
4364  *		if so there is a possible recursion into fuse if this
4365  *		file is on NTFS, and fuse is not recursion safe.
4366  */
4367 
4368 struct MAPPING *ntfs_do_user_mapping(struct MAPLIST *firstitem)
4369 {
4370 	struct MAPLIST *item;
4371 	struct MAPPING *firstmapping;
4372 	struct MAPPING *lastmapping;
4373 	struct MAPPING *mapping;
4374 	struct passwd *pwd;
4375 	SID *sid;
4376 	int uid;
4377 
4378 	firstmapping = (struct MAPPING*)NULL;
4379 	lastmapping = (struct MAPPING*)NULL;
4380 	for (item = firstitem; item; item = item->next) {
4381 		if ((item->uidstr[0] >= '0') && (item->uidstr[0] <= '9'))
4382 			uid = atoi(item->uidstr);
4383 		else {
4384 			uid = 0;
4385 			if (item->uidstr[0]) {
4386 				pwd = getpwnam(item->uidstr);
4387 				if (pwd)
4388 					uid = pwd->pw_uid;
4389 				else
4390 					ntfs_log_early_error("Invalid user \"%s\"\n",
4391 						item->uidstr);
4392 			}
4393 		}
4394 			/*
4395 			 * Records with no uid and no gid are inserted
4396 			 * to define the implicit mapping pattern
4397 			 */
4398 		if (uid
4399 		   || (!item->uidstr[0] && !item->gidstr[0])) {
4400 			sid = encodesid(item->sidstr);
4401 			if (sid && ntfs_known_group_sid(sid)) {
4402 				ntfs_log_error("Bad user SID %s\n",
4403 					item->sidstr);
4404 				free(sid);
4405 				sid = (SID*)NULL;
4406 			}
4407 			if (sid && !item->uidstr[0] && !item->gidstr[0]
4408 			    && !ntfs_valid_pattern(sid)) {
4409 				ntfs_log_error("Bad implicit SID pattern %s\n",
4410 					item->sidstr);
4411 				sid = (SID*)NULL;
4412 				}
4413 			if (sid) {
4414 				mapping =
4415 				    (struct MAPPING*)
4416 				    ntfs_malloc(sizeof(struct MAPPING));
4417 				if (mapping) {
4418 					mapping->sid = sid;
4419 					mapping->xid = uid;
4420 					mapping->grcnt = 0;
4421 					mapping->next = (struct MAPPING*)NULL;
4422 					if (lastmapping)
4423 						lastmapping->next = mapping;
4424 					else
4425 						firstmapping = mapping;
4426 					lastmapping = mapping;
4427 				}
4428 			}
4429 		}
4430 	}
4431 	return (firstmapping);
4432 }
4433 
4434 /*
4435  *		Build the group mapping list
4436  *	group identification may be given in symbolic or numeric format
4437  *
4438  *	gid not associated to a uid are processed first in order
4439  *	to favour real groups
4440  *
4441  *	! Note ! : does getgrnam() read /etc/group or some other file ?
4442  *		if so there is a possible recursion into fuse if this
4443  *		file is on NTFS, and fuse is not recursion safe.
4444  */
4445 
4446 struct MAPPING *ntfs_do_group_mapping(struct MAPLIST *firstitem)
4447 {
4448 	struct MAPLIST *item;
4449 	struct MAPPING *firstmapping;
4450 	struct MAPPING *lastmapping;
4451 	struct MAPPING *mapping;
4452 	struct group *grp;
4453 	BOOL secondstep;
4454 	BOOL ok;
4455 	int step;
4456 	SID *sid;
4457 	int gid;
4458 
4459 	firstmapping = (struct MAPPING*)NULL;
4460 	lastmapping = (struct MAPPING*)NULL;
4461 	for (step=1; step<=2; step++) {
4462 		for (item = firstitem; item; item = item->next) {
4463 			secondstep = (item->uidstr[0] != '\0')
4464 				|| !item->gidstr[0];
4465 			ok = (step == 1 ? !secondstep : secondstep);
4466 			if ((item->gidstr[0] >= '0')
4467 			     && (item->gidstr[0] <= '9'))
4468 				gid = atoi(item->gidstr);
4469 			else {
4470 				gid = 0;
4471 				if (item->gidstr[0]) {
4472 					grp = getgrnam(item->gidstr);
4473 					if (grp)
4474 						gid = grp->gr_gid;
4475 					else
4476 						ntfs_log_early_error("Invalid group \"%s\"\n",
4477 							item->gidstr);
4478 				}
4479 			}
4480 			/*
4481 			 * Records with no uid and no gid are inserted in the
4482 			 * second step to define the implicit mapping pattern
4483 			 */
4484 			if (ok
4485 			    && (gid
4486 				 || (!item->uidstr[0] && !item->gidstr[0]))) {
4487 				sid = encodesid(item->sidstr);
4488 				if (sid && !item->uidstr[0] && !item->gidstr[0]
4489 				    && !ntfs_valid_pattern(sid)) {
4490 					/* error already logged */
4491 					sid = (SID*)NULL;
4492 					}
4493 				if (sid) {
4494 					mapping = (struct MAPPING*)
4495 					    ntfs_malloc(sizeof(struct MAPPING));
4496 					if (mapping) {
4497 						mapping->sid = sid;
4498 						mapping->xid = gid;
4499 					/* special groups point to themselves */
4500 						if (ntfs_known_group_sid(sid)) {
4501 							mapping->groups =
4502 							  (gid_t*)&mapping->xid;
4503 							mapping->grcnt = 1;
4504 						} else
4505 							mapping->grcnt = 0;
4506 
4507 
4508 						mapping->next = (struct MAPPING*)NULL;
4509 						if (lastmapping)
4510 							lastmapping->next = mapping;
4511 						else
4512 							firstmapping = mapping;
4513 						lastmapping = mapping;
4514 					}
4515 				}
4516 			}
4517 		}
4518 	}
4519 	return (firstmapping);
4520 }
4521