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