Merge tag 'docs-5.6-fixes' of git://git.lwn.net/linux
[linux-2.6-microblaze.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;
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         if (sidtype == SIDOWNER)
454                 fattr->cf_uid = fuid;
455         else
456                 fattr->cf_gid = fgid;
457         return 0;
458 }
459
460 int
461 init_cifs_idmap(void)
462 {
463         struct cred *cred;
464         struct key *keyring;
465         int ret;
466
467         cifs_dbg(FYI, "Registering the %s key type\n",
468                  cifs_idmap_key_type.name);
469
470         /* create an override credential set with a special thread keyring in
471          * which requests are cached
472          *
473          * this is used to prevent malicious redirections from being installed
474          * with add_key().
475          */
476         cred = prepare_kernel_cred(NULL);
477         if (!cred)
478                 return -ENOMEM;
479
480         keyring = keyring_alloc(".cifs_idmap",
481                                 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
482                                 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
483                                 KEY_USR_VIEW | KEY_USR_READ,
484                                 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
485         if (IS_ERR(keyring)) {
486                 ret = PTR_ERR(keyring);
487                 goto failed_put_cred;
488         }
489
490         ret = register_key_type(&cifs_idmap_key_type);
491         if (ret < 0)
492                 goto failed_put_key;
493
494         /* instruct request_key() to use this special keyring as a cache for
495          * the results it looks up */
496         set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
497         cred->thread_keyring = keyring;
498         cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
499         root_cred = cred;
500
501         cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
502         return 0;
503
504 failed_put_key:
505         key_put(keyring);
506 failed_put_cred:
507         put_cred(cred);
508         return ret;
509 }
510
511 void
512 exit_cifs_idmap(void)
513 {
514         key_revoke(root_cred->thread_keyring);
515         unregister_key_type(&cifs_idmap_key_type);
516         put_cred(root_cred);
517         cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
518 }
519
520 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
521 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
522                                 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
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         owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
537                                 le32_to_cpu(pntsd->osidoffset));
538         nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
539         cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
540
541         /* copy group sid */
542         group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
543                                 le32_to_cpu(pntsd->gsidoffset));
544         ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
545                                         sizeof(struct cifs_sid));
546         cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
547
548         return;
549 }
550
551
552 /*
553    change posix mode to reflect permissions
554    pmode is the existing mode (we only want to overwrite part of this
555    bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
556 */
557 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
558                                  umode_t *pbits_to_set)
559 {
560         __u32 flags = le32_to_cpu(ace_flags);
561         /* the order of ACEs is important.  The canonical order is to begin with
562            DENY entries followed by ALLOW, otherwise an allow entry could be
563            encountered first, making the subsequent deny entry like "dead code"
564            which would be superflous since Windows stops when a match is made
565            for the operation you are trying to perform for your user */
566
567         /* For deny ACEs we change the mask so that subsequent allow access
568            control entries do not turn on the bits we are denying */
569         if (type == ACCESS_DENIED) {
570                 if (flags & GENERIC_ALL)
571                         *pbits_to_set &= ~S_IRWXUGO;
572
573                 if ((flags & GENERIC_WRITE) ||
574                         ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
575                         *pbits_to_set &= ~S_IWUGO;
576                 if ((flags & GENERIC_READ) ||
577                         ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
578                         *pbits_to_set &= ~S_IRUGO;
579                 if ((flags & GENERIC_EXECUTE) ||
580                         ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
581                         *pbits_to_set &= ~S_IXUGO;
582                 return;
583         } else if (type != ACCESS_ALLOWED) {
584                 cifs_dbg(VFS, "unknown access control type %d\n", type);
585                 return;
586         }
587         /* else ACCESS_ALLOWED type */
588
589         if (flags & GENERIC_ALL) {
590                 *pmode |= (S_IRWXUGO & (*pbits_to_set));
591                 cifs_dbg(NOISY, "all perms\n");
592                 return;
593         }
594         if ((flags & GENERIC_WRITE) ||
595                         ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
596                 *pmode |= (S_IWUGO & (*pbits_to_set));
597         if ((flags & GENERIC_READ) ||
598                         ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
599                 *pmode |= (S_IRUGO & (*pbits_to_set));
600         if ((flags & GENERIC_EXECUTE) ||
601                         ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
602                 *pmode |= (S_IXUGO & (*pbits_to_set));
603
604         cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode);
605         return;
606 }
607
608 /*
609    Generate access flags to reflect permissions mode is the existing mode.
610    This function is called for every ACE in the DACL whose SID matches
611    with either owner or group or everyone.
612 */
613
614 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
615                                 __u32 *pace_flags)
616 {
617         /* reset access mask */
618         *pace_flags = 0x0;
619
620         /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
621         mode &= bits_to_use;
622
623         /* check for R/W/X UGO since we do not know whose flags
624            is this but we have cleared all the bits sans RWX for
625            either user or group or other as per bits_to_use */
626         if (mode & S_IRUGO)
627                 *pace_flags |= SET_FILE_READ_RIGHTS;
628         if (mode & S_IWUGO)
629                 *pace_flags |= SET_FILE_WRITE_RIGHTS;
630         if (mode & S_IXUGO)
631                 *pace_flags |= SET_FILE_EXEC_RIGHTS;
632
633         cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n",
634                  mode, *pace_flags);
635         return;
636 }
637
638 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
639                         const struct cifs_sid *psid, __u64 nmode, umode_t bits)
640 {
641         int i;
642         __u16 size = 0;
643         __u32 access_req = 0;
644
645         pntace->type = ACCESS_ALLOWED;
646         pntace->flags = 0x0;
647         mode_to_access_flags(nmode, bits, &access_req);
648         if (!access_req)
649                 access_req = SET_MINIMUM_RIGHTS;
650         pntace->access_req = cpu_to_le32(access_req);
651
652         pntace->sid.revision = psid->revision;
653         pntace->sid.num_subauth = psid->num_subauth;
654         for (i = 0; i < NUM_AUTHS; i++)
655                 pntace->sid.authority[i] = psid->authority[i];
656         for (i = 0; i < psid->num_subauth; i++)
657                 pntace->sid.sub_auth[i] = psid->sub_auth[i];
658
659         size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
660         pntace->size = cpu_to_le16(size);
661
662         return size;
663 }
664
665
666 #ifdef CONFIG_CIFS_DEBUG2
667 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
668 {
669         int num_subauth;
670
671         /* validate that we do not go past end of acl */
672
673         if (le16_to_cpu(pace->size) < 16) {
674                 cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
675                 return;
676         }
677
678         if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
679                 cifs_dbg(VFS, "ACL too small to parse ACE\n");
680                 return;
681         }
682
683         num_subauth = pace->sid.num_subauth;
684         if (num_subauth) {
685                 int i;
686                 cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
687                          pace->sid.revision, pace->sid.num_subauth, pace->type,
688                          pace->flags, le16_to_cpu(pace->size));
689                 for (i = 0; i < num_subauth; ++i) {
690                         cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
691                                  i, le32_to_cpu(pace->sid.sub_auth[i]));
692                 }
693
694                 /* BB add length check to make sure that we do not have huge
695                         num auths and therefore go off the end */
696         }
697
698         return;
699 }
700 #endif
701
702 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
703                        struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
704                        struct cifs_fattr *fattr, bool mode_from_special_sid)
705 {
706         int i;
707         int num_aces = 0;
708         int acl_size;
709         char *acl_base;
710         struct cifs_ace **ppace;
711
712         /* BB need to add parm so we can store the SID BB */
713
714         if (!pdacl) {
715                 /* no DACL in the security descriptor, set
716                    all the permissions for user/group/other */
717                 fattr->cf_mode |= S_IRWXUGO;
718                 return;
719         }
720
721         /* validate that we do not go past end of acl */
722         if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
723                 cifs_dbg(VFS, "ACL too small to parse DACL\n");
724                 return;
725         }
726
727         cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
728                  le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
729                  le32_to_cpu(pdacl->num_aces));
730
731         /* reset rwx permissions for user/group/other.
732            Also, if num_aces is 0 i.e. DACL has no ACEs,
733            user/group/other have no permissions */
734         fattr->cf_mode &= ~(S_IRWXUGO);
735
736         acl_base = (char *)pdacl;
737         acl_size = sizeof(struct cifs_acl);
738
739         num_aces = le32_to_cpu(pdacl->num_aces);
740         if (num_aces > 0) {
741                 umode_t user_mask = S_IRWXU;
742                 umode_t group_mask = S_IRWXG;
743                 umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
744
745                 if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
746                         return;
747                 ppace = kmalloc_array(num_aces, sizeof(struct cifs_ace *),
748                                       GFP_KERNEL);
749                 if (!ppace)
750                         return;
751
752                 for (i = 0; i < num_aces; ++i) {
753                         ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
754 #ifdef CONFIG_CIFS_DEBUG2
755                         dump_ace(ppace[i], end_of_acl);
756 #endif
757                         if (mode_from_special_sid &&
758                             (compare_sids(&(ppace[i]->sid),
759                                           &sid_unix_NFS_mode) == 0)) {
760                                 /*
761                                  * Full permissions are:
762                                  * 07777 = S_ISUID | S_ISGID | S_ISVTX |
763                                  *         S_IRWXU | S_IRWXG | S_IRWXO
764                                  */
765                                 fattr->cf_mode &= ~07777;
766                                 fattr->cf_mode |=
767                                         le32_to_cpu(ppace[i]->sid.sub_auth[2]);
768                                 break;
769                         } else if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
770                                 access_flags_to_mode(ppace[i]->access_req,
771                                                      ppace[i]->type,
772                                                      &fattr->cf_mode,
773                                                      &user_mask);
774                         else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
775                                 access_flags_to_mode(ppace[i]->access_req,
776                                                      ppace[i]->type,
777                                                      &fattr->cf_mode,
778                                                      &group_mask);
779                         else if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
780                                 access_flags_to_mode(ppace[i]->access_req,
781                                                      ppace[i]->type,
782                                                      &fattr->cf_mode,
783                                                      &other_mask);
784                         else if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
785                                 access_flags_to_mode(ppace[i]->access_req,
786                                                      ppace[i]->type,
787                                                      &fattr->cf_mode,
788                                                      &other_mask);
789
790
791 /*                      memcpy((void *)(&(cifscred->aces[i])),
792                                 (void *)ppace[i],
793                                 sizeof(struct cifs_ace)); */
794
795                         acl_base = (char *)ppace[i];
796                         acl_size = le16_to_cpu(ppace[i]->size);
797                 }
798
799                 kfree(ppace);
800         }
801
802         return;
803 }
804
805 unsigned int setup_authusers_ACE(struct cifs_ace *pntace)
806 {
807         int i;
808         unsigned int ace_size = 20;
809
810         pntace->type = ACCESS_ALLOWED_ACE_TYPE;
811         pntace->flags = 0x0;
812         pntace->access_req = cpu_to_le32(GENERIC_ALL);
813         pntace->sid.num_subauth = 1;
814         pntace->sid.revision = 1;
815         for (i = 0; i < NUM_AUTHS; i++)
816                 pntace->sid.authority[i] =  sid_authusers.authority[i];
817
818         pntace->sid.sub_auth[0] =  sid_authusers.sub_auth[0];
819
820         /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
821         pntace->size = cpu_to_le16(ace_size);
822         return ace_size;
823 }
824
825 /*
826  * Fill in the special SID based on the mode. See
827  * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
828  */
829 unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
830 {
831         int i;
832         unsigned int ace_size = 28;
833
834         pntace->type = ACCESS_DENIED_ACE_TYPE;
835         pntace->flags = 0x0;
836         pntace->access_req = 0;
837         pntace->sid.num_subauth = 3;
838         pntace->sid.revision = 1;
839         for (i = 0; i < NUM_AUTHS; i++)
840                 pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
841
842         pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
843         pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
844         pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
845
846         /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
847         pntace->size = cpu_to_le16(ace_size);
848         return ace_size;
849 }
850
851 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
852                         struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
853 {
854         u16 size = 0;
855         u32 num_aces = 0;
856         struct cifs_acl *pnndacl;
857
858         pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
859
860         if (modefromsid) {
861                 struct cifs_ace *pntace =
862                         (struct cifs_ace *)((char *)pnndacl + size);
863
864                 size += setup_special_mode_ACE(pntace, nmode);
865                 num_aces++;
866         }
867
868         size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
869                                         pownersid, nmode, S_IRWXU);
870         num_aces++;
871         size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
872                                         pgrpsid, nmode, S_IRWXG);
873         num_aces++;
874         size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
875                                          &sid_everyone, nmode, S_IRWXO);
876         num_aces++;
877
878         pndacl->num_aces = cpu_to_le32(num_aces);
879         pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
880
881         return 0;
882 }
883
884
885 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
886 {
887         /* BB need to add parm so we can store the SID BB */
888
889         /* validate that we do not go past end of ACL - sid must be at least 8
890            bytes long (assuming no sub-auths - e.g. the null SID */
891         if (end_of_acl < (char *)psid + 8) {
892                 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
893                 return -EINVAL;
894         }
895
896 #ifdef CONFIG_CIFS_DEBUG2
897         if (psid->num_subauth) {
898                 int i;
899                 cifs_dbg(FYI, "SID revision %d num_auth %d\n",
900                          psid->revision, psid->num_subauth);
901
902                 for (i = 0; i < psid->num_subauth; i++) {
903                         cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
904                                  i, le32_to_cpu(psid->sub_auth[i]));
905                 }
906
907                 /* BB add length check to make sure that we do not have huge
908                         num auths and therefore go off the end */
909                 cifs_dbg(FYI, "RID 0x%x\n",
910                          le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
911         }
912 #endif
913
914         return 0;
915 }
916
917
918 /* Convert CIFS ACL to POSIX form */
919 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
920                 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
921                 bool get_mode_from_special_sid)
922 {
923         int rc = 0;
924         struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
925         struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
926         char *end_of_acl = ((char *)pntsd) + acl_len;
927         __u32 dacloffset;
928
929         if (pntsd == NULL)
930                 return -EIO;
931
932         owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
933                                 le32_to_cpu(pntsd->osidoffset));
934         group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
935                                 le32_to_cpu(pntsd->gsidoffset));
936         dacloffset = le32_to_cpu(pntsd->dacloffset);
937         dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
938         cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
939                  pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
940                  le32_to_cpu(pntsd->gsidoffset),
941                  le32_to_cpu(pntsd->sacloffset), dacloffset);
942 /*      cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
943         rc = parse_sid(owner_sid_ptr, end_of_acl);
944         if (rc) {
945                 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
946                 return rc;
947         }
948         rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
949         if (rc) {
950                 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
951                          __func__, rc);
952                 return rc;
953         }
954
955         rc = parse_sid(group_sid_ptr, end_of_acl);
956         if (rc) {
957                 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
958                          __func__, rc);
959                 return rc;
960         }
961         rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
962         if (rc) {
963                 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
964                          __func__, rc);
965                 return rc;
966         }
967
968         if (dacloffset)
969                 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
970                            group_sid_ptr, fattr, get_mode_from_special_sid);
971         else
972                 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
973
974         return rc;
975 }
976
977 /* Convert permission bits from mode to equivalent CIFS ACL */
978 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
979         __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
980         bool mode_from_sid, int *aclflag)
981 {
982         int rc = 0;
983         __u32 dacloffset;
984         __u32 ndacloffset;
985         __u32 sidsoffset;
986         struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
987         struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
988         struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
989         struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
990
991         if (nmode != NO_CHANGE_64) { /* chmod */
992                 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
993                                 le32_to_cpu(pntsd->osidoffset));
994                 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
995                                 le32_to_cpu(pntsd->gsidoffset));
996                 dacloffset = le32_to_cpu(pntsd->dacloffset);
997                 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
998                 ndacloffset = sizeof(struct cifs_ntsd);
999                 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1000                 ndacl_ptr->revision = dacl_ptr->revision;
1001                 ndacl_ptr->size = 0;
1002                 ndacl_ptr->num_aces = 0;
1003
1004                 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1005                                     nmode, mode_from_sid);
1006                 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1007                 /* copy sec desc control portion & owner and group sids */
1008                 copy_sec_desc(pntsd, pnntsd, sidsoffset);
1009                 *aclflag = CIFS_ACL_DACL;
1010         } else {
1011                 memcpy(pnntsd, pntsd, secdesclen);
1012                 if (uid_valid(uid)) { /* chown */
1013                         uid_t id;
1014                         owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1015                                         le32_to_cpu(pnntsd->osidoffset));
1016                         nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1017                                                                 GFP_KERNEL);
1018                         if (!nowner_sid_ptr)
1019                                 return -ENOMEM;
1020                         id = from_kuid(&init_user_ns, uid);
1021                         rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1022                         if (rc) {
1023                                 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1024                                          __func__, rc, id);
1025                                 kfree(nowner_sid_ptr);
1026                                 return rc;
1027                         }
1028                         cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1029                         kfree(nowner_sid_ptr);
1030                         *aclflag = CIFS_ACL_OWNER;
1031                 }
1032                 if (gid_valid(gid)) { /* chgrp */
1033                         gid_t id;
1034                         group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1035                                         le32_to_cpu(pnntsd->gsidoffset));
1036                         ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1037                                                                 GFP_KERNEL);
1038                         if (!ngroup_sid_ptr)
1039                                 return -ENOMEM;
1040                         id = from_kgid(&init_user_ns, gid);
1041                         rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1042                         if (rc) {
1043                                 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1044                                          __func__, rc, id);
1045                                 kfree(ngroup_sid_ptr);
1046                                 return rc;
1047                         }
1048                         cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1049                         kfree(ngroup_sid_ptr);
1050                         *aclflag = CIFS_ACL_GROUP;
1051                 }
1052         }
1053
1054         return rc;
1055 }
1056
1057 struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1058                 const struct cifs_fid *cifsfid, u32 *pacllen)
1059 {
1060         struct cifs_ntsd *pntsd = NULL;
1061         unsigned int xid;
1062         int rc;
1063         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1064
1065         if (IS_ERR(tlink))
1066                 return ERR_CAST(tlink);
1067
1068         xid = get_xid();
1069         rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1070                                 pacllen);
1071         free_xid(xid);
1072
1073         cifs_put_tlink(tlink);
1074
1075         cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1076         if (rc)
1077                 return ERR_PTR(rc);
1078         return pntsd;
1079 }
1080
1081 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1082                 const char *path, u32 *pacllen)
1083 {
1084         struct cifs_ntsd *pntsd = NULL;
1085         int oplock = 0;
1086         unsigned int xid;
1087         int rc;
1088         struct cifs_tcon *tcon;
1089         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1090         struct cifs_fid fid;
1091         struct cifs_open_parms oparms;
1092
1093         if (IS_ERR(tlink))
1094                 return ERR_CAST(tlink);
1095
1096         tcon = tlink_tcon(tlink);
1097         xid = get_xid();
1098
1099         oparms.tcon = tcon;
1100         oparms.cifs_sb = cifs_sb;
1101         oparms.desired_access = READ_CONTROL;
1102         oparms.create_options = cifs_create_options(cifs_sb, 0);
1103         oparms.disposition = FILE_OPEN;
1104         oparms.path = path;
1105         oparms.fid = &fid;
1106         oparms.reconnect = false;
1107
1108         rc = CIFS_open(xid, &oparms, &oplock, NULL);
1109         if (!rc) {
1110                 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1111                 CIFSSMBClose(xid, tcon, fid.netfid);
1112         }
1113
1114         cifs_put_tlink(tlink);
1115         free_xid(xid);
1116
1117         cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1118         if (rc)
1119                 return ERR_PTR(rc);
1120         return pntsd;
1121 }
1122
1123 /* Retrieve an ACL from the server */
1124 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1125                                       struct inode *inode, const char *path,
1126                                       u32 *pacllen)
1127 {
1128         struct cifs_ntsd *pntsd = NULL;
1129         struct cifsFileInfo *open_file = NULL;
1130
1131         if (inode)
1132                 open_file = find_readable_file(CIFS_I(inode), true);
1133         if (!open_file)
1134                 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1135
1136         pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1137         cifsFileInfo_put(open_file);
1138         return pntsd;
1139 }
1140
1141  /* Set an ACL on the server */
1142 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1143                         struct inode *inode, const char *path, int aclflag)
1144 {
1145         int oplock = 0;
1146         unsigned int xid;
1147         int rc, access_flags;
1148         struct cifs_tcon *tcon;
1149         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1150         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1151         struct cifs_fid fid;
1152         struct cifs_open_parms oparms;
1153
1154         if (IS_ERR(tlink))
1155                 return PTR_ERR(tlink);
1156
1157         tcon = tlink_tcon(tlink);
1158         xid = get_xid();
1159
1160         if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1161                 access_flags = WRITE_OWNER;
1162         else
1163                 access_flags = WRITE_DAC;
1164
1165         oparms.tcon = tcon;
1166         oparms.cifs_sb = cifs_sb;
1167         oparms.desired_access = access_flags;
1168         oparms.create_options = cifs_create_options(cifs_sb, 0);
1169         oparms.disposition = FILE_OPEN;
1170         oparms.path = path;
1171         oparms.fid = &fid;
1172         oparms.reconnect = false;
1173
1174         rc = CIFS_open(xid, &oparms, &oplock, NULL);
1175         if (rc) {
1176                 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1177                 goto out;
1178         }
1179
1180         rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1181         cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1182
1183         CIFSSMBClose(xid, tcon, fid.netfid);
1184 out:
1185         free_xid(xid);
1186         cifs_put_tlink(tlink);
1187         return rc;
1188 }
1189
1190 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1191 int
1192 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1193                   struct inode *inode, bool mode_from_special_sid,
1194                   const char *path, const struct cifs_fid *pfid)
1195 {
1196         struct cifs_ntsd *pntsd = NULL;
1197         u32 acllen = 0;
1198         int rc = 0;
1199         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1200         struct smb_version_operations *ops;
1201
1202         cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1203
1204         if (IS_ERR(tlink))
1205                 return PTR_ERR(tlink);
1206
1207         ops = tlink_tcon(tlink)->ses->server->ops;
1208
1209         if (pfid && (ops->get_acl_by_fid))
1210                 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1211         else if (ops->get_acl)
1212                 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1213         else {
1214                 cifs_put_tlink(tlink);
1215                 return -EOPNOTSUPP;
1216         }
1217         /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1218         if (IS_ERR(pntsd)) {
1219                 rc = PTR_ERR(pntsd);
1220                 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1221         } else if (mode_from_special_sid) {
1222                 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1223         } else {
1224                 /* get approximated mode from ACL */
1225                 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1226                 kfree(pntsd);
1227                 if (rc)
1228                         cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1229         }
1230
1231         cifs_put_tlink(tlink);
1232
1233         return rc;
1234 }
1235
1236 /* Convert mode bits to an ACL so we can update the ACL on the server */
1237 int
1238 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1239                         kuid_t uid, kgid_t gid)
1240 {
1241         int rc = 0;
1242         int aclflag = CIFS_ACL_DACL; /* default flag to set */
1243         __u32 secdesclen = 0;
1244         struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1245         struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1246         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1247         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1248         struct smb_version_operations *ops;
1249         bool mode_from_sid;
1250
1251         if (IS_ERR(tlink))
1252                 return PTR_ERR(tlink);
1253
1254         ops = tlink_tcon(tlink)->ses->server->ops;
1255
1256         cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1257
1258         /* Get the security descriptor */
1259
1260         if (ops->get_acl == NULL) {
1261                 cifs_put_tlink(tlink);
1262                 return -EOPNOTSUPP;
1263         }
1264
1265         pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1266         if (IS_ERR(pntsd)) {
1267                 rc = PTR_ERR(pntsd);
1268                 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1269                 cifs_put_tlink(tlink);
1270                 return rc;
1271         }
1272
1273         /*
1274          * Add three ACEs for owner, group, everyone getting rid of other ACEs
1275          * as chmod disables ACEs and set the security descriptor. Allocate
1276          * memory for the smb header, set security descriptor request security
1277          * descriptor parameters, and secuirty descriptor itself
1278          */
1279         secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1280         pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1281         if (!pnntsd) {
1282                 kfree(pntsd);
1283                 cifs_put_tlink(tlink);
1284                 return -ENOMEM;
1285         }
1286
1287         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1288                 mode_from_sid = true;
1289         else
1290                 mode_from_sid = false;
1291
1292         rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1293                             mode_from_sid, &aclflag);
1294
1295         cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1296
1297         if (ops->set_acl == NULL)
1298                 rc = -EOPNOTSUPP;
1299
1300         if (!rc) {
1301                 /* Set the security descriptor */
1302                 rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1303                 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1304         }
1305         cifs_put_tlink(tlink);
1306
1307         kfree(pnntsd);
1308         kfree(pntsd);
1309         return rc;
1310 }