1 // SPDX-License-Identifier: LGPL-2.1 2 /* 3 * 4 * Copyright (C) International Business Machines Corp., 2002, 2011 5 * Etersoft, 2012 6 * Author(s): Pavel Shilovsky (pshilovsky@samba.org), 7 * Steve French (sfrench@us.ibm.com) 8 * 9 */ 10 #include <linux/fs.h> 11 #include <linux/stat.h> 12 #include <linux/slab.h> 13 #include <linux/pagemap.h> 14 #include <asm/div64.h> 15 #include "cifsfs.h" 16 #include "cifsglob.h" 17 #include "cifsproto.h" 18 #include "cifs_debug.h" 19 #include "cifs_fs_sb.h" 20 #include "cifs_unicode.h" 21 #include "fscache.h" 22 #include "smb2glob.h" 23 #include "smb2proto.h" 24 #include "cached_dir.h" 25 #include "../common/smb2status.h" 26 #include "../common/smbfsctl.h" 27 28 static struct reparse_data_buffer *reparse_buf_ptr(struct kvec *iov) 29 { 30 struct reparse_data_buffer *buf; 31 struct smb2_ioctl_rsp *io = iov->iov_base; 32 u32 off, count, len; 33 u16 rdlen; 34 35 count = le32_to_cpu(io->OutputCount); 36 off = le32_to_cpu(io->OutputOffset); 37 if (check_add_overflow(off, count, &len) || len > iov->iov_len) 38 return ERR_PTR(smb_EIO2(smb_eio_trace_reparse_overlong, 39 off, count)); 40 41 buf = (struct reparse_data_buffer *)((u8 *)io + off); 42 len = sizeof(*buf); 43 rdlen = le16_to_cpu(buf->ReparseDataLength); 44 45 if (count < len || count < rdlen + len) 46 return ERR_PTR(smb_EIO2(smb_eio_trace_reparse_rdlen, count, rdlen)); 47 return buf; 48 } 49 50 static inline __u32 file_create_options(struct dentry *dentry) 51 { 52 struct cifsInodeInfo *ci; 53 54 if (dentry) { 55 ci = CIFS_I(d_inode(dentry)); 56 if (ci->cifsAttrs & ATTR_REPARSE_POINT) 57 return OPEN_REPARSE_POINT; 58 } 59 return 0; 60 } 61 62 /* Parse owner and group from SMB3.1.1 POSIX query info */ 63 static int parse_posix_sids(struct cifs_open_info_data *data, 64 struct kvec *rsp_iov) 65 { 66 struct smb2_query_info_rsp *qi = rsp_iov->iov_base; 67 unsigned int out_len = le32_to_cpu(qi->OutputBufferLength); 68 unsigned int qi_len = sizeof(data->posix_fi); 69 int owner_len, group_len; 70 u8 *sidsbuf, *sidsbuf_end; 71 72 if (out_len <= qi_len) 73 return -EINVAL; 74 75 sidsbuf = (u8 *)qi + le16_to_cpu(qi->OutputBufferOffset) + qi_len; 76 sidsbuf_end = sidsbuf + out_len - qi_len; 77 78 owner_len = posix_info_sid_size(sidsbuf, sidsbuf_end); 79 if (owner_len == -1) 80 return -EINVAL; 81 82 memcpy(&data->posix_owner, sidsbuf, owner_len); 83 group_len = posix_info_sid_size(sidsbuf + owner_len, sidsbuf_end); 84 if (group_len == -1) 85 return -EINVAL; 86 87 memcpy(&data->posix_group, sidsbuf + owner_len, group_len); 88 return 0; 89 } 90 91 struct wsl_query_ea { 92 __le32 next; 93 __u8 name_len; 94 __u8 name[SMB2_WSL_XATTR_NAME_LEN + 1]; 95 } __packed; 96 97 #define NEXT_OFF cpu_to_le32(sizeof(struct wsl_query_ea)) 98 99 static const struct wsl_query_ea wsl_query_eas[] = { 100 { .next = NEXT_OFF, .name_len = SMB2_WSL_XATTR_NAME_LEN, .name = SMB2_WSL_XATTR_UID, }, 101 { .next = NEXT_OFF, .name_len = SMB2_WSL_XATTR_NAME_LEN, .name = SMB2_WSL_XATTR_GID, }, 102 { .next = NEXT_OFF, .name_len = SMB2_WSL_XATTR_NAME_LEN, .name = SMB2_WSL_XATTR_MODE, }, 103 { .next = 0, .name_len = SMB2_WSL_XATTR_NAME_LEN, .name = SMB2_WSL_XATTR_DEV, }, 104 }; 105 106 static int check_wsl_eas(struct kvec *rsp_iov) 107 { 108 struct smb2_file_full_ea_info *ea; 109 struct smb2_query_info_rsp *rsp = rsp_iov->iov_base; 110 unsigned long addr; 111 u32 outlen, next; 112 u16 vlen; 113 u8 nlen; 114 u8 *end; 115 116 outlen = le32_to_cpu(rsp->OutputBufferLength); 117 if (outlen < SMB2_WSL_MIN_QUERY_EA_RESP_SIZE || 118 outlen > SMB2_WSL_MAX_QUERY_EA_RESP_SIZE) 119 return -EINVAL; 120 121 ea = (void *)((u8 *)rsp_iov->iov_base + 122 le16_to_cpu(rsp->OutputBufferOffset)); 123 end = (u8 *)rsp_iov->iov_base + rsp_iov->iov_len; 124 for (;;) { 125 if ((u8 *)ea > end - sizeof(*ea)) 126 return -EINVAL; 127 128 nlen = ea->ea_name_length; 129 vlen = le16_to_cpu(ea->ea_value_length); 130 if (nlen != SMB2_WSL_XATTR_NAME_LEN || 131 (u8 *)ea->ea_data + nlen + 1 + vlen > end) 132 return -EINVAL; 133 134 switch (vlen) { 135 case 4: 136 if (strncmp(ea->ea_data, SMB2_WSL_XATTR_UID, nlen) && 137 strncmp(ea->ea_data, SMB2_WSL_XATTR_GID, nlen) && 138 strncmp(ea->ea_data, SMB2_WSL_XATTR_MODE, nlen)) 139 return -EINVAL; 140 break; 141 case 8: 142 if (strncmp(ea->ea_data, SMB2_WSL_XATTR_DEV, nlen)) 143 return -EINVAL; 144 break; 145 case 0: 146 if (!strncmp(ea->ea_data, SMB2_WSL_XATTR_UID, nlen) || 147 !strncmp(ea->ea_data, SMB2_WSL_XATTR_GID, nlen) || 148 !strncmp(ea->ea_data, SMB2_WSL_XATTR_MODE, nlen) || 149 !strncmp(ea->ea_data, SMB2_WSL_XATTR_DEV, nlen)) 150 break; 151 fallthrough; 152 default: 153 return -EINVAL; 154 } 155 156 next = le32_to_cpu(ea->next_entry_offset); 157 if (!next) 158 break; 159 if (!IS_ALIGNED(next, 4) || 160 check_add_overflow((unsigned long)ea, next, &addr)) 161 return -EINVAL; 162 ea = (void *)addr; 163 } 164 return 0; 165 } 166 167 /* 168 * If @cfile is NULL, then need to account for trailing CLOSE request in the 169 * compound chain. 170 */ 171 static void set_next_compound(struct cifs_tcon *tcon, 172 struct cifsFileInfo *cfile, 173 int i, int num_cmds, 174 struct smb_rqst *rqst, int *num_rqst) 175 { 176 int k = !cfile ? 1 : 0; 177 178 if (i + 1 < num_cmds + k) 179 smb2_set_next_command(tcon, &rqst[*num_rqst]); 180 if (i + k > 0) 181 smb2_set_related(&rqst[*num_rqst]); 182 (*num_rqst)++; 183 } 184 185 #define COMP_PID(cfile) ((cfile) ? (cfile)->fid.persistent_fid : COMPOUND_FID) 186 #define COMP_VID(cfile) ((cfile) ? (cfile)->fid.volatile_fid : COMPOUND_FID) 187 188 /* 189 * note: If cfile is passed, the reference to it is dropped here. 190 * So make sure that you do not reuse cfile after return from this func. 191 * 192 * If passing @out_iov and @out_buftype, ensure to make them both large enough 193 * (>= 3) to hold all compounded responses. Caller is also responsible for 194 * freeing them up with free_rsp_buf(). 195 */ 196 static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, 197 struct cifs_sb_info *cifs_sb, const char *full_path, 198 struct cifs_open_parms *oparms, struct kvec *in_iov, 199 int *cmds, int num_cmds, struct cifsFileInfo *cfile, 200 struct kvec *out_iov, int *out_buftype, struct dentry *dentry) 201 { 202 203 struct smb2_create_rsp *create_rsp = NULL; 204 struct smb2_query_info_rsp *qi_rsp = NULL; 205 struct smb2_compound_vars *vars = NULL; 206 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 207 struct cifs_open_info_data *idata; 208 struct cifs_ses *ses = tcon->ses; 209 struct reparse_data_buffer *rbuf; 210 struct TCP_Server_Info *server; 211 int resp_buftype[MAX_COMPOUND]; 212 int retries = 0, cur_sleep = 0; 213 __u8 delete_pending[8] = {1,}; 214 struct kvec *rsp_iov, *iov; 215 struct inode *inode = NULL; 216 __le16 *utf16_path = NULL; 217 struct smb_rqst *rqst; 218 unsigned int size[2]; 219 struct cifs_fid fid; 220 int num_rqst = 0, i; 221 unsigned int len; 222 int tmp_rc, rc; 223 int flags = 0; 224 void *data[2]; 225 226 replay_again: 227 /* reinitialize for possible replay */ 228 flags = 0; 229 oplock = SMB2_OPLOCK_LEVEL_NONE; 230 num_rqst = 0; 231 server = cifs_pick_channel(ses); 232 233 vars = kzalloc_obj(*vars, GFP_ATOMIC); 234 if (vars == NULL) { 235 rc = -ENOMEM; 236 goto out; 237 } 238 rqst = &vars->rqst[0]; 239 rsp_iov = &vars->rsp_iov[0]; 240 241 if (smb3_encryption_required(tcon)) 242 flags |= CIFS_TRANSFORM_REQ; 243 244 for (i = 0; i < ARRAY_SIZE(resp_buftype); i++) 245 resp_buftype[i] = CIFS_NO_BUFFER; 246 247 /* We already have a handle so we can skip the open */ 248 if (cfile) 249 goto after_open; 250 251 /* Open */ 252 utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); 253 if (!utf16_path) { 254 rc = -ENOMEM; 255 goto finished; 256 } 257 258 /* if there is an existing lease, reuse it */ 259 260 /* 261 * note: files with hardlinks cause unexpected behaviour. As per MS-SMB2, 262 * lease keys are associated with the filepath. We are maintaining lease keys 263 * with the inode on the client. If the file has hardlinks, it is possible 264 * that the lease for a file be reused for an operation on its hardlink or 265 * vice versa. 266 * As a workaround, send request using an existing lease key and if the server 267 * returns STATUS_INVALID_PARAMETER, which maps to EINVAL, send the request 268 * again without the lease. 269 */ 270 if (dentry) { 271 inode = d_inode(dentry); 272 if (CIFS_I(inode)->lease_granted && server->ops->get_lease_key) { 273 oplock = SMB2_OPLOCK_LEVEL_LEASE; 274 server->ops->get_lease_key(inode, &fid); 275 } 276 } 277 278 vars->oparms = *oparms; 279 vars->oparms.fid = &fid; 280 281 rqst[num_rqst].rq_iov = &vars->open_iov[0]; 282 rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE; 283 rc = SMB2_open_init(tcon, server, 284 &rqst[num_rqst], &oplock, &vars->oparms, 285 utf16_path); 286 kfree(utf16_path); 287 if (rc) 288 goto finished; 289 290 smb2_set_next_command(tcon, &rqst[num_rqst]); 291 after_open: 292 num_rqst++; 293 rc = 0; 294 295 i = 0; 296 297 /* Skip the leading explicit OPEN operation */ 298 if (num_cmds > 0 && cmds[0] == SMB2_OP_OPEN_QUERY) 299 i++; 300 301 for (; i < num_cmds; i++) { 302 /* Operation */ 303 switch (cmds[i]) { 304 case SMB2_OP_QUERY_INFO: 305 rqst[num_rqst].rq_iov = &vars->qi_iov; 306 rqst[num_rqst].rq_nvec = 1; 307 308 rc = SMB2_query_info_init(tcon, server, 309 &rqst[num_rqst], 310 COMP_PID(cfile), COMP_VID(cfile), 311 FILE_ALL_INFORMATION, 312 SMB2_O_INFO_FILE, 0, 313 sizeof(struct smb2_file_all_info) + 314 PATH_MAX * 2, 0, NULL); 315 if (rc) 316 goto finished; 317 set_next_compound(tcon, cfile, i, num_cmds, rqst, &num_rqst); 318 trace_smb3_query_info_compound_enter(xid, tcon->tid, 319 ses->Suid, full_path); 320 break; 321 case SMB2_OP_POSIX_QUERY_INFO: 322 rqst[num_rqst].rq_iov = &vars->qi_iov; 323 rqst[num_rqst].rq_nvec = 1; 324 325 /* TBD: fix following to allow for longer SIDs */ 326 rc = SMB2_query_info_init(tcon, server, 327 &rqst[num_rqst], 328 COMP_PID(cfile), COMP_VID(cfile), 329 SMB_FIND_FILE_POSIX_INFO, 330 SMB2_O_INFO_FILE, 0, 331 sizeof(struct smb311_posix_qinfo) + 332 (PATH_MAX * 2) + 333 (sizeof(struct smb_sid) * 2), 0, NULL); 334 if (rc) 335 goto finished; 336 set_next_compound(tcon, cfile, i, num_cmds, rqst, &num_rqst); 337 trace_smb3_posix_query_info_compound_enter(xid, tcon->tid, 338 ses->Suid, full_path); 339 break; 340 case SMB2_OP_MKDIR: 341 /* 342 * Directories are created through parameters in the 343 * SMB2_open() call. 344 */ 345 trace_smb3_mkdir_enter(xid, tcon->tid, ses->Suid, full_path); 346 break; 347 case SMB2_OP_UNLINK: 348 rqst[num_rqst].rq_iov = vars->unlink_iov; 349 rqst[num_rqst].rq_nvec = 1; 350 351 size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */ 352 data[0] = &delete_pending[0]; 353 354 rc = SMB2_set_info_init(tcon, server, 355 &rqst[num_rqst], 356 COMP_PID(cfile), COMP_VID(cfile), 357 current->tgid, FILE_DISPOSITION_INFORMATION, 358 SMB2_O_INFO_FILE, 0, 359 data, size); 360 if (rc) 361 goto finished; 362 set_next_compound(tcon, cfile, i, num_cmds, rqst, &num_rqst); 363 trace_smb3_unlink_enter(xid, tcon->tid, ses->Suid, full_path); 364 break; 365 case SMB2_OP_SET_EOF: 366 rqst[num_rqst].rq_iov = &vars->si_iov[0]; 367 rqst[num_rqst].rq_nvec = 1; 368 369 size[0] = in_iov[i].iov_len; 370 data[0] = in_iov[i].iov_base; 371 372 rc = SMB2_set_info_init(tcon, server, 373 &rqst[num_rqst], 374 COMP_PID(cfile), COMP_VID(cfile), 375 current->tgid, FILE_END_OF_FILE_INFORMATION, 376 SMB2_O_INFO_FILE, 0, 377 data, size); 378 if (rc) 379 goto finished; 380 set_next_compound(tcon, cfile, i, num_cmds, rqst, &num_rqst); 381 trace_smb3_set_eof_enter(xid, tcon->tid, ses->Suid, full_path); 382 break; 383 case SMB2_OP_SET_INFO: 384 rqst[num_rqst].rq_iov = &vars->si_iov[0]; 385 rqst[num_rqst].rq_nvec = 1; 386 387 size[0] = in_iov[i].iov_len; 388 data[0] = in_iov[i].iov_base; 389 390 rc = SMB2_set_info_init(tcon, server, 391 &rqst[num_rqst], 392 COMP_PID(cfile), COMP_VID(cfile), 393 current->tgid, FILE_BASIC_INFORMATION, 394 SMB2_O_INFO_FILE, 0, data, size); 395 if (rc) 396 goto finished; 397 set_next_compound(tcon, cfile, i, num_cmds, rqst, &num_rqst); 398 trace_smb3_set_info_compound_enter(xid, tcon->tid, 399 ses->Suid, full_path); 400 break; 401 case SMB2_OP_RENAME: 402 rqst[num_rqst].rq_iov = vars->rename_iov; 403 rqst[num_rqst].rq_nvec = 2; 404 405 len = in_iov[i].iov_len; 406 407 vars->rename_info.ReplaceIfExists = 1; 408 vars->rename_info.RootDirectory = 0; 409 vars->rename_info.FileNameLength = cpu_to_le32(len); 410 411 size[0] = sizeof(struct smb2_file_rename_info); 412 data[0] = &vars->rename_info; 413 414 size[1] = len + 2 /* null */; 415 data[1] = in_iov[i].iov_base; 416 417 rc = SMB2_set_info_init(tcon, server, 418 &rqst[num_rqst], 419 COMP_PID(cfile), COMP_VID(cfile), 420 current->tgid, FILE_RENAME_INFORMATION, 421 SMB2_O_INFO_FILE, 0, data, size); 422 423 if (rc) 424 goto finished; 425 set_next_compound(tcon, cfile, i, num_cmds, rqst, &num_rqst); 426 trace_smb3_rename_enter(xid, tcon->tid, ses->Suid, full_path); 427 break; 428 case SMB2_OP_HARDLINK: 429 rqst[num_rqst].rq_iov = vars->hl_iov; 430 rqst[num_rqst].rq_nvec = 2; 431 432 len = in_iov[i].iov_len; 433 434 vars->link_info.ReplaceIfExists = 0; 435 vars->link_info.RootDirectory = 0; 436 vars->link_info.FileNameLength = cpu_to_le32(len); 437 438 size[0] = sizeof(struct smb2_file_link_info); 439 data[0] = &vars->link_info; 440 441 size[1] = len + 2 /* null */; 442 data[1] = in_iov[i].iov_base; 443 444 rc = SMB2_set_info_init(tcon, server, 445 &rqst[num_rqst], 446 COMP_PID(cfile), COMP_VID(cfile), 447 current->tgid, FILE_LINK_INFORMATION, 448 SMB2_O_INFO_FILE, 0, data, size); 449 if (rc) 450 goto finished; 451 set_next_compound(tcon, cfile, i, num_cmds, rqst, &num_rqst); 452 trace_smb3_hardlink_enter(xid, tcon->tid, ses->Suid, full_path); 453 break; 454 case SMB2_OP_SET_REPARSE: 455 rqst[num_rqst].rq_iov = vars->io_iov; 456 rqst[num_rqst].rq_nvec = ARRAY_SIZE(vars->io_iov); 457 458 rc = SMB2_ioctl_init(tcon, server, &rqst[num_rqst], 459 COMP_PID(cfile), COMP_VID(cfile), 460 FSCTL_SET_REPARSE_POINT, 461 in_iov[i].iov_base, 462 in_iov[i].iov_len, 0); 463 if (rc) 464 goto finished; 465 set_next_compound(tcon, cfile, i, num_cmds, rqst, &num_rqst); 466 trace_smb3_set_reparse_compound_enter(xid, tcon->tid, 467 ses->Suid, full_path); 468 break; 469 case SMB2_OP_GET_REPARSE: 470 rqst[num_rqst].rq_iov = vars->io_iov; 471 rqst[num_rqst].rq_nvec = ARRAY_SIZE(vars->io_iov); 472 473 rc = SMB2_ioctl_init(tcon, server, &rqst[num_rqst], 474 COMP_PID(cfile), COMP_VID(cfile), 475 FSCTL_GET_REPARSE_POINT, 476 NULL, 0, CIFSMaxBufSize); 477 if (rc) 478 goto finished; 479 set_next_compound(tcon, cfile, i, num_cmds, rqst, &num_rqst); 480 trace_smb3_get_reparse_compound_enter(xid, tcon->tid, 481 ses->Suid, full_path); 482 break; 483 case SMB2_OP_QUERY_WSL_EA: 484 rqst[num_rqst].rq_iov = &vars->ea_iov; 485 rqst[num_rqst].rq_nvec = 1; 486 487 rc = SMB2_query_info_init(tcon, server, 488 &rqst[num_rqst], 489 COMP_PID(cfile), COMP_VID(cfile), 490 FILE_FULL_EA_INFORMATION, 491 SMB2_O_INFO_FILE, 0, 492 SMB2_WSL_MAX_QUERY_EA_RESP_SIZE, 493 sizeof(wsl_query_eas), 494 (void *)wsl_query_eas); 495 if (rc) 496 goto finished; 497 set_next_compound(tcon, cfile, i, num_cmds, rqst, &num_rqst); 498 trace_smb3_query_wsl_ea_compound_enter(xid, tcon->tid, 499 ses->Suid, full_path); 500 break; 501 default: 502 cifs_dbg(VFS, "Invalid command\n"); 503 rc = -EINVAL; 504 } 505 } 506 if (rc) 507 goto finished; 508 509 /* We already have a handle so we can skip the close */ 510 if (cfile) 511 goto after_close; 512 /* Close */ 513 flags |= CIFS_CP_CREATE_CLOSE_OP; 514 rqst[num_rqst].rq_iov = &vars->close_iov; 515 rqst[num_rqst].rq_nvec = 1; 516 rc = SMB2_close_init(tcon, server, 517 &rqst[num_rqst], COMPOUND_FID, 518 COMPOUND_FID, false); 519 smb2_set_related(&rqst[num_rqst]); 520 if (rc) 521 goto finished; 522 after_close: 523 num_rqst++; 524 525 if (cfile) { 526 if (retries) { 527 /* Back-off before retry */ 528 if (cur_sleep) 529 msleep(cur_sleep); 530 for (i = 1; i < num_rqst - 2; i++) 531 smb2_set_replay(server, &rqst[i]); 532 } 533 534 rc = compound_send_recv(xid, ses, server, 535 flags, num_rqst - 2, 536 &rqst[1], &resp_buftype[1], 537 &rsp_iov[1]); 538 } else { 539 if (retries) { 540 /* Back-off before retry */ 541 if (cur_sleep) 542 msleep(cur_sleep); 543 for (i = 0; i < num_rqst; i++) 544 smb2_set_replay(server, &rqst[i]); 545 } 546 547 rc = compound_send_recv(xid, ses, server, 548 flags, num_rqst, 549 rqst, resp_buftype, 550 rsp_iov); 551 } 552 553 finished: 554 num_rqst = 0; 555 SMB2_open_free(&rqst[num_rqst++]); 556 if (rc == -EREMCHG) { 557 pr_warn_once("server share %s deleted\n", tcon->tree_name); 558 tcon->need_reconnect = true; 559 } 560 561 tmp_rc = rc; 562 563 if (rc == 0 && num_cmds > 0 && cmds[0] == SMB2_OP_OPEN_QUERY) { 564 create_rsp = rsp_iov[0].iov_base; 565 idata = in_iov[0].iov_base; 566 idata->fi.CreationTime = create_rsp->CreationTime; 567 idata->fi.LastAccessTime = create_rsp->LastAccessTime; 568 idata->fi.LastWriteTime = create_rsp->LastWriteTime; 569 idata->fi.ChangeTime = create_rsp->ChangeTime; 570 idata->fi.Attributes = create_rsp->FileAttributes; 571 idata->fi.AllocationSize = create_rsp->AllocationSize; 572 idata->fi.EndOfFile = create_rsp->EndofFile; 573 if (le32_to_cpu(idata->fi.NumberOfLinks) == 0) 574 idata->fi.NumberOfLinks = cpu_to_le32(1); /* dummy value */ 575 idata->fi.DeletePending = 0; /* successful open = not delete pending */ 576 idata->fi.Directory = !!(le32_to_cpu(create_rsp->FileAttributes) & ATTR_DIRECTORY); 577 578 /* smb2_parse_contexts() fills idata->fi.IndexNumber */ 579 rc = smb2_parse_contexts(server, &rsp_iov[0], &oparms->fid->epoch, 580 oparms->fid->lease_key, &oplock, &idata->fi, NULL); 581 if (rc) 582 cifs_dbg(VFS, "rc: %d parsing context of compound op\n", rc); 583 } 584 585 for (i = 0; i < num_cmds; i++) { 586 char *buf = rsp_iov[i + 1].iov_base; 587 588 if (buf && resp_buftype[i + 1] != CIFS_NO_BUFFER) 589 rc = server->ops->map_error(buf, false); 590 else 591 rc = tmp_rc; 592 switch (cmds[i]) { 593 case SMB2_OP_QUERY_INFO: 594 idata = in_iov[i].iov_base; 595 idata->contains_posix_file_info = false; 596 if (rc == 0 && cfile && cfile->symlink_target) { 597 idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); 598 if (!idata->symlink_target) 599 rc = -ENOMEM; 600 } 601 if (rc == 0) { 602 qi_rsp = (struct smb2_query_info_rsp *) 603 rsp_iov[i + 1].iov_base; 604 rc = smb2_validate_and_copy_iov( 605 le16_to_cpu(qi_rsp->OutputBufferOffset), 606 le32_to_cpu(qi_rsp->OutputBufferLength), 607 &rsp_iov[i + 1], sizeof(idata->fi), (char *)&idata->fi); 608 } 609 SMB2_query_info_free(&rqst[num_rqst++]); 610 if (rc) 611 trace_smb3_query_info_compound_err(xid, tcon->tid, 612 ses->Suid, rc); 613 else 614 trace_smb3_query_info_compound_done(xid, tcon->tid, 615 ses->Suid); 616 break; 617 case SMB2_OP_POSIX_QUERY_INFO: 618 idata = in_iov[i].iov_base; 619 idata->contains_posix_file_info = true; 620 if (rc == 0 && cfile && cfile->symlink_target) { 621 idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL); 622 if (!idata->symlink_target) 623 rc = -ENOMEM; 624 } 625 if (rc == 0) { 626 qi_rsp = (struct smb2_query_info_rsp *) 627 rsp_iov[i + 1].iov_base; 628 rc = smb2_validate_and_copy_iov( 629 le16_to_cpu(qi_rsp->OutputBufferOffset), 630 le32_to_cpu(qi_rsp->OutputBufferLength), 631 &rsp_iov[i + 1], sizeof(idata->posix_fi) /* add SIDs */, 632 (char *)&idata->posix_fi); 633 } 634 if (rc == 0) 635 rc = parse_posix_sids(idata, &rsp_iov[i + 1]); 636 637 SMB2_query_info_free(&rqst[num_rqst++]); 638 if (rc) 639 trace_smb3_posix_query_info_compound_err(xid, tcon->tid, 640 ses->Suid, rc); 641 else 642 trace_smb3_posix_query_info_compound_done(xid, tcon->tid, 643 ses->Suid); 644 break; 645 case SMB2_OP_MKDIR: 646 if (rc) 647 trace_smb3_mkdir_err(xid, tcon->tid, ses->Suid, rc); 648 else 649 trace_smb3_mkdir_done(xid, tcon->tid, ses->Suid); 650 break; 651 case SMB2_OP_HARDLINK: 652 if (rc) 653 trace_smb3_hardlink_err(xid, tcon->tid, ses->Suid, rc); 654 else 655 trace_smb3_hardlink_done(xid, tcon->tid, ses->Suid); 656 SMB2_set_info_free(&rqst[num_rqst++]); 657 break; 658 case SMB2_OP_RENAME: 659 if (rc) 660 trace_smb3_rename_err(xid, tcon->tid, ses->Suid, rc); 661 else 662 trace_smb3_rename_done(xid, tcon->tid, ses->Suid); 663 SMB2_set_info_free(&rqst[num_rqst++]); 664 break; 665 case SMB2_OP_UNLINK: 666 if (!rc) 667 trace_smb3_unlink_done(xid, tcon->tid, ses->Suid); 668 else 669 trace_smb3_unlink_err(xid, tcon->tid, ses->Suid, rc); 670 SMB2_set_info_free(&rqst[num_rqst++]); 671 break; 672 case SMB2_OP_SET_EOF: 673 if (rc) 674 trace_smb3_set_eof_err(xid, tcon->tid, ses->Suid, rc); 675 else 676 trace_smb3_set_eof_done(xid, tcon->tid, ses->Suid); 677 SMB2_set_info_free(&rqst[num_rqst++]); 678 break; 679 case SMB2_OP_SET_INFO: 680 if (rc) 681 trace_smb3_set_info_compound_err(xid, tcon->tid, 682 ses->Suid, rc); 683 else 684 trace_smb3_set_info_compound_done(xid, tcon->tid, 685 ses->Suid); 686 SMB2_set_info_free(&rqst[num_rqst++]); 687 break; 688 case SMB2_OP_SET_REPARSE: 689 if (rc) { 690 trace_smb3_set_reparse_compound_err(xid, tcon->tid, 691 ses->Suid, rc); 692 } else { 693 trace_smb3_set_reparse_compound_done(xid, tcon->tid, 694 ses->Suid); 695 } 696 SMB2_ioctl_free(&rqst[num_rqst++]); 697 break; 698 case SMB2_OP_GET_REPARSE: 699 if (!rc) { 700 iov = &rsp_iov[i + 1]; 701 idata = in_iov[i].iov_base; 702 idata->reparse.io.iov = *iov; 703 idata->reparse.io.buftype = resp_buftype[i + 1]; 704 idata->contains_posix_file_info = false; /* BB VERIFY */ 705 rbuf = reparse_buf_ptr(iov); 706 if (IS_ERR(rbuf)) { 707 rc = PTR_ERR(rbuf); 708 trace_smb3_get_reparse_compound_err(xid, tcon->tid, 709 ses->Suid, rc); 710 } else { 711 idata->reparse.tag = le32_to_cpu(rbuf->ReparseTag); 712 trace_smb3_get_reparse_compound_done(xid, tcon->tid, 713 ses->Suid); 714 } 715 memset(iov, 0, sizeof(*iov)); 716 resp_buftype[i + 1] = CIFS_NO_BUFFER; 717 } else { 718 trace_smb3_get_reparse_compound_err(xid, tcon->tid, 719 ses->Suid, rc); 720 } 721 SMB2_ioctl_free(&rqst[num_rqst++]); 722 break; 723 case SMB2_OP_QUERY_WSL_EA: 724 if (!rc) { 725 idata = in_iov[i].iov_base; 726 idata->contains_posix_file_info = false; 727 qi_rsp = rsp_iov[i + 1].iov_base; 728 data[0] = (u8 *)qi_rsp + le16_to_cpu(qi_rsp->OutputBufferOffset); 729 size[0] = le32_to_cpu(qi_rsp->OutputBufferLength); 730 rc = check_wsl_eas(&rsp_iov[i + 1]); 731 if (!rc) { 732 memcpy(idata->wsl.eas, data[0], size[0]); 733 idata->wsl.eas_len = size[0]; 734 } 735 } 736 if (!rc) { 737 trace_smb3_query_wsl_ea_compound_done(xid, tcon->tid, 738 ses->Suid); 739 } else { 740 trace_smb3_query_wsl_ea_compound_err(xid, tcon->tid, 741 ses->Suid, rc); 742 } 743 SMB2_query_info_free(&rqst[num_rqst++]); 744 break; 745 } 746 } 747 SMB2_close_free(&rqst[num_rqst]); 748 rc = tmp_rc; 749 750 num_cmds += 2; 751 if (out_iov && out_buftype) { 752 memcpy(out_iov, rsp_iov, num_cmds * sizeof(*out_iov)); 753 memcpy(out_buftype, resp_buftype, 754 num_cmds * sizeof(*out_buftype)); 755 } else { 756 for (i = 0; i < num_cmds; i++) 757 free_rsp_buf(resp_buftype[i], rsp_iov[i].iov_base); 758 } 759 num_cmds -= 2; /* correct num_cmds as there could be a retry */ 760 kfree(vars); 761 762 if (is_replayable_error(rc) && 763 smb2_should_replay(tcon, &retries, &cur_sleep)) 764 goto replay_again; 765 766 out: 767 if (cfile) 768 cifsFileInfo_put(cfile); 769 770 return rc; 771 } 772 773 static int parse_create_response(struct cifs_open_info_data *data, 774 struct cifs_sb_info *cifs_sb, 775 const char *full_path, 776 const struct kvec *iov) 777 { 778 struct smb2_create_rsp *rsp = iov->iov_base; 779 bool reparse_point = false; 780 u32 tag = 0; 781 int rc = 0; 782 783 switch (rsp->hdr.Status) { 784 case STATUS_IO_REPARSE_TAG_NOT_HANDLED: 785 reparse_point = true; 786 break; 787 case STATUS_STOPPED_ON_SYMLINK: 788 rc = smb2_parse_symlink_response(cifs_sb, iov, 789 full_path, 790 &data->symlink_target); 791 if (rc) 792 return rc; 793 tag = IO_REPARSE_TAG_SYMLINK; 794 reparse_point = true; 795 break; 796 case STATUS_SUCCESS: 797 reparse_point = !!(rsp->Flags & SMB2_CREATE_FLAG_REPARSEPOINT); 798 break; 799 } 800 data->reparse_point = reparse_point; 801 data->reparse.tag = tag; 802 return rc; 803 } 804 805 /* Check only if SMB2_OP_QUERY_WSL_EA command failed in the compound chain */ 806 static bool ea_unsupported(int *cmds, int num_cmds, 807 struct kvec *out_iov, int *out_buftype) 808 { 809 int i; 810 811 if (cmds[num_cmds - 1] != SMB2_OP_QUERY_WSL_EA) 812 return false; 813 814 for (i = 1; i < num_cmds - 1; i++) { 815 struct smb2_hdr *hdr = out_iov[i].iov_base; 816 817 if (out_buftype[i] == CIFS_NO_BUFFER || !hdr || 818 hdr->Status != STATUS_SUCCESS) 819 return false; 820 } 821 return true; 822 } 823 824 static inline void free_rsp_iov(struct kvec *iovs, int *buftype, int count) 825 { 826 int i; 827 828 for (i = 0; i < count; i++) { 829 free_rsp_buf(buftype[i], iovs[i].iov_base); 830 memset(&iovs[i], 0, sizeof(*iovs)); 831 buftype[i] = CIFS_NO_BUFFER; 832 } 833 } 834 835 int smb2_query_path_info(const unsigned int xid, 836 struct cifs_tcon *tcon, 837 struct cifs_sb_info *cifs_sb, 838 const char *full_path, 839 struct cifs_open_info_data *data) 840 { 841 struct kvec in_iov[3], out_iov[5] = {}; 842 struct cached_fid *cfid = NULL; 843 struct cifs_open_parms oparms; 844 struct cifsFileInfo *cfile; 845 __u32 create_options = 0; 846 int out_buftype[5] = {}; 847 struct smb2_hdr *hdr; 848 int num_cmds = 0; 849 int cmds[3]; 850 bool islink; 851 int rc, rc2; 852 853 data->adjust_tz = false; 854 data->reparse_point = false; 855 856 /* 857 * BB TODO: Add support for using cached root handle in SMB3.1.1 POSIX. 858 * Create SMB2_query_posix_info worker function to do non-compounded 859 * query when we already have an open file handle for this. For now this 860 * is fast enough (always using the compounded version). 861 */ 862 if (!tcon->posix_extensions) { 863 if (*full_path) { 864 rc = -ENOENT; 865 } else { 866 rc = open_cached_dir(xid, tcon, full_path, 867 cifs_sb, false, &cfid); 868 } 869 /* If it is a root and its handle is cached then use it */ 870 if (!rc) { 871 if (cfid->file_all_info_is_valid) { 872 memcpy(&data->fi, &cfid->file_all_info, 873 sizeof(data->fi)); 874 } else { 875 rc = SMB2_query_info(xid, tcon, 876 cfid->fid.persistent_fid, 877 cfid->fid.volatile_fid, 878 &data->fi); 879 } 880 close_cached_dir(cfid); 881 return rc; 882 } 883 cmds[num_cmds++] = SMB2_OP_QUERY_INFO; 884 } else { 885 cmds[num_cmds++] = SMB2_OP_POSIX_QUERY_INFO; 886 } 887 888 in_iov[0].iov_base = data; 889 in_iov[0].iov_len = sizeof(*data); 890 in_iov[1] = in_iov[0]; 891 in_iov[2] = in_iov[0]; 892 893 cifs_get_readable_path(tcon, full_path, &cfile); 894 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_READ_ATTRIBUTES, 895 FILE_OPEN, create_options, ACL_NO_MODE); 896 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, 897 &oparms, in_iov, cmds, num_cmds, 898 cfile, out_iov, out_buftype, NULL); 899 hdr = out_iov[0].iov_base; 900 /* 901 * If first iov is unset, then SMB session was dropped or we've got a 902 * cached open file (@cfile). 903 */ 904 if (!hdr || out_buftype[0] == CIFS_NO_BUFFER) 905 goto out; 906 907 switch (rc) { 908 case 0: 909 rc = parse_create_response(data, cifs_sb, full_path, &out_iov[0]); 910 break; 911 case -EACCES: 912 /* 913 * If SMB2_OP_QUERY_INFO (called when POSIX extensions are not used) failed with 914 * STATUS_ACCESS_DENIED then it means that caller does not have permission to 915 * open the path with FILE_READ_ATTRIBUTES access and therefore cannot issue 916 * SMB2_OP_QUERY_INFO command. 917 * 918 * There is an alternative way how to query limited information about path but still 919 * suitable for stat() syscall. SMB2 OPEN/CREATE operation returns in its successful 920 * response subset of query information. 921 * 922 * So try to open the path without FILE_READ_ATTRIBUTES but with MAXIMUM_ALLOWED 923 * access which will grant the maximum possible access to the file and the response 924 * will contain required query information for stat() syscall. 925 */ 926 927 if (tcon->posix_extensions) 928 break; 929 930 num_cmds = 1; 931 cmds[0] = SMB2_OP_OPEN_QUERY; 932 in_iov[0].iov_base = data; 933 in_iov[0].iov_len = sizeof(*data); 934 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, MAXIMUM_ALLOWED, 935 FILE_OPEN, create_options, ACL_NO_MODE); 936 free_rsp_iov(out_iov, out_buftype, ARRAY_SIZE(out_iov)); 937 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, 938 &oparms, in_iov, cmds, num_cmds, 939 cfile, out_iov, out_buftype, NULL); 940 941 hdr = out_iov[0].iov_base; 942 if (!hdr || out_buftype[0] == CIFS_NO_BUFFER) 943 goto out; 944 945 if (!rc) 946 rc = parse_create_response(data, cifs_sb, full_path, &out_iov[0]); 947 break; 948 case -EOPNOTSUPP: 949 /* 950 * BB TODO: When support for special files added to Samba 951 * re-verify this path. 952 */ 953 rc = parse_create_response(data, cifs_sb, full_path, &out_iov[0]); 954 if (rc || !data->reparse_point) 955 goto out; 956 957 /* 958 * Skip SMB2_OP_GET_REPARSE if symlink already parsed in create 959 * response. 960 */ 961 if (data->reparse.tag != IO_REPARSE_TAG_SYMLINK) { 962 cmds[num_cmds++] = SMB2_OP_GET_REPARSE; 963 if (!tcon->posix_extensions) 964 cmds[num_cmds++] = SMB2_OP_QUERY_WSL_EA; 965 } 966 967 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, 968 FILE_READ_ATTRIBUTES | 969 FILE_READ_EA | SYNCHRONIZE, 970 FILE_OPEN, create_options | 971 OPEN_REPARSE_POINT, ACL_NO_MODE); 972 cifs_get_readable_path(tcon, full_path, &cfile); 973 free_rsp_iov(out_iov, out_buftype, ARRAY_SIZE(out_iov)); 974 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, 975 &oparms, in_iov, cmds, num_cmds, 976 cfile, out_iov, out_buftype, NULL); 977 if (rc && ea_unsupported(cmds, num_cmds, 978 out_iov, out_buftype)) { 979 if (data->reparse.tag != IO_REPARSE_TAG_LX_BLK && 980 data->reparse.tag != IO_REPARSE_TAG_LX_CHR) 981 rc = 0; 982 else 983 rc = -EOPNOTSUPP; 984 } 985 986 if (data->reparse.tag == IO_REPARSE_TAG_SYMLINK && !rc) { 987 bool directory = le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY; 988 rc = smb2_fix_symlink_target_type(&data->symlink_target, directory, cifs_sb); 989 } 990 break; 991 case -EREMOTE: 992 break; 993 default: 994 if (hdr->Status != STATUS_OBJECT_NAME_INVALID) 995 break; 996 rc2 = cifs_inval_name_dfs_link_error(xid, tcon, cifs_sb, 997 full_path, &islink); 998 if (rc2) { 999 rc = rc2; 1000 goto out; 1001 } 1002 if (islink) 1003 rc = -EREMOTE; 1004 } 1005 1006 out: 1007 free_rsp_iov(out_iov, out_buftype, ARRAY_SIZE(out_iov)); 1008 return rc; 1009 } 1010 1011 int 1012 smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode, 1013 struct cifs_tcon *tcon, const char *name, 1014 struct cifs_sb_info *cifs_sb) 1015 { 1016 struct cifs_open_parms oparms; 1017 1018 oparms = CIFS_OPARMS(cifs_sb, tcon, name, FILE_WRITE_ATTRIBUTES, 1019 FILE_CREATE, CREATE_NOT_FILE, mode); 1020 return smb2_compound_op(xid, tcon, cifs_sb, 1021 name, &oparms, NULL, 1022 &(int){SMB2_OP_MKDIR}, 1, 1023 NULL, NULL, NULL, NULL); 1024 } 1025 1026 void 1027 smb2_mkdir_setinfo(struct inode *inode, const char *name, 1028 struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, 1029 const unsigned int xid) 1030 { 1031 struct cifs_open_parms oparms; 1032 FILE_BASIC_INFO data = {}; 1033 struct cifsInodeInfo *cifs_i; 1034 struct cifsFileInfo *cfile; 1035 struct kvec in_iov; 1036 u32 dosattrs; 1037 int tmprc; 1038 1039 in_iov.iov_base = &data; 1040 in_iov.iov_len = sizeof(data); 1041 cifs_i = CIFS_I(inode); 1042 dosattrs = cifs_i->cifsAttrs | ATTR_READONLY; 1043 data.Attributes = cpu_to_le32(dosattrs); 1044 cifs_get_writable_path(tcon, name, inode, FIND_ANY, &cfile); 1045 oparms = CIFS_OPARMS(cifs_sb, tcon, name, FILE_WRITE_ATTRIBUTES, 1046 FILE_CREATE, CREATE_NOT_FILE, ACL_NO_MODE); 1047 tmprc = smb2_compound_op(xid, tcon, cifs_sb, name, 1048 &oparms, &in_iov, 1049 &(int){SMB2_OP_SET_INFO}, 1, 1050 cfile, NULL, NULL, NULL); 1051 if (tmprc == 0) 1052 cifs_i->cifsAttrs = dosattrs; 1053 } 1054 1055 int 1056 smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, 1057 struct cifs_sb_info *cifs_sb) 1058 { 1059 struct cifs_open_parms oparms; 1060 1061 drop_cached_dir_by_name(xid, tcon, name, cifs_sb); 1062 oparms = CIFS_OPARMS(cifs_sb, tcon, name, DELETE, 1063 FILE_OPEN, CREATE_NOT_FILE, ACL_NO_MODE); 1064 return smb2_compound_op(xid, tcon, cifs_sb, 1065 name, &oparms, NULL, 1066 &(int){SMB2_OP_UNLINK}, 1, 1067 NULL, NULL, NULL, NULL); 1068 } 1069 1070 int 1071 smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, 1072 struct cifs_sb_info *cifs_sb, struct dentry *dentry) 1073 { 1074 struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; 1075 __le16 *utf16_path __free(kfree) = NULL; 1076 int retries = 0, cur_sleep = 0; 1077 struct TCP_Server_Info *server; 1078 struct cifs_open_parms oparms; 1079 struct smb2_create_req *creq; 1080 struct inode *inode = NULL; 1081 struct smb_rqst rqst[2]; 1082 struct kvec rsp_iov[2]; 1083 struct kvec close_iov; 1084 int resp_buftype[2]; 1085 struct cifs_fid fid; 1086 int flags = 0; 1087 __u8 oplock; 1088 int rc; 1089 1090 utf16_path = cifs_convert_path_to_utf16(name, cifs_sb); 1091 if (!utf16_path) 1092 return -ENOMEM; 1093 1094 if (smb3_encryption_required(tcon)) 1095 flags |= CIFS_TRANSFORM_REQ; 1096 again: 1097 oplock = SMB2_OPLOCK_LEVEL_NONE; 1098 server = cifs_pick_channel(tcon->ses); 1099 1100 memset(rqst, 0, sizeof(rqst)); 1101 memset(resp_buftype, 0, sizeof(resp_buftype)); 1102 memset(rsp_iov, 0, sizeof(rsp_iov)); 1103 1104 memset(open_iov, 0, sizeof(open_iov)); 1105 rqst[0].rq_iov = open_iov; 1106 rqst[0].rq_nvec = ARRAY_SIZE(open_iov); 1107 1108 oparms = CIFS_OPARMS(cifs_sb, tcon, name, DELETE | FILE_READ_ATTRIBUTES, 1109 FILE_OPEN, CREATE_DELETE_ON_CLOSE | 1110 OPEN_REPARSE_POINT, ACL_NO_MODE); 1111 oparms.fid = &fid; 1112 1113 if (dentry) { 1114 inode = d_inode(dentry); 1115 if (CIFS_I(inode)->lease_granted && server->ops->get_lease_key) { 1116 oplock = SMB2_OPLOCK_LEVEL_LEASE; 1117 server->ops->get_lease_key(inode, &fid); 1118 } 1119 } 1120 1121 rc = SMB2_open_init(tcon, server, 1122 &rqst[0], &oplock, &oparms, utf16_path); 1123 if (rc) 1124 goto err_free; 1125 smb2_set_next_command(tcon, &rqst[0]); 1126 creq = rqst[0].rq_iov[0].iov_base; 1127 creq->ShareAccess = FILE_SHARE_DELETE_LE; 1128 1129 memset(&close_iov, 0, sizeof(close_iov)); 1130 rqst[1].rq_iov = &close_iov; 1131 rqst[1].rq_nvec = 1; 1132 1133 rc = SMB2_close_init(tcon, server, &rqst[1], 1134 COMPOUND_FID, COMPOUND_FID, false); 1135 if (rc) 1136 goto err_free; 1137 smb2_set_related(&rqst[1]); 1138 1139 if (retries) { 1140 /* Back-off before retry */ 1141 if (cur_sleep) 1142 msleep(cur_sleep); 1143 for (int i = 0; i < ARRAY_SIZE(rqst); i++) 1144 smb2_set_replay(server, &rqst[i]); 1145 } 1146 1147 rc = compound_send_recv(xid, tcon->ses, server, flags, 1148 ARRAY_SIZE(rqst), rqst, 1149 resp_buftype, rsp_iov); 1150 SMB2_open_free(&rqst[0]); 1151 SMB2_close_free(&rqst[1]); 1152 free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); 1153 free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); 1154 1155 if (is_replayable_error(rc) && 1156 smb2_should_replay(tcon, &retries, &cur_sleep)) 1157 goto again; 1158 1159 /* Retry compound request without lease */ 1160 if (rc == -EINVAL && dentry) { 1161 dentry = NULL; 1162 retries = 0; 1163 cur_sleep = 0; 1164 goto again; 1165 } 1166 /* 1167 * If dentry (hence, inode) is NULL, lease break is going to 1168 * take care of degrading leases on handles for deleted files. 1169 */ 1170 if (!rc && inode) 1171 cifs_mark_open_handles_for_deleted_file(inode, name); 1172 1173 return rc; 1174 1175 err_free: 1176 SMB2_open_free(&rqst[0]); 1177 SMB2_close_free(&rqst[1]); 1178 free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); 1179 free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); 1180 return rc; 1181 } 1182 1183 static int smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, 1184 const char *from_name, const char *to_name, 1185 struct cifs_sb_info *cifs_sb, 1186 __u32 create_options, __u32 access, 1187 int command, struct cifsFileInfo *cfile, 1188 struct dentry *dentry) 1189 { 1190 struct cifs_open_parms oparms; 1191 struct kvec in_iov; 1192 __le16 *smb2_to_name = NULL; 1193 int rc; 1194 1195 smb2_to_name = cifs_convert_path_to_utf16(to_name, cifs_sb); 1196 if (smb2_to_name == NULL) { 1197 rc = -ENOMEM; 1198 if (cfile) 1199 cifsFileInfo_put(cfile); 1200 goto smb2_rename_path; 1201 } 1202 in_iov.iov_base = smb2_to_name; 1203 in_iov.iov_len = 2 * UniStrnlen((wchar_t *)smb2_to_name, PATH_MAX); 1204 oparms = CIFS_OPARMS(cifs_sb, tcon, from_name, access, FILE_OPEN, 1205 create_options, ACL_NO_MODE); 1206 rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, 1207 &oparms, &in_iov, &command, 1, 1208 cfile, NULL, NULL, dentry); 1209 smb2_rename_path: 1210 kfree(smb2_to_name); 1211 return rc; 1212 } 1213 1214 int smb2_rename_path(const unsigned int xid, 1215 struct cifs_tcon *tcon, 1216 struct dentry *source_dentry, 1217 const char *from_name, const char *to_name, 1218 struct cifs_sb_info *cifs_sb) 1219 { 1220 struct inode *inode = source_dentry ? d_inode(source_dentry) : NULL; 1221 struct cifsFileInfo *cfile; 1222 __u32 co = file_create_options(source_dentry); 1223 1224 drop_cached_dir_by_name(xid, tcon, from_name, cifs_sb); 1225 cifs_get_writable_path(tcon, from_name, inode, 1226 FIND_WITH_DELETE, &cfile); 1227 1228 int rc = smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, 1229 co, DELETE, SMB2_OP_RENAME, cfile, source_dentry); 1230 if (rc == -EINVAL) { 1231 cifs_dbg(FYI, "invalid lease key, resending request without lease"); 1232 cifs_get_writable_path(tcon, from_name, inode, 1233 FIND_WITH_DELETE, &cfile); 1234 rc = smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, 1235 co, DELETE, SMB2_OP_RENAME, cfile, NULL); 1236 } 1237 return rc; 1238 } 1239 1240 static int clear_tmpfile_attr(const unsigned int xid, struct cifs_tcon *tcon, 1241 struct inode *inode, const char *full_path) 1242 { 1243 struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses); 1244 struct cifsInodeInfo *cinode = CIFS_I(inode); 1245 FILE_BASIC_INFO fi; 1246 1247 cinode->cifsAttrs &= ~(ATTR_TEMPORARY | ATTR_HIDDEN); 1248 fi = (FILE_BASIC_INFO) { 1249 .Attributes = cpu_to_le32(cinode->cifsAttrs), 1250 }; 1251 return server->ops->set_file_info(inode, full_path, &fi, xid); 1252 } 1253 1254 int smb2_create_hardlink(const unsigned int xid, 1255 struct cifs_tcon *tcon, 1256 struct dentry *source_dentry, 1257 const char *from_name, const char *to_name, 1258 struct cifs_sb_info *cifs_sb) 1259 { 1260 struct inode *inode = source_dentry ? d_inode(source_dentry) : NULL; 1261 __u32 co = file_create_options(source_dentry); 1262 struct cifsFileInfo *cfile; 1263 int rc; 1264 1265 if (inode && test_bit(CIFS_INO_TMPFILE, &CIFS_I(inode)->flags)) { 1266 rc = clear_tmpfile_attr(xid, tcon, inode, from_name); 1267 if (rc) 1268 return rc; 1269 } 1270 1271 cifs_get_writable_path(tcon, from_name, inode, 1272 FIND_WITH_DELETE, &cfile); 1273 return smb2_set_path_attr(xid, tcon, from_name, to_name, 1274 cifs_sb, co, FILE_READ_ATTRIBUTES, 1275 SMB2_OP_HARDLINK, cfile, NULL); 1276 } 1277 1278 int 1279 smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, 1280 const char *full_path, __u64 size, 1281 struct cifs_sb_info *cifs_sb, bool set_alloc, 1282 struct dentry *dentry) 1283 { 1284 struct inode *inode = dentry ? d_inode(dentry) : NULL; 1285 __le64 eof = cpu_to_le64(size); 1286 struct cifs_open_parms oparms; 1287 struct cifsFileInfo *cfile; 1288 struct kvec in_iov; 1289 int rc; 1290 1291 in_iov.iov_base = &eof; 1292 in_iov.iov_len = sizeof(eof); 1293 cifs_get_writable_path(tcon, full_path, inode, FIND_ANY, &cfile); 1294 1295 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_WRITE_DATA, 1296 FILE_OPEN, 0, ACL_NO_MODE); 1297 rc = smb2_compound_op(xid, tcon, cifs_sb, 1298 full_path, &oparms, &in_iov, 1299 &(int){SMB2_OP_SET_EOF}, 1, 1300 cfile, NULL, NULL, dentry); 1301 if (rc == -EINVAL) { 1302 cifs_dbg(FYI, "invalid lease key, resending request without lease"); 1303 cifs_get_writable_path(tcon, full_path, 1304 inode, FIND_ANY, &cfile); 1305 rc = smb2_compound_op(xid, tcon, cifs_sb, 1306 full_path, &oparms, &in_iov, 1307 &(int){SMB2_OP_SET_EOF}, 1, 1308 cfile, NULL, NULL, NULL); 1309 } 1310 return rc; 1311 } 1312 1313 int 1314 smb2_set_file_info(struct inode *inode, const char *full_path, 1315 FILE_BASIC_INFO *buf, const unsigned int xid) 1316 { 1317 struct kvec in_iov = { .iov_base = buf, .iov_len = sizeof(*buf), }; 1318 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1319 struct cifsFileInfo *cfile = NULL; 1320 struct cifs_open_parms oparms; 1321 struct tcon_link *tlink; 1322 struct cifs_tcon *tcon; 1323 int rc = 0; 1324 1325 tlink = cifs_sb_tlink(cifs_sb); 1326 if (IS_ERR(tlink)) 1327 return PTR_ERR(tlink); 1328 tcon = tlink_tcon(tlink); 1329 1330 if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) && 1331 (buf->LastWriteTime == 0) && (buf->ChangeTime == 0)) { 1332 if (buf->Attributes == 0) 1333 goto out; /* would be a no op, no sense sending this */ 1334 cifs_get_writable_path(tcon, full_path, 1335 inode, FIND_ANY, &cfile); 1336 } 1337 1338 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_WRITE_ATTRIBUTES, 1339 FILE_OPEN, 0, ACL_NO_MODE); 1340 rc = smb2_compound_op(xid, tcon, cifs_sb, 1341 full_path, &oparms, &in_iov, 1342 &(int){SMB2_OP_SET_INFO}, 1, 1343 cfile, NULL, NULL, NULL); 1344 out: 1345 cifs_put_tlink(tlink); 1346 return rc; 1347 } 1348 1349 struct inode *smb2_create_reparse_inode(struct cifs_open_info_data *data, 1350 struct super_block *sb, 1351 const unsigned int xid, 1352 struct cifs_tcon *tcon, 1353 const char *full_path, 1354 bool directory, 1355 struct kvec *reparse_iov, 1356 struct kvec *xattr_iov) 1357 { 1358 struct cifs_open_parms oparms; 1359 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 1360 struct cifsFileInfo *cfile; 1361 struct inode *new = NULL; 1362 int out_buftype[4] = {}; 1363 struct kvec out_iov[4] = {}; 1364 struct kvec in_iov[2]; 1365 int cmds[2]; 1366 int rc; 1367 int i; 1368 1369 /* 1370 * If server filesystem does not support reparse points then do not 1371 * attempt to create reparse point. This will prevent creating unusable 1372 * empty object on the server. 1373 */ 1374 if (!CIFS_REPARSE_SUPPORT(tcon)) 1375 return ERR_PTR(-EOPNOTSUPP); 1376 1377 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, 1378 SYNCHRONIZE | DELETE | 1379 FILE_READ_ATTRIBUTES | 1380 FILE_WRITE_ATTRIBUTES, 1381 FILE_CREATE, 1382 (directory ? CREATE_NOT_FILE : CREATE_NOT_DIR) | OPEN_REPARSE_POINT, 1383 ACL_NO_MODE); 1384 if (xattr_iov) 1385 oparms.ea_cctx = xattr_iov; 1386 1387 cmds[0] = SMB2_OP_SET_REPARSE; 1388 in_iov[0] = *reparse_iov; 1389 in_iov[1].iov_base = data; 1390 in_iov[1].iov_len = sizeof(*data); 1391 1392 if (tcon->posix_extensions) { 1393 cmds[1] = SMB2_OP_POSIX_QUERY_INFO; 1394 cifs_get_writable_path(tcon, full_path, NULL, FIND_ANY, &cfile); 1395 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, 1396 in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL); 1397 if (!rc) { 1398 rc = smb311_posix_get_inode_info(&new, full_path, 1399 data, sb, xid); 1400 } 1401 } else { 1402 cmds[1] = SMB2_OP_QUERY_INFO; 1403 cifs_get_writable_path(tcon, full_path, NULL, FIND_ANY, &cfile); 1404 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, 1405 in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL); 1406 if (!rc) { 1407 rc = cifs_get_inode_info(&new, full_path, 1408 data, sb, xid, NULL); 1409 } 1410 } 1411 1412 1413 /* 1414 * If CREATE was successful but SMB2_OP_SET_REPARSE failed then 1415 * remove the intermediate object created by CREATE. Otherwise 1416 * empty object stay on the server when reparse call failed. 1417 */ 1418 if (rc && 1419 out_iov[0].iov_base != NULL && out_buftype[0] != CIFS_NO_BUFFER && 1420 ((struct smb2_hdr *)out_iov[0].iov_base)->Status == STATUS_SUCCESS && 1421 (out_iov[1].iov_base == NULL || out_buftype[1] == CIFS_NO_BUFFER || 1422 ((struct smb2_hdr *)out_iov[1].iov_base)->Status != STATUS_SUCCESS)) 1423 smb2_unlink(xid, tcon, full_path, cifs_sb, NULL); 1424 1425 for (i = 0; i < ARRAY_SIZE(out_buftype); i++) 1426 free_rsp_buf(out_buftype[i], out_iov[i].iov_base); 1427 1428 return rc ? ERR_PTR(rc) : new; 1429 } 1430 1431 int smb2_query_reparse_point(const unsigned int xid, 1432 struct cifs_tcon *tcon, 1433 struct cifs_sb_info *cifs_sb, 1434 const char *full_path, 1435 u32 *tag, struct kvec *rsp, 1436 int *rsp_buftype) 1437 { 1438 struct cifs_open_parms oparms; 1439 struct cifs_open_info_data data = {}; 1440 struct cifsFileInfo *cfile; 1441 struct kvec in_iov = { .iov_base = &data, .iov_len = sizeof(data), }; 1442 int rc; 1443 1444 cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); 1445 1446 cifs_get_readable_path(tcon, full_path, &cfile); 1447 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, 1448 FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE, 1449 FILE_OPEN, OPEN_REPARSE_POINT, ACL_NO_MODE); 1450 rc = smb2_compound_op(xid, tcon, cifs_sb, 1451 full_path, &oparms, &in_iov, 1452 &(int){SMB2_OP_GET_REPARSE}, 1, 1453 cfile, NULL, NULL, NULL); 1454 if (rc) 1455 goto out; 1456 1457 *tag = data.reparse.tag; 1458 *rsp = data.reparse.io.iov; 1459 *rsp_buftype = data.reparse.io.buftype; 1460 memset(&data.reparse.io.iov, 0, sizeof(data.reparse.io.iov)); 1461 data.reparse.io.buftype = CIFS_NO_BUFFER; 1462 out: 1463 cifs_free_open_info(&data); 1464 return rc; 1465 } 1466 1467 static inline __le16 *utf16_smb2_path(struct cifs_sb_info *cifs_sb, 1468 const char *name, size_t namelen) 1469 { 1470 int len; 1471 1472 if (*name == '\\' || 1473 (cifs_sb_master_tlink(cifs_sb) && 1474 cifs_sb_master_tcon(cifs_sb)->posix_extensions && *name == '/')) 1475 name++; 1476 return cifs_strndup_to_utf16(name, namelen, &len, 1477 cifs_sb->local_nls, 1478 cifs_remap(cifs_sb)); 1479 } 1480 1481 int smb2_rename_pending_delete(const char *full_path, 1482 struct dentry *dentry, 1483 const unsigned int xid) 1484 { 1485 struct cifsInodeInfo *cinode = CIFS_I(d_inode(dentry)); 1486 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry); 1487 __le16 *utf16_path __free(kfree) = NULL; 1488 __u32 co = file_create_options(dentry); 1489 int cmds[] = { 1490 SMB2_OP_SET_INFO, 1491 SMB2_OP_RENAME, 1492 SMB2_OP_UNLINK, 1493 }; 1494 const int num_cmds = ARRAY_SIZE(cmds); 1495 char *to_name __free(kfree) = NULL; 1496 __u32 attrs = cinode->cifsAttrs; 1497 struct cifs_open_parms oparms; 1498 struct cifsFileInfo *cfile; 1499 struct tcon_link *tlink; 1500 struct cifs_tcon *tcon; 1501 struct kvec iov[2]; 1502 int rc; 1503 1504 tlink = cifs_sb_tlink(cifs_sb); 1505 if (IS_ERR(tlink)) 1506 return PTR_ERR(tlink); 1507 tcon = tlink_tcon(tlink); 1508 1509 to_name = cifs_silly_fullpath(dentry); 1510 if (IS_ERR(to_name)) { 1511 rc = PTR_ERR(to_name); 1512 to_name = NULL; 1513 goto out; 1514 } 1515 1516 utf16_path = utf16_smb2_path(cifs_sb, to_name, strlen(to_name)); 1517 if (!utf16_path) { 1518 rc = -ENOMEM; 1519 goto out; 1520 } 1521 1522 drop_cached_dir_by_name(xid, tcon, full_path, cifs_sb); 1523 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, 1524 DELETE | FILE_WRITE_ATTRIBUTES, 1525 FILE_OPEN, co, ACL_NO_MODE); 1526 1527 attrs &= ~ATTR_READONLY; 1528 if (!attrs) 1529 attrs = ATTR_NORMAL; 1530 if (d_inode(dentry)->i_nlink <= 1) 1531 attrs |= ATTR_HIDDEN; 1532 iov[0].iov_base = &(FILE_BASIC_INFO) { 1533 .Attributes = cpu_to_le32(attrs), 1534 }; 1535 iov[0].iov_len = sizeof(FILE_BASIC_INFO); 1536 iov[1].iov_base = utf16_path; 1537 iov[1].iov_len = sizeof(*utf16_path) * UniStrlen((wchar_t *)utf16_path); 1538 1539 cifs_get_writable_path(tcon, full_path, d_inode(dentry), 1540 FIND_WITH_DELETE, &cfile); 1541 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, iov, 1542 cmds, num_cmds, cfile, NULL, NULL, dentry); 1543 if (rc == -EINVAL) { 1544 cifs_dbg(FYI, "invalid lease key, resending request without lease\n"); 1545 cifs_get_writable_path(tcon, full_path, d_inode(dentry), 1546 FIND_WITH_DELETE, &cfile); 1547 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, iov, 1548 cmds, num_cmds, cfile, NULL, NULL, NULL); 1549 } 1550 if (!rc) { 1551 set_bit(CIFS_INO_DELETE_PENDING, &cinode->flags); 1552 } else { 1553 cifs_tcon_dbg(FYI, "%s: failed to rename '%s' to '%s': %d\n", 1554 __func__, full_path, to_name, rc); 1555 rc = smb_EIO1(smb_eio_trace_pend_del_fail, rc); 1556 } 1557 out: 1558 cifs_put_tlink(tlink); 1559 return rc; 1560 } 1561