1 /*
2  *   fs/cifs/cifsacl.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2007,2008
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   Contains the routines for mapping CIFS/NTFS ACLs
8  *
9  *   This library is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU Lesser General Public License as published
11  *   by the Free Software Foundation; either version 2.1 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This library is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  *   the GNU Lesser General Public License for more details.
18  *
19  *   You should have received a copy of the GNU Lesser General Public License
20  *   along with this library; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 #include <linux/fs.h>
25 #include <linux/slab.h>
26 #include "cifspdu.h"
27 #include "cifsglob.h"
28 #include "cifsacl.h"
29 #include "cifsproto.h"
30 #include "cifs_debug.h"
31 
32 
33 static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
34 	{{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
35 	{{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
36 	{{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"},
37 	{{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
38 	{{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(544), 0, 0, 0} }, "root"},
39 	{{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(545), 0, 0, 0} }, "users"},
40 	{{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(546), 0, 0, 0} }, "guest"} }
41 ;
42 
43 
44 /* security id for everyone/world system group */
45 static const struct cifs_sid sid_everyone = {
46 	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
47 /* security id for Authenticated Users system group */
48 static const struct cifs_sid sid_authusers = {
49 	1, 1, {0, 0, 0, 0, 0, 5}, {11} };
50 /* group users */
51 static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
52 
53 
match_sid(struct cifs_sid * ctsid)54 int match_sid(struct cifs_sid *ctsid)
55 {
56 	int i, j;
57 	int num_subauth, num_sat, num_saw;
58 	struct cifs_sid *cwsid;
59 
60 	if (!ctsid)
61 		return -1;
62 
63 	for (i = 0; i < NUM_WK_SIDS; ++i) {
64 		cwsid = &(wksidarr[i].cifssid);
65 
66 		/* compare the revision */
67 		if (ctsid->revision != cwsid->revision)
68 			continue;
69 
70 		/* compare all of the six auth values */
71 		for (j = 0; j < 6; ++j) {
72 			if (ctsid->authority[j] != cwsid->authority[j])
73 				break;
74 		}
75 		if (j < 6)
76 			continue; /* all of the auth values did not match */
77 
78 		/* compare all of the subauth values if any */
79 		num_sat = ctsid->num_subauth;
80 		num_saw = cwsid->num_subauth;
81 		num_subauth = num_sat < num_saw ? num_sat : num_saw;
82 		if (num_subauth) {
83 			for (j = 0; j < num_subauth; ++j) {
84 				if (ctsid->sub_auth[j] != cwsid->sub_auth[j])
85 					break;
86 			}
87 			if (j < num_subauth)
88 				continue; /* all sub_auth values do not match */
89 		}
90 
91 		cFYI(1, "matching sid: %s\n", wksidarr[i].sidname);
92 		return 0; /* sids compare/match */
93 	}
94 
95 	cFYI(1, "No matching sid");
96 	return -1;
97 }
98 
99 /* if the two SIDs (roughly equivalent to a UUID for a user or group) are
100    the same returns 1, if they do not match returns 0 */
compare_sids(const struct cifs_sid * ctsid,const struct cifs_sid * cwsid)101 int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
102 {
103 	int i;
104 	int num_subauth, num_sat, num_saw;
105 
106 	if ((!ctsid) || (!cwsid))
107 		return 0;
108 
109 	/* compare the revision */
110 	if (ctsid->revision != cwsid->revision)
111 		return 0;
112 
113 	/* compare all of the six auth values */
114 	for (i = 0; i < 6; ++i) {
115 		if (ctsid->authority[i] != cwsid->authority[i])
116 			return 0;
117 	}
118 
119 	/* compare all of the subauth values if any */
120 	num_sat = ctsid->num_subauth;
121 	num_saw = cwsid->num_subauth;
122 	num_subauth = num_sat < num_saw ? num_sat : num_saw;
123 	if (num_subauth) {
124 		for (i = 0; i < num_subauth; ++i) {
125 			if (ctsid->sub_auth[i] != cwsid->sub_auth[i])
126 				return 0;
127 		}
128 	}
129 
130 	return 1; /* sids compare/match */
131 }
132 
133 
134 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
copy_sec_desc(const struct cifs_ntsd * pntsd,struct cifs_ntsd * pnntsd,__u32 sidsoffset)135 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
136 				struct cifs_ntsd *pnntsd, __u32 sidsoffset)
137 {
138 	int i;
139 
140 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
141 	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
142 
143 	/* copy security descriptor control portion */
144 	pnntsd->revision = pntsd->revision;
145 	pnntsd->type = pntsd->type;
146 	pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
147 	pnntsd->sacloffset = 0;
148 	pnntsd->osidoffset = cpu_to_le32(sidsoffset);
149 	pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
150 
151 	/* copy owner sid */
152 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
153 				le32_to_cpu(pntsd->osidoffset));
154 	nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
155 
156 	nowner_sid_ptr->revision = owner_sid_ptr->revision;
157 	nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
158 	for (i = 0; i < 6; i++)
159 		nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
160 	for (i = 0; i < 5; i++)
161 		nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
162 
163 	/* copy group sid */
164 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
165 				le32_to_cpu(pntsd->gsidoffset));
166 	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
167 					sizeof(struct cifs_sid));
168 
169 	ngroup_sid_ptr->revision = group_sid_ptr->revision;
170 	ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
171 	for (i = 0; i < 6; i++)
172 		ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
173 	for (i = 0; i < 5; i++)
174 		ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
175 
176 	return;
177 }
178 
179 
180 /*
181    change posix mode to reflect permissions
182    pmode is the existing mode (we only want to overwrite part of this
183    bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
184 */
access_flags_to_mode(__le32 ace_flags,int type,umode_t * pmode,umode_t * pbits_to_set)185 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
186 				 umode_t *pbits_to_set)
187 {
188 	__u32 flags = le32_to_cpu(ace_flags);
189 	/* the order of ACEs is important.  The canonical order is to begin with
190 	   DENY entries followed by ALLOW, otherwise an allow entry could be
191 	   encountered first, making the subsequent deny entry like "dead code"
192 	   which would be superflous since Windows stops when a match is made
193 	   for the operation you are trying to perform for your user */
194 
195 	/* For deny ACEs we change the mask so that subsequent allow access
196 	   control entries do not turn on the bits we are denying */
197 	if (type == ACCESS_DENIED) {
198 		if (flags & GENERIC_ALL)
199 			*pbits_to_set &= ~S_IRWXUGO;
200 
201 		if ((flags & GENERIC_WRITE) ||
202 			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
203 			*pbits_to_set &= ~S_IWUGO;
204 		if ((flags & GENERIC_READ) ||
205 			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
206 			*pbits_to_set &= ~S_IRUGO;
207 		if ((flags & GENERIC_EXECUTE) ||
208 			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
209 			*pbits_to_set &= ~S_IXUGO;
210 		return;
211 	} else if (type != ACCESS_ALLOWED) {
212 		cERROR(1, "unknown access control type %d", type);
213 		return;
214 	}
215 	/* else ACCESS_ALLOWED type */
216 
217 	if (flags & GENERIC_ALL) {
218 		*pmode |= (S_IRWXUGO & (*pbits_to_set));
219 		cFYI(DBG2, "all perms");
220 		return;
221 	}
222 	if ((flags & GENERIC_WRITE) ||
223 			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
224 		*pmode |= (S_IWUGO & (*pbits_to_set));
225 	if ((flags & GENERIC_READ) ||
226 			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
227 		*pmode |= (S_IRUGO & (*pbits_to_set));
228 	if ((flags & GENERIC_EXECUTE) ||
229 			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
230 		*pmode |= (S_IXUGO & (*pbits_to_set));
231 
232 	cFYI(DBG2, "access flags 0x%x mode now 0x%x", flags, *pmode);
233 	return;
234 }
235 
236 /*
237    Generate access flags to reflect permissions mode is the existing mode.
238    This function is called for every ACE in the DACL whose SID matches
239    with either owner or group or everyone.
240 */
241 
mode_to_access_flags(umode_t mode,umode_t bits_to_use,__u32 * pace_flags)242 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
243 				__u32 *pace_flags)
244 {
245 	/* reset access mask */
246 	*pace_flags = 0x0;
247 
248 	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
249 	mode &= bits_to_use;
250 
251 	/* check for R/W/X UGO since we do not know whose flags
252 	   is this but we have cleared all the bits sans RWX for
253 	   either user or group or other as per bits_to_use */
254 	if (mode & S_IRUGO)
255 		*pace_flags |= SET_FILE_READ_RIGHTS;
256 	if (mode & S_IWUGO)
257 		*pace_flags |= SET_FILE_WRITE_RIGHTS;
258 	if (mode & S_IXUGO)
259 		*pace_flags |= SET_FILE_EXEC_RIGHTS;
260 
261 	cFYI(DBG2, "mode: 0x%x, access flags now 0x%x", mode, *pace_flags);
262 	return;
263 }
264 
fill_ace_for_sid(struct cifs_ace * pntace,const struct cifs_sid * psid,__u64 nmode,umode_t bits)265 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
266 			const struct cifs_sid *psid, __u64 nmode, umode_t bits)
267 {
268 	int i;
269 	__u16 size = 0;
270 	__u32 access_req = 0;
271 
272 	pntace->type = ACCESS_ALLOWED;
273 	pntace->flags = 0x0;
274 	mode_to_access_flags(nmode, bits, &access_req);
275 	if (!access_req)
276 		access_req = SET_MINIMUM_RIGHTS;
277 	pntace->access_req = cpu_to_le32(access_req);
278 
279 	pntace->sid.revision = psid->revision;
280 	pntace->sid.num_subauth = psid->num_subauth;
281 	for (i = 0; i < 6; i++)
282 		pntace->sid.authority[i] = psid->authority[i];
283 	for (i = 0; i < psid->num_subauth; i++)
284 		pntace->sid.sub_auth[i] = psid->sub_auth[i];
285 
286 	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
287 	pntace->size = cpu_to_le16(size);
288 
289 	return size;
290 }
291 
292 
293 #ifdef CONFIG_CIFS_DEBUG2
dump_ace(struct cifs_ace * pace,char * end_of_acl)294 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
295 {
296 	int num_subauth;
297 
298 	/* validate that we do not go past end of acl */
299 
300 	if (le16_to_cpu(pace->size) < 16) {
301 		cERROR(1, "ACE too small %d", le16_to_cpu(pace->size));
302 		return;
303 	}
304 
305 	if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
306 		cERROR(1, "ACL too small to parse ACE");
307 		return;
308 	}
309 
310 	num_subauth = pace->sid.num_subauth;
311 	if (num_subauth) {
312 		int i;
313 		cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
314 			pace->sid.revision, pace->sid.num_subauth, pace->type,
315 			pace->flags, le16_to_cpu(pace->size));
316 		for (i = 0; i < num_subauth; ++i) {
317 			cFYI(1, "ACE sub_auth[%d]: 0x%x", i,
318 				le32_to_cpu(pace->sid.sub_auth[i]));
319 		}
320 
321 		/* BB add length check to make sure that we do not have huge
322 			num auths and therefore go off the end */
323 	}
324 
325 	return;
326 }
327 #endif
328 
329 
parse_dacl(struct cifs_acl * pdacl,char * end_of_acl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,struct cifs_fattr * fattr)330 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
331 		       struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
332 		       struct cifs_fattr *fattr)
333 {
334 	int i;
335 	int num_aces = 0;
336 	int acl_size;
337 	char *acl_base;
338 	struct cifs_ace **ppace;
339 
340 	/* BB need to add parm so we can store the SID BB */
341 
342 	if (!pdacl) {
343 		/* no DACL in the security descriptor, set
344 		   all the permissions for user/group/other */
345 		fattr->cf_mode |= S_IRWXUGO;
346 		return;
347 	}
348 
349 	/* validate that we do not go past end of acl */
350 	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
351 		cERROR(1, "ACL too small to parse DACL");
352 		return;
353 	}
354 
355 	cFYI(DBG2, "DACL revision %d size %d num aces %d",
356 		le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
357 		le32_to_cpu(pdacl->num_aces));
358 
359 	/* reset rwx permissions for user/group/other.
360 	   Also, if num_aces is 0 i.e. DACL has no ACEs,
361 	   user/group/other have no permissions */
362 	fattr->cf_mode &= ~(S_IRWXUGO);
363 
364 	acl_base = (char *)pdacl;
365 	acl_size = sizeof(struct cifs_acl);
366 
367 	num_aces = le32_to_cpu(pdacl->num_aces);
368 	if (num_aces  > 0) {
369 		umode_t user_mask = S_IRWXU;
370 		umode_t group_mask = S_IRWXG;
371 		umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
372 
373 		ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
374 				GFP_KERNEL);
375 		if (!ppace) {
376 			cERROR(1, "DACL memory allocation error");
377 			return;
378 		}
379 
380 		for (i = 0; i < num_aces; ++i) {
381 			ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
382 #ifdef CONFIG_CIFS_DEBUG2
383 			dump_ace(ppace[i], end_of_acl);
384 #endif
385 			if (compare_sids(&(ppace[i]->sid), pownersid))
386 				access_flags_to_mode(ppace[i]->access_req,
387 						     ppace[i]->type,
388 						     &fattr->cf_mode,
389 						     &user_mask);
390 			if (compare_sids(&(ppace[i]->sid), pgrpsid))
391 				access_flags_to_mode(ppace[i]->access_req,
392 						     ppace[i]->type,
393 						     &fattr->cf_mode,
394 						     &group_mask);
395 			if (compare_sids(&(ppace[i]->sid), &sid_everyone))
396 				access_flags_to_mode(ppace[i]->access_req,
397 						     ppace[i]->type,
398 						     &fattr->cf_mode,
399 						     &other_mask);
400 			if (compare_sids(&(ppace[i]->sid), &sid_authusers))
401 				access_flags_to_mode(ppace[i]->access_req,
402 						     ppace[i]->type,
403 						     &fattr->cf_mode,
404 						     &other_mask);
405 
406 
407 /*			memcpy((void *)(&(cifscred->aces[i])),
408 				(void *)ppace[i],
409 				sizeof(struct cifs_ace)); */
410 
411 			acl_base = (char *)ppace[i];
412 			acl_size = le16_to_cpu(ppace[i]->size);
413 		}
414 
415 		kfree(ppace);
416 	}
417 
418 	return;
419 }
420 
421 
set_chmod_dacl(struct cifs_acl * pndacl,struct cifs_sid * pownersid,struct cifs_sid * pgrpsid,__u64 nmode)422 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
423 			struct cifs_sid *pgrpsid, __u64 nmode)
424 {
425 	u16 size = 0;
426 	struct cifs_acl *pnndacl;
427 
428 	pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
429 
430 	size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
431 					pownersid, nmode, S_IRWXU);
432 	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
433 					pgrpsid, nmode, S_IRWXG);
434 	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
435 					 &sid_everyone, nmode, S_IRWXO);
436 
437 	pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
438 	pndacl->num_aces = cpu_to_le32(3);
439 
440 	return 0;
441 }
442 
443 
parse_sid(struct cifs_sid * psid,char * end_of_acl)444 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
445 {
446 	/* BB need to add parm so we can store the SID BB */
447 
448 	/* validate that we do not go past end of ACL - sid must be at least 8
449 	   bytes long (assuming no sub-auths - e.g. the null SID */
450 	if (end_of_acl < (char *)psid + 8) {
451 		cERROR(1, "ACL too small to parse SID %p", psid);
452 		return -EINVAL;
453 	}
454 
455 	if (psid->num_subauth) {
456 #ifdef CONFIG_CIFS_DEBUG2
457 		int i;
458 		cFYI(1, "SID revision %d num_auth %d",
459 			psid->revision, psid->num_subauth);
460 
461 		for (i = 0; i < psid->num_subauth; i++) {
462 			cFYI(1, "SID sub_auth[%d]: 0x%x ", i,
463 				le32_to_cpu(psid->sub_auth[i]));
464 		}
465 
466 		/* BB add length check to make sure that we do not have huge
467 			num auths and therefore go off the end */
468 		cFYI(1, "RID 0x%x",
469 			le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
470 #endif
471 	}
472 
473 	return 0;
474 }
475 
476 
477 /* Convert CIFS ACL to POSIX form */
parse_sec_desc(struct cifs_ntsd * pntsd,int acl_len,struct cifs_fattr * fattr)478 static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
479 			  struct cifs_fattr *fattr)
480 {
481 	int rc;
482 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
483 	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
484 	char *end_of_acl = ((char *)pntsd) + acl_len;
485 	__u32 dacloffset;
486 
487 	if (pntsd == NULL)
488 		return -EIO;
489 
490 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
491 				le32_to_cpu(pntsd->osidoffset));
492 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
493 				le32_to_cpu(pntsd->gsidoffset));
494 	dacloffset = le32_to_cpu(pntsd->dacloffset);
495 	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
496 	cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
497 		 "sacloffset 0x%x dacloffset 0x%x",
498 		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
499 		 le32_to_cpu(pntsd->gsidoffset),
500 		 le32_to_cpu(pntsd->sacloffset), dacloffset);
501 /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
502 	rc = parse_sid(owner_sid_ptr, end_of_acl);
503 	if (rc)
504 		return rc;
505 
506 	rc = parse_sid(group_sid_ptr, end_of_acl);
507 	if (rc)
508 		return rc;
509 
510 	if (dacloffset)
511 		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
512 			   group_sid_ptr, fattr);
513 	else
514 		cFYI(1, "no ACL"); /* BB grant all or default perms? */
515 
516 /*	cifscred->uid = owner_sid_ptr->rid;
517 	cifscred->gid = group_sid_ptr->rid;
518 	memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
519 			sizeof(struct cifs_sid));
520 	memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
521 			sizeof(struct cifs_sid)); */
522 
523 	return 0;
524 }
525 
526 
527 /* Convert permission bits from mode to equivalent CIFS ACL */
build_sec_desc(struct cifs_ntsd * pntsd,struct cifs_ntsd * pnntsd,struct inode * inode,__u64 nmode)528 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
529 				struct inode *inode, __u64 nmode)
530 {
531 	int rc = 0;
532 	__u32 dacloffset;
533 	__u32 ndacloffset;
534 	__u32 sidsoffset;
535 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
536 	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
537 	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
538 
539 	if ((inode == NULL) || (pntsd == NULL) || (pnntsd == NULL))
540 		return -EIO;
541 
542 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
543 				le32_to_cpu(pntsd->osidoffset));
544 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
545 				le32_to_cpu(pntsd->gsidoffset));
546 
547 	dacloffset = le32_to_cpu(pntsd->dacloffset);
548 	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
549 
550 	ndacloffset = sizeof(struct cifs_ntsd);
551 	ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
552 	ndacl_ptr->revision = dacl_ptr->revision;
553 	ndacl_ptr->size = 0;
554 	ndacl_ptr->num_aces = 0;
555 
556 	rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, nmode);
557 
558 	sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
559 
560 	/* copy security descriptor control portion and owner and group sid */
561 	copy_sec_desc(pntsd, pnntsd, sidsoffset);
562 
563 	return rc;
564 }
565 
get_cifs_acl_by_fid(struct cifs_sb_info * cifs_sb,__u16 fid,u32 * pacllen)566 static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
567 		__u16 fid, u32 *pacllen)
568 {
569 	struct cifs_ntsd *pntsd = NULL;
570 	int xid, rc;
571 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
572 
573 	if (IS_ERR(tlink))
574 		return ERR_CAST(tlink);
575 
576 	xid = GetXid();
577 	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
578 	FreeXid(xid);
579 
580 	cifs_put_tlink(tlink);
581 
582 	cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
583 	if (rc)
584 		return ERR_PTR(rc);
585 	return pntsd;
586 }
587 
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen)588 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
589 		const char *path, u32 *pacllen)
590 {
591 	struct cifs_ntsd *pntsd = NULL;
592 	int oplock = 0;
593 	int xid, rc;
594 	__u16 fid;
595 	struct cifsTconInfo *tcon;
596 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
597 
598 	if (IS_ERR(tlink))
599 		return ERR_CAST(tlink);
600 
601 	tcon = tlink_tcon(tlink);
602 	xid = GetXid();
603 
604 	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
605 			 &fid, &oplock, NULL, cifs_sb->local_nls,
606 			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
607 	if (!rc) {
608 		rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
609 		CIFSSMBClose(xid, tcon, fid);
610 	}
611 
612 	cifs_put_tlink(tlink);
613 	FreeXid(xid);
614 
615 	cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
616 	if (rc)
617 		return ERR_PTR(rc);
618 	return pntsd;
619 }
620 
621 /* Retrieve an ACL from the server */
get_cifs_acl(struct cifs_sb_info * cifs_sb,struct inode * inode,const char * path,u32 * pacllen)622 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
623 				      struct inode *inode, const char *path,
624 				      u32 *pacllen)
625 {
626 	struct cifs_ntsd *pntsd = NULL;
627 	struct cifsFileInfo *open_file = NULL;
628 
629 	if (inode)
630 		open_file = find_readable_file(CIFS_I(inode), true);
631 	if (!open_file)
632 		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
633 
634 	pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen);
635 	cifsFileInfo_put(open_file);
636 	return pntsd;
637 }
638 
set_cifs_acl_by_fid(struct cifs_sb_info * cifs_sb,__u16 fid,struct cifs_ntsd * pnntsd,u32 acllen)639 static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid,
640 		struct cifs_ntsd *pnntsd, u32 acllen)
641 {
642 	int xid, rc;
643 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
644 
645 	if (IS_ERR(tlink))
646 		return PTR_ERR(tlink);
647 
648 	xid = GetXid();
649 	rc = CIFSSMBSetCIFSACL(xid, tlink_tcon(tlink), fid, pnntsd, acllen);
650 	FreeXid(xid);
651 	cifs_put_tlink(tlink);
652 
653 	cFYI(DBG2, "SetCIFSACL rc = %d", rc);
654 	return rc;
655 }
656 
set_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,struct cifs_ntsd * pnntsd,u32 acllen)657 static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
658 		struct cifs_ntsd *pnntsd, u32 acllen)
659 {
660 	int oplock = 0;
661 	int xid, rc;
662 	__u16 fid;
663 	struct cifsTconInfo *tcon;
664 	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
665 
666 	if (IS_ERR(tlink))
667 		return PTR_ERR(tlink);
668 
669 	tcon = tlink_tcon(tlink);
670 	xid = GetXid();
671 
672 	rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0,
673 			 &fid, &oplock, NULL, cifs_sb->local_nls,
674 			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
675 	if (rc) {
676 		cERROR(1, "Unable to open file to set ACL");
677 		goto out;
678 	}
679 
680 	rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen);
681 	cFYI(DBG2, "SetCIFSACL rc = %d", rc);
682 
683 	CIFSSMBClose(xid, tcon, fid);
684 out:
685 	FreeXid(xid);
686 	cifs_put_tlink(tlink);
687 	return rc;
688 }
689 
690 /* Set an ACL on the server */
set_cifs_acl(struct cifs_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path)691 static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
692 				struct inode *inode, const char *path)
693 {
694 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
695 	struct cifsFileInfo *open_file;
696 	int rc;
697 
698 	cFYI(DBG2, "set ACL for %s from mode 0x%x", path, inode->i_mode);
699 
700 	open_file = find_readable_file(CIFS_I(inode), true);
701 	if (!open_file)
702 		return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen);
703 
704 	rc = set_cifs_acl_by_fid(cifs_sb, open_file->netfid, pnntsd, acllen);
705 	cifsFileInfo_put(open_file);
706 	return rc;
707 }
708 
709 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
710 int
cifs_acl_to_fattr(struct cifs_sb_info * cifs_sb,struct cifs_fattr * fattr,struct inode * inode,const char * path,const __u16 * pfid)711 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
712 		  struct inode *inode, const char *path, const __u16 *pfid)
713 {
714 	struct cifs_ntsd *pntsd = NULL;
715 	u32 acllen = 0;
716 	int rc = 0;
717 
718 	cFYI(DBG2, "converting ACL to mode for %s", path);
719 
720 	if (pfid)
721 		pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
722 	else
723 		pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
724 
725 	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
726 	if (IS_ERR(pntsd)) {
727 		rc = PTR_ERR(pntsd);
728 		cERROR(1, "%s: error %d getting sec desc", __func__, rc);
729 	} else {
730 		rc = parse_sec_desc(pntsd, acllen, fattr);
731 		kfree(pntsd);
732 		if (rc)
733 			cERROR(1, "parse sec desc failed rc = %d", rc);
734 	}
735 
736 	return rc;
737 }
738 
739 /* Convert mode bits to an ACL so we can update the ACL on the server */
mode_to_cifs_acl(struct inode * inode,const char * path,__u64 nmode)740 int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode)
741 {
742 	int rc = 0;
743 	__u32 secdesclen = 0;
744 	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
745 	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
746 
747 	cFYI(DBG2, "set ACL from mode for %s", path);
748 
749 	/* Get the security descriptor */
750 	pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
751 
752 	/* Add three ACEs for owner, group, everyone getting rid of
753 	   other ACEs as chmod disables ACEs and set the security descriptor */
754 
755 	if (IS_ERR(pntsd)) {
756 		rc = PTR_ERR(pntsd);
757 		cERROR(1, "%s: error %d getting sec desc", __func__, rc);
758 	} else {
759 		/* allocate memory for the smb header,
760 		   set security descriptor request security descriptor
761 		   parameters, and secuirty descriptor itself */
762 
763 		secdesclen = secdesclen < DEFSECDESCLEN ?
764 					DEFSECDESCLEN : secdesclen;
765 		pnntsd = kmalloc(secdesclen, GFP_KERNEL);
766 		if (!pnntsd) {
767 			cERROR(1, "Unable to allocate security descriptor");
768 			kfree(pntsd);
769 			return -ENOMEM;
770 		}
771 
772 		rc = build_sec_desc(pntsd, pnntsd, inode, nmode);
773 
774 		cFYI(DBG2, "build_sec_desc rc: %d", rc);
775 
776 		if (!rc) {
777 			/* Set the security descriptor */
778 			rc = set_cifs_acl(pnntsd, secdesclen, inode, path);
779 			cFYI(DBG2, "set_cifs_acl rc: %d", rc);
780 		}
781 
782 		kfree(pnntsd);
783 		kfree(pntsd);
784 	}
785 
786 	return rc;
787 }
788