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