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