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