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