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