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