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