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 if (prep->datalen > U16_MAX)
72 return -EINVAL;
73
74 /*
75 * If the payload is less than or equal to the size of a pointer, then
76 * an allocation here is wasteful. Just copy the data directly to the
77 * payload.value union member instead.
78 *
79 * With this however, you must check the datalen before trying to
80 * dereference payload.data!
81 */
82 if (prep->datalen <= sizeof(key->payload)) {
83 key->payload.data[0] = NULL;
84 memcpy(&key->payload, prep->data, prep->datalen);
85 } else {
86 payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
87 if (!payload)
88 return -ENOMEM;
89 key->payload.data[0] = payload;
90 }
91
92 key->datalen = prep->datalen;
93 return 0;
94 }
95
96 static inline void
cifs_idmap_key_destroy(struct key * key)97 cifs_idmap_key_destroy(struct key *key)
98 {
99 if (key->datalen > sizeof(key->payload))
100 kfree(key->payload.data[0]);
101 }
102
103 static int
cifs_idmap_key_vet_description(const char * description)104 cifs_idmap_key_vet_description(const char *description)
105 {
106 /*
107 * cifs.idmap descriptions are authority-bearing inputs to the
108 * cifs.idmap upcall helper. Only allow the kernel to create this
109 * type of key using the private root_cred installed in
110 * init_cifs_idmap; reject userspace request_key(2)/add_key(2).
111 */
112 if (current_cred() != root_cred)
113 return -EPERM;
114 return 0;
115 }
116
117 static struct key_type cifs_idmap_key_type = {
118 .name = "cifs.idmap",
119 .vet_description = cifs_idmap_key_vet_description,
120 .instantiate = cifs_idmap_key_instantiate,
121 .destroy = cifs_idmap_key_destroy,
122 .describe = user_describe,
123 };
124
125 static char *
sid_to_key_str(struct smb_sid * sidptr,unsigned int type)126 sid_to_key_str(struct smb_sid *sidptr, unsigned int type)
127 {
128 int i, len;
129 unsigned int saval;
130 char *sidstr, *strptr;
131 unsigned long long id_auth_val;
132
133 /* 3 bytes for prefix */
134 sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
135 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
136 GFP_KERNEL);
137 if (!sidstr)
138 return sidstr;
139
140 strptr = sidstr;
141 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
142 sidptr->revision);
143 strptr += len;
144
145 /* The authority field is a single 48-bit number */
146 id_auth_val = (unsigned long long)sidptr->authority[5];
147 id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
148 id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
149 id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
150 id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
151 id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
152
153 /*
154 * MS-DTYP states that if the authority is >= 2^32, then it should be
155 * expressed as a hex value.
156 */
157 if (id_auth_val <= UINT_MAX)
158 len = sprintf(strptr, "-%llu", id_auth_val);
159 else
160 len = sprintf(strptr, "-0x%llx", id_auth_val);
161
162 strptr += len;
163
164 for (i = 0; i < sidptr->num_subauth; ++i) {
165 saval = le32_to_cpu(sidptr->sub_auth[i]);
166 len = sprintf(strptr, "-%u", saval);
167 strptr += len;
168 }
169
170 return sidstr;
171 }
172
173 /*
174 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
175 * the same returns zero, if they do not match returns non-zero.
176 */
177 static int
compare_sids(const struct smb_sid * ctsid,const struct smb_sid * cwsid)178 compare_sids(const struct smb_sid *ctsid, const struct smb_sid *cwsid)
179 {
180 int i;
181 int num_subauth, num_sat, num_saw;
182
183 if ((!ctsid) || (!cwsid))
184 return 1;
185
186 /* compare the revision */
187 if (ctsid->revision != cwsid->revision) {
188 if (ctsid->revision > cwsid->revision)
189 return 1;
190 else
191 return -1;
192 }
193
194 /* compare all of the six auth values */
195 for (i = 0; i < NUM_AUTHS; ++i) {
196 if (ctsid->authority[i] != cwsid->authority[i]) {
197 if (ctsid->authority[i] > cwsid->authority[i])
198 return 1;
199 else
200 return -1;
201 }
202 }
203
204 /* compare all of the subauth values if any */
205 num_sat = ctsid->num_subauth;
206 num_saw = cwsid->num_subauth;
207 num_subauth = min(num_sat, num_saw);
208 if (num_subauth) {
209 for (i = 0; i < num_subauth; ++i) {
210 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
211 if (le32_to_cpu(ctsid->sub_auth[i]) >
212 le32_to_cpu(cwsid->sub_auth[i]))
213 return 1;
214 else
215 return -1;
216 }
217 }
218 }
219
220 return 0; /* sids compare/match */
221 }
222
223 static bool
is_well_known_sid(const struct smb_sid * psid,uint32_t * puid,bool is_group)224 is_well_known_sid(const struct smb_sid *psid, uint32_t *puid, bool is_group)
225 {
226 int i;
227 int num_subauth;
228 const struct smb_sid *pwell_known_sid;
229
230 if (!psid || (puid == NULL))
231 return false;
232
233 num_subauth = psid->num_subauth;
234
235 /* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
236 if (num_subauth == 2) {
237 if (is_group)
238 pwell_known_sid = &sid_unix_groups;
239 else
240 pwell_known_sid = &sid_unix_users;
241 } else if (num_subauth == 3) {
242 if (is_group)
243 pwell_known_sid = &sid_unix_NFS_groups;
244 else
245 pwell_known_sid = &sid_unix_NFS_users;
246 } else
247 return false;
248
249 /* compare the revision */
250 if (psid->revision != pwell_known_sid->revision)
251 return false;
252
253 /* compare all of the six auth values */
254 for (i = 0; i < NUM_AUTHS; ++i) {
255 if (psid->authority[i] != pwell_known_sid->authority[i]) {
256 cifs_dbg(FYI, "auth %d did not match\n", i);
257 return false;
258 }
259 }
260
261 if (num_subauth == 2) {
262 if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
263 return false;
264
265 *puid = le32_to_cpu(psid->sub_auth[1]);
266 } else /* 3 subauths, ie Windows/Mac style */ {
267 *puid = le32_to_cpu(psid->sub_auth[0]);
268 if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
269 (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
270 return false;
271
272 *puid = le32_to_cpu(psid->sub_auth[2]);
273 }
274
275 cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
276 return true; /* well known sid found, uid returned */
277 }
278
279 static __u16
cifs_copy_sid(struct smb_sid * dst,const struct smb_sid * src)280 cifs_copy_sid(struct smb_sid *dst, const struct smb_sid *src)
281 {
282 int i;
283 __u16 size = 1 + 1 + 6;
284
285 dst->revision = src->revision;
286 dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
287 for (i = 0; i < NUM_AUTHS; ++i)
288 dst->authority[i] = src->authority[i];
289 for (i = 0; i < dst->num_subauth; ++i)
290 dst->sub_auth[i] = src->sub_auth[i];
291 size += (dst->num_subauth * 4);
292
293 return size;
294 }
295
parse_sid(const struct smb_sid * psid,const char * end_of_acl)296 static int parse_sid(const struct smb_sid *psid, const char *end_of_acl)
297 {
298 unsigned int sid_len;
299
300 /* SID must contain the fixed header before num_subauth is trusted. */
301 if (end_of_acl < (const char *)psid + CIFS_SID_BASE_SIZE) {
302 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
303 return -EINVAL;
304 }
305 if (psid->num_subauth > SID_MAX_SUB_AUTHORITIES) {
306 cifs_dbg(VFS, "SID contains too many subauthorities %u\n",
307 psid->num_subauth);
308 return -EINVAL;
309 }
310
311 sid_len = CIFS_SID_BASE_SIZE + psid->num_subauth * sizeof(__le32);
312 if (end_of_acl < (const char *)psid + sid_len) {
313 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
314 return -EINVAL;
315 }
316
317 #ifdef CONFIG_CIFS_DEBUG2
318 if (psid->num_subauth) {
319 int i;
320
321 cifs_dbg(FYI, "SID revision %d num_auth %d\n",
322 psid->revision, psid->num_subauth);
323
324 for (i = 0; i < psid->num_subauth; i++) {
325 cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
326 i, le32_to_cpu(psid->sub_auth[i]));
327 }
328
329 cifs_dbg(FYI, "RID 0x%x\n",
330 le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]));
331 }
332 #endif
333
334 return 0;
335 }
336
sid_from_sd(const struct smb_ntsd * pntsd,__u32 secdesclen,__u32 sid_offset,struct smb_sid ** sid)337 static int sid_from_sd(const struct smb_ntsd *pntsd, __u32 secdesclen,
338 __u32 sid_offset, struct smb_sid **sid)
339 {
340 struct smb_sid *psid;
341 char *end_of_acl;
342
343 if (secdesclen < sizeof(struct smb_ntsd)) {
344 cifs_dbg(VFS, "ACL too small to parse security descriptor\n");
345 return -EINVAL;
346 }
347 end_of_acl = (char *)pntsd + secdesclen;
348
349 if (sid_offset < sizeof(struct smb_ntsd) ||
350 sid_offset > secdesclen - CIFS_SID_BASE_SIZE) {
351 cifs_dbg(VFS, "Server returned illegal SID offset\n");
352 return -EINVAL;
353 }
354
355 psid = (struct smb_sid *)((char *)pntsd + sid_offset);
356 if (parse_sid(psid, end_of_acl))
357 return -EINVAL;
358
359 *sid = psid;
360 return 0;
361 }
362
363 static int
id_to_sid(unsigned int cid,uint sidtype,struct smb_sid * ssid)364 id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
365 {
366 int rc;
367 struct key *sidkey;
368 struct smb_sid *ksid;
369 unsigned int ksid_size;
370 char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
371 const struct cred *saved_cred;
372
373 rc = snprintf(desc, sizeof(desc), "%ci:%u",
374 sidtype == SIDOWNER ? 'o' : 'g', cid);
375 if (rc >= sizeof(desc))
376 return -EINVAL;
377
378 rc = 0;
379 saved_cred = override_creds(root_cred);
380 sidkey = request_key(&cifs_idmap_key_type, desc, "");
381 if (IS_ERR(sidkey)) {
382 rc = -EINVAL;
383 cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
384 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
385 goto out_revert_creds;
386 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
387 rc = smb_EIO1(smb_eio_trace_malformed_sid_key, sidkey->datalen);
388 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
389 __func__, sidkey->datalen);
390 goto invalidate_key;
391 }
392
393 /*
394 * A sid is usually too large to be embedded in payload.value, but if
395 * there are no subauthorities and the host has 8-byte pointers, then
396 * it could be.
397 */
398 ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
399 (struct smb_sid *)&sidkey->payload :
400 (struct smb_sid *)sidkey->payload.data[0];
401
402 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
403 if (ksid_size > sidkey->datalen) {
404 rc = smb_EIO2(smb_eio_trace_malformed_ksid_key,
405 ksid_size, sidkey->datalen);
406 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
407 __func__, sidkey->datalen, ksid_size);
408 goto invalidate_key;
409 }
410
411 cifs_copy_sid(ssid, ksid);
412 out_key_put:
413 key_put(sidkey);
414 out_revert_creds:
415 revert_creds(saved_cred);
416 return rc;
417
418 invalidate_key:
419 key_invalidate(sidkey);
420 goto out_key_put;
421 }
422
423 int
sid_to_id(struct cifs_sb_info * cifs_sb,struct smb_sid * psid,struct cifs_fattr * fattr,uint sidtype)424 sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
425 struct cifs_fattr *fattr, uint sidtype)
426 {
427 struct key *sidkey;
428 char *sidstr;
429 const struct cred *saved_cred;
430 kuid_t fuid = cifs_sb->ctx->linux_uid;
431 kgid_t fgid = cifs_sb->ctx->linux_gid;
432
433 /*
434 * If we have too many subauthorities, then something is really wrong.
435 * Just return an error.
436 */
437 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
438 cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
439 __func__, psid->num_subauth);
440 return smb_EIO2(smb_eio_trace_sid_too_many_auth,
441 psid->num_subauth, SID_MAX_SUB_AUTHORITIES);
442 }
443
444 if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_UID_FROM_ACL) ||
445 (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
446 uint32_t unix_id;
447 bool is_group;
448
449 if (sidtype != SIDOWNER)
450 is_group = true;
451 else
452 is_group = false;
453
454 if (is_well_known_sid(psid, &unix_id, is_group) == false)
455 goto try_upcall_to_get_id;
456
457 if (is_group) {
458 kgid_t gid;
459 gid_t id;
460
461 id = (gid_t)unix_id;
462 gid = make_kgid(&init_user_ns, id);
463 if (gid_valid(gid)) {
464 fgid = gid;
465 goto got_valid_id;
466 }
467 } else {
468 kuid_t uid;
469 uid_t id;
470
471 id = (uid_t)unix_id;
472 uid = make_kuid(&init_user_ns, id);
473 if (uid_valid(uid)) {
474 fuid = uid;
475 goto got_valid_id;
476 }
477 }
478 /* If unable to find uid/gid easily from SID try via upcall */
479 }
480
481 try_upcall_to_get_id:
482 sidstr = sid_to_key_str(psid, sidtype);
483 if (!sidstr)
484 return -ENOMEM;
485
486 saved_cred = override_creds(root_cred);
487 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
488 if (IS_ERR(sidkey)) {
489 cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
490 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
491 goto out_revert_creds;
492 }
493
494 /*
495 * FIXME: Here we assume that uid_t and gid_t are same size. It's
496 * probably a safe assumption but might be better to check based on
497 * sidtype.
498 */
499 BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
500 if (sidkey->datalen != sizeof(uid_t)) {
501 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
502 __func__, sidkey->datalen);
503 key_invalidate(sidkey);
504 goto out_key_put;
505 }
506
507 if (sidtype == SIDOWNER) {
508 kuid_t uid;
509 uid_t id;
510 memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
511 uid = make_kuid(&init_user_ns, id);
512 if (uid_valid(uid))
513 fuid = uid;
514 } else {
515 kgid_t gid;
516 gid_t id;
517 memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
518 gid = make_kgid(&init_user_ns, id);
519 if (gid_valid(gid))
520 fgid = gid;
521 }
522
523 out_key_put:
524 key_put(sidkey);
525 out_revert_creds:
526 revert_creds(saved_cred);
527 kfree(sidstr);
528
529 /*
530 * Note that we return 0 here unconditionally. If the mapping
531 * fails then we just fall back to using the ctx->linux_uid/linux_gid.
532 */
533 got_valid_id:
534 if (sidtype == SIDOWNER)
535 fattr->cf_uid = fuid;
536 else
537 fattr->cf_gid = fgid;
538
539 return 0;
540 }
541
542 int
init_cifs_idmap(void)543 init_cifs_idmap(void)
544 {
545 struct cred *cred;
546 struct key *keyring;
547 int ret;
548
549 cifs_dbg(FYI, "Registering the %s key type\n",
550 cifs_idmap_key_type.name);
551
552 /* create an override credential set with a special thread keyring in
553 * which requests are cached
554 *
555 * this is used to prevent malicious redirections from being installed
556 * with add_key().
557 */
558 cred = prepare_kernel_cred(&init_task);
559 if (!cred)
560 return -ENOMEM;
561
562 keyring = keyring_alloc(".cifs_idmap",
563 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
564 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
565 KEY_USR_VIEW | KEY_USR_READ,
566 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
567 if (IS_ERR(keyring)) {
568 ret = PTR_ERR(keyring);
569 goto failed_put_cred;
570 }
571
572 ret = register_key_type(&cifs_idmap_key_type);
573 if (ret < 0)
574 goto failed_put_key;
575
576 /* instruct request_key() to use this special keyring as a cache for
577 * the results it looks up */
578 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
579 cred->thread_keyring = keyring;
580 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
581 root_cred = cred;
582
583 cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
584 return 0;
585
586 failed_put_key:
587 key_put(keyring);
588 failed_put_cred:
589 put_cred(cred);
590 return ret;
591 }
592
593 void
exit_cifs_idmap(void)594 exit_cifs_idmap(void)
595 {
596 key_revoke(root_cred->thread_keyring);
597 unregister_key_type(&cifs_idmap_key_type);
598 put_cred(root_cred);
599 cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
600 }
601
602 /* 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,__u32 secdesclen,__u32 * pnsecdesclen,struct smb_sid * pownersid,struct smb_sid * pgrpsid)603 static int copy_sec_desc(const struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
604 __u32 sidsoffset, __u32 secdesclen,
605 __u32 *pnsecdesclen, struct smb_sid *pownersid,
606 struct smb_sid *pgrpsid)
607 {
608 struct smb_sid *owner_sid_ptr, *group_sid_ptr;
609 struct smb_sid *nowner_sid_ptr, *ngroup_sid_ptr;
610 int rc;
611
612 /* copy security descriptor control portion */
613 pnntsd->revision = pntsd->revision;
614 pnntsd->type = pntsd->type;
615 pnntsd->dacloffset = cpu_to_le32(sizeof(struct smb_ntsd));
616 pnntsd->sacloffset = 0;
617 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
618 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct smb_sid));
619
620 /* copy owner sid */
621 if (pownersid) {
622 owner_sid_ptr = pownersid;
623 } else {
624 rc = sid_from_sd(pntsd, secdesclen,
625 le32_to_cpu(pntsd->osidoffset), &owner_sid_ptr);
626 if (rc)
627 return rc;
628 }
629 nowner_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset);
630 cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
631
632 /* copy group sid */
633 if (pgrpsid) {
634 group_sid_ptr = pgrpsid;
635 } else {
636 rc = sid_from_sd(pntsd, secdesclen,
637 le32_to_cpu(pntsd->gsidoffset), &group_sid_ptr);
638 if (rc)
639 return rc;
640 }
641 ngroup_sid_ptr = (struct smb_sid *)((char *)pnntsd + sidsoffset +
642 sizeof(struct smb_sid));
643 cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
644
645 *pnsecdesclen = sidsoffset + (2 * sizeof(struct smb_sid));
646 return 0;
647 }
648
649 /*
650 change posix mode to reflect permissions
651 pmode is the existing mode (we only want to overwrite part of this
652 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
653 */
access_flags_to_mode(__le32 ace_flags,int type,umode_t * pmode,umode_t * pdenied,umode_t mask)654 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
655 umode_t *pdenied, umode_t mask)
656 {
657 __u32 flags = le32_to_cpu(ace_flags);
658 /*
659 * Do not assume "preferred" or "canonical" order.
660 * The first DENY or ALLOW ACE which matches perfectly is
661 * the permission to be used. Once allowed or denied, same
662 * permission in later ACEs do not matter.
663 */
664
665 /* If not already allowed, deny these bits */
666 if (type == ACCESS_DENIED) {
667 if (flags & GENERIC_ALL &&
668 !(*pmode & mask & 0777))
669 *pdenied |= mask & 0777;
670
671 if (((flags & GENERIC_WRITE) ||
672 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
673 !(*pmode & mask & 0222))
674 *pdenied |= mask & 0222;
675
676 if (((flags & GENERIC_READ) ||
677 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
678 !(*pmode & mask & 0444))
679 *pdenied |= mask & 0444;
680
681 if (((flags & GENERIC_EXECUTE) ||
682 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
683 !(*pmode & mask & 0111))
684 *pdenied |= mask & 0111;
685
686 return;
687 } else if (type != ACCESS_ALLOWED) {
688 cifs_dbg(VFS, "unknown access control type %d\n", type);
689 return;
690 }
691 /* else ACCESS_ALLOWED type */
692
693 if ((flags & GENERIC_ALL) &&
694 !(*pdenied & mask & 0777)) {
695 *pmode |= mask & 0777;
696 cifs_dbg(NOISY, "all perms\n");
697 return;
698 }
699
700 if (((flags & GENERIC_WRITE) ||
701 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) &&
702 !(*pdenied & mask & 0222))
703 *pmode |= mask & 0222;
704
705 if (((flags & GENERIC_READ) ||
706 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS)) &&
707 !(*pdenied & mask & 0444))
708 *pmode |= mask & 0444;
709
710 if (((flags & GENERIC_EXECUTE) ||
711 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) &&
712 !(*pdenied & mask & 0111))
713 *pmode |= mask & 0111;
714
715 /* If DELETE_CHILD is set only on an owner ACE, set sticky bit */
716 if (flags & FILE_DELETE_CHILD) {
717 if (mask == ACL_OWNER_MASK) {
718 if (!(*pdenied & 01000))
719 *pmode |= 01000;
720 } else if (!(*pdenied & 01000)) {
721 *pmode &= ~01000;
722 *pdenied |= 01000;
723 }
724 }
725
726 cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
727 return;
728 }
729
730 /*
731 Generate access flags to reflect permissions mode is the existing mode.
732 This function is called for every ACE in the DACL whose SID matches
733 with either owner or group or everyone.
734 */
735
mode_to_access_flags(umode_t mode,umode_t bits_to_use,__u32 * pace_flags)736 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
737 __u32 *pace_flags)
738 {
739 /* reset access mask */
740 *pace_flags = 0x0;
741
742 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
743 mode &= bits_to_use;
744
745 /* check for R/W/X UGO since we do not know whose flags
746 is this but we have cleared all the bits sans RWX for
747 either user or group or other as per bits_to_use */
748 if (mode & S_IRUGO)
749 *pace_flags |= SET_FILE_READ_RIGHTS;
750 if (mode & S_IWUGO)
751 *pace_flags |= SET_FILE_WRITE_RIGHTS;
752 if (mode & S_IXUGO)
753 *pace_flags |= SET_FILE_EXEC_RIGHTS;
754
755 cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
756 mode, *pace_flags);
757 return;
758 }
759
cifs_copy_ace(struct smb_ace * dst,struct smb_ace * src,struct smb_sid * psid)760 static __u16 cifs_copy_ace(struct smb_ace *dst, struct smb_ace *src, struct smb_sid *psid)
761 {
762 __u16 size = 1 + 1 + 2 + 4;
763
764 dst->type = src->type;
765 dst->flags = src->flags;
766 dst->access_req = src->access_req;
767
768 /* Check if there's a replacement sid specified */
769 if (psid)
770 size += cifs_copy_sid(&dst->sid, psid);
771 else
772 size += cifs_copy_sid(&dst->sid, &src->sid);
773
774 dst->size = cpu_to_le16(size);
775
776 return size;
777 }
778
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)779 static __u16 fill_ace_for_sid(struct smb_ace *pntace,
780 const struct smb_sid *psid, __u64 nmode,
781 umode_t bits, __u8 access_type,
782 bool allow_delete_child)
783 {
784 int i;
785 __u16 size = 0;
786 __u32 access_req = 0;
787
788 pntace->type = access_type;
789 pntace->flags = 0x0;
790 mode_to_access_flags(nmode, bits, &access_req);
791
792 if (access_type == ACCESS_ALLOWED && allow_delete_child)
793 access_req |= FILE_DELETE_CHILD;
794
795 if (access_type == ACCESS_ALLOWED && !access_req)
796 access_req = SET_MINIMUM_RIGHTS;
797 else if (access_type == ACCESS_DENIED)
798 access_req &= ~SET_MINIMUM_RIGHTS;
799
800 pntace->access_req = cpu_to_le32(access_req);
801
802 pntace->sid.revision = psid->revision;
803 pntace->sid.num_subauth = psid->num_subauth;
804 for (i = 0; i < NUM_AUTHS; i++)
805 pntace->sid.authority[i] = psid->authority[i];
806 for (i = 0; i < psid->num_subauth; i++)
807 pntace->sid.sub_auth[i] = psid->sub_auth[i];
808
809 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
810 pntace->size = cpu_to_le16(size);
811
812 return size;
813 }
814
815
816 #ifdef CONFIG_CIFS_DEBUG2
dump_ace(struct smb_ace * pace,char * end_of_acl)817 static void dump_ace(struct smb_ace *pace, char *end_of_acl)
818 {
819 int num_subauth;
820
821 /* validate that we do not go past end of acl */
822
823 if (le16_to_cpu(pace->size) < 16) {
824 cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
825 return;
826 }
827
828 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
829 cifs_dbg(VFS, "ACL too small to parse ACE\n");
830 return;
831 }
832
833 num_subauth = pace->sid.num_subauth;
834 if (num_subauth) {
835 int i;
836 cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
837 pace->sid.revision, pace->sid.num_subauth, pace->type,
838 pace->flags, le16_to_cpu(pace->size));
839 for (i = 0; i < num_subauth; ++i) {
840 cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
841 i, le32_to_cpu(pace->sid.sub_auth[i]));
842 }
843
844 /* BB add length check to make sure that we do not have huge
845 num auths and therefore go off the end */
846 }
847
848 return;
849 }
850 #endif
851
validate_dacl(struct smb_acl * pdacl,char * end_of_acl)852 static int validate_dacl(struct smb_acl *pdacl, char *end_of_acl)
853 {
854 int i, ace_hdr_size, ace_size, min_ace_size;
855 u16 dacl_size, num_aces;
856 char *acl_base, *end_of_dacl;
857 struct smb_ace *pace;
858
859 if (!pdacl)
860 return 0;
861
862 if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl)) {
863 cifs_dbg(VFS, "ACL too small to parse DACL\n");
864 return -EINVAL;
865 }
866
867 dacl_size = le16_to_cpu(pdacl->size);
868 if (dacl_size < sizeof(struct smb_acl) ||
869 end_of_acl < (char *)pdacl + dacl_size) {
870 cifs_dbg(VFS, "ACL too small to parse DACL\n");
871 return -EINVAL;
872 }
873
874 num_aces = le16_to_cpu(pdacl->num_aces);
875 if (!num_aces)
876 return 0;
877
878 ace_hdr_size = offsetof(struct smb_ace, sid) +
879 offsetof(struct smb_sid, sub_auth);
880 min_ace_size = ace_hdr_size + sizeof(__le32);
881 if (num_aces > (dacl_size - sizeof(struct smb_acl)) / min_ace_size) {
882 cifs_dbg(VFS, "ACL too small to parse DACL\n");
883 return -EINVAL;
884 }
885
886 end_of_dacl = (char *)pdacl + dacl_size;
887 acl_base = (char *)pdacl;
888 ace_size = sizeof(struct smb_acl);
889
890 for (i = 0; i < num_aces; ++i) {
891 if (end_of_dacl - acl_base < ace_size) {
892 cifs_dbg(VFS, "ACL too small to parse ACE\n");
893 return -EINVAL;
894 }
895
896 pace = (struct smb_ace *)(acl_base + ace_size);
897 acl_base = (char *)pace;
898
899 if (end_of_dacl - acl_base < ace_hdr_size ||
900 pace->sid.num_subauth == 0 ||
901 pace->sid.num_subauth > SID_MAX_SUB_AUTHORITIES) {
902 cifs_dbg(VFS, "ACL too small to parse ACE\n");
903 return -EINVAL;
904 }
905
906 ace_size = ace_hdr_size + sizeof(__le32) * pace->sid.num_subauth;
907 if (end_of_dacl - acl_base < ace_size ||
908 le16_to_cpu(pace->size) < ace_size) {
909 cifs_dbg(VFS, "ACL too small to parse ACE\n");
910 return -EINVAL;
911 }
912
913 ace_size = le16_to_cpu(pace->size);
914 if (end_of_dacl - acl_base < ace_size) {
915 cifs_dbg(VFS, "ACL too small to parse ACE\n");
916 return -EINVAL;
917 }
918 }
919
920 return 0;
921 }
922
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)923 static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
924 struct smb_sid *pownersid, struct smb_sid *pgrpsid,
925 struct cifs_fattr *fattr, bool mode_from_special_sid)
926 {
927 int i;
928 u16 num_aces = 0;
929 int acl_size;
930 char *acl_base;
931 struct smb_ace **ppace;
932
933 /* BB need to add parm so we can store the SID BB */
934
935 if (!pdacl) {
936 /* no DACL in the security descriptor, set
937 all the permissions for user/group/other */
938 fattr->cf_mode |= 0777;
939 return;
940 }
941
942 if (validate_dacl(pdacl, end_of_acl))
943 return;
944
945 cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
946 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
947 le16_to_cpu(pdacl->num_aces));
948
949 /* reset rwx permissions for user/group/other.
950 Also, if num_aces is 0 i.e. DACL has no ACEs,
951 user/group/other have no permissions */
952 fattr->cf_mode &= ~(0777);
953
954 acl_base = (char *)pdacl;
955 acl_size = sizeof(struct smb_acl);
956
957 num_aces = le16_to_cpu(pdacl->num_aces);
958 if (num_aces > 0) {
959 umode_t denied_mode = 0;
960
961 ppace = kmalloc_objs(struct smb_ace *, num_aces);
962 if (!ppace)
963 return;
964
965 for (i = 0; i < num_aces; ++i) {
966 ppace[i] = (struct smb_ace *) (acl_base + acl_size);
967
968 #ifdef CONFIG_CIFS_DEBUG2
969 dump_ace(ppace[i],
970 (char *)pdacl + le16_to_cpu(pdacl->size));
971 #endif
972 if (mode_from_special_sid &&
973 ppace[i]->sid.num_subauth >= 3 &&
974 (compare_sids(&(ppace[i]->sid),
975 &sid_unix_NFS_mode) == 0)) {
976 /*
977 * Full permissions are:
978 * 07777 = S_ISUID | S_ISGID | S_ISVTX |
979 * S_IRWXU | S_IRWXG | S_IRWXO
980 */
981 fattr->cf_mode &= ~07777;
982 fattr->cf_mode |=
983 le32_to_cpu(ppace[i]->sid.sub_auth[2]) & 07777;
984 break;
985 } else {
986 if (compare_sids(&(ppace[i]->sid), pownersid) == 0) {
987 access_flags_to_mode(ppace[i]->access_req,
988 ppace[i]->type,
989 &fattr->cf_mode,
990 &denied_mode,
991 ACL_OWNER_MASK);
992 } else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) {
993 access_flags_to_mode(ppace[i]->access_req,
994 ppace[i]->type,
995 &fattr->cf_mode,
996 &denied_mode,
997 ACL_GROUP_MASK);
998 } else if ((compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) ||
999 (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)) {
1000 access_flags_to_mode(ppace[i]->access_req,
1001 ppace[i]->type,
1002 &fattr->cf_mode,
1003 &denied_mode,
1004 ACL_EVERYONE_MASK);
1005 }
1006 }
1007
1008
1009 /* memcpy((void *)(&(cifscred->aces[i])),
1010 (void *)ppace[i],
1011 sizeof(struct smb_ace)); */
1012
1013 acl_base = (char *)ppace[i];
1014 acl_size = le16_to_cpu(ppace[i]->size);
1015 }
1016
1017 kfree(ppace);
1018 }
1019
1020 return;
1021 }
1022
setup_authusers_ACE(struct smb_ace * pntace)1023 unsigned int setup_authusers_ACE(struct smb_ace *pntace)
1024 {
1025 int i;
1026 unsigned int ace_size = 20;
1027
1028 pntace->type = ACCESS_ALLOWED_ACE_TYPE;
1029 pntace->flags = 0x0;
1030 pntace->access_req = cpu_to_le32(GENERIC_ALL);
1031 pntace->sid.num_subauth = 1;
1032 pntace->sid.revision = 1;
1033 for (i = 0; i < NUM_AUTHS; i++)
1034 pntace->sid.authority[i] = sid_authusers.authority[i];
1035
1036 pntace->sid.sub_auth[0] = sid_authusers.sub_auth[0];
1037
1038 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
1039 pntace->size = cpu_to_le16(ace_size);
1040 return ace_size;
1041 }
1042
1043 /*
1044 * Fill in the special SID based on the mode. See
1045 * https://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
1046 */
setup_special_mode_ACE(struct smb_ace * pntace,bool posix,__u64 nmode)1047 unsigned int setup_special_mode_ACE(struct smb_ace *pntace,
1048 bool posix,
1049 __u64 nmode)
1050 {
1051 int i;
1052 unsigned int ace_size = 28;
1053
1054 if (posix)
1055 pntace->type = ACCESS_ALLOWED_ACE_TYPE;
1056 else
1057 pntace->type = ACCESS_DENIED_ACE_TYPE;
1058 pntace->flags = 0x0;
1059 pntace->access_req = 0;
1060 pntace->sid.num_subauth = 3;
1061 pntace->sid.revision = 1;
1062 for (i = 0; i < NUM_AUTHS; i++)
1063 pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
1064
1065 pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
1066 pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
1067 pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
1068
1069 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
1070 pntace->size = cpu_to_le16(ace_size);
1071 return ace_size;
1072 }
1073
setup_special_user_owner_ACE(struct smb_ace * pntace)1074 unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace)
1075 {
1076 int i;
1077 unsigned int ace_size = 28;
1078
1079 pntace->type = ACCESS_ALLOWED_ACE_TYPE;
1080 pntace->flags = 0x0;
1081 pntace->access_req = cpu_to_le32(GENERIC_ALL);
1082 pntace->sid.num_subauth = 3;
1083 pntace->sid.revision = 1;
1084 for (i = 0; i < NUM_AUTHS; i++)
1085 pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
1086
1087 pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
1088 pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
1089 pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
1090
1091 /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
1092 pntace->size = cpu_to_le16(ace_size);
1093 return ace_size;
1094 }
1095
populate_new_aces(char * nacl_base,struct smb_sid * pownersid,struct smb_sid * pgrpsid,__u64 * pnmode,u16 * pnum_aces,u32 * pnsize,bool modefromsid,bool posix)1096 static void populate_new_aces(char *nacl_base,
1097 struct smb_sid *pownersid,
1098 struct smb_sid *pgrpsid,
1099 __u64 *pnmode, u16 *pnum_aces, u32 *pnsize,
1100 bool modefromsid,
1101 bool posix)
1102 {
1103 __u64 nmode;
1104 u16 num_aces = 0;
1105 u32 nsize = 0;
1106 __u64 user_mode;
1107 __u64 group_mode;
1108 __u64 other_mode;
1109 __u64 deny_user_mode = 0;
1110 __u64 deny_group_mode = 0;
1111 bool sticky_set = false;
1112 struct smb_ace *pnntace = NULL;
1113
1114 nmode = *pnmode;
1115 num_aces = *pnum_aces;
1116 nsize = *pnsize;
1117
1118 if (modefromsid || posix) {
1119 pnntace = (struct smb_ace *) (nacl_base + nsize);
1120 nsize += setup_special_mode_ACE(pnntace, posix, nmode);
1121 num_aces++;
1122 if (modefromsid) {
1123 pnntace = (struct smb_ace *) (nacl_base + nsize);
1124 nsize += setup_authusers_ACE(pnntace);
1125 num_aces++;
1126 }
1127 goto set_size;
1128 }
1129
1130 /*
1131 * We'll try to keep the mode as requested by the user.
1132 * But in cases where we cannot meaningfully convert that
1133 * into ACL, return back the updated mode, so that it is
1134 * updated in the inode.
1135 */
1136
1137 if (!memcmp(pownersid, pgrpsid, sizeof(struct smb_sid))) {
1138 /*
1139 * Case when owner and group SIDs are the same.
1140 * Set the more restrictive of the two modes.
1141 */
1142 user_mode = nmode & (nmode << 3) & 0700;
1143 group_mode = nmode & (nmode >> 3) & 0070;
1144 } else {
1145 user_mode = nmode & 0700;
1146 group_mode = nmode & 0070;
1147 }
1148
1149 other_mode = nmode & 0007;
1150
1151 /* We need DENY ACE when the perm is more restrictive than the next sets. */
1152 deny_user_mode = ~(user_mode) & ((group_mode << 3) | (other_mode << 6)) & 0700;
1153 deny_group_mode = ~(group_mode) & (other_mode << 3) & 0070;
1154
1155 *pnmode = user_mode | group_mode | other_mode | (nmode & ~0777);
1156
1157 /* This tells if we should allow delete child for group and everyone. */
1158 if (nmode & 01000)
1159 sticky_set = true;
1160
1161 if (deny_user_mode) {
1162 pnntace = (struct smb_ace *) (nacl_base + nsize);
1163 nsize += fill_ace_for_sid(pnntace, pownersid, deny_user_mode,
1164 0700, ACCESS_DENIED, false);
1165 num_aces++;
1166 }
1167
1168 /* Group DENY ACE does not conflict with owner ALLOW ACE. Keep in preferred order*/
1169 if (deny_group_mode && !(deny_group_mode & (user_mode >> 3))) {
1170 pnntace = (struct smb_ace *) (nacl_base + nsize);
1171 nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1172 0070, ACCESS_DENIED, false);
1173 num_aces++;
1174 }
1175
1176 pnntace = (struct smb_ace *) (nacl_base + nsize);
1177 nsize += fill_ace_for_sid(pnntace, pownersid, user_mode,
1178 0700, ACCESS_ALLOWED, true);
1179 num_aces++;
1180
1181 /* Group DENY ACE conflicts with owner ALLOW ACE. So keep it after. */
1182 if (deny_group_mode && (deny_group_mode & (user_mode >> 3))) {
1183 pnntace = (struct smb_ace *) (nacl_base + nsize);
1184 nsize += fill_ace_for_sid(pnntace, pgrpsid, deny_group_mode,
1185 0070, ACCESS_DENIED, false);
1186 num_aces++;
1187 }
1188
1189 pnntace = (struct smb_ace *) (nacl_base + nsize);
1190 nsize += fill_ace_for_sid(pnntace, pgrpsid, group_mode,
1191 0070, ACCESS_ALLOWED, !sticky_set);
1192 num_aces++;
1193
1194 pnntace = (struct smb_ace *) (nacl_base + nsize);
1195 nsize += fill_ace_for_sid(pnntace, &sid_everyone, other_mode,
1196 0007, ACCESS_ALLOWED, !sticky_set);
1197 num_aces++;
1198
1199 set_size:
1200 *pnum_aces = num_aces;
1201 *pnsize = nsize;
1202 }
1203
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,int * aclflag,u16 * pnsize)1204 static int replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
1205 struct smb_sid *pownersid, struct smb_sid *pgrpsid,
1206 struct smb_sid *pnownersid, struct smb_sid *pngrpsid,
1207 int *aclflag, u16 *pnsize)
1208 {
1209 int i;
1210 u16 size = 0;
1211 struct smb_ace *pntace = NULL;
1212 char *acl_base = NULL;
1213 u16 src_num_aces = 0;
1214 u32 nsize = 0;
1215 struct smb_ace *pnntace = NULL;
1216 char *nacl_base = NULL;
1217 u16 ace_size = 0;
1218
1219 acl_base = (char *)pdacl;
1220 size = sizeof(struct smb_acl);
1221 src_num_aces = le16_to_cpu(pdacl->num_aces);
1222
1223 nacl_base = (char *)pndacl;
1224 nsize = sizeof(struct smb_acl);
1225
1226 /* Go through all the ACEs */
1227 for (i = 0; i < src_num_aces; ++i) {
1228 pntace = (struct smb_ace *) (acl_base + size);
1229 pnntace = (struct smb_ace *) (nacl_base + nsize);
1230
1231 if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0) {
1232 ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
1233 *aclflag |= CIFS_ACL_DACL;
1234 } else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0) {
1235 ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
1236 *aclflag |= CIFS_ACL_DACL;
1237 } else {
1238 ace_size = cifs_copy_ace(pnntace, pntace, NULL);
1239 }
1240
1241 size += le16_to_cpu(pntace->size);
1242 nsize += ace_size;
1243 if (nsize > U16_MAX)
1244 return -EOVERFLOW;
1245 }
1246
1247 *pnsize = nsize;
1248 return 0;
1249 }
1250
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)1251 static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
1252 struct smb_sid *pownersid, struct smb_sid *pgrpsid,
1253 __u64 *pnmode, bool mode_from_sid, bool posix)
1254 {
1255 int i;
1256 u16 size = 0;
1257 struct smb_ace *pntace = NULL;
1258 char *acl_base = NULL;
1259 u16 src_num_aces = 0;
1260 u32 nsize = 0;
1261 struct smb_ace *pnntace = NULL;
1262 char *nacl_base = NULL;
1263 u16 num_aces = 0;
1264 bool new_aces_set = false;
1265
1266 /* Assuming that pndacl and pnmode are never NULL */
1267 nacl_base = (char *)pndacl;
1268 nsize = sizeof(struct smb_acl);
1269
1270 /* If pdacl is NULL, we don't have a src. Simply populate new ACL. */
1271 if (!pdacl || posix) {
1272 populate_new_aces(nacl_base,
1273 pownersid, pgrpsid,
1274 pnmode, &num_aces, &nsize,
1275 mode_from_sid, posix);
1276 goto finalize_dacl;
1277 }
1278
1279 acl_base = (char *)pdacl;
1280 size = sizeof(struct smb_acl);
1281 src_num_aces = le16_to_cpu(pdacl->num_aces);
1282
1283 /* Retain old ACEs which we can retain */
1284 for (i = 0; i < src_num_aces; ++i) {
1285 pntace = (struct smb_ace *) (acl_base + size);
1286
1287 if (!new_aces_set && (pntace->flags & INHERITED_ACE)) {
1288 /* Place the new ACEs in between existing explicit and inherited */
1289 populate_new_aces(nacl_base,
1290 pownersid, pgrpsid,
1291 pnmode, &num_aces, &nsize,
1292 mode_from_sid, posix);
1293
1294 new_aces_set = true;
1295 }
1296
1297 /* If it's any one of the ACE we're replacing, skip! */
1298 if (((compare_sids(&pntace->sid, &sid_unix_NFS_mode) == 0) ||
1299 (compare_sids(&pntace->sid, pownersid) == 0) ||
1300 (compare_sids(&pntace->sid, pgrpsid) == 0) ||
1301 (compare_sids(&pntace->sid, &sid_everyone) == 0) ||
1302 (compare_sids(&pntace->sid, &sid_authusers) == 0))) {
1303 goto next_ace;
1304 }
1305
1306 /* update the pointer to the next ACE to populate*/
1307 pnntace = (struct smb_ace *) (nacl_base + nsize);
1308
1309 nsize += cifs_copy_ace(pnntace, pntace, NULL);
1310 num_aces++;
1311 if (nsize > U16_MAX)
1312 return -EOVERFLOW;
1313
1314 next_ace:
1315 size += le16_to_cpu(pntace->size);
1316 }
1317
1318 /* If inherited ACEs are not present, place the new ones at the tail */
1319 if (!new_aces_set) {
1320 populate_new_aces(nacl_base,
1321 pownersid, pgrpsid,
1322 pnmode, &num_aces, &nsize,
1323 mode_from_sid, posix);
1324
1325 new_aces_set = true;
1326 }
1327
1328 finalize_dacl:
1329 /* The DACL size field is 16-bit on the wire, see MS-DTYP 2.4.5 */
1330 if (nsize > U16_MAX)
1331 return -EOVERFLOW;
1332
1333 pndacl->num_aces = cpu_to_le16(num_aces);
1334 pndacl->size = cpu_to_le16(nsize);
1335
1336 return 0;
1337 }
1338
dacl_offset_valid(unsigned int acl_len,__u32 dacloffset)1339 static bool dacl_offset_valid(unsigned int acl_len, __u32 dacloffset)
1340 {
1341 if (acl_len < sizeof(struct smb_acl))
1342 return false;
1343
1344 if (dacloffset < sizeof(struct smb_ntsd))
1345 return false;
1346
1347 return dacloffset <= acl_len - sizeof(struct smb_acl);
1348 }
1349
1350
1351 /* 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)1352 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1353 struct smb_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
1354 bool get_mode_from_special_sid)
1355 {
1356 int rc = 0;
1357 struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1358 unsigned int sbflags = cifs_sb_flags(cifs_sb);
1359 struct smb_acl *dacl_ptr; /* no need for SACL ptr */
1360 char *end_of_acl;
1361 __u32 dacloffset, osidoffset, gsidoffset;
1362
1363 if (pntsd == NULL)
1364 return smb_EIO(smb_eio_trace_null_pointers);
1365 if (acl_len < (int)sizeof(struct smb_ntsd)) {
1366 cifs_dbg(VFS, "ACL too small to parse security descriptor\n");
1367 return -EINVAL;
1368 }
1369 end_of_acl = ((char *)pntsd) + acl_len;
1370
1371 osidoffset = le32_to_cpu(pntsd->osidoffset);
1372 gsidoffset = le32_to_cpu(pntsd->gsidoffset);
1373 dacloffset = le32_to_cpu(pntsd->dacloffset);
1374 cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
1375 pntsd->revision, pntsd->type, osidoffset, gsidoffset,
1376 le32_to_cpu(pntsd->sacloffset), dacloffset);
1377 fattr->cf_uid = cifs_sb->ctx->linux_uid;
1378 fattr->cf_gid = cifs_sb->ctx->linux_gid;
1379
1380 rc = sid_from_sd(pntsd, acl_len, osidoffset, &owner_sid_ptr);
1381 if (rc) {
1382 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1383 return rc;
1384 }
1385 if (!(sbflags & CIFS_MOUNT_OVERR_UID)) {
1386 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1387 if (rc) {
1388 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
1389 __func__, rc);
1390 return rc;
1391 }
1392 }
1393
1394 rc = sid_from_sd(pntsd, acl_len, gsidoffset, &group_sid_ptr);
1395 if (rc) {
1396 cifs_dbg(FYI, "%s: Error %d parsing Group SID\n",
1397 __func__, rc);
1398 return rc;
1399 }
1400 if (!(sbflags & CIFS_MOUNT_OVERR_GID)) {
1401 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1402 if (rc) {
1403 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
1404 __func__, rc);
1405 return rc;
1406 }
1407 }
1408
1409 if (dacloffset) {
1410 if (!dacl_offset_valid(acl_len, dacloffset)) {
1411 cifs_dbg(VFS, "Server returned illegal DACL offset\n");
1412 return -EINVAL;
1413 }
1414
1415 dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1416 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1417 group_sid_ptr, fattr, get_mode_from_special_sid);
1418 } else {
1419 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
1420 }
1421
1422 return rc;
1423 }
1424
1425 /* 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)1426 static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
1427 __u32 secdesclen, __u32 *pnsecdesclen, __u64 *pnmode, kuid_t uid, kgid_t gid,
1428 bool mode_from_sid, bool id_from_sid, bool posix, int *aclflag)
1429 {
1430 int rc = 0;
1431 __u32 dacloffset;
1432 __u32 ndacloffset;
1433 __u32 sidsoffset;
1434 struct smb_sid *owner_sid_ptr, *group_sid_ptr;
1435 struct smb_sid *nowner_sid_ptr = NULL, *ngroup_sid_ptr = NULL;
1436 struct smb_acl *dacl_ptr = NULL; /* no need for SACL ptr */
1437 struct smb_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1438 char *end_of_acl;
1439 u16 size = 0;
1440 __u32 osidoffset, gsidoffset;
1441
1442 if (secdesclen < sizeof(struct smb_ntsd)) {
1443 cifs_dbg(VFS, "ACL too small to parse security descriptor\n");
1444 return -EINVAL;
1445 }
1446 end_of_acl = ((char *)pntsd) + secdesclen;
1447
1448 dacloffset = le32_to_cpu(pntsd->dacloffset);
1449 if (dacloffset) {
1450 if (!dacl_offset_valid(secdesclen, dacloffset)) {
1451 cifs_dbg(VFS, "Server returned illegal DACL offset\n");
1452 return -EINVAL;
1453 }
1454
1455 dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1456 rc = validate_dacl(dacl_ptr, end_of_acl);
1457 if (rc)
1458 return rc;
1459 }
1460
1461 osidoffset = le32_to_cpu(pntsd->osidoffset);
1462 gsidoffset = le32_to_cpu(pntsd->gsidoffset);
1463 rc = sid_from_sd(pntsd, secdesclen, osidoffset, &owner_sid_ptr);
1464 if (rc) {
1465 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
1466 return rc;
1467 }
1468 rc = sid_from_sd(pntsd, secdesclen, gsidoffset, &group_sid_ptr);
1469 if (rc) {
1470 cifs_dbg(FYI, "%s: Error %d parsing Group SID\n", __func__, rc);
1471 return rc;
1472 }
1473
1474 if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1475 ndacloffset = sizeof(struct smb_ntsd);
1476 ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
1477 ndacl_ptr->revision =
1478 dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1479
1480 ndacl_ptr->size = cpu_to_le16(0);
1481 ndacl_ptr->num_aces = cpu_to_le16(0);
1482
1483 rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1484 pnmode, mode_from_sid, posix);
1485 if (rc)
1486 return rc;
1487
1488 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1489 /* copy the non-dacl portion of secdesc */
1490 rc = copy_sec_desc(pntsd, pnntsd, sidsoffset, secdesclen,
1491 pnsecdesclen, NULL, NULL);
1492 if (rc)
1493 return rc;
1494
1495 *aclflag |= CIFS_ACL_DACL;
1496 } else {
1497 ndacloffset = sizeof(struct smb_ntsd);
1498 ndacl_ptr = (struct smb_acl *)((char *)pnntsd + ndacloffset);
1499 ndacl_ptr->revision =
1500 dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
1501 ndacl_ptr->num_aces = dacl_ptr ? dacl_ptr->num_aces : 0;
1502
1503 if (uid_valid(uid)) { /* chown */
1504 uid_t id;
1505 nowner_sid_ptr = kzalloc_obj(struct smb_sid);
1506 if (!nowner_sid_ptr) {
1507 rc = -ENOMEM;
1508 goto chown_chgrp_exit;
1509 }
1510 id = from_kuid(&init_user_ns, uid);
1511 if (id_from_sid) {
1512 struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1513 /* Populate the user ownership fields S-1-5-88-1 */
1514 osid->Revision = 1;
1515 osid->NumAuth = 3;
1516 osid->Authority[5] = 5;
1517 osid->SubAuthorities[0] = cpu_to_le32(88);
1518 osid->SubAuthorities[1] = cpu_to_le32(1);
1519 osid->SubAuthorities[2] = cpu_to_le32(id);
1520
1521 } else { /* lookup sid with upcall */
1522 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1523 if (rc) {
1524 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1525 __func__, rc, id);
1526 goto chown_chgrp_exit;
1527 }
1528 }
1529 *aclflag |= CIFS_ACL_OWNER;
1530 }
1531 if (gid_valid(gid)) { /* chgrp */
1532 gid_t id;
1533 ngroup_sid_ptr = kzalloc_obj(struct smb_sid);
1534 if (!ngroup_sid_ptr) {
1535 rc = -ENOMEM;
1536 goto chown_chgrp_exit;
1537 }
1538 id = from_kgid(&init_user_ns, gid);
1539 if (id_from_sid) {
1540 struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1541 /* Populate the group ownership fields S-1-5-88-2 */
1542 gsid->Revision = 1;
1543 gsid->NumAuth = 3;
1544 gsid->Authority[5] = 5;
1545 gsid->SubAuthorities[0] = cpu_to_le32(88);
1546 gsid->SubAuthorities[1] = cpu_to_le32(2);
1547 gsid->SubAuthorities[2] = cpu_to_le32(id);
1548
1549 } else { /* lookup sid with upcall */
1550 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1551 if (rc) {
1552 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1553 __func__, rc, id);
1554 goto chown_chgrp_exit;
1555 }
1556 }
1557 *aclflag |= CIFS_ACL_GROUP;
1558 }
1559
1560 if (dacloffset) {
1561 /* Replace ACEs for old owner with new one */
1562 rc = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
1563 owner_sid_ptr, group_sid_ptr,
1564 nowner_sid_ptr, ngroup_sid_ptr,
1565 aclflag, &size);
1566 if (rc)
1567 goto chown_chgrp_exit;
1568 ndacl_ptr->size = cpu_to_le16(size);
1569 }
1570
1571 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1572 /* copy the non-dacl portion of secdesc */
1573 rc = copy_sec_desc(pntsd, pnntsd, sidsoffset, secdesclen,
1574 pnsecdesclen, nowner_sid_ptr, ngroup_sid_ptr);
1575 if (rc)
1576 goto chown_chgrp_exit;
1577
1578 chown_chgrp_exit:
1579 /* errors could jump here. So make sure we return soon after this */
1580 kfree(nowner_sid_ptr);
1581 kfree(ngroup_sid_ptr);
1582 }
1583
1584 return rc;
1585 }
1586
1587 #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)1588 struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1589 const struct cifs_fid *cifsfid, u32 *pacllen,
1590 u32 info)
1591 {
1592 struct smb_ntsd *pntsd = NULL;
1593 unsigned int xid;
1594 int rc;
1595 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1596
1597 if (IS_ERR(tlink))
1598 return ERR_CAST(tlink);
1599
1600 xid = get_xid();
1601 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1602 pacllen, info);
1603 free_xid(xid);
1604
1605 cifs_put_tlink(tlink);
1606
1607 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1608 if (rc)
1609 return ERR_PTR(rc);
1610 return pntsd;
1611 }
1612
get_cifs_acl_by_path(struct cifs_sb_info * cifs_sb,const char * path,u32 * pacllen,u32 info)1613 static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1614 const char *path, u32 *pacllen, u32 info)
1615 {
1616 struct smb_ntsd *pntsd = NULL;
1617 int oplock = 0;
1618 unsigned int xid;
1619 int rc;
1620 struct cifs_tcon *tcon;
1621 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1622 struct cifs_fid fid;
1623 struct cifs_open_parms oparms;
1624
1625 if (IS_ERR(tlink))
1626 return ERR_CAST(tlink);
1627
1628 tcon = tlink_tcon(tlink);
1629 xid = get_xid();
1630
1631 oparms = (struct cifs_open_parms) {
1632 .tcon = tcon,
1633 .cifs_sb = cifs_sb,
1634 .desired_access = READ_CONTROL,
1635 .create_options = cifs_create_options(cifs_sb, 0),
1636 .disposition = FILE_OPEN,
1637 .path = path,
1638 .fid = &fid,
1639 };
1640
1641 if (info & SACL_SECINFO)
1642 oparms.desired_access |= SYSTEM_SECURITY;
1643
1644 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1645 if (!rc) {
1646 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen, info);
1647 CIFSSMBClose(xid, tcon, fid.netfid);
1648 }
1649
1650 cifs_put_tlink(tlink);
1651 free_xid(xid);
1652
1653 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1654 if (rc)
1655 return ERR_PTR(rc);
1656 return pntsd;
1657 }
1658
1659 /* 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)1660 struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1661 struct inode *inode, const char *path,
1662 u32 *pacllen, u32 info)
1663 {
1664 struct smb_ntsd *pntsd = NULL;
1665 struct cifsFileInfo *open_file = NULL;
1666
1667 if (inode)
1668 open_file = find_readable_file(CIFS_I(inode), FIND_FSUID_ONLY);
1669 if (!open_file)
1670 return get_cifs_acl_by_path(cifs_sb, path, pacllen, info);
1671
1672 pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
1673 cifsFileInfo_put(open_file);
1674 return pntsd;
1675 }
1676
1677 /* Set an ACL on the server */
set_cifs_acl(struct smb_ntsd * pnntsd,__u32 acllen,struct inode * inode,const char * path,int aclflag)1678 int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
1679 struct inode *inode, const char *path, int aclflag)
1680 {
1681 int oplock = 0;
1682 unsigned int xid;
1683 int rc, access_flags = 0;
1684 struct cifs_tcon *tcon;
1685 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1686 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1687 struct cifs_fid fid;
1688 struct cifs_open_parms oparms;
1689
1690 if (IS_ERR(tlink))
1691 return PTR_ERR(tlink);
1692
1693 tcon = tlink_tcon(tlink);
1694 xid = get_xid();
1695
1696 if (aclflag & CIFS_ACL_OWNER || aclflag & CIFS_ACL_GROUP)
1697 access_flags |= WRITE_OWNER;
1698 if (aclflag & CIFS_ACL_SACL)
1699 access_flags |= SYSTEM_SECURITY;
1700 if (aclflag & CIFS_ACL_DACL)
1701 access_flags |= WRITE_DAC;
1702
1703 oparms = (struct cifs_open_parms) {
1704 .tcon = tcon,
1705 .cifs_sb = cifs_sb,
1706 .desired_access = access_flags,
1707 .create_options = cifs_create_options(cifs_sb, 0),
1708 .disposition = FILE_OPEN,
1709 .path = path,
1710 .fid = &fid,
1711 };
1712
1713 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1714 if (rc) {
1715 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1716 goto out;
1717 }
1718
1719 rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1720 cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1721
1722 CIFSSMBClose(xid, tcon, fid.netfid);
1723 out:
1724 free_xid(xid);
1725 cifs_put_tlink(tlink);
1726 return rc;
1727 }
1728 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
1729
1730 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1731 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)1732 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1733 struct inode *inode, bool mode_from_special_sid,
1734 const char *path, const struct cifs_fid *pfid)
1735 {
1736 struct smb_ntsd *pntsd = NULL;
1737 u32 acllen = 0;
1738 int rc = 0;
1739 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1740 struct smb_version_operations *ops;
1741 const u32 info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO;
1742
1743 cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1744
1745 if (IS_ERR(tlink))
1746 return PTR_ERR(tlink);
1747
1748 ops = tlink_tcon(tlink)->ses->server->ops;
1749
1750 if (pfid && (ops->get_acl_by_fid))
1751 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen, info);
1752 else if (ops->get_acl)
1753 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen, info);
1754 else {
1755 cifs_put_tlink(tlink);
1756 return -EOPNOTSUPP;
1757 }
1758 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1759 if (IS_ERR(pntsd)) {
1760 rc = PTR_ERR(pntsd);
1761 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1762 } else if (mode_from_special_sid) {
1763 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1764 kfree(pntsd);
1765 } else {
1766 /* get approximated mode from ACL */
1767 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1768 kfree(pntsd);
1769 if (rc)
1770 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1771 }
1772
1773 cifs_put_tlink(tlink);
1774
1775 return rc;
1776 }
1777
1778 /* Convert mode bits to an ACL so we can update the ACL on the server */
1779 int
id_mode_to_cifs_acl(struct inode * inode,const char * path,__u64 * pnmode,kuid_t uid,kgid_t gid)1780 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
1781 kuid_t uid, kgid_t gid)
1782 {
1783 int rc = 0;
1784 int aclflag = 0;
1785 __u32 secdesclen = 0;
1786 __u32 nsecdesclen = 0;
1787 __u32 dacloffset = 0;
1788 struct smb_acl *dacl_ptr = NULL;
1789 struct smb_ntsd *pntsd = NULL; /* acl obtained from server */
1790 struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1791 struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
1792 unsigned int sbflags;
1793 struct tcon_link *tlink;
1794 struct smb_version_operations *ops;
1795 bool mode_from_sid, id_from_sid;
1796 const u32 info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO;
1797 bool posix;
1798
1799 tlink = cifs_sb_tlink(cifs_sb);
1800 if (IS_ERR(tlink))
1801 return PTR_ERR(tlink);
1802 posix = tlink_tcon(tlink)->posix_extensions;
1803
1804 ops = tlink_tcon(tlink)->ses->server->ops;
1805
1806 cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1807
1808 /* Get the security descriptor */
1809
1810 if (ops->get_acl == NULL) {
1811 cifs_put_tlink(tlink);
1812 return -EOPNOTSUPP;
1813 }
1814
1815 pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen, info);
1816 if (IS_ERR(pntsd)) {
1817 rc = PTR_ERR(pntsd);
1818 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1819 cifs_put_tlink(tlink);
1820 return rc;
1821 }
1822
1823 sbflags = cifs_sb_flags(cifs_sb);
1824 mode_from_sid = sbflags & CIFS_MOUNT_MODE_FROM_SID;
1825 id_from_sid = sbflags & CIFS_MOUNT_UID_FROM_ACL;
1826
1827 /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
1828 if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
1829 if (posix)
1830 nsecdesclen = 1 * sizeof(struct smb_ace);
1831 else if (mode_from_sid)
1832 nsecdesclen = secdesclen + (2 * sizeof(struct smb_ace));
1833 else /* cifsacl */
1834 nsecdesclen = secdesclen + (5 * sizeof(struct smb_ace));
1835 } else { /* chown */
1836 /* When ownership changes, changes new owner sid length could be different */
1837 nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2);
1838 dacloffset = le32_to_cpu(pntsd->dacloffset);
1839 if (dacloffset) {
1840 if (!dacl_offset_valid(secdesclen, dacloffset)) {
1841 cifs_dbg(VFS, "Server returned illegal DACL offset\n");
1842 rc = -EINVAL;
1843 goto id_mode_to_cifs_acl_exit;
1844 }
1845
1846 dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
1847 rc = validate_dacl(dacl_ptr, (char *)pntsd + secdesclen);
1848 if (rc) {
1849 kfree(pntsd);
1850 cifs_put_tlink(tlink);
1851 return rc;
1852 }
1853 /*
1854 * Worst case: every ACE is rewritten with a new SID of
1855 * SID_MAX_SUB_AUTHORITIES sub-auths -> sizeof(smb_ace) each,
1856 * plus the smb_acl header replace_sids_and_copy_aces() emits.
1857 */
1858 nsecdesclen += sizeof(struct smb_acl) +
1859 le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
1860 }
1861 }
1862
1863 /*
1864 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1865 * as chmod disables ACEs and set the security descriptor. Allocate
1866 * memory for the smb header, set security descriptor request security
1867 * descriptor parameters, and security descriptor itself
1868 */
1869 nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
1870 pnntsd = kzalloc(nsecdesclen, GFP_KERNEL);
1871 if (!pnntsd) {
1872 kfree(pntsd);
1873 cifs_put_tlink(tlink);
1874 return -ENOMEM;
1875 }
1876
1877 rc = build_sec_desc(pntsd, pnntsd, secdesclen, &nsecdesclen, pnmode, uid, gid,
1878 mode_from_sid, id_from_sid, posix, &aclflag);
1879
1880 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1881
1882 if (rc != 0)
1883 goto id_mode_to_cifs_acl_exit;
1884
1885 if (aclflag == 0) {
1886 cifs_dbg(FYI, "set_cifs_acl aclflag=0, no change mapped\n");
1887 goto id_mode_to_cifs_acl_exit;
1888 }
1889
1890 if (ops->set_acl == NULL) {
1891 rc = -EOPNOTSUPP;
1892 goto id_mode_to_cifs_acl_exit;
1893 }
1894
1895 /* Set the security descriptor */
1896 rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
1897 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1898
1899 id_mode_to_cifs_acl_exit:
1900 cifs_put_tlink(tlink);
1901
1902 kfree(pnntsd);
1903 kfree(pntsd);
1904 return rc;
1905 }
1906
cifs_get_acl(struct mnt_idmap * idmap,struct dentry * dentry,int type)1907 struct posix_acl *cifs_get_acl(struct mnt_idmap *idmap,
1908 struct dentry *dentry, int type)
1909 {
1910 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1911 struct posix_acl *acl = NULL;
1912 ssize_t rc = -EOPNOTSUPP;
1913 unsigned int xid;
1914 struct super_block *sb = dentry->d_sb;
1915 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1916 struct tcon_link *tlink;
1917 struct cifs_tcon *pTcon;
1918 const char *full_path;
1919 void *page;
1920
1921 tlink = cifs_sb_tlink(cifs_sb);
1922 if (IS_ERR(tlink))
1923 return ERR_CAST(tlink);
1924 pTcon = tlink_tcon(tlink);
1925
1926 xid = get_xid();
1927 page = alloc_dentry_path();
1928
1929 full_path = build_path_from_dentry(dentry, page);
1930 if (IS_ERR(full_path)) {
1931 acl = ERR_CAST(full_path);
1932 goto out;
1933 }
1934
1935 /* return alt name if available as pseudo attr */
1936 switch (type) {
1937 case ACL_TYPE_ACCESS:
1938 if (sb->s_flags & SB_POSIXACL)
1939 rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1940 ACL_TYPE_ACCESS,
1941 cifs_sb->local_nls,
1942 cifs_remap(cifs_sb));
1943 break;
1944
1945 case ACL_TYPE_DEFAULT:
1946 if (sb->s_flags & SB_POSIXACL)
1947 rc = cifs_do_get_acl(xid, pTcon, full_path, &acl,
1948 ACL_TYPE_DEFAULT,
1949 cifs_sb->local_nls,
1950 cifs_remap(cifs_sb));
1951 break;
1952 }
1953
1954 if (rc < 0) {
1955 if (rc == -EINVAL)
1956 acl = ERR_PTR(-EOPNOTSUPP);
1957 else
1958 acl = ERR_PTR(rc);
1959 }
1960
1961 out:
1962 free_dentry_path(page);
1963 free_xid(xid);
1964 cifs_put_tlink(tlink);
1965 return acl;
1966 #else
1967 return ERR_PTR(-EOPNOTSUPP);
1968 #endif
1969 }
1970
cifs_set_acl(struct mnt_idmap * idmap,struct dentry * dentry,struct posix_acl * acl,int type)1971 int cifs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
1972 struct posix_acl *acl, int type)
1973 {
1974 #if defined(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) && defined(CONFIG_CIFS_POSIX)
1975 int rc = -EOPNOTSUPP;
1976 unsigned int xid;
1977 struct super_block *sb = dentry->d_sb;
1978 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1979 struct tcon_link *tlink;
1980 struct cifs_tcon *pTcon;
1981 const char *full_path;
1982 void *page;
1983
1984 tlink = cifs_sb_tlink(cifs_sb);
1985 if (IS_ERR(tlink))
1986 return PTR_ERR(tlink);
1987 pTcon = tlink_tcon(tlink);
1988
1989 xid = get_xid();
1990 page = alloc_dentry_path();
1991
1992 full_path = build_path_from_dentry(dentry, page);
1993 if (IS_ERR(full_path)) {
1994 rc = PTR_ERR(full_path);
1995 goto out;
1996 }
1997
1998 if (!acl)
1999 goto out;
2000
2001 /* return dos attributes as pseudo xattr */
2002 /* return alt name if available as pseudo attr */
2003
2004 /* if proc/fs/cifs/streamstoxattr is set then
2005 search server for EAs or streams to
2006 returns as xattrs */
2007 if (posix_acl_xattr_size(acl->a_count) > CIFSMaxBufSize) {
2008 cifs_dbg(FYI, "size of EA value too large\n");
2009 rc = -EOPNOTSUPP;
2010 goto out;
2011 }
2012
2013 switch (type) {
2014 case ACL_TYPE_ACCESS:
2015 if (sb->s_flags & SB_POSIXACL)
2016 rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
2017 ACL_TYPE_ACCESS,
2018 cifs_sb->local_nls,
2019 cifs_remap(cifs_sb));
2020 break;
2021
2022 case ACL_TYPE_DEFAULT:
2023 if (sb->s_flags & SB_POSIXACL)
2024 rc = cifs_do_set_acl(xid, pTcon, full_path, acl,
2025 ACL_TYPE_DEFAULT,
2026 cifs_sb->local_nls,
2027 cifs_remap(cifs_sb));
2028 break;
2029 }
2030
2031 out:
2032 free_dentry_path(page);
2033 free_xid(xid);
2034 cifs_put_tlink(tlink);
2035 return rc;
2036 #else
2037 return -EOPNOTSUPP;
2038 #endif
2039 }
2040