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