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