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} 1119