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