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