]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - fs/cifs/cifsacl.c
rtl8188eu: remove dead code
[mirror_ubuntu-bionic-kernel.git] / fs / cifs / cifsacl.c
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
36 /* security id for everyone/world system group */
37 static const struct cifs_sid sid_everyone = {
38 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
39 /* security id for Authenticated Users system group */
40 static const struct cifs_sid sid_authusers = {
41 1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11)} };
42 /* group users */
43 static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
44
45 static const struct cred *root_cred;
46
47 static int
48 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
49 {
50 char *payload;
51
52 /*
53 * If the payload is less than or equal to the size of a pointer, then
54 * an allocation here is wasteful. Just copy the data directly to the
55 * payload.value union member instead.
56 *
57 * With this however, you must check the datalen before trying to
58 * dereference payload.data!
59 */
60 if (prep->datalen <= sizeof(key->payload)) {
61 key->payload.value = 0;
62 memcpy(&key->payload.value, prep->data, prep->datalen);
63 key->datalen = prep->datalen;
64 return 0;
65 }
66 payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
67 if (!payload)
68 return -ENOMEM;
69
70 key->payload.data = payload;
71 key->datalen = prep->datalen;
72 return 0;
73 }
74
75 static inline void
76 cifs_idmap_key_destroy(struct key *key)
77 {
78 if (key->datalen > sizeof(key->payload))
79 kfree(key->payload.data);
80 }
81
82 static struct key_type cifs_idmap_key_type = {
83 .name = "cifs.idmap",
84 .instantiate = cifs_idmap_key_instantiate,
85 .destroy = cifs_idmap_key_destroy,
86 .describe = user_describe,
87 .match = user_match,
88 };
89
90 static char *
91 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
92 {
93 int i, len;
94 unsigned int saval;
95 char *sidstr, *strptr;
96 unsigned long long id_auth_val;
97
98 /* 3 bytes for prefix */
99 sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
100 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
101 GFP_KERNEL);
102 if (!sidstr)
103 return sidstr;
104
105 strptr = sidstr;
106 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
107 sidptr->revision);
108 strptr += len;
109
110 /* The authority field is a single 48-bit number */
111 id_auth_val = (unsigned long long)sidptr->authority[5];
112 id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
113 id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
114 id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
115 id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
116 id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
117
118 /*
119 * MS-DTYP states that if the authority is >= 2^32, then it should be
120 * expressed as a hex value.
121 */
122 if (id_auth_val <= UINT_MAX)
123 len = sprintf(strptr, "-%llu", id_auth_val);
124 else
125 len = sprintf(strptr, "-0x%llx", id_auth_val);
126
127 strptr += len;
128
129 for (i = 0; i < sidptr->num_subauth; ++i) {
130 saval = le32_to_cpu(sidptr->sub_auth[i]);
131 len = sprintf(strptr, "-%u", saval);
132 strptr += len;
133 }
134
135 return sidstr;
136 }
137
138 /*
139 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
140 * the same returns zero, if they do not match returns non-zero.
141 */
142 static int
143 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
144 {
145 int i;
146 int num_subauth, num_sat, num_saw;
147
148 if ((!ctsid) || (!cwsid))
149 return 1;
150
151 /* compare the revision */
152 if (ctsid->revision != cwsid->revision) {
153 if (ctsid->revision > cwsid->revision)
154 return 1;
155 else
156 return -1;
157 }
158
159 /* compare all of the six auth values */
160 for (i = 0; i < NUM_AUTHS; ++i) {
161 if (ctsid->authority[i] != cwsid->authority[i]) {
162 if (ctsid->authority[i] > cwsid->authority[i])
163 return 1;
164 else
165 return -1;
166 }
167 }
168
169 /* compare all of the subauth values if any */
170 num_sat = ctsid->num_subauth;
171 num_saw = cwsid->num_subauth;
172 num_subauth = num_sat < num_saw ? num_sat : num_saw;
173 if (num_subauth) {
174 for (i = 0; i < num_subauth; ++i) {
175 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
176 if (le32_to_cpu(ctsid->sub_auth[i]) >
177 le32_to_cpu(cwsid->sub_auth[i]))
178 return 1;
179 else
180 return -1;
181 }
182 }
183 }
184
185 return 0; /* sids compare/match */
186 }
187
188 static void
189 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
190 {
191 int i;
192
193 dst->revision = src->revision;
194 dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
195 for (i = 0; i < NUM_AUTHS; ++i)
196 dst->authority[i] = src->authority[i];
197 for (i = 0; i < dst->num_subauth; ++i)
198 dst->sub_auth[i] = src->sub_auth[i];
199 }
200
201 static int
202 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
203 {
204 int rc;
205 struct key *sidkey;
206 struct cifs_sid *ksid;
207 unsigned int ksid_size;
208 char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
209 const struct cred *saved_cred;
210
211 rc = snprintf(desc, sizeof(desc), "%ci:%u",
212 sidtype == SIDOWNER ? 'o' : 'g', cid);
213 if (rc >= sizeof(desc))
214 return -EINVAL;
215
216 rc = 0;
217 saved_cred = override_creds(root_cred);
218 sidkey = request_key(&cifs_idmap_key_type, desc, "");
219 if (IS_ERR(sidkey)) {
220 rc = -EINVAL;
221 cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
222 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
223 goto out_revert_creds;
224 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
225 rc = -EIO;
226 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
227 __func__, sidkey->datalen);
228 goto invalidate_key;
229 }
230
231 /*
232 * A sid is usually too large to be embedded in payload.value, but if
233 * there are no subauthorities and the host has 8-byte pointers, then
234 * it could be.
235 */
236 ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
237 (struct cifs_sid *)&sidkey->payload.value :
238 (struct cifs_sid *)sidkey->payload.data;
239
240 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
241 if (ksid_size > sidkey->datalen) {
242 rc = -EIO;
243 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
244 __func__, sidkey->datalen, ksid_size);
245 goto invalidate_key;
246 }
247
248 cifs_copy_sid(ssid, ksid);
249 out_key_put:
250 key_put(sidkey);
251 out_revert_creds:
252 revert_creds(saved_cred);
253 return rc;
254
255 invalidate_key:
256 key_invalidate(sidkey);
257 goto out_key_put;
258 }
259
260 static int
261 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
262 struct cifs_fattr *fattr, uint sidtype)
263 {
264 int rc;
265 struct key *sidkey;
266 char *sidstr;
267 const struct cred *saved_cred;
268 kuid_t fuid = cifs_sb->mnt_uid;
269 kgid_t fgid = cifs_sb->mnt_gid;
270
271 /*
272 * If we have too many subauthorities, then something is really wrong.
273 * Just return an error.
274 */
275 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
276 cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
277 __func__, psid->num_subauth);
278 return -EIO;
279 }
280
281 sidstr = sid_to_key_str(psid, sidtype);
282 if (!sidstr)
283 return -ENOMEM;
284
285 saved_cred = override_creds(root_cred);
286 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
287 if (IS_ERR(sidkey)) {
288 rc = -EINVAL;
289 cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
290 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
291 goto out_revert_creds;
292 }
293
294 /*
295 * FIXME: Here we assume that uid_t and gid_t are same size. It's
296 * probably a safe assumption but might be better to check based on
297 * sidtype.
298 */
299 BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
300 if (sidkey->datalen != sizeof(uid_t)) {
301 rc = -EIO;
302 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
303 __func__, sidkey->datalen);
304 key_invalidate(sidkey);
305 goto out_key_put;
306 }
307
308 if (sidtype == SIDOWNER) {
309 kuid_t uid;
310 uid_t id;
311 memcpy(&id, &sidkey->payload.value, sizeof(uid_t));
312 uid = make_kuid(&init_user_ns, id);
313 if (uid_valid(uid))
314 fuid = uid;
315 } else {
316 kgid_t gid;
317 gid_t id;
318 memcpy(&id, &sidkey->payload.value, sizeof(gid_t));
319 gid = make_kgid(&init_user_ns, id);
320 if (gid_valid(gid))
321 fgid = gid;
322 }
323
324 out_key_put:
325 key_put(sidkey);
326 out_revert_creds:
327 revert_creds(saved_cred);
328 kfree(sidstr);
329
330 /*
331 * Note that we return 0 here unconditionally. If the mapping
332 * fails then we just fall back to using the mnt_uid/mnt_gid.
333 */
334 if (sidtype == SIDOWNER)
335 fattr->cf_uid = fuid;
336 else
337 fattr->cf_gid = fgid;
338 return 0;
339 }
340
341 int
342 init_cifs_idmap(void)
343 {
344 struct cred *cred;
345 struct key *keyring;
346 int ret;
347
348 cifs_dbg(FYI, "Registering the %s key type\n",
349 cifs_idmap_key_type.name);
350
351 /* create an override credential set with a special thread keyring in
352 * which requests are cached
353 *
354 * this is used to prevent malicious redirections from being installed
355 * with add_key().
356 */
357 cred = prepare_kernel_cred(NULL);
358 if (!cred)
359 return -ENOMEM;
360
361 keyring = keyring_alloc(".cifs_idmap",
362 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
363 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
364 KEY_USR_VIEW | KEY_USR_READ,
365 KEY_ALLOC_NOT_IN_QUOTA, NULL);
366 if (IS_ERR(keyring)) {
367 ret = PTR_ERR(keyring);
368 goto failed_put_cred;
369 }
370
371 ret = register_key_type(&cifs_idmap_key_type);
372 if (ret < 0)
373 goto failed_put_key;
374
375 /* instruct request_key() to use this special keyring as a cache for
376 * the results it looks up */
377 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
378 cred->thread_keyring = keyring;
379 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
380 root_cred = cred;
381
382 cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
383 return 0;
384
385 failed_put_key:
386 key_put(keyring);
387 failed_put_cred:
388 put_cred(cred);
389 return ret;
390 }
391
392 void
393 exit_cifs_idmap(void)
394 {
395 key_revoke(root_cred->thread_keyring);
396 unregister_key_type(&cifs_idmap_key_type);
397 put_cred(root_cred);
398 cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
399 }
400
401 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
402 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
403 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
404 {
405 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
406 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
407
408 /* copy security descriptor control portion */
409 pnntsd->revision = pntsd->revision;
410 pnntsd->type = pntsd->type;
411 pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
412 pnntsd->sacloffset = 0;
413 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
414 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
415
416 /* copy owner sid */
417 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
418 le32_to_cpu(pntsd->osidoffset));
419 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
420 cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
421
422 /* copy group sid */
423 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
424 le32_to_cpu(pntsd->gsidoffset));
425 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
426 sizeof(struct cifs_sid));
427 cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
428
429 return;
430 }
431
432
433 /*
434 change posix mode to reflect permissions
435 pmode is the existing mode (we only want to overwrite part of this
436 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
437 */
438 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
439 umode_t *pbits_to_set)
440 {
441 __u32 flags = le32_to_cpu(ace_flags);
442 /* the order of ACEs is important. The canonical order is to begin with
443 DENY entries followed by ALLOW, otherwise an allow entry could be
444 encountered first, making the subsequent deny entry like "dead code"
445 which would be superflous since Windows stops when a match is made
446 for the operation you are trying to perform for your user */
447
448 /* For deny ACEs we change the mask so that subsequent allow access
449 control entries do not turn on the bits we are denying */
450 if (type == ACCESS_DENIED) {
451 if (flags & GENERIC_ALL)
452 *pbits_to_set &= ~S_IRWXUGO;
453
454 if ((flags & GENERIC_WRITE) ||
455 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
456 *pbits_to_set &= ~S_IWUGO;
457 if ((flags & GENERIC_READ) ||
458 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
459 *pbits_to_set &= ~S_IRUGO;
460 if ((flags & GENERIC_EXECUTE) ||
461 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
462 *pbits_to_set &= ~S_IXUGO;
463 return;
464 } else if (type != ACCESS_ALLOWED) {
465 cifs_dbg(VFS, "unknown access control type %d\n", type);
466 return;
467 }
468 /* else ACCESS_ALLOWED type */
469
470 if (flags & GENERIC_ALL) {
471 *pmode |= (S_IRWXUGO & (*pbits_to_set));
472 cifs_dbg(NOISY, "all perms\n");
473 return;
474 }
475 if ((flags & GENERIC_WRITE) ||
476 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
477 *pmode |= (S_IWUGO & (*pbits_to_set));
478 if ((flags & GENERIC_READ) ||
479 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
480 *pmode |= (S_IRUGO & (*pbits_to_set));
481 if ((flags & GENERIC_EXECUTE) ||
482 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
483 *pmode |= (S_IXUGO & (*pbits_to_set));
484
485 cifs_dbg(NOISY, "access flags 0x%x mode now 0x%x\n", flags, *pmode);
486 return;
487 }
488
489 /*
490 Generate access flags to reflect permissions mode is the existing mode.
491 This function is called for every ACE in the DACL whose SID matches
492 with either owner or group or everyone.
493 */
494
495 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
496 __u32 *pace_flags)
497 {
498 /* reset access mask */
499 *pace_flags = 0x0;
500
501 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
502 mode &= bits_to_use;
503
504 /* check for R/W/X UGO since we do not know whose flags
505 is this but we have cleared all the bits sans RWX for
506 either user or group or other as per bits_to_use */
507 if (mode & S_IRUGO)
508 *pace_flags |= SET_FILE_READ_RIGHTS;
509 if (mode & S_IWUGO)
510 *pace_flags |= SET_FILE_WRITE_RIGHTS;
511 if (mode & S_IXUGO)
512 *pace_flags |= SET_FILE_EXEC_RIGHTS;
513
514 cifs_dbg(NOISY, "mode: 0x%x, access flags now 0x%x\n",
515 mode, *pace_flags);
516 return;
517 }
518
519 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
520 const struct cifs_sid *psid, __u64 nmode, umode_t bits)
521 {
522 int i;
523 __u16 size = 0;
524 __u32 access_req = 0;
525
526 pntace->type = ACCESS_ALLOWED;
527 pntace->flags = 0x0;
528 mode_to_access_flags(nmode, bits, &access_req);
529 if (!access_req)
530 access_req = SET_MINIMUM_RIGHTS;
531 pntace->access_req = cpu_to_le32(access_req);
532
533 pntace->sid.revision = psid->revision;
534 pntace->sid.num_subauth = psid->num_subauth;
535 for (i = 0; i < NUM_AUTHS; i++)
536 pntace->sid.authority[i] = psid->authority[i];
537 for (i = 0; i < psid->num_subauth; i++)
538 pntace->sid.sub_auth[i] = psid->sub_auth[i];
539
540 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
541 pntace->size = cpu_to_le16(size);
542
543 return size;
544 }
545
546
547 #ifdef CONFIG_CIFS_DEBUG2
548 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
549 {
550 int num_subauth;
551
552 /* validate that we do not go past end of acl */
553
554 if (le16_to_cpu(pace->size) < 16) {
555 cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
556 return;
557 }
558
559 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
560 cifs_dbg(VFS, "ACL too small to parse ACE\n");
561 return;
562 }
563
564 num_subauth = pace->sid.num_subauth;
565 if (num_subauth) {
566 int i;
567 cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
568 pace->sid.revision, pace->sid.num_subauth, pace->type,
569 pace->flags, le16_to_cpu(pace->size));
570 for (i = 0; i < num_subauth; ++i) {
571 cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
572 i, le32_to_cpu(pace->sid.sub_auth[i]));
573 }
574
575 /* BB add length check to make sure that we do not have huge
576 num auths and therefore go off the end */
577 }
578
579 return;
580 }
581 #endif
582
583
584 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
585 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
586 struct cifs_fattr *fattr)
587 {
588 int i;
589 int num_aces = 0;
590 int acl_size;
591 char *acl_base;
592 struct cifs_ace **ppace;
593
594 /* BB need to add parm so we can store the SID BB */
595
596 if (!pdacl) {
597 /* no DACL in the security descriptor, set
598 all the permissions for user/group/other */
599 fattr->cf_mode |= S_IRWXUGO;
600 return;
601 }
602
603 /* validate that we do not go past end of acl */
604 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
605 cifs_dbg(VFS, "ACL too small to parse DACL\n");
606 return;
607 }
608
609 cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
610 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
611 le32_to_cpu(pdacl->num_aces));
612
613 /* reset rwx permissions for user/group/other.
614 Also, if num_aces is 0 i.e. DACL has no ACEs,
615 user/group/other have no permissions */
616 fattr->cf_mode &= ~(S_IRWXUGO);
617
618 acl_base = (char *)pdacl;
619 acl_size = sizeof(struct cifs_acl);
620
621 num_aces = le32_to_cpu(pdacl->num_aces);
622 if (num_aces > 0) {
623 umode_t user_mask = S_IRWXU;
624 umode_t group_mask = S_IRWXG;
625 umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
626
627 if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
628 return;
629 ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
630 GFP_KERNEL);
631 if (!ppace)
632 return;
633
634 for (i = 0; i < num_aces; ++i) {
635 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
636 #ifdef CONFIG_CIFS_DEBUG2
637 dump_ace(ppace[i], end_of_acl);
638 #endif
639 if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
640 access_flags_to_mode(ppace[i]->access_req,
641 ppace[i]->type,
642 &fattr->cf_mode,
643 &user_mask);
644 if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
645 access_flags_to_mode(ppace[i]->access_req,
646 ppace[i]->type,
647 &fattr->cf_mode,
648 &group_mask);
649 if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
650 access_flags_to_mode(ppace[i]->access_req,
651 ppace[i]->type,
652 &fattr->cf_mode,
653 &other_mask);
654 if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
655 access_flags_to_mode(ppace[i]->access_req,
656 ppace[i]->type,
657 &fattr->cf_mode,
658 &other_mask);
659
660
661 /* memcpy((void *)(&(cifscred->aces[i])),
662 (void *)ppace[i],
663 sizeof(struct cifs_ace)); */
664
665 acl_base = (char *)ppace[i];
666 acl_size = le16_to_cpu(ppace[i]->size);
667 }
668
669 kfree(ppace);
670 }
671
672 return;
673 }
674
675
676 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
677 struct cifs_sid *pgrpsid, __u64 nmode)
678 {
679 u16 size = 0;
680 struct cifs_acl *pnndacl;
681
682 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
683
684 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
685 pownersid, nmode, S_IRWXU);
686 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
687 pgrpsid, nmode, S_IRWXG);
688 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
689 &sid_everyone, nmode, S_IRWXO);
690
691 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
692 pndacl->num_aces = cpu_to_le32(3);
693
694 return 0;
695 }
696
697
698 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
699 {
700 /* BB need to add parm so we can store the SID BB */
701
702 /* validate that we do not go past end of ACL - sid must be at least 8
703 bytes long (assuming no sub-auths - e.g. the null SID */
704 if (end_of_acl < (char *)psid + 8) {
705 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
706 return -EINVAL;
707 }
708
709 #ifdef CONFIG_CIFS_DEBUG2
710 if (psid->num_subauth) {
711 int i;
712 cifs_dbg(FYI, "SID revision %d num_auth %d\n",
713 psid->revision, psid->num_subauth);
714
715 for (i = 0; i < psid->num_subauth; i++) {
716 cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
717 i, le32_to_cpu(psid->sub_auth[i]));
718 }
719
720 /* BB add length check to make sure that we do not have huge
721 num auths and therefore go off the end */
722 cifs_dbg(FYI, "RID 0x%x\n",
723 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
724 }
725 #endif
726
727 return 0;
728 }
729
730
731 /* Convert CIFS ACL to POSIX form */
732 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
733 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
734 {
735 int rc = 0;
736 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
737 struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
738 char *end_of_acl = ((char *)pntsd) + acl_len;
739 __u32 dacloffset;
740
741 if (pntsd == NULL)
742 return -EIO;
743
744 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
745 le32_to_cpu(pntsd->osidoffset));
746 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
747 le32_to_cpu(pntsd->gsidoffset));
748 dacloffset = le32_to_cpu(pntsd->dacloffset);
749 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
750 cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
751 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
752 le32_to_cpu(pntsd->gsidoffset),
753 le32_to_cpu(pntsd->sacloffset), dacloffset);
754 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
755 rc = parse_sid(owner_sid_ptr, end_of_acl);
756 if (rc) {
757 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
758 return rc;
759 }
760 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
761 if (rc) {
762 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
763 __func__, rc);
764 return rc;
765 }
766
767 rc = parse_sid(group_sid_ptr, end_of_acl);
768 if (rc) {
769 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
770 __func__, rc);
771 return rc;
772 }
773 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
774 if (rc) {
775 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
776 __func__, rc);
777 return rc;
778 }
779
780 if (dacloffset)
781 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
782 group_sid_ptr, fattr);
783 else
784 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
785
786 return rc;
787 }
788
789 /* Convert permission bits from mode to equivalent CIFS ACL */
790 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
791 __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag)
792 {
793 int rc = 0;
794 __u32 dacloffset;
795 __u32 ndacloffset;
796 __u32 sidsoffset;
797 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
798 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
799 struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */
800 struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
801
802 if (nmode != NO_CHANGE_64) { /* chmod */
803 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
804 le32_to_cpu(pntsd->osidoffset));
805 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
806 le32_to_cpu(pntsd->gsidoffset));
807 dacloffset = le32_to_cpu(pntsd->dacloffset);
808 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
809 ndacloffset = sizeof(struct cifs_ntsd);
810 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
811 ndacl_ptr->revision = dacl_ptr->revision;
812 ndacl_ptr->size = 0;
813 ndacl_ptr->num_aces = 0;
814
815 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
816 nmode);
817 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
818 /* copy sec desc control portion & owner and group sids */
819 copy_sec_desc(pntsd, pnntsd, sidsoffset);
820 *aclflag = CIFS_ACL_DACL;
821 } else {
822 memcpy(pnntsd, pntsd, secdesclen);
823 if (uid_valid(uid)) { /* chown */
824 uid_t id;
825 owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
826 le32_to_cpu(pnntsd->osidoffset));
827 nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
828 GFP_KERNEL);
829 if (!nowner_sid_ptr)
830 return -ENOMEM;
831 id = from_kuid(&init_user_ns, uid);
832 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
833 if (rc) {
834 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
835 __func__, rc, id);
836 kfree(nowner_sid_ptr);
837 return rc;
838 }
839 cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
840 kfree(nowner_sid_ptr);
841 *aclflag = CIFS_ACL_OWNER;
842 }
843 if (gid_valid(gid)) { /* chgrp */
844 gid_t id;
845 group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
846 le32_to_cpu(pnntsd->gsidoffset));
847 ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
848 GFP_KERNEL);
849 if (!ngroup_sid_ptr)
850 return -ENOMEM;
851 id = from_kgid(&init_user_ns, gid);
852 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
853 if (rc) {
854 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
855 __func__, rc, id);
856 kfree(ngroup_sid_ptr);
857 return rc;
858 }
859 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
860 kfree(ngroup_sid_ptr);
861 *aclflag = CIFS_ACL_GROUP;
862 }
863 }
864
865 return rc;
866 }
867
868 static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
869 __u16 fid, u32 *pacllen)
870 {
871 struct cifs_ntsd *pntsd = NULL;
872 unsigned int xid;
873 int rc;
874 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
875
876 if (IS_ERR(tlink))
877 return ERR_CAST(tlink);
878
879 xid = get_xid();
880 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
881 free_xid(xid);
882
883 cifs_put_tlink(tlink);
884
885 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
886 if (rc)
887 return ERR_PTR(rc);
888 return pntsd;
889 }
890
891 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
892 const char *path, u32 *pacllen)
893 {
894 struct cifs_ntsd *pntsd = NULL;
895 int oplock = 0;
896 unsigned int xid;
897 int rc, create_options = 0;
898 __u16 fid;
899 struct cifs_tcon *tcon;
900 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
901
902 if (IS_ERR(tlink))
903 return ERR_CAST(tlink);
904
905 tcon = tlink_tcon(tlink);
906 xid = get_xid();
907
908 if (backup_cred(cifs_sb))
909 create_options |= CREATE_OPEN_BACKUP_INTENT;
910
911 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
912 create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
913 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
914 if (!rc) {
915 rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
916 CIFSSMBClose(xid, tcon, fid);
917 }
918
919 cifs_put_tlink(tlink);
920 free_xid(xid);
921
922 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
923 if (rc)
924 return ERR_PTR(rc);
925 return pntsd;
926 }
927
928 /* Retrieve an ACL from the server */
929 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
930 struct inode *inode, const char *path,
931 u32 *pacllen)
932 {
933 struct cifs_ntsd *pntsd = NULL;
934 struct cifsFileInfo *open_file = NULL;
935
936 if (inode)
937 open_file = find_readable_file(CIFS_I(inode), true);
938 if (!open_file)
939 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
940
941 pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->fid.netfid, pacllen);
942 cifsFileInfo_put(open_file);
943 return pntsd;
944 }
945
946 /* Set an ACL on the server */
947 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
948 struct inode *inode, const char *path, int aclflag)
949 {
950 int oplock = 0;
951 unsigned int xid;
952 int rc, access_flags, create_options = 0;
953 __u16 fid;
954 struct cifs_tcon *tcon;
955 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
956 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
957
958 if (IS_ERR(tlink))
959 return PTR_ERR(tlink);
960
961 tcon = tlink_tcon(tlink);
962 xid = get_xid();
963
964 if (backup_cred(cifs_sb))
965 create_options |= CREATE_OPEN_BACKUP_INTENT;
966
967 if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
968 access_flags = WRITE_OWNER;
969 else
970 access_flags = WRITE_DAC;
971
972 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags,
973 create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
974 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
975 if (rc) {
976 cifs_dbg(VFS, "Unable to open file to set ACL\n");
977 goto out;
978 }
979
980 rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen, aclflag);
981 cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
982
983 CIFSSMBClose(xid, tcon, fid);
984 out:
985 free_xid(xid);
986 cifs_put_tlink(tlink);
987 return rc;
988 }
989
990 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
991 int
992 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
993 struct inode *inode, const char *path, const __u16 *pfid)
994 {
995 struct cifs_ntsd *pntsd = NULL;
996 u32 acllen = 0;
997 int rc = 0;
998
999 cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1000
1001 if (pfid)
1002 pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
1003 else
1004 pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
1005
1006 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1007 if (IS_ERR(pntsd)) {
1008 rc = PTR_ERR(pntsd);
1009 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1010 } else {
1011 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
1012 kfree(pntsd);
1013 if (rc)
1014 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1015 }
1016
1017 return rc;
1018 }
1019
1020 /* Convert mode bits to an ACL so we can update the ACL on the server */
1021 int
1022 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1023 kuid_t uid, kgid_t gid)
1024 {
1025 int rc = 0;
1026 int aclflag = CIFS_ACL_DACL; /* default flag to set */
1027 __u32 secdesclen = 0;
1028 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1029 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1030
1031 cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1032
1033 /* Get the security descriptor */
1034 pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
1035 if (IS_ERR(pntsd)) {
1036 rc = PTR_ERR(pntsd);
1037 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1038 goto out;
1039 }
1040
1041 /*
1042 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1043 * as chmod disables ACEs and set the security descriptor. Allocate
1044 * memory for the smb header, set security descriptor request security
1045 * descriptor parameters, and secuirty descriptor itself
1046 */
1047 secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1048 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1049 if (!pnntsd) {
1050 kfree(pntsd);
1051 return -ENOMEM;
1052 }
1053
1054 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1055 &aclflag);
1056
1057 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1058
1059 if (!rc) {
1060 /* Set the security descriptor */
1061 rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag);
1062 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1063 }
1064
1065 kfree(pnntsd);
1066 kfree(pntsd);
1067 out:
1068 return rc;
1069 }