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