GNU Linux-libre 5.4.257-gnu1
[releases.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 %04o\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: %04o, 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;
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         oparms.tcon = tcon;
1072         oparms.cifs_sb = cifs_sb;
1073         oparms.desired_access = READ_CONTROL;
1074         oparms.create_options = cifs_create_options(cifs_sb, 0);
1075         oparms.disposition = FILE_OPEN;
1076         oparms.path = path;
1077         oparms.fid = &fid;
1078         oparms.reconnect = false;
1079
1080         rc = CIFS_open(xid, &oparms, &oplock, NULL);
1081         if (!rc) {
1082                 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1083                 CIFSSMBClose(xid, tcon, fid.netfid);
1084         }
1085
1086         cifs_put_tlink(tlink);
1087         free_xid(xid);
1088
1089         cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1090         if (rc)
1091                 return ERR_PTR(rc);
1092         return pntsd;
1093 }
1094
1095 /* Retrieve an ACL from the server */
1096 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1097                                       struct inode *inode, const char *path,
1098                                       u32 *pacllen)
1099 {
1100         struct cifs_ntsd *pntsd = NULL;
1101         struct cifsFileInfo *open_file = NULL;
1102
1103         if (inode)
1104                 open_file = find_readable_file(CIFS_I(inode), true);
1105         if (!open_file)
1106                 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1107
1108         pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1109         cifsFileInfo_put(open_file);
1110         return pntsd;
1111 }
1112
1113  /* Set an ACL on the server */
1114 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1115                         struct inode *inode, const char *path, int aclflag)
1116 {
1117         int oplock = 0;
1118         unsigned int xid;
1119         int rc, access_flags;
1120         struct cifs_tcon *tcon;
1121         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1122         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1123         struct cifs_fid fid;
1124         struct cifs_open_parms oparms;
1125
1126         if (IS_ERR(tlink))
1127                 return PTR_ERR(tlink);
1128
1129         tcon = tlink_tcon(tlink);
1130         xid = get_xid();
1131
1132         if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1133                 access_flags = WRITE_OWNER;
1134         else
1135                 access_flags = WRITE_DAC;
1136
1137         oparms.tcon = tcon;
1138         oparms.cifs_sb = cifs_sb;
1139         oparms.desired_access = access_flags;
1140         oparms.create_options = cifs_create_options(cifs_sb, 0);
1141         oparms.disposition = FILE_OPEN;
1142         oparms.path = path;
1143         oparms.fid = &fid;
1144         oparms.reconnect = false;
1145
1146         rc = CIFS_open(xid, &oparms, &oplock, NULL);
1147         if (rc) {
1148                 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1149                 goto out;
1150         }
1151
1152         rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1153         cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1154
1155         CIFSSMBClose(xid, tcon, fid.netfid);
1156 out:
1157         free_xid(xid);
1158         cifs_put_tlink(tlink);
1159         return rc;
1160 }
1161
1162 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */
1163 int
1164 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1165                   struct inode *inode, bool mode_from_special_sid,
1166                   const char *path, const struct cifs_fid *pfid)
1167 {
1168         struct cifs_ntsd *pntsd = NULL;
1169         u32 acllen = 0;
1170         int rc = 0;
1171         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1172         struct smb_version_operations *ops;
1173
1174         cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1175
1176         if (IS_ERR(tlink))
1177                 return PTR_ERR(tlink);
1178
1179         ops = tlink_tcon(tlink)->ses->server->ops;
1180
1181         if (pfid && (ops->get_acl_by_fid))
1182                 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1183         else if (ops->get_acl)
1184                 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1185         else {
1186                 cifs_put_tlink(tlink);
1187                 return -EOPNOTSUPP;
1188         }
1189         /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1190         if (IS_ERR(pntsd)) {
1191                 rc = PTR_ERR(pntsd);
1192                 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1193         } else if (mode_from_special_sid) {
1194                 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true);
1195                 kfree(pntsd);
1196         } else {
1197                 /* get approximated mode from ACL */
1198                 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false);
1199                 kfree(pntsd);
1200                 if (rc)
1201                         cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1202         }
1203
1204         cifs_put_tlink(tlink);
1205
1206         return rc;
1207 }
1208
1209 /* Convert mode bits to an ACL so we can update the ACL on the server */
1210 int
1211 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1212                         kuid_t uid, kgid_t gid)
1213 {
1214         int rc = 0;
1215         int aclflag = CIFS_ACL_DACL; /* default flag to set */
1216         __u32 secdesclen = 0;
1217         struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1218         struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1219         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1220         struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1221         struct smb_version_operations *ops;
1222         bool mode_from_sid;
1223
1224         if (IS_ERR(tlink))
1225                 return PTR_ERR(tlink);
1226
1227         ops = tlink_tcon(tlink)->ses->server->ops;
1228
1229         cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1230
1231         /* Get the security descriptor */
1232
1233         if (ops->get_acl == NULL) {
1234                 cifs_put_tlink(tlink);
1235                 return -EOPNOTSUPP;
1236         }
1237
1238         pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1239         if (IS_ERR(pntsd)) {
1240                 rc = PTR_ERR(pntsd);
1241                 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1242                 cifs_put_tlink(tlink);
1243                 return rc;
1244         }
1245
1246         /*
1247          * Add three ACEs for owner, group, everyone getting rid of other ACEs
1248          * as chmod disables ACEs and set the security descriptor. Allocate
1249          * memory for the smb header, set security descriptor request security
1250          * descriptor parameters, and secuirty descriptor itself
1251          */
1252         secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1253         pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1254         if (!pnntsd) {
1255                 kfree(pntsd);
1256                 cifs_put_tlink(tlink);
1257                 return -ENOMEM;
1258         }
1259
1260         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
1261                 mode_from_sid = true;
1262         else
1263                 mode_from_sid = false;
1264
1265         rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1266                             mode_from_sid, &aclflag);
1267
1268         cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1269
1270         if (ops->set_acl == NULL)
1271                 rc = -EOPNOTSUPP;
1272
1273         if (!rc) {
1274                 /* Set the security descriptor */
1275                 rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1276                 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1277         }
1278         cifs_put_tlink(tlink);
1279
1280         kfree(pnntsd);
1281         kfree(pntsd);
1282         return rc;
1283 }