Merge tag 'v5.7-rc1' into locking/kcsan, to resolve conflicts and refresh
[linux-2.6-block.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 }