xref: /openbmc/linux/fs/smb/client/cifsacl.c (revision 060f35a317ef09101b128f399dce7ed13d019461)
1  // SPDX-License-Identifier: LGPL-2.1
2  /*
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   */
10  
11  #include <linux/fs.h>
12  #include <linux/slab.h>
13  #include <linux/string.h>
14  #include <linux/keyctl.h>
15  #include <linux/key-type.h>
16  #include <uapi/linux/posix_acl.h>
17  #include <linux/posix_acl.h>
18  #include <linux/posix_acl_xattr.h>
19  #include <keys/user-type.h>
20  #include "cifspdu.h"
21  #include "cifsglob.h"
22  #include "cifsacl.h"
23  #include "cifsproto.h"
24  #include "cifs_debug.h"
25  #include "fs_context.h"
26  #include "cifs_fs_sb.h"
27  #include "cifs_unicode.h"
28  
29  /* security id for everyone/world system group */
30  static const struct smb_sid sid_everyone = {
31  	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
32  /* security id for Authenticated Users system group */
33  static const struct smb_sid sid_authusers = {
34  	1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
35  
36  /* S-1-22-1 Unmapped Unix users */
37  static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
38  		{cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
39  
40  /* S-1-22-2 Unmapped Unix groups */
41  static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
42  		{cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
43  
44  /*
45   * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
46   */
47  
48  /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
49  
50  /* S-1-5-88-1 Unix uid */
51  static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
52  	{cpu_to_le32(88),
53  	 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
54  
55  /* S-1-5-88-2 Unix gid */
56  static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
57  	{cpu_to_le32(88),
58  	 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
59  
60  /* S-1-5-88-3 Unix mode */
61  static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
62  	{cpu_to_le32(88),
63  	 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
64  
65  static const struct cred *root_cred;
66  
67  static int
cifs_idmap_key_instantiate(struct key * key,struct key_preparsed_payload * prep)68  cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
69  {
70  	char *payload;
71  
72  	/*
73  	 * If the payload is less than or equal to the size of a pointer, then
74  	 * an allocation here is wasteful. Just copy the data directly to the
75  	 * payload.value union member instead.
76  	 *
77  	 * With this however, you must check the datalen before trying to
78  	 * dereference payload.data!
79  	 */
80  	if (prep->datalen <= sizeof(key->payload)) {
81  		key->payload.data[0] = NULL;
82  		memcpy(&key->payload, prep->data, prep->datalen);
83  	} else {
84  		payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
85  		if (!payload)
86  			return -ENOMEM;
87  		key->payload.data[0] = payload;
88  	}
89  
90  	key->datalen = prep->datalen;
91  	return 0;
92  }
93  
94  static inline void
cifs_idmap_key_destroy(struct key * key)95  cifs_idmap_key_destroy(struct key *key)
96  {
97  	if (key->datalen > sizeof(key->payload))
98  		kfree(key->payload.data[0]);
99  }
100  
101  static struct key_type cifs_idmap_key_type = {
102  	.name        = "cifs.idmap",
103  	.instantiate = cifs_idmap_key_instantiate,
104  	.destroy     = cifs_idmap_key_destroy,
105  	.describe    = user_describe,
106  };
107  
108  static char *
sid_to_key_str(struct smb_sid * sidptr,unsigned int type)109  sid_to_key_str(struct smb_sid *sidptr, unsigned int type)
110  {
111  	int i, len;
112  	unsigned int saval;
113  	char *sidstr, *strptr;
114  	unsigned long long id_auth_val;
115  
116  	/* 3 bytes for prefix */
117  	sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
118  			 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
119  			 GFP_KERNEL);
120  	if (!sidstr)
121  		return sidstr;
122  
123  	strptr = sidstr;
124  	len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
125  			sidptr->revision);
126  	strptr += len;
127  
128  	/* The authority field is a single 48-bit number */
129  	id_auth_val = (unsigned long long)sidptr->authority[5];
130  	id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
131  	id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
132  	id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
133  	id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
134  	id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
135  
136  	/*
137  	 * MS-DTYP states that if the authority is >= 2^32, then it should be
138  	 * expressed as a hex value.
139  	 */
140  	if (id_auth_val <= UINT_MAX)
141  		len = sprintf(strptr, "-%llu", id_auth_val);
142  	else
143  		len = sprintf(strptr, "-0x%llx", id_auth_val);
144  
145  	strptr += len;
146  
147  	for (i = 0; i < sidptr->num_subauth; ++i) {
148  		saval = le32_to_cpu(sidptr->sub_auth[i]);
149  		len = sprintf(strptr, "-%u", saval);
150  		strptr += len;
151  	}
152  
153  	return sidstr;
154  }
155  
156  /*
157   * if the two SIDs (roughly equivalent to a UUID for a user or group) are
158   * the same returns zero, if they do not match returns non-zero.
159   */
160  static int
compare_sids(const struct smb_sid * ctsid,const struct smb_sid * cwsid)161  compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
162  {
163  	int i;
164  	int num_subauth, num_sat, num_saw;
165  
166  	if ((!ctsid) || (!cwsid))
167  		return 1;
168  
169  	/* compare the revision */
170  	if (ctsid->revision != cwsid->revision) {
171  		if (ctsid->revision > cwsid->revision)
172  			return 1;
173  		else
174  			return -1;
175  	}
176  
177  	/* compare all of the six auth values */
178  	for (i = 0; i < NUM_AUTHS; ++i) {
179  		if (ctsid->authority[i] != cwsid->authority[i]) {
180  			if (ctsid->authority[i] > cwsid->authority[i])
181  				return 1;
182  			else
183  				return -1;
184  		}
185  	}
186  
187  	/* compare all of the subauth values if any */
188  	num_sat = ctsid->num_subauth;
189  	num_saw = cwsid->num_subauth;
190  	num_subauth = num_sat < num_saw ? num_sat : num_saw;
191  	if (num_subauth) {
192  		for (i = 0; i < num_subauth; ++i) {
193  			if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
194  				if (le32_to_cpu(ctsid->sub_auth[i]) >
195  					le32_to_cpu(cwsid->sub_auth[i]))
196  					return 1;
197  				else
198  					return -1;
199  			}
200  		}
201  	}
202  
203  	return 0; /* sids compare/match */
204  }
205  
206  static bool
is_well_known_sid(const struct smb_sid * psid,uint32_t * puid,bool is_group)207  is_well_known_sid(const struct smb_sid *psid, uint32_t *puid, bool is_group)
208  {
209  	int i;
210  	int num_subauth;
211  	const struct smb_sid *pwell_known_sid;
212  
213  	if (!psid || (puid == NULL))
214  		return false;
215  
216  	num_subauth = psid->num_subauth;
217  
218  	/* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
219  	if (num_subauth == 2) {
220  		if (is_group)
221  			pwell_known_sid = &sid_unix_groups;
222  		else
223  			pwell_known_sid = &sid_unix_users;
224  	} else if (num_subauth == 3) {
225  		if (is_group)
226  			pwell_known_sid = &sid_unix_NFS_groups;
227  		else
228  			pwell_known_sid = &sid_unix_NFS_users;
229  	} else
230  		return false;
231  
232  	/* compare the revision */
233  	if (psid->revision != pwell_known_sid->revision)
234  		return false;
235  
236  	/* compare all of the six auth values */
237  	for (i = 0; i < NUM_AUTHS; ++i) {
238  		if (psid->authority[i] != pwell_known_sid->authority[i]) {
239  			cifs_dbg(FYI, "auth %d did not match\n", i);
240  			return false;
241  		}
242  	}
243  
244  	if (num_subauth == 2) {
245  		if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
246  			return false;
247  
248  		*puid = le32_to_cpu(psid->sub_auth[1]);
249  	} else /* 3 subauths, ie Windows/Mac style */ {
250  		*puid = le32_to_cpu(psid->sub_auth[0]);
251  		if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
252  		    (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
253  			return false;
254  
255  		*puid = le32_to_cpu(psid->sub_auth[2]);
256  	}
257  
258  	cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
259  	return true; /* well known sid found, uid returned */
260  }
261  
262  static __u16
cifs_copy_sid(struct smb_sid * dst,const struct smb_sid * src)263  cifs_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
264  {
265  	int i;
266  	__u16 size = 1 + 1 + 6;
267  
268  	dst->revision = src->revision;
269  	dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
270  	for (i = 0; i < NUM_AUTHS; ++i)
271  		dst->authority[i] = src->authority[i];
272  	for (i = 0; i < dst->num_subauth; ++i)
273  		dst->sub_auth[i] = src->sub_auth[i];
274  	size += (dst->num_subauth * 4);
275  
276  	return size;
277  }
278  
279  static int
id_to_sid(unsigned int cid,uint sidtype,struct smb_sid * ssid)280  id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
281  {
282  	int rc;
283  	struct key *sidkey;
284  	struct smb_sid *ksid;
285  	unsigned int ksid_size;
286  	char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
287  	const struct cred *saved_cred;
288  
289  	rc = snprintf(desc, sizeof(desc), "%ci:%u",
290  			sidtype == SIDOWNER ? 'o' : 'g', cid);
291  	if (rc >= sizeof(desc))
292  		return -EINVAL;
293  
294  	rc = 0;
295  	saved_cred = override_creds(root_cred);
296  	sidkey = request_key(&cifs_idmap_key_type, desc, "");
297  	if (IS_ERR(sidkey)) {
298  		rc = -EINVAL;
299  		cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
300  			 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
301  		goto out_revert_creds;
302  	} else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
303  		rc = -EIO;
304  		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
305  			 __func__, sidkey->datalen);
306  		goto invalidate_key;
307  	}
308  
309  	/*
310  	 * A sid is usually too large to be embedded in payload.value, but if
311  	 * there are no subauthorities and the host has 8-byte pointers, then
312  	 * it could be.
313  	 */
314  	ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
315  		(struct smb_sid *)&sidkey->payload :
316  		(struct smb_sid *)sidkey->payload.data[0];
317  
318  	ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
319  	if (ksid_size > sidkey->datalen) {
320  		rc = -EIO;
321  		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
322  			 __func__, sidkey->datalen, ksid_size);
323  		goto invalidate_key;
324  	}
325  
326  	cifs_copy_sid(ssid, ksid);
327  out_key_put:
328  	key_put(sidkey);
329  out_revert_creds:
330  	revert_creds(saved_cred);
331  	return rc;
332  
333  invalidate_key:
334  	key_invalidate(sidkey);
335  	goto out_key_put;
336  }
337  
338  int
sid_to_id(struct cifs_sb_info * cifs_sb,struct smb_sid * psid,struct cifs_fattr * fattr,uint sidtype)339  sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
340  		struct cifs_fattr *fattr, uint sidtype)
341  {
342  	int rc = 0;
343  	struct key *sidkey;
344  	char *sidstr;
345  	const struct cred *saved_cred;
346  	kuid_t fuid = cifs_sb->ctx->linux_uid;
347  	kgid_t fgid = cifs_sb->ctx->linux_gid;
348  
349  	/*
350  	 * If we have too many subauthorities, then something is really wrong.
351  	 * Just return an error.
352  	 */
353  	if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
354  		cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
355  			 __func__, psid->num_subauth);
356  		return -EIO;
357  	}
358  
359  	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
360  	    (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
361  		uint32_t unix_id;
362  		bool is_group;
363  
364  		if (sidtype != SIDOWNER)
365  			is_group = true;
366  		else
367  			is_group = false;
368  
369  		if (is_well_known_sid(psid, &unix_id, is_group) == false)
370  			goto try_upcall_to_get_id;
371  
372  		if (is_group) {
373  			kgid_t gid;
374  			gid_t id;
375  
376  			id = (gid_t)unix_id;
377  			gid = make_kgid(&init_user_ns, id);
378  			if (gid_valid(gid)) {
379  				fgid = gid;
380  				goto got_valid_id;
381  			}
382  		} else {
383  			kuid_t uid;
384  			uid_t id;
385  
386  			id = (uid_t)unix_id;
387  			uid = make_kuid(&init_user_ns, id);
388  			if (uid_valid(uid)) {
389  				fuid = uid;
390  				goto got_valid_id;
391  			}
392  		}
393  		/* If unable to find uid/gid easily from SID try via upcall */
394  	}
395  
396  try_upcall_to_get_id:
397  	sidstr = sid_to_key_str(psid, sidtype);
398  	if (!sidstr)
399  		return -ENOMEM;
400  
401  	saved_cred = override_creds(root_cred);
402  	sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
403  	if (IS_ERR(sidkey)) {
404  		cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
405  			 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
406  		goto out_revert_creds;
407  	}
408  
409  	/*
410  	 * FIXME: Here we assume that uid_t and gid_t are same size. It's
411  	 * probably a safe assumption but might be better to check based on
412  	 * sidtype.
413  	 */
414  	BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
415  	if (sidkey->datalen != sizeof(uid_t)) {
416  		cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
417  			 __func__, sidkey->datalen);
418  		key_invalidate(sidkey);
419  		goto out_key_put;
420  	}
421  
422  	if (sidtype == SIDOWNER) {
423  		kuid_t uid;
424  		uid_t id;
425  		memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
426  		uid = make_kuid(&init_user_ns, id);
427  		if (uid_valid(uid))
428  			fuid = uid;
429  	} else {
430  		kgid_t gid;
431  		gid_t id;
432  		memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
433  		gid = make_kgid(&init_user_ns, id);
434  		if (gid_valid(gid))
435  			fgid = gid;
436  	}
437  
438  out_key_put:
439  	key_put(sidkey);
440  out_revert_creds:
441  	revert_creds(saved_cred);
442  	kfree(sidstr);
443  
444  	/*
445  	 * Note that we return 0 here unconditionally. If the mapping
446  	 * fails then we just fall back to using the ctx->linux_uid/linux_gid.
447  	 */
448  got_valid_id:
449  	rc = 0;
450  	if (sidtype == SIDOWNER)
451  		fattr->cf_uid = fuid;
452  	else
453  		fattr->cf_gid = fgid;
454  	return rc;
455  }
456  
457  int
init_cifs_idmap(void)458  init_cifs_idmap(void)
459  {
460  	struct cred *cred;
461  	struct key *keyring;
462  	int ret;
463  
464  	cifs_dbg(FYI, "Registering the %s key type\n",
465  		 cifs_idmap_key_type.name);
466  
467  	/* create an override credential set with a special thread keyring in
468  	 * which requests are cached
469  	 *
470  	 * this is used to prevent malicious redirections from being installed
471  	 * with add_key().
472  	 */
473  	cred = prepare_kernel_cred(&init_task);
474  	if (!cred)
475  		return -ENOMEM;
476  
477  	keyring = keyring_alloc(".cifs_idmap",
478  				GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
479  				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
480  				KEY_USR_VIEW | KEY_USR_READ,
481  				KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
482  	if (IS_ERR(keyring)) {
483  		ret = PTR_ERR(keyring);
484  		goto failed_put_cred;
485  	}
486  
487  	ret = register_key_type(&cifs_idmap_key_type);
488  	if (ret < 0)
489  		goto failed_put_key;
490  
491  	/* instruct request_key() to use this special keyring as a cache for
492  	 * the results it looks up */
493  	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
494  	cred->thread_keyring = keyring;
495  	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
496  	root_cred = cred;
497  
498  	cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
499  	return 0;
500  
501  failed_put_key:
502  	key_put(keyring);
503  failed_put_cred:
504  	put_cred(cred);
505  	return ret;
506  }
507  
508  void
exit_cifs_idmap(void)509  exit_cifs_idmap(void)
510  {
511  	key_revoke(root_cred->thread_keyring);
512  	unregister_key_type(&cifs_idmap_key_type);
513  	put_cred(root_cred);
514  	cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
515  }
516  
517  /* copy ntsd, owner sid, and group sid from a security descriptor to another */
copy_sec_desc(const struct smb_ntsd * pntsd,struct smb_ntsd * pnntsd,__u32 sidsoffset,struct smb_sid * pownersid,struct smb_sid * pgrpsid)518  static __u32 copy_sec_desc(const struct smb_ntsd *pntsd,
519  				struct smb_ntsd *pnntsd,
520  				__u32 sidsoffset,
521  				struct smb_sid *pownersid,
522  				struct smb_sid *pgrpsid)
523  {
524  	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
525  	struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
526  
527  	/* copy security descriptor control portion */
528  	pnntsd->revision = pntsd->revision;
529  	pnntsd->type = pntsd->type;
530  	pnntsd->dacloffset = cpu_to_le32(sizeof(struct smb_ntsd));
531  	pnntsd->sacloffset = 0;
532  	pnntsd->osidoffset = cpu_to_le32(sidsoffset);
533  	pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct smb_sid));
534  
535  	/* copy owner sid */
536  	if (pownersid)
537  		owner_sid_ptr = pownersid;
538  	else
539  		owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
540  				le32_to_cpu(pntsd->osidoffset));
541  	nowner_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset);
542  	cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
543  
544  	/* copy group sid */
545  	if (pgrpsid)
546  		group_sid_ptr = pgrpsid;
547  	else
548  		group_sid_ptr = (struct smb_sid *)((char *)pntsd +
549  				le32_to_cpu(pntsd->gsidoffset));
550  	ngroup_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset +
551  					sizeof(struct smb_sid));
552  	cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
553  
554  	return sidsoffset + (2 * sizeof(struct smb_sid));
555  }
556  
557  
558  /*
559     change posix mode to reflect permissions
560     pmode is the existing mode (we only want to overwrite part of this
561     bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
562  */
access_flags_to_mode(__le32 ace_flags,int type,umode_t * pmode,umode_t * pdenied,umode_t mask)563  static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
564  				 umode_t *pdenied, umode_t mask)
565  {
566  	__u32 flags = le32_to_cpu(ace_flags);
567  	/*
568  	 * Do not assume "preferred" or "canonical" order.
569  	 * The first DENY or ALLOW ACE which matches perfectly is
570  	 * the permission to be used. Once allowed or denied, same
571  	 * permission in later ACEs do not matter.
572  	 */
573  
574  	/* If not already allowed, deny these bits */
575  	if (type == ACCESS_DENIED) {
576  		if (flags & GENERIC_ALL &&
577  				!(*pmode & mask & 0777))
578  			*pdenied |= mask & 0777;
579  
580  		if (((flags & GENERIC_WRITE) ||
581  				((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
582  				!(*pmode & mask & 0222))
583  			*pdenied |= mask & 0222;
584  
585  		if (((flags & GENERIC_READ) ||
586  				((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
587  				!(*pmode & mask & 0444))
588  			*pdenied |= mask & 0444;
589  
590  		if (((flags & GENERIC_EXECUTE) ||
591  				((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
592  				!(*pmode & mask & 0111))
593  			*pdenied |= mask & 0111;
594  
595  		return;
596  	} else if (type != ACCESS_ALLOWED) {
597  		cifs_dbg(VFS, "unknown access control type %d\n", type);
598  		return;
599  	}
600  	/* else ACCESS_ALLOWED type */
601  
602  	if ((flags & GENERIC_ALL) &&
603  			!(*pdenied & mask & 0777)) {
604  		*pmode |= mask & 0777;
605  		cifs_dbg(NOISY, "all perms\n");
606  		return;
607  	}
608  
609  	if (((flags & GENERIC_WRITE) ||
610  			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
611  			!(*pdenied & mask & 0222))
612  		*pmode |= mask & 0222;
613  
614  	if (((flags & GENERIC_READ) ||
615  			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
616  			!(*pdenied & mask & 0444))
617  		*pmode |= mask & 0444;
618  
619  	if (((flags & GENERIC_EXECUTE) ||
620  			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
621  			!(*pdenied & mask & 0111))
622  		*pmode |= mask & 0111;
623  
624  	/* If DELETE_CHILD is set only on an owner ACE, set sticky bit */
625  	if (flags & FILE_DELETE_CHILD) {
626  		if (mask == ACL_OWNER_MASK) {
627  			if (!(*pdenied & 01000))
628  				*pmode |= 01000;
629  		} else if (!(*pdenied & 01000)) {
630  			*pmode &= ~01000;
631  			*pdenied |= 01000;
632  		}
633  	}
634  
635  	cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
636  	return;
637  }
638  
639  /*
640     Generate access flags to reflect permissions mode is the existing mode.
641     This function is called for every ACE in the DACL whose SID matches
642     with either owner or group or everyone.
643  */
644  
mode_to_access_flags(umode_t mode,umode_t bits_to_use,__u32 * pace_flags)645  static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
646  				__u32 *pace_flags)
647  {
648  	/* reset access mask */
649  	*pace_flags = 0x0;
650  
651  	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
652  	mode &= bits_to_use;
653  
654  	/* check for R/W/X UGO since we do not know whose flags
655  	   is this but we have cleared all the bits sans RWX for
656  	   either user or group or other as per bits_to_use */
657  	if (mode & S_IRUGO)
658  		*pace_flags |= SET_FILE_READ_RIGHTS;
659  	if (mode & S_IWUGO)
660  		*pace_flags |= SET_FILE_WRITE_RIGHTS;
661  	if (mode & S_IXUGO)
662  		*pace_flags |= SET_FILE_EXEC_RIGHTS;
663  
664  	cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
665  		 mode, *pace_flags);
666  	return;
667  }
668  
cifs_copy_ace(struct smb_ace * dst,struct smb_ace * src,struct smb_sid * psid)669  static __u16 cifs_copy_ace(struct smb_ace *dst, struct smb_ace *src, struct smb_sid *psid)
670  {
671  	__u16 size = 1 + 1 + 2 + 4;
672  
673  	dst->type = src->type;
674  	dst->flags = src->flags;
675  	dst->access_req = src->access_req;
676  
677  	/* Check if there's a replacement sid specified */
678  	if (psid)
679  		size += cifs_copy_sid(&dst->sid, psid);
680  	else
681  		size += cifs_copy_sid(&dst->sid, &src->sid);
682  
683  	dst->size = cpu_to_le16(size);
684  
685  	return size;
686  }
687  
fill_ace_for_sid(struct smb_ace * pntace,const struct smb_sid * psid,__u64 nmode,umode_t bits,__u8 access_type,bool allow_delete_child)688  static __u16 fill_ace_for_sid(struct smb_ace *pntace,
689  			const struct smb_sid *psid, __u64 nmode,
690  			umode_t bits, __u8 access_type,
691  			bool allow_delete_child)
692  {
693  	int i;
694  	__u16 size = 0;
695  	__u32 access_req = 0;
696  
697  	pntace->type = access_type;
698  	pntace->flags = 0x0;
699  	mode_to_access_flags(nmode, bits, &access_req);
700  
701  	if (access_type == ACCESS_ALLOWED && allow_delete_child)
702  		access_req |= FILE_DELETE_CHILD;
703  
704  	if (access_type == ACCESS_ALLOWED && !access_req)
705  		access_req = SET_MINIMUM_RIGHTS;
706  	else if (access_type == ACCESS_DENIED)
707  		access_req &= ~SET_MINIMUM_RIGHTS;
708  
709  	pntace->access_req = cpu_to_le32(access_req);
710  
711  	pntace->sid.revision = psid->revision;
712  	pntace->sid.num_subauth = psid->num_subauth;
713  	for (i = 0; i < NUM_AUTHS; i++)
714  		pntace->sid.authority[i] = psid->authority[i];
715  	for (i = 0; i < psid->num_subauth; i++)
716  		pntace->sid.sub_auth[i] = psid->sub_auth[i];
717  
718  	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
719  	pntace->size = cpu_to_le16(size);
720  
721  	return size;
722  }
723  
724  
725  #ifdef CONFIG_CIFS_DEBUG2
dump_ace(struct smb_ace * pace,char * end_of_acl)726  static void dump_ace(struct smb_ace *pace, char *end_of_acl)
727  {
728  	int num_subauth;
729  
730  	/* validate that we do not go past end of acl */
731  
732  	if (le16_to_cpu(pace->size) < 16) {
733  		cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
734  		return;
735  	}
736  
737  	if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
738  		cifs_dbg(VFS, "ACL too small to parse ACE\n");
739  		return;
740  	}
741  
742  	num_subauth = pace->sid.num_subauth;
743  	if (num_subauth) {
744  		int i;
745  		cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
746  			 pace->sid.revision, pace->sid.num_subauth, pace->type,
747  			 pace->flags, le16_to_cpu(pace->size));
748  		for (i = 0; i < num_subauth; ++i) {
749  			cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
750  				 i, le32_to_cpu(pace->sid.sub_auth[i]));
751  		}
752  
753  		/* BB add length check to make sure that we do not have huge
754  			num auths and therefore go off the end */
755  	}
756  
757  	return;
758  }
759  #endif
760  
parse_dacl(struct smb_acl * pdacl,char * end_of_acl,struct smb_sid * pownersid,struct smb_sid * pgrpsid,struct cifs_fattr * fattr,bool mode_from_special_sid)761  static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
762  		       struct smb_sid *pownersid, struct smb_sid *pgrpsid,
763  		       struct cifs_fattr *fattr, bool mode_from_special_sid)
764  {
765  	int i;
766  	int num_aces = 0;
767  	int acl_size;
768  	char *acl_base;
769  	struct smb_ace **ppace;
770  
771  	/* BB need to add parm so we can store the SID BB */
772  
773  	if (!pdacl) {
774  		/* no DACL in the security descriptor, set
775  		   all the permissions for user/group/other */
776  		fattr->cf_mode |= 0777;
777  		return;
778  	}
779  
780  	/* validate that we do not go past end of acl */
781  	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
782  		cifs_dbg(VFS, "ACL too small to parse DACL\n");
783  		return;
784  	}
785  
786  	cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
787  		 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
788  		 le32_to_cpu(pdacl->num_aces));
789  
790  	/* reset rwx permissions for user/group/other.
791  	   Also, if num_aces is 0 i.e. DACL has no ACEs,
792  	   user/group/other have no permissions */
793  	fattr->cf_mode &= ~(0777);
794  
795  	acl_base = (char *)pdacl;
796  	acl_size = sizeof(struct smb_acl);
797  
798  	num_aces = le32_to_cpu(pdacl->num_aces);
799  	if (num_aces > 0) {
800  		umode_t denied_mode = 0;
801  
802  		if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
803  			return;
804  		ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *),
805  				      GFP_KERNEL);
806  		if (!ppace)
807  			return;
808  
809  		for (i = 0; i < num_aces; ++i) {
810  			ppace[i] = (struct smb_ace *) (acl_base + acl_size);
811  #ifdef CONFIG_CIFS_DEBUG2
812  			dump_ace(ppace[i], end_of_acl);
813  #endif
814  			if (mode_from_special_sid &&
815  			    (compare_sids(&(ppace[i]->sid),
816  					  &sid_unix_NFS_mode) == 0)) {
817  				/*
818  				 * Full permissions are:
819  				 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
820  				 *         S_IRWXU | S_IRWXG | S_IRWXO
821  				 */
822  				fattr->cf_mode &= ~07777;
823  				fattr->cf_mode |=
824  					le32_to_cpu(ppace[i]->sid.sub_auth[2]);
825  				break;
826  			} else {
827  				if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
828  					access_flags_to_mode(ppace[i]->access_req,
829  							ppace[i]->type,
830  							&fattr->cf_mode,
831  							&denied_mode,
832  							ACL_OWNER_MASK);
833  				} else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
834  					access_flags_to_mode(ppace[i]->access_req,
835  							ppace[i]->type,
836  							&fattr->cf_mode,
837  							&denied_mode,
838  							ACL_GROUP_MASK);
839  				} else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
840  						(compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
841  					access_flags_to_mode(ppace[i]->access_req,
842  							ppace[i]->type,
843  							&fattr->cf_mode,
844  							&denied_mode,
845  							ACL_EVERYONE_MASK);
846  				}
847  			}
848  
849  
850  /*			memcpy((void *)(&(cifscred->aces[i])),
851  				(void *)ppace[i],
852  				sizeof(struct smb_ace)); */
853  
854  			acl_base = (char *)ppace[i];
855  			acl_size = le16_to_cpu(ppace[i]->size);
856  		}
857  
858  		kfree(ppace);
859  	}
860  
861  	return;
862  }
863  
setup_authusers_ACE(struct smb_ace * pntace)864  unsigned int setup_authusers_ACE(struct smb_ace *pntace)
865  {
866  	int i;
867  	unsigned int ace_size = 20;
868  
869  	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
870  	pntace->flags = 0x0;
871  	pntace->access_req = cpu_to_le32(GENERIC_ALL);
872  	pntace->sid.num_subauth = 1;
873  	pntace->sid.revision = 1;
874  	for (i = 0; i < NUM_AUTHS; i++)
875  		pntace->sid.authority[i] =  sid_authusers.authority[i];
876  
877  	pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
878  
879  	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
880  	pntace->size = cpu_to_le16(ace_size);
881  	return ace_size;
882  }
883  
884  /*
885   * Fill in the special SID based on the mode. See
886   * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
887   */
setup_special_mode_ACE(struct smb_ace * pntace,bool posix,__u64 nmode)888  unsigned int setup_special_mode_ACE(struct smb_ace *pntace,
889  				    bool posix,
890  				    __u64 nmode)
891  {
892  	int i;
893  	unsigned int ace_size = 28;
894  
895  	if (posix)
896  		pntace->type = ACCESS_ALLOWED_ACE_TYPE;
897  	else
898  		pntace->type = ACCESS_DENIED_ACE_TYPE;
899  	pntace->flags = 0x0;
900  	pntace->access_req = 0;
901  	pntace->sid.num_subauth = 3;
902  	pntace->sid.revision = 1;
903  	for (i = 0; i < NUM_AUTHS; i++)
904  		pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
905  
906  	pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
907  	pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
908  	pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
909  
910  	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
911  	pntace->size = cpu_to_le16(ace_size);
912  	return ace_size;
913  }
914  
setup_special_user_owner_ACE(struct smb_ace * pntace)915  unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace)
916  {
917  	int i;
918  	unsigned int ace_size = 28;
919  
920  	pntace->type = ACCESS_ALLOWED_ACE_TYPE;
921  	pntace->flags = 0x0;
922  	pntace->access_req = cpu_to_le32(GENERIC_ALL);
923  	pntace->sid.num_subauth = 3;
924  	pntace->sid.revision = 1;
925  	for (i = 0; i < NUM_AUTHS; i++)
926  		pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
927  
928  	pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
929  	pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
930  	pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
931  
932  	/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
933  	pntace->size = cpu_to_le16(ace_size);
934  	return ace_size;
935  }
936  
populate_new_aces(char * nacl_base,struct smb_sid * pownersid,struct smb_sid * pgrpsid,__u64 * pnmode,u32 * pnum_aces,u16 * pnsize,bool modefromsid,bool posix)937  static void populate_new_aces(char *nacl_base,
938  		struct smb_sid *pownersid,
939  		struct smb_sid *pgrpsid,
940  		__u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
941  		bool modefromsid,
942  		bool posix)
943  {
944  	__u64 nmode;
945  	u32 num_aces = 0;
946  	u16 nsize = 0;
947  	__u64 user_mode;
948  	__u64 group_mode;
949  	__u64 other_mode;
950  	__u64 deny_user_mode = 0;
951  	__u64 deny_group_mode = 0;
952  	bool sticky_set = false;
953  	struct smb_ace *pnntace = NULL;
954  
955  	nmode = *pnmode;
956  	num_aces = *pnum_aces;
957  	nsize = *pnsize;
958  
959  	if (modefromsid || posix) {
960  		pnntace = (struct smb_ace *) (nacl_base + nsize);
961  		nsize += setup_special_mode_ACE(pnntace, posix, nmode);
962  		num_aces++;
963  		if (modefromsid) {
964  			pnntace = (struct smb_ace *) (nacl_base + nsize);
965  			nsize += setup_authusers_ACE(pnntace);
966  			num_aces++;
967  		}
968  		goto set_size;
969  	}
970  
971  	/*
972  	 * We'll try to keep the mode as requested by the user.
973  	 * But in cases where we cannot meaningfully convert that
974  	 * into ACL, return back the updated mode, so that it is
975  	 * updated in the inode.
976  	 */
977  
978  	if (!memcmp(pownersid, pgrpsid, sizeof(struct smb_sid))) {
979  		/*
980  		 * Case when owner and group SIDs are the same.
981  		 * Set the more restrictive of the two modes.
982  		 */
983  		user_mode = nmode & (nmode << 3) & 0700;
984  		group_mode = nmode & (nmode >> 3) & 0070;
985  	} else {
986  		user_mode = nmode & 0700;
987  		group_mode = nmode & 0070;
988  	}
989  
990  	other_mode = nmode & 0007;
991  
992  	/* We need DENY ACE when the perm is more restrictive than the next sets. */
993  	deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
994  	deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
995  
996  	*pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
997  
998  	/* This tells if we should allow delete child for group and everyone. */
999  	if (nmode & 01000)
1000  		sticky_set = true;
1001  
1002  	if (deny_user_mode) {
1003  		pnntace = (struct smb_ace *) (nacl_base + nsize);
1004  		nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
1005  				0700, ACCESS_DENIED, false);
1006  		num_aces++;
1007  	}
1008  
1009  	/* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
1010  	if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
1011  		pnntace = (struct smb_ace *) (nacl_base + nsize);
1012  		nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1013  				0070, ACCESS_DENIED, false);
1014  		num_aces++;
1015  	}
1016  
1017  	pnntace = (struct smb_ace *) (nacl_base + nsize);
1018  	nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1019  			0700, ACCESS_ALLOWED, true);
1020  	num_aces++;
1021  
1022  	/* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
1023  	if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1024  		pnntace = (struct smb_ace *) (nacl_base + nsize);
1025  		nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1026  				0070, ACCESS_DENIED, false);
1027  		num_aces++;
1028  	}
1029  
1030  	pnntace = (struct smb_ace *) (nacl_base + nsize);
1031  	nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1032  			0070, ACCESS_ALLOWED, !sticky_set);
1033  	num_aces++;
1034  
1035  	pnntace = (struct smb_ace *) (nacl_base + nsize);
1036  	nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1037  			0007, ACCESS_ALLOWED, !sticky_set);
1038  	num_aces++;
1039  
1040  set_size:
1041  	*pnum_aces = num_aces;
1042  	*pnsize = nsize;
1043  }
1044  
replace_sids_and_copy_aces(struct smb_acl * pdacl,struct smb_acl * pndacl,struct smb_sid * pownersid,struct smb_sid * pgrpsid,struct smb_sid * pnownersid,struct smb_sid * pngrpsid)1045  static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
1046  		struct smb_sid *pownersid, struct smb_sid *pgrpsid,
1047  		struct smb_sid *pnownersid, struct smb_sid *pngrpsid)
1048  {
1049  	int i;
1050  	u16 size = 0;
1051  	struct smb_ace *pntace = NULL;
1052  	char *acl_base = NULL;
1053  	u32 src_num_aces = 0;
1054  	u16 nsize = 0;
1055  	struct smb_ace *pnntace = NULL;
1056  	char *nacl_base = NULL;
1057  	u16 ace_size = 0;
1058  
1059  	acl_base = (char *)pdacl;
1060  	size = sizeof(struct smb_acl);
1061  	src_num_aces = le32_to_cpu(pdacl->num_aces);
1062  
1063  	nacl_base = (char *)pndacl;
1064  	nsize = sizeof(struct smb_acl);
1065  
1066  	/* Go through all the ACEs */
1067  	for (i = 0; i < src_num_aces; ++i) {
1068  		pntace = (struct smb_ace *) (acl_base + size);
1069  		pnntace = (struct smb_ace *) (nacl_base + nsize);
1070  
1071  		if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
1072  			ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1073  		else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
1074  			ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1075  		else
1076  			ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1077  
1078  		size += le16_to_cpu(pntace->size);
1079  		nsize += ace_size;
1080  	}
1081  
1082  	return nsize;
1083  }
1084  
set_chmod_dacl(struct smb_acl * pdacl,struct smb_acl * pndacl,struct smb_sid * pownersid,struct smb_sid * pgrpsid,__u64 * pnmode,bool mode_from_sid,bool posix)1085  static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
1086  		struct smb_sid *pownersid,	struct smb_sid *pgrpsid,
1087  		__u64 *pnmode, bool mode_from_sid, bool posix)
1088  {
1089  	int i;
1090  	u16 size = 0;
1091  	struct smb_ace *pntace = NULL;
1092  	char *acl_base = NULL;
1093  	u32 src_num_aces = 0;
1094  	u16 nsize = 0;
1095  	struct smb_ace *pnntace = NULL;
1096  	char *nacl_base = NULL;
1097  	u32 num_aces = 0;
1098  	bool new_aces_set = false;
1099  
1100  	/* Assuming that pndacl and pnmode are never NULL */
1101  	nacl_base = (char *)pndacl;
1102  	nsize = sizeof(struct smb_acl);
1103  
1104  	/* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1105  	if (!pdacl || posix) {
1106  		populate_new_aces(nacl_base,
1107  				pownersid, pgrpsid,
1108  				pnmode, &num_aces, &nsize,
1109  				mode_from_sid, posix);
1110  		goto finalize_dacl;
1111  	}
1112  
1113  	acl_base = (char *)pdacl;
1114  	size = sizeof(struct smb_acl);
1115  	src_num_aces = le32_to_cpu(pdacl->num_aces);
1116  
1117  	/* Retain old ACEs which we can retain */
1118  	for (i = 0; i < src_num_aces; ++i) {
1119  		pntace = (struct smb_ace *) (acl_base + size);
1120  
1121  		if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1122  			/* Place the new ACEs in between existing explicit and inherited */
1123  			populate_new_aces(nacl_base,
1124  					pownersid, pgrpsid,
1125  					pnmode, &num_aces, &nsize,
1126  					mode_from_sid, posix);
1127  
1128  			new_aces_set = true;
1129  		}
1130  
1131  		/* If it's any one of the ACE we're replacing, skip! */
1132  		if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1133  				(compare_sids(&pntace->sid, pownersid) == 0) ||
1134  				(compare_sids(&pntace->sid, pgrpsid) == 0) ||
1135  				(compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1136  				(compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1137  			goto next_ace;
1138  		}
1139  
1140  		/* update the pointer to the next ACE to populate*/
1141  		pnntace = (struct smb_ace *) (nacl_base + nsize);
1142  
1143  		nsize += cifs_copy_ace(pnntace, pntace, NULL);
1144  		num_aces++;
1145  
1146  next_ace:
1147  		size += le16_to_cpu(pntace->size);
1148  	}
1149  
1150  	/* If inherited ACEs are not present, place the new ones at the tail */
1151  	if (!new_aces_set) {
1152  		populate_new_aces(nacl_base,
1153  				pownersid, pgrpsid,
1154  				pnmode, &num_aces, &nsize,
1155  				mode_from_sid, posix);
1156  
1157  		new_aces_set = true;
1158  	}
1159  
1160  finalize_dacl:
1161  	pndacl->num_aces = cpu_to_le32(num_aces);
1162  	pndacl->size = cpu_to_le16(nsize);
1163  
1164  	return 0;
1165  }
1166  
parse_sid(struct smb_sid * psid,char * end_of_acl)1167  static int parse_sid(struct smb_sid *psid, char *end_of_acl)
1168  {
1169  	/* BB need to add parm so we can store the SID BB */
1170  
1171  	/* validate that we do not go past end of ACL - sid must be at least 8
1172  	   bytes long (assuming no sub-auths - e.g. the null SID */
1173  	if (end_of_acl < (char *)psid + 8) {
1174  		cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
1175  		return -EINVAL;
1176  	}
1177  
1178  #ifdef CONFIG_CIFS_DEBUG2
1179  	if (psid->num_subauth) {
1180  		int i;
1181  		cifs_dbg(FYI, "SID revision %d num_auth %d\n",
1182  			 psid->revision, psid->num_subauth);
1183  
1184  		for (i = 0; i < psid->num_subauth; i++) {
1185  			cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
1186  				 i, le32_to_cpu(psid->sub_auth[i]));
1187  		}
1188  
1189  		/* BB add length check to make sure that we do not have huge
1190  			num auths and therefore go off the end */
1191  		cifs_dbg(FYI, "RID 0x%x\n",
1192  			 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1193  	}
1194  #endif
1195  
1196  	return 0;
1197  }
1198  
1199  
1200  /* Convert CIFS ACL to POSIX form */
parse_sec_desc(struct cifs_sb_info * cifs_sb,struct smb_ntsd * pntsd,int acl_len,struct cifs_fattr * fattr,bool get_mode_from_special_sid)1201  static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1202  		struct smb_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1203  		bool get_mode_from_special_sid)
1204  {
1205  	int rc = 0;
1206  	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1207  	struct smb_acl *dacl_ptr; /* no need for SACL ptr */
1208  	char *end_of_acl = ((char *)pntsd) + acl_len;
1209  	__u32 dacloffset;
1210  
1211  	if (pntsd == NULL)
1212  		return -EIO;
1213  
1214  	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
1215  				le32_to_cpu(pntsd->osidoffset));
1216  	group_sid_ptr = (struct smb_sid *)((char *)pntsd +
1217  				le32_to_cpu(pntsd->gsidoffset));
1218  	dacloffset = le32_to_cpu(pntsd->dacloffset);
1219  	dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1220  	cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1221  		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1222  		 le32_to_cpu(pntsd->gsidoffset),
1223  		 le32_to_cpu(pntsd->sacloffset), dacloffset);
1224  /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1225  	rc = parse_sid(owner_sid_ptr, end_of_acl);
1226  	if (rc) {
1227  		cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1228  		return rc;
1229  	}
1230  	rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1231  	if (rc) {
1232  		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1233  			 __func__, rc);
1234  		return rc;
1235  	}
1236  
1237  	rc = parse_sid(group_sid_ptr, end_of_acl);
1238  	if (rc) {
1239  		cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1240  			 __func__, rc);
1241  		return rc;
1242  	}
1243  	rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1244  	if (rc) {
1245  		cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1246  			 __func__, rc);
1247  		return rc;
1248  	}
1249  
1250  	if (dacloffset)
1251  		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1252  			   group_sid_ptr, fattr, get_mode_from_special_sid);
1253  	else
1254  		cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1255  
1256  	return rc;
1257  }
1258  
1259  /* Convert permission bits from mode to equivalent CIFS ACL */
build_sec_desc(struct smb_ntsd * pntsd,struct smb_ntsd * pnntsd,__u32 secdesclen,__u32 * pnsecdesclen,__u64 * pnmode,kuid_t uid,kgid_t gid,bool mode_from_sid,bool id_from_sid,bool posix,int * aclflag)1260  static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
1261  	__u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1262  	bool mode_from_sid, bool id_from_sid, bool posix, int *aclflag)
1263  {
1264  	int rc = 0;
1265  	__u32 dacloffset;
1266  	__u32 ndacloffset;
1267  	__u32 sidsoffset;
1268  	struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1269  	struct smb_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1270  	struct smb_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
1271  	struct smb_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1272  	char *end_of_acl = ((char *)pntsd) + secdesclen;
1273  	u16 size = 0;
1274  
1275  	dacloffset = le32_to_cpu(pntsd->dacloffset);
1276  	if (dacloffset) {
1277  		dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1278  		if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
1279  			cifs_dbg(VFS, "Server returned illegal ACL size\n");
1280  			return -EINVAL;
1281  		}
1282  	}
1283  
1284  	owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
1285  			le32_to_cpu(pntsd->osidoffset));
1286  	group_sid_ptr = (struct smb_sid *)((char *)pntsd +
1287  			le32_to_cpu(pntsd->gsidoffset));
1288  
1289  	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1290  		ndacloffset = sizeof(struct smb_ntsd);
1291  		ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
1292  		ndacl_ptr->revision =
1293  			dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1294  
1295  		ndacl_ptr->size = cpu_to_le16(0);
1296  		ndacl_ptr->num_aces = cpu_to_le32(0);
1297  
1298  		rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1299  				    pnmode, mode_from_sid, posix);
1300  
1301  		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1302  		/* copy the non-dacl portion of secdesc */
1303  		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1304  				NULL, NULL);
1305  
1306  		*aclflag |= CIFS_ACL_DACL;
1307  	} else {
1308  		ndacloffset = sizeof(struct smb_ntsd);
1309  		ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
1310  		ndacl_ptr->revision =
1311  			dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1312  		ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
1313  
1314  		if (uid_valid(uid)) { /* chown */
1315  			uid_t id;
1316  			nowner_sid_ptr = kzalloc(sizeof(struct smb_sid),
1317  								GFP_KERNEL);
1318  			if (!nowner_sid_ptr) {
1319  				rc = -ENOMEM;
1320  				goto chown_chgrp_exit;
1321  			}
1322  			id = from_kuid(&init_user_ns, uid);
1323  			if (id_from_sid) {
1324  				struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1325  				/* Populate the user ownership fields S-1-5-88-1 */
1326  				osid->Revision = 1;
1327  				osid->NumAuth = 3;
1328  				osid->Authority[5] = 5;
1329  				osid->SubAuthorities[0] = cpu_to_le32(88);
1330  				osid->SubAuthorities[1] = cpu_to_le32(1);
1331  				osid->SubAuthorities[2] = cpu_to_le32(id);
1332  
1333  			} else { /* lookup sid with upcall */
1334  				rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1335  				if (rc) {
1336  					cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1337  						 __func__, rc, id);
1338  					goto chown_chgrp_exit;
1339  				}
1340  			}
1341  			*aclflag |= CIFS_ACL_OWNER;
1342  		}
1343  		if (gid_valid(gid)) { /* chgrp */
1344  			gid_t id;
1345  			ngroup_sid_ptr = kzalloc(sizeof(struct smb_sid),
1346  								GFP_KERNEL);
1347  			if (!ngroup_sid_ptr) {
1348  				rc = -ENOMEM;
1349  				goto chown_chgrp_exit;
1350  			}
1351  			id = from_kgid(&init_user_ns, gid);
1352  			if (id_from_sid) {
1353  				struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1354  				/* Populate the group ownership fields S-1-5-88-2 */
1355  				gsid->Revision = 1;
1356  				gsid->NumAuth = 3;
1357  				gsid->Authority[5] = 5;
1358  				gsid->SubAuthorities[0] = cpu_to_le32(88);
1359  				gsid->SubAuthorities[1] = cpu_to_le32(2);
1360  				gsid->SubAuthorities[2] = cpu_to_le32(id);
1361  
1362  			} else { /* lookup sid with upcall */
1363  				rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1364  				if (rc) {
1365  					cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1366  						 __func__, rc, id);
1367  					goto chown_chgrp_exit;
1368  				}
1369  			}
1370  			*aclflag |= CIFS_ACL_GROUP;
1371  		}
1372  
1373  		if (dacloffset) {
1374  			/* Replace ACEs for old owner with new one */
1375  			size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1376  					owner_sid_ptr, group_sid_ptr,
1377  					nowner_sid_ptr, ngroup_sid_ptr);
1378  			ndacl_ptr->size = cpu_to_le16(size);
1379  		}
1380  
1381  		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1382  		/* copy the non-dacl portion of secdesc */
1383  		*pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1384  				nowner_sid_ptr, ngroup_sid_ptr);
1385  
1386  chown_chgrp_exit:
1387  		/* errors could jump here. So make sure we return soon after this */
1388  		kfree(nowner_sid_ptr);
1389  		kfree(ngroup_sid_ptr);
1390  	}
1391  
1392  	return rc;
1393  }
1394  
1395  #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
get_cifs_acl_by_fid(struct cifs_sb_info * cifs_sb,const struct cifs_fid * cifsfid,u32 * pacllen,u32 info)1396  struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1397  				      const struct cifs_fid *cifsfid, u32 *pacllen,
1398  				      u32 info)
1399  {
1400  	struct smb_ntsd *pntsd = NULL;
1401  	unsigned int xid;
1402  	int rc;
1403  	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1404  
1405  	if (IS_ERR(tlink))
1406  		return ERR_CAST(tlink);
1407  
1408  	xid = get_xid();
1409  	rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1410  				pacllen, info);
1411  	free_xid(xid);
1412  
1413  	cifs_put_tlink(tlink);
1414  
1415  	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1416  	if (rc)
1417  		return ERR_PTR(rc);
1418  	return pntsd;
1419  }
1420  
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen,u32 info)1421  static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1422  		const char *path, u32 *pacllen, u32 info)
1423  {
1424  	struct smb_ntsd *pntsd = NULL;
1425  	int oplock = 0;
1426  	unsigned int xid;
1427  	int rc;
1428  	struct cifs_tcon *tcon;
1429  	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1430  	struct cifs_fid fid;
1431  	struct cifs_open_parms oparms;
1432  
1433  	if (IS_ERR(tlink))
1434  		return ERR_CAST(tlink);
1435  
1436  	tcon = tlink_tcon(tlink);
1437  	xid = get_xid();
1438  
1439  	oparms = (struct cifs_open_parms) {
1440  		.tcon = tcon,
1441  		.cifs_sb = cifs_sb,
1442  		.desired_access = READ_CONTROL,
1443  		.create_options = cifs_create_options(cifs_sb, 0),
1444  		.disposition = FILE_OPEN,
1445  		.path = path,
1446  		.fid = &fid,
1447  	};
1448  
1449  	if (info & SACL_SECINFO)
1450  		oparms.desired_access |= SYSTEM_SECURITY;
1451  
1452  	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1453  	if (!rc) {
1454  		rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen, info);
1455  		CIFSSMBClose(xid, tcon, fid.netfid);
1456  	}
1457  
1458  	cifs_put_tlink(tlink);
1459  	free_xid(xid);
1460  
1461  	cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1462  	if (rc)
1463  		return ERR_PTR(rc);
1464  	return pntsd;
1465  }
1466  
1467  /* Retrieve an ACL from the server */
get_cifs_acl(struct cifs_sb_info * cifs_sb,struct inode * inode,const char * path,u32 * pacllen,u32 info)1468  struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1469  				      struct inode *inode, const char *path,
1470  			       u32 *pacllen, u32 info)
1471  {
1472  	struct smb_ntsd *pntsd = NULL;
1473  	struct cifsFileInfo *open_file = NULL;
1474  
1475  	if (inode)
1476  		open_file = find_readable_file(CIFS_I(inode), true);
1477  	if (!open_file)
1478  		return get_cifs_acl_by_path(cifs_sb, path, pacllen, info);
1479  
1480  	pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1481  	cifsFileInfo_put(open_file);
1482  	return pntsd;
1483  }
1484  
1485   /* Set an ACL on the server */
set_cifs_acl(struct smb_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path,int aclflag)1486  int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
1487  			struct inode *inode, const char *path, int aclflag)
1488  {
1489  	int oplock = 0;
1490  	unsigned int xid;
1491  	int rc, access_flags = 0;
1492  	struct cifs_tcon *tcon;
1493  	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1494  	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1495  	struct cifs_fid fid;
1496  	struct cifs_open_parms oparms;
1497  
1498  	if (IS_ERR(tlink))
1499  		return PTR_ERR(tlink);
1500  
1501  	tcon = tlink_tcon(tlink);
1502  	xid = get_xid();
1503  
1504  	if (aclflag & CIFS_ACL_OWNER || aclflag & CIFS_ACL_GROUP)
1505  		access_flags |= WRITE_OWNER;
1506  	if (aclflag & CIFS_ACL_SACL)
1507  		access_flags |= SYSTEM_SECURITY;
1508  	if (aclflag & CIFS_ACL_DACL)
1509  		access_flags |= WRITE_DAC;
1510  
1511  	oparms = (struct cifs_open_parms) {
1512  		.tcon = tcon,
1513  		.cifs_sb = cifs_sb,
1514  		.desired_access = access_flags,
1515  		.create_options = cifs_create_options(cifs_sb, 0),
1516  		.disposition = FILE_OPEN,
1517  		.path = path,
1518  		.fid = &fid,
1519  	};
1520  
1521  	rc = CIFS_open(xid, &oparms, &oplock, NULL);
1522  	if (rc) {
1523  		cifs_dbg(VFS, "Unable to open file to set ACL\n");
1524  		goto out;
1525  	}
1526  
1527  	rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1528  	cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1529  
1530  	CIFSSMBClose(xid, tcon, fid.netfid);
1531  out:
1532  	free_xid(xid);
1533  	cifs_put_tlink(tlink);
1534  	return rc;
1535  }
1536  #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1537  
1538  /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1539  int
cifs_acl_to_fattr(struct cifs_sb_info * cifs_sb,struct cifs_fattr * fattr,struct inode * inode,bool mode_from_special_sid,const char * path,const struct cifs_fid * pfid)1540  cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1541  		  struct inode *inode, bool mode_from_special_sid,
1542  		  const char *path, const struct cifs_fid *pfid)
1543  {
1544  	struct smb_ntsd *pntsd = NULL;
1545  	u32 acllen = 0;
1546  	int rc = 0;
1547  	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1548  	struct smb_version_operations *ops;
1549  	const u32 info = 0;
1550  
1551  	cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1552  
1553  	if (IS_ERR(tlink))
1554  		return PTR_ERR(tlink);
1555  
1556  	ops = tlink_tcon(tlink)->ses->server->ops;
1557  
1558  	if (pfid && (ops->get_acl_by_fid))
1559  		pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1560  	else if (ops->get_acl)
1561  		pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1562  	else {
1563  		cifs_put_tlink(tlink);
1564  		return -EOPNOTSUPP;
1565  	}
1566  	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1567  	if (IS_ERR(pntsd)) {
1568  		rc = PTR_ERR(pntsd);
1569  		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1570  	} else if (mode_from_special_sid) {
1571  		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1572  		kfree(pntsd);
1573  	} else {
1574  		/* get approximated mode from ACL */
1575  		rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1576  		kfree(pntsd);
1577  		if (rc)
1578  			cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1579  	}
1580  
1581  	cifs_put_tlink(tlink);
1582  
1583  	return rc;
1584  }
1585  
1586  /* Convert mode bits to an ACL so we can update the ACL on the server */
1587  int
id_mode_to_cifs_acl(struct inode * inode,const char * path,__u64 * pnmode,kuid_t uid,kgid_t gid)1588  id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1589  			kuid_t uid, kgid_t gid)
1590  {
1591  	int rc = 0;
1592  	int aclflag = CIFS_ACL_DACL; /* default flag to set */
1593  	__u32 secdesclen = 0;
1594  	__u32 nsecdesclen = 0;
1595  	__u32 dacloffset = 0;
1596  	struct smb_acl *dacl_ptr = NULL;
1597  	struct smb_ntsd *pntsd = NULL; /* acl obtained from server */
1598  	struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1599  	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1600  	struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1601  	struct smb_version_operations *ops;
1602  	bool mode_from_sid, id_from_sid;
1603  	bool posix = tlink_tcon(tlink)->posix_extensions;
1604  	const u32 info = 0;
1605  
1606  	if (IS_ERR(tlink))
1607  		return PTR_ERR(tlink);
1608  
1609  	ops = tlink_tcon(tlink)->ses->server->ops;
1610  
1611  	cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1612  
1613  	/* Get the security descriptor */
1614  
1615  	if (ops->get_acl == NULL) {
1616  		cifs_put_tlink(tlink);
1617  		return -EOPNOTSUPP;
1618  	}
1619  
1620  	pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1621  	if (IS_ERR(pntsd)) {
1622  		rc = PTR_ERR(pntsd);
1623  		cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1624  		cifs_put_tlink(tlink);
1625  		return rc;
1626  	}
1627  
1628  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1629  		mode_from_sid = true;
1630  	else
1631  		mode_from_sid = false;
1632  
1633  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1634  		id_from_sid = true;
1635  	else
1636  		id_from_sid = false;
1637  
1638  	/* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1639  	if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1640  		if (posix)
1641  			nsecdesclen = 1 * sizeof(struct smb_ace);
1642  		else if (mode_from_sid)
1643  			nsecdesclen = secdesclen + (2 * sizeof(struct smb_ace));
1644  		else /* cifsacl */
1645  			nsecdesclen = secdesclen + (5 * sizeof(struct smb_ace));
1646  	} else { /* chown */
1647  		/* When ownership changes, changes new owner sid length could be different */
1648  		nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
1649  		dacloffset = le32_to_cpu(pntsd->dacloffset);
1650  		if (dacloffset) {
1651  			dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1652  			if (mode_from_sid)
1653  				nsecdesclen +=
1654  					le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
1655  			else /* cifsacl */
1656  				nsecdesclen += le16_to_cpu(dacl_ptr->size);
1657  		}
1658  	}
1659  
1660  	/*
1661  	 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1662  	 * as chmod disables ACEs and set the security descriptor. Allocate
1663  	 * memory for the smb header, set security descriptor request security
1664  	 * descriptor parameters, and security descriptor itself
1665  	 */
1666  	nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1667  	pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1668  	if (!pnntsd) {
1669  		kfree(pntsd);
1670  		cifs_put_tlink(tlink);
1671  		return -ENOMEM;
1672  	}
1673  
1674  	rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1675  			    mode_from_sid, id_from_sid, posix, &aclflag);
1676  
1677  	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1678  
1679  	if (ops->set_acl == NULL)
1680  		rc = -EOPNOTSUPP;
1681  
1682  	if (!rc) {
1683  		/* Set the security descriptor */
1684  		rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1685  		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1686  	}
1687  	cifs_put_tlink(tlink);
1688  
1689  	kfree(pnntsd);
1690  	kfree(pntsd);
1691  	return rc;
1692  }
1693  
cifs_get_acl(struct mnt_idmap * idmap,struct dentry * dentry,int type)1694  struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
1695  			       struct dentry *dentry, int type)
1696  {
1697  #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1698  	struct posix_acl *acl = NULL;
1699  	ssize_t rc = -EOPNOTSUPP;
1700  	unsigned int xid;
1701  	struct super_block *sb = dentry->d_sb;
1702  	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1703  	struct tcon_link *tlink;
1704  	struct cifs_tcon *pTcon;
1705  	const char *full_path;
1706  	void *page;
1707  
1708  	tlink = cifs_sb_tlink(cifs_sb);
1709  	if (IS_ERR(tlink))
1710  		return ERR_CAST(tlink);
1711  	pTcon = tlink_tcon(tlink);
1712  
1713  	xid = get_xid();
1714  	page = alloc_dentry_path();
1715  
1716  	full_path = build_path_from_dentry(dentry, page);
1717  	if (IS_ERR(full_path)) {
1718  		acl = ERR_CAST(full_path);
1719  		goto out;
1720  	}
1721  
1722  	/* return alt name if available as pseudo attr */
1723  	switch (type) {
1724  	case ACL_TYPE_ACCESS:
1725  		if (sb->s_flags & SB_POSIXACL)
1726  			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1727  					     ACL_TYPE_ACCESS,
1728  					     cifs_sb->local_nls,
1729  					     cifs_remap(cifs_sb));
1730  		break;
1731  
1732  	case ACL_TYPE_DEFAULT:
1733  		if (sb->s_flags & SB_POSIXACL)
1734  			rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1735  					     ACL_TYPE_DEFAULT,
1736  					     cifs_sb->local_nls,
1737  					     cifs_remap(cifs_sb));
1738  		break;
1739  	}
1740  
1741  	if (rc < 0) {
1742  		if (rc == -EINVAL)
1743  			acl = ERR_PTR(-EOPNOTSUPP);
1744  		else
1745  			acl = ERR_PTR(rc);
1746  	}
1747  
1748  out:
1749  	free_dentry_path(page);
1750  	free_xid(xid);
1751  	cifs_put_tlink(tlink);
1752  	return acl;
1753  #else
1754  	return ERR_PTR(-EOPNOTSUPP);
1755  #endif
1756  }
1757  
cifs_set_acl(struct mnt_idmap * idmap,struct dentry * dentry,struct posix_acl * acl,int type)1758  int cifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
1759  		 struct posix_acl *acl, int type)
1760  {
1761  #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1762  	int rc = -EOPNOTSUPP;
1763  	unsigned int xid;
1764  	struct super_block *sb = dentry->d_sb;
1765  	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1766  	struct tcon_link *tlink;
1767  	struct cifs_tcon *pTcon;
1768  	const char *full_path;
1769  	void *page;
1770  
1771  	tlink = cifs_sb_tlink(cifs_sb);
1772  	if (IS_ERR(tlink))
1773  		return PTR_ERR(tlink);
1774  	pTcon = tlink_tcon(tlink);
1775  
1776  	xid = get_xid();
1777  	page = alloc_dentry_path();
1778  
1779  	full_path = build_path_from_dentry(dentry, page);
1780  	if (IS_ERR(full_path)) {
1781  		rc = PTR_ERR(full_path);
1782  		goto out;
1783  	}
1784  
1785  	if (!acl)
1786  		goto out;
1787  
1788  	/* return dos attributes as pseudo xattr */
1789  	/* return alt name if available as pseudo attr */
1790  
1791  	/* if proc/fs/cifs/streamstoxattr is set then
1792  		search server for EAs or streams to
1793  		returns as xattrs */
1794  	if (posix_acl_xattr_size(acl->a_count) > CIFSMaxBufSize) {
1795  		cifs_dbg(FYI, "size of EA value too large\n");
1796  		rc = -EOPNOTSUPP;
1797  		goto out;
1798  	}
1799  
1800  	switch (type) {
1801  	case ACL_TYPE_ACCESS:
1802  		if (sb->s_flags & SB_POSIXACL)
1803  			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1804  					     ACL_TYPE_ACCESS,
1805  					     cifs_sb->local_nls,
1806  					     cifs_remap(cifs_sb));
1807  		break;
1808  
1809  	case ACL_TYPE_DEFAULT:
1810  		if (sb->s_flags & SB_POSIXACL)
1811  			rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1812  					     ACL_TYPE_DEFAULT,
1813  					     cifs_sb->local_nls,
1814  					     cifs_remap(cifs_sb));
1815  		break;
1816  	}
1817  
1818  out:
1819  	free_dentry_path(page);
1820  	free_xid(xid);
1821  	cifs_put_tlink(tlink);
1822  	return rc;
1823  #else
1824  	return -EOPNOTSUPP;
1825  #endif
1826  }
1827