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 struct nls_table *nls_codepage; 3962 unsigned int lnoff; 3963 __u16 params, byte_count; 3964 int bytes_returned = 0; 3965 int name_len, remap; 3966 int rc = 0; 3967 3968 cifs_dbg(FYI, "In FindFirst for %s\n", searchName); 3969 3970 findFirstRetry: 3971 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3972 (void **) &pSMBr); 3973 if (rc) 3974 return rc; 3975 3976 nls_codepage = cifs_sb->local_nls; 3977 remap = cifs_remap(cifs_sb); 3978 3979 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3980 name_len = 3981 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 3982 PATH_MAX, nls_codepage, remap); 3983 /* We can not add the asterik earlier in case 3984 it got remapped to 0xF03A as if it were part of the 3985 directory name instead of a wildcard */ 3986 name_len *= 2; 3987 if (msearch) { 3988 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb); 3989 pSMB->FileName[name_len+1] = 0; 3990 pSMB->FileName[name_len+2] = '*'; 3991 pSMB->FileName[name_len+3] = 0; 3992 name_len += 4; /* now the trailing null */ 3993 /* null terminate just in case */ 3994 pSMB->FileName[name_len] = 0; 3995 pSMB->FileName[name_len+1] = 0; 3996 name_len += 2; 3997 } 3998 } else { 3999 name_len = copy_path_name(pSMB->FileName, searchName); 4000 if (msearch) { 4001 if (WARN_ON_ONCE(name_len > PATH_MAX-2)) 4002 name_len = PATH_MAX-2; 4003 /* overwrite nul byte */ 4004 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb); 4005 pSMB->FileName[name_len] = '*'; 4006 pSMB->FileName[name_len+1] = 0; 4007 name_len += 2; 4008 } 4009 } 4010 4011 params = 12 + name_len /* includes null */ ; 4012 pSMB->TotalDataCount = 0; /* no EAs */ 4013 pSMB->MaxParameterCount = cpu_to_le16(10); 4014 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4015 pSMB->MaxSetupCount = 0; 4016 pSMB->Reserved = 0; 4017 pSMB->Flags = 0; 4018 pSMB->Timeout = 0; 4019 pSMB->Reserved2 = 0; 4020 byte_count = params + 1 /* pad */ ; 4021 pSMB->TotalParameterCount = cpu_to_le16(params); 4022 pSMB->ParameterCount = pSMB->TotalParameterCount; 4023 pSMB->ParameterOffset = cpu_to_le16( 4024 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) 4025 - 4); 4026 pSMB->DataCount = 0; 4027 pSMB->DataOffset = 0; 4028 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */ 4029 pSMB->Reserved3 = 0; 4030 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST); 4031 pSMB->SearchAttributes = 4032 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 4033 ATTR_DIRECTORY); 4034 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO)); 4035 pSMB->SearchFlags = cpu_to_le16(search_flags); 4036 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4037 4038 /* BB what should we set StorageType to? Does it matter? BB */ 4039 pSMB->SearchStorageType = 0; 4040 inc_rfc1001_len(pSMB, byte_count); 4041 pSMB->ByteCount = cpu_to_le16(byte_count); 4042 4043 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4044 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4045 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst); 4046 4047 if (rc) { 4048 /* 4049 * BB: add logic to retry regular search if Unix search rejected 4050 * unexpectedly by server. 4051 */ 4052 /* BB: add code to handle unsupported level rc */ 4053 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc); 4054 cifs_buf_release(pSMB); 4055 /* 4056 * BB: eventually could optimize out free and realloc of buf for 4057 * this case. 4058 */ 4059 if (rc == -EAGAIN) 4060 goto findFirstRetry; 4061 return rc; 4062 } 4063 /* decode response */ 4064 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4065 if (rc) { 4066 cifs_buf_release(pSMB); 4067 return rc; 4068 } 4069 4070 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE); 4071 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 4072 psrch_inf->smallBuf = false; 4073 psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol + 4074 le16_to_cpu(pSMBr->t2.DataOffset); 4075 4076 parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol + 4077 le16_to_cpu(pSMBr->t2.ParameterOffset)); 4078 psrch_inf->endOfSearch = !!parms->EndofSearch; 4079 4080 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 4081 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + 4082 psrch_inf->entries_in_buffer; 4083 lnoff = le16_to_cpu(parms->LastNameOffset); 4084 if (CIFSMaxBufSize < lnoff) { 4085 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4086 psrch_inf->last_entry = NULL; 4087 } else { 4088 psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff; 4089 if (pnetfid) 4090 *pnetfid = parms->SearchHandle; 4091 } 4092 return 0; 4093 } 4094 4095 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon, 4096 __u16 searchHandle, __u16 search_flags, 4097 struct cifs_search_info *psrch_inf) 4098 { 4099 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 4100 TRANSACTION2_FNEXT_RSP *pSMBr = NULL; 4101 T2_FNEXT_RSP_PARMS *parms; 4102 unsigned int name_len; 4103 unsigned int lnoff; 4104 __u16 params, byte_count; 4105 char *response_data; 4106 int bytes_returned; 4107 int rc = 0; 4108 4109 cifs_dbg(FYI, "In FindNext\n"); 4110 4111 if (psrch_inf->endOfSearch) 4112 return -ENOENT; 4113 4114 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4115 (void **) &pSMBr); 4116 if (rc) 4117 return rc; 4118 4119 params = 14; /* includes 2 bytes of null string, converted to LE below*/ 4120 byte_count = 0; 4121 pSMB->TotalDataCount = 0; /* no EAs */ 4122 pSMB->MaxParameterCount = cpu_to_le16(8); 4123 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4124 pSMB->MaxSetupCount = 0; 4125 pSMB->Reserved = 0; 4126 pSMB->Flags = 0; 4127 pSMB->Timeout = 0; 4128 pSMB->Reserved2 = 0; 4129 pSMB->ParameterOffset = cpu_to_le16( 4130 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4); 4131 pSMB->DataCount = 0; 4132 pSMB->DataOffset = 0; 4133 pSMB->SetupCount = 1; 4134 pSMB->Reserved3 = 0; 4135 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); 4136 pSMB->SearchHandle = searchHandle; /* always kept as le */ 4137 pSMB->SearchCount = 4138 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); 4139 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4140 pSMB->ResumeKey = psrch_inf->resume_key; 4141 pSMB->SearchFlags = cpu_to_le16(search_flags); 4142 4143 name_len = psrch_inf->resume_name_len; 4144 params += name_len; 4145 if (name_len < PATH_MAX) { 4146 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len); 4147 byte_count += name_len; 4148 /* 14 byte parm len above enough for 2 byte null terminator */ 4149 pSMB->ResumeFileName[name_len] = 0; 4150 pSMB->ResumeFileName[name_len+1] = 0; 4151 } else { 4152 cifs_buf_release(pSMB); 4153 return -EINVAL; 4154 } 4155 byte_count = params + 1 /* pad */ ; 4156 pSMB->TotalParameterCount = cpu_to_le16(params); 4157 pSMB->ParameterCount = pSMB->TotalParameterCount; 4158 inc_rfc1001_len(pSMB, byte_count); 4159 pSMB->ByteCount = cpu_to_le16(byte_count); 4160 4161 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4162 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4163 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext); 4164 4165 if (rc) { 4166 cifs_buf_release(pSMB); 4167 if (rc == -EBADF) { 4168 psrch_inf->endOfSearch = true; 4169 rc = 0; /* search probably was closed at end of search*/ 4170 } else { 4171 cifs_dbg(FYI, "FindNext returned = %d\n", rc); 4172 } 4173 return rc; 4174 } 4175 4176 /* decode response */ 4177 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4178 if (rc) { 4179 cifs_buf_release(pSMB); 4180 return rc; 4181 } 4182 /* BB fixme add lock for file (srch_info) struct here */ 4183 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE); 4184 response_data = (char *)&pSMBr->hdr.Protocol + 4185 le16_to_cpu(pSMBr->t2.ParameterOffset); 4186 parms = (T2_FNEXT_RSP_PARMS *)response_data; 4187 response_data = (char *)&pSMBr->hdr.Protocol + 4188 le16_to_cpu(pSMBr->t2.DataOffset); 4189 4190 if (psrch_inf->smallBuf) 4191 cifs_small_buf_release(psrch_inf->ntwrk_buf_start); 4192 else 4193 cifs_buf_release(psrch_inf->ntwrk_buf_start); 4194 4195 psrch_inf->srch_entries_start = response_data; 4196 psrch_inf->ntwrk_buf_start = (char *)pSMB; 4197 psrch_inf->smallBuf = false; 4198 psrch_inf->endOfSearch = !!parms->EndofSearch; 4199 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 4200 psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer; 4201 lnoff = le16_to_cpu(parms->LastNameOffset); 4202 if (CIFSMaxBufSize < lnoff) { 4203 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4204 psrch_inf->last_entry = NULL; 4205 } else { 4206 psrch_inf->last_entry = 4207 psrch_inf->srch_entries_start + lnoff; 4208 } 4209 /* BB fixme add unlock here */ 4210 4211 /* 4212 * BB: On error, should we leave previous search buf 4213 * (and count and last entry fields) intact or free the previous one? 4214 * 4215 * Note: On -EAGAIN error only caller can retry on handle based calls 4216 * since file handle passed in no longer valid. 4217 */ 4218 return 0; 4219 } 4220 4221 int 4222 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon, 4223 const __u16 searchHandle) 4224 { 4225 int rc = 0; 4226 FINDCLOSE_REQ *pSMB = NULL; 4227 4228 cifs_dbg(FYI, "In CIFSSMBFindClose\n"); 4229 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); 4230 4231 /* no sense returning error if session restarted 4232 as file handle has been closed */ 4233 if (rc == -EAGAIN) 4234 return 0; 4235 if (rc) 4236 return rc; 4237 4238 pSMB->FileID = searchHandle; 4239 pSMB->ByteCount = 0; 4240 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 4241 cifs_small_buf_release(pSMB); 4242 if (rc) 4243 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc); 4244 4245 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose); 4246 4247 /* Since session is dead, search handle closed on server already */ 4248 if (rc == -EAGAIN) 4249 rc = 0; 4250 4251 return rc; 4252 } 4253 4254 int 4255 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon, 4256 const char *search_name, __u64 *inode_number, 4257 const struct nls_table *nls_codepage, int remap) 4258 { 4259 int rc = 0; 4260 TRANSACTION2_QPI_REQ *pSMB = NULL; 4261 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4262 int name_len, bytes_returned; 4263 __u16 params, byte_count; 4264 4265 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name); 4266 if (tcon == NULL) 4267 return -ENODEV; 4268 4269 GetInodeNumberRetry: 4270 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4271 (void **) &pSMBr); 4272 if (rc) 4273 return rc; 4274 4275 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4276 name_len = 4277 cifsConvertToUTF16((__le16 *) pSMB->FileName, 4278 search_name, PATH_MAX, nls_codepage, 4279 remap); 4280 name_len++; /* trailing null */ 4281 name_len *= 2; 4282 } else { 4283 name_len = copy_path_name(pSMB->FileName, search_name); 4284 } 4285 4286 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 4287 pSMB->TotalDataCount = 0; 4288 pSMB->MaxParameterCount = cpu_to_le16(2); 4289 /* BB find exact max data count below from sess structure BB */ 4290 pSMB->MaxDataCount = cpu_to_le16(4000); 4291 pSMB->MaxSetupCount = 0; 4292 pSMB->Reserved = 0; 4293 pSMB->Flags = 0; 4294 pSMB->Timeout = 0; 4295 pSMB->Reserved2 = 0; 4296 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4297 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 4298 pSMB->DataCount = 0; 4299 pSMB->DataOffset = 0; 4300 pSMB->SetupCount = 1; 4301 pSMB->Reserved3 = 0; 4302 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4303 byte_count = params + 1 /* pad */ ; 4304 pSMB->TotalParameterCount = cpu_to_le16(params); 4305 pSMB->ParameterCount = pSMB->TotalParameterCount; 4306 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO); 4307 pSMB->Reserved4 = 0; 4308 inc_rfc1001_len(pSMB, byte_count); 4309 pSMB->ByteCount = cpu_to_le16(byte_count); 4310 4311 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4312 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4313 if (rc) { 4314 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc); 4315 } else { 4316 /* decode response */ 4317 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4318 /* BB also check enough total bytes returned */ 4319 if (rc || get_bcc(&pSMBr->hdr) < 2) 4320 /* If rc should we check for EOPNOSUPP and 4321 disable the srvino flag? or in caller? */ 4322 rc = -EIO; /* bad smb */ 4323 else { 4324 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4325 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 4326 struct file_internal_info *pfinfo; 4327 /* BB Do we need a cast or hash here ? */ 4328 if (count < 8) { 4329 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n"); 4330 rc = -EIO; 4331 goto GetInodeNumOut; 4332 } 4333 pfinfo = (struct file_internal_info *) 4334 (data_offset + (char *) &pSMBr->hdr.Protocol); 4335 *inode_number = le64_to_cpu(pfinfo->UniqueId); 4336 } 4337 } 4338 GetInodeNumOut: 4339 cifs_buf_release(pSMB); 4340 if (rc == -EAGAIN) 4341 goto GetInodeNumberRetry; 4342 return rc; 4343 } 4344 4345 int 4346 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses, 4347 const char *search_name, struct dfs_info3_param **target_nodes, 4348 unsigned int *num_of_nodes, 4349 const struct nls_table *nls_codepage, int remap) 4350 { 4351 /* TRANS2_GET_DFS_REFERRAL */ 4352 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; 4353 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL; 4354 int rc = 0; 4355 int bytes_returned; 4356 int name_len; 4357 __u16 params, byte_count; 4358 *num_of_nodes = 0; 4359 *target_nodes = NULL; 4360 4361 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name); 4362 if (ses == NULL || ses->tcon_ipc == NULL) 4363 return -ENODEV; 4364 4365 getDFSRetry: 4366 /* 4367 * Use smb_init_no_reconnect() instead of smb_init() as 4368 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus 4369 * causing an infinite recursion. 4370 */ 4371 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, 4372 (void **)&pSMB, (void **)&pSMBr); 4373 if (rc) 4374 return rc; 4375 4376 /* server pointer checked in called function, 4377 but should never be null here anyway */ 4378 pSMB->hdr.Mid = get_next_mid(ses->server); 4379 pSMB->hdr.Tid = ses->tcon_ipc->tid; 4380 pSMB->hdr.Uid = ses->Suid; 4381 if (ses->capabilities & CAP_STATUS32) 4382 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; 4383 if (ses->capabilities & CAP_DFS) 4384 pSMB->hdr.Flags2 |= SMBFLG2_DFS; 4385 4386 if (ses->capabilities & CAP_UNICODE) { 4387 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 4388 name_len = 4389 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName, 4390 search_name, PATH_MAX, nls_codepage, 4391 remap); 4392 name_len++; /* trailing null */ 4393 name_len *= 2; 4394 } else { /* BB improve the check for buffer overruns BB */ 4395 name_len = copy_path_name(pSMB->RequestFileName, search_name); 4396 } 4397 4398 if (ses->server->sign) 4399 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 4400 4401 pSMB->hdr.Uid = ses->Suid; 4402 4403 params = 2 /* level */ + name_len /*includes null */ ; 4404 pSMB->TotalDataCount = 0; 4405 pSMB->DataCount = 0; 4406 pSMB->DataOffset = 0; 4407 pSMB->MaxParameterCount = 0; 4408 /* BB find exact max SMB PDU from sess structure BB */ 4409 pSMB->MaxDataCount = cpu_to_le16(4000); 4410 pSMB->MaxSetupCount = 0; 4411 pSMB->Reserved = 0; 4412 pSMB->Flags = 0; 4413 pSMB->Timeout = 0; 4414 pSMB->Reserved2 = 0; 4415 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4416 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4); 4417 pSMB->SetupCount = 1; 4418 pSMB->Reserved3 = 0; 4419 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL); 4420 byte_count = params + 3 /* pad */ ; 4421 pSMB->ParameterCount = cpu_to_le16(params); 4422 pSMB->TotalParameterCount = pSMB->ParameterCount; 4423 pSMB->MaxReferralLevel = cpu_to_le16(3); 4424 inc_rfc1001_len(pSMB, byte_count); 4425 pSMB->ByteCount = cpu_to_le16(byte_count); 4426 4427 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 4428 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4429 if (rc) { 4430 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc); 4431 goto GetDFSRefExit; 4432 } 4433 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4434 4435 /* BB Also check if enough total bytes returned? */ 4436 if (rc || get_bcc(&pSMBr->hdr) < 17) { 4437 rc = -EIO; /* bad smb */ 4438 goto GetDFSRefExit; 4439 } 4440 4441 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n", 4442 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset)); 4443 4444 /* parse returned result into more usable form */ 4445 rc = parse_dfs_referrals(&pSMBr->dfs_data, 4446 le16_to_cpu(pSMBr->t2.DataCount), 4447 num_of_nodes, target_nodes, nls_codepage, 4448 remap, search_name, 4449 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0); 4450 4451 GetDFSRefExit: 4452 cifs_buf_release(pSMB); 4453 4454 if (rc == -EAGAIN) 4455 goto getDFSRetry; 4456 4457 return rc; 4458 } 4459 4460 /* Query File System Info such as free space to old servers such as Win 9x */ 4461 int 4462 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 4463 struct kstatfs *FSData) 4464 { 4465 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */ 4466 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4467 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4468 FILE_SYSTEM_ALLOC_INFO *response_data; 4469 int rc = 0; 4470 int bytes_returned = 0; 4471 __u16 params, byte_count; 4472 4473 cifs_dbg(FYI, "OldQFSInfo\n"); 4474 oldQFSInfoRetry: 4475 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4476 (void **) &pSMBr); 4477 if (rc) 4478 return rc; 4479 4480 params = 2; /* level */ 4481 pSMB->TotalDataCount = 0; 4482 pSMB->MaxParameterCount = cpu_to_le16(2); 4483 pSMB->MaxDataCount = cpu_to_le16(1000); 4484 pSMB->MaxSetupCount = 0; 4485 pSMB->Reserved = 0; 4486 pSMB->Flags = 0; 4487 pSMB->Timeout = 0; 4488 pSMB->Reserved2 = 0; 4489 byte_count = params + 1 /* pad */ ; 4490 pSMB->TotalParameterCount = cpu_to_le16(params); 4491 pSMB->ParameterCount = pSMB->TotalParameterCount; 4492 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4493 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4494 pSMB->DataCount = 0; 4495 pSMB->DataOffset = 0; 4496 pSMB->SetupCount = 1; 4497 pSMB->Reserved3 = 0; 4498 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4499 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION); 4500 inc_rfc1001_len(pSMB, byte_count); 4501 pSMB->ByteCount = cpu_to_le16(byte_count); 4502 4503 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4504 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4505 if (rc) { 4506 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 4507 } else { /* decode response */ 4508 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4509 4510 if (rc || get_bcc(&pSMBr->hdr) < 18) 4511 rc = -EIO; /* bad smb */ 4512 else { 4513 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4514 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n", 4515 get_bcc(&pSMBr->hdr), data_offset); 4516 4517 response_data = (FILE_SYSTEM_ALLOC_INFO *) 4518 (((char *) &pSMBr->hdr.Protocol) + data_offset); 4519 FSData->f_bsize = 4520 le16_to_cpu(response_data->BytesPerSector) * 4521 le32_to_cpu(response_data-> 4522 SectorsPerAllocationUnit); 4523 /* 4524 * much prefer larger but if server doesn't report 4525 * a valid size than 4K is a reasonable minimum 4526 */ 4527 if (FSData->f_bsize < 512) 4528 FSData->f_bsize = 4096; 4529 4530 FSData->f_blocks = 4531 le32_to_cpu(response_data->TotalAllocationUnits); 4532 FSData->f_bfree = FSData->f_bavail = 4533 le32_to_cpu(response_data->FreeAllocationUnits); 4534 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 4535 (unsigned long long)FSData->f_blocks, 4536 (unsigned long long)FSData->f_bfree, 4537 FSData->f_bsize); 4538 } 4539 } 4540 cifs_buf_release(pSMB); 4541 4542 if (rc == -EAGAIN) 4543 goto oldQFSInfoRetry; 4544 4545 return rc; 4546 } 4547 4548 int 4549 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 4550 struct kstatfs *FSData) 4551 { 4552 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ 4553 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4554 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4555 FILE_SYSTEM_INFO *response_data; 4556 int rc = 0; 4557 int bytes_returned = 0; 4558 __u16 params, byte_count; 4559 4560 cifs_dbg(FYI, "In QFSInfo\n"); 4561 QFSInfoRetry: 4562 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4563 (void **) &pSMBr); 4564 if (rc) 4565 return rc; 4566 4567 params = 2; /* level */ 4568 pSMB->TotalDataCount = 0; 4569 pSMB->MaxParameterCount = cpu_to_le16(2); 4570 pSMB->MaxDataCount = cpu_to_le16(1000); 4571 pSMB->MaxSetupCount = 0; 4572 pSMB->Reserved = 0; 4573 pSMB->Flags = 0; 4574 pSMB->Timeout = 0; 4575 pSMB->Reserved2 = 0; 4576 byte_count = params + 1 /* pad */ ; 4577 pSMB->TotalParameterCount = cpu_to_le16(params); 4578 pSMB->ParameterCount = pSMB->TotalParameterCount; 4579 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4580 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4581 pSMB->DataCount = 0; 4582 pSMB->DataOffset = 0; 4583 pSMB->SetupCount = 1; 4584 pSMB->Reserved3 = 0; 4585 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4586 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO); 4587 inc_rfc1001_len(pSMB, byte_count); 4588 pSMB->ByteCount = cpu_to_le16(byte_count); 4589 4590 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4591 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4592 if (rc) { 4593 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 4594 } else { /* decode response */ 4595 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4596 4597 if (rc || get_bcc(&pSMBr->hdr) < 24) 4598 rc = -EIO; /* bad smb */ 4599 else { 4600 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4601 4602 response_data = 4603 (FILE_SYSTEM_INFO 4604 *) (((char *) &pSMBr->hdr.Protocol) + 4605 data_offset); 4606 FSData->f_bsize = 4607 le32_to_cpu(response_data->BytesPerSector) * 4608 le32_to_cpu(response_data-> 4609 SectorsPerAllocationUnit); 4610 /* 4611 * much prefer larger but if server doesn't report 4612 * a valid size than 4K is a reasonable minimum 4613 */ 4614 if (FSData->f_bsize < 512) 4615 FSData->f_bsize = 4096; 4616 4617 FSData->f_blocks = 4618 le64_to_cpu(response_data->TotalAllocationUnits); 4619 FSData->f_bfree = FSData->f_bavail = 4620 le64_to_cpu(response_data->FreeAllocationUnits); 4621 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 4622 (unsigned long long)FSData->f_blocks, 4623 (unsigned long long)FSData->f_bfree, 4624 FSData->f_bsize); 4625 } 4626 } 4627 cifs_buf_release(pSMB); 4628 4629 if (rc == -EAGAIN) 4630 goto QFSInfoRetry; 4631 4632 return rc; 4633 } 4634 4635 int 4636 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon) 4637 { 4638 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ 4639 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4640 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4641 FILE_SYSTEM_ATTRIBUTE_INFO *response_data; 4642 int rc = 0; 4643 int bytes_returned = 0; 4644 __u16 params, byte_count; 4645 4646 cifs_dbg(FYI, "In QFSAttributeInfo\n"); 4647 QFSAttributeRetry: 4648 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4649 (void **) &pSMBr); 4650 if (rc) 4651 return rc; 4652 4653 params = 2; /* level */ 4654 pSMB->TotalDataCount = 0; 4655 pSMB->MaxParameterCount = cpu_to_le16(2); 4656 /* BB find exact max SMB PDU from sess structure BB */ 4657 pSMB->MaxDataCount = cpu_to_le16(1000); 4658 pSMB->MaxSetupCount = 0; 4659 pSMB->Reserved = 0; 4660 pSMB->Flags = 0; 4661 pSMB->Timeout = 0; 4662 pSMB->Reserved2 = 0; 4663 byte_count = params + 1 /* pad */ ; 4664 pSMB->TotalParameterCount = cpu_to_le16(params); 4665 pSMB->ParameterCount = pSMB->TotalParameterCount; 4666 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4667 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4668 pSMB->DataCount = 0; 4669 pSMB->DataOffset = 0; 4670 pSMB->SetupCount = 1; 4671 pSMB->Reserved3 = 0; 4672 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4673 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO); 4674 inc_rfc1001_len(pSMB, byte_count); 4675 pSMB->ByteCount = cpu_to_le16(byte_count); 4676 4677 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4678 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4679 if (rc) { 4680 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc); 4681 } else { /* decode response */ 4682 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4683 4684 if (rc || get_bcc(&pSMBr->hdr) < 13) { 4685 /* BB also check if enough bytes returned */ 4686 rc = -EIO; /* bad smb */ 4687 } else { 4688 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4689 response_data = 4690 (FILE_SYSTEM_ATTRIBUTE_INFO 4691 *) (((char *) &pSMBr->hdr.Protocol) + 4692 data_offset); 4693 memcpy(&tcon->fsAttrInfo, response_data, 4694 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)); 4695 } 4696 } 4697 cifs_buf_release(pSMB); 4698 4699 if (rc == -EAGAIN) 4700 goto QFSAttributeRetry; 4701 4702 return rc; 4703 } 4704 4705 int 4706 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon) 4707 { 4708 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ 4709 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4710 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4711 FILE_SYSTEM_DEVICE_INFO *response_data; 4712 int rc = 0; 4713 int bytes_returned = 0; 4714 __u16 params, byte_count; 4715 4716 cifs_dbg(FYI, "In QFSDeviceInfo\n"); 4717 QFSDeviceRetry: 4718 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4719 (void **) &pSMBr); 4720 if (rc) 4721 return rc; 4722 4723 params = 2; /* level */ 4724 pSMB->TotalDataCount = 0; 4725 pSMB->MaxParameterCount = cpu_to_le16(2); 4726 /* BB find exact max SMB PDU from sess structure BB */ 4727 pSMB->MaxDataCount = cpu_to_le16(1000); 4728 pSMB->MaxSetupCount = 0; 4729 pSMB->Reserved = 0; 4730 pSMB->Flags = 0; 4731 pSMB->Timeout = 0; 4732 pSMB->Reserved2 = 0; 4733 byte_count = params + 1 /* pad */ ; 4734 pSMB->TotalParameterCount = cpu_to_le16(params); 4735 pSMB->ParameterCount = pSMB->TotalParameterCount; 4736 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4737 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4738 4739 pSMB->DataCount = 0; 4740 pSMB->DataOffset = 0; 4741 pSMB->SetupCount = 1; 4742 pSMB->Reserved3 = 0; 4743 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4744 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO); 4745 inc_rfc1001_len(pSMB, byte_count); 4746 pSMB->ByteCount = cpu_to_le16(byte_count); 4747 4748 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4749 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4750 if (rc) { 4751 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc); 4752 } else { /* decode response */ 4753 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4754 4755 if (rc || get_bcc(&pSMBr->hdr) < 4756 sizeof(FILE_SYSTEM_DEVICE_INFO)) 4757 rc = -EIO; /* bad smb */ 4758 else { 4759 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4760 response_data = 4761 (FILE_SYSTEM_DEVICE_INFO *) 4762 (((char *) &pSMBr->hdr.Protocol) + 4763 data_offset); 4764 memcpy(&tcon->fsDevInfo, response_data, 4765 sizeof(FILE_SYSTEM_DEVICE_INFO)); 4766 } 4767 } 4768 cifs_buf_release(pSMB); 4769 4770 if (rc == -EAGAIN) 4771 goto QFSDeviceRetry; 4772 4773 return rc; 4774 } 4775 4776 int 4777 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon) 4778 { 4779 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ 4780 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4781 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4782 FILE_SYSTEM_UNIX_INFO *response_data; 4783 int rc = 0; 4784 int bytes_returned = 0; 4785 __u16 params, byte_count; 4786 4787 cifs_dbg(FYI, "In QFSUnixInfo\n"); 4788 QFSUnixRetry: 4789 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 4790 (void **) &pSMB, (void **) &pSMBr); 4791 if (rc) 4792 return rc; 4793 4794 params = 2; /* level */ 4795 pSMB->TotalDataCount = 0; 4796 pSMB->DataCount = 0; 4797 pSMB->DataOffset = 0; 4798 pSMB->MaxParameterCount = cpu_to_le16(2); 4799 /* BB find exact max SMB PDU from sess structure BB */ 4800 pSMB->MaxDataCount = cpu_to_le16(100); 4801 pSMB->MaxSetupCount = 0; 4802 pSMB->Reserved = 0; 4803 pSMB->Flags = 0; 4804 pSMB->Timeout = 0; 4805 pSMB->Reserved2 = 0; 4806 byte_count = params + 1 /* pad */ ; 4807 pSMB->ParameterCount = cpu_to_le16(params); 4808 pSMB->TotalParameterCount = pSMB->ParameterCount; 4809 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 4810 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4811 pSMB->SetupCount = 1; 4812 pSMB->Reserved3 = 0; 4813 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4814 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO); 4815 inc_rfc1001_len(pSMB, byte_count); 4816 pSMB->ByteCount = cpu_to_le16(byte_count); 4817 4818 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4819 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4820 if (rc) { 4821 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc); 4822 } else { /* decode response */ 4823 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4824 4825 if (rc || get_bcc(&pSMBr->hdr) < 13) { 4826 rc = -EIO; /* bad smb */ 4827 } else { 4828 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4829 response_data = 4830 (FILE_SYSTEM_UNIX_INFO 4831 *) (((char *) &pSMBr->hdr.Protocol) + 4832 data_offset); 4833 memcpy(&tcon->fsUnixInfo, response_data, 4834 sizeof(FILE_SYSTEM_UNIX_INFO)); 4835 } 4836 } 4837 cifs_buf_release(pSMB); 4838 4839 if (rc == -EAGAIN) 4840 goto QFSUnixRetry; 4841 4842 4843 return rc; 4844 } 4845 4846 int 4847 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap) 4848 { 4849 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */ 4850 TRANSACTION2_SETFSI_REQ *pSMB = NULL; 4851 TRANSACTION2_SETFSI_RSP *pSMBr = NULL; 4852 int rc = 0; 4853 int bytes_returned = 0; 4854 __u16 params, param_offset, offset, byte_count; 4855 4856 cifs_dbg(FYI, "In SETFSUnixInfo\n"); 4857 SETFSUnixRetry: 4858 /* BB switch to small buf init to save memory */ 4859 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 4860 (void **) &pSMB, (void **) &pSMBr); 4861 if (rc) 4862 return rc; 4863 4864 params = 4; /* 2 bytes zero followed by info level. */ 4865 pSMB->MaxSetupCount = 0; 4866 pSMB->Reserved = 0; 4867 pSMB->Flags = 0; 4868 pSMB->Timeout = 0; 4869 pSMB->Reserved2 = 0; 4870 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) 4871 - 4; 4872 offset = param_offset + params; 4873 4874 pSMB->MaxParameterCount = cpu_to_le16(4); 4875 /* BB find exact max SMB PDU from sess structure BB */ 4876 pSMB->MaxDataCount = cpu_to_le16(100); 4877 pSMB->SetupCount = 1; 4878 pSMB->Reserved3 = 0; 4879 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION); 4880 byte_count = 1 /* pad */ + params + 12; 4881 4882 pSMB->DataCount = cpu_to_le16(12); 4883 pSMB->ParameterCount = cpu_to_le16(params); 4884 pSMB->TotalDataCount = pSMB->DataCount; 4885 pSMB->TotalParameterCount = pSMB->ParameterCount; 4886 pSMB->ParameterOffset = cpu_to_le16(param_offset); 4887 pSMB->DataOffset = cpu_to_le16(offset); 4888 4889 /* Params. */ 4890 pSMB->FileNum = 0; 4891 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO); 4892 4893 /* Data. */ 4894 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION); 4895 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION); 4896 pSMB->ClientUnixCap = cpu_to_le64(cap); 4897 4898 inc_rfc1001_len(pSMB, byte_count); 4899 pSMB->ByteCount = cpu_to_le16(byte_count); 4900 4901 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4902 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4903 if (rc) { 4904 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc); 4905 } else { /* decode response */ 4906 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4907 if (rc) 4908 rc = -EIO; /* bad smb */ 4909 } 4910 cifs_buf_release(pSMB); 4911 4912 if (rc == -EAGAIN) 4913 goto SETFSUnixRetry; 4914 4915 return rc; 4916 } 4917 4918 4919 4920 int 4921 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon, 4922 struct kstatfs *FSData) 4923 { 4924 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ 4925 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4926 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4927 FILE_SYSTEM_POSIX_INFO *response_data; 4928 int rc = 0; 4929 int bytes_returned = 0; 4930 __u16 params, byte_count; 4931 4932 cifs_dbg(FYI, "In QFSPosixInfo\n"); 4933 QFSPosixRetry: 4934 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4935 (void **) &pSMBr); 4936 if (rc) 4937 return rc; 4938 4939 params = 2; /* level */ 4940 pSMB->TotalDataCount = 0; 4941 pSMB->DataCount = 0; 4942 pSMB->DataOffset = 0; 4943 pSMB->MaxParameterCount = cpu_to_le16(2); 4944 /* BB find exact max SMB PDU from sess structure BB */ 4945 pSMB->MaxDataCount = cpu_to_le16(100); 4946 pSMB->MaxSetupCount = 0; 4947 pSMB->Reserved = 0; 4948 pSMB->Flags = 0; 4949 pSMB->Timeout = 0; 4950 pSMB->Reserved2 = 0; 4951 byte_count = params + 1 /* pad */ ; 4952 pSMB->ParameterCount = cpu_to_le16(params); 4953 pSMB->TotalParameterCount = pSMB->ParameterCount; 4954 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 4955 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4956 pSMB->SetupCount = 1; 4957 pSMB->Reserved3 = 0; 4958 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4959 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO); 4960 inc_rfc1001_len(pSMB, byte_count); 4961 pSMB->ByteCount = cpu_to_le16(byte_count); 4962 4963 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4964 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4965 if (rc) { 4966 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc); 4967 } else { /* decode response */ 4968 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4969 4970 if (rc || get_bcc(&pSMBr->hdr) < 13) { 4971 rc = -EIO; /* bad smb */ 4972 } else { 4973 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4974 response_data = 4975 (FILE_SYSTEM_POSIX_INFO 4976 *) (((char *) &pSMBr->hdr.Protocol) + 4977 data_offset); 4978 FSData->f_bsize = 4979 le32_to_cpu(response_data->BlockSize); 4980 /* 4981 * much prefer larger but if server doesn't report 4982 * a valid size than 4K is a reasonable minimum 4983 */ 4984 if (FSData->f_bsize < 512) 4985 FSData->f_bsize = 4096; 4986 4987 FSData->f_blocks = 4988 le64_to_cpu(response_data->TotalBlocks); 4989 FSData->f_bfree = 4990 le64_to_cpu(response_data->BlocksAvail); 4991 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) { 4992 FSData->f_bavail = FSData->f_bfree; 4993 } else { 4994 FSData->f_bavail = 4995 le64_to_cpu(response_data->UserBlocksAvail); 4996 } 4997 if (response_data->TotalFileNodes != cpu_to_le64(-1)) 4998 FSData->f_files = 4999 le64_to_cpu(response_data->TotalFileNodes); 5000 if (response_data->FreeFileNodes != cpu_to_le64(-1)) 5001 FSData->f_ffree = 5002 le64_to_cpu(response_data->FreeFileNodes); 5003 } 5004 } 5005 cifs_buf_release(pSMB); 5006 5007 if (rc == -EAGAIN) 5008 goto QFSPosixRetry; 5009 5010 return rc; 5011 } 5012 5013 5014 /* 5015 * We can not use write of zero bytes trick to set file size due to need for 5016 * large file support. Also note that this SetPathInfo is preferred to 5017 * SetFileInfo based method in next routine which is only needed to work around 5018 * a sharing violation bugin Samba which this routine can run into. 5019 */ 5020 int 5021 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon, 5022 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb, 5023 bool set_allocation) 5024 { 5025 struct smb_com_transaction2_spi_req *pSMB = NULL; 5026 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5027 struct file_end_of_file_info *parm_data; 5028 int name_len; 5029 int rc = 0; 5030 int bytes_returned = 0; 5031 int remap = cifs_remap(cifs_sb); 5032 5033 __u16 params, byte_count, data_count, param_offset, offset; 5034 5035 cifs_dbg(FYI, "In SetEOF\n"); 5036 SetEOFRetry: 5037 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5038 (void **) &pSMBr); 5039 if (rc) 5040 return rc; 5041 5042 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5043 name_len = 5044 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 5045 PATH_MAX, cifs_sb->local_nls, remap); 5046 name_len++; /* trailing null */ 5047 name_len *= 2; 5048 } else { 5049 name_len = copy_path_name(pSMB->FileName, file_name); 5050 } 5051 params = 6 + name_len; 5052 data_count = sizeof(struct file_end_of_file_info); 5053 pSMB->MaxParameterCount = cpu_to_le16(2); 5054 pSMB->MaxDataCount = cpu_to_le16(4100); 5055 pSMB->MaxSetupCount = 0; 5056 pSMB->Reserved = 0; 5057 pSMB->Flags = 0; 5058 pSMB->Timeout = 0; 5059 pSMB->Reserved2 = 0; 5060 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5061 InformationLevel) - 4; 5062 offset = param_offset + params; 5063 if (set_allocation) { 5064 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5065 pSMB->InformationLevel = 5066 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5067 else 5068 pSMB->InformationLevel = 5069 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5070 } else /* Set File Size */ { 5071 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5072 pSMB->InformationLevel = 5073 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5074 else 5075 pSMB->InformationLevel = 5076 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5077 } 5078 5079 parm_data = 5080 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) + 5081 offset); 5082 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5083 pSMB->DataOffset = cpu_to_le16(offset); 5084 pSMB->SetupCount = 1; 5085 pSMB->Reserved3 = 0; 5086 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5087 byte_count = 3 /* pad */ + params + data_count; 5088 pSMB->DataCount = cpu_to_le16(data_count); 5089 pSMB->TotalDataCount = pSMB->DataCount; 5090 pSMB->ParameterCount = cpu_to_le16(params); 5091 pSMB->TotalParameterCount = pSMB->ParameterCount; 5092 pSMB->Reserved4 = 0; 5093 inc_rfc1001_len(pSMB, byte_count); 5094 parm_data->FileSize = cpu_to_le64(size); 5095 pSMB->ByteCount = cpu_to_le16(byte_count); 5096 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5097 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5098 if (rc) 5099 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc); 5100 5101 cifs_buf_release(pSMB); 5102 5103 if (rc == -EAGAIN) 5104 goto SetEOFRetry; 5105 5106 return rc; 5107 } 5108 5109 int 5110 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, 5111 struct cifsFileInfo *cfile, __u64 size, bool set_allocation) 5112 { 5113 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5114 struct file_end_of_file_info *parm_data; 5115 int rc = 0; 5116 __u16 params, param_offset, offset, byte_count, count; 5117 5118 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n", 5119 (long long)size); 5120 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5121 5122 if (rc) 5123 return rc; 5124 5125 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid); 5126 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16)); 5127 5128 params = 6; 5129 pSMB->MaxSetupCount = 0; 5130 pSMB->Reserved = 0; 5131 pSMB->Flags = 0; 5132 pSMB->Timeout = 0; 5133 pSMB->Reserved2 = 0; 5134 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5135 offset = param_offset + params; 5136 5137 count = sizeof(struct file_end_of_file_info); 5138 pSMB->MaxParameterCount = cpu_to_le16(2); 5139 /* BB find exact max SMB PDU from sess structure BB */ 5140 pSMB->MaxDataCount = cpu_to_le16(1000); 5141 pSMB->SetupCount = 1; 5142 pSMB->Reserved3 = 0; 5143 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5144 byte_count = 3 /* pad */ + params + count; 5145 pSMB->DataCount = cpu_to_le16(count); 5146 pSMB->ParameterCount = cpu_to_le16(params); 5147 pSMB->TotalDataCount = pSMB->DataCount; 5148 pSMB->TotalParameterCount = pSMB->ParameterCount; 5149 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5150 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5151 parm_data = 5152 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4); 5153 pSMB->DataOffset = cpu_to_le16(offset); 5154 parm_data->FileSize = cpu_to_le64(size); 5155 pSMB->Fid = cfile->fid.netfid; 5156 if (set_allocation) { 5157 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5158 pSMB->InformationLevel = 5159 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5160 else 5161 pSMB->InformationLevel = 5162 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5163 } else /* Set File Size */ { 5164 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5165 pSMB->InformationLevel = 5166 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5167 else 5168 pSMB->InformationLevel = 5169 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5170 } 5171 pSMB->Reserved4 = 0; 5172 inc_rfc1001_len(pSMB, byte_count); 5173 pSMB->ByteCount = cpu_to_le16(byte_count); 5174 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5175 cifs_small_buf_release(pSMB); 5176 if (rc) { 5177 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n", 5178 rc); 5179 } 5180 5181 /* Note: On -EAGAIN error only caller can retry on handle based calls 5182 since file handle passed in no longer valid */ 5183 5184 return rc; 5185 } 5186 5187 /* Some legacy servers such as NT4 require that the file times be set on 5188 an open handle, rather than by pathname - this is awkward due to 5189 potential access conflicts on the open, but it is unavoidable for these 5190 old servers since the only other choice is to go from 100 nanosecond DCE 5191 time and resort to the original setpathinfo level which takes the ancient 5192 DOS time format with 2 second granularity */ 5193 int 5194 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 5195 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener) 5196 { 5197 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5198 char *data_offset; 5199 int rc = 0; 5200 __u16 params, param_offset, offset, byte_count, count; 5201 5202 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n"); 5203 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5204 5205 if (rc) 5206 return rc; 5207 5208 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5209 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5210 5211 params = 6; 5212 pSMB->MaxSetupCount = 0; 5213 pSMB->Reserved = 0; 5214 pSMB->Flags = 0; 5215 pSMB->Timeout = 0; 5216 pSMB->Reserved2 = 0; 5217 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5218 offset = param_offset + params; 5219 5220 data_offset = (char *)pSMB + 5221 offsetof(struct smb_hdr, Protocol) + offset; 5222 5223 count = sizeof(FILE_BASIC_INFO); 5224 pSMB->MaxParameterCount = cpu_to_le16(2); 5225 /* BB find max SMB PDU from sess */ 5226 pSMB->MaxDataCount = cpu_to_le16(1000); 5227 pSMB->SetupCount = 1; 5228 pSMB->Reserved3 = 0; 5229 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5230 byte_count = 3 /* pad */ + params + count; 5231 pSMB->DataCount = cpu_to_le16(count); 5232 pSMB->ParameterCount = cpu_to_le16(params); 5233 pSMB->TotalDataCount = pSMB->DataCount; 5234 pSMB->TotalParameterCount = pSMB->ParameterCount; 5235 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5236 pSMB->DataOffset = cpu_to_le16(offset); 5237 pSMB->Fid = fid; 5238 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5239 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5240 else 5241 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5242 pSMB->Reserved4 = 0; 5243 inc_rfc1001_len(pSMB, byte_count); 5244 pSMB->ByteCount = cpu_to_le16(byte_count); 5245 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5246 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5247 cifs_small_buf_release(pSMB); 5248 if (rc) 5249 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 5250 rc); 5251 5252 /* Note: On -EAGAIN error only caller can retry on handle based calls 5253 since file handle passed in no longer valid */ 5254 5255 return rc; 5256 } 5257 5258 int 5259 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon, 5260 bool delete_file, __u16 fid, __u32 pid_of_opener) 5261 { 5262 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5263 char *data_offset; 5264 int rc = 0; 5265 __u16 params, param_offset, offset, byte_count, count; 5266 5267 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n"); 5268 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5269 5270 if (rc) 5271 return rc; 5272 5273 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5274 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5275 5276 params = 6; 5277 pSMB->MaxSetupCount = 0; 5278 pSMB->Reserved = 0; 5279 pSMB->Flags = 0; 5280 pSMB->Timeout = 0; 5281 pSMB->Reserved2 = 0; 5282 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5283 offset = param_offset + params; 5284 5285 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5286 data_offset = (char *)(pSMB) + offset + 4; 5287 5288 count = 1; 5289 pSMB->MaxParameterCount = cpu_to_le16(2); 5290 /* BB find max SMB PDU from sess */ 5291 pSMB->MaxDataCount = cpu_to_le16(1000); 5292 pSMB->SetupCount = 1; 5293 pSMB->Reserved3 = 0; 5294 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5295 byte_count = 3 /* pad */ + params + count; 5296 pSMB->DataCount = cpu_to_le16(count); 5297 pSMB->ParameterCount = cpu_to_le16(params); 5298 pSMB->TotalDataCount = pSMB->DataCount; 5299 pSMB->TotalParameterCount = pSMB->ParameterCount; 5300 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5301 pSMB->DataOffset = cpu_to_le16(offset); 5302 pSMB->Fid = fid; 5303 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO); 5304 pSMB->Reserved4 = 0; 5305 inc_rfc1001_len(pSMB, byte_count); 5306 pSMB->ByteCount = cpu_to_le16(byte_count); 5307 *data_offset = delete_file ? 1 : 0; 5308 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5309 cifs_small_buf_release(pSMB); 5310 if (rc) 5311 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc); 5312 5313 return rc; 5314 } 5315 5316 static int 5317 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon, 5318 const char *fileName, const FILE_BASIC_INFO *data, 5319 const struct nls_table *nls_codepage, 5320 struct cifs_sb_info *cifs_sb) 5321 { 5322 int oplock = 0; 5323 struct cifs_open_parms oparms; 5324 struct cifs_fid fid; 5325 int rc; 5326 5327 oparms = (struct cifs_open_parms) { 5328 .tcon = tcon, 5329 .cifs_sb = cifs_sb, 5330 .desired_access = GENERIC_WRITE, 5331 .create_options = cifs_create_options(cifs_sb, 0), 5332 .disposition = FILE_OPEN, 5333 .path = fileName, 5334 .fid = &fid, 5335 }; 5336 5337 rc = CIFS_open(xid, &oparms, &oplock, NULL); 5338 if (rc) 5339 goto out; 5340 5341 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid); 5342 CIFSSMBClose(xid, tcon, fid.netfid); 5343 out: 5344 5345 return rc; 5346 } 5347 5348 int 5349 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5350 const char *fileName, const FILE_BASIC_INFO *data, 5351 const struct nls_table *nls_codepage, 5352 struct cifs_sb_info *cifs_sb) 5353 { 5354 TRANSACTION2_SPI_REQ *pSMB = NULL; 5355 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5356 int name_len; 5357 int rc = 0; 5358 int bytes_returned = 0; 5359 char *data_offset; 5360 __u16 params, param_offset, offset, byte_count, count; 5361 int remap = cifs_remap(cifs_sb); 5362 5363 cifs_dbg(FYI, "In SetTimes\n"); 5364 5365 SetTimesRetry: 5366 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5367 (void **) &pSMBr); 5368 if (rc) 5369 return rc; 5370 5371 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5372 name_len = 5373 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 5374 PATH_MAX, nls_codepage, remap); 5375 name_len++; /* trailing null */ 5376 name_len *= 2; 5377 } else { 5378 name_len = copy_path_name(pSMB->FileName, fileName); 5379 } 5380 5381 params = 6 + name_len; 5382 count = sizeof(FILE_BASIC_INFO); 5383 pSMB->MaxParameterCount = cpu_to_le16(2); 5384 /* BB find max SMB PDU from sess structure BB */ 5385 pSMB->MaxDataCount = cpu_to_le16(1000); 5386 pSMB->MaxSetupCount = 0; 5387 pSMB->Reserved = 0; 5388 pSMB->Flags = 0; 5389 pSMB->Timeout = 0; 5390 pSMB->Reserved2 = 0; 5391 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5392 InformationLevel) - 4; 5393 offset = param_offset + params; 5394 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 5395 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5396 pSMB->DataOffset = cpu_to_le16(offset); 5397 pSMB->SetupCount = 1; 5398 pSMB->Reserved3 = 0; 5399 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5400 byte_count = 3 /* pad */ + params + count; 5401 5402 pSMB->DataCount = cpu_to_le16(count); 5403 pSMB->ParameterCount = cpu_to_le16(params); 5404 pSMB->TotalDataCount = pSMB->DataCount; 5405 pSMB->TotalParameterCount = pSMB->ParameterCount; 5406 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5407 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5408 else 5409 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5410 pSMB->Reserved4 = 0; 5411 inc_rfc1001_len(pSMB, byte_count); 5412 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5413 pSMB->ByteCount = cpu_to_le16(byte_count); 5414 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5415 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5416 if (rc) 5417 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc); 5418 5419 cifs_buf_release(pSMB); 5420 5421 if (rc == -EAGAIN) 5422 goto SetTimesRetry; 5423 5424 if (rc == -EOPNOTSUPP) 5425 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data, 5426 nls_codepage, cifs_sb); 5427 5428 return rc; 5429 } 5430 5431 static void 5432 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, 5433 const struct cifs_unix_set_info_args *args) 5434 { 5435 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64; 5436 u64 mode = args->mode; 5437 5438 if (uid_valid(args->uid)) 5439 uid = from_kuid(&init_user_ns, args->uid); 5440 if (gid_valid(args->gid)) 5441 gid = from_kgid(&init_user_ns, args->gid); 5442 5443 /* 5444 * Samba server ignores set of file size to zero due to bugs in some 5445 * older clients, but we should be precise - we use SetFileSize to 5446 * set file size and do not want to truncate file size to zero 5447 * accidentally as happened on one Samba server beta by putting 5448 * zero instead of -1 here 5449 */ 5450 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); 5451 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); 5452 data_offset->LastStatusChange = cpu_to_le64(args->ctime); 5453 data_offset->LastAccessTime = cpu_to_le64(args->atime); 5454 data_offset->LastModificationTime = cpu_to_le64(args->mtime); 5455 data_offset->Uid = cpu_to_le64(uid); 5456 data_offset->Gid = cpu_to_le64(gid); 5457 /* better to leave device as zero when it is */ 5458 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); 5459 data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); 5460 data_offset->Permissions = cpu_to_le64(mode); 5461 5462 if (S_ISREG(mode)) 5463 data_offset->Type = cpu_to_le32(UNIX_FILE); 5464 else if (S_ISDIR(mode)) 5465 data_offset->Type = cpu_to_le32(UNIX_DIR); 5466 else if (S_ISLNK(mode)) 5467 data_offset->Type = cpu_to_le32(UNIX_SYMLINK); 5468 else if (S_ISCHR(mode)) 5469 data_offset->Type = cpu_to_le32(UNIX_CHARDEV); 5470 else if (S_ISBLK(mode)) 5471 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); 5472 else if (S_ISFIFO(mode)) 5473 data_offset->Type = cpu_to_le32(UNIX_FIFO); 5474 else if (S_ISSOCK(mode)) 5475 data_offset->Type = cpu_to_le32(UNIX_SOCKET); 5476 } 5477 5478 int 5479 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 5480 const struct cifs_unix_set_info_args *args, 5481 u16 fid, u32 pid_of_opener) 5482 { 5483 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5484 char *data_offset; 5485 int rc = 0; 5486 u16 params, param_offset, offset, byte_count, count; 5487 5488 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n"); 5489 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5490 5491 if (rc) 5492 return rc; 5493 5494 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5495 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5496 5497 params = 6; 5498 pSMB->MaxSetupCount = 0; 5499 pSMB->Reserved = 0; 5500 pSMB->Flags = 0; 5501 pSMB->Timeout = 0; 5502 pSMB->Reserved2 = 0; 5503 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5504 offset = param_offset + params; 5505 5506 data_offset = (char *)pSMB + 5507 offsetof(struct smb_hdr, Protocol) + offset; 5508 5509 count = sizeof(FILE_UNIX_BASIC_INFO); 5510 5511 pSMB->MaxParameterCount = cpu_to_le16(2); 5512 /* BB find max SMB PDU from sess */ 5513 pSMB->MaxDataCount = cpu_to_le16(1000); 5514 pSMB->SetupCount = 1; 5515 pSMB->Reserved3 = 0; 5516 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5517 byte_count = 3 /* pad */ + params + count; 5518 pSMB->DataCount = cpu_to_le16(count); 5519 pSMB->ParameterCount = cpu_to_le16(params); 5520 pSMB->TotalDataCount = pSMB->DataCount; 5521 pSMB->TotalParameterCount = pSMB->ParameterCount; 5522 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5523 pSMB->DataOffset = cpu_to_le16(offset); 5524 pSMB->Fid = fid; 5525 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5526 pSMB->Reserved4 = 0; 5527 inc_rfc1001_len(pSMB, byte_count); 5528 pSMB->ByteCount = cpu_to_le16(byte_count); 5529 5530 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args); 5531 5532 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5533 cifs_small_buf_release(pSMB); 5534 if (rc) 5535 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 5536 rc); 5537 5538 /* Note: On -EAGAIN error only caller can retry on handle based calls 5539 since file handle passed in no longer valid */ 5540 5541 return rc; 5542 } 5543 5544 int 5545 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5546 const char *file_name, 5547 const struct cifs_unix_set_info_args *args, 5548 const struct nls_table *nls_codepage, int remap) 5549 { 5550 TRANSACTION2_SPI_REQ *pSMB = NULL; 5551 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5552 int name_len; 5553 int rc = 0; 5554 int bytes_returned = 0; 5555 FILE_UNIX_BASIC_INFO *data_offset; 5556 __u16 params, param_offset, offset, count, byte_count; 5557 5558 cifs_dbg(FYI, "In SetUID/GID/Mode\n"); 5559 setPermsRetry: 5560 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5561 (void **) &pSMBr); 5562 if (rc) 5563 return rc; 5564 5565 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5566 name_len = 5567 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 5568 PATH_MAX, nls_codepage, remap); 5569 name_len++; /* trailing null */ 5570 name_len *= 2; 5571 } else { 5572 name_len = copy_path_name(pSMB->FileName, file_name); 5573 } 5574 5575 params = 6 + name_len; 5576 count = sizeof(FILE_UNIX_BASIC_INFO); 5577 pSMB->MaxParameterCount = cpu_to_le16(2); 5578 /* BB find max SMB PDU from sess structure BB */ 5579 pSMB->MaxDataCount = cpu_to_le16(1000); 5580 pSMB->MaxSetupCount = 0; 5581 pSMB->Reserved = 0; 5582 pSMB->Flags = 0; 5583 pSMB->Timeout = 0; 5584 pSMB->Reserved2 = 0; 5585 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5586 InformationLevel) - 4; 5587 offset = param_offset + params; 5588 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5589 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4); 5590 memset(data_offset, 0, count); 5591 pSMB->DataOffset = cpu_to_le16(offset); 5592 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5593 pSMB->SetupCount = 1; 5594 pSMB->Reserved3 = 0; 5595 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5596 byte_count = 3 /* pad */ + params + count; 5597 pSMB->ParameterCount = cpu_to_le16(params); 5598 pSMB->DataCount = cpu_to_le16(count); 5599 pSMB->TotalParameterCount = pSMB->ParameterCount; 5600 pSMB->TotalDataCount = pSMB->DataCount; 5601 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5602 pSMB->Reserved4 = 0; 5603 inc_rfc1001_len(pSMB, byte_count); 5604 5605 cifs_fill_unix_set_info(data_offset, args); 5606 5607 pSMB->ByteCount = cpu_to_le16(byte_count); 5608 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5609 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5610 if (rc) 5611 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc); 5612 5613 cifs_buf_release(pSMB); 5614 if (rc == -EAGAIN) 5615 goto setPermsRetry; 5616 return rc; 5617 } 5618 5619 #ifdef CONFIG_CIFS_XATTR 5620 /* 5621 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common 5622 * function used by listxattr and getxattr type calls. When ea_name is set, 5623 * it looks for that attribute name and stuffs that value into the EAData 5624 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the 5625 * buffer. In both cases, the return value is either the length of the 5626 * resulting data or a negative error code. If EAData is a NULL pointer then 5627 * the data isn't copied to it, but the length is returned. 5628 */ 5629 ssize_t 5630 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon, 5631 const unsigned char *searchName, const unsigned char *ea_name, 5632 char *EAData, size_t buf_size, 5633 struct cifs_sb_info *cifs_sb) 5634 { 5635 /* BB assumes one setup word */ 5636 TRANSACTION2_QPI_REQ *pSMB = NULL; 5637 TRANSACTION2_QPI_RSP *pSMBr = NULL; 5638 int remap = cifs_remap(cifs_sb); 5639 struct nls_table *nls_codepage = cifs_sb->local_nls; 5640 int rc = 0; 5641 int bytes_returned; 5642 int list_len; 5643 struct fealist *ea_response_data; 5644 struct fea *temp_fea; 5645 char *temp_ptr; 5646 char *end_of_smb; 5647 __u16 params, byte_count, data_offset; 5648 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0; 5649 5650 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName); 5651 QAllEAsRetry: 5652 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5653 (void **) &pSMBr); 5654 if (rc) 5655 return rc; 5656 5657 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5658 list_len = 5659 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 5660 PATH_MAX, nls_codepage, remap); 5661 list_len++; /* trailing null */ 5662 list_len *= 2; 5663 } else { 5664 list_len = copy_path_name(pSMB->FileName, searchName); 5665 } 5666 5667 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */; 5668 pSMB->TotalDataCount = 0; 5669 pSMB->MaxParameterCount = cpu_to_le16(2); 5670 /* BB find exact max SMB PDU from sess structure BB */ 5671 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 5672 pSMB->MaxSetupCount = 0; 5673 pSMB->Reserved = 0; 5674 pSMB->Flags = 0; 5675 pSMB->Timeout = 0; 5676 pSMB->Reserved2 = 0; 5677 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5678 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 5679 pSMB->DataCount = 0; 5680 pSMB->DataOffset = 0; 5681 pSMB->SetupCount = 1; 5682 pSMB->Reserved3 = 0; 5683 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 5684 byte_count = params + 1 /* pad */ ; 5685 pSMB->TotalParameterCount = cpu_to_le16(params); 5686 pSMB->ParameterCount = pSMB->TotalParameterCount; 5687 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS); 5688 pSMB->Reserved4 = 0; 5689 inc_rfc1001_len(pSMB, byte_count); 5690 pSMB->ByteCount = cpu_to_le16(byte_count); 5691 5692 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5693 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5694 if (rc) { 5695 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc); 5696 goto QAllEAsOut; 5697 } 5698 5699 5700 /* BB also check enough total bytes returned */ 5701 /* BB we need to improve the validity checking 5702 of these trans2 responses */ 5703 5704 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5705 if (rc || get_bcc(&pSMBr->hdr) < 4) { 5706 rc = -EIO; /* bad smb */ 5707 goto QAllEAsOut; 5708 } 5709 5710 /* check that length of list is not more than bcc */ 5711 /* check that each entry does not go beyond length 5712 of list */ 5713 /* check that each element of each entry does not 5714 go beyond end of list */ 5715 /* validate_trans2_offsets() */ 5716 /* BB check if start of smb + data_offset > &bcc+ bcc */ 5717 5718 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5719 ea_response_data = (struct fealist *) 5720 (((char *) &pSMBr->hdr.Protocol) + data_offset); 5721 5722 list_len = le32_to_cpu(ea_response_data->list_len); 5723 cifs_dbg(FYI, "ea length %d\n", list_len); 5724 if (list_len <= 8) { 5725 cifs_dbg(FYI, "empty EA list returned from server\n"); 5726 /* didn't find the named attribute */ 5727 if (ea_name) 5728 rc = -ENODATA; 5729 goto QAllEAsOut; 5730 } 5731 5732 /* make sure list_len doesn't go past end of SMB */ 5733 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr); 5734 if ((char *)ea_response_data + list_len > end_of_smb) { 5735 cifs_dbg(FYI, "EA list appears to go beyond SMB\n"); 5736 rc = -EIO; 5737 goto QAllEAsOut; 5738 } 5739 5740 /* account for ea list len */ 5741 list_len -= 4; 5742 temp_fea = &ea_response_data->list; 5743 temp_ptr = (char *)temp_fea; 5744 while (list_len > 0) { 5745 unsigned int name_len; 5746 __u16 value_len; 5747 5748 list_len -= 4; 5749 temp_ptr += 4; 5750 /* make sure we can read name_len and value_len */ 5751 if (list_len < 0) { 5752 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 5753 rc = -EIO; 5754 goto QAllEAsOut; 5755 } 5756 5757 name_len = temp_fea->name_len; 5758 value_len = le16_to_cpu(temp_fea->value_len); 5759 list_len -= name_len + 1 + value_len; 5760 if (list_len < 0) { 5761 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 5762 rc = -EIO; 5763 goto QAllEAsOut; 5764 } 5765 5766 if (ea_name) { 5767 if (ea_name_len == name_len && 5768 memcmp(ea_name, temp_ptr, name_len) == 0) { 5769 temp_ptr += name_len + 1; 5770 rc = value_len; 5771 if (buf_size == 0) 5772 goto QAllEAsOut; 5773 if ((size_t)value_len > buf_size) { 5774 rc = -ERANGE; 5775 goto QAllEAsOut; 5776 } 5777 memcpy(EAData, temp_ptr, value_len); 5778 goto QAllEAsOut; 5779 } 5780 } else { 5781 /* account for prefix user. and trailing null */ 5782 rc += (5 + 1 + name_len); 5783 if (rc < (int) buf_size) { 5784 memcpy(EAData, "user.", 5); 5785 EAData += 5; 5786 memcpy(EAData, temp_ptr, name_len); 5787 EAData += name_len; 5788 /* null terminate name */ 5789 *EAData = 0; 5790 ++EAData; 5791 } else if (buf_size == 0) { 5792 /* skip copy - calc size only */ 5793 } else { 5794 /* stop before overrun buffer */ 5795 rc = -ERANGE; 5796 break; 5797 } 5798 } 5799 temp_ptr += name_len + 1 + value_len; 5800 temp_fea = (struct fea *)temp_ptr; 5801 } 5802 5803 /* didn't find the named attribute */ 5804 if (ea_name) 5805 rc = -ENODATA; 5806 5807 QAllEAsOut: 5808 cifs_buf_release(pSMB); 5809 if (rc == -EAGAIN) 5810 goto QAllEAsRetry; 5811 5812 return (ssize_t)rc; 5813 } 5814 5815 int 5816 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, 5817 const char *fileName, const char *ea_name, const void *ea_value, 5818 const __u16 ea_value_len, const struct nls_table *nls_codepage, 5819 struct cifs_sb_info *cifs_sb) 5820 { 5821 struct smb_com_transaction2_spi_req *pSMB = NULL; 5822 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5823 struct fealist *parm_data; 5824 int name_len; 5825 int rc = 0; 5826 int bytes_returned = 0; 5827 __u16 params, param_offset, byte_count, offset, count; 5828 int remap = cifs_remap(cifs_sb); 5829 5830 cifs_dbg(FYI, "In SetEA\n"); 5831 SetEARetry: 5832 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5833 (void **) &pSMBr); 5834 if (rc) 5835 return rc; 5836 5837 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5838 name_len = 5839 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 5840 PATH_MAX, nls_codepage, remap); 5841 name_len++; /* trailing null */ 5842 name_len *= 2; 5843 } else { 5844 name_len = copy_path_name(pSMB->FileName, fileName); 5845 } 5846 5847 params = 6 + name_len; 5848 5849 /* done calculating parms using name_len of file name, 5850 now use name_len to calculate length of ea name 5851 we are going to create in the inode xattrs */ 5852 if (ea_name == NULL) 5853 name_len = 0; 5854 else 5855 name_len = strnlen(ea_name, 255); 5856 5857 count = sizeof(*parm_data) + 1 + ea_value_len + name_len; 5858 pSMB->MaxParameterCount = cpu_to_le16(2); 5859 /* BB find max SMB PDU from sess */ 5860 pSMB->MaxDataCount = cpu_to_le16(1000); 5861 pSMB->MaxSetupCount = 0; 5862 pSMB->Reserved = 0; 5863 pSMB->Flags = 0; 5864 pSMB->Timeout = 0; 5865 pSMB->Reserved2 = 0; 5866 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5867 InformationLevel) - 4; 5868 offset = param_offset + params; 5869 pSMB->InformationLevel = 5870 cpu_to_le16(SMB_SET_FILE_EA); 5871 5872 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset; 5873 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5874 pSMB->DataOffset = cpu_to_le16(offset); 5875 pSMB->SetupCount = 1; 5876 pSMB->Reserved3 = 0; 5877 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5878 byte_count = 3 /* pad */ + params + count; 5879 pSMB->DataCount = cpu_to_le16(count); 5880 parm_data->list_len = cpu_to_le32(count); 5881 parm_data->list.EA_flags = 0; 5882 /* we checked above that name len is less than 255 */ 5883 parm_data->list.name_len = (__u8)name_len; 5884 /* EA names are always ASCII */ 5885 if (ea_name) 5886 strncpy(parm_data->list.name, ea_name, name_len); 5887 parm_data->list.name[name_len] = '\0'; 5888 parm_data->list.value_len = cpu_to_le16(ea_value_len); 5889 /* caller ensures that ea_value_len is less than 64K but 5890 we need to ensure that it fits within the smb */ 5891 5892 /*BB add length check to see if it would fit in 5893 negotiated SMB buffer size BB */ 5894 /* if (ea_value_len > buffer_size - 512 (enough for header)) */ 5895 if (ea_value_len) 5896 memcpy(parm_data->list.name + name_len + 1, 5897 ea_value, ea_value_len); 5898 5899 pSMB->TotalDataCount = pSMB->DataCount; 5900 pSMB->ParameterCount = cpu_to_le16(params); 5901 pSMB->TotalParameterCount = pSMB->ParameterCount; 5902 pSMB->Reserved4 = 0; 5903 inc_rfc1001_len(pSMB, byte_count); 5904 pSMB->ByteCount = cpu_to_le16(byte_count); 5905 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5906 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5907 if (rc) 5908 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc); 5909 5910 cifs_buf_release(pSMB); 5911 5912 if (rc == -EAGAIN) 5913 goto SetEARetry; 5914 5915 return rc; 5916 } 5917 #endif 5918