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