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