staging/irda/net: Drop extraneous parentheses around test
[linux-2.6/btrfs-unstable.git] / fs / cifs / cifsacl.c
blobb98436f5c7c74f9e773db0485bb9e80fcb43be99
1 /*
2 * fs/cifs/cifsacl.c
4 * Copyright (C) International Business Machines Corp., 2007,2008
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for mapping CIFS/NTFS ACLs
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.
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.
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
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"
36 /* security id for everyone/world system group */
37 static const struct cifs_sid sid_everyone = {
38 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
39 /* security id for Authenticated Users system group */
40 static const struct cifs_sid sid_authusers = {
41 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
42 /* group users */
43 static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
45 /* S-1-22-1 Unmapped Unix users */
46 static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22},
47 {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
49 /* S-1-22-2 Unmapped Unix groups */
50 static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22},
51 {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
54 * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
57 /* S-1-5-88 MS NFS and Apple style UID/GID/mode */
59 /* S-1-5-88-1 Unix uid */
60 static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5},
61 {cpu_to_le32(88),
62 cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
64 /* S-1-5-88-2 Unix gid */
65 static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5},
66 {cpu_to_le32(88),
67 cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
69 /* S-1-5-88-3 Unix mode */
70 static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5},
71 {cpu_to_le32(88),
72 cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} };
74 static const struct cred *root_cred;
76 static int
77 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
79 char *payload;
82 * If the payload is less than or equal to the size of a pointer, then
83 * an allocation here is wasteful. Just copy the data directly to the
84 * payload.value union member instead.
86 * With this however, you must check the datalen before trying to
87 * dereference payload.data!
89 if (prep->datalen <= sizeof(key->payload)) {
90 key->payload.data[0] = NULL;
91 memcpy(&key->payload, prep->data, prep->datalen);
92 } else {
93 payload = kmemdup(prep->data, prep->datalen, GFP_KERNEL);
94 if (!payload)
95 return -ENOMEM;
96 key->payload.data[0] = payload;
99 key->datalen = prep->datalen;
100 return 0;
103 static inline void
104 cifs_idmap_key_destroy(struct key *key)
106 if (key->datalen > sizeof(key->payload))
107 kfree(key->payload.data[0]);
110 static struct key_type cifs_idmap_key_type = {
111 .name = "cifs.idmap",
112 .instantiate = cifs_idmap_key_instantiate,
113 .destroy = cifs_idmap_key_destroy,
114 .describe = user_describe,
117 static char *
118 sid_to_key_str(struct cifs_sid *sidptr, unsigned int type)
120 int i, len;
121 unsigned int saval;
122 char *sidstr, *strptr;
123 unsigned long long id_auth_val;
125 /* 3 bytes for prefix */
126 sidstr = kmalloc(3 + SID_STRING_BASE_SIZE +
127 (SID_STRING_SUBAUTH_SIZE * sidptr->num_subauth),
128 GFP_KERNEL);
129 if (!sidstr)
130 return sidstr;
132 strptr = sidstr;
133 len = sprintf(strptr, "%cs:S-%hhu", type == SIDOWNER ? 'o' : 'g',
134 sidptr->revision);
135 strptr += len;
137 /* The authority field is a single 48-bit number */
138 id_auth_val = (unsigned long long)sidptr->authority[5];
139 id_auth_val |= (unsigned long long)sidptr->authority[4] << 8;
140 id_auth_val |= (unsigned long long)sidptr->authority[3] << 16;
141 id_auth_val |= (unsigned long long)sidptr->authority[2] << 24;
142 id_auth_val |= (unsigned long long)sidptr->authority[1] << 32;
143 id_auth_val |= (unsigned long long)sidptr->authority[0] << 48;
146 * MS-DTYP states that if the authority is >= 2^32, then it should be
147 * expressed as a hex value.
149 if (id_auth_val <= UINT_MAX)
150 len = sprintf(strptr, "-%llu", id_auth_val);
151 else
152 len = sprintf(strptr, "-0x%llx", id_auth_val);
154 strptr += len;
156 for (i = 0; i < sidptr->num_subauth; ++i) {
157 saval = le32_to_cpu(sidptr->sub_auth[i]);
158 len = sprintf(strptr, "-%u", saval);
159 strptr += len;
162 return sidstr;
166 * if the two SIDs (roughly equivalent to a UUID for a user or group) are
167 * the same returns zero, if they do not match returns non-zero.
169 static int
170 compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
172 int i;
173 int num_subauth, num_sat, num_saw;
175 if ((!ctsid) || (!cwsid))
176 return 1;
178 /* compare the revision */
179 if (ctsid->revision != cwsid->revision) {
180 if (ctsid->revision > cwsid->revision)
181 return 1;
182 else
183 return -1;
186 /* compare all of the six auth values */
187 for (i = 0; i < NUM_AUTHS; ++i) {
188 if (ctsid->authority[i] != cwsid->authority[i]) {
189 if (ctsid->authority[i] > cwsid->authority[i])
190 return 1;
191 else
192 return -1;
196 /* compare all of the subauth values if any */
197 num_sat = ctsid->num_subauth;
198 num_saw = cwsid->num_subauth;
199 num_subauth = num_sat < num_saw ? num_sat : num_saw;
200 if (num_subauth) {
201 for (i = 0; i < num_subauth; ++i) {
202 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
203 if (le32_to_cpu(ctsid->sub_auth[i]) >
204 le32_to_cpu(cwsid->sub_auth[i]))
205 return 1;
206 else
207 return -1;
212 return 0; /* sids compare/match */
215 static bool
216 is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group)
218 int i;
219 int num_subauth;
220 const struct cifs_sid *pwell_known_sid;
222 if (!psid || (puid == NULL))
223 return false;
225 num_subauth = psid->num_subauth;
227 /* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */
228 if (num_subauth == 2) {
229 if (is_group)
230 pwell_known_sid = &sid_unix_groups;
231 else
232 pwell_known_sid = &sid_unix_users;
233 } else if (num_subauth == 3) {
234 if (is_group)
235 pwell_known_sid = &sid_unix_NFS_groups;
236 else
237 pwell_known_sid = &sid_unix_NFS_users;
238 } else
239 return false;
241 /* compare the revision */
242 if (psid->revision != pwell_known_sid->revision)
243 return false;
245 /* compare all of the six auth values */
246 for (i = 0; i < NUM_AUTHS; ++i) {
247 if (psid->authority[i] != pwell_known_sid->authority[i]) {
248 cifs_dbg(FYI, "auth %d did not match\n", i);
249 return false;
253 if (num_subauth == 2) {
254 if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0])
255 return false;
257 *puid = le32_to_cpu(psid->sub_auth[1]);
258 } else /* 3 subauths, ie Windows/Mac style */ {
259 *puid = le32_to_cpu(psid->sub_auth[0]);
260 if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) ||
261 (psid->sub_auth[1] != pwell_known_sid->sub_auth[1]))
262 return false;
264 *puid = le32_to_cpu(psid->sub_auth[2]);
267 cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid);
268 return true; /* well known sid found, uid returned */
271 static void
272 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
274 int i;
276 dst->revision = src->revision;
277 dst->num_subauth = min_t(u8, src->num_subauth, SID_MAX_SUB_AUTHORITIES);
278 for (i = 0; i < NUM_AUTHS; ++i)
279 dst->authority[i] = src->authority[i];
280 for (i = 0; i < dst->num_subauth; ++i)
281 dst->sub_auth[i] = src->sub_auth[i];
284 static int
285 id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
287 int rc;
288 struct key *sidkey;
289 struct cifs_sid *ksid;
290 unsigned int ksid_size;
291 char desc[3 + 10 + 1]; /* 3 byte prefix + 10 bytes for value + NULL */
292 const struct cred *saved_cred;
294 rc = snprintf(desc, sizeof(desc), "%ci:%u",
295 sidtype == SIDOWNER ? 'o' : 'g', cid);
296 if (rc >= sizeof(desc))
297 return -EINVAL;
299 rc = 0;
300 saved_cred = override_creds(root_cred);
301 sidkey = request_key(&cifs_idmap_key_type, desc, "");
302 if (IS_ERR(sidkey)) {
303 rc = -EINVAL;
304 cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
305 __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
306 goto out_revert_creds;
307 } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
308 rc = -EIO;
309 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
310 __func__, sidkey->datalen);
311 goto invalidate_key;
315 * A sid is usually too large to be embedded in payload.value, but if
316 * there are no subauthorities and the host has 8-byte pointers, then
317 * it could be.
319 ksid = sidkey->datalen <= sizeof(sidkey->payload) ?
320 (struct cifs_sid *)&sidkey->payload :
321 (struct cifs_sid *)sidkey->payload.data[0];
323 ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
324 if (ksid_size > sidkey->datalen) {
325 rc = -EIO;
326 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
327 __func__, sidkey->datalen, ksid_size);
328 goto invalidate_key;
331 cifs_copy_sid(ssid, ksid);
332 out_key_put:
333 key_put(sidkey);
334 out_revert_creds:
335 revert_creds(saved_cred);
336 return rc;
338 invalidate_key:
339 key_invalidate(sidkey);
340 goto out_key_put;
343 static int
344 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
345 struct cifs_fattr *fattr, uint sidtype)
347 int rc;
348 struct key *sidkey;
349 char *sidstr;
350 const struct cred *saved_cred;
351 kuid_t fuid = cifs_sb->mnt_uid;
352 kgid_t fgid = cifs_sb->mnt_gid;
355 * If we have too many subauthorities, then something is really wrong.
356 * Just return an error.
358 if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
359 cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
360 __func__, psid->num_subauth);
361 return -EIO;
364 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) {
365 uint32_t unix_id;
366 bool is_group;
368 if (sidtype != SIDOWNER)
369 is_group = true;
370 else
371 is_group = false;
373 if (is_well_known_sid(psid, &unix_id, is_group) == false)
374 goto try_upcall_to_get_id;
376 if (is_group) {
377 kgid_t gid;
378 gid_t id;
380 id = (gid_t)unix_id;
381 gid = make_kgid(&init_user_ns, id);
382 if (gid_valid(gid)) {
383 fgid = gid;
384 goto got_valid_id;
386 } else {
387 kuid_t uid;
388 uid_t id;
390 id = (uid_t)unix_id;
391 uid = make_kuid(&init_user_ns, id);
392 if (uid_valid(uid)) {
393 fuid = uid;
394 goto got_valid_id;
397 /* If unable to find uid/gid easily from SID try via upcall */
400 try_upcall_to_get_id:
401 sidstr = sid_to_key_str(psid, sidtype);
402 if (!sidstr)
403 return -ENOMEM;
405 saved_cred = override_creds(root_cred);
406 sidkey = request_key(&cifs_idmap_key_type, sidstr, "");
407 if (IS_ERR(sidkey)) {
408 rc = -EINVAL;
409 cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
410 __func__, sidstr, sidtype == SIDOWNER ? 'u' : 'g');
411 goto out_revert_creds;
415 * FIXME: Here we assume that uid_t and gid_t are same size. It's
416 * probably a safe assumption but might be better to check based on
417 * sidtype.
419 BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
420 if (sidkey->datalen != sizeof(uid_t)) {
421 rc = -EIO;
422 cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
423 __func__, sidkey->datalen);
424 key_invalidate(sidkey);
425 goto out_key_put;
428 if (sidtype == SIDOWNER) {
429 kuid_t uid;
430 uid_t id;
431 memcpy(&id, &sidkey->payload.data[0], sizeof(uid_t));
432 uid = make_kuid(&init_user_ns, id);
433 if (uid_valid(uid))
434 fuid = uid;
435 } else {
436 kgid_t gid;
437 gid_t id;
438 memcpy(&id, &sidkey->payload.data[0], sizeof(gid_t));
439 gid = make_kgid(&init_user_ns, id);
440 if (gid_valid(gid))
441 fgid = gid;
444 out_key_put:
445 key_put(sidkey);
446 out_revert_creds:
447 revert_creds(saved_cred);
448 kfree(sidstr);
451 * Note that we return 0 here unconditionally. If the mapping
452 * fails then we just fall back to using the mnt_uid/mnt_gid.
454 got_valid_id:
455 if (sidtype == SIDOWNER)
456 fattr->cf_uid = fuid;
457 else
458 fattr->cf_gid = fgid;
459 return 0;
463 init_cifs_idmap(void)
465 struct cred *cred;
466 struct key *keyring;
467 int ret;
469 cifs_dbg(FYI, "Registering the %s key type\n",
470 cifs_idmap_key_type.name);
472 /* create an override credential set with a special thread keyring in
473 * which requests are cached
475 * this is used to prevent malicious redirections from being installed
476 * with add_key().
478 cred = prepare_kernel_cred(NULL);
479 if (!cred)
480 return -ENOMEM;
482 keyring = keyring_alloc(".cifs_idmap",
483 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
484 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
485 KEY_USR_VIEW | KEY_USR_READ,
486 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
487 if (IS_ERR(keyring)) {
488 ret = PTR_ERR(keyring);
489 goto failed_put_cred;
492 ret = register_key_type(&cifs_idmap_key_type);
493 if (ret < 0)
494 goto failed_put_key;
496 /* instruct request_key() to use this special keyring as a cache for
497 * the results it looks up */
498 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
499 cred->thread_keyring = keyring;
500 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
501 root_cred = cred;
503 cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));
504 return 0;
506 failed_put_key:
507 key_put(keyring);
508 failed_put_cred:
509 put_cred(cred);
510 return ret;
513 void
514 exit_cifs_idmap(void)
516 key_revoke(root_cred->thread_keyring);
517 unregister_key_type(&cifs_idmap_key_type);
518 put_cred(root_cred);
519 cifs_dbg(FYI, "Unregistered %s key type\n", cifs_idmap_key_type.name);
522 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
523 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
524 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
526 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
527 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
529 /* copy security descriptor control portion */
530 pnntsd->revision = pntsd->revision;
531 pnntsd->type = pntsd->type;
532 pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
533 pnntsd->sacloffset = 0;
534 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
535 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
537 /* copy owner sid */
538 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
539 le32_to_cpu(pntsd->osidoffset));
540 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
541 cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
543 /* copy group sid */
544 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
545 le32_to_cpu(pntsd->gsidoffset));
546 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
547 sizeof(struct cifs_sid));
548 cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
550 return;
555 change posix mode to reflect permissions
556 pmode is the existing mode (we only want to overwrite part of this
557 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
559 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
560 umode_t *pbits_to_set)
562 __u32 flags = le32_to_cpu(ace_flags);
563 /* the order of ACEs is important. The canonical order is to begin with
564 DENY entries followed by ALLOW, otherwise an allow entry could be
565 encountered first, making the subsequent deny entry like "dead code"
566 which would be superflous since Windows stops when a match is made
567 for the operation you are trying to perform for your user */
569 /* For deny ACEs we change the mask so that subsequent allow access
570 control entries do not turn on the bits we are denying */
571 if (type == ACCESS_DENIED) {
572 if (flags & GENERIC_ALL)
573 *pbits_to_set &= ~S_IRWXUGO;
575 if ((flags & GENERIC_WRITE) ||
576 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
577 *pbits_to_set &= ~S_IWUGO;
578 if ((flags & GENERIC_READ) ||
579 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
580 *pbits_to_set &= ~S_IRUGO;
581 if ((flags & GENERIC_EXECUTE) ||
582 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
583 *pbits_to_set &= ~S_IXUGO;
584 return;
585 } else if (type != ACCESS_ALLOWED) {
586 cifs_dbg(VFS, "unknown access control type %d\n", type);
587 return;
589 /* else ACCESS_ALLOWED type */
591 if (flags & GENERIC_ALL) {
592 *pmode |= (S_IRWXUGO & (*pbits_to_set));
593 cifs_dbg(NOISY, "all perms\n");
594 return;
596 if ((flags & GENERIC_WRITE) ||
597 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
598 *pmode |= (S_IWUGO & (*pbits_to_set));
599 if ((flags & GENERIC_READ) ||
600 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
601 *pmode |= (S_IRUGO & (*pbits_to_set));
602 if ((flags & GENERIC_EXECUTE) ||
603 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
604 *pmode |= (S_IXUGO & (*pbits_to_set));
606 cifs_dbg(NOISY, "access flags 0x%x mode now 0x%x\n", flags, *pmode);
607 return;
611 Generate access flags to reflect permissions mode is the existing mode.
612 This function is called for every ACE in the DACL whose SID matches
613 with either owner or group or everyone.
616 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
617 __u32 *pace_flags)
619 /* reset access mask */
620 *pace_flags = 0x0;
622 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
623 mode &= bits_to_use;
625 /* check for R/W/X UGO since we do not know whose flags
626 is this but we have cleared all the bits sans RWX for
627 either user or group or other as per bits_to_use */
628 if (mode & S_IRUGO)
629 *pace_flags |= SET_FILE_READ_RIGHTS;
630 if (mode & S_IWUGO)
631 *pace_flags |= SET_FILE_WRITE_RIGHTS;
632 if (mode & S_IXUGO)
633 *pace_flags |= SET_FILE_EXEC_RIGHTS;
635 cifs_dbg(NOISY, "mode: 0x%x, access flags now 0x%x\n",
636 mode, *pace_flags);
637 return;
640 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
641 const struct cifs_sid *psid, __u64 nmode, umode_t bits)
643 int i;
644 __u16 size = 0;
645 __u32 access_req = 0;
647 pntace->type = ACCESS_ALLOWED;
648 pntace->flags = 0x0;
649 mode_to_access_flags(nmode, bits, &access_req);
650 if (!access_req)
651 access_req = SET_MINIMUM_RIGHTS;
652 pntace->access_req = cpu_to_le32(access_req);
654 pntace->sid.revision = psid->revision;
655 pntace->sid.num_subauth = psid->num_subauth;
656 for (i = 0; i < NUM_AUTHS; i++)
657 pntace->sid.authority[i] = psid->authority[i];
658 for (i = 0; i < psid->num_subauth; i++)
659 pntace->sid.sub_auth[i] = psid->sub_auth[i];
661 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
662 pntace->size = cpu_to_le16(size);
664 return size;
668 #ifdef CONFIG_CIFS_DEBUG2
669 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
671 int num_subauth;
673 /* validate that we do not go past end of acl */
675 if (le16_to_cpu(pace->size) < 16) {
676 cifs_dbg(VFS, "ACE too small %d\n", le16_to_cpu(pace->size));
677 return;
680 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
681 cifs_dbg(VFS, "ACL too small to parse ACE\n");
682 return;
685 num_subauth = pace->sid.num_subauth;
686 if (num_subauth) {
687 int i;
688 cifs_dbg(FYI, "ACE revision %d num_auth %d type %d flags %d size %d\n",
689 pace->sid.revision, pace->sid.num_subauth, pace->type,
690 pace->flags, le16_to_cpu(pace->size));
691 for (i = 0; i < num_subauth; ++i) {
692 cifs_dbg(FYI, "ACE sub_auth[%d]: 0x%x\n",
693 i, le32_to_cpu(pace->sid.sub_auth[i]));
696 /* BB add length check to make sure that we do not have huge
697 num auths and therefore go off the end */
700 return;
702 #endif
705 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
706 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
707 struct cifs_fattr *fattr)
709 int i;
710 int num_aces = 0;
711 int acl_size;
712 char *acl_base;
713 struct cifs_ace **ppace;
715 /* BB need to add parm so we can store the SID BB */
717 if (!pdacl) {
718 /* no DACL in the security descriptor, set
719 all the permissions for user/group/other */
720 fattr->cf_mode |= S_IRWXUGO;
721 return;
724 /* validate that we do not go past end of acl */
725 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
726 cifs_dbg(VFS, "ACL too small to parse DACL\n");
727 return;
730 cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
731 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
732 le32_to_cpu(pdacl->num_aces));
734 /* reset rwx permissions for user/group/other.
735 Also, if num_aces is 0 i.e. DACL has no ACEs,
736 user/group/other have no permissions */
737 fattr->cf_mode &= ~(S_IRWXUGO);
739 acl_base = (char *)pdacl;
740 acl_size = sizeof(struct cifs_acl);
742 num_aces = le32_to_cpu(pdacl->num_aces);
743 if (num_aces > 0) {
744 umode_t user_mask = S_IRWXU;
745 umode_t group_mask = S_IRWXG;
746 umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
748 if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
749 return;
750 ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
751 GFP_KERNEL);
752 if (!ppace)
753 return;
755 for (i = 0; i < num_aces; ++i) {
756 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
757 #ifdef CONFIG_CIFS_DEBUG2
758 dump_ace(ppace[i], end_of_acl);
759 #endif
760 if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
761 access_flags_to_mode(ppace[i]->access_req,
762 ppace[i]->type,
763 &fattr->cf_mode,
764 &user_mask);
765 if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
766 access_flags_to_mode(ppace[i]->access_req,
767 ppace[i]->type,
768 &fattr->cf_mode,
769 &group_mask);
770 if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
771 access_flags_to_mode(ppace[i]->access_req,
772 ppace[i]->type,
773 &fattr->cf_mode,
774 &other_mask);
775 if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
776 access_flags_to_mode(ppace[i]->access_req,
777 ppace[i]->type,
778 &fattr->cf_mode,
779 &other_mask);
782 /* memcpy((void *)(&(cifscred->aces[i])),
783 (void *)ppace[i],
784 sizeof(struct cifs_ace)); */
786 acl_base = (char *)ppace[i];
787 acl_size = le16_to_cpu(ppace[i]->size);
790 kfree(ppace);
793 return;
797 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
798 struct cifs_sid *pgrpsid, __u64 nmode)
800 u16 size = 0;
801 struct cifs_acl *pnndacl;
803 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
805 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
806 pownersid, nmode, S_IRWXU);
807 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
808 pgrpsid, nmode, S_IRWXG);
809 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
810 &sid_everyone, nmode, S_IRWXO);
812 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
813 pndacl->num_aces = cpu_to_le32(3);
815 return 0;
819 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
821 /* BB need to add parm so we can store the SID BB */
823 /* validate that we do not go past end of ACL - sid must be at least 8
824 bytes long (assuming no sub-auths - e.g. the null SID */
825 if (end_of_acl < (char *)psid + 8) {
826 cifs_dbg(VFS, "ACL too small to parse SID %p\n", psid);
827 return -EINVAL;
830 #ifdef CONFIG_CIFS_DEBUG2
831 if (psid->num_subauth) {
832 int i;
833 cifs_dbg(FYI, "SID revision %d num_auth %d\n",
834 psid->revision, psid->num_subauth);
836 for (i = 0; i < psid->num_subauth; i++) {
837 cifs_dbg(FYI, "SID sub_auth[%d]: 0x%x\n",
838 i, le32_to_cpu(psid->sub_auth[i]));
841 /* BB add length check to make sure that we do not have huge
842 num auths and therefore go off the end */
843 cifs_dbg(FYI, "RID 0x%x\n",
844 le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
846 #endif
848 return 0;
852 /* Convert CIFS ACL to POSIX form */
853 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
854 struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
856 int rc = 0;
857 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
858 struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
859 char *end_of_acl = ((char *)pntsd) + acl_len;
860 __u32 dacloffset;
862 if (pntsd == NULL)
863 return -EIO;
865 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
866 le32_to_cpu(pntsd->osidoffset));
867 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
868 le32_to_cpu(pntsd->gsidoffset));
869 dacloffset = le32_to_cpu(pntsd->dacloffset);
870 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
871 cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
872 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
873 le32_to_cpu(pntsd->gsidoffset),
874 le32_to_cpu(pntsd->sacloffset), dacloffset);
875 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
876 rc = parse_sid(owner_sid_ptr, end_of_acl);
877 if (rc) {
878 cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
879 return rc;
881 rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
882 if (rc) {
883 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
884 __func__, rc);
885 return rc;
888 rc = parse_sid(group_sid_ptr, end_of_acl);
889 if (rc) {
890 cifs_dbg(FYI, "%s: Error %d mapping Owner SID to gid\n",
891 __func__, rc);
892 return rc;
894 rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
895 if (rc) {
896 cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
897 __func__, rc);
898 return rc;
901 if (dacloffset)
902 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
903 group_sid_ptr, fattr);
904 else
905 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
907 return rc;
910 /* Convert permission bits from mode to equivalent CIFS ACL */
911 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
912 __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag)
914 int rc = 0;
915 __u32 dacloffset;
916 __u32 ndacloffset;
917 __u32 sidsoffset;
918 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
919 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
920 struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */
921 struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
923 if (nmode != NO_CHANGE_64) { /* chmod */
924 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
925 le32_to_cpu(pntsd->osidoffset));
926 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
927 le32_to_cpu(pntsd->gsidoffset));
928 dacloffset = le32_to_cpu(pntsd->dacloffset);
929 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
930 ndacloffset = sizeof(struct cifs_ntsd);
931 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
932 ndacl_ptr->revision = dacl_ptr->revision;
933 ndacl_ptr->size = 0;
934 ndacl_ptr->num_aces = 0;
936 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
937 nmode);
938 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
939 /* copy sec desc control portion & owner and group sids */
940 copy_sec_desc(pntsd, pnntsd, sidsoffset);
941 *aclflag = CIFS_ACL_DACL;
942 } else {
943 memcpy(pnntsd, pntsd, secdesclen);
944 if (uid_valid(uid)) { /* chown */
945 uid_t id;
946 owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
947 le32_to_cpu(pnntsd->osidoffset));
948 nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
949 GFP_KERNEL);
950 if (!nowner_sid_ptr)
951 return -ENOMEM;
952 id = from_kuid(&init_user_ns, uid);
953 rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
954 if (rc) {
955 cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
956 __func__, rc, id);
957 kfree(nowner_sid_ptr);
958 return rc;
960 cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
961 kfree(nowner_sid_ptr);
962 *aclflag = CIFS_ACL_OWNER;
964 if (gid_valid(gid)) { /* chgrp */
965 gid_t id;
966 group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
967 le32_to_cpu(pnntsd->gsidoffset));
968 ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
969 GFP_KERNEL);
970 if (!ngroup_sid_ptr)
971 return -ENOMEM;
972 id = from_kgid(&init_user_ns, gid);
973 rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
974 if (rc) {
975 cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
976 __func__, rc, id);
977 kfree(ngroup_sid_ptr);
978 return rc;
980 cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
981 kfree(ngroup_sid_ptr);
982 *aclflag = CIFS_ACL_GROUP;
986 return rc;
989 struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
990 const struct cifs_fid *cifsfid, u32 *pacllen)
992 struct cifs_ntsd *pntsd = NULL;
993 unsigned int xid;
994 int rc;
995 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
997 if (IS_ERR(tlink))
998 return ERR_CAST(tlink);
1000 xid = get_xid();
1001 rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1002 pacllen);
1003 free_xid(xid);
1005 cifs_put_tlink(tlink);
1007 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1008 if (rc)
1009 return ERR_PTR(rc);
1010 return pntsd;
1013 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1014 const char *path, u32 *pacllen)
1016 struct cifs_ntsd *pntsd = NULL;
1017 int oplock = 0;
1018 unsigned int xid;
1019 int rc, create_options = 0;
1020 struct cifs_tcon *tcon;
1021 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1022 struct cifs_fid fid;
1023 struct cifs_open_parms oparms;
1025 if (IS_ERR(tlink))
1026 return ERR_CAST(tlink);
1028 tcon = tlink_tcon(tlink);
1029 xid = get_xid();
1031 if (backup_cred(cifs_sb))
1032 create_options |= CREATE_OPEN_BACKUP_INTENT;
1034 oparms.tcon = tcon;
1035 oparms.cifs_sb = cifs_sb;
1036 oparms.desired_access = READ_CONTROL;
1037 oparms.create_options = create_options;
1038 oparms.disposition = FILE_OPEN;
1039 oparms.path = path;
1040 oparms.fid = &fid;
1041 oparms.reconnect = false;
1043 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1044 if (!rc) {
1045 rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1046 CIFSSMBClose(xid, tcon, fid.netfid);
1049 cifs_put_tlink(tlink);
1050 free_xid(xid);
1052 cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen);
1053 if (rc)
1054 return ERR_PTR(rc);
1055 return pntsd;
1058 /* Retrieve an ACL from the server */
1059 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1060 struct inode *inode, const char *path,
1061 u32 *pacllen)
1063 struct cifs_ntsd *pntsd = NULL;
1064 struct cifsFileInfo *open_file = NULL;
1066 if (inode)
1067 open_file = find_readable_file(CIFS_I(inode), true);
1068 if (!open_file)
1069 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1071 pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen);
1072 cifsFileInfo_put(open_file);
1073 return pntsd;
1076 /* Set an ACL on the server */
1077 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1078 struct inode *inode, const char *path, int aclflag)
1080 int oplock = 0;
1081 unsigned int xid;
1082 int rc, access_flags, create_options = 0;
1083 struct cifs_tcon *tcon;
1084 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1085 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1086 struct cifs_fid fid;
1087 struct cifs_open_parms oparms;
1089 if (IS_ERR(tlink))
1090 return PTR_ERR(tlink);
1092 tcon = tlink_tcon(tlink);
1093 xid = get_xid();
1095 if (backup_cred(cifs_sb))
1096 create_options |= CREATE_OPEN_BACKUP_INTENT;
1098 if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1099 access_flags = WRITE_OWNER;
1100 else
1101 access_flags = WRITE_DAC;
1103 oparms.tcon = tcon;
1104 oparms.cifs_sb = cifs_sb;
1105 oparms.desired_access = access_flags;
1106 oparms.create_options = create_options;
1107 oparms.disposition = FILE_OPEN;
1108 oparms.path = path;
1109 oparms.fid = &fid;
1110 oparms.reconnect = false;
1112 rc = CIFS_open(xid, &oparms, &oplock, NULL);
1113 if (rc) {
1114 cifs_dbg(VFS, "Unable to open file to set ACL\n");
1115 goto out;
1118 rc = CIFSSMBSetCIFSACL(xid, tcon, fid.netfid, pnntsd, acllen, aclflag);
1119 cifs_dbg(NOISY, "SetCIFSACL rc = %d\n", rc);
1121 CIFSSMBClose(xid, tcon, fid.netfid);
1122 out:
1123 free_xid(xid);
1124 cifs_put_tlink(tlink);
1125 return rc;
1128 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
1130 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1131 struct inode *inode, const char *path,
1132 const struct cifs_fid *pfid)
1134 struct cifs_ntsd *pntsd = NULL;
1135 u32 acllen = 0;
1136 int rc = 0;
1137 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1138 struct smb_version_operations *ops;
1140 cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
1142 if (IS_ERR(tlink))
1143 return PTR_ERR(tlink);
1145 ops = tlink_tcon(tlink)->ses->server->ops;
1147 if (pfid && (ops->get_acl_by_fid))
1148 pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
1149 else if (ops->get_acl)
1150 pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
1151 else {
1152 cifs_put_tlink(tlink);
1153 return -EOPNOTSUPP;
1155 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1156 if (IS_ERR(pntsd)) {
1157 rc = PTR_ERR(pntsd);
1158 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1159 } else {
1160 rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
1161 kfree(pntsd);
1162 if (rc)
1163 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc);
1166 cifs_put_tlink(tlink);
1168 return rc;
1171 /* Convert mode bits to an ACL so we can update the ACL on the server */
1173 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1174 kuid_t uid, kgid_t gid)
1176 int rc = 0;
1177 int aclflag = CIFS_ACL_DACL; /* default flag to set */
1178 __u32 secdesclen = 0;
1179 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1180 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1181 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1182 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1183 struct smb_version_operations *ops;
1185 if (IS_ERR(tlink))
1186 return PTR_ERR(tlink);
1188 ops = tlink_tcon(tlink)->ses->server->ops;
1190 cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
1192 /* Get the security descriptor */
1194 if (ops->get_acl == NULL) {
1195 cifs_put_tlink(tlink);
1196 return -EOPNOTSUPP;
1199 pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
1200 if (IS_ERR(pntsd)) {
1201 rc = PTR_ERR(pntsd);
1202 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
1203 cifs_put_tlink(tlink);
1204 return rc;
1208 * Add three ACEs for owner, group, everyone getting rid of other ACEs
1209 * as chmod disables ACEs and set the security descriptor. Allocate
1210 * memory for the smb header, set security descriptor request security
1211 * descriptor parameters, and secuirty descriptor itself
1213 secdesclen = max_t(u32, secdesclen, DEFAULT_SEC_DESC_LEN);
1214 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1215 if (!pnntsd) {
1216 kfree(pntsd);
1217 cifs_put_tlink(tlink);
1218 return -ENOMEM;
1221 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1222 &aclflag);
1224 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
1226 if (ops->set_acl == NULL)
1227 rc = -EOPNOTSUPP;
1229 if (!rc) {
1230 /* Set the security descriptor */
1231 rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
1232 cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
1234 cifs_put_tlink(tlink);
1236 kfree(pnntsd);
1237 kfree(pntsd);
1238 return rc;