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