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