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