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