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 = min(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 u16 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 + sizeof(struct smb_acl) ||
782 end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
783 cifs_dbg(VFS, "ACL too small to parse DACL\n");
784 return;
785 }
786
787 cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
788 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
789 le16_to_cpu(pdacl->num_aces));
790
791 /* reset rwx permissions for user/group/other.
792 Also, if num_aces is 0 i.e. DACL has no ACEs,
793 user/group/other have no permissions */
794 fattr->cf_mode &= ~(0777);
795
796 acl_base = (char *)pdacl;
797 acl_size = sizeof(struct smb_acl);
798
799 num_aces = le16_to_cpu(pdacl->num_aces);
800 if (num_aces > 0) {
801 umode_t denied_mode = 0;
802
803 if (num_aces > (le16_to_cpu(pdacl->size) - sizeof(struct smb_acl)) /
804 (offsetof(struct smb_ace, sid) +
805 offsetof(struct smb_sid, sub_auth) + sizeof(__le16)))
806 return;
807
808 ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *),
809 GFP_KERNEL);
810 if (!ppace)
811 return;
812
813 for (i = 0; i < num_aces; ++i) {
814 ppace[i] = (struct smb_ace *) (acl_base + acl_size);
815 #ifdef CONFIG_CIFS_DEBUG2
816 dump_ace(ppace[i], end_of_acl);
817 #endif
818 if (mode_from_special_sid &&
819 (compare_sids(&(ppace[i]->sid),
820 &sid_unix_NFS_mode) == 0)) {
821 /*
822 * Full permissions are:
823 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
824 * S_IRWXU | S_IRWXG | S_IRWXO
825 */
826 fattr->cf_mode &= ~07777;
827 fattr->cf_mode |=
828 le32_to_cpu(ppace[i]->sid.sub_auth[2]);
829 break;
830 } else {
831 if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
832 access_flags_to_mode(ppace[i]->access_req,
833 ppace[i]->type,
834 &fattr->cf_mode,
835 &denied_mode,
836 ACL_OWNER_MASK);
837 } else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
838 access_flags_to_mode(ppace[i]->access_req,
839 ppace[i]->type,
840 &fattr->cf_mode,
841 &denied_mode,
842 ACL_GROUP_MASK);
843 } else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
844 (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
845 access_flags_to_mode(ppace[i]->access_req,
846 ppace[i]->type,
847 &fattr->cf_mode,
848 &denied_mode,
849 ACL_EVERYONE_MASK);
850 }
851 }
852
853
854 /* memcpy((void *)(&(cifscred->aces[i])),
855 (void *)ppace[i],
856 sizeof(struct smb_ace)); */
857
858 acl_base = (char *)ppace[i];
859 acl_size = le16_to_cpu(ppace[i]->size);
860 }
861
862 kfree(ppace);
863 }
864
865 return;
866 }
867
setup_authusers_ACE(struct smb_ace * pntace)868 unsigned int setup_authusers_ACE(struct smb_ace *pntace)
869 {
870 int i;
871 unsigned int ace_size = 20;
872
873 pntace->type = ACCESS_ALLOWED_ACE_TYPE;
874 pntace->flags = 0x0;
875 pntace->access_req = cpu_to_le32(GENERIC_ALL);
876 pntace->sid.num_subauth = 1;
877 pntace->sid.revision = 1;
878 for (i = 0; i < NUM_AUTHS; i++)
879 pntace->sid.authority[i] = sid_authusers.authority[i];
880
881 pntace->sid.sub_auth[0] = sid_authusers.sub_auth[0];
882
883 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
884 pntace->size = cpu_to_le16(ace_size);
885 return ace_size;
886 }
887
888 /*
889 * Fill in the special SID based on the mode. See
890 * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
891 */
setup_special_mode_ACE(struct smb_ace * pntace,bool posix,__u64 nmode)892 unsigned int setup_special_mode_ACE(struct smb_ace *pntace,
893 bool posix,
894 __u64 nmode)
895 {
896 int i;
897 unsigned int ace_size = 28;
898
899 if (posix)
900 pntace->type = ACCESS_ALLOWED_ACE_TYPE;
901 else
902 pntace->type = ACCESS_DENIED_ACE_TYPE;
903 pntace->flags = 0x0;
904 pntace->access_req = 0;
905 pntace->sid.num_subauth = 3;
906 pntace->sid.revision = 1;
907 for (i = 0; i < NUM_AUTHS; i++)
908 pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
909
910 pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
911 pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
912 pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
913
914 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
915 pntace->size = cpu_to_le16(ace_size);
916 return ace_size;
917 }
918
setup_special_user_owner_ACE(struct smb_ace * pntace)919 unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace)
920 {
921 int i;
922 unsigned int ace_size = 28;
923
924 pntace->type = ACCESS_ALLOWED_ACE_TYPE;
925 pntace->flags = 0x0;
926 pntace->access_req = cpu_to_le32(GENERIC_ALL);
927 pntace->sid.num_subauth = 3;
928 pntace->sid.revision = 1;
929 for (i = 0; i < NUM_AUTHS; i++)
930 pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
931
932 pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
933 pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
934 pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
935
936 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
937 pntace->size = cpu_to_le16(ace_size);
938 return ace_size;
939 }
940
populate_new_aces(char * nacl_base,struct smb_sid * pownersid,struct smb_sid * pgrpsid,__u64 * pnmode,u16 * pnum_aces,u16 * pnsize,bool modefromsid,bool posix)941 static void populate_new_aces(char *nacl_base,
942 struct smb_sid *pownersid,
943 struct smb_sid *pgrpsid,
944 __u64 *pnmode, u16 *pnum_aces, u16 *pnsize,
945 bool modefromsid,
946 bool posix)
947 {
948 __u64 nmode;
949 u16 num_aces = 0;
950 u16 nsize = 0;
951 __u64 user_mode;
952 __u64 group_mode;
953 __u64 other_mode;
954 __u64 deny_user_mode = 0;
955 __u64 deny_group_mode = 0;
956 bool sticky_set = false;
957 struct smb_ace *pnntace = NULL;
958
959 nmode = *pnmode;
960 num_aces = *pnum_aces;
961 nsize = *pnsize;
962
963 if (modefromsid || posix) {
964 pnntace = (struct smb_ace *) (nacl_base + nsize);
965 nsize += setup_special_mode_ACE(pnntace, posix, nmode);
966 num_aces++;
967 if (modefromsid) {
968 pnntace = (struct smb_ace *) (nacl_base + nsize);
969 nsize += setup_authusers_ACE(pnntace);
970 num_aces++;
971 }
972 goto set_size;
973 }
974
975 /*
976 * We'll try to keep the mode as requested by the user.
977 * But in cases where we cannot meaningfully convert that
978 * into ACL, return back the updated mode, so that it is
979 * updated in the inode.
980 */
981
982 if (!memcmp(pownersid, pgrpsid, sizeof(struct smb_sid))) {
983 /*
984 * Case when owner and group SIDs are the same.
985 * Set the more restrictive of the two modes.
986 */
987 user_mode = nmode & (nmode << 3) & 0700;
988 group_mode = nmode & (nmode >> 3) & 0070;
989 } else {
990 user_mode = nmode & 0700;
991 group_mode = nmode & 0070;
992 }
993
994 other_mode = nmode & 0007;
995
996 /* We need DENY ACE when the perm is more restrictive than the next sets. */
997 deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
998 deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
999
1000 *pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
1001
1002 /* This tells if we should allow delete child for group and everyone. */
1003 if (nmode & 01000)
1004 sticky_set = true;
1005
1006 if (deny_user_mode) {
1007 pnntace = (struct smb_ace *) (nacl_base + nsize);
1008 nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
1009 0700, ACCESS_DENIED, false);
1010 num_aces++;
1011 }
1012
1013 /* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
1014 if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
1015 pnntace = (struct smb_ace *) (nacl_base + nsize);
1016 nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1017 0070, ACCESS_DENIED, false);
1018 num_aces++;
1019 }
1020
1021 pnntace = (struct smb_ace *) (nacl_base + nsize);
1022 nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1023 0700, ACCESS_ALLOWED, true);
1024 num_aces++;
1025
1026 /* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
1027 if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1028 pnntace = (struct smb_ace *) (nacl_base + nsize);
1029 nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1030 0070, ACCESS_DENIED, false);
1031 num_aces++;
1032 }
1033
1034 pnntace = (struct smb_ace *) (nacl_base + nsize);
1035 nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1036 0070, ACCESS_ALLOWED, !sticky_set);
1037 num_aces++;
1038
1039 pnntace = (struct smb_ace *) (nacl_base + nsize);
1040 nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1041 0007, ACCESS_ALLOWED, !sticky_set);
1042 num_aces++;
1043
1044 set_size:
1045 *pnum_aces = num_aces;
1046 *pnsize = nsize;
1047 }
1048
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)1049 static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
1050 struct smb_sid *pownersid, struct smb_sid *pgrpsid,
1051 struct smb_sid *pnownersid, struct smb_sid *pngrpsid)
1052 {
1053 int i;
1054 u16 size = 0;
1055 struct smb_ace *pntace = NULL;
1056 char *acl_base = NULL;
1057 u16 src_num_aces = 0;
1058 u16 nsize = 0;
1059 struct smb_ace *pnntace = NULL;
1060 char *nacl_base = NULL;
1061 u16 ace_size = 0;
1062
1063 acl_base = (char *)pdacl;
1064 size = sizeof(struct smb_acl);
1065 src_num_aces = le16_to_cpu(pdacl->num_aces);
1066
1067 nacl_base = (char *)pndacl;
1068 nsize = sizeof(struct smb_acl);
1069
1070 /* Go through all the ACEs */
1071 for (i = 0; i < src_num_aces; ++i) {
1072 pntace = (struct smb_ace *) (acl_base + size);
1073 pnntace = (struct smb_ace *) (nacl_base + nsize);
1074
1075 if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
1076 ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1077 else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
1078 ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1079 else
1080 ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1081
1082 size += le16_to_cpu(pntace->size);
1083 nsize += ace_size;
1084 }
1085
1086 return nsize;
1087 }
1088
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)1089 static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
1090 struct smb_sid *pownersid, struct smb_sid *pgrpsid,
1091 __u64 *pnmode, bool mode_from_sid, bool posix)
1092 {
1093 int i;
1094 u16 size = 0;
1095 struct smb_ace *pntace = NULL;
1096 char *acl_base = NULL;
1097 u16 src_num_aces = 0;
1098 u16 nsize = 0;
1099 struct smb_ace *pnntace = NULL;
1100 char *nacl_base = NULL;
1101 u16 num_aces = 0;
1102 bool new_aces_set = false;
1103
1104 /* Assuming that pndacl and pnmode are never NULL */
1105 nacl_base = (char *)pndacl;
1106 nsize = sizeof(struct smb_acl);
1107
1108 /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1109 if (!pdacl || posix) {
1110 populate_new_aces(nacl_base,
1111 pownersid, pgrpsid,
1112 pnmode, &num_aces, &nsize,
1113 mode_from_sid, posix);
1114 goto finalize_dacl;
1115 }
1116
1117 acl_base = (char *)pdacl;
1118 size = sizeof(struct smb_acl);
1119 src_num_aces = le16_to_cpu(pdacl->num_aces);
1120
1121 /* Retain old ACEs which we can retain */
1122 for (i = 0; i < src_num_aces; ++i) {
1123 pntace = (struct smb_ace *) (acl_base + size);
1124
1125 if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1126 /* Place the new ACEs in between existing explicit and inherited */
1127 populate_new_aces(nacl_base,
1128 pownersid, pgrpsid,
1129 pnmode, &num_aces, &nsize,
1130 mode_from_sid, posix);
1131
1132 new_aces_set = true;
1133 }
1134
1135 /* If it's any one of the ACE we're replacing, skip! */
1136 if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1137 (compare_sids(&pntace->sid, pownersid) == 0) ||
1138 (compare_sids(&pntace->sid, pgrpsid) == 0) ||
1139 (compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1140 (compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1141 goto next_ace;
1142 }
1143
1144 /* update the pointer to the next ACE to populate*/
1145 pnntace = (struct smb_ace *) (nacl_base + nsize);
1146
1147 nsize += cifs_copy_ace(pnntace, pntace, NULL);
1148 num_aces++;
1149
1150 next_ace:
1151 size += le16_to_cpu(pntace->size);
1152 }
1153
1154 /* If inherited ACEs are not present, place the new ones at the tail */
1155 if (!new_aces_set) {
1156 populate_new_aces(nacl_base,
1157 pownersid, pgrpsid,
1158 pnmode, &num_aces, &nsize,
1159 mode_from_sid, posix);
1160
1161 new_aces_set = true;
1162 }
1163
1164 finalize_dacl:
1165 pndacl->num_aces = cpu_to_le16(num_aces);
1166 pndacl->size = cpu_to_le16(nsize);
1167
1168 return 0;
1169 }
1170
parse_sid(struct smb_sid * psid,char * end_of_acl)1171 static int parse_sid(struct smb_sid *psid, char *end_of_acl)
1172 {
1173 /* BB need to add parm so we can store the SID BB */
1174
1175 /* validate that we do not go past end of ACL - sid must be at least 8
1176 bytes long (assuming no sub-auths - e.g. the null SID */
1177 if (end_of_acl < (char *)psid + 8) {
1178 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
1179 return -EINVAL;
1180 }
1181
1182 #ifdef CONFIG_CIFS_DEBUG2
1183 if (psid->num_subauth) {
1184 int i;
1185 cifs_dbg(FYI, "SID revision %d num_auth %d\n",
1186 psid->revision, psid->num_subauth);
1187
1188 for (i = 0; i < psid->num_subauth; i++) {
1189 cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
1190 i, le32_to_cpu(psid->sub_auth[i]));
1191 }
1192
1193 /* BB add length check to make sure that we do not have huge
1194 num auths and therefore go off the end */
1195 cifs_dbg(FYI, "RID 0x%x\n",
1196 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1197 }
1198 #endif
1199
1200 return 0;
1201 }
1202
1203
1204 /* 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)1205 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1206 struct smb_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1207 bool get_mode_from_special_sid)
1208 {
1209 int rc = 0;
1210 struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1211 struct smb_acl *dacl_ptr; /* no need for SACL ptr */
1212 char *end_of_acl = ((char *)pntsd) + acl_len;
1213 __u32 dacloffset;
1214
1215 if (pntsd == NULL)
1216 return -EIO;
1217
1218 owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
1219 le32_to_cpu(pntsd->osidoffset));
1220 group_sid_ptr = (struct smb_sid *)((char *)pntsd +
1221 le32_to_cpu(pntsd->gsidoffset));
1222 dacloffset = le32_to_cpu(pntsd->dacloffset);
1223 dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1224 cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1225 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1226 le32_to_cpu(pntsd->gsidoffset),
1227 le32_to_cpu(pntsd->sacloffset), dacloffset);
1228 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1229 rc = parse_sid(owner_sid_ptr, end_of_acl);
1230 if (rc) {
1231 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1232 return rc;
1233 }
1234 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1235 if (rc) {
1236 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1237 __func__, rc);
1238 return rc;
1239 }
1240
1241 rc = parse_sid(group_sid_ptr, end_of_acl);
1242 if (rc) {
1243 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
1244 __func__, rc);
1245 return rc;
1246 }
1247 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1248 if (rc) {
1249 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1250 __func__, rc);
1251 return rc;
1252 }
1253
1254 if (dacloffset)
1255 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1256 group_sid_ptr, fattr, get_mode_from_special_sid);
1257 else
1258 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1259
1260 return rc;
1261 }
1262
1263 /* 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)1264 static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
1265 __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1266 bool mode_from_sid, bool id_from_sid, bool posix, int *aclflag)
1267 {
1268 int rc = 0;
1269 __u32 dacloffset;
1270 __u32 ndacloffset;
1271 __u32 sidsoffset;
1272 struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1273 struct smb_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1274 struct smb_acl *dacl_ptr = NULL; /* no need for SACL ptr */
1275 struct smb_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1276 char *end_of_acl = ((char *)pntsd) + secdesclen;
1277 u16 size = 0;
1278
1279 dacloffset = le32_to_cpu(pntsd->dacloffset);
1280 if (dacloffset) {
1281 dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1282 if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) {
1283 cifs_dbg(VFS, "Server returned illegal ACL size\n");
1284 return -EINVAL;
1285 }
1286 }
1287
1288 owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
1289 le32_to_cpu(pntsd->osidoffset));
1290 group_sid_ptr = (struct smb_sid *)((char *)pntsd +
1291 le32_to_cpu(pntsd->gsidoffset));
1292
1293 if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1294 ndacloffset = sizeof(struct smb_ntsd);
1295 ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
1296 ndacl_ptr->revision =
1297 dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1298
1299 ndacl_ptr->size = cpu_to_le16(0);
1300 ndacl_ptr->num_aces = cpu_to_le16(0);
1301
1302 rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1303 pnmode, mode_from_sid, posix);
1304
1305 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1306 /* copy the non-dacl portion of secdesc */
1307 *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1308 NULL, NULL);
1309
1310 *aclflag |= CIFS_ACL_DACL;
1311 } else {
1312 ndacloffset = sizeof(struct smb_ntsd);
1313 ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
1314 ndacl_ptr->revision =
1315 dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1316 ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
1317
1318 if (uid_valid(uid)) { /* chown */
1319 uid_t id;
1320 nowner_sid_ptr = kzalloc(sizeof(struct smb_sid),
1321 GFP_KERNEL);
1322 if (!nowner_sid_ptr) {
1323 rc = -ENOMEM;
1324 goto chown_chgrp_exit;
1325 }
1326 id = from_kuid(&init_user_ns, uid);
1327 if (id_from_sid) {
1328 struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1329 /* Populate the user ownership fields S-1-5-88-1 */
1330 osid->Revision = 1;
1331 osid->NumAuth = 3;
1332 osid->Authority[5] = 5;
1333 osid->SubAuthorities[0] = cpu_to_le32(88);
1334 osid->SubAuthorities[1] = cpu_to_le32(1);
1335 osid->SubAuthorities[2] = cpu_to_le32(id);
1336
1337 } else { /* lookup sid with upcall */
1338 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1339 if (rc) {
1340 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1341 __func__, rc, id);
1342 goto chown_chgrp_exit;
1343 }
1344 }
1345 *aclflag |= CIFS_ACL_OWNER;
1346 }
1347 if (gid_valid(gid)) { /* chgrp */
1348 gid_t id;
1349 ngroup_sid_ptr = kzalloc(sizeof(struct smb_sid),
1350 GFP_KERNEL);
1351 if (!ngroup_sid_ptr) {
1352 rc = -ENOMEM;
1353 goto chown_chgrp_exit;
1354 }
1355 id = from_kgid(&init_user_ns, gid);
1356 if (id_from_sid) {
1357 struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1358 /* Populate the group ownership fields S-1-5-88-2 */
1359 gsid->Revision = 1;
1360 gsid->NumAuth = 3;
1361 gsid->Authority[5] = 5;
1362 gsid->SubAuthorities[0] = cpu_to_le32(88);
1363 gsid->SubAuthorities[1] = cpu_to_le32(2);
1364 gsid->SubAuthorities[2] = cpu_to_le32(id);
1365
1366 } else { /* lookup sid with upcall */
1367 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1368 if (rc) {
1369 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1370 __func__, rc, id);
1371 goto chown_chgrp_exit;
1372 }
1373 }
1374 *aclflag |= CIFS_ACL_GROUP;
1375 }
1376
1377 if (dacloffset) {
1378 /* Replace ACEs for old owner with new one */
1379 size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1380 owner_sid_ptr, group_sid_ptr,
1381 nowner_sid_ptr, ngroup_sid_ptr);
1382 ndacl_ptr->size = cpu_to_le16(size);
1383 }
1384
1385 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1386 /* copy the non-dacl portion of secdesc */
1387 *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1388 nowner_sid_ptr, ngroup_sid_ptr);
1389
1390 chown_chgrp_exit:
1391 /* errors could jump here. So make sure we return soon after this */
1392 kfree(nowner_sid_ptr);
1393 kfree(ngroup_sid_ptr);
1394 }
1395
1396 return rc;
1397 }
1398
1399 #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)1400 struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1401 const struct cifs_fid *cifsfid, u32 *pacllen,
1402 u32 info)
1403 {
1404 struct smb_ntsd *pntsd = NULL;
1405 unsigned int xid;
1406 int rc;
1407 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1408
1409 if (IS_ERR(tlink))
1410 return ERR_CAST(tlink);
1411
1412 xid = get_xid();
1413 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1414 pacllen, info);
1415 free_xid(xid);
1416
1417 cifs_put_tlink(tlink);
1418
1419 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1420 if (rc)
1421 return ERR_PTR(rc);
1422 return pntsd;
1423 }
1424
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen,u32 info)1425 static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1426 const char *path, u32 *pacllen, u32 info)
1427 {
1428 struct smb_ntsd *pntsd = NULL;
1429 int oplock = 0;
1430 unsigned int xid;
1431 int rc;
1432 struct cifs_tcon *tcon;
1433 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1434 struct cifs_fid fid;
1435 struct cifs_open_parms oparms;
1436
1437 if (IS_ERR(tlink))
1438 return ERR_CAST(tlink);
1439
1440 tcon = tlink_tcon(tlink);
1441 xid = get_xid();
1442
1443 oparms = (struct cifs_open_parms) {
1444 .tcon = tcon,
1445 .cifs_sb = cifs_sb,
1446 .desired_access = READ_CONTROL,
1447 .create_options = cifs_create_options(cifs_sb, 0),
1448 .disposition = FILE_OPEN,
1449 .path = path,
1450 .fid = &fid,
1451 };
1452
1453 if (info & SACL_SECINFO)
1454 oparms.desired_access |= SYSTEM_SECURITY;
1455
1456 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1457 if (!rc) {
1458 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen, info);
1459 CIFSSMBClose(xid, tcon, fid.netfid);
1460 }
1461
1462 cifs_put_tlink(tlink);
1463 free_xid(xid);
1464
1465 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1466 if (rc)
1467 return ERR_PTR(rc);
1468 return pntsd;
1469 }
1470
1471 /* 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)1472 struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1473 struct inode *inode, const char *path,
1474 u32 *pacllen, u32 info)
1475 {
1476 struct smb_ntsd *pntsd = NULL;
1477 struct cifsFileInfo *open_file = NULL;
1478
1479 if (inode)
1480 open_file = find_readable_file(CIFS_I(inode), true);
1481 if (!open_file)
1482 return get_cifs_acl_by_path(cifs_sb, path, pacllen, info);
1483
1484 pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1485 cifsFileInfo_put(open_file);
1486 return pntsd;
1487 }
1488
1489 /* Set an ACL on the server */
set_cifs_acl(struct smb_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path,int aclflag)1490 int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
1491 struct inode *inode, const char *path, int aclflag)
1492 {
1493 int oplock = 0;
1494 unsigned int xid;
1495 int rc, access_flags = 0;
1496 struct cifs_tcon *tcon;
1497 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1498 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1499 struct cifs_fid fid;
1500 struct cifs_open_parms oparms;
1501
1502 if (IS_ERR(tlink))
1503 return PTR_ERR(tlink);
1504
1505 tcon = tlink_tcon(tlink);
1506 xid = get_xid();
1507
1508 if (aclflag & CIFS_ACL_OWNER || aclflag & CIFS_ACL_GROUP)
1509 access_flags |= WRITE_OWNER;
1510 if (aclflag & CIFS_ACL_SACL)
1511 access_flags |= SYSTEM_SECURITY;
1512 if (aclflag & CIFS_ACL_DACL)
1513 access_flags |= WRITE_DAC;
1514
1515 oparms = (struct cifs_open_parms) {
1516 .tcon = tcon,
1517 .cifs_sb = cifs_sb,
1518 .desired_access = access_flags,
1519 .create_options = cifs_create_options(cifs_sb, 0),
1520 .disposition = FILE_OPEN,
1521 .path = path,
1522 .fid = &fid,
1523 };
1524
1525 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1526 if (rc) {
1527 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1528 goto out;
1529 }
1530
1531 rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1532 cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1533
1534 CIFSSMBClose(xid, tcon, fid.netfid);
1535 out:
1536 free_xid(xid);
1537 cifs_put_tlink(tlink);
1538 return rc;
1539 }
1540 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1541
1542 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1543 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)1544 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1545 struct inode *inode, bool mode_from_special_sid,
1546 const char *path, const struct cifs_fid *pfid)
1547 {
1548 struct smb_ntsd *pntsd = NULL;
1549 u32 acllen = 0;
1550 int rc = 0;
1551 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1552 struct smb_version_operations *ops;
1553 const u32 info = 0;
1554
1555 cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1556
1557 if (IS_ERR(tlink))
1558 return PTR_ERR(tlink);
1559
1560 ops = tlink_tcon(tlink)->ses->server->ops;
1561
1562 if (pfid && (ops->get_acl_by_fid))
1563 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1564 else if (ops->get_acl)
1565 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1566 else {
1567 cifs_put_tlink(tlink);
1568 return -EOPNOTSUPP;
1569 }
1570 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1571 if (IS_ERR(pntsd)) {
1572 rc = PTR_ERR(pntsd);
1573 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1574 } else if (mode_from_special_sid) {
1575 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1576 kfree(pntsd);
1577 } else {
1578 /* get approximated mode from ACL */
1579 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1580 kfree(pntsd);
1581 if (rc)
1582 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1583 }
1584
1585 cifs_put_tlink(tlink);
1586
1587 return rc;
1588 }
1589
1590 /* Convert mode bits to an ACL so we can update the ACL on the server */
1591 int
id_mode_to_cifs_acl(struct inode * inode,const char * path,__u64 * pnmode,kuid_t uid,kgid_t gid)1592 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1593 kuid_t uid, kgid_t gid)
1594 {
1595 int rc = 0;
1596 int aclflag = CIFS_ACL_DACL; /* default flag to set */
1597 __u32 secdesclen = 0;
1598 __u32 nsecdesclen = 0;
1599 __u32 dacloffset = 0;
1600 struct smb_acl *dacl_ptr = NULL;
1601 struct smb_ntsd *pntsd = NULL; /* acl obtained from server */
1602 struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1603 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1604 struct tcon_link *tlink;
1605 struct smb_version_operations *ops;
1606 bool mode_from_sid, id_from_sid;
1607 const u32 info = 0;
1608 bool posix;
1609
1610 tlink = cifs_sb_tlink(cifs_sb);
1611 if (IS_ERR(tlink))
1612 return PTR_ERR(tlink);
1613 posix = tlink_tcon(tlink)->posix_extensions;
1614
1615 ops = tlink_tcon(tlink)->ses->server->ops;
1616
1617 cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1618
1619 /* Get the security descriptor */
1620
1621 if (ops->get_acl == NULL) {
1622 cifs_put_tlink(tlink);
1623 return -EOPNOTSUPP;
1624 }
1625
1626 pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1627 if (IS_ERR(pntsd)) {
1628 rc = PTR_ERR(pntsd);
1629 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1630 cifs_put_tlink(tlink);
1631 return rc;
1632 }
1633
1634 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1635 mode_from_sid = true;
1636 else
1637 mode_from_sid = false;
1638
1639 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1640 id_from_sid = true;
1641 else
1642 id_from_sid = false;
1643
1644 /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1645 if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1646 if (posix)
1647 nsecdesclen = 1 * sizeof(struct smb_ace);
1648 else if (mode_from_sid)
1649 nsecdesclen = secdesclen + (2 * sizeof(struct smb_ace));
1650 else /* cifsacl */
1651 nsecdesclen = secdesclen + (5 * sizeof(struct smb_ace));
1652 } else { /* chown */
1653 /* When ownership changes, changes new owner sid length could be different */
1654 nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
1655 dacloffset = le32_to_cpu(pntsd->dacloffset);
1656 if (dacloffset) {
1657 dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1658 if (mode_from_sid)
1659 nsecdesclen +=
1660 le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
1661 else /* cifsacl */
1662 nsecdesclen += le16_to_cpu(dacl_ptr->size);
1663 }
1664 }
1665
1666 /*
1667 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1668 * as chmod disables ACEs and set the security descriptor. Allocate
1669 * memory for the smb header, set security descriptor request security
1670 * descriptor parameters, and security descriptor itself
1671 */
1672 nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1673 pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1674 if (!pnntsd) {
1675 kfree(pntsd);
1676 cifs_put_tlink(tlink);
1677 return -ENOMEM;
1678 }
1679
1680 rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1681 mode_from_sid, id_from_sid, posix, &aclflag);
1682
1683 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1684
1685 if (ops->set_acl == NULL)
1686 rc = -EOPNOTSUPP;
1687
1688 if (!rc) {
1689 /* Set the security descriptor */
1690 rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1691 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1692 }
1693 cifs_put_tlink(tlink);
1694
1695 kfree(pnntsd);
1696 kfree(pntsd);
1697 return rc;
1698 }
1699
cifs_get_acl(struct mnt_idmap * idmap,struct dentry * dentry,int type)1700 struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
1701 struct dentry *dentry, int type)
1702 {
1703 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1704 struct posix_acl *acl = NULL;
1705 ssize_t rc = -EOPNOTSUPP;
1706 unsigned int xid;
1707 struct super_block *sb = dentry->d_sb;
1708 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1709 struct tcon_link *tlink;
1710 struct cifs_tcon *pTcon;
1711 const char *full_path;
1712 void *page;
1713
1714 tlink = cifs_sb_tlink(cifs_sb);
1715 if (IS_ERR(tlink))
1716 return ERR_CAST(tlink);
1717 pTcon = tlink_tcon(tlink);
1718
1719 xid = get_xid();
1720 page = alloc_dentry_path();
1721
1722 full_path = build_path_from_dentry(dentry, page);
1723 if (IS_ERR(full_path)) {
1724 acl = ERR_CAST(full_path);
1725 goto out;
1726 }
1727
1728 /* return alt name if available as pseudo attr */
1729 switch (type) {
1730 case ACL_TYPE_ACCESS:
1731 if (sb->s_flags & SB_POSIXACL)
1732 rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1733 ACL_TYPE_ACCESS,
1734 cifs_sb->local_nls,
1735 cifs_remap(cifs_sb));
1736 break;
1737
1738 case ACL_TYPE_DEFAULT:
1739 if (sb->s_flags & SB_POSIXACL)
1740 rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1741 ACL_TYPE_DEFAULT,
1742 cifs_sb->local_nls,
1743 cifs_remap(cifs_sb));
1744 break;
1745 }
1746
1747 if (rc < 0) {
1748 if (rc == -EINVAL)
1749 acl = ERR_PTR(-EOPNOTSUPP);
1750 else
1751 acl = ERR_PTR(rc);
1752 }
1753
1754 out:
1755 free_dentry_path(page);
1756 free_xid(xid);
1757 cifs_put_tlink(tlink);
1758 return acl;
1759 #else
1760 return ERR_PTR(-EOPNOTSUPP);
1761 #endif
1762 }
1763
cifs_set_acl(struct mnt_idmap * idmap,struct dentry * dentry,struct posix_acl * acl,int type)1764 int cifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
1765 struct posix_acl *acl, int type)
1766 {
1767 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1768 int rc = -EOPNOTSUPP;
1769 unsigned int xid;
1770 struct super_block *sb = dentry->d_sb;
1771 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1772 struct tcon_link *tlink;
1773 struct cifs_tcon *pTcon;
1774 const char *full_path;
1775 void *page;
1776
1777 tlink = cifs_sb_tlink(cifs_sb);
1778 if (IS_ERR(tlink))
1779 return PTR_ERR(tlink);
1780 pTcon = tlink_tcon(tlink);
1781
1782 xid = get_xid();
1783 page = alloc_dentry_path();
1784
1785 full_path = build_path_from_dentry(dentry, page);
1786 if (IS_ERR(full_path)) {
1787 rc = PTR_ERR(full_path);
1788 goto out;
1789 }
1790
1791 if (!acl)
1792 goto out;
1793
1794 /* return dos attributes as pseudo xattr */
1795 /* return alt name if available as pseudo attr */
1796
1797 /* if proc/fs/cifs/streamstoxattr is set then
1798 search server for EAs or streams to
1799 returns as xattrs */
1800 if (posix_acl_xattr_size(acl->a_count) > CIFSMaxBufSize) {
1801 cifs_dbg(FYI, "size of EA value too large\n");
1802 rc = -EOPNOTSUPP;
1803 goto out;
1804 }
1805
1806 switch (type) {
1807 case ACL_TYPE_ACCESS:
1808 if (sb->s_flags & SB_POSIXACL)
1809 rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1810 ACL_TYPE_ACCESS,
1811 cifs_sb->local_nls,
1812 cifs_remap(cifs_sb));
1813 break;
1814
1815 case ACL_TYPE_DEFAULT:
1816 if (sb->s_flags & SB_POSIXACL)
1817 rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1818 ACL_TYPE_DEFAULT,
1819 cifs_sb->local_nls,
1820 cifs_remap(cifs_sb));
1821 break;
1822 }
1823
1824 out:
1825 free_dentry_path(page);
1826 free_xid(xid);
1827 cifs_put_tlink(tlink);
1828 return rc;
1829 #else
1830 return -EOPNOTSUPP;
1831 #endif
1832 }
1833