Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[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 0x%x\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: 0x%x, 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 /*
806  * Fill in the special SID based on the mode. See
807  * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
808  */
809 unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
810 {
811         int i;
812         unsigned int ace_size = 28;
813
814         pntace->type = ACCESS_DENIED_ACE_TYPE;
815         pntace->flags = 0x0;
816         pntace->access_req = 0;
817         pntace->sid.num_subauth = 3;
818         pntace->sid.revision = 1;
819         for (i = 0; i < NUM_AUTHS; i++)
820                 pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
821
822         pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
823         pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
824         pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
825
826         /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
827         pntace->size = cpu_to_le16(ace_size);
828         return ace_size;
829 }
830
831 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
832                         struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
833 {
834         u16 size = 0;
835         u32 num_aces = 0;
836         struct cifs_acl *pnndacl;
837
838         pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
839
840         if (modefromsid) {
841                 struct cifs_ace *pntace =
842                         (struct cifs_ace *)((char *)pnndacl + size);
843
844                 size += setup_special_mode_ACE(pntace, nmode);
845                 num_aces++;
846         }
847
848         size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
849                                         pownersid, nmode, S_IRWXU);
850         num_aces++;
851         size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
852                                         pgrpsid, nmode, S_IRWXG);
853         num_aces++;
854         size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
855                                          &sid_everyone, nmode, S_IRWXO);
856         num_aces++;
857
858         pndacl->num_aces = cpu_to_le32(num_aces);
859         pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
860
861         return 0;
862 }
863
864
865 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
866 {
867         /* BB need to add parm so we can store the SID BB */
868
869         /* validate that we do not go past end of ACL - sid must be at least 8
870            bytes long (assuming no sub-auths - e.g. the null SID */
871         if (end_of_acl < (char *)psid + 8) {
872                 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
873                 return -EINVAL;
874         }
875
876 #ifdef CONFIG_CIFS_DEBUG2
877         if (psid->num_subauth) {
878                 int i;
879                 cifs_dbg(FYI, "SID revision %d num_auth %d\n",
880                          psid->revision, psid->num_subauth);
881
882                 for (i = 0; i < psid->num_subauth; i++) {
883                         cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
884                                  i, le32_to_cpu(psid->sub_auth[i]));
885                 }
886
887                 /* BB add length check to make sure that we do not have huge
888                         num auths and therefore go off the end */
889                 cifs_dbg(FYI, "RID 0x%x\n",
890                          le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
891         }
892 #endif
893
894         return 0;
895 }
896
897
898 /* Convert CIFS ACL to POSIX form */
899 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
900                 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr,
901                 bool get_mode_from_special_sid)
902 {
903         int rc = 0;
904         struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
905         struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
906         char *end_of_acl = ((char *)pntsd) + acl_len;
907         __u32 dacloffset;
908
909         if (pntsd == NULL)
910                 return -EIO;
911
912         owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
913                                 le32_to_cpu(pntsd->osidoffset));
914         group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
915                                 le32_to_cpu(pntsd->gsidoffset));
916         dacloffset = le32_to_cpu(pntsd->dacloffset);
917         dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
918         cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
919                  pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
920                  le32_to_cpu(pntsd->gsidoffset),
921                  le32_to_cpu(pntsd->sacloffset), dacloffset);
922 /*      cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
923         rc = parse_sid(owner_sid_ptr, end_of_acl);
924         if (rc) {
925                 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
926                 return rc;
927         }
928         rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
929         if (rc) {
930                 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
931                          __func__, rc);
932                 return rc;
933         }
934
935         rc = parse_sid(group_sid_ptr, end_of_acl);
936         if (rc) {
937                 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
938                          __func__, rc);
939                 return rc;
940         }
941         rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
942         if (rc) {
943                 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
944                          __func__, rc);
945                 return rc;
946         }
947
948         if (dacloffset)
949                 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
950                            group_sid_ptr, fattr, get_mode_from_special_sid);
951         else
952                 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
953
954         return rc;
955 }
956
957 /* Convert permission bits from mode to equivalent CIFS ACL */
958 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
959         __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
960         bool mode_from_sid, int *aclflag)
961 {
962         int rc = 0;
963         __u32 dacloffset;
964         __u32 ndacloffset;
965         __u32 sidsoffset;
966         struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
967         struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
968         struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
969         struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
970
971         if (nmode != NO_CHANGE_64) { /* chmod */
972                 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
973                                 le32_to_cpu(pntsd->osidoffset));
974                 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
975                                 le32_to_cpu(pntsd->gsidoffset));
976                 dacloffset = le32_to_cpu(pntsd->dacloffset);
977                 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
978                 ndacloffset = sizeof(struct cifs_ntsd);
979                 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
980                 ndacl_ptr->revision = dacl_ptr->revision;
981                 ndacl_ptr->size = 0;
982                 ndacl_ptr->num_aces = 0;
983
984                 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
985                                     nmode, mode_from_sid);
986                 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
987                 /* copy sec desc control portion & owner and group sids */
988                 copy_sec_desc(pntsd, pnntsd, sidsoffset);
989                 *aclflag = CIFS_ACL_DACL;
990         } else {
991                 memcpy(pnntsd, pntsd, secdesclen);
992                 if (uid_valid(uid)) { /* chown */
993                         uid_t id;
994                         owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
995                                         le32_to_cpu(pnntsd->osidoffset));
996                         nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
997                                                                 GFP_KERNEL);
998                         if (!nowner_sid_ptr)
999                                 return -ENOMEM;
1000                         id = from_kuid(&init_user_ns, uid);
1001                         rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1002                         if (rc) {
1003                                 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1004                                          __func__, rc, id);
1005                                 kfree(nowner_sid_ptr);
1006                                 return rc;
1007                         }
1008                         cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1009                         kfree(nowner_sid_ptr);
1010                         *aclflag = CIFS_ACL_OWNER;
1011                 }
1012                 if (gid_valid(gid)) { /* chgrp */
1013                         gid_t id;
1014                         group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1015                                         le32_to_cpu(pnntsd->gsidoffset));
1016                         ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1017                                                                 GFP_KERNEL);
1018                         if (!ngroup_sid_ptr)
1019                                 return -ENOMEM;
1020                         id = from_kgid(&init_user_ns, gid);
1021                         rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1022                         if (rc) {
1023                                 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1024                                          __func__, rc, id);
1025                                 kfree(ngroup_sid_ptr);
1026                                 return rc;
1027                         }
1028                         cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1029                         kfree(ngroup_sid_ptr);
1030                         *aclflag = CIFS_ACL_GROUP;
1031                 }
1032         }
1033
1034         return rc;
1035 }
1036
1037 struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1038                 const struct cifs_fid *cifsfid, u32 *pacllen)
1039 {
1040         struct cifs_ntsd *pntsd = NULL;
1041         unsigned int xid;
1042         int rc;
1043         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1044
1045         if (IS_ERR(tlink))
1046                 return ERR_CAST(tlink);
1047
1048         xid = get_xid();
1049         rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1050                                 pacllen);
1051         free_xid(xid);
1052
1053         cifs_put_tlink(tlink);
1054
1055         cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1056         if (rc)
1057                 return ERR_PTR(rc);
1058         return pntsd;
1059 }
1060
1061 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1062                 const char *path, u32 *pacllen)
1063 {
1064         struct cifs_ntsd *pntsd = NULL;
1065         int oplock = 0;
1066         unsigned int xid;
1067         int rc, create_options = 0;
1068         struct cifs_tcon *tcon;
1069         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1070         struct cifs_fid fid;
1071         struct cifs_open_parms oparms;
1072
1073         if (IS_ERR(tlink))
1074                 return ERR_CAST(tlink);
1075
1076         tcon = tlink_tcon(tlink);
1077         xid = get_xid();
1078
1079         if (backup_cred(cifs_sb))
1080                 create_options |= CREATE_OPEN_BACKUP_INTENT;
1081
1082         oparms.tcon = tcon;
1083         oparms.cifs_sb = cifs_sb;
1084         oparms.desired_access = READ_CONTROL;
1085         oparms.create_options = create_options;
1086         oparms.disposition = FILE_OPEN;
1087         oparms.path = path;
1088         oparms.fid = &fid;
1089         oparms.reconnect = false;
1090
1091         rc = CIFS_open(xid, &oparms, &oplock, NULL);
1092         if (!rc) {
1093                 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1094                 CIFSSMBClose(xid, tcon, fid.netfid);
1095         }
1096
1097         cifs_put_tlink(tlink);
1098         free_xid(xid);
1099
1100         cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1101         if (rc)
1102                 return ERR_PTR(rc);
1103         return pntsd;
1104 }
1105
1106 /* Retrieve an ACL from the server */
1107 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1108                                       struct inode *inode, const char *path,
1109                                       u32 *pacllen)
1110 {
1111         struct cifs_ntsd *pntsd = NULL;
1112         struct cifsFileInfo *open_file = NULL;
1113
1114         if (inode)
1115                 open_file = find_readable_file(CIFS_I(inode), true);
1116         if (!open_file)
1117                 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1118
1119         pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1120         cifsFileInfo_put(open_file);
1121         return pntsd;
1122 }
1123
1124  /* Set an ACL on the server */
1125 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1126                         struct inode *inode, const char *path, int aclflag)
1127 {
1128         int oplock = 0;
1129         unsigned int xid;
1130         int rc, access_flags, create_options = 0;
1131         struct cifs_tcon *tcon;
1132         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1133         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1134         struct cifs_fid fid;
1135         struct cifs_open_parms oparms;
1136
1137         if (IS_ERR(tlink))
1138                 return PTR_ERR(tlink);
1139
1140         tcon = tlink_tcon(tlink);
1141         xid = get_xid();
1142
1143         if (backup_cred(cifs_sb))
1144                 create_options |= CREATE_OPEN_BACKUP_INTENT;
1145
1146         if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1147                 access_flags = WRITE_OWNER;
1148         else
1149                 access_flags = WRITE_DAC;
1150
1151         oparms.tcon = tcon;
1152         oparms.cifs_sb = cifs_sb;
1153         oparms.desired_access = access_flags;
1154         oparms.create_options = create_options;
1155         oparms.disposition = FILE_OPEN;
1156         oparms.path = path;
1157         oparms.fid = &fid;
1158         oparms.reconnect = false;
1159
1160         rc = CIFS_open(xid, &oparms, &oplock, NULL);
1161         if (rc) {
1162                 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1163                 goto out;
1164         }
1165
1166         rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1167         cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1168
1169         CIFSSMBClose(xid, tcon, fid.netfid);
1170 out:
1171         free_xid(xid);
1172         cifs_put_tlink(tlink);
1173         return rc;
1174 }
1175
1176 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1177 int
1178 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1179                   struct inode *inode, bool mode_from_special_sid,
1180                   const char *path, const struct cifs_fid *pfid)
1181 {
1182         struct cifs_ntsd *pntsd = NULL;
1183         u32 acllen = 0;
1184         int rc = 0;
1185         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1186         struct smb_version_operations *ops;
1187
1188         cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1189
1190         if (IS_ERR(tlink))
1191                 return PTR_ERR(tlink);
1192
1193         ops = tlink_tcon(tlink)->ses->server->ops;
1194
1195         if (pfid && (ops->get_acl_by_fid))
1196                 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1197         else if (ops->get_acl)
1198                 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1199         else {
1200                 cifs_put_tlink(tlink);
1201                 return -EOPNOTSUPP;
1202         }
1203         /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1204         if (IS_ERR(pntsd)) {
1205                 rc = PTR_ERR(pntsd);
1206                 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1207         } else if (mode_from_special_sid) {
1208                 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1209         } else {
1210                 /* get approximated mode from ACL */
1211                 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1212                 kfree(pntsd);
1213                 if (rc)
1214                         cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1215         }
1216
1217         cifs_put_tlink(tlink);
1218
1219         return rc;
1220 }
1221
1222 /* Convert mode bits to an ACL so we can update the ACL on the server */
1223 int
1224 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1225                         kuid_t uid, kgid_t gid)
1226 {
1227         int rc = 0;
1228         int aclflag = CIFS_ACL_DACL; /* default flag to set */
1229         __u32 secdesclen = 0;
1230         struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1231         struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1232         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1233         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1234         struct smb_version_operations *ops;
1235         bool mode_from_sid;
1236
1237         if (IS_ERR(tlink))
1238                 return PTR_ERR(tlink);
1239
1240         ops = tlink_tcon(tlink)->ses->server->ops;
1241
1242         cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1243
1244         /* Get the security descriptor */
1245
1246         if (ops->get_acl == NULL) {
1247                 cifs_put_tlink(tlink);
1248                 return -EOPNOTSUPP;
1249         }
1250
1251         pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1252         if (IS_ERR(pntsd)) {
1253                 rc = PTR_ERR(pntsd);
1254                 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1255                 cifs_put_tlink(tlink);
1256                 return rc;
1257         }
1258
1259         /*
1260          * Add three ACEs for owner, group, everyone getting rid of other ACEs
1261          * as chmod disables ACEs and set the security descriptor. Allocate
1262          * memory for the smb header, set security descriptor request security
1263          * descriptor parameters, and secuirty descriptor itself
1264          */
1265         secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1266         pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1267         if (!pnntsd) {
1268                 kfree(pntsd);
1269                 cifs_put_tlink(tlink);
1270                 return -ENOMEM;
1271         }
1272
1273         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1274                 mode_from_sid = true;
1275         else
1276                 mode_from_sid = false;
1277
1278         rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1279                             mode_from_sid, &aclflag);
1280
1281         cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1282
1283         if (ops->set_acl == NULL)
1284                 rc = -EOPNOTSUPP;
1285
1286         if (!rc) {
1287                 /* Set the security descriptor */
1288                 rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1289                 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1290         }
1291         cifs_put_tlink(tlink);
1292
1293         kfree(pnntsd);
1294         kfree(pntsd);
1295         return rc;
1296 }