1 // SPDX-License-Identifier: LGPL-2.1 2 /* 3 * 4 * Copyright (C) International Business Machines Corp., 2002,2010 5 * Author(s): Steve French (sfrench@us.ibm.com) 6 * 7 * Contains the routines for constructing the SMB PDUs themselves 8 * 9 */ 10 11 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */ 12 /* These are mostly routines that operate on a pathname, or on a tree id */ 13 /* (mounted volume), but there are eight handle based routines which must be */ 14 /* treated slightly differently for reconnection purposes since we never */ 15 /* want to reuse a stale file handle and only the caller knows the file info */ 16 17 #include <linux/fs.h> 18 #include <linux/filelock.h> 19 #include <linux/kernel.h> 20 #include <linux/vfs.h> 21 #include <linux/slab.h> 22 #include <linux/posix_acl_xattr.h> 23 #include <linux/pagemap.h> 24 #include <linux/swap.h> 25 #include <linux/task_io_accounting_ops.h> 26 #include <linux/uaccess.h> 27 #include <linux/netfs.h> 28 #include <trace/events/netfs.h> 29 #include "cifspdu.h" 30 #include "cifsfs.h" 31 #include "cifsglob.h" 32 #include "cifsacl.h" 33 #include "cifsproto.h" 34 #include "cifs_unicode.h" 35 #include "cifs_debug.h" 36 #include "fscache.h" 37 #include "smbdirect.h" 38 #ifdef CONFIG_CIFS_DFS_UPCALL 39 #include "dfs_cache.h" 40 #endif 41 42 #ifdef CONFIG_CIFS_POSIX 43 static struct { 44 int index; 45 char *name; 46 } protocols[] = { 47 {CIFS_PROT, "\2NT LM 0.12"}, 48 {POSIX_PROT, "\2POSIX 2"}, 49 {BAD_PROT, "\2"} 50 }; 51 #else 52 static struct { 53 int index; 54 char *name; 55 } protocols[] = { 56 {CIFS_PROT, "\2NT LM 0.12"}, 57 {BAD_PROT, "\2"} 58 }; 59 #endif 60 61 /* define the number of elements in the cifs dialect array */ 62 #ifdef CONFIG_CIFS_POSIX 63 #define CIFS_NUM_PROT 2 64 #else /* not posix */ 65 #define CIFS_NUM_PROT 1 66 #endif /* CIFS_POSIX */ 67 68 69 /* reconnect the socket, tcon, and smb session if needed */ 70 static int 71 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) 72 { 73 struct TCP_Server_Info *server; 74 struct cifs_ses *ses; 75 int rc; 76 77 /* 78 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for 79 * tcp and smb session status done differently for those three - in the 80 * calling routine 81 */ 82 if (!tcon) 83 return 0; 84 85 ses = tcon->ses; 86 server = ses->server; 87 88 /* 89 * only tree disconnect, open, and write, (and ulogoff which does not 90 * have tcon) are allowed as we start umount 91 */ 92 spin_lock(&tcon->tc_lock); 93 if (tcon->status == TID_EXITING) { 94 if (smb_command != SMB_COM_TREE_DISCONNECT) { 95 spin_unlock(&tcon->tc_lock); 96 cifs_dbg(FYI, "can not send cmd %d while umounting\n", 97 smb_command); 98 return -ENODEV; 99 } 100 } 101 spin_unlock(&tcon->tc_lock); 102 103 again: 104 rc = cifs_wait_for_server_reconnect(server, tcon->retry); 105 if (rc) 106 return rc; 107 108 spin_lock(&ses->chan_lock); 109 if (!cifs_chan_needs_reconnect(ses, server) && !tcon->need_reconnect) { 110 spin_unlock(&ses->chan_lock); 111 return 0; 112 } 113 spin_unlock(&ses->chan_lock); 114 115 mutex_lock(&ses->session_mutex); 116 /* 117 * Handle the case where a concurrent thread failed to negotiate or 118 * killed a channel. 119 */ 120 spin_lock(&server->srv_lock); 121 switch (server->tcpStatus) { 122 case CifsExiting: 123 spin_unlock(&server->srv_lock); 124 mutex_unlock(&ses->session_mutex); 125 return -EHOSTDOWN; 126 case CifsNeedReconnect: 127 spin_unlock(&server->srv_lock); 128 mutex_unlock(&ses->session_mutex); 129 if (!tcon->retry) 130 return -EHOSTDOWN; 131 goto again; 132 default: 133 break; 134 } 135 spin_unlock(&server->srv_lock); 136 137 /* 138 * need to prevent multiple threads trying to simultaneously 139 * reconnect the same SMB session 140 */ 141 spin_lock(&ses->ses_lock); 142 spin_lock(&ses->chan_lock); 143 if (!cifs_chan_needs_reconnect(ses, server) && 144 ses->ses_status == SES_GOOD) { 145 spin_unlock(&ses->chan_lock); 146 spin_unlock(&ses->ses_lock); 147 148 /* this means that we only need to tree connect */ 149 if (tcon->need_reconnect) 150 goto skip_sess_setup; 151 152 mutex_unlock(&ses->session_mutex); 153 goto out; 154 } 155 spin_unlock(&ses->chan_lock); 156 spin_unlock(&ses->ses_lock); 157 158 rc = cifs_negotiate_protocol(0, ses, server); 159 if (rc) { 160 mutex_unlock(&ses->session_mutex); 161 if (!tcon->retry) 162 return -EHOSTDOWN; 163 goto again; 164 } 165 rc = cifs_setup_session(0, ses, server, ses->local_nls); 166 if ((rc == -EACCES) || (rc == -EHOSTDOWN) || (rc == -EKEYREVOKED)) { 167 /* 168 * Try alternate password for next reconnect if an alternate 169 * password is available. 170 */ 171 if (ses->password2) 172 swap(ses->password2, ses->password); 173 } 174 175 /* do we need to reconnect tcon? */ 176 if (rc || !tcon->need_reconnect) { 177 mutex_unlock(&ses->session_mutex); 178 goto out; 179 } 180 181 skip_sess_setup: 182 cifs_mark_open_files_invalid(tcon); 183 rc = cifs_tree_connect(0, tcon); 184 mutex_unlock(&ses->session_mutex); 185 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); 186 187 if (rc) { 188 pr_warn_once("reconnect tcon failed rc = %d\n", rc); 189 goto out; 190 } 191 192 atomic_inc(&tconInfoReconnectCount); 193 194 /* tell server Unix caps we support */ 195 if (cap_unix(ses)) 196 reset_cifs_unix_caps(0, tcon, NULL, NULL); 197 198 /* 199 * Removed call to reopen open files here. It is safer (and faster) to 200 * reopen files one at a time as needed in read and write. 201 * 202 * FIXME: what about file locks? don't we need to reclaim them ASAP? 203 */ 204 205 out: 206 /* 207 * Check if handle based operation so we know whether we can continue 208 * or not without returning to caller to reset file handle 209 */ 210 switch (smb_command) { 211 case SMB_COM_READ_ANDX: 212 case SMB_COM_WRITE_ANDX: 213 case SMB_COM_CLOSE: 214 case SMB_COM_FIND_CLOSE2: 215 case SMB_COM_LOCKING_ANDX: 216 rc = -EAGAIN; 217 } 218 219 return rc; 220 } 221 222 /* Allocate and return pointer to an SMB request buffer, and set basic 223 SMB information in the SMB header. If the return code is zero, this 224 function must have filled in request_buf pointer */ 225 static int 226 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon, 227 void **request_buf) 228 { 229 int rc; 230 231 rc = cifs_reconnect_tcon(tcon, smb_command); 232 if (rc) 233 return rc; 234 235 *request_buf = cifs_small_buf_get(); 236 if (*request_buf == NULL) { 237 /* BB should we add a retry in here if not a writepage? */ 238 return -ENOMEM; 239 } 240 241 header_assemble((struct smb_hdr *) *request_buf, smb_command, 242 tcon, wct); 243 244 if (tcon != NULL) 245 cifs_stats_inc(&tcon->num_smbs_sent); 246 247 return 0; 248 } 249 250 int 251 small_smb_init_no_tc(const int smb_command, const int wct, 252 struct cifs_ses *ses, void **request_buf) 253 { 254 int rc; 255 struct smb_hdr *buffer; 256 257 rc = small_smb_init(smb_command, wct, NULL, request_buf); 258 if (rc) 259 return rc; 260 261 buffer = (struct smb_hdr *)*request_buf; 262 buffer->Mid = get_next_mid(ses->server); 263 if (ses->capabilities & CAP_UNICODE) 264 buffer->Flags2 |= SMBFLG2_UNICODE; 265 if (ses->capabilities & CAP_STATUS32) 266 buffer->Flags2 |= SMBFLG2_ERR_STATUS; 267 268 /* uid, tid can stay at zero as set in header assemble */ 269 270 /* BB add support for turning on the signing when 271 this function is used after 1st of session setup requests */ 272 273 return rc; 274 } 275 276 /* If the return code is zero, this function must fill in request_buf pointer */ 277 static int 278 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon, 279 void **request_buf, void **response_buf) 280 { 281 *request_buf = cifs_buf_get(); 282 if (*request_buf == NULL) { 283 /* BB should we add a retry in here if not a writepage? */ 284 return -ENOMEM; 285 } 286 /* Although the original thought was we needed the response buf for */ 287 /* potential retries of smb operations it turns out we can determine */ 288 /* from the mid flags when the request buffer can be resent without */ 289 /* having to use a second distinct buffer for the response */ 290 if (response_buf) 291 *response_buf = *request_buf; 292 293 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, 294 wct); 295 296 if (tcon != NULL) 297 cifs_stats_inc(&tcon->num_smbs_sent); 298 299 return 0; 300 } 301 302 /* If the return code is zero, this function must fill in request_buf pointer */ 303 static int 304 smb_init(int smb_command, int wct, struct cifs_tcon *tcon, 305 void **request_buf, void **response_buf) 306 { 307 int rc; 308 309 rc = cifs_reconnect_tcon(tcon, smb_command); 310 if (rc) 311 return rc; 312 313 return __smb_init(smb_command, wct, tcon, request_buf, response_buf); 314 } 315 316 static int 317 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon, 318 void **request_buf, void **response_buf) 319 { 320 spin_lock(&tcon->ses->chan_lock); 321 if (cifs_chan_needs_reconnect(tcon->ses, tcon->ses->server) || 322 tcon->need_reconnect) { 323 spin_unlock(&tcon->ses->chan_lock); 324 return -EHOSTDOWN; 325 } 326 spin_unlock(&tcon->ses->chan_lock); 327 328 return __smb_init(smb_command, wct, tcon, request_buf, response_buf); 329 } 330 331 static int validate_t2(struct smb_t2_rsp *pSMB) 332 { 333 unsigned int total_size; 334 335 /* check for plausible wct */ 336 if (pSMB->hdr.WordCount < 10) 337 goto vt2_err; 338 339 /* check for parm and data offset going beyond end of smb */ 340 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 || 341 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024) 342 goto vt2_err; 343 344 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount); 345 if (total_size >= 512) 346 goto vt2_err; 347 348 /* check that bcc is at least as big as parms + data, and that it is 349 * less than negotiated smb buffer 350 */ 351 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount); 352 if (total_size > get_bcc(&pSMB->hdr) || 353 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) 354 goto vt2_err; 355 356 return 0; 357 vt2_err: 358 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB, 359 sizeof(struct smb_t2_rsp) + 16); 360 return -EINVAL; 361 } 362 363 static int 364 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr) 365 { 366 int rc = 0; 367 u16 count; 368 char *guid = pSMBr->u.extended_response.GUID; 369 struct TCP_Server_Info *server = ses->server; 370 371 count = get_bcc(&pSMBr->hdr); 372 if (count < SMB1_CLIENT_GUID_SIZE) 373 return -EIO; 374 375 spin_lock(&cifs_tcp_ses_lock); 376 if (server->srv_count > 1) { 377 spin_unlock(&cifs_tcp_ses_lock); 378 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) { 379 cifs_dbg(FYI, "server UID changed\n"); 380 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE); 381 } 382 } else { 383 spin_unlock(&cifs_tcp_ses_lock); 384 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE); 385 } 386 387 if (count == SMB1_CLIENT_GUID_SIZE) { 388 server->sec_ntlmssp = true; 389 } else { 390 count -= SMB1_CLIENT_GUID_SIZE; 391 rc = decode_negTokenInit( 392 pSMBr->u.extended_response.SecurityBlob, count, server); 393 if (rc != 1) 394 return -EINVAL; 395 } 396 397 return 0; 398 } 399 400 static bool 401 should_set_ext_sec_flag(enum securityEnum sectype) 402 { 403 switch (sectype) { 404 case RawNTLMSSP: 405 case Kerberos: 406 return true; 407 case Unspecified: 408 if (global_secflags & 409 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)) 410 return true; 411 fallthrough; 412 default: 413 return false; 414 } 415 } 416 417 int 418 CIFSSMBNegotiate(const unsigned int xid, 419 struct cifs_ses *ses, 420 struct TCP_Server_Info *server) 421 { 422 NEGOTIATE_REQ *pSMB; 423 NEGOTIATE_RSP *pSMBr; 424 int rc = 0; 425 int bytes_returned; 426 int i; 427 u16 count; 428 429 if (!server) { 430 WARN(1, "%s: server is NULL!\n", __func__); 431 return -EIO; 432 } 433 434 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ , 435 (void **) &pSMB, (void **) &pSMBr); 436 if (rc) 437 return rc; 438 439 pSMB->hdr.Mid = get_next_mid(server); 440 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; 441 442 if (ses->unicode != 0) 443 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 444 445 if (should_set_ext_sec_flag(ses->sectype)) { 446 cifs_dbg(FYI, "Requesting extended security\n"); 447 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 448 } 449 450 count = 0; 451 /* 452 * We know that all the name entries in the protocols array 453 * are short (< 16 bytes anyway) and are NUL terminated. 454 */ 455 for (i = 0; i < CIFS_NUM_PROT; i++) { 456 size_t len = strlen(protocols[i].name) + 1; 457 458 memcpy(&pSMB->DialectsArray[count], protocols[i].name, len); 459 count += len; 460 } 461 inc_rfc1001_len(pSMB, count); 462 pSMB->ByteCount = cpu_to_le16(count); 463 464 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 465 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 466 if (rc != 0) 467 goto neg_err_exit; 468 469 server->dialect = le16_to_cpu(pSMBr->DialectIndex); 470 cifs_dbg(FYI, "Dialect: %d\n", server->dialect); 471 /* Check wct = 1 error case */ 472 if ((pSMBr->hdr.WordCount <= 13) || (server->dialect == BAD_PROT)) { 473 /* core returns wct = 1, but we do not ask for core - otherwise 474 small wct just comes when dialect index is -1 indicating we 475 could not negotiate a common dialect */ 476 rc = -EOPNOTSUPP; 477 goto neg_err_exit; 478 } else if (pSMBr->hdr.WordCount != 17) { 479 /* unknown wct */ 480 rc = -EOPNOTSUPP; 481 goto neg_err_exit; 482 } 483 /* else wct == 17, NTLM or better */ 484 485 server->sec_mode = pSMBr->SecurityMode; 486 if ((server->sec_mode & SECMODE_USER) == 0) 487 cifs_dbg(FYI, "share mode security\n"); 488 489 /* one byte, so no need to convert this or EncryptionKeyLen from 490 little endian */ 491 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount), 492 cifs_max_pending); 493 set_credits(server, server->maxReq); 494 /* probably no need to store and check maxvcs */ 495 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize); 496 /* set up max_read for readahead check */ 497 server->max_read = server->maxBuf; 498 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize); 499 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf); 500 server->capabilities = le32_to_cpu(pSMBr->Capabilities); 501 server->session_key_id = pSMBr->SessionKey; 502 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); 503 server->timeAdj *= 60; 504 505 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 506 server->negflavor = CIFS_NEGFLAVOR_UNENCAP; 507 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, 508 CIFS_CRYPTO_KEY_SIZE); 509 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC || 510 server->capabilities & CAP_EXTENDED_SECURITY) { 511 server->negflavor = CIFS_NEGFLAVOR_EXTENDED; 512 rc = decode_ext_sec_blob(ses, pSMBr); 513 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) { 514 rc = -EIO; /* no crypt key only if plain text pwd */ 515 } else { 516 server->negflavor = CIFS_NEGFLAVOR_UNENCAP; 517 server->capabilities &= ~CAP_EXTENDED_SECURITY; 518 } 519 520 if (!rc) 521 rc = cifs_enable_signing(server, ses->sign); 522 neg_err_exit: 523 cifs_buf_release(pSMB); 524 525 cifs_dbg(FYI, "negprot rc %d\n", rc); 526 return rc; 527 } 528 529 int 530 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon) 531 { 532 struct smb_hdr *smb_buffer; 533 int rc = 0; 534 535 cifs_dbg(FYI, "In tree disconnect\n"); 536 537 /* BB: do we need to check this? These should never be NULL. */ 538 if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) 539 return -EIO; 540 541 /* 542 * No need to return error on this operation if tid invalidated and 543 * closed on server already e.g. due to tcp session crashing. Also, 544 * the tcon is no longer on the list, so no need to take lock before 545 * checking this. 546 */ 547 spin_lock(&tcon->ses->chan_lock); 548 if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) { 549 spin_unlock(&tcon->ses->chan_lock); 550 return -EIO; 551 } 552 spin_unlock(&tcon->ses->chan_lock); 553 554 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, 555 (void **)&smb_buffer); 556 if (rc) 557 return rc; 558 559 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0); 560 cifs_small_buf_release(smb_buffer); 561 if (rc) 562 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc); 563 564 /* No need to return error on this operation if tid invalidated and 565 closed on server already e.g. due to tcp session crashing */ 566 if (rc == -EAGAIN) 567 rc = 0; 568 569 return rc; 570 } 571 572 /* 573 * This is a no-op for now. We're not really interested in the reply, but 574 * rather in the fact that the server sent one and that server->lstrp 575 * gets updated. 576 * 577 * FIXME: maybe we should consider checking that the reply matches request? 578 */ 579 static void 580 cifs_echo_callback(struct mid_q_entry *mid) 581 { 582 struct TCP_Server_Info *server = mid->callback_data; 583 struct cifs_credits credits = { .value = 1, .instance = 0 }; 584 585 release_mid(mid); 586 add_credits(server, &credits, CIFS_ECHO_OP); 587 } 588 589 int 590 CIFSSMBEcho(struct TCP_Server_Info *server) 591 { 592 ECHO_REQ *smb; 593 int rc = 0; 594 struct kvec iov[2]; 595 struct smb_rqst rqst = { .rq_iov = iov, 596 .rq_nvec = 2 }; 597 598 cifs_dbg(FYI, "In echo request\n"); 599 600 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb); 601 if (rc) 602 return rc; 603 604 if (server->capabilities & CAP_UNICODE) 605 smb->hdr.Flags2 |= SMBFLG2_UNICODE; 606 607 /* set up echo request */ 608 smb->hdr.Tid = 0xffff; 609 smb->hdr.WordCount = 1; 610 put_unaligned_le16(1, &smb->EchoCount); 611 put_bcc(1, &smb->hdr); 612 smb->Data[0] = 'a'; 613 inc_rfc1001_len(smb, 3); 614 615 iov[0].iov_len = 4; 616 iov[0].iov_base = smb; 617 iov[1].iov_len = get_rfc1002_length(smb); 618 iov[1].iov_base = (char *)smb + 4; 619 620 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL, 621 server, CIFS_NON_BLOCKING | CIFS_ECHO_OP, NULL); 622 if (rc) 623 cifs_dbg(FYI, "Echo request failed: %d\n", rc); 624 625 cifs_small_buf_release(smb); 626 627 return rc; 628 } 629 630 int 631 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses) 632 { 633 LOGOFF_ANDX_REQ *pSMB; 634 int rc = 0; 635 636 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n"); 637 638 /* 639 * BB: do we need to check validity of ses and server? They should 640 * always be valid since we have an active reference. If not, that 641 * should probably be a BUG() 642 */ 643 if (!ses || !ses->server) 644 return -EIO; 645 646 mutex_lock(&ses->session_mutex); 647 spin_lock(&ses->chan_lock); 648 if (CIFS_ALL_CHANS_NEED_RECONNECT(ses)) { 649 spin_unlock(&ses->chan_lock); 650 goto session_already_dead; /* no need to send SMBlogoff if uid 651 already closed due to reconnect */ 652 } 653 spin_unlock(&ses->chan_lock); 654 655 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB); 656 if (rc) { 657 mutex_unlock(&ses->session_mutex); 658 return rc; 659 } 660 661 pSMB->hdr.Mid = get_next_mid(ses->server); 662 663 if (ses->server->sign) 664 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 665 666 pSMB->hdr.Uid = ses->Suid; 667 668 pSMB->AndXCommand = 0xFF; 669 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0); 670 cifs_small_buf_release(pSMB); 671 session_already_dead: 672 mutex_unlock(&ses->session_mutex); 673 674 /* if session dead then we do not need to do ulogoff, 675 since server closed smb session, no sense reporting 676 error */ 677 if (rc == -EAGAIN) 678 rc = 0; 679 return rc; 680 } 681 682 int 683 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon, 684 const char *fileName, __u16 type, 685 const struct nls_table *nls_codepage, int remap) 686 { 687 TRANSACTION2_SPI_REQ *pSMB = NULL; 688 TRANSACTION2_SPI_RSP *pSMBr = NULL; 689 struct unlink_psx_rq *pRqD; 690 int name_len; 691 int rc = 0; 692 int bytes_returned = 0; 693 __u16 params, param_offset, offset, byte_count; 694 695 cifs_dbg(FYI, "In POSIX delete\n"); 696 PsxDelete: 697 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 698 (void **) &pSMBr); 699 if (rc) 700 return rc; 701 702 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 703 name_len = 704 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 705 PATH_MAX, nls_codepage, remap); 706 name_len++; /* trailing null */ 707 name_len *= 2; 708 } else { 709 name_len = copy_path_name(pSMB->FileName, fileName); 710 } 711 712 params = 6 + name_len; 713 pSMB->MaxParameterCount = cpu_to_le16(2); 714 pSMB->MaxDataCount = 0; /* BB double check this with jra */ 715 pSMB->MaxSetupCount = 0; 716 pSMB->Reserved = 0; 717 pSMB->Flags = 0; 718 pSMB->Timeout = 0; 719 pSMB->Reserved2 = 0; 720 param_offset = offsetof(struct smb_com_transaction2_spi_req, 721 InformationLevel) - 4; 722 offset = param_offset + params; 723 724 /* Setup pointer to Request Data (inode type). 725 * Note that SMB offsets are from the beginning of SMB which is 4 bytes 726 * in, after RFC1001 field 727 */ 728 pRqD = (struct unlink_psx_rq *)((char *)(pSMB) + offset + 4); 729 pRqD->type = cpu_to_le16(type); 730 pSMB->ParameterOffset = cpu_to_le16(param_offset); 731 pSMB->DataOffset = cpu_to_le16(offset); 732 pSMB->SetupCount = 1; 733 pSMB->Reserved3 = 0; 734 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 735 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq); 736 737 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq)); 738 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq)); 739 pSMB->ParameterCount = cpu_to_le16(params); 740 pSMB->TotalParameterCount = pSMB->ParameterCount; 741 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK); 742 pSMB->Reserved4 = 0; 743 inc_rfc1001_len(pSMB, byte_count); 744 pSMB->ByteCount = cpu_to_le16(byte_count); 745 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 746 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 747 if (rc) 748 cifs_dbg(FYI, "Posix delete returned %d\n", rc); 749 cifs_buf_release(pSMB); 750 751 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes); 752 753 if (rc == -EAGAIN) 754 goto PsxDelete; 755 756 return rc; 757 } 758 759 int 760 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name, 761 struct cifs_sb_info *cifs_sb, struct dentry *dentry) 762 { 763 DELETE_FILE_REQ *pSMB = NULL; 764 DELETE_FILE_RSP *pSMBr = NULL; 765 int rc = 0; 766 int bytes_returned; 767 int name_len; 768 int remap = cifs_remap(cifs_sb); 769 770 DelFileRetry: 771 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB, 772 (void **) &pSMBr); 773 if (rc) 774 return rc; 775 776 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 777 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name, 778 PATH_MAX, cifs_sb->local_nls, 779 remap); 780 name_len++; /* trailing null */ 781 name_len *= 2; 782 } else { 783 name_len = copy_path_name(pSMB->fileName, name); 784 } 785 pSMB->SearchAttributes = 786 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM); 787 pSMB->BufferFormat = 0x04; 788 inc_rfc1001_len(pSMB, name_len + 1); 789 pSMB->ByteCount = cpu_to_le16(name_len + 1); 790 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 791 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 792 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes); 793 if (rc) 794 cifs_dbg(FYI, "Error in RMFile = %d\n", rc); 795 796 cifs_buf_release(pSMB); 797 if (rc == -EAGAIN) 798 goto DelFileRetry; 799 800 return rc; 801 } 802 803 int 804 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, 805 struct cifs_sb_info *cifs_sb) 806 { 807 DELETE_DIRECTORY_REQ *pSMB = NULL; 808 DELETE_DIRECTORY_RSP *pSMBr = NULL; 809 int rc = 0; 810 int bytes_returned; 811 int name_len; 812 int remap = cifs_remap(cifs_sb); 813 814 cifs_dbg(FYI, "In CIFSSMBRmDir\n"); 815 RmDirRetry: 816 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB, 817 (void **) &pSMBr); 818 if (rc) 819 return rc; 820 821 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 822 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, 823 PATH_MAX, cifs_sb->local_nls, 824 remap); 825 name_len++; /* trailing null */ 826 name_len *= 2; 827 } else { 828 name_len = copy_path_name(pSMB->DirName, name); 829 } 830 831 pSMB->BufferFormat = 0x04; 832 inc_rfc1001_len(pSMB, name_len + 1); 833 pSMB->ByteCount = cpu_to_le16(name_len + 1); 834 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 835 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 836 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs); 837 if (rc) 838 cifs_dbg(FYI, "Error in RMDir = %d\n", rc); 839 840 cifs_buf_release(pSMB); 841 if (rc == -EAGAIN) 842 goto RmDirRetry; 843 return rc; 844 } 845 846 int 847 CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode, 848 struct cifs_tcon *tcon, const char *name, 849 struct cifs_sb_info *cifs_sb) 850 { 851 int rc = 0; 852 CREATE_DIRECTORY_REQ *pSMB = NULL; 853 CREATE_DIRECTORY_RSP *pSMBr = NULL; 854 int bytes_returned; 855 int name_len; 856 int remap = cifs_remap(cifs_sb); 857 858 cifs_dbg(FYI, "In CIFSSMBMkDir\n"); 859 MkDirRetry: 860 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB, 861 (void **) &pSMBr); 862 if (rc) 863 return rc; 864 865 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 866 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, 867 PATH_MAX, cifs_sb->local_nls, 868 remap); 869 name_len++; /* trailing null */ 870 name_len *= 2; 871 } else { 872 name_len = copy_path_name(pSMB->DirName, name); 873 } 874 875 pSMB->BufferFormat = 0x04; 876 inc_rfc1001_len(pSMB, name_len + 1); 877 pSMB->ByteCount = cpu_to_le16(name_len + 1); 878 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 879 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 880 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs); 881 if (rc) 882 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc); 883 884 cifs_buf_release(pSMB); 885 if (rc == -EAGAIN) 886 goto MkDirRetry; 887 return rc; 888 } 889 890 int 891 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon, 892 __u32 posix_flags, __u64 mode, __u16 *netfid, 893 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock, 894 const char *name, const struct nls_table *nls_codepage, 895 int remap) 896 { 897 TRANSACTION2_SPI_REQ *pSMB = NULL; 898 TRANSACTION2_SPI_RSP *pSMBr = NULL; 899 int name_len; 900 int rc = 0; 901 int bytes_returned = 0; 902 __u16 params, param_offset, offset, byte_count, count; 903 OPEN_PSX_REQ *pdata; 904 OPEN_PSX_RSP *psx_rsp; 905 906 cifs_dbg(FYI, "In POSIX Create\n"); 907 PsxCreat: 908 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 909 (void **) &pSMBr); 910 if (rc) 911 return rc; 912 913 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 914 name_len = 915 cifsConvertToUTF16((__le16 *) pSMB->FileName, name, 916 PATH_MAX, nls_codepage, remap); 917 name_len++; /* trailing null */ 918 name_len *= 2; 919 } else { 920 name_len = copy_path_name(pSMB->FileName, name); 921 } 922 923 params = 6 + name_len; 924 count = sizeof(OPEN_PSX_REQ); 925 pSMB->MaxParameterCount = cpu_to_le16(2); 926 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */ 927 pSMB->MaxSetupCount = 0; 928 pSMB->Reserved = 0; 929 pSMB->Flags = 0; 930 pSMB->Timeout = 0; 931 pSMB->Reserved2 = 0; 932 param_offset = offsetof(struct smb_com_transaction2_spi_req, 933 InformationLevel) - 4; 934 offset = param_offset + params; 935 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 936 pdata = (OPEN_PSX_REQ *)((char *)(pSMB) + offset + 4); 937 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 938 pdata->Permissions = cpu_to_le64(mode); 939 pdata->PosixOpenFlags = cpu_to_le32(posix_flags); 940 pdata->OpenFlags = cpu_to_le32(*pOplock); 941 pSMB->ParameterOffset = cpu_to_le16(param_offset); 942 pSMB->DataOffset = cpu_to_le16(offset); 943 pSMB->SetupCount = 1; 944 pSMB->Reserved3 = 0; 945 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 946 byte_count = 3 /* pad */ + params + count; 947 948 pSMB->DataCount = cpu_to_le16(count); 949 pSMB->ParameterCount = cpu_to_le16(params); 950 pSMB->TotalDataCount = pSMB->DataCount; 951 pSMB->TotalParameterCount = pSMB->ParameterCount; 952 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN); 953 pSMB->Reserved4 = 0; 954 inc_rfc1001_len(pSMB, byte_count); 955 pSMB->ByteCount = cpu_to_le16(byte_count); 956 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 957 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 958 if (rc) { 959 cifs_dbg(FYI, "Posix create returned %d\n", rc); 960 goto psx_create_err; 961 } 962 963 cifs_dbg(FYI, "copying inode info\n"); 964 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 965 966 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) { 967 rc = -EIO; /* bad smb */ 968 goto psx_create_err; 969 } 970 971 /* copy return information to pRetData */ 972 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol 973 + le16_to_cpu(pSMBr->t2.DataOffset)); 974 975 *pOplock = le16_to_cpu(psx_rsp->OplockFlags); 976 if (netfid) 977 *netfid = psx_rsp->Fid; /* cifs fid stays in le */ 978 /* Let caller know file was created so we can set the mode. */ 979 /* Do we care about the CreateAction in any other cases? */ 980 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) 981 *pOplock |= CIFS_CREATE_ACTION; 982 /* check to make sure response data is there */ 983 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) { 984 pRetData->Type = cpu_to_le32(-1); /* unknown */ 985 cifs_dbg(NOISY, "unknown type\n"); 986 } else { 987 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP) 988 + sizeof(FILE_UNIX_BASIC_INFO)) { 989 cifs_dbg(VFS, "Open response data too small\n"); 990 pRetData->Type = cpu_to_le32(-1); 991 goto psx_create_err; 992 } 993 memcpy((char *) pRetData, 994 (char *)psx_rsp + sizeof(OPEN_PSX_RSP), 995 sizeof(FILE_UNIX_BASIC_INFO)); 996 } 997 998 psx_create_err: 999 cifs_buf_release(pSMB); 1000 1001 if (posix_flags & SMB_O_DIRECTORY) 1002 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs); 1003 else 1004 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens); 1005 1006 if (rc == -EAGAIN) 1007 goto PsxCreat; 1008 1009 return rc; 1010 } 1011 1012 static __u16 convert_disposition(int disposition) 1013 { 1014 __u16 ofun = 0; 1015 1016 switch (disposition) { 1017 case FILE_SUPERSEDE: 1018 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC; 1019 break; 1020 case FILE_OPEN: 1021 ofun = SMBOPEN_OAPPEND; 1022 break; 1023 case FILE_CREATE: 1024 ofun = SMBOPEN_OCREATE; 1025 break; 1026 case FILE_OPEN_IF: 1027 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND; 1028 break; 1029 case FILE_OVERWRITE: 1030 ofun = SMBOPEN_OTRUNC; 1031 break; 1032 case FILE_OVERWRITE_IF: 1033 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC; 1034 break; 1035 default: 1036 cifs_dbg(FYI, "unknown disposition %d\n", disposition); 1037 ofun = SMBOPEN_OAPPEND; /* regular open */ 1038 } 1039 return ofun; 1040 } 1041 1042 static int 1043 access_flags_to_smbopen_mode(const int access_flags) 1044 { 1045 /* 1046 * SYSTEM_SECURITY grants both read and write access to SACL, treat is as read/write. 1047 * MAXIMUM_ALLOWED grants as many access as possible, so treat it as read/write too. 1048 * SYNCHRONIZE as is does not grant any specific access, so do not check its mask. 1049 * If only SYNCHRONIZE bit is specified then fallback to read access. 1050 */ 1051 bool with_write_flags = access_flags & (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA | 1052 FILE_DELETE_CHILD | FILE_WRITE_ATTRIBUTES | DELETE | 1053 WRITE_DAC | WRITE_OWNER | SYSTEM_SECURITY | 1054 MAXIMUM_ALLOWED | GENERIC_WRITE | GENERIC_ALL); 1055 bool with_read_flags = access_flags & (FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE | 1056 FILE_READ_ATTRIBUTES | READ_CONTROL | 1057 SYSTEM_SECURITY | MAXIMUM_ALLOWED | GENERIC_ALL | 1058 GENERIC_EXECUTE | GENERIC_READ); 1059 bool with_execute_flags = access_flags & (FILE_EXECUTE | MAXIMUM_ALLOWED | GENERIC_ALL | 1060 GENERIC_EXECUTE); 1061 1062 if (with_write_flags && with_read_flags) 1063 return SMBOPEN_READWRITE; 1064 else if (with_write_flags) 1065 return SMBOPEN_WRITE; 1066 else if (with_execute_flags) 1067 return SMBOPEN_EXECUTE; 1068 else 1069 return SMBOPEN_READ; 1070 } 1071 1072 int 1073 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon, 1074 const char *fileName, const int openDisposition, 1075 const int access_flags, const int create_options, __u16 *netfid, 1076 int *pOplock, FILE_ALL_INFO *pfile_info, 1077 const struct nls_table *nls_codepage, int remap) 1078 { 1079 int rc; 1080 OPENX_REQ *pSMB = NULL; 1081 OPENX_RSP *pSMBr = NULL; 1082 int bytes_returned; 1083 int name_len; 1084 __u16 count; 1085 1086 OldOpenRetry: 1087 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB, 1088 (void **) &pSMBr); 1089 if (rc) 1090 return rc; 1091 1092 pSMB->AndXCommand = 0xFF; /* none */ 1093 1094 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1095 count = 1; /* account for one byte pad to word boundary */ 1096 name_len = 1097 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1), 1098 fileName, PATH_MAX, nls_codepage, remap); 1099 name_len++; /* trailing null */ 1100 name_len *= 2; 1101 } else { 1102 count = 0; /* no pad */ 1103 name_len = copy_path_name(pSMB->fileName, fileName); 1104 } 1105 if (*pOplock & REQ_OPLOCK) 1106 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); 1107 else if (*pOplock & REQ_BATCHOPLOCK) 1108 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); 1109 1110 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); 1111 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags)); 1112 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */ 1113 /* set file as system file if special file such as fifo, 1114 * socket, char or block and server expecting SFU style and 1115 no Unix extensions */ 1116 1117 if (create_options & CREATE_OPTION_SPECIAL) 1118 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM); 1119 else /* BB FIXME BB */ 1120 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); 1121 1122 if (create_options & CREATE_OPTION_READONLY) 1123 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY); 1124 1125 /* BB FIXME BB */ 1126 /* pSMB->CreateOptions = cpu_to_le32(create_options & 1127 CREATE_OPTIONS_MASK); */ 1128 /* BB FIXME END BB */ 1129 1130 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY); 1131 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition)); 1132 count += name_len; 1133 inc_rfc1001_len(pSMB, count); 1134 1135 pSMB->ByteCount = cpu_to_le16(count); 1136 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1137 (struct smb_hdr *)pSMBr, &bytes_returned, 0); 1138 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens); 1139 if (rc) { 1140 cifs_dbg(FYI, "Error in Open = %d\n", rc); 1141 } else { 1142 /* BB verify if wct == 15 */ 1143 1144 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/ 1145 1146 *netfid = pSMBr->Fid; /* cifs fid stays in le */ 1147 /* Let caller know file was created so we can set the mode. */ 1148 /* Do we care about the CreateAction in any other cases? */ 1149 /* BB FIXME BB */ 1150 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction) 1151 *pOplock |= CIFS_CREATE_ACTION; */ 1152 /* BB FIXME END */ 1153 1154 if (pfile_info) { 1155 pfile_info->CreationTime = 0; /* BB convert CreateTime*/ 1156 pfile_info->LastAccessTime = 0; /* BB fixme */ 1157 pfile_info->LastWriteTime = 0; /* BB fixme */ 1158 pfile_info->ChangeTime = 0; /* BB fixme */ 1159 pfile_info->Attributes = 1160 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes)); 1161 /* the file_info buf is endian converted by caller */ 1162 pfile_info->AllocationSize = 1163 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile)); 1164 pfile_info->EndOfFile = pfile_info->AllocationSize; 1165 pfile_info->NumberOfLinks = cpu_to_le32(1); 1166 pfile_info->DeletePending = 0; /* successful open = not delete pending */ 1167 } 1168 } 1169 1170 cifs_buf_release(pSMB); 1171 if (rc == -EAGAIN) 1172 goto OldOpenRetry; 1173 return rc; 1174 } 1175 1176 int 1177 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock, 1178 FILE_ALL_INFO *buf) 1179 { 1180 int rc; 1181 OPEN_REQ *req = NULL; 1182 OPEN_RSP *rsp = NULL; 1183 int bytes_returned; 1184 int name_len; 1185 __u16 count; 1186 struct cifs_sb_info *cifs_sb = oparms->cifs_sb; 1187 struct cifs_tcon *tcon = oparms->tcon; 1188 int remap = cifs_remap(cifs_sb); 1189 const struct nls_table *nls = cifs_sb->local_nls; 1190 int create_options = oparms->create_options; 1191 int desired_access = oparms->desired_access; 1192 int disposition = oparms->disposition; 1193 const char *path = oparms->path; 1194 1195 openRetry: 1196 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req, 1197 (void **)&rsp); 1198 if (rc) 1199 return rc; 1200 1201 /* no commands go after this */ 1202 req->AndXCommand = 0xFF; 1203 1204 if (req->hdr.Flags2 & SMBFLG2_UNICODE) { 1205 /* account for one byte pad to word boundary */ 1206 count = 1; 1207 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1), 1208 path, PATH_MAX, nls, remap); 1209 /* trailing null */ 1210 name_len++; 1211 name_len *= 2; 1212 req->NameLength = cpu_to_le16(name_len); 1213 } else { 1214 /* BB improve check for buffer overruns BB */ 1215 /* no pad */ 1216 count = 0; 1217 name_len = copy_path_name(req->fileName, path); 1218 req->NameLength = cpu_to_le16(name_len); 1219 } 1220 1221 if (*oplock & REQ_OPLOCK) 1222 req->OpenFlags = cpu_to_le32(REQ_OPLOCK); 1223 else if (*oplock & REQ_BATCHOPLOCK) 1224 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK); 1225 1226 req->DesiredAccess = cpu_to_le32(desired_access); 1227 req->AllocationSize = 0; 1228 1229 /* 1230 * Set file as system file if special file such as fifo, socket, char 1231 * or block and server expecting SFU style and no Unix extensions. 1232 */ 1233 if (create_options & CREATE_OPTION_SPECIAL) 1234 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM); 1235 else 1236 req->FileAttributes = cpu_to_le32(ATTR_NORMAL); 1237 1238 /* 1239 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case 1240 * sensitive checks for other servers such as Samba. 1241 */ 1242 if (tcon->ses->capabilities & CAP_UNIX) 1243 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS); 1244 1245 if (create_options & CREATE_OPTION_READONLY) 1246 req->FileAttributes |= cpu_to_le32(ATTR_READONLY); 1247 1248 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); 1249 req->CreateDisposition = cpu_to_le32(disposition); 1250 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); 1251 1252 /* BB Experiment with various impersonation levels and verify */ 1253 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); 1254 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY; 1255 1256 count += name_len; 1257 inc_rfc1001_len(req, count); 1258 1259 req->ByteCount = cpu_to_le16(count); 1260 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req, 1261 (struct smb_hdr *)rsp, &bytes_returned, 0); 1262 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens); 1263 if (rc) { 1264 cifs_dbg(FYI, "Error in Open = %d\n", rc); 1265 cifs_buf_release(req); 1266 if (rc == -EAGAIN) 1267 goto openRetry; 1268 return rc; 1269 } 1270 1271 /* 1 byte no need to le_to_cpu */ 1272 *oplock = rsp->OplockLevel; 1273 /* cifs fid stays in le */ 1274 oparms->fid->netfid = rsp->Fid; 1275 oparms->fid->access = desired_access; 1276 1277 /* Let caller know file was created so we can set the mode. */ 1278 /* Do we care about the CreateAction in any other cases? */ 1279 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction) 1280 *oplock |= CIFS_CREATE_ACTION; 1281 1282 if (buf) { 1283 /* copy commonly used attributes */ 1284 memcpy(&buf->common_attributes, 1285 &rsp->common_attributes, 1286 sizeof(buf->common_attributes)); 1287 /* the file_info buf is endian converted by caller */ 1288 buf->AllocationSize = rsp->AllocationSize; 1289 buf->EndOfFile = rsp->EndOfFile; 1290 buf->NumberOfLinks = cpu_to_le32(1); 1291 buf->DeletePending = 0; /* successful open = not delete pending */ 1292 } 1293 1294 cifs_buf_release(req); 1295 return rc; 1296 } 1297 1298 static void 1299 cifs_readv_callback(struct mid_q_entry *mid) 1300 { 1301 struct cifs_io_subrequest *rdata = mid->callback_data; 1302 struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode); 1303 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink); 1304 struct TCP_Server_Info *server = tcon->ses->server; 1305 struct smb_rqst rqst = { .rq_iov = rdata->iov, 1306 .rq_nvec = 2, 1307 .rq_iter = rdata->subreq.io_iter }; 1308 struct cifs_credits credits = { 1309 .value = 1, 1310 .instance = 0, 1311 .rreq_debug_id = rdata->rreq->debug_id, 1312 .rreq_debug_index = rdata->subreq.debug_index, 1313 }; 1314 unsigned int rreq_debug_id = rdata->rreq->debug_id; 1315 unsigned int subreq_debug_index = rdata->subreq.debug_index; 1316 1317 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n", 1318 __func__, mid->mid, mid->mid_state, rdata->result, 1319 rdata->subreq.len); 1320 1321 switch (mid->mid_state) { 1322 case MID_RESPONSE_RECEIVED: 1323 /* result already set, check signature */ 1324 if (server->sign) { 1325 int rc = 0; 1326 1327 iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes); 1328 rc = cifs_verify_signature(&rqst, server, 1329 mid->sequence_number); 1330 if (rc) 1331 cifs_dbg(VFS, "SMB signature verification returned error = %d\n", 1332 rc); 1333 } 1334 /* FIXME: should this be counted toward the initiating task? */ 1335 task_io_account_read(rdata->got_bytes); 1336 cifs_stats_bytes_read(tcon, rdata->got_bytes); 1337 break; 1338 case MID_REQUEST_SUBMITTED: 1339 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_req_submitted); 1340 goto do_retry; 1341 case MID_RETRY_NEEDED: 1342 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_retry_needed); 1343 do_retry: 1344 __set_bit(NETFS_SREQ_NEED_RETRY, &rdata->subreq.flags); 1345 rdata->result = -EAGAIN; 1346 if (server->sign && rdata->got_bytes) 1347 /* reset bytes number since we can not check a sign */ 1348 rdata->got_bytes = 0; 1349 /* FIXME: should this be counted toward the initiating task? */ 1350 task_io_account_read(rdata->got_bytes); 1351 cifs_stats_bytes_read(tcon, rdata->got_bytes); 1352 break; 1353 case MID_RESPONSE_MALFORMED: 1354 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed); 1355 rdata->result = -EIO; 1356 break; 1357 default: 1358 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown); 1359 rdata->result = -EIO; 1360 break; 1361 } 1362 1363 if (rdata->result == -ENODATA) { 1364 rdata->result = 0; 1365 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 1366 trace_smb3_read_err(rdata->rreq->debug_id, 1367 rdata->subreq.debug_index, 1368 rdata->xid, 1369 rdata->req->cfile->fid.persistent_fid, 1370 tcon->tid, tcon->ses->Suid, 1371 rdata->subreq.start + rdata->subreq.transferred, 1372 rdata->subreq.len - rdata->subreq.transferred, 1373 rdata->result); 1374 } else { 1375 size_t trans = rdata->subreq.transferred + rdata->got_bytes; 1376 if (trans < rdata->subreq.len && 1377 rdata->subreq.start + trans == ictx->remote_i_size) { 1378 rdata->result = 0; 1379 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 1380 } else if (rdata->got_bytes > 0) { 1381 __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); 1382 } 1383 if (rdata->got_bytes) 1384 __set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags); 1385 trace_smb3_read_done(rdata->rreq->debug_id, 1386 rdata->subreq.debug_index, 1387 rdata->xid, 1388 rdata->req->cfile->fid.persistent_fid, 1389 tcon->tid, tcon->ses->Suid, 1390 rdata->subreq.start + rdata->subreq.transferred, 1391 rdata->got_bytes); 1392 } 1393 1394 trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value, 1395 server->credits, server->in_flight, 1396 0, cifs_trace_rw_credits_read_response_clear); 1397 rdata->credits.value = 0; 1398 rdata->subreq.error = rdata->result; 1399 rdata->subreq.transferred += rdata->got_bytes; 1400 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress); 1401 netfs_read_subreq_terminated(&rdata->subreq); 1402 release_mid(mid); 1403 add_credits(server, &credits, 0); 1404 trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, 0, 1405 server->credits, server->in_flight, 1406 credits.value, cifs_trace_rw_credits_read_response_add); 1407 } 1408 1409 /* cifs_async_readv - send an async write, and set up mid to handle result */ 1410 int 1411 cifs_async_readv(struct cifs_io_subrequest *rdata) 1412 { 1413 int rc; 1414 READ_REQ *smb = NULL; 1415 int wct; 1416 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink); 1417 struct smb_rqst rqst = { .rq_iov = rdata->iov, 1418 .rq_nvec = 2 }; 1419 1420 cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n", 1421 __func__, rdata->subreq.start, rdata->subreq.len); 1422 1423 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1424 wct = 12; 1425 else { 1426 wct = 10; /* old style read */ 1427 if ((rdata->subreq.start >> 32) > 0) { 1428 /* can not handle this big offset for old */ 1429 return -EIO; 1430 } 1431 } 1432 1433 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb); 1434 if (rc) 1435 return rc; 1436 1437 smb->hdr.Pid = cpu_to_le16((__u16)rdata->req->pid); 1438 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->req->pid >> 16)); 1439 1440 smb->AndXCommand = 0xFF; /* none */ 1441 smb->Fid = rdata->req->cfile->fid.netfid; 1442 smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF); 1443 if (wct == 12) 1444 smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32); 1445 smb->Remaining = 0; 1446 smb->MaxCount = cpu_to_le16(rdata->subreq.len & 0xFFFF); 1447 smb->MaxCountHigh = cpu_to_le32(rdata->subreq.len >> 16); 1448 if (wct == 12) 1449 smb->ByteCount = 0; 1450 else { 1451 /* old style read */ 1452 struct smb_com_readx_req *smbr = 1453 (struct smb_com_readx_req *)smb; 1454 smbr->ByteCount = 0; 1455 } 1456 1457 /* 4 for RFC1001 length + 1 for BCC */ 1458 rdata->iov[0].iov_base = smb; 1459 rdata->iov[0].iov_len = 4; 1460 rdata->iov[1].iov_base = (char *)smb + 4; 1461 rdata->iov[1].iov_len = get_rfc1002_length(smb); 1462 1463 trace_smb3_read_enter(rdata->rreq->debug_id, 1464 rdata->subreq.debug_index, 1465 rdata->xid, 1466 rdata->req->cfile->fid.netfid, 1467 tcon->tid, tcon->ses->Suid, 1468 rdata->subreq.start, rdata->subreq.len); 1469 1470 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive, 1471 cifs_readv_callback, NULL, rdata, 0, NULL); 1472 1473 if (rc == 0) 1474 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1475 cifs_small_buf_release(smb); 1476 return rc; 1477 } 1478 1479 int 1480 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms, 1481 unsigned int *nbytes, char **buf, int *pbuf_type) 1482 { 1483 int rc = -EACCES; 1484 READ_REQ *pSMB = NULL; 1485 READ_RSP *pSMBr = NULL; 1486 char *pReadData = NULL; 1487 int wct; 1488 int resp_buf_type = 0; 1489 struct kvec iov[1]; 1490 struct kvec rsp_iov; 1491 __u32 pid = io_parms->pid; 1492 __u16 netfid = io_parms->netfid; 1493 __u64 offset = io_parms->offset; 1494 struct cifs_tcon *tcon = io_parms->tcon; 1495 unsigned int count = io_parms->length; 1496 1497 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid); 1498 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1499 wct = 12; 1500 else { 1501 wct = 10; /* old style read */ 1502 if ((offset >> 32) > 0) { 1503 /* can not handle this big offset for old */ 1504 return -EIO; 1505 } 1506 } 1507 1508 *nbytes = 0; 1509 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB); 1510 if (rc) 1511 return rc; 1512 1513 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1514 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1515 1516 /* tcon and ses pointer are checked in smb_init */ 1517 if (tcon->ses->server == NULL) 1518 return -ECONNABORTED; 1519 1520 pSMB->AndXCommand = 0xFF; /* none */ 1521 pSMB->Fid = netfid; 1522 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1523 if (wct == 12) 1524 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1525 1526 pSMB->Remaining = 0; 1527 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1528 pSMB->MaxCountHigh = cpu_to_le32(count >> 16); 1529 if (wct == 12) 1530 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ 1531 else { 1532 /* old style read */ 1533 struct smb_com_readx_req *pSMBW = 1534 (struct smb_com_readx_req *)pSMB; 1535 pSMBW->ByteCount = 0; 1536 } 1537 1538 iov[0].iov_base = (char *)pSMB; 1539 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 1540 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type, 1541 CIFS_LOG_ERROR, &rsp_iov); 1542 cifs_small_buf_release(pSMB); 1543 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1544 pSMBr = (READ_RSP *)rsp_iov.iov_base; 1545 if (rc) { 1546 cifs_dbg(VFS, "Send error in read = %d\n", rc); 1547 } else { 1548 int data_length = le16_to_cpu(pSMBr->DataLengthHigh); 1549 data_length = data_length << 16; 1550 data_length += le16_to_cpu(pSMBr->DataLength); 1551 *nbytes = data_length; 1552 1553 /*check that DataLength would not go beyond end of SMB */ 1554 if ((data_length > CIFSMaxBufSize) 1555 || (data_length > count)) { 1556 cifs_dbg(FYI, "bad length %d for count %d\n", 1557 data_length, count); 1558 rc = -EIO; 1559 *nbytes = 0; 1560 } else { 1561 pReadData = (char *) (&pSMBr->hdr.Protocol) + 1562 le16_to_cpu(pSMBr->DataOffset); 1563 /* if (rc = copy_to_user(buf, pReadData, data_length)) { 1564 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc); 1565 rc = -EFAULT; 1566 }*/ /* can not use copy_to_user when using page cache*/ 1567 if (*buf) 1568 memcpy(*buf, pReadData, data_length); 1569 } 1570 } 1571 1572 if (*buf) { 1573 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 1574 } else if (resp_buf_type != CIFS_NO_BUFFER) { 1575 /* return buffer to caller to free */ 1576 *buf = rsp_iov.iov_base; 1577 if (resp_buf_type == CIFS_SMALL_BUFFER) 1578 *pbuf_type = CIFS_SMALL_BUFFER; 1579 else if (resp_buf_type == CIFS_LARGE_BUFFER) 1580 *pbuf_type = CIFS_LARGE_BUFFER; 1581 } /* else no valid buffer on return - leave as null */ 1582 1583 /* Note: On -EAGAIN error only caller can retry on handle based calls 1584 since file handle passed in no longer valid */ 1585 return rc; 1586 } 1587 1588 1589 int 1590 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms, 1591 unsigned int *nbytes, const char *buf) 1592 { 1593 int rc = -EACCES; 1594 WRITE_REQ *pSMB = NULL; 1595 WRITE_RSP *pSMBr = NULL; 1596 int bytes_returned, wct; 1597 __u32 bytes_sent; 1598 __u16 byte_count; 1599 __u32 pid = io_parms->pid; 1600 __u16 netfid = io_parms->netfid; 1601 __u64 offset = io_parms->offset; 1602 struct cifs_tcon *tcon = io_parms->tcon; 1603 unsigned int count = io_parms->length; 1604 1605 *nbytes = 0; 1606 1607 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/ 1608 if (tcon->ses == NULL) 1609 return -ECONNABORTED; 1610 1611 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1612 wct = 14; 1613 else { 1614 wct = 12; 1615 if ((offset >> 32) > 0) { 1616 /* can not handle big offset for old srv */ 1617 return -EIO; 1618 } 1619 } 1620 1621 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB, 1622 (void **) &pSMBr); 1623 if (rc) 1624 return rc; 1625 1626 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1627 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1628 1629 /* tcon and ses pointer are checked in smb_init */ 1630 if (tcon->ses->server == NULL) 1631 return -ECONNABORTED; 1632 1633 pSMB->AndXCommand = 0xFF; /* none */ 1634 pSMB->Fid = netfid; 1635 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1636 if (wct == 14) 1637 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1638 1639 pSMB->Reserved = 0xFFFFFFFF; 1640 pSMB->WriteMode = 0; 1641 pSMB->Remaining = 0; 1642 1643 /* Can increase buffer size if buffer is big enough in some cases ie we 1644 can send more if LARGE_WRITE_X capability returned by the server and if 1645 our buffer is big enough or if we convert to iovecs on socket writes 1646 and eliminate the copy to the CIFS buffer */ 1647 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) { 1648 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count); 1649 } else { 1650 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) 1651 & ~0xFF; 1652 } 1653 1654 if (bytes_sent > count) 1655 bytes_sent = count; 1656 pSMB->DataOffset = 1657 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 1658 if (buf) 1659 memcpy(pSMB->Data, buf, bytes_sent); 1660 else if (count != 0) { 1661 /* No buffer */ 1662 cifs_buf_release(pSMB); 1663 return -EINVAL; 1664 } /* else setting file size with write of zero bytes */ 1665 if (wct == 14) 1666 byte_count = bytes_sent + 1; /* pad */ 1667 else /* wct == 12 */ 1668 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ 1669 1670 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); 1671 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1672 inc_rfc1001_len(pSMB, byte_count); 1673 1674 if (wct == 14) 1675 pSMB->ByteCount = cpu_to_le16(byte_count); 1676 else { /* old style write has byte count 4 bytes earlier 1677 so 4 bytes pad */ 1678 struct smb_com_writex_req *pSMBW = 1679 (struct smb_com_writex_req *)pSMB; 1680 pSMBW->ByteCount = cpu_to_le16(byte_count); 1681 } 1682 1683 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1684 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1685 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1686 if (rc) { 1687 cifs_dbg(FYI, "Send error in write = %d\n", rc); 1688 } else { 1689 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1690 *nbytes = (*nbytes) << 16; 1691 *nbytes += le16_to_cpu(pSMBr->Count); 1692 1693 /* 1694 * Mask off high 16 bits when bytes written as returned by the 1695 * server is greater than bytes requested by the client. Some 1696 * OS/2 servers are known to set incorrect CountHigh values. 1697 */ 1698 if (*nbytes > count) 1699 *nbytes &= 0xFFFF; 1700 } 1701 1702 cifs_buf_release(pSMB); 1703 1704 /* Note: On -EAGAIN error only caller can retry on handle based calls 1705 since file handle passed in no longer valid */ 1706 1707 return rc; 1708 } 1709 1710 /* 1711 * Check the mid_state and signature on received buffer (if any), and queue the 1712 * workqueue completion task. 1713 */ 1714 static void 1715 cifs_writev_callback(struct mid_q_entry *mid) 1716 { 1717 struct cifs_io_subrequest *wdata = mid->callback_data; 1718 struct TCP_Server_Info *server = wdata->server; 1719 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink); 1720 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; 1721 struct cifs_credits credits = { 1722 .value = 1, 1723 .instance = 0, 1724 .rreq_debug_id = wdata->rreq->debug_id, 1725 .rreq_debug_index = wdata->subreq.debug_index, 1726 }; 1727 ssize_t result; 1728 size_t written; 1729 1730 switch (mid->mid_state) { 1731 case MID_RESPONSE_RECEIVED: 1732 result = cifs_check_receive(mid, tcon->ses->server, 0); 1733 if (result != 0) 1734 break; 1735 1736 written = le16_to_cpu(smb->CountHigh); 1737 written <<= 16; 1738 written += le16_to_cpu(smb->Count); 1739 /* 1740 * Mask off high 16 bits when bytes written as returned 1741 * by the server is greater than bytes requested by the 1742 * client. OS/2 servers are known to set incorrect 1743 * CountHigh values. 1744 */ 1745 if (written > wdata->subreq.len) 1746 written &= 0xFFFF; 1747 1748 if (written < wdata->subreq.len) { 1749 result = -ENOSPC; 1750 } else { 1751 result = written; 1752 if (written > 0) 1753 __set_bit(NETFS_SREQ_MADE_PROGRESS, &wdata->subreq.flags); 1754 } 1755 break; 1756 case MID_REQUEST_SUBMITTED: 1757 trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_req_submitted); 1758 __set_bit(NETFS_SREQ_NEED_RETRY, &wdata->subreq.flags); 1759 result = -EAGAIN; 1760 break; 1761 case MID_RETRY_NEEDED: 1762 trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_retry_needed); 1763 __set_bit(NETFS_SREQ_NEED_RETRY, &wdata->subreq.flags); 1764 result = -EAGAIN; 1765 break; 1766 case MID_RESPONSE_MALFORMED: 1767 trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed); 1768 result = -EIO; 1769 break; 1770 default: 1771 trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown); 1772 result = -EIO; 1773 break; 1774 } 1775 1776 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 1777 wdata->credits.value, 1778 server->credits, server->in_flight, 1779 0, cifs_trace_rw_credits_write_response_clear); 1780 wdata->credits.value = 0; 1781 cifs_write_subrequest_terminated(wdata, result); 1782 release_mid(mid); 1783 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0, 1784 server->credits, server->in_flight, 1785 credits.value, cifs_trace_rw_credits_write_response_add); 1786 add_credits(tcon->ses->server, &credits, 0); 1787 } 1788 1789 /* cifs_async_writev - send an async write, and set up mid to handle result */ 1790 void 1791 cifs_async_writev(struct cifs_io_subrequest *wdata) 1792 { 1793 int rc = -EACCES; 1794 WRITE_REQ *smb = NULL; 1795 int wct; 1796 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink); 1797 struct kvec iov[2]; 1798 struct smb_rqst rqst = { }; 1799 1800 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 1801 wct = 14; 1802 } else { 1803 wct = 12; 1804 if (wdata->subreq.start >> 32 > 0) { 1805 /* can not handle big offset for old srv */ 1806 rc = -EIO; 1807 goto out; 1808 } 1809 } 1810 1811 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb); 1812 if (rc) 1813 goto async_writev_out; 1814 1815 smb->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid); 1816 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16)); 1817 1818 smb->AndXCommand = 0xFF; /* none */ 1819 smb->Fid = wdata->req->cfile->fid.netfid; 1820 smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF); 1821 if (wct == 14) 1822 smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32); 1823 smb->Reserved = 0xFFFFFFFF; 1824 smb->WriteMode = 0; 1825 smb->Remaining = 0; 1826 1827 smb->DataOffset = 1828 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 1829 1830 /* 4 for RFC1001 length + 1 for BCC */ 1831 iov[0].iov_len = 4; 1832 iov[0].iov_base = smb; 1833 iov[1].iov_len = get_rfc1002_length(smb) + 1; 1834 iov[1].iov_base = (char *)smb + 4; 1835 1836 rqst.rq_iov = iov; 1837 rqst.rq_nvec = 2; 1838 rqst.rq_iter = wdata->subreq.io_iter; 1839 1840 cifs_dbg(FYI, "async write at %llu %zu bytes\n", 1841 wdata->subreq.start, wdata->subreq.len); 1842 1843 smb->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF); 1844 smb->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16); 1845 1846 if (wct == 14) { 1847 inc_rfc1001_len(&smb->hdr, wdata->subreq.len + 1); 1848 put_bcc(wdata->subreq.len + 1, &smb->hdr); 1849 } else { 1850 /* wct == 12 */ 1851 struct smb_com_writex_req *smbw = 1852 (struct smb_com_writex_req *)smb; 1853 inc_rfc1001_len(&smbw->hdr, wdata->subreq.len + 5); 1854 put_bcc(wdata->subreq.len + 5, &smbw->hdr); 1855 iov[1].iov_len += 4; /* pad bigger by four bytes */ 1856 } 1857 1858 rc = cifs_call_async(tcon->ses->server, &rqst, NULL, 1859 cifs_writev_callback, NULL, wdata, 0, NULL); 1860 /* Can't touch wdata if rc == 0 */ 1861 if (rc == 0) 1862 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1863 1864 async_writev_out: 1865 cifs_small_buf_release(smb); 1866 out: 1867 if (rc) { 1868 add_credits_and_wake_if(wdata->server, &wdata->credits, 0); 1869 cifs_write_subrequest_terminated(wdata, rc); 1870 } 1871 } 1872 1873 int 1874 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms, 1875 unsigned int *nbytes, struct kvec *iov, int n_vec) 1876 { 1877 int rc; 1878 WRITE_REQ *pSMB = NULL; 1879 int wct; 1880 int smb_hdr_len; 1881 int resp_buf_type = 0; 1882 __u32 pid = io_parms->pid; 1883 __u16 netfid = io_parms->netfid; 1884 __u64 offset = io_parms->offset; 1885 struct cifs_tcon *tcon = io_parms->tcon; 1886 unsigned int count = io_parms->length; 1887 struct kvec rsp_iov; 1888 1889 *nbytes = 0; 1890 1891 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count); 1892 1893 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 1894 wct = 14; 1895 } else { 1896 wct = 12; 1897 if ((offset >> 32) > 0) { 1898 /* can not handle big offset for old srv */ 1899 return -EIO; 1900 } 1901 } 1902 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); 1903 if (rc) 1904 return rc; 1905 1906 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1907 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1908 1909 /* tcon and ses pointer are checked in smb_init */ 1910 if (tcon->ses->server == NULL) 1911 return -ECONNABORTED; 1912 1913 pSMB->AndXCommand = 0xFF; /* none */ 1914 pSMB->Fid = netfid; 1915 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1916 if (wct == 14) 1917 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1918 pSMB->Reserved = 0xFFFFFFFF; 1919 pSMB->WriteMode = 0; 1920 pSMB->Remaining = 0; 1921 1922 pSMB->DataOffset = 1923 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 1924 1925 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); 1926 pSMB->DataLengthHigh = cpu_to_le16(count >> 16); 1927 /* header + 1 byte pad */ 1928 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1; 1929 if (wct == 14) 1930 inc_rfc1001_len(pSMB, count + 1); 1931 else /* wct == 12 */ 1932 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */ 1933 if (wct == 14) 1934 pSMB->ByteCount = cpu_to_le16(count + 1); 1935 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ { 1936 struct smb_com_writex_req *pSMBW = 1937 (struct smb_com_writex_req *)pSMB; 1938 pSMBW->ByteCount = cpu_to_le16(count + 5); 1939 } 1940 iov[0].iov_base = pSMB; 1941 if (wct == 14) 1942 iov[0].iov_len = smb_hdr_len + 4; 1943 else /* wct == 12 pad bigger by four bytes */ 1944 iov[0].iov_len = smb_hdr_len + 8; 1945 1946 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0, 1947 &rsp_iov); 1948 cifs_small_buf_release(pSMB); 1949 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1950 if (rc) { 1951 cifs_dbg(FYI, "Send error Write2 = %d\n", rc); 1952 } else if (resp_buf_type == 0) { 1953 /* presumably this can not happen, but best to be safe */ 1954 rc = -EIO; 1955 } else { 1956 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base; 1957 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1958 *nbytes = (*nbytes) << 16; 1959 *nbytes += le16_to_cpu(pSMBr->Count); 1960 1961 /* 1962 * Mask off high 16 bits when bytes written as returned by the 1963 * server is greater than bytes requested by the client. OS/2 1964 * servers are known to set incorrect CountHigh values. 1965 */ 1966 if (*nbytes > count) 1967 *nbytes &= 0xFFFF; 1968 } 1969 1970 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 1971 1972 /* Note: On -EAGAIN error only caller can retry on handle based calls 1973 since file handle passed in no longer valid */ 1974 1975 return rc; 1976 } 1977 1978 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon, 1979 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock, 1980 const __u32 num_lock, LOCKING_ANDX_RANGE *buf) 1981 { 1982 int rc = 0; 1983 LOCK_REQ *pSMB = NULL; 1984 struct kvec iov[2]; 1985 struct kvec rsp_iov; 1986 int resp_buf_type; 1987 __u16 count; 1988 1989 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n", 1990 num_lock, num_unlock); 1991 1992 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 1993 if (rc) 1994 return rc; 1995 1996 pSMB->Timeout = 0; 1997 pSMB->NumberOfLocks = cpu_to_le16(num_lock); 1998 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock); 1999 pSMB->LockType = lock_type; 2000 pSMB->AndXCommand = 0xFF; /* none */ 2001 pSMB->Fid = netfid; /* netfid stays le */ 2002 2003 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 2004 inc_rfc1001_len(pSMB, count); 2005 pSMB->ByteCount = cpu_to_le16(count); 2006 2007 iov[0].iov_base = (char *)pSMB; 2008 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 - 2009 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 2010 iov[1].iov_base = (char *)buf; 2011 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 2012 2013 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); 2014 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, 2015 CIFS_NO_RSP_BUF, &rsp_iov); 2016 cifs_small_buf_release(pSMB); 2017 if (rc) 2018 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc); 2019 2020 return rc; 2021 } 2022 2023 int 2024 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon, 2025 const __u16 smb_file_id, const __u32 netpid, const __u64 len, 2026 const __u64 offset, const __u32 numUnlock, 2027 const __u32 numLock, const __u8 lockType, 2028 const bool waitFlag, const __u8 oplock_level) 2029 { 2030 int rc = 0; 2031 LOCK_REQ *pSMB = NULL; 2032 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */ 2033 int bytes_returned; 2034 int flags = 0; 2035 __u16 count; 2036 2037 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n", 2038 (int)waitFlag, numLock); 2039 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 2040 2041 if (rc) 2042 return rc; 2043 2044 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 2045 /* no response expected */ 2046 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP; 2047 pSMB->Timeout = 0; 2048 } else if (waitFlag) { 2049 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ 2050 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ 2051 } else { 2052 pSMB->Timeout = 0; 2053 } 2054 2055 pSMB->NumberOfLocks = cpu_to_le16(numLock); 2056 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock); 2057 pSMB->LockType = lockType; 2058 pSMB->OplockLevel = oplock_level; 2059 pSMB->AndXCommand = 0xFF; /* none */ 2060 pSMB->Fid = smb_file_id; /* netfid stays le */ 2061 2062 if ((numLock != 0) || (numUnlock != 0)) { 2063 pSMB->Locks[0].Pid = cpu_to_le16(netpid); 2064 /* BB where to store pid high? */ 2065 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len); 2066 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32)); 2067 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset); 2068 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32)); 2069 count = sizeof(LOCKING_ANDX_RANGE); 2070 } else { 2071 /* oplock break */ 2072 count = 0; 2073 } 2074 inc_rfc1001_len(pSMB, count); 2075 pSMB->ByteCount = cpu_to_le16(count); 2076 2077 if (waitFlag) 2078 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 2079 (struct smb_hdr *) pSMB, &bytes_returned); 2080 else 2081 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags); 2082 cifs_small_buf_release(pSMB); 2083 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); 2084 if (rc) 2085 cifs_dbg(FYI, "Send error in Lock = %d\n", rc); 2086 2087 /* Note: On -EAGAIN error only caller can retry on handle based calls 2088 since file handle passed in no longer valid */ 2089 return rc; 2090 } 2091 2092 int 2093 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon, 2094 const __u16 smb_file_id, const __u32 netpid, 2095 const loff_t start_offset, const __u64 len, 2096 struct file_lock *pLockData, const __u16 lock_type, 2097 const bool waitFlag) 2098 { 2099 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2100 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 2101 struct cifs_posix_lock *parm_data; 2102 int rc = 0; 2103 int timeout = 0; 2104 int bytes_returned = 0; 2105 int resp_buf_type = 0; 2106 __u16 params, param_offset, offset, byte_count, count; 2107 struct kvec iov[1]; 2108 struct kvec rsp_iov; 2109 2110 cifs_dbg(FYI, "Posix Lock\n"); 2111 2112 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 2113 2114 if (rc) 2115 return rc; 2116 2117 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; 2118 2119 params = 6; 2120 pSMB->MaxSetupCount = 0; 2121 pSMB->Reserved = 0; 2122 pSMB->Flags = 0; 2123 pSMB->Reserved2 = 0; 2124 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 2125 offset = param_offset + params; 2126 2127 count = sizeof(struct cifs_posix_lock); 2128 pSMB->MaxParameterCount = cpu_to_le16(2); 2129 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ 2130 pSMB->SetupCount = 1; 2131 pSMB->Reserved3 = 0; 2132 if (pLockData) 2133 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 2134 else 2135 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 2136 byte_count = 3 /* pad */ + params + count; 2137 pSMB->DataCount = cpu_to_le16(count); 2138 pSMB->ParameterCount = cpu_to_le16(params); 2139 pSMB->TotalDataCount = pSMB->DataCount; 2140 pSMB->TotalParameterCount = pSMB->ParameterCount; 2141 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2142 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2143 parm_data = (struct cifs_posix_lock *) 2144 (((char *)pSMB) + offset + 4); 2145 2146 parm_data->lock_type = cpu_to_le16(lock_type); 2147 if (waitFlag) { 2148 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ 2149 parm_data->lock_flags = cpu_to_le16(1); 2150 pSMB->Timeout = cpu_to_le32(-1); 2151 } else 2152 pSMB->Timeout = 0; 2153 2154 parm_data->pid = cpu_to_le32(netpid); 2155 parm_data->start = cpu_to_le64(start_offset); 2156 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */ 2157 2158 pSMB->DataOffset = cpu_to_le16(offset); 2159 pSMB->Fid = smb_file_id; 2160 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK); 2161 pSMB->Reserved4 = 0; 2162 inc_rfc1001_len(pSMB, byte_count); 2163 pSMB->ByteCount = cpu_to_le16(byte_count); 2164 if (waitFlag) { 2165 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 2166 (struct smb_hdr *) pSMBr, &bytes_returned); 2167 } else { 2168 iov[0].iov_base = (char *)pSMB; 2169 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 2170 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 2171 &resp_buf_type, timeout, &rsp_iov); 2172 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base; 2173 } 2174 cifs_small_buf_release(pSMB); 2175 2176 if (rc) { 2177 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc); 2178 } else if (pLockData) { 2179 /* lock structure can be returned on get */ 2180 __u16 data_offset; 2181 __u16 data_count; 2182 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2183 2184 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) { 2185 rc = -EIO; /* bad smb */ 2186 goto plk_err_exit; 2187 } 2188 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 2189 data_count = le16_to_cpu(pSMBr->t2.DataCount); 2190 if (data_count < sizeof(struct cifs_posix_lock)) { 2191 rc = -EIO; 2192 goto plk_err_exit; 2193 } 2194 parm_data = (struct cifs_posix_lock *) 2195 ((char *)&pSMBr->hdr.Protocol + data_offset); 2196 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) 2197 pLockData->c.flc_type = F_UNLCK; 2198 else { 2199 if (parm_data->lock_type == 2200 cpu_to_le16(CIFS_RDLCK)) 2201 pLockData->c.flc_type = F_RDLCK; 2202 else if (parm_data->lock_type == 2203 cpu_to_le16(CIFS_WRLCK)) 2204 pLockData->c.flc_type = F_WRLCK; 2205 2206 pLockData->fl_start = le64_to_cpu(parm_data->start); 2207 pLockData->fl_end = pLockData->fl_start + 2208 (le64_to_cpu(parm_data->length) ? 2209 le64_to_cpu(parm_data->length) - 1 : 0); 2210 pLockData->c.flc_pid = -le32_to_cpu(parm_data->pid); 2211 } 2212 } 2213 2214 plk_err_exit: 2215 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 2216 2217 /* Note: On -EAGAIN error only caller can retry on handle based calls 2218 since file handle passed in no longer valid */ 2219 2220 return rc; 2221 } 2222 2223 2224 int 2225 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) 2226 { 2227 int rc = 0; 2228 CLOSE_REQ *pSMB = NULL; 2229 cifs_dbg(FYI, "In CIFSSMBClose\n"); 2230 2231 /* do not retry on dead session on close */ 2232 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB); 2233 if (rc == -EAGAIN) 2234 return 0; 2235 if (rc) 2236 return rc; 2237 2238 pSMB->FileID = (__u16) smb_file_id; 2239 pSMB->LastWriteTime = 0xFFFFFFFF; 2240 pSMB->ByteCount = 0; 2241 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 2242 cifs_small_buf_release(pSMB); 2243 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes); 2244 if (rc) { 2245 if (rc != -EINTR) { 2246 /* EINTR is expected when user ctl-c to kill app */ 2247 cifs_dbg(VFS, "Send error in Close = %d\n", rc); 2248 } 2249 } 2250 2251 /* Since session is dead, file will be closed on server already */ 2252 if (rc == -EAGAIN) 2253 rc = 0; 2254 2255 return rc; 2256 } 2257 2258 int 2259 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) 2260 { 2261 int rc = 0; 2262 FLUSH_REQ *pSMB = NULL; 2263 cifs_dbg(FYI, "In CIFSSMBFlush\n"); 2264 2265 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB); 2266 if (rc) 2267 return rc; 2268 2269 pSMB->FileID = (__u16) smb_file_id; 2270 pSMB->ByteCount = 0; 2271 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 2272 cifs_small_buf_release(pSMB); 2273 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes); 2274 if (rc) 2275 cifs_dbg(VFS, "Send error in Flush = %d\n", rc); 2276 2277 return rc; 2278 } 2279 2280 int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, 2281 struct dentry *source_dentry, 2282 const char *from_name, const char *to_name, 2283 struct cifs_sb_info *cifs_sb) 2284 { 2285 int rc = 0; 2286 RENAME_REQ *pSMB = NULL; 2287 RENAME_RSP *pSMBr = NULL; 2288 int bytes_returned; 2289 int name_len, name_len2; 2290 __u16 count; 2291 int remap = cifs_remap(cifs_sb); 2292 2293 cifs_dbg(FYI, "In CIFSSMBRename\n"); 2294 renameRetry: 2295 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB, 2296 (void **) &pSMBr); 2297 if (rc) 2298 return rc; 2299 2300 pSMB->BufferFormat = 0x04; 2301 pSMB->SearchAttributes = 2302 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 2303 ATTR_DIRECTORY); 2304 2305 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2306 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName, 2307 from_name, PATH_MAX, 2308 cifs_sb->local_nls, remap); 2309 name_len++; /* trailing null */ 2310 name_len *= 2; 2311 pSMB->OldFileName[name_len] = 0x04; /* pad */ 2312 /* protocol requires ASCII signature byte on Unicode string */ 2313 pSMB->OldFileName[name_len + 1] = 0x00; 2314 name_len2 = 2315 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2316 to_name, PATH_MAX, cifs_sb->local_nls, 2317 remap); 2318 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2319 name_len2 *= 2; /* convert to bytes */ 2320 } else { 2321 name_len = copy_path_name(pSMB->OldFileName, from_name); 2322 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name); 2323 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2324 name_len2++; /* signature byte */ 2325 } 2326 2327 count = 1 /* 1st signature byte */ + name_len + name_len2; 2328 inc_rfc1001_len(pSMB, count); 2329 pSMB->ByteCount = cpu_to_le16(count); 2330 2331 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2332 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2333 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames); 2334 if (rc) 2335 cifs_dbg(FYI, "Send error in rename = %d\n", rc); 2336 2337 cifs_buf_release(pSMB); 2338 2339 if (rc == -EAGAIN) 2340 goto renameRetry; 2341 2342 return rc; 2343 } 2344 2345 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon, 2346 int netfid, const char *target_name, 2347 const struct nls_table *nls_codepage, int remap) 2348 { 2349 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2350 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 2351 struct set_file_rename *rename_info; 2352 char *data_offset; 2353 char dummy_string[30]; 2354 int rc = 0; 2355 int bytes_returned = 0; 2356 int len_of_str; 2357 __u16 params, param_offset, offset, count, byte_count; 2358 2359 cifs_dbg(FYI, "Rename to File by handle\n"); 2360 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB, 2361 (void **) &pSMBr); 2362 if (rc) 2363 return rc; 2364 2365 params = 6; 2366 pSMB->MaxSetupCount = 0; 2367 pSMB->Reserved = 0; 2368 pSMB->Flags = 0; 2369 pSMB->Timeout = 0; 2370 pSMB->Reserved2 = 0; 2371 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 2372 offset = param_offset + params; 2373 2374 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2375 data_offset = (char *)(pSMB) + offset + 4; 2376 rename_info = (struct set_file_rename *) data_offset; 2377 pSMB->MaxParameterCount = cpu_to_le16(2); 2378 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ 2379 pSMB->SetupCount = 1; 2380 pSMB->Reserved3 = 0; 2381 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 2382 byte_count = 3 /* pad */ + params; 2383 pSMB->ParameterCount = cpu_to_le16(params); 2384 pSMB->TotalParameterCount = pSMB->ParameterCount; 2385 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2386 pSMB->DataOffset = cpu_to_le16(offset); 2387 /* construct random name ".cifs_tmp<inodenum><mid>" */ 2388 rename_info->overwrite = cpu_to_le32(1); 2389 rename_info->root_fid = 0; 2390 /* unicode only call */ 2391 if (target_name == NULL) { 2392 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid); 2393 len_of_str = 2394 cifsConvertToUTF16((__le16 *)rename_info->target_name, 2395 dummy_string, 24, nls_codepage, remap); 2396 } else { 2397 len_of_str = 2398 cifsConvertToUTF16((__le16 *)rename_info->target_name, 2399 target_name, PATH_MAX, nls_codepage, 2400 remap); 2401 } 2402 rename_info->target_name_len = cpu_to_le32(2 * len_of_str); 2403 count = sizeof(struct set_file_rename) + (2 * len_of_str); 2404 byte_count += count; 2405 pSMB->DataCount = cpu_to_le16(count); 2406 pSMB->TotalDataCount = pSMB->DataCount; 2407 pSMB->Fid = netfid; 2408 pSMB->InformationLevel = 2409 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION); 2410 pSMB->Reserved4 = 0; 2411 inc_rfc1001_len(pSMB, byte_count); 2412 pSMB->ByteCount = cpu_to_le16(byte_count); 2413 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, 2414 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2415 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames); 2416 if (rc) 2417 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n", 2418 rc); 2419 2420 cifs_buf_release(pSMB); 2421 2422 /* Note: On -EAGAIN error only caller can retry on handle based calls 2423 since file handle passed in no longer valid */ 2424 2425 return rc; 2426 } 2427 2428 int 2429 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon, 2430 const char *fromName, const char *toName, 2431 const struct nls_table *nls_codepage, int remap) 2432 { 2433 TRANSACTION2_SPI_REQ *pSMB = NULL; 2434 TRANSACTION2_SPI_RSP *pSMBr = NULL; 2435 char *data_offset; 2436 int name_len; 2437 int name_len_target; 2438 int rc = 0; 2439 int bytes_returned = 0; 2440 __u16 params, param_offset, offset, byte_count; 2441 2442 cifs_dbg(FYI, "In Symlink Unix style\n"); 2443 createSymLinkRetry: 2444 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2445 (void **) &pSMBr); 2446 if (rc) 2447 return rc; 2448 2449 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2450 name_len = 2451 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName, 2452 /* find define for this maxpathcomponent */ 2453 PATH_MAX, nls_codepage, remap); 2454 name_len++; /* trailing null */ 2455 name_len *= 2; 2456 2457 } else { 2458 name_len = copy_path_name(pSMB->FileName, fromName); 2459 } 2460 params = 6 + name_len; 2461 pSMB->MaxSetupCount = 0; 2462 pSMB->Reserved = 0; 2463 pSMB->Flags = 0; 2464 pSMB->Timeout = 0; 2465 pSMB->Reserved2 = 0; 2466 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2467 InformationLevel) - 4; 2468 offset = param_offset + params; 2469 2470 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2471 data_offset = (char *)pSMB + offset + 4; 2472 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2473 name_len_target = 2474 cifsConvertToUTF16((__le16 *) data_offset, toName, 2475 /* find define for this maxpathcomponent */ 2476 PATH_MAX, nls_codepage, remap); 2477 name_len_target++; /* trailing null */ 2478 name_len_target *= 2; 2479 } else { 2480 name_len_target = copy_path_name(data_offset, toName); 2481 } 2482 2483 pSMB->MaxParameterCount = cpu_to_le16(2); 2484 /* BB find exact max on data count below from sess */ 2485 pSMB->MaxDataCount = cpu_to_le16(1000); 2486 pSMB->SetupCount = 1; 2487 pSMB->Reserved3 = 0; 2488 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 2489 byte_count = 3 /* pad */ + params + name_len_target; 2490 pSMB->DataCount = cpu_to_le16(name_len_target); 2491 pSMB->ParameterCount = cpu_to_le16(params); 2492 pSMB->TotalDataCount = pSMB->DataCount; 2493 pSMB->TotalParameterCount = pSMB->ParameterCount; 2494 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2495 pSMB->DataOffset = cpu_to_le16(offset); 2496 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK); 2497 pSMB->Reserved4 = 0; 2498 inc_rfc1001_len(pSMB, byte_count); 2499 pSMB->ByteCount = cpu_to_le16(byte_count); 2500 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2501 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2502 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks); 2503 if (rc) 2504 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n", 2505 rc); 2506 2507 cifs_buf_release(pSMB); 2508 2509 if (rc == -EAGAIN) 2510 goto createSymLinkRetry; 2511 2512 return rc; 2513 } 2514 2515 int 2516 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, 2517 const char *fromName, const char *toName, 2518 const struct nls_table *nls_codepage, int remap) 2519 { 2520 TRANSACTION2_SPI_REQ *pSMB = NULL; 2521 TRANSACTION2_SPI_RSP *pSMBr = NULL; 2522 char *data_offset; 2523 int name_len; 2524 int name_len_target; 2525 int rc = 0; 2526 int bytes_returned = 0; 2527 __u16 params, param_offset, offset, byte_count; 2528 2529 cifs_dbg(FYI, "In Create Hard link Unix style\n"); 2530 createHardLinkRetry: 2531 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2532 (void **) &pSMBr); 2533 if (rc) 2534 return rc; 2535 2536 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2537 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName, 2538 PATH_MAX, nls_codepage, remap); 2539 name_len++; /* trailing null */ 2540 name_len *= 2; 2541 2542 } else { 2543 name_len = copy_path_name(pSMB->FileName, toName); 2544 } 2545 params = 6 + name_len; 2546 pSMB->MaxSetupCount = 0; 2547 pSMB->Reserved = 0; 2548 pSMB->Flags = 0; 2549 pSMB->Timeout = 0; 2550 pSMB->Reserved2 = 0; 2551 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2552 InformationLevel) - 4; 2553 offset = param_offset + params; 2554 2555 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2556 data_offset = (char *)pSMB + offset + 4; 2557 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2558 name_len_target = 2559 cifsConvertToUTF16((__le16 *) data_offset, fromName, 2560 PATH_MAX, nls_codepage, remap); 2561 name_len_target++; /* trailing null */ 2562 name_len_target *= 2; 2563 } else { 2564 name_len_target = copy_path_name(data_offset, fromName); 2565 } 2566 2567 pSMB->MaxParameterCount = cpu_to_le16(2); 2568 /* BB find exact max on data count below from sess*/ 2569 pSMB->MaxDataCount = cpu_to_le16(1000); 2570 pSMB->SetupCount = 1; 2571 pSMB->Reserved3 = 0; 2572 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 2573 byte_count = 3 /* pad */ + params + name_len_target; 2574 pSMB->ParameterCount = cpu_to_le16(params); 2575 pSMB->TotalParameterCount = pSMB->ParameterCount; 2576 pSMB->DataCount = cpu_to_le16(name_len_target); 2577 pSMB->TotalDataCount = pSMB->DataCount; 2578 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2579 pSMB->DataOffset = cpu_to_le16(offset); 2580 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK); 2581 pSMB->Reserved4 = 0; 2582 inc_rfc1001_len(pSMB, byte_count); 2583 pSMB->ByteCount = cpu_to_le16(byte_count); 2584 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2585 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2586 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); 2587 if (rc) 2588 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n", 2589 rc); 2590 2591 cifs_buf_release(pSMB); 2592 if (rc == -EAGAIN) 2593 goto createHardLinkRetry; 2594 2595 return rc; 2596 } 2597 2598 int CIFSCreateHardLink(const unsigned int xid, 2599 struct cifs_tcon *tcon, 2600 struct dentry *source_dentry, 2601 const char *from_name, const char *to_name, 2602 struct cifs_sb_info *cifs_sb) 2603 { 2604 int rc = 0; 2605 NT_RENAME_REQ *pSMB = NULL; 2606 RENAME_RSP *pSMBr = NULL; 2607 int bytes_returned; 2608 int name_len, name_len2; 2609 __u16 count; 2610 int remap = cifs_remap(cifs_sb); 2611 2612 cifs_dbg(FYI, "In CIFSCreateHardLink\n"); 2613 winCreateHardLinkRetry: 2614 2615 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB, 2616 (void **) &pSMBr); 2617 if (rc) 2618 return rc; 2619 2620 pSMB->SearchAttributes = 2621 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 2622 ATTR_DIRECTORY); 2623 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK); 2624 pSMB->ClusterCount = 0; 2625 2626 pSMB->BufferFormat = 0x04; 2627 2628 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2629 name_len = 2630 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name, 2631 PATH_MAX, cifs_sb->local_nls, remap); 2632 name_len++; /* trailing null */ 2633 name_len *= 2; 2634 2635 /* protocol specifies ASCII buffer format (0x04) for unicode */ 2636 pSMB->OldFileName[name_len] = 0x04; 2637 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */ 2638 name_len2 = 2639 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2640 to_name, PATH_MAX, cifs_sb->local_nls, 2641 remap); 2642 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2643 name_len2 *= 2; /* convert to bytes */ 2644 } else { 2645 name_len = copy_path_name(pSMB->OldFileName, from_name); 2646 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2647 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name); 2648 name_len2++; /* signature byte */ 2649 } 2650 2651 count = 1 /* string type byte */ + name_len + name_len2; 2652 inc_rfc1001_len(pSMB, count); 2653 pSMB->ByteCount = cpu_to_le16(count); 2654 2655 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2656 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2657 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); 2658 if (rc) 2659 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc); 2660 2661 cifs_buf_release(pSMB); 2662 if (rc == -EAGAIN) 2663 goto winCreateHardLinkRetry; 2664 2665 return rc; 2666 } 2667 2668 int 2669 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, 2670 const unsigned char *searchName, char **symlinkinfo, 2671 const struct nls_table *nls_codepage, int remap) 2672 { 2673 /* SMB_QUERY_FILE_UNIX_LINK */ 2674 TRANSACTION2_QPI_REQ *pSMB = NULL; 2675 TRANSACTION2_QPI_RSP *pSMBr = NULL; 2676 int rc = 0; 2677 int bytes_returned; 2678 int name_len; 2679 __u16 params, byte_count; 2680 char *data_start; 2681 2682 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName); 2683 2684 querySymLinkRetry: 2685 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2686 (void **) &pSMBr); 2687 if (rc) 2688 return rc; 2689 2690 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2691 name_len = 2692 cifsConvertToUTF16((__le16 *) pSMB->FileName, 2693 searchName, PATH_MAX, nls_codepage, 2694 remap); 2695 name_len++; /* trailing null */ 2696 name_len *= 2; 2697 } else { 2698 name_len = copy_path_name(pSMB->FileName, searchName); 2699 } 2700 2701 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 2702 pSMB->TotalDataCount = 0; 2703 pSMB->MaxParameterCount = cpu_to_le16(2); 2704 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 2705 pSMB->MaxSetupCount = 0; 2706 pSMB->Reserved = 0; 2707 pSMB->Flags = 0; 2708 pSMB->Timeout = 0; 2709 pSMB->Reserved2 = 0; 2710 pSMB->ParameterOffset = cpu_to_le16(offsetof( 2711 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 2712 pSMB->DataCount = 0; 2713 pSMB->DataOffset = 0; 2714 pSMB->SetupCount = 1; 2715 pSMB->Reserved3 = 0; 2716 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 2717 byte_count = params + 1 /* pad */ ; 2718 pSMB->TotalParameterCount = cpu_to_le16(params); 2719 pSMB->ParameterCount = pSMB->TotalParameterCount; 2720 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK); 2721 pSMB->Reserved4 = 0; 2722 inc_rfc1001_len(pSMB, byte_count); 2723 pSMB->ByteCount = cpu_to_le16(byte_count); 2724 2725 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2726 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2727 if (rc) { 2728 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc); 2729 } else { 2730 /* decode response */ 2731 2732 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2733 /* BB also check enough total bytes returned */ 2734 if (rc || get_bcc(&pSMBr->hdr) < 2) 2735 rc = -EIO; 2736 else { 2737 bool is_unicode; 2738 u16 count = le16_to_cpu(pSMBr->t2.DataCount); 2739 2740 data_start = ((char *) &pSMBr->hdr.Protocol) + 2741 le16_to_cpu(pSMBr->t2.DataOffset); 2742 2743 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 2744 is_unicode = true; 2745 else 2746 is_unicode = false; 2747 2748 /* BB FIXME investigate remapping reserved chars here */ 2749 *symlinkinfo = cifs_strndup_from_utf16(data_start, 2750 count, is_unicode, nls_codepage); 2751 if (!*symlinkinfo) 2752 rc = -ENOMEM; 2753 } 2754 } 2755 cifs_buf_release(pSMB); 2756 if (rc == -EAGAIN) 2757 goto querySymLinkRetry; 2758 return rc; 2759 } 2760 2761 int cifs_query_reparse_point(const unsigned int xid, 2762 struct cifs_tcon *tcon, 2763 struct cifs_sb_info *cifs_sb, 2764 const char *full_path, 2765 u32 *tag, struct kvec *rsp, 2766 int *rsp_buftype) 2767 { 2768 struct reparse_data_buffer *buf; 2769 struct cifs_open_parms oparms; 2770 TRANSACT_IOCTL_REQ *io_req = NULL; 2771 TRANSACT_IOCTL_RSP *io_rsp = NULL; 2772 struct cifs_fid fid; 2773 __u32 data_offset, data_count, len; 2774 __u8 *start, *end; 2775 int io_rsp_len; 2776 int oplock = 0; 2777 int rc; 2778 2779 cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path); 2780 2781 if (cap_unix(tcon->ses)) 2782 return -EOPNOTSUPP; 2783 2784 if (!CIFS_REPARSE_SUPPORT(tcon)) 2785 return -EOPNOTSUPP; 2786 2787 oparms = (struct cifs_open_parms) { 2788 .tcon = tcon, 2789 .cifs_sb = cifs_sb, 2790 .desired_access = FILE_READ_ATTRIBUTES, 2791 .create_options = cifs_create_options(cifs_sb, 2792 OPEN_REPARSE_POINT), 2793 .disposition = FILE_OPEN, 2794 .path = full_path, 2795 .fid = &fid, 2796 }; 2797 2798 rc = CIFS_open(xid, &oparms, &oplock, NULL); 2799 if (rc) 2800 return rc; 2801 2802 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, 2803 (void **)&io_req, (void **)&io_rsp); 2804 if (rc) 2805 goto error; 2806 2807 io_req->TotalParameterCount = 0; 2808 io_req->TotalDataCount = 0; 2809 io_req->MaxParameterCount = cpu_to_le32(0); 2810 /* BB find exact data count max from sess structure BB */ 2811 io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); 2812 io_req->MaxSetupCount = 1; 2813 io_req->Reserved = 0; 2814 io_req->ParameterOffset = 0; 2815 io_req->DataCount = 0; 2816 io_req->DataOffset = 0; 2817 io_req->SetupCount = 4; 2818 io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 2819 io_req->ParameterCount = io_req->TotalParameterCount; 2820 io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT); 2821 io_req->IsFsctl = 1; 2822 io_req->IsRootFlag = 0; 2823 io_req->Fid = fid.netfid; 2824 io_req->ByteCount = 0; 2825 2826 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req, 2827 (struct smb_hdr *)io_rsp, &io_rsp_len, 0); 2828 if (rc) 2829 goto error; 2830 2831 data_offset = le32_to_cpu(io_rsp->DataOffset); 2832 data_count = le32_to_cpu(io_rsp->DataCount); 2833 if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 || 2834 !data_count || data_count > 2048) { 2835 rc = -EIO; 2836 goto error; 2837 } 2838 2839 /* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */ 2840 if (io_rsp->SetupCount != 1) { 2841 rc = -EIO; 2842 goto error; 2843 } 2844 2845 /* 2846 * ReturnedDataLen is output length of executed IOCTL. 2847 * DataCount is output length transferred over network. 2848 * Check that we have full FSCTL_GET_REPARSE_POINT buffer. 2849 */ 2850 if (data_count != le16_to_cpu(io_rsp->ReturnedDataLen)) { 2851 rc = -EIO; 2852 goto error; 2853 } 2854 2855 end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount; 2856 start = (__u8 *)&io_rsp->hdr.Protocol + data_offset; 2857 if (start >= end) { 2858 rc = -EIO; 2859 goto error; 2860 } 2861 2862 data_count = le16_to_cpu(io_rsp->ByteCount); 2863 buf = (struct reparse_data_buffer *)start; 2864 len = sizeof(*buf); 2865 if (data_count < len || 2866 data_count < le16_to_cpu(buf->ReparseDataLength) + len) { 2867 rc = -EIO; 2868 goto error; 2869 } 2870 2871 *tag = le32_to_cpu(buf->ReparseTag); 2872 rsp->iov_base = io_rsp; 2873 rsp->iov_len = io_rsp_len; 2874 *rsp_buftype = CIFS_LARGE_BUFFER; 2875 CIFSSMBClose(xid, tcon, fid.netfid); 2876 return 0; 2877 2878 error: 2879 cifs_buf_release(io_req); 2880 CIFSSMBClose(xid, tcon, fid.netfid); 2881 return rc; 2882 } 2883 2884 struct inode *cifs_create_reparse_inode(struct cifs_open_info_data *data, 2885 struct super_block *sb, 2886 const unsigned int xid, 2887 struct cifs_tcon *tcon, 2888 const char *full_path, 2889 bool directory, 2890 struct kvec *reparse_iov, 2891 struct kvec *xattr_iov) 2892 { 2893 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 2894 struct cifs_open_parms oparms; 2895 TRANSACT_IOCTL_REQ *io_req; 2896 struct inode *new = NULL; 2897 struct kvec in_iov[2]; 2898 struct kvec out_iov; 2899 struct cifs_fid fid; 2900 int io_req_len; 2901 int oplock = 0; 2902 int buf_type = 0; 2903 int rc; 2904 2905 cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path); 2906 2907 /* 2908 * If server filesystem does not support reparse points then do not 2909 * attempt to create reparse point. This will prevent creating unusable 2910 * empty object on the server. 2911 */ 2912 if (!CIFS_REPARSE_SUPPORT(tcon)) 2913 return ERR_PTR(-EOPNOTSUPP); 2914 2915 #ifndef CONFIG_CIFS_XATTR 2916 if (xattr_iov) 2917 return ERR_PTR(-EOPNOTSUPP); 2918 #endif 2919 2920 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, 2921 FILE_READ_ATTRIBUTES | FILE_WRITE_DATA | FILE_WRITE_EA, 2922 FILE_CREATE, 2923 (directory ? CREATE_NOT_FILE : CREATE_NOT_DIR) | OPEN_REPARSE_POINT, 2924 ACL_NO_MODE); 2925 oparms.fid = &fid; 2926 2927 rc = CIFS_open(xid, &oparms, &oplock, NULL); 2928 if (rc) 2929 return ERR_PTR(rc); 2930 2931 #ifdef CONFIG_CIFS_XATTR 2932 if (xattr_iov) { 2933 struct smb2_file_full_ea_info *ea; 2934 2935 ea = &((struct smb2_create_ea_ctx *)xattr_iov->iov_base)->ea; 2936 while (1) { 2937 rc = CIFSSMBSetEA(xid, 2938 tcon, 2939 full_path, 2940 &ea->ea_data[0], 2941 &ea->ea_data[ea->ea_name_length+1], 2942 le16_to_cpu(ea->ea_value_length), 2943 cifs_sb->local_nls, 2944 cifs_sb); 2945 if (rc) 2946 goto out_close; 2947 if (le32_to_cpu(ea->next_entry_offset) == 0) 2948 break; 2949 ea = (struct smb2_file_full_ea_info *)((u8 *)ea + 2950 le32_to_cpu(ea->next_entry_offset)); 2951 } 2952 } 2953 #endif 2954 2955 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **)&io_req, NULL); 2956 if (rc) 2957 goto out_close; 2958 2959 inc_rfc1001_len(io_req, sizeof(io_req->Pad)); 2960 2961 io_req_len = be32_to_cpu(io_req->hdr.smb_buf_length) + sizeof(io_req->hdr.smb_buf_length); 2962 2963 /* NT IOCTL response contains one-word long output setup buffer with size of output data. */ 2964 io_req->MaxSetupCount = 1; 2965 /* NT IOCTL response does not contain output parameters. */ 2966 io_req->MaxParameterCount = cpu_to_le32(0); 2967 /* FSCTL_SET_REPARSE_POINT response contains empty output data. */ 2968 io_req->MaxDataCount = cpu_to_le32(0); 2969 2970 io_req->TotalParameterCount = cpu_to_le32(0); 2971 io_req->TotalDataCount = cpu_to_le32(reparse_iov->iov_len); 2972 io_req->ParameterCount = io_req->TotalParameterCount; 2973 io_req->ParameterOffset = cpu_to_le32(0); 2974 io_req->DataCount = io_req->TotalDataCount; 2975 io_req->DataOffset = cpu_to_le32(offsetof(typeof(*io_req), Data) - 2976 sizeof(io_req->hdr.smb_buf_length)); 2977 io_req->SetupCount = 4; 2978 io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 2979 io_req->FunctionCode = cpu_to_le32(FSCTL_SET_REPARSE_POINT); 2980 io_req->Fid = fid.netfid; 2981 io_req->IsFsctl = 1; 2982 io_req->IsRootFlag = 0; 2983 io_req->ByteCount = cpu_to_le16(le32_to_cpu(io_req->DataCount) + sizeof(io_req->Pad)); 2984 2985 inc_rfc1001_len(io_req, reparse_iov->iov_len); 2986 2987 in_iov[0].iov_base = (char *)io_req; 2988 in_iov[0].iov_len = io_req_len; 2989 in_iov[1] = *reparse_iov; 2990 rc = SendReceive2(xid, tcon->ses, in_iov, ARRAY_SIZE(in_iov), &buf_type, 2991 CIFS_NO_RSP_BUF, &out_iov); 2992 2993 cifs_buf_release(io_req); 2994 2995 if (!rc) 2996 rc = cifs_get_inode_info(&new, full_path, data, sb, xid, NULL); 2997 2998 out_close: 2999 CIFSSMBClose(xid, tcon, fid.netfid); 3000 3001 /* 3002 * If CREATE was successful but FSCTL_SET_REPARSE_POINT failed then 3003 * remove the intermediate object created by CREATE. Otherwise 3004 * empty object stay on the server when reparse call failed. 3005 */ 3006 if (rc) 3007 CIFSSMBDelFile(xid, tcon, full_path, cifs_sb, NULL); 3008 3009 return rc ? ERR_PTR(rc) : new; 3010 } 3011 3012 int 3013 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon, 3014 __u16 fid) 3015 { 3016 int rc = 0; 3017 int bytes_returned; 3018 struct smb_com_transaction_compr_ioctl_req *pSMB; 3019 struct smb_com_transaction_ioctl_rsp *pSMBr; 3020 3021 cifs_dbg(FYI, "Set compression for %u\n", fid); 3022 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, 3023 (void **) &pSMBr); 3024 if (rc) 3025 return rc; 3026 3027 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT); 3028 3029 pSMB->TotalParameterCount = 0; 3030 pSMB->TotalDataCount = cpu_to_le32(2); 3031 pSMB->MaxParameterCount = 0; 3032 pSMB->MaxDataCount = 0; 3033 pSMB->MaxSetupCount = 4; 3034 pSMB->Reserved = 0; 3035 pSMB->ParameterOffset = 0; 3036 pSMB->DataCount = cpu_to_le32(2); 3037 pSMB->DataOffset = 3038 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req, 3039 compression_state) - 4); /* 84 */ 3040 pSMB->SetupCount = 4; 3041 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 3042 pSMB->ParameterCount = 0; 3043 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION); 3044 pSMB->IsFsctl = 1; /* FSCTL */ 3045 pSMB->IsRootFlag = 0; 3046 pSMB->Fid = fid; /* file handle always le */ 3047 /* 3 byte pad, followed by 2 byte compress state */ 3048 pSMB->ByteCount = cpu_to_le16(5); 3049 inc_rfc1001_len(pSMB, 5); 3050 3051 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3052 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3053 if (rc) 3054 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc); 3055 3056 cifs_buf_release(pSMB); 3057 3058 /* 3059 * Note: On -EAGAIN error only caller can retry on handle based calls 3060 * since file handle passed in no longer valid. 3061 */ 3062 return rc; 3063 } 3064 3065 3066 #ifdef CONFIG_CIFS_POSIX 3067 3068 #ifdef CONFIG_FS_POSIX_ACL 3069 /** 3070 * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format 3071 * @ace: POSIX ACL entry to store converted ACL into 3072 * @cifs_ace: ACL in cifs format 3073 * 3074 * Convert an Access Control Entry from wire format to local POSIX xattr 3075 * format. 3076 * 3077 * Note that the @cifs_uid member is used to store both {g,u}id_t. 3078 */ 3079 static void cifs_init_posix_acl(struct posix_acl_entry *ace, 3080 struct cifs_posix_ace *cifs_ace) 3081 { 3082 /* u8 cifs fields do not need le conversion */ 3083 ace->e_perm = cifs_ace->cifs_e_perm; 3084 ace->e_tag = cifs_ace->cifs_e_tag; 3085 3086 switch (ace->e_tag) { 3087 case ACL_USER: 3088 ace->e_uid = make_kuid(&init_user_ns, 3089 le64_to_cpu(cifs_ace->cifs_uid)); 3090 break; 3091 case ACL_GROUP: 3092 ace->e_gid = make_kgid(&init_user_ns, 3093 le64_to_cpu(cifs_ace->cifs_uid)); 3094 break; 3095 } 3096 return; 3097 } 3098 3099 /** 3100 * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format 3101 * @acl: ACLs returned in POSIX ACL format 3102 * @src: ACLs in cifs format 3103 * @acl_type: type of POSIX ACL requested 3104 * @size_of_data_area: size of SMB we got 3105 * 3106 * This function converts ACLs from cifs format to POSIX ACL format. 3107 * If @acl is NULL then the size of the buffer required to store POSIX ACLs in 3108 * their uapi format is returned. 3109 */ 3110 static int cifs_to_posix_acl(struct posix_acl **acl, char *src, 3111 const int acl_type, const int size_of_data_area) 3112 { 3113 int size = 0; 3114 __u16 count; 3115 struct cifs_posix_ace *pACE; 3116 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src; 3117 struct posix_acl *kacl = NULL; 3118 struct posix_acl_entry *pa, *pe; 3119 3120 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION) 3121 return -EOPNOTSUPP; 3122 3123 if (acl_type == ACL_TYPE_ACCESS) { 3124 count = le16_to_cpu(cifs_acl->access_entry_count); 3125 pACE = &cifs_acl->ace_array[0]; 3126 size = sizeof(struct cifs_posix_acl); 3127 size += sizeof(struct cifs_posix_ace) * count; 3128 /* check if we would go beyond end of SMB */ 3129 if (size_of_data_area < size) { 3130 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n", 3131 size_of_data_area, size); 3132 return -EINVAL; 3133 } 3134 } else if (acl_type == ACL_TYPE_DEFAULT) { 3135 count = le16_to_cpu(cifs_acl->access_entry_count); 3136 size = sizeof(struct cifs_posix_acl); 3137 size += sizeof(struct cifs_posix_ace) * count; 3138 /* skip past access ACEs to get to default ACEs */ 3139 pACE = &cifs_acl->ace_array[count]; 3140 count = le16_to_cpu(cifs_acl->default_entry_count); 3141 size += sizeof(struct cifs_posix_ace) * count; 3142 /* check if we would go beyond end of SMB */ 3143 if (size_of_data_area < size) 3144 return -EINVAL; 3145 } else { 3146 /* illegal type */ 3147 return -EINVAL; 3148 } 3149 3150 /* Allocate number of POSIX ACLs to store in VFS format. */ 3151 kacl = posix_acl_alloc(count, GFP_NOFS); 3152 if (!kacl) 3153 return -ENOMEM; 3154 3155 FOREACH_ACL_ENTRY(pa, kacl, pe) { 3156 cifs_init_posix_acl(pa, pACE); 3157 pACE++; 3158 } 3159 3160 *acl = kacl; 3161 return 0; 3162 } 3163 3164 /** 3165 * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format 3166 * @cifs_ace: the cifs ACL entry to store into 3167 * @local_ace: the POSIX ACL entry to convert 3168 */ 3169 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace, 3170 const struct posix_acl_entry *local_ace) 3171 { 3172 cifs_ace->cifs_e_perm = local_ace->e_perm; 3173 cifs_ace->cifs_e_tag = local_ace->e_tag; 3174 3175 switch (local_ace->e_tag) { 3176 case ACL_USER: 3177 cifs_ace->cifs_uid = 3178 cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid)); 3179 break; 3180 case ACL_GROUP: 3181 cifs_ace->cifs_uid = 3182 cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid)); 3183 break; 3184 default: 3185 cifs_ace->cifs_uid = cpu_to_le64(-1); 3186 } 3187 } 3188 3189 /** 3190 * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format 3191 * @parm_data: ACLs in cifs format to convert to 3192 * @acl: ACLs in POSIX ACL format to convert from 3193 * @acl_type: the type of POSIX ACLs stored in @acl 3194 * 3195 * Return: the number cifs ACL entries after conversion 3196 */ 3197 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl, 3198 const int acl_type) 3199 { 3200 __u16 rc = 0; 3201 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data; 3202 const struct posix_acl_entry *pa, *pe; 3203 int count; 3204 int i = 0; 3205 3206 if ((acl == NULL) || (cifs_acl == NULL)) 3207 return 0; 3208 3209 count = acl->a_count; 3210 cifs_dbg(FYI, "setting acl with %d entries\n", count); 3211 3212 /* 3213 * Note that the uapi POSIX ACL version is verified by the VFS and is 3214 * independent of the cifs ACL version. Changing the POSIX ACL version 3215 * is a uapi change and if it's changed we will pass down the POSIX ACL 3216 * version in struct posix_acl from the VFS. For now there's really 3217 * only one that all filesystems know how to deal with. 3218 */ 3219 cifs_acl->version = cpu_to_le16(1); 3220 if (acl_type == ACL_TYPE_ACCESS) { 3221 cifs_acl->access_entry_count = cpu_to_le16(count); 3222 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF); 3223 } else if (acl_type == ACL_TYPE_DEFAULT) { 3224 cifs_acl->default_entry_count = cpu_to_le16(count); 3225 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF); 3226 } else { 3227 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type); 3228 return 0; 3229 } 3230 FOREACH_ACL_ENTRY(pa, acl, pe) { 3231 cifs_init_ace(&cifs_acl->ace_array[i++], pa); 3232 } 3233 if (rc == 0) { 3234 rc = (__u16)(count * sizeof(struct cifs_posix_ace)); 3235 rc += sizeof(struct cifs_posix_acl); 3236 /* BB add check to make sure ACL does not overflow SMB */ 3237 } 3238 return rc; 3239 } 3240 3241 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, 3242 const unsigned char *searchName, struct posix_acl **acl, 3243 const int acl_type, const struct nls_table *nls_codepage, 3244 int remap) 3245 { 3246 /* SMB_QUERY_POSIX_ACL */ 3247 TRANSACTION2_QPI_REQ *pSMB = NULL; 3248 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3249 int rc = 0; 3250 int bytes_returned; 3251 int name_len; 3252 __u16 params, byte_count; 3253 3254 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName); 3255 3256 queryAclRetry: 3257 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3258 (void **) &pSMBr); 3259 if (rc) 3260 return rc; 3261 3262 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3263 name_len = 3264 cifsConvertToUTF16((__le16 *) pSMB->FileName, 3265 searchName, PATH_MAX, nls_codepage, 3266 remap); 3267 name_len++; /* trailing null */ 3268 name_len *= 2; 3269 pSMB->FileName[name_len] = 0; 3270 pSMB->FileName[name_len+1] = 0; 3271 } else { 3272 name_len = copy_path_name(pSMB->FileName, searchName); 3273 } 3274 3275 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 3276 pSMB->TotalDataCount = 0; 3277 pSMB->MaxParameterCount = cpu_to_le16(2); 3278 /* BB find exact max data count below from sess structure BB */ 3279 pSMB->MaxDataCount = cpu_to_le16(4000); 3280 pSMB->MaxSetupCount = 0; 3281 pSMB->Reserved = 0; 3282 pSMB->Flags = 0; 3283 pSMB->Timeout = 0; 3284 pSMB->Reserved2 = 0; 3285 pSMB->ParameterOffset = cpu_to_le16( 3286 offsetof(struct smb_com_transaction2_qpi_req, 3287 InformationLevel) - 4); 3288 pSMB->DataCount = 0; 3289 pSMB->DataOffset = 0; 3290 pSMB->SetupCount = 1; 3291 pSMB->Reserved3 = 0; 3292 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3293 byte_count = params + 1 /* pad */ ; 3294 pSMB->TotalParameterCount = cpu_to_le16(params); 3295 pSMB->ParameterCount = pSMB->TotalParameterCount; 3296 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL); 3297 pSMB->Reserved4 = 0; 3298 inc_rfc1001_len(pSMB, byte_count); 3299 pSMB->ByteCount = cpu_to_le16(byte_count); 3300 3301 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3302 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3303 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); 3304 if (rc) { 3305 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc); 3306 } else { 3307 /* decode response */ 3308 3309 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3310 /* BB also check enough total bytes returned */ 3311 if (rc || get_bcc(&pSMBr->hdr) < 2) 3312 rc = -EIO; /* bad smb */ 3313 else { 3314 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3315 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3316 rc = cifs_to_posix_acl(acl, 3317 (char *)&pSMBr->hdr.Protocol+data_offset, 3318 acl_type, count); 3319 } 3320 } 3321 cifs_buf_release(pSMB); 3322 /* 3323 * The else branch after SendReceive() doesn't return EAGAIN so if we 3324 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return 3325 * here and don't leak POSIX ACLs. 3326 */ 3327 if (rc == -EAGAIN) 3328 goto queryAclRetry; 3329 return rc; 3330 } 3331 3332 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon, 3333 const unsigned char *fileName, const struct posix_acl *acl, 3334 const int acl_type, const struct nls_table *nls_codepage, 3335 int remap) 3336 { 3337 struct smb_com_transaction2_spi_req *pSMB = NULL; 3338 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 3339 char *parm_data; 3340 int name_len; 3341 int rc = 0; 3342 int bytes_returned = 0; 3343 __u16 params, byte_count, data_count, param_offset, offset; 3344 3345 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName); 3346 setAclRetry: 3347 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3348 (void **) &pSMBr); 3349 if (rc) 3350 return rc; 3351 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3352 name_len = 3353 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 3354 PATH_MAX, nls_codepage, remap); 3355 name_len++; /* trailing null */ 3356 name_len *= 2; 3357 } else { 3358 name_len = copy_path_name(pSMB->FileName, fileName); 3359 } 3360 params = 6 + name_len; 3361 pSMB->MaxParameterCount = cpu_to_le16(2); 3362 /* BB find max SMB size from sess */ 3363 pSMB->MaxDataCount = cpu_to_le16(1000); 3364 pSMB->MaxSetupCount = 0; 3365 pSMB->Reserved = 0; 3366 pSMB->Flags = 0; 3367 pSMB->Timeout = 0; 3368 pSMB->Reserved2 = 0; 3369 param_offset = offsetof(struct smb_com_transaction2_spi_req, 3370 InformationLevel) - 4; 3371 offset = param_offset + params; 3372 parm_data = ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset; 3373 pSMB->ParameterOffset = cpu_to_le16(param_offset); 3374 3375 /* convert to on the wire format for POSIX ACL */ 3376 data_count = posix_acl_to_cifs(parm_data, acl, acl_type); 3377 3378 if (data_count == 0) { 3379 rc = -EOPNOTSUPP; 3380 goto setACLerrorExit; 3381 } 3382 pSMB->DataOffset = cpu_to_le16(offset); 3383 pSMB->SetupCount = 1; 3384 pSMB->Reserved3 = 0; 3385 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 3386 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL); 3387 byte_count = 3 /* pad */ + params + data_count; 3388 pSMB->DataCount = cpu_to_le16(data_count); 3389 pSMB->TotalDataCount = pSMB->DataCount; 3390 pSMB->ParameterCount = cpu_to_le16(params); 3391 pSMB->TotalParameterCount = pSMB->ParameterCount; 3392 pSMB->Reserved4 = 0; 3393 inc_rfc1001_len(pSMB, byte_count); 3394 pSMB->ByteCount = cpu_to_le16(byte_count); 3395 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3396 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3397 if (rc) 3398 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc); 3399 3400 setACLerrorExit: 3401 cifs_buf_release(pSMB); 3402 if (rc == -EAGAIN) 3403 goto setAclRetry; 3404 return rc; 3405 } 3406 #else 3407 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, 3408 const unsigned char *searchName, struct posix_acl **acl, 3409 const int acl_type, const struct nls_table *nls_codepage, 3410 int remap) 3411 { 3412 return -EOPNOTSUPP; 3413 } 3414 3415 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon, 3416 const unsigned char *fileName, const struct posix_acl *acl, 3417 const int acl_type, const struct nls_table *nls_codepage, 3418 int remap) 3419 { 3420 return -EOPNOTSUPP; 3421 } 3422 #endif /* CONFIG_FS_POSIX_ACL */ 3423 3424 int 3425 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon, 3426 const int netfid, __u64 *pExtAttrBits, __u64 *pMask) 3427 { 3428 int rc = 0; 3429 struct smb_t2_qfi_req *pSMB = NULL; 3430 struct smb_t2_qfi_rsp *pSMBr = NULL; 3431 int bytes_returned; 3432 __u16 params, byte_count; 3433 3434 cifs_dbg(FYI, "In GetExtAttr\n"); 3435 if (tcon == NULL) 3436 return -ENODEV; 3437 3438 GetExtAttrRetry: 3439 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3440 (void **) &pSMBr); 3441 if (rc) 3442 return rc; 3443 3444 params = 2 /* level */ + 2 /* fid */; 3445 pSMB->t2.TotalDataCount = 0; 3446 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3447 /* BB find exact max data count below from sess structure BB */ 3448 pSMB->t2.MaxDataCount = cpu_to_le16(4000); 3449 pSMB->t2.MaxSetupCount = 0; 3450 pSMB->t2.Reserved = 0; 3451 pSMB->t2.Flags = 0; 3452 pSMB->t2.Timeout = 0; 3453 pSMB->t2.Reserved2 = 0; 3454 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3455 Fid) - 4); 3456 pSMB->t2.DataCount = 0; 3457 pSMB->t2.DataOffset = 0; 3458 pSMB->t2.SetupCount = 1; 3459 pSMB->t2.Reserved3 = 0; 3460 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3461 byte_count = params + 1 /* pad */ ; 3462 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3463 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3464 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); 3465 pSMB->Pad = 0; 3466 pSMB->Fid = netfid; 3467 inc_rfc1001_len(pSMB, byte_count); 3468 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3469 3470 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3471 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3472 if (rc) { 3473 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc); 3474 } else { 3475 /* decode response */ 3476 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3477 /* BB also check enough total bytes returned */ 3478 if (rc || get_bcc(&pSMBr->hdr) < 2) 3479 /* If rc should we check for EOPNOSUPP and 3480 disable the srvino flag? or in caller? */ 3481 rc = -EIO; /* bad smb */ 3482 else { 3483 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3484 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3485 struct file_chattr_info *pfinfo; 3486 3487 if (count != 16) { 3488 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n"); 3489 rc = -EIO; 3490 goto GetExtAttrOut; 3491 } 3492 pfinfo = (struct file_chattr_info *) 3493 (data_offset + (char *) &pSMBr->hdr.Protocol); 3494 *pExtAttrBits = le64_to_cpu(pfinfo->mode); 3495 *pMask = le64_to_cpu(pfinfo->mask); 3496 } 3497 } 3498 GetExtAttrOut: 3499 cifs_buf_release(pSMB); 3500 if (rc == -EAGAIN) 3501 goto GetExtAttrRetry; 3502 return rc; 3503 } 3504 3505 #endif /* CONFIG_POSIX */ 3506 3507 /* 3508 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that 3509 * all NT TRANSACTS that we init here have total parm and data under about 400 3510 * bytes (to fit in small cifs buffer size), which is the case so far, it 3511 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of 3512 * returned setup area) and MaxParameterCount (returned parms size) must be set 3513 * by caller 3514 */ 3515 static int 3516 smb_init_nttransact(const __u16 sub_command, const int setup_count, 3517 const int parm_len, struct cifs_tcon *tcon, 3518 void **ret_buf) 3519 { 3520 int rc; 3521 __u32 temp_offset; 3522 struct smb_com_ntransact_req *pSMB; 3523 3524 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, 3525 (void **)&pSMB); 3526 if (rc) 3527 return rc; 3528 *ret_buf = (void *)pSMB; 3529 pSMB->Reserved = 0; 3530 pSMB->TotalParameterCount = cpu_to_le32(parm_len); 3531 pSMB->TotalDataCount = 0; 3532 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); 3533 pSMB->ParameterCount = pSMB->TotalParameterCount; 3534 pSMB->DataCount = pSMB->TotalDataCount; 3535 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + 3536 (setup_count * 2) - 4 /* for rfc1001 length itself */; 3537 pSMB->ParameterOffset = cpu_to_le32(temp_offset); 3538 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); 3539 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ 3540 pSMB->SubCommand = cpu_to_le16(sub_command); 3541 return 0; 3542 } 3543 3544 static int 3545 validate_ntransact(char *buf, char **ppparm, char **ppdata, 3546 __u32 *pparmlen, __u32 *pdatalen) 3547 { 3548 char *end_of_smb; 3549 __u32 data_count, data_offset, parm_count, parm_offset; 3550 struct smb_com_ntransact_rsp *pSMBr; 3551 u16 bcc; 3552 3553 *pdatalen = 0; 3554 *pparmlen = 0; 3555 3556 if (buf == NULL) 3557 return -EINVAL; 3558 3559 pSMBr = (struct smb_com_ntransact_rsp *)buf; 3560 3561 bcc = get_bcc(&pSMBr->hdr); 3562 end_of_smb = 2 /* sizeof byte count */ + bcc + 3563 (char *)&pSMBr->ByteCount; 3564 3565 data_offset = le32_to_cpu(pSMBr->DataOffset); 3566 data_count = le32_to_cpu(pSMBr->DataCount); 3567 parm_offset = le32_to_cpu(pSMBr->ParameterOffset); 3568 parm_count = le32_to_cpu(pSMBr->ParameterCount); 3569 3570 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; 3571 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; 3572 3573 /* should we also check that parm and data areas do not overlap? */ 3574 if (*ppparm > end_of_smb) { 3575 cifs_dbg(FYI, "parms start after end of smb\n"); 3576 return -EINVAL; 3577 } else if (parm_count + *ppparm > end_of_smb) { 3578 cifs_dbg(FYI, "parm end after end of smb\n"); 3579 return -EINVAL; 3580 } else if (*ppdata > end_of_smb) { 3581 cifs_dbg(FYI, "data starts after end of smb\n"); 3582 return -EINVAL; 3583 } else if (data_count + *ppdata > end_of_smb) { 3584 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n", 3585 *ppdata, data_count, (data_count + *ppdata), 3586 end_of_smb, pSMBr); 3587 return -EINVAL; 3588 } else if (parm_count + data_count > bcc) { 3589 cifs_dbg(FYI, "parm count and data count larger than SMB\n"); 3590 return -EINVAL; 3591 } 3592 *pdatalen = data_count; 3593 *pparmlen = parm_count; 3594 return 0; 3595 } 3596 3597 /* Get Security Descriptor (by handle) from remote server for a file or dir */ 3598 int 3599 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, 3600 struct smb_ntsd **acl_inf, __u32 *pbuflen, __u32 info) 3601 { 3602 int rc = 0; 3603 int buf_type = 0; 3604 QUERY_SEC_DESC_REQ *pSMB; 3605 struct kvec iov[1]; 3606 struct kvec rsp_iov; 3607 3608 cifs_dbg(FYI, "GetCifsACL\n"); 3609 3610 *pbuflen = 0; 3611 *acl_inf = NULL; 3612 3613 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 3614 8 /* parm len */, tcon, (void **) &pSMB); 3615 if (rc) 3616 return rc; 3617 3618 pSMB->MaxParameterCount = cpu_to_le32(4); 3619 /* BB TEST with big acls that might need to be e.g. larger than 16K */ 3620 pSMB->MaxSetupCount = 0; 3621 pSMB->Fid = fid; /* file handle always le */ 3622 pSMB->AclFlags = cpu_to_le32(info); 3623 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ 3624 inc_rfc1001_len(pSMB, 11); 3625 iov[0].iov_base = (char *)pSMB; 3626 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 3627 3628 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 3629 0, &rsp_iov); 3630 cifs_small_buf_release(pSMB); 3631 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); 3632 if (rc) { 3633 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc); 3634 } else { /* decode response */ 3635 __le32 *parm; 3636 __u32 parm_len; 3637 __u32 acl_len; 3638 struct smb_com_ntransact_rsp *pSMBr; 3639 char *pdata; 3640 3641 /* validate_nttransact */ 3642 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm, 3643 &pdata, &parm_len, pbuflen); 3644 if (rc) 3645 goto qsec_out; 3646 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base; 3647 3648 cifs_dbg(FYI, "smb %p parm %p data %p\n", 3649 pSMBr, parm, *acl_inf); 3650 3651 if (le32_to_cpu(pSMBr->ParameterCount) != 4) { 3652 rc = -EIO; /* bad smb */ 3653 *pbuflen = 0; 3654 goto qsec_out; 3655 } 3656 3657 /* BB check that data area is minimum length and as big as acl_len */ 3658 3659 acl_len = le32_to_cpu(*parm); 3660 if (acl_len != *pbuflen) { 3661 cifs_dbg(VFS, "acl length %d does not match %d\n", 3662 acl_len, *pbuflen); 3663 if (*pbuflen > acl_len) 3664 *pbuflen = acl_len; 3665 } 3666 3667 /* check if buffer is big enough for the acl 3668 header followed by the smallest SID */ 3669 if ((*pbuflen < sizeof(struct smb_ntsd) + 8) || 3670 (*pbuflen >= 64 * 1024)) { 3671 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen); 3672 rc = -EINVAL; 3673 *pbuflen = 0; 3674 } else { 3675 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL); 3676 if (*acl_inf == NULL) { 3677 *pbuflen = 0; 3678 rc = -ENOMEM; 3679 } 3680 } 3681 } 3682 qsec_out: 3683 free_rsp_buf(buf_type, rsp_iov.iov_base); 3684 return rc; 3685 } 3686 3687 int 3688 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, 3689 struct smb_ntsd *pntsd, __u32 acllen, int aclflag) 3690 { 3691 __u16 byte_count, param_count, data_count, param_offset, data_offset; 3692 int rc = 0; 3693 int bytes_returned = 0; 3694 SET_SEC_DESC_REQ *pSMB = NULL; 3695 void *pSMBr; 3696 3697 setCifsAclRetry: 3698 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr); 3699 if (rc) 3700 return rc; 3701 3702 pSMB->MaxSetupCount = 0; 3703 pSMB->Reserved = 0; 3704 3705 param_count = 8; 3706 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4; 3707 data_count = acllen; 3708 data_offset = param_offset + param_count; 3709 byte_count = 3 /* pad */ + param_count; 3710 3711 pSMB->DataCount = cpu_to_le32(data_count); 3712 pSMB->TotalDataCount = pSMB->DataCount; 3713 pSMB->MaxParameterCount = cpu_to_le32(4); 3714 pSMB->MaxDataCount = cpu_to_le32(16384); 3715 pSMB->ParameterCount = cpu_to_le32(param_count); 3716 pSMB->ParameterOffset = cpu_to_le32(param_offset); 3717 pSMB->TotalParameterCount = pSMB->ParameterCount; 3718 pSMB->DataOffset = cpu_to_le32(data_offset); 3719 pSMB->SetupCount = 0; 3720 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC); 3721 pSMB->ByteCount = cpu_to_le16(byte_count+data_count); 3722 3723 pSMB->Fid = fid; /* file handle always le */ 3724 pSMB->Reserved2 = 0; 3725 pSMB->AclFlags = cpu_to_le32(aclflag); 3726 3727 if (pntsd && acllen) { 3728 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) + 3729 data_offset, pntsd, acllen); 3730 inc_rfc1001_len(pSMB, byte_count + data_count); 3731 } else 3732 inc_rfc1001_len(pSMB, byte_count); 3733 3734 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3735 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3736 3737 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n", 3738 bytes_returned, rc); 3739 if (rc) 3740 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc); 3741 cifs_buf_release(pSMB); 3742 3743 if (rc == -EAGAIN) 3744 goto setCifsAclRetry; 3745 3746 return (rc); 3747 } 3748 3749 3750 /* Legacy Query Path Information call for lookup to old servers such 3751 as Win9x/WinME */ 3752 int 3753 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, 3754 const char *search_name, FILE_ALL_INFO *data, 3755 const struct nls_table *nls_codepage, int remap) 3756 { 3757 QUERY_INFORMATION_REQ *pSMB; 3758 QUERY_INFORMATION_RSP *pSMBr; 3759 int rc = 0; 3760 int bytes_returned; 3761 int name_len; 3762 3763 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name); 3764 QInfRetry: 3765 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, 3766 (void **) &pSMBr); 3767 if (rc) 3768 return rc; 3769 3770 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3771 name_len = 3772 cifsConvertToUTF16((__le16 *) pSMB->FileName, 3773 search_name, PATH_MAX, nls_codepage, 3774 remap); 3775 name_len++; /* trailing null */ 3776 name_len *= 2; 3777 } else { 3778 name_len = copy_path_name(pSMB->FileName, search_name); 3779 } 3780 pSMB->BufferFormat = 0x04; 3781 name_len++; /* account for buffer type byte */ 3782 inc_rfc1001_len(pSMB, (__u16)name_len); 3783 pSMB->ByteCount = cpu_to_le16(name_len); 3784 3785 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3786 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3787 if (rc) { 3788 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc); 3789 } else if (data) { 3790 struct timespec64 ts; 3791 __u32 time = le32_to_cpu(pSMBr->last_write_time); 3792 3793 /* decode response */ 3794 /* BB FIXME - add time zone adjustment BB */ 3795 memset(data, 0, sizeof(FILE_ALL_INFO)); 3796 ts.tv_nsec = 0; 3797 ts.tv_sec = time; 3798 /* decode time fields */ 3799 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts)); 3800 data->LastWriteTime = data->ChangeTime; 3801 data->LastAccessTime = 0; 3802 data->AllocationSize = 3803 cpu_to_le64(le32_to_cpu(pSMBr->size)); 3804 data->EndOfFile = data->AllocationSize; 3805 data->Attributes = 3806 cpu_to_le32(le16_to_cpu(pSMBr->attr)); 3807 } else 3808 rc = -EIO; /* bad buffer passed in */ 3809 3810 cifs_buf_release(pSMB); 3811 3812 if (rc == -EAGAIN) 3813 goto QInfRetry; 3814 3815 return rc; 3816 } 3817 3818 int 3819 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 3820 u16 netfid, FILE_ALL_INFO *pFindData) 3821 { 3822 struct smb_t2_qfi_req *pSMB = NULL; 3823 struct smb_t2_qfi_rsp *pSMBr = NULL; 3824 int rc = 0; 3825 int bytes_returned; 3826 __u16 params, byte_count; 3827 3828 QFileInfoRetry: 3829 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3830 (void **) &pSMBr); 3831 if (rc) 3832 return rc; 3833 3834 params = 2 /* level */ + 2 /* fid */; 3835 pSMB->t2.TotalDataCount = 0; 3836 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3837 /* BB find exact max data count below from sess structure BB */ 3838 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 3839 pSMB->t2.MaxSetupCount = 0; 3840 pSMB->t2.Reserved = 0; 3841 pSMB->t2.Flags = 0; 3842 pSMB->t2.Timeout = 0; 3843 pSMB->t2.Reserved2 = 0; 3844 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3845 Fid) - 4); 3846 pSMB->t2.DataCount = 0; 3847 pSMB->t2.DataOffset = 0; 3848 pSMB->t2.SetupCount = 1; 3849 pSMB->t2.Reserved3 = 0; 3850 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3851 byte_count = params + 1 /* pad */ ; 3852 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3853 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3854 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3855 pSMB->Pad = 0; 3856 pSMB->Fid = netfid; 3857 inc_rfc1001_len(pSMB, byte_count); 3858 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3859 3860 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3861 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3862 if (rc) { 3863 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc); 3864 } else { /* decode response */ 3865 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3866 3867 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3868 rc = -EIO; 3869 else if (get_bcc(&pSMBr->hdr) < 40) 3870 rc = -EIO; /* bad smb */ 3871 else if (pFindData) { 3872 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3873 memcpy((char *) pFindData, 3874 (char *) &pSMBr->hdr.Protocol + 3875 data_offset, sizeof(FILE_ALL_INFO)); 3876 } else 3877 rc = -ENOMEM; 3878 } 3879 cifs_buf_release(pSMB); 3880 if (rc == -EAGAIN) 3881 goto QFileInfoRetry; 3882 3883 return rc; 3884 } 3885 3886 int 3887 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 3888 const char *search_name, FILE_ALL_INFO *data, 3889 int legacy /* old style infolevel */, 3890 const struct nls_table *nls_codepage, int remap) 3891 { 3892 /* level 263 SMB_QUERY_FILE_ALL_INFO */ 3893 TRANSACTION2_QPI_REQ *pSMB = NULL; 3894 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3895 int rc = 0; 3896 int bytes_returned; 3897 int name_len; 3898 __u16 params, byte_count; 3899 3900 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */ 3901 QPathInfoRetry: 3902 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3903 (void **) &pSMBr); 3904 if (rc) 3905 return rc; 3906 3907 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3908 name_len = 3909 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name, 3910 PATH_MAX, nls_codepage, remap); 3911 name_len++; /* trailing null */ 3912 name_len *= 2; 3913 } else { 3914 name_len = copy_path_name(pSMB->FileName, search_name); 3915 } 3916 3917 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 3918 pSMB->TotalDataCount = 0; 3919 pSMB->MaxParameterCount = cpu_to_le16(2); 3920 /* BB find exact max SMB PDU from sess structure BB */ 3921 pSMB->MaxDataCount = cpu_to_le16(4000); 3922 pSMB->MaxSetupCount = 0; 3923 pSMB->Reserved = 0; 3924 pSMB->Flags = 0; 3925 pSMB->Timeout = 0; 3926 pSMB->Reserved2 = 0; 3927 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3928 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 3929 pSMB->DataCount = 0; 3930 pSMB->DataOffset = 0; 3931 pSMB->SetupCount = 1; 3932 pSMB->Reserved3 = 0; 3933 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3934 byte_count = params + 1 /* pad */ ; 3935 pSMB->TotalParameterCount = cpu_to_le16(params); 3936 pSMB->ParameterCount = pSMB->TotalParameterCount; 3937 if (legacy) 3938 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD); 3939 else 3940 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3941 pSMB->Reserved4 = 0; 3942 inc_rfc1001_len(pSMB, byte_count); 3943 pSMB->ByteCount = cpu_to_le16(byte_count); 3944 3945 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3946 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3947 if (rc) { 3948 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc); 3949 } else { /* decode response */ 3950 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3951 3952 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3953 rc = -EIO; 3954 else if (!legacy && get_bcc(&pSMBr->hdr) < 40) 3955 rc = -EIO; /* bad smb */ 3956 else if (legacy && get_bcc(&pSMBr->hdr) < 24) 3957 rc = -EIO; /* 24 or 26 expected but we do not read 3958 last field */ 3959 else if (data) { 3960 int size; 3961 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3962 3963 /* 3964 * On legacy responses we do not read the last field, 3965 * EAsize, fortunately since it varies by subdialect and 3966 * also note it differs on Set vs Get, ie two bytes or 4 3967 * bytes depending but we don't care here. 3968 */ 3969 if (legacy) 3970 size = sizeof(FILE_INFO_STANDARD); 3971 else 3972 size = sizeof(FILE_ALL_INFO); 3973 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol + 3974 data_offset, size); 3975 } else 3976 rc = -ENOMEM; 3977 } 3978 cifs_buf_release(pSMB); 3979 if (rc == -EAGAIN) 3980 goto QPathInfoRetry; 3981 3982 return rc; 3983 } 3984 3985 int 3986 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 3987 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData) 3988 { 3989 struct smb_t2_qfi_req *pSMB = NULL; 3990 struct smb_t2_qfi_rsp *pSMBr = NULL; 3991 int rc = 0; 3992 int bytes_returned; 3993 __u16 params, byte_count; 3994 3995 UnixQFileInfoRetry: 3996 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3997 (void **) &pSMBr); 3998 if (rc) 3999 return rc; 4000 4001 params = 2 /* level */ + 2 /* fid */; 4002 pSMB->t2.TotalDataCount = 0; 4003 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 4004 /* BB find exact max data count below from sess structure BB */ 4005 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 4006 pSMB->t2.MaxSetupCount = 0; 4007 pSMB->t2.Reserved = 0; 4008 pSMB->t2.Flags = 0; 4009 pSMB->t2.Timeout = 0; 4010 pSMB->t2.Reserved2 = 0; 4011 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 4012 Fid) - 4); 4013 pSMB->t2.DataCount = 0; 4014 pSMB->t2.DataOffset = 0; 4015 pSMB->t2.SetupCount = 1; 4016 pSMB->t2.Reserved3 = 0; 4017 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 4018 byte_count = params + 1 /* pad */ ; 4019 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 4020 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 4021 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 4022 pSMB->Pad = 0; 4023 pSMB->Fid = netfid; 4024 inc_rfc1001_len(pSMB, byte_count); 4025 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 4026 4027 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4028 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4029 if (rc) { 4030 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc); 4031 } else { /* decode response */ 4032 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4033 4034 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { 4035 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n"); 4036 rc = -EIO; /* bad smb */ 4037 } else { 4038 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4039 memcpy((char *) pFindData, 4040 (char *) &pSMBr->hdr.Protocol + 4041 data_offset, 4042 sizeof(FILE_UNIX_BASIC_INFO)); 4043 } 4044 } 4045 4046 cifs_buf_release(pSMB); 4047 if (rc == -EAGAIN) 4048 goto UnixQFileInfoRetry; 4049 4050 return rc; 4051 } 4052 4053 int 4054 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 4055 const unsigned char *searchName, 4056 FILE_UNIX_BASIC_INFO *pFindData, 4057 const struct nls_table *nls_codepage, int remap) 4058 { 4059 /* SMB_QUERY_FILE_UNIX_BASIC */ 4060 TRANSACTION2_QPI_REQ *pSMB = NULL; 4061 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4062 int rc = 0; 4063 int bytes_returned = 0; 4064 int name_len; 4065 __u16 params, byte_count; 4066 4067 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName); 4068 UnixQPathInfoRetry: 4069 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4070 (void **) &pSMBr); 4071 if (rc) 4072 return rc; 4073 4074 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4075 name_len = 4076 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 4077 PATH_MAX, nls_codepage, remap); 4078 name_len++; /* trailing null */ 4079 name_len *= 2; 4080 } else { 4081 name_len = copy_path_name(pSMB->FileName, searchName); 4082 } 4083 4084 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 4085 pSMB->TotalDataCount = 0; 4086 pSMB->MaxParameterCount = cpu_to_le16(2); 4087 /* BB find exact max SMB PDU from sess structure BB */ 4088 pSMB->MaxDataCount = cpu_to_le16(4000); 4089 pSMB->MaxSetupCount = 0; 4090 pSMB->Reserved = 0; 4091 pSMB->Flags = 0; 4092 pSMB->Timeout = 0; 4093 pSMB->Reserved2 = 0; 4094 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4095 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 4096 pSMB->DataCount = 0; 4097 pSMB->DataOffset = 0; 4098 pSMB->SetupCount = 1; 4099 pSMB->Reserved3 = 0; 4100 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4101 byte_count = params + 1 /* pad */ ; 4102 pSMB->TotalParameterCount = cpu_to_le16(params); 4103 pSMB->ParameterCount = pSMB->TotalParameterCount; 4104 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 4105 pSMB->Reserved4 = 0; 4106 inc_rfc1001_len(pSMB, byte_count); 4107 pSMB->ByteCount = cpu_to_le16(byte_count); 4108 4109 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4110 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4111 if (rc) { 4112 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc); 4113 } else { /* decode response */ 4114 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4115 4116 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { 4117 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n"); 4118 rc = -EIO; /* bad smb */ 4119 } else { 4120 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4121 memcpy((char *) pFindData, 4122 (char *) &pSMBr->hdr.Protocol + 4123 data_offset, 4124 sizeof(FILE_UNIX_BASIC_INFO)); 4125 } 4126 } 4127 cifs_buf_release(pSMB); 4128 if (rc == -EAGAIN) 4129 goto UnixQPathInfoRetry; 4130 4131 return rc; 4132 } 4133 4134 /* xid, tcon, searchName and codepage are input parms, rest are returned */ 4135 int 4136 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon, 4137 const char *searchName, struct cifs_sb_info *cifs_sb, 4138 __u16 *pnetfid, __u16 search_flags, 4139 struct cifs_search_info *psrch_inf, bool msearch) 4140 { 4141 /* level 257 SMB_ */ 4142 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 4143 TRANSACTION2_FFIRST_RSP *pSMBr = NULL; 4144 T2_FFIRST_RSP_PARMS *parms; 4145 struct nls_table *nls_codepage; 4146 unsigned int lnoff; 4147 __u16 params, byte_count; 4148 int bytes_returned = 0; 4149 int name_len, remap; 4150 int rc = 0; 4151 4152 cifs_dbg(FYI, "In FindFirst for %s\n", searchName); 4153 4154 findFirstRetry: 4155 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4156 (void **) &pSMBr); 4157 if (rc) 4158 return rc; 4159 4160 nls_codepage = cifs_sb->local_nls; 4161 remap = cifs_remap(cifs_sb); 4162 4163 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4164 name_len = 4165 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 4166 PATH_MAX, nls_codepage, remap); 4167 /* We can not add the asterisk earlier in case 4168 it got remapped to 0xF03A as if it were part of the 4169 directory name instead of a wildcard */ 4170 name_len *= 2; 4171 if (msearch) { 4172 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb); 4173 pSMB->FileName[name_len+1] = 0; 4174 pSMB->FileName[name_len+2] = '*'; 4175 pSMB->FileName[name_len+3] = 0; 4176 name_len += 4; /* now the trailing null */ 4177 /* null terminate just in case */ 4178 pSMB->FileName[name_len] = 0; 4179 pSMB->FileName[name_len+1] = 0; 4180 name_len += 2; 4181 } else if (!searchName[0]) { 4182 pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb); 4183 pSMB->FileName[1] = 0; 4184 pSMB->FileName[2] = 0; 4185 pSMB->FileName[3] = 0; 4186 name_len = 4; 4187 } 4188 } else { 4189 name_len = copy_path_name(pSMB->FileName, searchName); 4190 if (msearch) { 4191 if (WARN_ON_ONCE(name_len > PATH_MAX-2)) 4192 name_len = PATH_MAX-2; 4193 /* overwrite nul byte */ 4194 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb); 4195 pSMB->FileName[name_len] = '*'; 4196 pSMB->FileName[name_len+1] = 0; 4197 name_len += 2; 4198 } else if (!searchName[0]) { 4199 pSMB->FileName[0] = CIFS_DIR_SEP(cifs_sb); 4200 pSMB->FileName[1] = 0; 4201 name_len = 2; 4202 } 4203 } 4204 4205 params = 12 + name_len /* includes null */ ; 4206 pSMB->TotalDataCount = 0; /* no EAs */ 4207 pSMB->MaxParameterCount = cpu_to_le16(10); 4208 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4209 pSMB->MaxSetupCount = 0; 4210 pSMB->Reserved = 0; 4211 pSMB->Flags = 0; 4212 pSMB->Timeout = 0; 4213 pSMB->Reserved2 = 0; 4214 byte_count = params + 1 /* pad */ ; 4215 pSMB->TotalParameterCount = cpu_to_le16(params); 4216 pSMB->ParameterCount = pSMB->TotalParameterCount; 4217 pSMB->ParameterOffset = cpu_to_le16( 4218 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) 4219 - 4); 4220 pSMB->DataCount = 0; 4221 pSMB->DataOffset = 0; 4222 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */ 4223 pSMB->Reserved3 = 0; 4224 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST); 4225 pSMB->SearchAttributes = 4226 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 4227 ATTR_DIRECTORY); 4228 pSMB->SearchCount = cpu_to_le16(msearch ? CIFSMaxBufSize/sizeof(FILE_UNIX_INFO) : 1); 4229 pSMB->SearchFlags = cpu_to_le16(search_flags); 4230 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4231 4232 /* BB what should we set StorageType to? Does it matter? BB */ 4233 pSMB->SearchStorageType = 0; 4234 inc_rfc1001_len(pSMB, byte_count); 4235 pSMB->ByteCount = cpu_to_le16(byte_count); 4236 4237 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4238 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4239 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst); 4240 4241 if (rc) { 4242 /* 4243 * BB: add logic to retry regular search if Unix search rejected 4244 * unexpectedly by server. 4245 */ 4246 /* BB: add code to handle unsupported level rc */ 4247 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc); 4248 cifs_buf_release(pSMB); 4249 /* 4250 * BB: eventually could optimize out free and realloc of buf for 4251 * this case. 4252 */ 4253 if (rc == -EAGAIN) 4254 goto findFirstRetry; 4255 return rc; 4256 } 4257 /* decode response */ 4258 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4259 if (rc) { 4260 cifs_buf_release(pSMB); 4261 return rc; 4262 } 4263 4264 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE); 4265 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 4266 psrch_inf->smallBuf = false; 4267 psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol + 4268 le16_to_cpu(pSMBr->t2.DataOffset); 4269 4270 parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol + 4271 le16_to_cpu(pSMBr->t2.ParameterOffset)); 4272 psrch_inf->endOfSearch = !!parms->EndofSearch; 4273 4274 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 4275 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + 4276 psrch_inf->entries_in_buffer; 4277 lnoff = le16_to_cpu(parms->LastNameOffset); 4278 if (CIFSMaxBufSize < lnoff) { 4279 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4280 psrch_inf->last_entry = NULL; 4281 } else { 4282 psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff; 4283 if (pnetfid) 4284 *pnetfid = parms->SearchHandle; 4285 } 4286 return 0; 4287 } 4288 4289 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon, 4290 __u16 searchHandle, __u16 search_flags, 4291 struct cifs_search_info *psrch_inf) 4292 { 4293 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 4294 TRANSACTION2_FNEXT_RSP *pSMBr = NULL; 4295 T2_FNEXT_RSP_PARMS *parms; 4296 unsigned int name_len; 4297 unsigned int lnoff; 4298 __u16 params, byte_count; 4299 char *response_data; 4300 int bytes_returned; 4301 int rc = 0; 4302 4303 cifs_dbg(FYI, "In FindNext\n"); 4304 4305 if (psrch_inf->endOfSearch) 4306 return -ENOENT; 4307 4308 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4309 (void **) &pSMBr); 4310 if (rc) 4311 return rc; 4312 4313 params = 14; /* includes 2 bytes of null string, converted to LE below*/ 4314 byte_count = 0; 4315 pSMB->TotalDataCount = 0; /* no EAs */ 4316 pSMB->MaxParameterCount = cpu_to_le16(8); 4317 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4318 pSMB->MaxSetupCount = 0; 4319 pSMB->Reserved = 0; 4320 pSMB->Flags = 0; 4321 pSMB->Timeout = 0; 4322 pSMB->Reserved2 = 0; 4323 pSMB->ParameterOffset = cpu_to_le16( 4324 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4); 4325 pSMB->DataCount = 0; 4326 pSMB->DataOffset = 0; 4327 pSMB->SetupCount = 1; 4328 pSMB->Reserved3 = 0; 4329 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); 4330 pSMB->SearchHandle = searchHandle; /* always kept as le */ 4331 pSMB->SearchCount = 4332 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); 4333 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4334 pSMB->ResumeKey = psrch_inf->resume_key; 4335 pSMB->SearchFlags = cpu_to_le16(search_flags); 4336 4337 name_len = psrch_inf->resume_name_len; 4338 params += name_len; 4339 if (name_len < PATH_MAX) { 4340 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len); 4341 byte_count += name_len; 4342 /* 14 byte parm len above enough for 2 byte null terminator */ 4343 pSMB->ResumeFileName[name_len] = 0; 4344 pSMB->ResumeFileName[name_len+1] = 0; 4345 } else { 4346 cifs_buf_release(pSMB); 4347 return -EINVAL; 4348 } 4349 byte_count = params + 1 /* pad */ ; 4350 pSMB->TotalParameterCount = cpu_to_le16(params); 4351 pSMB->ParameterCount = pSMB->TotalParameterCount; 4352 inc_rfc1001_len(pSMB, byte_count); 4353 pSMB->ByteCount = cpu_to_le16(byte_count); 4354 4355 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4356 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4357 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext); 4358 4359 if (rc) { 4360 cifs_buf_release(pSMB); 4361 if (rc == -EBADF) { 4362 psrch_inf->endOfSearch = true; 4363 rc = 0; /* search probably was closed at end of search*/ 4364 } else { 4365 cifs_dbg(FYI, "FindNext returned = %d\n", rc); 4366 } 4367 return rc; 4368 } 4369 4370 /* decode response */ 4371 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4372 if (rc) { 4373 cifs_buf_release(pSMB); 4374 return rc; 4375 } 4376 /* BB fixme add lock for file (srch_info) struct here */ 4377 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE); 4378 response_data = (char *)&pSMBr->hdr.Protocol + 4379 le16_to_cpu(pSMBr->t2.ParameterOffset); 4380 parms = (T2_FNEXT_RSP_PARMS *)response_data; 4381 response_data = (char *)&pSMBr->hdr.Protocol + 4382 le16_to_cpu(pSMBr->t2.DataOffset); 4383 4384 if (psrch_inf->smallBuf) 4385 cifs_small_buf_release(psrch_inf->ntwrk_buf_start); 4386 else 4387 cifs_buf_release(psrch_inf->ntwrk_buf_start); 4388 4389 psrch_inf->srch_entries_start = response_data; 4390 psrch_inf->ntwrk_buf_start = (char *)pSMB; 4391 psrch_inf->smallBuf = false; 4392 psrch_inf->endOfSearch = !!parms->EndofSearch; 4393 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 4394 psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer; 4395 lnoff = le16_to_cpu(parms->LastNameOffset); 4396 if (CIFSMaxBufSize < lnoff) { 4397 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4398 psrch_inf->last_entry = NULL; 4399 } else { 4400 psrch_inf->last_entry = 4401 psrch_inf->srch_entries_start + lnoff; 4402 } 4403 /* BB fixme add unlock here */ 4404 4405 /* 4406 * BB: On error, should we leave previous search buf 4407 * (and count and last entry fields) intact or free the previous one? 4408 * 4409 * Note: On -EAGAIN error only caller can retry on handle based calls 4410 * since file handle passed in no longer valid. 4411 */ 4412 return 0; 4413 } 4414 4415 int 4416 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon, 4417 const __u16 searchHandle) 4418 { 4419 int rc = 0; 4420 FINDCLOSE_REQ *pSMB = NULL; 4421 4422 cifs_dbg(FYI, "In CIFSSMBFindClose\n"); 4423 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); 4424 4425 /* no sense returning error if session restarted 4426 as file handle has been closed */ 4427 if (rc == -EAGAIN) 4428 return 0; 4429 if (rc) 4430 return rc; 4431 4432 pSMB->FileID = searchHandle; 4433 pSMB->ByteCount = 0; 4434 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 4435 cifs_small_buf_release(pSMB); 4436 if (rc) 4437 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc); 4438 4439 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose); 4440 4441 /* Since session is dead, search handle closed on server already */ 4442 if (rc == -EAGAIN) 4443 rc = 0; 4444 4445 return rc; 4446 } 4447 4448 int 4449 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon, 4450 const char *search_name, __u64 *inode_number, 4451 const struct nls_table *nls_codepage, int remap) 4452 { 4453 int rc = 0; 4454 TRANSACTION2_QPI_REQ *pSMB = NULL; 4455 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4456 int name_len, bytes_returned; 4457 __u16 params, byte_count; 4458 4459 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name); 4460 if (tcon == NULL) 4461 return -ENODEV; 4462 4463 GetInodeNumberRetry: 4464 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4465 (void **) &pSMBr); 4466 if (rc) 4467 return rc; 4468 4469 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4470 name_len = 4471 cifsConvertToUTF16((__le16 *) pSMB->FileName, 4472 search_name, PATH_MAX, nls_codepage, 4473 remap); 4474 name_len++; /* trailing null */ 4475 name_len *= 2; 4476 } else { 4477 name_len = copy_path_name(pSMB->FileName, search_name); 4478 } 4479 4480 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 4481 pSMB->TotalDataCount = 0; 4482 pSMB->MaxParameterCount = cpu_to_le16(2); 4483 /* BB find exact max data count below from sess structure BB */ 4484 pSMB->MaxDataCount = cpu_to_le16(4000); 4485 pSMB->MaxSetupCount = 0; 4486 pSMB->Reserved = 0; 4487 pSMB->Flags = 0; 4488 pSMB->Timeout = 0; 4489 pSMB->Reserved2 = 0; 4490 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4491 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 4492 pSMB->DataCount = 0; 4493 pSMB->DataOffset = 0; 4494 pSMB->SetupCount = 1; 4495 pSMB->Reserved3 = 0; 4496 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4497 byte_count = params + 1 /* pad */ ; 4498 pSMB->TotalParameterCount = cpu_to_le16(params); 4499 pSMB->ParameterCount = pSMB->TotalParameterCount; 4500 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO); 4501 pSMB->Reserved4 = 0; 4502 inc_rfc1001_len(pSMB, byte_count); 4503 pSMB->ByteCount = cpu_to_le16(byte_count); 4504 4505 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4506 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4507 if (rc) { 4508 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc); 4509 } else { 4510 /* decode response */ 4511 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4512 /* BB also check enough total bytes returned */ 4513 if (rc || get_bcc(&pSMBr->hdr) < 2) 4514 /* If rc should we check for EOPNOSUPP and 4515 disable the srvino flag? or in caller? */ 4516 rc = -EIO; /* bad smb */ 4517 else { 4518 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4519 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 4520 struct file_internal_info *pfinfo; 4521 /* BB Do we need a cast or hash here ? */ 4522 if (count < 8) { 4523 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n"); 4524 rc = -EIO; 4525 goto GetInodeNumOut; 4526 } 4527 pfinfo = (struct file_internal_info *) 4528 (data_offset + (char *) &pSMBr->hdr.Protocol); 4529 *inode_number = le64_to_cpu(pfinfo->UniqueId); 4530 } 4531 } 4532 GetInodeNumOut: 4533 cifs_buf_release(pSMB); 4534 if (rc == -EAGAIN) 4535 goto GetInodeNumberRetry; 4536 return rc; 4537 } 4538 4539 int 4540 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses, 4541 const char *search_name, struct dfs_info3_param **target_nodes, 4542 unsigned int *num_of_nodes, 4543 const struct nls_table *nls_codepage, int remap) 4544 { 4545 /* TRANS2_GET_DFS_REFERRAL */ 4546 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; 4547 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL; 4548 int rc = 0; 4549 int bytes_returned; 4550 int name_len; 4551 __u16 params, byte_count; 4552 *num_of_nodes = 0; 4553 *target_nodes = NULL; 4554 4555 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name); 4556 if (ses == NULL || ses->tcon_ipc == NULL) 4557 return -ENODEV; 4558 4559 getDFSRetry: 4560 /* 4561 * Use smb_init_no_reconnect() instead of smb_init() as 4562 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus 4563 * causing an infinite recursion. 4564 */ 4565 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, 4566 (void **)&pSMB, (void **)&pSMBr); 4567 if (rc) 4568 return rc; 4569 4570 /* server pointer checked in called function, 4571 but should never be null here anyway */ 4572 pSMB->hdr.Mid = get_next_mid(ses->server); 4573 pSMB->hdr.Tid = ses->tcon_ipc->tid; 4574 pSMB->hdr.Uid = ses->Suid; 4575 if (ses->capabilities & CAP_STATUS32) 4576 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; 4577 if (ses->capabilities & CAP_DFS) 4578 pSMB->hdr.Flags2 |= SMBFLG2_DFS; 4579 4580 if (ses->capabilities & CAP_UNICODE) { 4581 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 4582 name_len = 4583 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName, 4584 search_name, PATH_MAX, nls_codepage, 4585 remap); 4586 name_len++; /* trailing null */ 4587 name_len *= 2; 4588 } else { /* BB improve the check for buffer overruns BB */ 4589 name_len = copy_path_name(pSMB->RequestFileName, search_name); 4590 } 4591 4592 if (ses->server->sign) 4593 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 4594 4595 pSMB->hdr.Uid = ses->Suid; 4596 4597 params = 2 /* level */ + name_len /*includes null */ ; 4598 pSMB->TotalDataCount = 0; 4599 pSMB->DataCount = 0; 4600 pSMB->DataOffset = 0; 4601 pSMB->MaxParameterCount = 0; 4602 /* BB find exact max SMB PDU from sess structure BB */ 4603 pSMB->MaxDataCount = cpu_to_le16(4000); 4604 pSMB->MaxSetupCount = 0; 4605 pSMB->Reserved = 0; 4606 pSMB->Flags = 0; 4607 pSMB->Timeout = 0; 4608 pSMB->Reserved2 = 0; 4609 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4610 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4); 4611 pSMB->SetupCount = 1; 4612 pSMB->Reserved3 = 0; 4613 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL); 4614 byte_count = params + 3 /* pad */ ; 4615 pSMB->ParameterCount = cpu_to_le16(params); 4616 pSMB->TotalParameterCount = pSMB->ParameterCount; 4617 pSMB->MaxReferralLevel = cpu_to_le16(3); 4618 inc_rfc1001_len(pSMB, byte_count); 4619 pSMB->ByteCount = cpu_to_le16(byte_count); 4620 4621 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 4622 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4623 if (rc) { 4624 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc); 4625 goto GetDFSRefExit; 4626 } 4627 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4628 4629 /* BB Also check if enough total bytes returned? */ 4630 if (rc || get_bcc(&pSMBr->hdr) < 17) { 4631 rc = -EIO; /* bad smb */ 4632 goto GetDFSRefExit; 4633 } 4634 4635 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n", 4636 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset)); 4637 4638 /* parse returned result into more usable form */ 4639 rc = parse_dfs_referrals(&pSMBr->dfs_data, 4640 le16_to_cpu(pSMBr->t2.DataCount), 4641 num_of_nodes, target_nodes, nls_codepage, 4642 remap, search_name, 4643 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0); 4644 4645 GetDFSRefExit: 4646 cifs_buf_release(pSMB); 4647 4648 if (rc == -EAGAIN) 4649 goto getDFSRetry; 4650 4651 return rc; 4652 } 4653 4654 /* Query File System Info such as free space to old servers such as Win 9x */ 4655 int 4656 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 4657 struct kstatfs *FSData) 4658 { 4659 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */ 4660 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4661 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4662 FILE_SYSTEM_ALLOC_INFO *response_data; 4663 int rc = 0; 4664 int bytes_returned = 0; 4665 __u16 params, byte_count; 4666 4667 cifs_dbg(FYI, "OldQFSInfo\n"); 4668 oldQFSInfoRetry: 4669 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4670 (void **) &pSMBr); 4671 if (rc) 4672 return rc; 4673 4674 params = 2; /* level */ 4675 pSMB->TotalDataCount = 0; 4676 pSMB->MaxParameterCount = cpu_to_le16(2); 4677 pSMB->MaxDataCount = cpu_to_le16(1000); 4678 pSMB->MaxSetupCount = 0; 4679 pSMB->Reserved = 0; 4680 pSMB->Flags = 0; 4681 pSMB->Timeout = 0; 4682 pSMB->Reserved2 = 0; 4683 byte_count = params + 1 /* pad */ ; 4684 pSMB->TotalParameterCount = cpu_to_le16(params); 4685 pSMB->ParameterCount = pSMB->TotalParameterCount; 4686 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4687 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4688 pSMB->DataCount = 0; 4689 pSMB->DataOffset = 0; 4690 pSMB->SetupCount = 1; 4691 pSMB->Reserved3 = 0; 4692 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4693 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION); 4694 inc_rfc1001_len(pSMB, byte_count); 4695 pSMB->ByteCount = cpu_to_le16(byte_count); 4696 4697 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4698 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4699 if (rc) { 4700 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 4701 } else { /* decode response */ 4702 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4703 4704 if (rc || get_bcc(&pSMBr->hdr) < 18) 4705 rc = -EIO; /* bad smb */ 4706 else { 4707 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4708 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n", 4709 get_bcc(&pSMBr->hdr), data_offset); 4710 4711 response_data = (FILE_SYSTEM_ALLOC_INFO *) 4712 (((char *) &pSMBr->hdr.Protocol) + data_offset); 4713 FSData->f_bsize = 4714 le16_to_cpu(response_data->BytesPerSector) * 4715 le32_to_cpu(response_data-> 4716 SectorsPerAllocationUnit); 4717 /* 4718 * much prefer larger but if server doesn't report 4719 * a valid size than 4K is a reasonable minimum 4720 */ 4721 if (FSData->f_bsize < 512) 4722 FSData->f_bsize = 4096; 4723 4724 FSData->f_blocks = 4725 le32_to_cpu(response_data->TotalAllocationUnits); 4726 FSData->f_bfree = FSData->f_bavail = 4727 le32_to_cpu(response_data->FreeAllocationUnits); 4728 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 4729 (unsigned long long)FSData->f_blocks, 4730 (unsigned long long)FSData->f_bfree, 4731 FSData->f_bsize); 4732 } 4733 } 4734 cifs_buf_release(pSMB); 4735 4736 if (rc == -EAGAIN) 4737 goto oldQFSInfoRetry; 4738 4739 return rc; 4740 } 4741 4742 int 4743 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 4744 struct kstatfs *FSData) 4745 { 4746 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ 4747 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4748 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4749 FILE_SYSTEM_INFO *response_data; 4750 int rc = 0; 4751 int bytes_returned = 0; 4752 __u16 params, byte_count; 4753 4754 cifs_dbg(FYI, "In QFSInfo\n"); 4755 QFSInfoRetry: 4756 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4757 (void **) &pSMBr); 4758 if (rc) 4759 return rc; 4760 4761 params = 2; /* level */ 4762 pSMB->TotalDataCount = 0; 4763 pSMB->MaxParameterCount = cpu_to_le16(2); 4764 pSMB->MaxDataCount = cpu_to_le16(1000); 4765 pSMB->MaxSetupCount = 0; 4766 pSMB->Reserved = 0; 4767 pSMB->Flags = 0; 4768 pSMB->Timeout = 0; 4769 pSMB->Reserved2 = 0; 4770 byte_count = params + 1 /* pad */ ; 4771 pSMB->TotalParameterCount = cpu_to_le16(params); 4772 pSMB->ParameterCount = pSMB->TotalParameterCount; 4773 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4774 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4775 pSMB->DataCount = 0; 4776 pSMB->DataOffset = 0; 4777 pSMB->SetupCount = 1; 4778 pSMB->Reserved3 = 0; 4779 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4780 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO); 4781 inc_rfc1001_len(pSMB, byte_count); 4782 pSMB->ByteCount = cpu_to_le16(byte_count); 4783 4784 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4785 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4786 if (rc) { 4787 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 4788 } else { /* decode response */ 4789 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4790 4791 if (rc || get_bcc(&pSMBr->hdr) < 24) 4792 rc = -EIO; /* bad smb */ 4793 else { 4794 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4795 4796 response_data = 4797 (FILE_SYSTEM_INFO 4798 *) (((char *) &pSMBr->hdr.Protocol) + 4799 data_offset); 4800 FSData->f_bsize = 4801 le32_to_cpu(response_data->BytesPerSector) * 4802 le32_to_cpu(response_data-> 4803 SectorsPerAllocationUnit); 4804 /* 4805 * much prefer larger but if server doesn't report 4806 * a valid size than 4K is a reasonable minimum 4807 */ 4808 if (FSData->f_bsize < 512) 4809 FSData->f_bsize = 4096; 4810 4811 FSData->f_blocks = 4812 le64_to_cpu(response_data->TotalAllocationUnits); 4813 FSData->f_bfree = FSData->f_bavail = 4814 le64_to_cpu(response_data->FreeAllocationUnits); 4815 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 4816 (unsigned long long)FSData->f_blocks, 4817 (unsigned long long)FSData->f_bfree, 4818 FSData->f_bsize); 4819 } 4820 } 4821 cifs_buf_release(pSMB); 4822 4823 if (rc == -EAGAIN) 4824 goto QFSInfoRetry; 4825 4826 return rc; 4827 } 4828 4829 int 4830 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon) 4831 { 4832 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ 4833 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4834 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4835 FILE_SYSTEM_ATTRIBUTE_INFO *response_data; 4836 int rc = 0; 4837 int bytes_returned = 0; 4838 __u16 params, byte_count; 4839 4840 cifs_dbg(FYI, "In QFSAttributeInfo\n"); 4841 QFSAttributeRetry: 4842 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4843 (void **) &pSMBr); 4844 if (rc) 4845 return rc; 4846 4847 params = 2; /* level */ 4848 pSMB->TotalDataCount = 0; 4849 pSMB->MaxParameterCount = cpu_to_le16(2); 4850 /* BB find exact max SMB PDU from sess structure BB */ 4851 pSMB->MaxDataCount = cpu_to_le16(1000); 4852 pSMB->MaxSetupCount = 0; 4853 pSMB->Reserved = 0; 4854 pSMB->Flags = 0; 4855 pSMB->Timeout = 0; 4856 pSMB->Reserved2 = 0; 4857 byte_count = params + 1 /* pad */ ; 4858 pSMB->TotalParameterCount = cpu_to_le16(params); 4859 pSMB->ParameterCount = pSMB->TotalParameterCount; 4860 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4861 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4862 pSMB->DataCount = 0; 4863 pSMB->DataOffset = 0; 4864 pSMB->SetupCount = 1; 4865 pSMB->Reserved3 = 0; 4866 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4867 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO); 4868 inc_rfc1001_len(pSMB, byte_count); 4869 pSMB->ByteCount = cpu_to_le16(byte_count); 4870 4871 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4872 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4873 if (rc) { 4874 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc); 4875 } else { /* decode response */ 4876 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4877 4878 if (rc || get_bcc(&pSMBr->hdr) < 13) { 4879 /* BB also check if enough bytes returned */ 4880 rc = -EIO; /* bad smb */ 4881 } else { 4882 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4883 response_data = 4884 (FILE_SYSTEM_ATTRIBUTE_INFO 4885 *) (((char *) &pSMBr->hdr.Protocol) + 4886 data_offset); 4887 memcpy(&tcon->fsAttrInfo, response_data, 4888 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)); 4889 } 4890 } 4891 cifs_buf_release(pSMB); 4892 4893 if (rc == -EAGAIN) 4894 goto QFSAttributeRetry; 4895 4896 return rc; 4897 } 4898 4899 int 4900 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon) 4901 { 4902 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ 4903 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4904 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4905 FILE_SYSTEM_DEVICE_INFO *response_data; 4906 int rc = 0; 4907 int bytes_returned = 0; 4908 __u16 params, byte_count; 4909 4910 cifs_dbg(FYI, "In QFSDeviceInfo\n"); 4911 QFSDeviceRetry: 4912 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4913 (void **) &pSMBr); 4914 if (rc) 4915 return rc; 4916 4917 params = 2; /* level */ 4918 pSMB->TotalDataCount = 0; 4919 pSMB->MaxParameterCount = cpu_to_le16(2); 4920 /* BB find exact max SMB PDU from sess structure BB */ 4921 pSMB->MaxDataCount = cpu_to_le16(1000); 4922 pSMB->MaxSetupCount = 0; 4923 pSMB->Reserved = 0; 4924 pSMB->Flags = 0; 4925 pSMB->Timeout = 0; 4926 pSMB->Reserved2 = 0; 4927 byte_count = params + 1 /* pad */ ; 4928 pSMB->TotalParameterCount = cpu_to_le16(params); 4929 pSMB->ParameterCount = pSMB->TotalParameterCount; 4930 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4931 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4932 4933 pSMB->DataCount = 0; 4934 pSMB->DataOffset = 0; 4935 pSMB->SetupCount = 1; 4936 pSMB->Reserved3 = 0; 4937 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4938 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO); 4939 inc_rfc1001_len(pSMB, byte_count); 4940 pSMB->ByteCount = cpu_to_le16(byte_count); 4941 4942 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4943 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4944 if (rc) { 4945 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc); 4946 } else { /* decode response */ 4947 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4948 4949 if (rc || get_bcc(&pSMBr->hdr) < 4950 sizeof(FILE_SYSTEM_DEVICE_INFO)) 4951 rc = -EIO; /* bad smb */ 4952 else { 4953 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4954 response_data = 4955 (FILE_SYSTEM_DEVICE_INFO *) 4956 (((char *) &pSMBr->hdr.Protocol) + 4957 data_offset); 4958 memcpy(&tcon->fsDevInfo, response_data, 4959 sizeof(FILE_SYSTEM_DEVICE_INFO)); 4960 } 4961 } 4962 cifs_buf_release(pSMB); 4963 4964 if (rc == -EAGAIN) 4965 goto QFSDeviceRetry; 4966 4967 return rc; 4968 } 4969 4970 int 4971 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon) 4972 { 4973 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ 4974 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4975 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4976 FILE_SYSTEM_UNIX_INFO *response_data; 4977 int rc = 0; 4978 int bytes_returned = 0; 4979 __u16 params, byte_count; 4980 4981 cifs_dbg(FYI, "In QFSUnixInfo\n"); 4982 QFSUnixRetry: 4983 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 4984 (void **) &pSMB, (void **) &pSMBr); 4985 if (rc) 4986 return rc; 4987 4988 params = 2; /* level */ 4989 pSMB->TotalDataCount = 0; 4990 pSMB->DataCount = 0; 4991 pSMB->DataOffset = 0; 4992 pSMB->MaxParameterCount = cpu_to_le16(2); 4993 /* BB find exact max SMB PDU from sess structure BB */ 4994 pSMB->MaxDataCount = cpu_to_le16(100); 4995 pSMB->MaxSetupCount = 0; 4996 pSMB->Reserved = 0; 4997 pSMB->Flags = 0; 4998 pSMB->Timeout = 0; 4999 pSMB->Reserved2 = 0; 5000 byte_count = params + 1 /* pad */ ; 5001 pSMB->ParameterCount = cpu_to_le16(params); 5002 pSMB->TotalParameterCount = pSMB->ParameterCount; 5003 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 5004 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 5005 pSMB->SetupCount = 1; 5006 pSMB->Reserved3 = 0; 5007 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5008 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO); 5009 inc_rfc1001_len(pSMB, byte_count); 5010 pSMB->ByteCount = cpu_to_le16(byte_count); 5011 5012 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5013 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5014 if (rc) { 5015 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc); 5016 } else { /* decode response */ 5017 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5018 5019 if (rc || get_bcc(&pSMBr->hdr) < 13) { 5020 rc = -EIO; /* bad smb */ 5021 } else { 5022 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5023 response_data = 5024 (FILE_SYSTEM_UNIX_INFO 5025 *) (((char *) &pSMBr->hdr.Protocol) + 5026 data_offset); 5027 memcpy(&tcon->fsUnixInfo, response_data, 5028 sizeof(FILE_SYSTEM_UNIX_INFO)); 5029 } 5030 } 5031 cifs_buf_release(pSMB); 5032 5033 if (rc == -EAGAIN) 5034 goto QFSUnixRetry; 5035 5036 5037 return rc; 5038 } 5039 5040 int 5041 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap) 5042 { 5043 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */ 5044 TRANSACTION2_SETFSI_REQ *pSMB = NULL; 5045 TRANSACTION2_SETFSI_RSP *pSMBr = NULL; 5046 int rc = 0; 5047 int bytes_returned = 0; 5048 __u16 params, param_offset, offset, byte_count; 5049 5050 cifs_dbg(FYI, "In SETFSUnixInfo\n"); 5051 SETFSUnixRetry: 5052 /* BB switch to small buf init to save memory */ 5053 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 5054 (void **) &pSMB, (void **) &pSMBr); 5055 if (rc) 5056 return rc; 5057 5058 params = 4; /* 2 bytes zero followed by info level. */ 5059 pSMB->MaxSetupCount = 0; 5060 pSMB->Reserved = 0; 5061 pSMB->Flags = 0; 5062 pSMB->Timeout = 0; 5063 pSMB->Reserved2 = 0; 5064 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) 5065 - 4; 5066 offset = param_offset + params; 5067 5068 pSMB->MaxParameterCount = cpu_to_le16(4); 5069 /* BB find exact max SMB PDU from sess structure BB */ 5070 pSMB->MaxDataCount = cpu_to_le16(100); 5071 pSMB->SetupCount = 1; 5072 pSMB->Reserved3 = 0; 5073 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION); 5074 byte_count = 1 /* pad */ + params + 12; 5075 5076 pSMB->DataCount = cpu_to_le16(12); 5077 pSMB->ParameterCount = cpu_to_le16(params); 5078 pSMB->TotalDataCount = pSMB->DataCount; 5079 pSMB->TotalParameterCount = pSMB->ParameterCount; 5080 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5081 pSMB->DataOffset = cpu_to_le16(offset); 5082 5083 /* Params. */ 5084 pSMB->FileNum = 0; 5085 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO); 5086 5087 /* Data. */ 5088 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION); 5089 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION); 5090 pSMB->ClientUnixCap = cpu_to_le64(cap); 5091 5092 inc_rfc1001_len(pSMB, byte_count); 5093 pSMB->ByteCount = cpu_to_le16(byte_count); 5094 5095 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5096 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5097 if (rc) { 5098 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc); 5099 } else { /* decode response */ 5100 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5101 if (rc) 5102 rc = -EIO; /* bad smb */ 5103 } 5104 cifs_buf_release(pSMB); 5105 5106 if (rc == -EAGAIN) 5107 goto SETFSUnixRetry; 5108 5109 return rc; 5110 } 5111 5112 5113 5114 int 5115 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon, 5116 struct kstatfs *FSData) 5117 { 5118 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ 5119 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5120 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5121 FILE_SYSTEM_POSIX_INFO *response_data; 5122 int rc = 0; 5123 int bytes_returned = 0; 5124 __u16 params, byte_count; 5125 5126 cifs_dbg(FYI, "In QFSPosixInfo\n"); 5127 QFSPosixRetry: 5128 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5129 (void **) &pSMBr); 5130 if (rc) 5131 return rc; 5132 5133 params = 2; /* level */ 5134 pSMB->TotalDataCount = 0; 5135 pSMB->DataCount = 0; 5136 pSMB->DataOffset = 0; 5137 pSMB->MaxParameterCount = cpu_to_le16(2); 5138 /* BB find exact max SMB PDU from sess structure BB */ 5139 pSMB->MaxDataCount = cpu_to_le16(100); 5140 pSMB->MaxSetupCount = 0; 5141 pSMB->Reserved = 0; 5142 pSMB->Flags = 0; 5143 pSMB->Timeout = 0; 5144 pSMB->Reserved2 = 0; 5145 byte_count = params + 1 /* pad */ ; 5146 pSMB->ParameterCount = cpu_to_le16(params); 5147 pSMB->TotalParameterCount = pSMB->ParameterCount; 5148 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 5149 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 5150 pSMB->SetupCount = 1; 5151 pSMB->Reserved3 = 0; 5152 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5153 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO); 5154 inc_rfc1001_len(pSMB, byte_count); 5155 pSMB->ByteCount = cpu_to_le16(byte_count); 5156 5157 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5158 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5159 if (rc) { 5160 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc); 5161 } else { /* decode response */ 5162 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5163 5164 if (rc || get_bcc(&pSMBr->hdr) < 13) { 5165 rc = -EIO; /* bad smb */ 5166 } else { 5167 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5168 response_data = 5169 (FILE_SYSTEM_POSIX_INFO 5170 *) (((char *) &pSMBr->hdr.Protocol) + 5171 data_offset); 5172 FSData->f_bsize = 5173 le32_to_cpu(response_data->BlockSize); 5174 /* 5175 * much prefer larger but if server doesn't report 5176 * a valid size than 4K is a reasonable minimum 5177 */ 5178 if (FSData->f_bsize < 512) 5179 FSData->f_bsize = 4096; 5180 5181 FSData->f_blocks = 5182 le64_to_cpu(response_data->TotalBlocks); 5183 FSData->f_bfree = 5184 le64_to_cpu(response_data->BlocksAvail); 5185 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) { 5186 FSData->f_bavail = FSData->f_bfree; 5187 } else { 5188 FSData->f_bavail = 5189 le64_to_cpu(response_data->UserBlocksAvail); 5190 } 5191 if (response_data->TotalFileNodes != cpu_to_le64(-1)) 5192 FSData->f_files = 5193 le64_to_cpu(response_data->TotalFileNodes); 5194 if (response_data->FreeFileNodes != cpu_to_le64(-1)) 5195 FSData->f_ffree = 5196 le64_to_cpu(response_data->FreeFileNodes); 5197 } 5198 } 5199 cifs_buf_release(pSMB); 5200 5201 if (rc == -EAGAIN) 5202 goto QFSPosixRetry; 5203 5204 return rc; 5205 } 5206 5207 5208 /* 5209 * We can not use write of zero bytes trick to set file size due to need for 5210 * large file support. Also note that this SetPathInfo is preferred to 5211 * SetFileInfo based method in next routine which is only needed to work around 5212 * a sharing violation bugin Samba which this routine can run into. 5213 */ 5214 int 5215 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon, 5216 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb, 5217 bool set_allocation, struct dentry *dentry) 5218 { 5219 struct smb_com_transaction2_spi_req *pSMB = NULL; 5220 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5221 struct file_end_of_file_info *parm_data; 5222 int name_len; 5223 int rc = 0; 5224 int bytes_returned = 0; 5225 int remap = cifs_remap(cifs_sb); 5226 5227 __u16 params, byte_count, data_count, param_offset, offset; 5228 5229 cifs_dbg(FYI, "In SetEOF\n"); 5230 SetEOFRetry: 5231 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5232 (void **) &pSMBr); 5233 if (rc) 5234 return rc; 5235 5236 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5237 name_len = 5238 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 5239 PATH_MAX, cifs_sb->local_nls, remap); 5240 name_len++; /* trailing null */ 5241 name_len *= 2; 5242 } else { 5243 name_len = copy_path_name(pSMB->FileName, file_name); 5244 } 5245 params = 6 + name_len; 5246 data_count = sizeof(struct file_end_of_file_info); 5247 pSMB->MaxParameterCount = cpu_to_le16(2); 5248 pSMB->MaxDataCount = cpu_to_le16(4100); 5249 pSMB->MaxSetupCount = 0; 5250 pSMB->Reserved = 0; 5251 pSMB->Flags = 0; 5252 pSMB->Timeout = 0; 5253 pSMB->Reserved2 = 0; 5254 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5255 InformationLevel) - 4; 5256 offset = param_offset + params; 5257 if (set_allocation) { 5258 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5259 pSMB->InformationLevel = 5260 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5261 else 5262 pSMB->InformationLevel = 5263 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5264 } else /* Set File Size */ { 5265 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5266 pSMB->InformationLevel = 5267 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5268 else 5269 pSMB->InformationLevel = 5270 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5271 } 5272 5273 parm_data = 5274 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) + 5275 offset); 5276 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5277 pSMB->DataOffset = cpu_to_le16(offset); 5278 pSMB->SetupCount = 1; 5279 pSMB->Reserved3 = 0; 5280 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5281 byte_count = 3 /* pad */ + params + data_count; 5282 pSMB->DataCount = cpu_to_le16(data_count); 5283 pSMB->TotalDataCount = pSMB->DataCount; 5284 pSMB->ParameterCount = cpu_to_le16(params); 5285 pSMB->TotalParameterCount = pSMB->ParameterCount; 5286 pSMB->Reserved4 = 0; 5287 inc_rfc1001_len(pSMB, byte_count); 5288 parm_data->FileSize = cpu_to_le64(size); 5289 pSMB->ByteCount = cpu_to_le16(byte_count); 5290 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5291 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5292 if (rc) 5293 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc); 5294 5295 cifs_buf_release(pSMB); 5296 5297 if (rc == -EAGAIN) 5298 goto SetEOFRetry; 5299 5300 return rc; 5301 } 5302 5303 int 5304 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, 5305 struct cifsFileInfo *cfile, __u64 size, bool set_allocation) 5306 { 5307 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5308 struct file_end_of_file_info *parm_data; 5309 int rc = 0; 5310 __u16 params, param_offset, offset, byte_count, count; 5311 5312 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n", 5313 (long long)size); 5314 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5315 5316 if (rc) 5317 return rc; 5318 5319 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid); 5320 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16)); 5321 5322 params = 6; 5323 pSMB->MaxSetupCount = 0; 5324 pSMB->Reserved = 0; 5325 pSMB->Flags = 0; 5326 pSMB->Timeout = 0; 5327 pSMB->Reserved2 = 0; 5328 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5329 offset = param_offset + params; 5330 5331 count = sizeof(struct file_end_of_file_info); 5332 pSMB->MaxParameterCount = cpu_to_le16(2); 5333 /* BB find exact max SMB PDU from sess structure BB */ 5334 pSMB->MaxDataCount = cpu_to_le16(1000); 5335 pSMB->SetupCount = 1; 5336 pSMB->Reserved3 = 0; 5337 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5338 byte_count = 3 /* pad */ + params + count; 5339 pSMB->DataCount = cpu_to_le16(count); 5340 pSMB->ParameterCount = cpu_to_le16(params); 5341 pSMB->TotalDataCount = pSMB->DataCount; 5342 pSMB->TotalParameterCount = pSMB->ParameterCount; 5343 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5344 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5345 parm_data = 5346 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4); 5347 pSMB->DataOffset = cpu_to_le16(offset); 5348 parm_data->FileSize = cpu_to_le64(size); 5349 pSMB->Fid = cfile->fid.netfid; 5350 if (set_allocation) { 5351 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5352 pSMB->InformationLevel = 5353 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5354 else 5355 pSMB->InformationLevel = 5356 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5357 } else /* Set File Size */ { 5358 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5359 pSMB->InformationLevel = 5360 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5361 else 5362 pSMB->InformationLevel = 5363 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5364 } 5365 pSMB->Reserved4 = 0; 5366 inc_rfc1001_len(pSMB, byte_count); 5367 pSMB->ByteCount = cpu_to_le16(byte_count); 5368 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5369 cifs_small_buf_release(pSMB); 5370 if (rc) { 5371 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n", 5372 rc); 5373 } 5374 5375 /* Note: On -EAGAIN error only caller can retry on handle based calls 5376 since file handle passed in no longer valid */ 5377 5378 return rc; 5379 } 5380 5381 int 5382 SMBSetInformation(const unsigned int xid, struct cifs_tcon *tcon, 5383 const char *fileName, __le32 attributes, __le64 write_time, 5384 const struct nls_table *nls_codepage, 5385 struct cifs_sb_info *cifs_sb) 5386 { 5387 SETATTR_REQ *pSMB; 5388 SETATTR_RSP *pSMBr; 5389 struct timespec64 ts; 5390 int bytes_returned; 5391 int name_len; 5392 int rc; 5393 5394 cifs_dbg(FYI, "In %s path %s\n", __func__, fileName); 5395 5396 retry: 5397 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB, 5398 (void **) &pSMBr); 5399 if (rc) 5400 return rc; 5401 5402 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5403 name_len = 5404 cifsConvertToUTF16((__le16 *) pSMB->fileName, 5405 fileName, PATH_MAX, nls_codepage, 5406 cifs_remap(cifs_sb)); 5407 name_len++; /* trailing null */ 5408 name_len *= 2; 5409 } else { 5410 name_len = copy_path_name(pSMB->fileName, fileName); 5411 } 5412 /* Only few attributes can be set by this command, others are not accepted by Win9x. */ 5413 pSMB->attr = cpu_to_le16(le32_to_cpu(attributes) & 5414 (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE)); 5415 /* Zero write time value (in both NT and SETATTR formats) means to not change it. */ 5416 if (le64_to_cpu(write_time) != 0) { 5417 ts = cifs_NTtimeToUnix(write_time); 5418 pSMB->last_write_time = cpu_to_le32(ts.tv_sec); 5419 } 5420 pSMB->BufferFormat = 0x04; 5421 name_len++; /* account for buffer type byte */ 5422 inc_rfc1001_len(pSMB, (__u16)name_len); 5423 pSMB->ByteCount = cpu_to_le16(name_len); 5424 5425 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5426 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5427 if (rc) 5428 cifs_dbg(FYI, "Send error in %s = %d\n", __func__, rc); 5429 5430 cifs_buf_release(pSMB); 5431 5432 if (rc == -EAGAIN) 5433 goto retry; 5434 5435 return rc; 5436 } 5437 5438 /* Some legacy servers such as NT4 require that the file times be set on 5439 an open handle, rather than by pathname - this is awkward due to 5440 potential access conflicts on the open, but it is unavoidable for these 5441 old servers since the only other choice is to go from 100 nanosecond DCE 5442 time and resort to the original setpathinfo level which takes the ancient 5443 DOS time format with 2 second granularity */ 5444 int 5445 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 5446 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener) 5447 { 5448 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5449 char *data_offset; 5450 int rc = 0; 5451 __u16 params, param_offset, offset, byte_count, count; 5452 5453 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n"); 5454 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5455 5456 if (rc) 5457 return rc; 5458 5459 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5460 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5461 5462 params = 6; 5463 pSMB->MaxSetupCount = 0; 5464 pSMB->Reserved = 0; 5465 pSMB->Flags = 0; 5466 pSMB->Timeout = 0; 5467 pSMB->Reserved2 = 0; 5468 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5469 offset = param_offset + params; 5470 5471 data_offset = (char *)pSMB + 5472 offsetof(struct smb_hdr, Protocol) + offset; 5473 5474 count = sizeof(FILE_BASIC_INFO); 5475 pSMB->MaxParameterCount = cpu_to_le16(2); 5476 /* BB find max SMB PDU from sess */ 5477 pSMB->MaxDataCount = cpu_to_le16(1000); 5478 pSMB->SetupCount = 1; 5479 pSMB->Reserved3 = 0; 5480 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5481 byte_count = 3 /* pad */ + params + count; 5482 pSMB->DataCount = cpu_to_le16(count); 5483 pSMB->ParameterCount = cpu_to_le16(params); 5484 pSMB->TotalDataCount = pSMB->DataCount; 5485 pSMB->TotalParameterCount = pSMB->ParameterCount; 5486 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5487 pSMB->DataOffset = cpu_to_le16(offset); 5488 pSMB->Fid = fid; 5489 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5490 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5491 else 5492 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5493 pSMB->Reserved4 = 0; 5494 inc_rfc1001_len(pSMB, byte_count); 5495 pSMB->ByteCount = cpu_to_le16(byte_count); 5496 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5497 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5498 cifs_small_buf_release(pSMB); 5499 if (rc) 5500 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 5501 rc); 5502 5503 /* Note: On -EAGAIN error only caller can retry on handle based calls 5504 since file handle passed in no longer valid */ 5505 5506 return rc; 5507 } 5508 5509 int 5510 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon, 5511 bool delete_file, __u16 fid, __u32 pid_of_opener) 5512 { 5513 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5514 char *data_offset; 5515 int rc = 0; 5516 __u16 params, param_offset, offset, byte_count, count; 5517 5518 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n"); 5519 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5520 5521 if (rc) 5522 return rc; 5523 5524 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5525 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5526 5527 params = 6; 5528 pSMB->MaxSetupCount = 0; 5529 pSMB->Reserved = 0; 5530 pSMB->Flags = 0; 5531 pSMB->Timeout = 0; 5532 pSMB->Reserved2 = 0; 5533 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5534 offset = param_offset + params; 5535 5536 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5537 data_offset = (char *)(pSMB) + offset + 4; 5538 5539 count = 1; 5540 pSMB->MaxParameterCount = cpu_to_le16(2); 5541 /* BB find max SMB PDU from sess */ 5542 pSMB->MaxDataCount = cpu_to_le16(1000); 5543 pSMB->SetupCount = 1; 5544 pSMB->Reserved3 = 0; 5545 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5546 byte_count = 3 /* pad */ + params + count; 5547 pSMB->DataCount = cpu_to_le16(count); 5548 pSMB->ParameterCount = cpu_to_le16(params); 5549 pSMB->TotalDataCount = pSMB->DataCount; 5550 pSMB->TotalParameterCount = pSMB->ParameterCount; 5551 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5552 pSMB->DataOffset = cpu_to_le16(offset); 5553 pSMB->Fid = fid; 5554 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO); 5555 pSMB->Reserved4 = 0; 5556 inc_rfc1001_len(pSMB, byte_count); 5557 pSMB->ByteCount = cpu_to_le16(byte_count); 5558 *data_offset = delete_file ? 1 : 0; 5559 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5560 cifs_small_buf_release(pSMB); 5561 if (rc) 5562 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc); 5563 5564 return rc; 5565 } 5566 5567 static int 5568 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon, 5569 const char *fileName, const FILE_BASIC_INFO *data, 5570 const struct nls_table *nls_codepage, 5571 struct cifs_sb_info *cifs_sb) 5572 { 5573 int oplock = 0; 5574 struct cifs_open_parms oparms; 5575 struct cifs_fid fid; 5576 int rc; 5577 5578 oparms = (struct cifs_open_parms) { 5579 .tcon = tcon, 5580 .cifs_sb = cifs_sb, 5581 .desired_access = GENERIC_WRITE, 5582 .create_options = cifs_create_options(cifs_sb, 0), 5583 .disposition = FILE_OPEN, 5584 .path = fileName, 5585 .fid = &fid, 5586 }; 5587 5588 rc = CIFS_open(xid, &oparms, &oplock, NULL); 5589 if (rc) 5590 goto out; 5591 5592 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid); 5593 CIFSSMBClose(xid, tcon, fid.netfid); 5594 out: 5595 5596 return rc; 5597 } 5598 5599 int 5600 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5601 const char *fileName, const FILE_BASIC_INFO *data, 5602 const struct nls_table *nls_codepage, 5603 struct cifs_sb_info *cifs_sb) 5604 { 5605 TRANSACTION2_SPI_REQ *pSMB = NULL; 5606 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5607 int name_len; 5608 int rc = 0; 5609 int bytes_returned = 0; 5610 char *data_offset; 5611 __u16 params, param_offset, offset, byte_count, count; 5612 int remap = cifs_remap(cifs_sb); 5613 5614 cifs_dbg(FYI, "In SetTimes\n"); 5615 5616 SetTimesRetry: 5617 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5618 (void **) &pSMBr); 5619 if (rc) 5620 return rc; 5621 5622 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5623 name_len = 5624 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 5625 PATH_MAX, nls_codepage, remap); 5626 name_len++; /* trailing null */ 5627 name_len *= 2; 5628 } else { 5629 name_len = copy_path_name(pSMB->FileName, fileName); 5630 } 5631 5632 params = 6 + name_len; 5633 count = sizeof(FILE_BASIC_INFO); 5634 pSMB->MaxParameterCount = cpu_to_le16(2); 5635 /* BB find max SMB PDU from sess structure BB */ 5636 pSMB->MaxDataCount = cpu_to_le16(1000); 5637 pSMB->MaxSetupCount = 0; 5638 pSMB->Reserved = 0; 5639 pSMB->Flags = 0; 5640 pSMB->Timeout = 0; 5641 pSMB->Reserved2 = 0; 5642 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5643 InformationLevel) - 4; 5644 offset = param_offset + params; 5645 data_offset = (char *)pSMB + offsetof(typeof(*pSMB), hdr.Protocol) + offset; 5646 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5647 pSMB->DataOffset = cpu_to_le16(offset); 5648 pSMB->SetupCount = 1; 5649 pSMB->Reserved3 = 0; 5650 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5651 byte_count = 3 /* pad */ + params + count; 5652 5653 pSMB->DataCount = cpu_to_le16(count); 5654 pSMB->ParameterCount = cpu_to_le16(params); 5655 pSMB->TotalDataCount = pSMB->DataCount; 5656 pSMB->TotalParameterCount = pSMB->ParameterCount; 5657 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5658 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5659 else 5660 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5661 pSMB->Reserved4 = 0; 5662 inc_rfc1001_len(pSMB, byte_count); 5663 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5664 pSMB->ByteCount = cpu_to_le16(byte_count); 5665 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5666 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5667 if (rc) 5668 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc); 5669 5670 cifs_buf_release(pSMB); 5671 5672 if (rc == -EAGAIN) 5673 goto SetTimesRetry; 5674 5675 if (rc == -EOPNOTSUPP) 5676 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data, 5677 nls_codepage, cifs_sb); 5678 5679 return rc; 5680 } 5681 5682 static void 5683 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, 5684 const struct cifs_unix_set_info_args *args) 5685 { 5686 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64; 5687 u64 mode = args->mode; 5688 5689 if (uid_valid(args->uid)) 5690 uid = from_kuid(&init_user_ns, args->uid); 5691 if (gid_valid(args->gid)) 5692 gid = from_kgid(&init_user_ns, args->gid); 5693 5694 /* 5695 * Samba server ignores set of file size to zero due to bugs in some 5696 * older clients, but we should be precise - we use SetFileSize to 5697 * set file size and do not want to truncate file size to zero 5698 * accidentally as happened on one Samba server beta by putting 5699 * zero instead of -1 here 5700 */ 5701 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); 5702 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); 5703 data_offset->LastStatusChange = cpu_to_le64(args->ctime); 5704 data_offset->LastAccessTime = cpu_to_le64(args->atime); 5705 data_offset->LastModificationTime = cpu_to_le64(args->mtime); 5706 data_offset->Uid = cpu_to_le64(uid); 5707 data_offset->Gid = cpu_to_le64(gid); 5708 /* better to leave device as zero when it is */ 5709 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); 5710 data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); 5711 data_offset->Permissions = cpu_to_le64(mode); 5712 5713 if (S_ISREG(mode)) 5714 data_offset->Type = cpu_to_le32(UNIX_FILE); 5715 else if (S_ISDIR(mode)) 5716 data_offset->Type = cpu_to_le32(UNIX_DIR); 5717 else if (S_ISLNK(mode)) 5718 data_offset->Type = cpu_to_le32(UNIX_SYMLINK); 5719 else if (S_ISCHR(mode)) 5720 data_offset->Type = cpu_to_le32(UNIX_CHARDEV); 5721 else if (S_ISBLK(mode)) 5722 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); 5723 else if (S_ISFIFO(mode)) 5724 data_offset->Type = cpu_to_le32(UNIX_FIFO); 5725 else if (S_ISSOCK(mode)) 5726 data_offset->Type = cpu_to_le32(UNIX_SOCKET); 5727 } 5728 5729 int 5730 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 5731 const struct cifs_unix_set_info_args *args, 5732 u16 fid, u32 pid_of_opener) 5733 { 5734 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5735 char *data_offset; 5736 int rc = 0; 5737 u16 params, param_offset, offset, byte_count, count; 5738 5739 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n"); 5740 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5741 5742 if (rc) 5743 return rc; 5744 5745 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5746 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5747 5748 params = 6; 5749 pSMB->MaxSetupCount = 0; 5750 pSMB->Reserved = 0; 5751 pSMB->Flags = 0; 5752 pSMB->Timeout = 0; 5753 pSMB->Reserved2 = 0; 5754 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5755 offset = param_offset + params; 5756 5757 data_offset = (char *)pSMB + 5758 offsetof(struct smb_hdr, Protocol) + offset; 5759 5760 count = sizeof(FILE_UNIX_BASIC_INFO); 5761 5762 pSMB->MaxParameterCount = cpu_to_le16(2); 5763 /* BB find max SMB PDU from sess */ 5764 pSMB->MaxDataCount = cpu_to_le16(1000); 5765 pSMB->SetupCount = 1; 5766 pSMB->Reserved3 = 0; 5767 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5768 byte_count = 3 /* pad */ + params + count; 5769 pSMB->DataCount = cpu_to_le16(count); 5770 pSMB->ParameterCount = cpu_to_le16(params); 5771 pSMB->TotalDataCount = pSMB->DataCount; 5772 pSMB->TotalParameterCount = pSMB->ParameterCount; 5773 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5774 pSMB->DataOffset = cpu_to_le16(offset); 5775 pSMB->Fid = fid; 5776 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5777 pSMB->Reserved4 = 0; 5778 inc_rfc1001_len(pSMB, byte_count); 5779 pSMB->ByteCount = cpu_to_le16(byte_count); 5780 5781 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args); 5782 5783 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5784 cifs_small_buf_release(pSMB); 5785 if (rc) 5786 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 5787 rc); 5788 5789 /* Note: On -EAGAIN error only caller can retry on handle based calls 5790 since file handle passed in no longer valid */ 5791 5792 return rc; 5793 } 5794 5795 int 5796 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5797 const char *file_name, 5798 const struct cifs_unix_set_info_args *args, 5799 const struct nls_table *nls_codepage, int remap) 5800 { 5801 TRANSACTION2_SPI_REQ *pSMB = NULL; 5802 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5803 int name_len; 5804 int rc = 0; 5805 int bytes_returned = 0; 5806 FILE_UNIX_BASIC_INFO *data_offset; 5807 __u16 params, param_offset, offset, count, byte_count; 5808 5809 cifs_dbg(FYI, "In SetUID/GID/Mode\n"); 5810 setPermsRetry: 5811 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5812 (void **) &pSMBr); 5813 if (rc) 5814 return rc; 5815 5816 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5817 name_len = 5818 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 5819 PATH_MAX, nls_codepage, remap); 5820 name_len++; /* trailing null */ 5821 name_len *= 2; 5822 } else { 5823 name_len = copy_path_name(pSMB->FileName, file_name); 5824 } 5825 5826 params = 6 + name_len; 5827 count = sizeof(FILE_UNIX_BASIC_INFO); 5828 pSMB->MaxParameterCount = cpu_to_le16(2); 5829 /* BB find max SMB PDU from sess structure BB */ 5830 pSMB->MaxDataCount = cpu_to_le16(1000); 5831 pSMB->MaxSetupCount = 0; 5832 pSMB->Reserved = 0; 5833 pSMB->Flags = 0; 5834 pSMB->Timeout = 0; 5835 pSMB->Reserved2 = 0; 5836 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5837 InformationLevel) - 4; 5838 offset = param_offset + params; 5839 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5840 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4); 5841 memset(data_offset, 0, count); 5842 pSMB->DataOffset = cpu_to_le16(offset); 5843 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5844 pSMB->SetupCount = 1; 5845 pSMB->Reserved3 = 0; 5846 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5847 byte_count = 3 /* pad */ + params + count; 5848 pSMB->ParameterCount = cpu_to_le16(params); 5849 pSMB->DataCount = cpu_to_le16(count); 5850 pSMB->TotalParameterCount = pSMB->ParameterCount; 5851 pSMB->TotalDataCount = pSMB->DataCount; 5852 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5853 pSMB->Reserved4 = 0; 5854 inc_rfc1001_len(pSMB, byte_count); 5855 5856 cifs_fill_unix_set_info(data_offset, args); 5857 5858 pSMB->ByteCount = cpu_to_le16(byte_count); 5859 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5860 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5861 if (rc) 5862 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc); 5863 5864 cifs_buf_release(pSMB); 5865 if (rc == -EAGAIN) 5866 goto setPermsRetry; 5867 return rc; 5868 } 5869 5870 #ifdef CONFIG_CIFS_XATTR 5871 /* 5872 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common 5873 * function used by listxattr and getxattr type calls. When ea_name is set, 5874 * it looks for that attribute name and stuffs that value into the EAData 5875 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the 5876 * buffer. In both cases, the return value is either the length of the 5877 * resulting data or a negative error code. If EAData is a NULL pointer then 5878 * the data isn't copied to it, but the length is returned. 5879 */ 5880 ssize_t 5881 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon, 5882 const unsigned char *searchName, const unsigned char *ea_name, 5883 char *EAData, size_t buf_size, 5884 struct cifs_sb_info *cifs_sb) 5885 { 5886 /* BB assumes one setup word */ 5887 TRANSACTION2_QPI_REQ *pSMB = NULL; 5888 TRANSACTION2_QPI_RSP *pSMBr = NULL; 5889 int remap = cifs_remap(cifs_sb); 5890 struct nls_table *nls_codepage = cifs_sb->local_nls; 5891 int rc = 0; 5892 int bytes_returned; 5893 int list_len; 5894 struct fealist *ea_response_data; 5895 struct fea *temp_fea; 5896 char *temp_ptr; 5897 char *end_of_smb; 5898 __u16 params, byte_count, data_offset; 5899 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0; 5900 5901 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName); 5902 QAllEAsRetry: 5903 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5904 (void **) &pSMBr); 5905 if (rc) 5906 return rc; 5907 5908 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5909 list_len = 5910 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 5911 PATH_MAX, nls_codepage, remap); 5912 list_len++; /* trailing null */ 5913 list_len *= 2; 5914 } else { 5915 list_len = copy_path_name(pSMB->FileName, searchName); 5916 } 5917 5918 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */; 5919 pSMB->TotalDataCount = 0; 5920 pSMB->MaxParameterCount = cpu_to_le16(2); 5921 /* BB find exact max SMB PDU from sess structure BB */ 5922 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 5923 pSMB->MaxSetupCount = 0; 5924 pSMB->Reserved = 0; 5925 pSMB->Flags = 0; 5926 pSMB->Timeout = 0; 5927 pSMB->Reserved2 = 0; 5928 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5929 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 5930 pSMB->DataCount = 0; 5931 pSMB->DataOffset = 0; 5932 pSMB->SetupCount = 1; 5933 pSMB->Reserved3 = 0; 5934 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 5935 byte_count = params + 1 /* pad */ ; 5936 pSMB->TotalParameterCount = cpu_to_le16(params); 5937 pSMB->ParameterCount = pSMB->TotalParameterCount; 5938 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS); 5939 pSMB->Reserved4 = 0; 5940 inc_rfc1001_len(pSMB, byte_count); 5941 pSMB->ByteCount = cpu_to_le16(byte_count); 5942 5943 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5944 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5945 if (rc) { 5946 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc); 5947 goto QAllEAsOut; 5948 } 5949 5950 5951 /* BB also check enough total bytes returned */ 5952 /* BB we need to improve the validity checking 5953 of these trans2 responses */ 5954 5955 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5956 if (rc || get_bcc(&pSMBr->hdr) < 4) { 5957 rc = -EIO; /* bad smb */ 5958 goto QAllEAsOut; 5959 } 5960 5961 /* check that length of list is not more than bcc */ 5962 /* check that each entry does not go beyond length 5963 of list */ 5964 /* check that each element of each entry does not 5965 go beyond end of list */ 5966 /* validate_trans2_offsets() */ 5967 /* BB check if start of smb + data_offset > &bcc+ bcc */ 5968 5969 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5970 ea_response_data = (struct fealist *) 5971 (((char *) &pSMBr->hdr.Protocol) + data_offset); 5972 5973 list_len = le32_to_cpu(ea_response_data->list_len); 5974 cifs_dbg(FYI, "ea length %d\n", list_len); 5975 if (list_len <= 8) { 5976 cifs_dbg(FYI, "empty EA list returned from server\n"); 5977 /* didn't find the named attribute */ 5978 if (ea_name) 5979 rc = -ENODATA; 5980 goto QAllEAsOut; 5981 } 5982 5983 /* make sure list_len doesn't go past end of SMB */ 5984 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr); 5985 if ((char *)ea_response_data + list_len > end_of_smb) { 5986 cifs_dbg(FYI, "EA list appears to go beyond SMB\n"); 5987 rc = -EIO; 5988 goto QAllEAsOut; 5989 } 5990 5991 /* account for ea list len */ 5992 list_len -= 4; 5993 temp_fea = &ea_response_data->list; 5994 temp_ptr = (char *)temp_fea; 5995 while (list_len > 0) { 5996 unsigned int name_len; 5997 __u16 value_len; 5998 5999 list_len -= 4; 6000 temp_ptr += 4; 6001 /* make sure we can read name_len and value_len */ 6002 if (list_len < 0) { 6003 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 6004 rc = -EIO; 6005 goto QAllEAsOut; 6006 } 6007 6008 name_len = temp_fea->name_len; 6009 value_len = le16_to_cpu(temp_fea->value_len); 6010 list_len -= name_len + 1 + value_len; 6011 if (list_len < 0) { 6012 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 6013 rc = -EIO; 6014 goto QAllEAsOut; 6015 } 6016 6017 if (ea_name) { 6018 if (ea_name_len == name_len && 6019 memcmp(ea_name, temp_ptr, name_len) == 0) { 6020 temp_ptr += name_len + 1; 6021 rc = value_len; 6022 if (buf_size == 0) 6023 goto QAllEAsOut; 6024 if ((size_t)value_len > buf_size) { 6025 rc = -ERANGE; 6026 goto QAllEAsOut; 6027 } 6028 memcpy(EAData, temp_ptr, value_len); 6029 goto QAllEAsOut; 6030 } 6031 } else { 6032 /* account for prefix user. and trailing null */ 6033 rc += (5 + 1 + name_len); 6034 if (rc < (int) buf_size) { 6035 memcpy(EAData, "user.", 5); 6036 EAData += 5; 6037 memcpy(EAData, temp_ptr, name_len); 6038 EAData += name_len; 6039 /* null terminate name */ 6040 *EAData = 0; 6041 ++EAData; 6042 } else if (buf_size == 0) { 6043 /* skip copy - calc size only */ 6044 } else { 6045 /* stop before overrun buffer */ 6046 rc = -ERANGE; 6047 break; 6048 } 6049 } 6050 temp_ptr += name_len + 1 + value_len; 6051 temp_fea = (struct fea *)temp_ptr; 6052 } 6053 6054 /* didn't find the named attribute */ 6055 if (ea_name) 6056 rc = -ENODATA; 6057 6058 QAllEAsOut: 6059 cifs_buf_release(pSMB); 6060 if (rc == -EAGAIN) 6061 goto QAllEAsRetry; 6062 6063 return (ssize_t)rc; 6064 } 6065 6066 int 6067 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, 6068 const char *fileName, const char *ea_name, const void *ea_value, 6069 const __u16 ea_value_len, const struct nls_table *nls_codepage, 6070 struct cifs_sb_info *cifs_sb) 6071 { 6072 struct smb_com_transaction2_spi_req *pSMB = NULL; 6073 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 6074 struct fealist *parm_data; 6075 int name_len; 6076 int rc = 0; 6077 int bytes_returned = 0; 6078 __u16 params, param_offset, byte_count, offset, count; 6079 int remap = cifs_remap(cifs_sb); 6080 6081 cifs_dbg(FYI, "In SetEA\n"); 6082 SetEARetry: 6083 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 6084 (void **) &pSMBr); 6085 if (rc) 6086 return rc; 6087 6088 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 6089 name_len = 6090 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 6091 PATH_MAX, nls_codepage, remap); 6092 name_len++; /* trailing null */ 6093 name_len *= 2; 6094 } else { 6095 name_len = copy_path_name(pSMB->FileName, fileName); 6096 } 6097 6098 params = 6 + name_len; 6099 6100 /* done calculating parms using name_len of file name, 6101 now use name_len to calculate length of ea name 6102 we are going to create in the inode xattrs */ 6103 if (ea_name == NULL) 6104 name_len = 0; 6105 else 6106 name_len = strnlen(ea_name, 255); 6107 6108 count = sizeof(*parm_data) + 1 + ea_value_len + name_len; 6109 pSMB->MaxParameterCount = cpu_to_le16(2); 6110 /* BB find max SMB PDU from sess */ 6111 pSMB->MaxDataCount = cpu_to_le16(1000); 6112 pSMB->MaxSetupCount = 0; 6113 pSMB->Reserved = 0; 6114 pSMB->Flags = 0; 6115 pSMB->Timeout = 0; 6116 pSMB->Reserved2 = 0; 6117 param_offset = offsetof(struct smb_com_transaction2_spi_req, 6118 InformationLevel) - 4; 6119 offset = param_offset + params; 6120 pSMB->InformationLevel = 6121 cpu_to_le16(SMB_SET_FILE_EA); 6122 6123 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset; 6124 pSMB->ParameterOffset = cpu_to_le16(param_offset); 6125 pSMB->DataOffset = cpu_to_le16(offset); 6126 pSMB->SetupCount = 1; 6127 pSMB->Reserved3 = 0; 6128 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 6129 byte_count = 3 /* pad */ + params + count; 6130 pSMB->DataCount = cpu_to_le16(count); 6131 parm_data->list_len = cpu_to_le32(count); 6132 parm_data->list.EA_flags = 0; 6133 /* we checked above that name len is less than 255 */ 6134 parm_data->list.name_len = (__u8)name_len; 6135 /* EA names are always ASCII and NUL-terminated */ 6136 strscpy(parm_data->list.name, ea_name ?: "", name_len + 1); 6137 parm_data->list.value_len = cpu_to_le16(ea_value_len); 6138 /* caller ensures that ea_value_len is less than 64K but 6139 we need to ensure that it fits within the smb */ 6140 6141 /*BB add length check to see if it would fit in 6142 negotiated SMB buffer size BB */ 6143 /* if (ea_value_len > buffer_size - 512 (enough for header)) */ 6144 if (ea_value_len) 6145 memcpy(parm_data->list.name + name_len + 1, 6146 ea_value, ea_value_len); 6147 6148 pSMB->TotalDataCount = pSMB->DataCount; 6149 pSMB->ParameterCount = cpu_to_le16(params); 6150 pSMB->TotalParameterCount = pSMB->ParameterCount; 6151 pSMB->Reserved4 = 0; 6152 inc_rfc1001_len(pSMB, byte_count); 6153 pSMB->ByteCount = cpu_to_le16(byte_count); 6154 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 6155 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 6156 if (rc) 6157 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc); 6158 6159 cifs_buf_release(pSMB); 6160 6161 if (rc == -EAGAIN) 6162 goto SetEARetry; 6163 6164 return rc; 6165 } 6166 #endif 6167