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