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 "cifsglob.h"
21 #include "cifsacl.h"
22 #include "cifsproto.h"
23 #include "cifs_debug.h"
24 #include "fs_context.h"
25 #include "cifs_fs_sb.h"
26 #include "cifs_unicode.h"
27
28 /* security id for everyone/world system group */
29 static const struct smb_sid sid_everyone = {
30 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
31 /* security id for Authenticated Users system group */
32 static const struct smb_sid sid_authusers = {
33 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
34
35 /* S-1-22-1 Unmapped Unix users */
36 static const struct smb_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
37 {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
38
39 /* S-1-22-2 Unmapped Unix groups */
40 static const struct smb_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
41 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
42
43 /*
44 * See https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
45 */
46
47 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
48
49 /* S-1-5-88-1 Unix uid */
50 static const struct smb_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
51 {cpu_to_le32(88),
52 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
53
54 /* S-1-5-88-2 Unix gid */
55 static const struct smb_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
56 {cpu_to_le32(88),
57 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
58
59 /* S-1-5-88-3 Unix mode */
60 static const struct smb_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
61 {cpu_to_le32(88),
62 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
63
64 static const struct cred *root_cred;
65
66 static int
cifs_idmap_key_instantiate(struct key * key,struct key_preparsed_payload * prep)67 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
68 {
69 char *payload;
70
71 /*
72 * If the payload is less than or equal to the size of a pointer, then
73 * an allocation here is wasteful. Just copy the data directly to the
74 * payload.value union member instead.
75 *
76 * With this however, you must check the datalen before trying to
77 * dereference payload.data!
78 */
79 if (prep->datalen <= sizeof(key->payload)) {
80 key->payload.data[0] = NULL;
81 memcpy(&key->payload, prep->data, prep->datalen);
82 } else {
83 payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
84 if (!payload)
85 return -ENOMEM;
86 key->payload.data[0] = payload;
87 }
88
89 key->datalen = prep->datalen;
90 return 0;
91 }
92
93 static inline void
cifs_idmap_key_destroy(struct key * key)94 cifs_idmap_key_destroy(struct key *key)
95 {
96 if (key->datalen > sizeof(key->payload))
97 kfree(key->payload.data[0]);
98 }
99
100 static struct key_type cifs_idmap_key_type = {
101 .name = "cifs.idmap",
102 .instantiate = cifs_idmap_key_instantiate,
103 .destroy = cifs_idmap_key_destroy,
104 .describe = user_describe,
105 };
106
107 static char *
sid_to_key_str(struct smb_sid * sidptr,unsigned int type)108 sid_to_key_str(struct smb_sid *sidptr, unsigned int type)
109 {
110 int i, len;
111 unsigned int saval;
112 char *sidstr, *strptr;
113 unsigned long long id_auth_val;
114
115 /* 3 bytes for prefix */
116 sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
117 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
118 GFP_KERNEL);
119 if (!sidstr)
120 return sidstr;
121
122 strptr = sidstr;
123 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
124 sidptr->revision);
125 strptr += len;
126
127 /* The authority field is a single 48-bit number */
128 id_auth_val = (unsigned long long)sidptr->authority[5];
129 id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
130 id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
131 id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
132 id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
133 id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
134
135 /*
136 * MS-DTYP states that if the authority is >= 2^32, then it should be
137 * expressed as a hex value.
138 */
139 if (id_auth_val <= UINT_MAX)
140 len = sprintf(strptr, "-%llu", id_auth_val);
141 else
142 len = sprintf(strptr, "-0x%llx", id_auth_val);
143
144 strptr += len;
145
146 for (i = 0; i < sidptr->num_subauth; ++i) {
147 saval = le32_to_cpu(sidptr->sub_auth[i]);
148 len = sprintf(strptr, "-%u", saval);
149 strptr += len;
150 }
151
152 return sidstr;
153 }
154
155 /*
156 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
157 * the same returns zero, if they do not match returns non-zero.
158 */
159 static int
compare_sids(const struct smb_sid * ctsid,const struct smb_sid * cwsid)160 compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
161 {
162 int i;
163 int num_subauth, num_sat, num_saw;
164
165 if ((!ctsid) || (!cwsid))
166 return 1;
167
168 /* compare the revision */
169 if (ctsid->revision != cwsid->revision) {
170 if (ctsid->revision > cwsid->revision)
171 return 1;
172 else
173 return -1;
174 }
175
176 /* compare all of the six auth values */
177 for (i = 0; i < NUM_AUTHS; ++i) {
178 if (ctsid->authority[i] != cwsid->authority[i]) {
179 if (ctsid->authority[i] > cwsid->authority[i])
180 return 1;
181 else
182 return -1;
183 }
184 }
185
186 /* compare all of the subauth values if any */
187 num_sat = ctsid->num_subauth;
188 num_saw = cwsid->num_subauth;
189 num_subauth = min(num_sat, num_saw);
190 if (num_subauth) {
191 for (i = 0; i < num_subauth; ++i) {
192 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
193 if (le32_to_cpu(ctsid->sub_auth[i]) >
194 le32_to_cpu(cwsid->sub_auth[i]))
195 return 1;
196 else
197 return -1;
198 }
199 }
200 }
201
202 return 0; /* sids compare/match */
203 }
204
205 static bool
is_well_known_sid(const struct smb_sid * psid,uint32_t * puid,bool is_group)206 is_well_known_sid(const struct smb_sid *psid, uint32_t *puid, bool is_group)
207 {
208 int i;
209 int num_subauth;
210 const struct smb_sid *pwell_known_sid;
211
212 if (!psid || (puid == NULL))
213 return false;
214
215 num_subauth = psid->num_subauth;
216
217 /* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
218 if (num_subauth == 2) {
219 if (is_group)
220 pwell_known_sid = &sid_unix_groups;
221 else
222 pwell_known_sid = &sid_unix_users;
223 } else if (num_subauth == 3) {
224 if (is_group)
225 pwell_known_sid = &sid_unix_NFS_groups;
226 else
227 pwell_known_sid = &sid_unix_NFS_users;
228 } else
229 return false;
230
231 /* compare the revision */
232 if (psid->revision != pwell_known_sid->revision)
233 return false;
234
235 /* compare all of the six auth values */
236 for (i = 0; i < NUM_AUTHS; ++i) {
237 if (psid->authority[i] != pwell_known_sid->authority[i]) {
238 cifs_dbg(FYI, "auth %d did not match\n", i);
239 return false;
240 }
241 }
242
243 if (num_subauth == 2) {
244 if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
245 return false;
246
247 *puid = le32_to_cpu(psid->sub_auth[1]);
248 } else /* 3 subauths, ie Windows/Mac style */ {
249 *puid = le32_to_cpu(psid->sub_auth[0]);
250 if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
251 (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
252 return false;
253
254 *puid = le32_to_cpu(psid->sub_auth[2]);
255 }
256
257 cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
258 return true; /* well known sid found, uid returned */
259 }
260
261 static __u16
cifs_copy_sid(struct smb_sid * dst,const struct smb_sid * src)262 cifs_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
263 {
264 int i;
265 __u16 size = 1 + 1 + 6;
266
267 dst->revision = src->revision;
268 dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
269 for (i = 0; i < NUM_AUTHS; ++i)
270 dst->authority[i] = src->authority[i];
271 for (i = 0; i < dst->num_subauth; ++i)
272 dst->sub_auth[i] = src->sub_auth[i];
273 size += (dst->num_subauth * 4);
274
275 return size;
276 }
277
278 static int
id_to_sid(unsigned int cid,uint sidtype,struct smb_sid * ssid)279 id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
280 {
281 int rc;
282 struct key *sidkey;
283 struct smb_sid *ksid;
284 unsigned int ksid_size;
285 char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
286 const struct cred *saved_cred;
287
288 rc = snprintf(desc, sizeof(desc), "%ci:%u",
289 sidtype == SIDOWNER ? 'o' : 'g', cid);
290 if (rc >= sizeof(desc))
291 return -EINVAL;
292
293 rc = 0;
294 saved_cred = override_creds(root_cred);
295 sidkey = request_key(&cifs_idmap_key_type, desc, "");
296 if (IS_ERR(sidkey)) {
297 rc = -EINVAL;
298 cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
299 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
300 goto out_revert_creds;
301 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
302 rc = smb_EIO1(smb_eio_trace_malformed_sid_key, sidkey->datalen);
303 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
304 __func__, sidkey->datalen);
305 goto invalidate_key;
306 }
307
308 /*
309 * A sid is usually too large to be embedded in payload.value, but if
310 * there are no subauthorities and the host has 8-byte pointers, then
311 * it could be.
312 */
313 ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
314 (struct smb_sid *)&sidkey->payload :
315 (struct smb_sid *)sidkey->payload.data[0];
316
317 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
318 if (ksid_size > sidkey->datalen) {
319 rc = smb_EIO2(smb_eio_trace_malformed_ksid_key,
320 ksid_size, sidkey->datalen);
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 smb_EIO2(smb_eio_trace_sid_too_many_auth,
356 psid->num_subauth, SID_MAX_SUB_AUTHORITIES);
357 }
358
359 if ((cifs_sb_flags(cifs_sb) & 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 if (sidtype == SIDOWNER)
450 fattr->cf_uid = fuid;
451 else
452 fattr->cf_gid = fgid;
453
454 return 0;
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_objs(struct smb_ace *, num_aces);
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 smb_EIO(smb_eio_trace_null_pointers);
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_obj(struct smb_sid);
1335 if (!nowner_sid_ptr) {
1336 rc = -ENOMEM;
1337 goto chown_chgrp_exit;
1338 }
1339 id = from_kuid(&init_user_ns, uid);
1340 if (id_from_sid) {
1341 struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1342 /* Populate the user ownership fields S-1-5-88-1 */
1343 osid->Revision = 1;
1344 osid->NumAuth = 3;
1345 osid->Authority[5] = 5;
1346 osid->SubAuthorities[0] = cpu_to_le32(88);
1347 osid->SubAuthorities[1] = cpu_to_le32(1);
1348 osid->SubAuthorities[2] = cpu_to_le32(id);
1349
1350 } else { /* lookup sid with upcall */
1351 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1352 if (rc) {
1353 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1354 __func__, rc, id);
1355 goto chown_chgrp_exit;
1356 }
1357 }
1358 *aclflag |= CIFS_ACL_OWNER;
1359 }
1360 if (gid_valid(gid)) { /* chgrp */
1361 gid_t id;
1362 ngroup_sid_ptr = kzalloc_obj(struct smb_sid);
1363 if (!ngroup_sid_ptr) {
1364 rc = -ENOMEM;
1365 goto chown_chgrp_exit;
1366 }
1367 id = from_kgid(&init_user_ns, gid);
1368 if (id_from_sid) {
1369 struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1370 /* Populate the group ownership fields S-1-5-88-2 */
1371 gsid->Revision = 1;
1372 gsid->NumAuth = 3;
1373 gsid->Authority[5] = 5;
1374 gsid->SubAuthorities[0] = cpu_to_le32(88);
1375 gsid->SubAuthorities[1] = cpu_to_le32(2);
1376 gsid->SubAuthorities[2] = cpu_to_le32(id);
1377
1378 } else { /* lookup sid with upcall */
1379 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1380 if (rc) {
1381 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1382 __func__, rc, id);
1383 goto chown_chgrp_exit;
1384 }
1385 }
1386 *aclflag |= CIFS_ACL_GROUP;
1387 }
1388
1389 if (dacloffset) {
1390 /* Replace ACEs for old owner with new one */
1391 size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1392 owner_sid_ptr, group_sid_ptr,
1393 nowner_sid_ptr, ngroup_sid_ptr);
1394 ndacl_ptr->size = cpu_to_le16(size);
1395 }
1396
1397 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1398 /* copy the non-dacl portion of secdesc */
1399 *pnsecdesclen = copy_sec_desc(pntsd, pnntsd, sidsoffset,
1400 nowner_sid_ptr, ngroup_sid_ptr);
1401
1402 chown_chgrp_exit:
1403 /* errors could jump here. So make sure we return soon after this */
1404 kfree(nowner_sid_ptr);
1405 kfree(ngroup_sid_ptr);
1406 }
1407
1408 return rc;
1409 }
1410
1411 #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)1412 struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1413 const struct cifs_fid *cifsfid, u32 *pacllen,
1414 u32 info)
1415 {
1416 struct smb_ntsd *pntsd = NULL;
1417 unsigned int xid;
1418 int rc;
1419 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1420
1421 if (IS_ERR(tlink))
1422 return ERR_CAST(tlink);
1423
1424 xid = get_xid();
1425 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1426 pacllen, info);
1427 free_xid(xid);
1428
1429 cifs_put_tlink(tlink);
1430
1431 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1432 if (rc)
1433 return ERR_PTR(rc);
1434 return pntsd;
1435 }
1436
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen,u32 info)1437 static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1438 const char *path, u32 *pacllen, u32 info)
1439 {
1440 struct smb_ntsd *pntsd = NULL;
1441 int oplock = 0;
1442 unsigned int xid;
1443 int rc;
1444 struct cifs_tcon *tcon;
1445 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1446 struct cifs_fid fid;
1447 struct cifs_open_parms oparms;
1448
1449 if (IS_ERR(tlink))
1450 return ERR_CAST(tlink);
1451
1452 tcon = tlink_tcon(tlink);
1453 xid = get_xid();
1454
1455 oparms = (struct cifs_open_parms) {
1456 .tcon = tcon,
1457 .cifs_sb = cifs_sb,
1458 .desired_access = READ_CONTROL,
1459 .create_options = cifs_create_options(cifs_sb, 0),
1460 .disposition = FILE_OPEN,
1461 .path = path,
1462 .fid = &fid,
1463 };
1464
1465 if (info & SACL_SECINFO)
1466 oparms.desired_access |= SYSTEM_SECURITY;
1467
1468 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1469 if (!rc) {
1470 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen, info);
1471 CIFSSMBClose(xid, tcon, fid.netfid);
1472 }
1473
1474 cifs_put_tlink(tlink);
1475 free_xid(xid);
1476
1477 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1478 if (rc)
1479 return ERR_PTR(rc);
1480 return pntsd;
1481 }
1482
1483 /* 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)1484 struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1485 struct inode *inode, const char *path,
1486 u32 *pacllen, u32 info)
1487 {
1488 struct smb_ntsd *pntsd = NULL;
1489 struct cifsFileInfo *open_file = NULL;
1490
1491 if (inode)
1492 open_file = find_readable_file(CIFS_I(inode), true);
1493 if (!open_file)
1494 return get_cifs_acl_by_path(cifs_sb, path, pacllen, info);
1495
1496 pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1497 cifsFileInfo_put(open_file);
1498 return pntsd;
1499 }
1500
1501 /* Set an ACL on the server */
set_cifs_acl(struct smb_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path,int aclflag)1502 int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
1503 struct inode *inode, const char *path, int aclflag)
1504 {
1505 int oplock = 0;
1506 unsigned int xid;
1507 int rc, access_flags = 0;
1508 struct cifs_tcon *tcon;
1509 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1510 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1511 struct cifs_fid fid;
1512 struct cifs_open_parms oparms;
1513
1514 if (IS_ERR(tlink))
1515 return PTR_ERR(tlink);
1516
1517 tcon = tlink_tcon(tlink);
1518 xid = get_xid();
1519
1520 if (aclflag & CIFS_ACL_OWNER || aclflag & CIFS_ACL_GROUP)
1521 access_flags |= WRITE_OWNER;
1522 if (aclflag & CIFS_ACL_SACL)
1523 access_flags |= SYSTEM_SECURITY;
1524 if (aclflag & CIFS_ACL_DACL)
1525 access_flags |= WRITE_DAC;
1526
1527 oparms = (struct cifs_open_parms) {
1528 .tcon = tcon,
1529 .cifs_sb = cifs_sb,
1530 .desired_access = access_flags,
1531 .create_options = cifs_create_options(cifs_sb, 0),
1532 .disposition = FILE_OPEN,
1533 .path = path,
1534 .fid = &fid,
1535 };
1536
1537 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1538 if (rc) {
1539 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1540 goto out;
1541 }
1542
1543 rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1544 cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1545
1546 CIFSSMBClose(xid, tcon, fid.netfid);
1547 out:
1548 free_xid(xid);
1549 cifs_put_tlink(tlink);
1550 return rc;
1551 }
1552 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1553
1554 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1555 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)1556 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1557 struct inode *inode, bool mode_from_special_sid,
1558 const char *path, const struct cifs_fid *pfid)
1559 {
1560 struct smb_ntsd *pntsd = NULL;
1561 u32 acllen = 0;
1562 int rc = 0;
1563 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1564 struct smb_version_operations *ops;
1565 const u32 info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO;
1566
1567 cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1568
1569 if (IS_ERR(tlink))
1570 return PTR_ERR(tlink);
1571
1572 ops = tlink_tcon(tlink)->ses->server->ops;
1573
1574 if (pfid && (ops->get_acl_by_fid))
1575 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1576 else if (ops->get_acl)
1577 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1578 else {
1579 cifs_put_tlink(tlink);
1580 return -EOPNOTSUPP;
1581 }
1582 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1583 if (IS_ERR(pntsd)) {
1584 rc = PTR_ERR(pntsd);
1585 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1586 } else if (mode_from_special_sid) {
1587 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1588 kfree(pntsd);
1589 } else {
1590 /* get approximated mode from ACL */
1591 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1592 kfree(pntsd);
1593 if (rc)
1594 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1595 }
1596
1597 cifs_put_tlink(tlink);
1598
1599 return rc;
1600 }
1601
1602 /* Convert mode bits to an ACL so we can update the ACL on the server */
1603 int
id_mode_to_cifs_acl(struct inode * inode,const char * path,__u64 * pnmode,kuid_t uid,kgid_t gid)1604 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1605 kuid_t uid, kgid_t gid)
1606 {
1607 int rc = 0;
1608 int aclflag = CIFS_ACL_DACL; /* default flag to set */
1609 __u32 secdesclen = 0;
1610 __u32 nsecdesclen = 0;
1611 __u32 dacloffset = 0;
1612 struct smb_acl *dacl_ptr = NULL;
1613 struct smb_ntsd *pntsd = NULL; /* acl obtained from server */
1614 struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1615 struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
1616 unsigned int sbflags;
1617 struct tcon_link *tlink;
1618 struct smb_version_operations *ops;
1619 bool mode_from_sid, id_from_sid;
1620 const u32 info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO;
1621 bool posix;
1622
1623 tlink = cifs_sb_tlink(cifs_sb);
1624 if (IS_ERR(tlink))
1625 return PTR_ERR(tlink);
1626 posix = tlink_tcon(tlink)->posix_extensions;
1627
1628 ops = tlink_tcon(tlink)->ses->server->ops;
1629
1630 cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1631
1632 /* Get the security descriptor */
1633
1634 if (ops->get_acl == NULL) {
1635 cifs_put_tlink(tlink);
1636 return -EOPNOTSUPP;
1637 }
1638
1639 pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1640 if (IS_ERR(pntsd)) {
1641 rc = PTR_ERR(pntsd);
1642 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1643 cifs_put_tlink(tlink);
1644 return rc;
1645 }
1646
1647 sbflags = cifs_sb_flags(cifs_sb);
1648 mode_from_sid = sbflags & CIFS_MOUNT_MODE_FROM_SID;
1649 id_from_sid = sbflags & CIFS_MOUNT_UID_FROM_ACL;
1650
1651 /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1652 if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1653 if (posix)
1654 nsecdesclen = 1 * sizeof(struct smb_ace);
1655 else if (mode_from_sid)
1656 nsecdesclen = secdesclen + (2 * sizeof(struct smb_ace));
1657 else /* cifsacl */
1658 nsecdesclen = secdesclen + (5 * sizeof(struct smb_ace));
1659 } else { /* chown */
1660 /* When ownership changes, changes new owner sid length could be different */
1661 nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
1662 dacloffset = le32_to_cpu(pntsd->dacloffset);
1663 if (dacloffset) {
1664 dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1665 if (mode_from_sid)
1666 nsecdesclen +=
1667 le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
1668 else /* cifsacl */
1669 nsecdesclen += le16_to_cpu(dacl_ptr->size);
1670 }
1671 }
1672
1673 /*
1674 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1675 * as chmod disables ACEs and set the security descriptor. Allocate
1676 * memory for the smb header, set security descriptor request security
1677 * descriptor parameters, and security descriptor itself
1678 */
1679 nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1680 pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);
1681 if (!pnntsd) {
1682 kfree(pntsd);
1683 cifs_put_tlink(tlink);
1684 return -ENOMEM;
1685 }
1686
1687 rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1688 mode_from_sid, id_from_sid, posix, &aclflag);
1689
1690 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1691
1692 if (ops->set_acl == NULL)
1693 rc = -EOPNOTSUPP;
1694
1695 if (!rc) {
1696 /* Set the security descriptor */
1697 rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1698 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1699 }
1700 cifs_put_tlink(tlink);
1701
1702 kfree(pnntsd);
1703 kfree(pntsd);
1704 return rc;
1705 }
1706
cifs_get_acl(struct mnt_idmap * idmap,struct dentry * dentry,int type)1707 struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
1708 struct dentry *dentry, int type)
1709 {
1710 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1711 struct posix_acl *acl = NULL;
1712 ssize_t rc = -EOPNOTSUPP;
1713 unsigned int xid;
1714 struct super_block *sb = dentry->d_sb;
1715 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1716 struct tcon_link *tlink;
1717 struct cifs_tcon *pTcon;
1718 const char *full_path;
1719 void *page;
1720
1721 tlink = cifs_sb_tlink(cifs_sb);
1722 if (IS_ERR(tlink))
1723 return ERR_CAST(tlink);
1724 pTcon = tlink_tcon(tlink);
1725
1726 xid = get_xid();
1727 page = alloc_dentry_path();
1728
1729 full_path = build_path_from_dentry(dentry, page);
1730 if (IS_ERR(full_path)) {
1731 acl = ERR_CAST(full_path);
1732 goto out;
1733 }
1734
1735 /* return alt name if available as pseudo attr */
1736 switch (type) {
1737 case ACL_TYPE_ACCESS:
1738 if (sb->s_flags & SB_POSIXACL)
1739 rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1740 ACL_TYPE_ACCESS,
1741 cifs_sb->local_nls,
1742 cifs_remap(cifs_sb));
1743 break;
1744
1745 case ACL_TYPE_DEFAULT:
1746 if (sb->s_flags & SB_POSIXACL)
1747 rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1748 ACL_TYPE_DEFAULT,
1749 cifs_sb->local_nls,
1750 cifs_remap(cifs_sb));
1751 break;
1752 }
1753
1754 if (rc < 0) {
1755 if (rc == -EINVAL)
1756 acl = ERR_PTR(-EOPNOTSUPP);
1757 else
1758 acl = ERR_PTR(rc);
1759 }
1760
1761 out:
1762 free_dentry_path(page);
1763 free_xid(xid);
1764 cifs_put_tlink(tlink);
1765 return acl;
1766 #else
1767 return ERR_PTR(-EOPNOTSUPP);
1768 #endif
1769 }
1770
cifs_set_acl(struct mnt_idmap * idmap,struct dentry * dentry,struct posix_acl * acl,int type)1771 int cifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
1772 struct posix_acl *acl, int type)
1773 {
1774 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1775 int rc = -EOPNOTSUPP;
1776 unsigned int xid;
1777 struct super_block *sb = dentry->d_sb;
1778 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1779 struct tcon_link *tlink;
1780 struct cifs_tcon *pTcon;
1781 const char *full_path;
1782 void *page;
1783
1784 tlink = cifs_sb_tlink(cifs_sb);
1785 if (IS_ERR(tlink))
1786 return PTR_ERR(tlink);
1787 pTcon = tlink_tcon(tlink);
1788
1789 xid = get_xid();
1790 page = alloc_dentry_path();
1791
1792 full_path = build_path_from_dentry(dentry, page);
1793 if (IS_ERR(full_path)) {
1794 rc = PTR_ERR(full_path);
1795 goto out;
1796 }
1797
1798 if (!acl)
1799 goto out;
1800
1801 /* return dos attributes as pseudo xattr */
1802 /* return alt name if available as pseudo attr */
1803
1804 /* if proc/fs/cifs/streamstoxattr is set then
1805 search server for EAs or streams to
1806 returns as xattrs */
1807 if (posix_acl_xattr_size(acl->a_count) > CIFSMaxBufSize) {
1808 cifs_dbg(FYI, "size of EA value too large\n");
1809 rc = -EOPNOTSUPP;
1810 goto out;
1811 }
1812
1813 switch (type) {
1814 case ACL_TYPE_ACCESS:
1815 if (sb->s_flags & SB_POSIXACL)
1816 rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1817 ACL_TYPE_ACCESS,
1818 cifs_sb->local_nls,
1819 cifs_remap(cifs_sb));
1820 break;
1821
1822 case ACL_TYPE_DEFAULT:
1823 if (sb->s_flags & SB_POSIXACL)
1824 rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
1825 ACL_TYPE_DEFAULT,
1826 cifs_sb->local_nls,
1827 cifs_remap(cifs_sb));
1828 break;
1829 }
1830
1831 out:
1832 free_dentry_path(page);
1833 free_xid(xid);
1834 cifs_put_tlink(tlink);
1835 return rc;
1836 #else
1837 return -EOPNOTSUPP;
1838 #endif
1839 }
1840