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