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