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