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