1 // SPDX-License-Identifier: LGPL-2.1 2 /* 3 * 4 * Copyright (C) International Business Machines Corp., 2002,2008 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 * 7 */ 8 #include <crypto/md5.h> 9 #include <linux/fs.h> 10 #include <linux/stat.h> 11 #include <linux/slab.h> 12 #include <linux/namei.h> 13 #include "cifsfs.h" 14 #include "cifsglob.h" 15 #include "cifsproto.h" 16 #include "cifs_debug.h" 17 #include "cifs_fs_sb.h" 18 #include "cifs_unicode.h" 19 #include "smb2proto.h" 20 #include "smb2glob.h" 21 #include "cifs_ioctl.h" 22 #include "fs_context.h" 23 #include "reparse.h" 24 25 /* 26 * M-F Symlink Functions - Begin 27 */ 28 29 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1) 30 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1)) 31 #define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1)) 32 #define CIFS_MF_SYMLINK_LINK_MAXLEN (1024) 33 #define CIFS_MF_SYMLINK_FILE_SIZE \ 34 (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN) 35 36 #define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n" 37 #define CIFS_MF_SYMLINK_MD5_FORMAT "%16phN\n" 38 #define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) md5_hash 39 40 static int 41 parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len, 42 char **_link_str) 43 { 44 int rc; 45 unsigned int link_len; 46 const char *md5_str1; 47 const char *link_str; 48 u8 md5_hash[16]; 49 char md5_str2[34]; 50 51 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE) 52 return -EINVAL; 53 54 md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET]; 55 link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET]; 56 57 rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len); 58 if (rc != 1) 59 return -EINVAL; 60 61 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN) 62 return -EINVAL; 63 64 md5(link_str, link_len, md5_hash); 65 66 scnprintf(md5_str2, sizeof(md5_str2), 67 CIFS_MF_SYMLINK_MD5_FORMAT, 68 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash)); 69 70 if (strncmp(md5_str1, md5_str2, 17) != 0) 71 return -EINVAL; 72 73 if (_link_str) { 74 *_link_str = kstrndup(link_str, link_len, GFP_KERNEL); 75 if (!*_link_str) 76 return -ENOMEM; 77 } 78 79 *_link_len = link_len; 80 return 0; 81 } 82 83 static int 84 format_mf_symlink(u8 *buf, unsigned int buf_len, const char *link_str) 85 { 86 unsigned int link_len; 87 unsigned int ofs; 88 u8 md5_hash[16]; 89 90 if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE) 91 return -EINVAL; 92 93 link_len = strlen(link_str); 94 95 if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN) 96 return -ENAMETOOLONG; 97 98 md5(link_str, link_len, md5_hash); 99 100 scnprintf(buf, buf_len, 101 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT, 102 link_len, 103 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash)); 104 105 ofs = CIFS_MF_SYMLINK_LINK_OFFSET; 106 memcpy(buf + ofs, link_str, link_len); 107 108 ofs += link_len; 109 if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) { 110 buf[ofs] = '\n'; 111 ofs++; 112 } 113 114 while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) { 115 buf[ofs] = ' '; 116 ofs++; 117 } 118 119 return 0; 120 } 121 122 bool 123 couldbe_mf_symlink(const struct cifs_fattr *fattr) 124 { 125 if (!S_ISREG(fattr->cf_mode)) 126 /* it's not a symlink */ 127 return false; 128 129 if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE) 130 /* it's not a symlink */ 131 return false; 132 133 return true; 134 } 135 136 static int 137 create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon, 138 struct cifs_sb_info *cifs_sb, const char *fromName, 139 const char *toName) 140 { 141 int rc; 142 u8 *buf; 143 unsigned int bytes_written = 0; 144 145 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 146 if (!buf) 147 return -ENOMEM; 148 149 rc = format_mf_symlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName); 150 if (rc) 151 goto out; 152 153 if (tcon->ses->server->ops->create_mf_symlink) 154 rc = tcon->ses->server->ops->create_mf_symlink(xid, tcon, 155 cifs_sb, fromName, buf, &bytes_written); 156 else 157 rc = -EOPNOTSUPP; 158 159 if (rc) 160 goto out; 161 162 if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE) 163 rc = smb_EIO2(smb_eio_trace_symlink_file_size, 164 bytes_written, CIFS_MF_SYMLINK_FILE_SIZE); 165 out: 166 kfree(buf); 167 return rc; 168 } 169 170 int cifs_check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 171 struct cifs_sb_info *cifs_sb, 172 const char *full_path, struct inode *inode, 173 struct cifs_fattr *fattr) 174 { 175 struct TCP_Server_Info *server = tcon->ses->server; 176 char *buf __free(kfree) = NULL; 177 unsigned int bytes_read = 0; 178 unsigned int link_len = 0; 179 char *symlink = NULL; 180 int rc = 0; 181 182 if (!couldbe_mf_symlink(fattr)) 183 goto out; 184 185 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 186 if (!buf) { 187 rc = -ENOMEM; 188 goto out; 189 } 190 191 if (server->ops->query_mf_symlink) { 192 rc = server->ops->query_mf_symlink(xid, tcon, 193 cifs_sb, full_path, 194 inode, buf, &bytes_read); 195 } else { 196 rc = -ENOSYS; 197 } 198 199 if (rc) 200 goto out; 201 202 if (bytes_read == 0) /* not a symlink */ 203 goto out; 204 205 rc = parse_mf_symlink(buf, bytes_read, &link_len, &symlink); 206 if (rc == -EINVAL) { 207 /* it's not a symlink */ 208 rc = 0; 209 goto out; 210 } 211 212 if (rc != 0) 213 goto out; 214 215 /* it is a symlink */ 216 fattr->cf_eof = link_len; 217 fattr->cf_mode &= ~S_IFMT; 218 fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; 219 fattr->cf_dtype = DT_LNK; 220 fattr->cf_symlink_target = symlink; 221 out: 222 cifs_dbg(FYI, "%s: rc = %d\n", __func__, rc); 223 return rc == -ENOMEM ? rc : 0; 224 } 225 226 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 227 int cifs_query_mf_symlink(const unsigned int xid, 228 struct cifs_tcon *tcon, 229 struct cifs_sb_info *cifs_sb, 230 const char *full_path, 231 struct inode *inode, char *pbuf, 232 unsigned int *pbytes_read) 233 { 234 int rc; 235 int oplock = 0; 236 struct cifs_fid fid; 237 struct cifs_open_parms oparms; 238 struct cifs_io_parms io_parms = {0}; 239 int buf_type = CIFS_NO_BUFFER; 240 struct cifs_open_info_data query_data = {}; 241 242 oparms = (struct cifs_open_parms) { 243 .tcon = tcon, 244 .cifs_sb = cifs_sb, 245 .desired_access = GENERIC_READ, 246 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR), 247 .disposition = FILE_OPEN, 248 .path = full_path, 249 .fid = &fid, 250 }; 251 252 rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, &query_data); 253 if (rc) 254 return rc; 255 256 if (query_data.fi.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { 257 rc = -ENOENT; 258 /* it's not a symlink */ 259 goto out; 260 } 261 262 io_parms.netfid = fid.netfid; 263 io_parms.pid = current->tgid; 264 io_parms.tcon = tcon; 265 io_parms.offset = 0; 266 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 267 268 rc = CIFSSMBRead(xid, &io_parms, pbytes_read, &pbuf, &buf_type); 269 out: 270 CIFSSMBClose(xid, tcon, fid.netfid); 271 return rc; 272 } 273 274 int 275 cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 276 struct cifs_sb_info *cifs_sb, const unsigned char *path, 277 char *pbuf, unsigned int *pbytes_written) 278 { 279 int rc; 280 int oplock = 0; 281 struct cifs_fid fid; 282 struct cifs_open_parms oparms; 283 struct cifs_io_parms io_parms = {0}; 284 285 oparms = (struct cifs_open_parms) { 286 .tcon = tcon, 287 .cifs_sb = cifs_sb, 288 .desired_access = GENERIC_WRITE, 289 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR), 290 .disposition = FILE_CREATE, 291 .path = path, 292 .fid = &fid, 293 }; 294 295 rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, NULL); 296 if (rc) 297 return rc; 298 299 io_parms.netfid = fid.netfid; 300 io_parms.pid = current->tgid; 301 io_parms.tcon = tcon; 302 io_parms.offset = 0; 303 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 304 305 rc = CIFSSMBWrite(xid, &io_parms, pbytes_written, pbuf); 306 CIFSSMBClose(xid, tcon, fid.netfid); 307 return rc; 308 } 309 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ 310 311 int smb2_query_mf_symlink(const unsigned int xid, 312 struct cifs_tcon *tcon, 313 struct cifs_sb_info *cifs_sb, 314 const char *full_path, 315 struct inode *inode, char *pbuf, 316 unsigned int *pbytes_read) 317 { 318 struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; 319 struct kvec read_iov[2], close_iov; 320 struct cifsFileInfo *cfile = NULL; 321 struct smb2_read_rsp *read_rsp; 322 struct TCP_Server_Info *server; 323 int retries = 0, cur_sleep = 0; 324 struct cifs_io_parms io_parms; 325 struct smb2_read_req *req; 326 struct smb_rqst rqst[3]; 327 unsigned int total_len; 328 struct kvec rsp_iov[3]; 329 struct cifs_fid fid; 330 int rsp_buftype[3]; 331 struct kvec *riov; 332 int num_rqst; 333 __u8 oplock; 334 int flags; 335 u32 dlen; 336 int rc; 337 338 cifs_get_readable_path(tcon, full_path, &cfile); 339 *pbytes_read = 0; 340 again: 341 flags = 0; 342 num_rqst = 0; 343 req = NULL; 344 oplock = SMB2_OPLOCK_LEVEL_NONE; 345 server = cifs_pick_channel(tcon->ses); 346 347 if (smb3_encryption_required(tcon)) 348 flags |= CIFS_TRANSFORM_REQ; 349 350 for (int i = 0; i < ARRAY_SIZE(rsp_buftype); i++) 351 rsp_buftype[i] = CIFS_NO_BUFFER; 352 353 memset(rqst, 0, sizeof(rqst)); 354 memset(rsp_iov, 0, sizeof(rsp_iov)); 355 356 if (!cfile) { 357 __le16 *utf16_path __free(kfree) = NULL; 358 struct cifs_open_parms oparms; 359 360 utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); 361 if (!utf16_path) { 362 rc = -ENOMEM; 363 goto out; 364 } 365 366 if (inode && CIFS_I(inode)->lease_granted && 367 server->ops->get_lease_key) { 368 oplock = SMB2_OPLOCK_LEVEL_LEASE; 369 server->ops->get_lease_key(inode, &fid); 370 } 371 372 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, GENERIC_READ, 373 FILE_OPEN, CREATE_NOT_DIR, ACL_NO_MODE); 374 oparms.fid = &fid; 375 376 memset(open_iov, 0, sizeof(open_iov)); 377 rqst[num_rqst].rq_iov = open_iov; 378 rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE; 379 380 rc = SMB2_open_init(tcon, server, &rqst[num_rqst], 381 &oplock, &oparms, utf16_path); 382 if (rc) 383 goto out; 384 smb2_set_next_command(tcon, &rqst[num_rqst++]); 385 } 386 387 io_parms = (struct cifs_io_parms) { 388 .pid = current->tgid, 389 .tcon = tcon, 390 .length = CIFS_MF_SYMLINK_FILE_SIZE, 391 .server = server, 392 .persistent_fid = COMP_PID(cfile), 393 .volatile_fid = COMP_VID(cfile), 394 }; 395 396 rc = smb2_new_read_req((void **)&req, &total_len, 397 &io_parms, NULL, 0, 0); 398 if (rc) 399 goto out; 400 401 read_iov[0].iov_base = req; 402 read_iov[0].iov_len = total_len; 403 rqst[num_rqst].rq_iov = read_iov; 404 rqst[num_rqst].rq_nvec = 1; 405 if (!cfile) { 406 smb2_set_next_command(tcon, &rqst[num_rqst]); 407 smb2_set_related(&rqst[num_rqst]); 408 } 409 num_rqst++; 410 411 if (!cfile) { 412 flags |= CIFS_CP_CREATE_CLOSE_OP; 413 memset(&close_iov, 0, sizeof(close_iov)); 414 rqst[num_rqst].rq_iov = &close_iov; 415 rqst[num_rqst].rq_nvec = 1; 416 rc = SMB2_close_init(tcon, server, &rqst[num_rqst], 417 COMPOUND_FID, COMPOUND_FID, false); 418 smb2_set_related(&rqst[num_rqst++]); 419 if (rc) 420 goto out; 421 } 422 423 if (retries) { 424 if (cur_sleep) 425 msleep(cur_sleep); 426 for (int i = 0; i < num_rqst; i++) 427 smb2_set_replay(server, &rqst[i]); 428 } 429 430 rc = compound_send_recv(xid, tcon->ses, server, flags, 431 num_rqst, rqst, rsp_buftype, rsp_iov); 432 if (rc) { 433 if (rc != -ENODATA) { 434 if (rc != -ENOENT) 435 cifs_stats_fail_inc(tcon, SMB2_READ_HE); 436 cifs_dbg(FYI, "%s: failed to read file: %d\n", 437 __func__, rc); 438 trace_smb3_read_err(0, 0, xid, req->PersistentFileId, 439 tcon->tid, tcon->ses->Suid, 440 io_parms.offset, io_parms.length, 441 rc); 442 } else { 443 trace_smb3_read_done(0, 0, xid, req->PersistentFileId, 444 tcon->tid, tcon->ses->Suid, 445 io_parms.offset, 0); 446 } 447 rc = rc == -ENODATA ? 0 : rc; 448 goto out; 449 } 450 trace_smb3_read_done(0, 0, xid, req->PersistentFileId, 451 tcon->tid, tcon->ses->Suid, 452 io_parms.offset, io_parms.length); 453 454 riov = &rsp_iov[!cfile ? 1 : 0]; 455 read_rsp = riov->iov_base; 456 dlen = le32_to_cpu(read_rsp->DataLength); 457 if (dlen > CIFS_MAX_MSGSIZE || dlen > io_parms.length) { 458 cifs_dbg(FYI, "%s: bad length %u for count %u\n", 459 __func__, dlen, io_parms.length); 460 rc = smb_EIO2(smb_eio_trace_read_overlarge, 461 dlen, io_parms.length); 462 } else if (dlen != CIFS_MF_SYMLINK_FILE_SIZE) { 463 rc = -ENOENT; 464 } else { 465 rc = smb2_validate_iov(read_rsp->DataOffset, dlen, riov, 466 CIFS_MF_SYMLINK_FILE_SIZE); 467 } 468 469 if (!rc) { 470 memcpy(pbuf, (u8 *)read_rsp + read_rsp->DataOffset, dlen); 471 *pbytes_read = dlen; 472 } 473 474 out: 475 if (!cfile) { 476 SMB2_open_free(&rqst[0]); 477 SMB2_close_free(&rqst[2]); 478 } 479 cifs_small_buf_release(req); 480 for (int i = 0; i < ARRAY_SIZE(rsp_buftype); i++) 481 free_rsp_buf(rsp_buftype[i], rsp_iov[i].iov_base); 482 483 if (is_replayable_error(rc) && 484 smb2_should_replay(tcon, &retries, &cur_sleep)) 485 goto again; 486 487 if (cfile) 488 cifsFileInfo_put(cfile); 489 return rc; 490 } 491 492 int 493 smb2_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, 494 struct cifs_sb_info *cifs_sb, const unsigned char *path, 495 char *pbuf, unsigned int *pbytes_written) 496 { 497 int rc; 498 struct cifs_fid fid; 499 struct cifs_open_parms oparms; 500 struct cifs_io_parms io_parms = {0}; 501 __le16 *utf16_path; 502 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 503 struct kvec iov[2]; 504 505 cifs_dbg(FYI, "%s: path: %s\n", __func__, path); 506 507 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); 508 if (!utf16_path) 509 return -ENOMEM; 510 511 oparms = (struct cifs_open_parms) { 512 .tcon = tcon, 513 .cifs_sb = cifs_sb, 514 .path = path, 515 .desired_access = GENERIC_WRITE, 516 .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR), 517 .disposition = FILE_CREATE, 518 .fid = &fid, 519 .mode = 0644, 520 }; 521 522 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, 523 NULL, NULL); 524 if (rc) { 525 kfree(utf16_path); 526 return rc; 527 } 528 529 io_parms.netfid = fid.netfid; 530 io_parms.pid = current->tgid; 531 io_parms.tcon = tcon; 532 io_parms.offset = 0; 533 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE; 534 io_parms.persistent_fid = fid.persistent_fid; 535 io_parms.volatile_fid = fid.volatile_fid; 536 537 /* iov[0] is reserved for smb header */ 538 iov[1].iov_base = pbuf; 539 iov[1].iov_len = CIFS_MF_SYMLINK_FILE_SIZE; 540 541 rc = SMB2_write(xid, &io_parms, pbytes_written, iov, 1); 542 543 /* Make sure we wrote all of the symlink data */ 544 if ((rc == 0) && (*pbytes_written != CIFS_MF_SYMLINK_FILE_SIZE)) 545 rc = smb_EIO2(smb_eio_trace_short_symlink_write, 546 *pbytes_written, CIFS_MF_SYMLINK_FILE_SIZE); 547 548 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 549 550 kfree(utf16_path); 551 return rc; 552 } 553 554 /* 555 * M-F Symlink Functions - End 556 */ 557 558 int 559 cifs_hardlink(struct dentry *old_file, struct inode *inode, 560 struct dentry *direntry) 561 { 562 int rc = -EACCES; 563 unsigned int xid; 564 const char *from_name, *to_name; 565 void *page1, *page2; 566 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 567 struct tcon_link *tlink; 568 struct cifs_tcon *tcon; 569 struct TCP_Server_Info *server; 570 struct cifsInodeInfo *cifsInode; 571 572 if (unlikely(cifs_forced_shutdown(cifs_sb))) 573 return smb_EIO(smb_eio_trace_forced_shutdown); 574 575 tlink = cifs_sb_tlink(cifs_sb); 576 if (IS_ERR(tlink)) 577 return PTR_ERR(tlink); 578 tcon = tlink_tcon(tlink); 579 580 xid = get_xid(); 581 page1 = alloc_dentry_path(); 582 page2 = alloc_dentry_path(); 583 584 from_name = build_path_from_dentry(old_file, page1); 585 if (IS_ERR(from_name)) { 586 rc = PTR_ERR(from_name); 587 goto cifs_hl_exit; 588 } 589 to_name = build_path_from_dentry(direntry, page2); 590 if (IS_ERR(to_name)) { 591 rc = PTR_ERR(to_name); 592 goto cifs_hl_exit; 593 } 594 595 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 596 if (tcon->unix_ext) 597 rc = CIFSUnixCreateHardLink(xid, tcon, from_name, to_name, 598 cifs_sb->local_nls, 599 cifs_remap(cifs_sb)); 600 else { 601 #else 602 { 603 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ 604 server = tcon->ses->server; 605 if (!server->ops->create_hardlink) { 606 rc = -ENOSYS; 607 goto cifs_hl_exit; 608 } 609 rc = server->ops->create_hardlink(xid, tcon, old_file, 610 from_name, to_name, cifs_sb); 611 if ((rc == -EIO) || (rc == -EINVAL)) 612 rc = -EOPNOTSUPP; 613 } 614 615 d_drop(direntry); /* force new lookup from server of target */ 616 617 /* 618 * if source file is cached (oplocked) revalidate will not go to server 619 * until the file is closed or oplock broken so update nlinks locally 620 */ 621 if (d_really_is_positive(old_file)) { 622 cifsInode = CIFS_I(d_inode(old_file)); 623 if (rc == 0) { 624 clear_bit(CIFS_INO_TMPFILE, &cifsInode->flags); 625 spin_lock(&d_inode(old_file)->i_lock); 626 inc_nlink(d_inode(old_file)); 627 spin_unlock(&d_inode(old_file)->i_lock); 628 629 /* 630 * parent dir timestamps will update from srv within a 631 * second, would it really be worth it to set the parent 632 * dir cifs inode time to zero to force revalidate 633 * (faster) for it too? 634 */ 635 } 636 /* 637 * if not oplocked will force revalidate to get info on source 638 * file from srv. Note Samba server prior to 4.2 has bug - 639 * not updating src file ctime on hardlinks but Windows servers 640 * handle it properly 641 */ 642 cifsInode->time = 0; 643 644 /* 645 * Will update parent dir timestamps from srv within a second. 646 * Would it really be worth it to set the parent dir (cifs 647 * inode) time field to zero to force revalidate on parent 648 * directory faster ie 649 * 650 * CIFS_I(inode)->time = 0; 651 */ 652 } 653 654 cifs_hl_exit: 655 free_dentry_path(page1); 656 free_dentry_path(page2); 657 free_xid(xid); 658 cifs_put_tlink(tlink); 659 return rc; 660 } 661 662 int 663 cifs_symlink(const struct mnt_idmap *idmap, struct inode *inode, 664 struct dentry *direntry, const char *symname) 665 { 666 struct cifs_sb_info *cifs_sb = CIFS_SB(inode); 667 struct inode *newinode = NULL; 668 struct tcon_link *tlink; 669 struct cifs_tcon *pTcon; 670 const char *full_path; 671 int rc = -EOPNOTSUPP; 672 unsigned int sbflags; 673 unsigned int xid; 674 void *page; 675 676 if (unlikely(cifs_forced_shutdown(cifs_sb))) 677 return smb_EIO(smb_eio_trace_forced_shutdown); 678 679 page = alloc_dentry_path(); 680 if (!page) 681 return -ENOMEM; 682 683 xid = get_xid(); 684 685 tlink = cifs_sb_tlink(cifs_sb); 686 if (IS_ERR(tlink)) { 687 rc = PTR_ERR(tlink); 688 /* BB could be clearer if skipped put_tlink on error here, but harmless */ 689 goto symlink_exit; 690 } 691 pTcon = tlink_tcon(tlink); 692 693 full_path = build_path_from_dentry(direntry, page); 694 if (IS_ERR(full_path)) { 695 rc = PTR_ERR(full_path); 696 goto symlink_exit; 697 } 698 699 cifs_dbg(FYI, "Full path: %s\n", full_path); 700 cifs_dbg(FYI, "symname is %s\n", symname); 701 702 /* BB what if DFS and this volume is on different share? BB */ 703 sbflags = cifs_sb_flags(cifs_sb); 704 rc = -EOPNOTSUPP; 705 switch (cifs_symlink_type(cifs_sb)) { 706 case CIFS_SYMLINK_TYPE_UNIX: 707 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 708 if (pTcon->unix_ext) { 709 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, 710 symname, 711 cifs_sb->local_nls, 712 cifs_remap(cifs_sb)); 713 } 714 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ 715 break; 716 717 case CIFS_SYMLINK_TYPE_MFSYMLINKS: 718 if (sbflags & CIFS_MOUNT_MF_SYMLINKS) { 719 rc = create_mf_symlink(xid, pTcon, cifs_sb, 720 full_path, symname); 721 } 722 break; 723 724 case CIFS_SYMLINK_TYPE_SFU: 725 if (sbflags & CIFS_MOUNT_UNX_EMUL) { 726 rc = __cifs_sfu_make_node(xid, inode, direntry, pTcon, 727 full_path, S_IFLNK, 728 0, symname); 729 } 730 break; 731 732 case CIFS_SYMLINK_TYPE_NATIVE: 733 case CIFS_SYMLINK_TYPE_NFS: 734 case CIFS_SYMLINK_TYPE_WSL: 735 if (CIFS_REPARSE_SUPPORT(pTcon)) { 736 rc = create_reparse_symlink(xid, inode, direntry, pTcon, 737 full_path, symname); 738 goto symlink_exit; 739 } 740 break; 741 default: 742 break; 743 } 744 745 if (rc == 0) { 746 if (pTcon->posix_extensions) { 747 rc = smb311_posix_get_inode_info(&newinode, full_path, 748 NULL, inode->i_sb, xid); 749 } else if (pTcon->unix_ext) { 750 rc = cifs_get_inode_info_unix(&newinode, full_path, 751 inode->i_sb, xid); 752 } else { 753 rc = cifs_get_inode_info(&newinode, full_path, NULL, 754 inode->i_sb, xid, NULL); 755 } 756 757 if (rc != 0) { 758 cifs_dbg(FYI, "Create symlink ok, getinodeinfo fail rc = %d\n", 759 rc); 760 } else { 761 d_instantiate(direntry, newinode); 762 } 763 } 764 symlink_exit: 765 free_dentry_path(page); 766 cifs_put_tlink(tlink); 767 free_xid(xid); 768 return rc; 769 } 770