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