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 as fifo, 1080 * socket, char or block 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, socket, char 1197 * or block and server 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_read_subreq_terminated(&rdata->subreq, rdata->result, false); 1270 } 1271 1272 static void 1273 cifs_readv_callback(struct mid_q_entry *mid) 1274 { 1275 struct cifs_io_subrequest *rdata = mid->callback_data; 1276 struct netfs_inode *ictx = netfs_inode(rdata->rreq->inode); 1277 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink); 1278 struct TCP_Server_Info *server = tcon->ses->server; 1279 struct smb_rqst rqst = { .rq_iov = rdata->iov, 1280 .rq_nvec = 2, 1281 .rq_iter = rdata->subreq.io_iter }; 1282 struct cifs_credits credits = { 1283 .value = 1, 1284 .instance = 0, 1285 .rreq_debug_id = rdata->rreq->debug_id, 1286 .rreq_debug_index = rdata->subreq.debug_index, 1287 }; 1288 1289 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n", 1290 __func__, mid->mid, mid->mid_state, rdata->result, 1291 rdata->subreq.len); 1292 1293 switch (mid->mid_state) { 1294 case MID_RESPONSE_RECEIVED: 1295 /* result already set, check signature */ 1296 if (server->sign) { 1297 int rc = 0; 1298 1299 iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes); 1300 rc = cifs_verify_signature(&rqst, server, 1301 mid->sequence_number); 1302 if (rc) 1303 cifs_dbg(VFS, "SMB signature verification returned error = %d\n", 1304 rc); 1305 } 1306 /* FIXME: should this be counted toward the initiating task? */ 1307 task_io_account_read(rdata->got_bytes); 1308 cifs_stats_bytes_read(tcon, rdata->got_bytes); 1309 break; 1310 case MID_REQUEST_SUBMITTED: 1311 case MID_RETRY_NEEDED: 1312 rdata->result = -EAGAIN; 1313 if (server->sign && rdata->got_bytes) 1314 /* reset bytes number since we can not check a sign */ 1315 rdata->got_bytes = 0; 1316 /* FIXME: should this be counted toward the initiating task? */ 1317 task_io_account_read(rdata->got_bytes); 1318 cifs_stats_bytes_read(tcon, rdata->got_bytes); 1319 break; 1320 default: 1321 rdata->result = -EIO; 1322 } 1323 1324 if (rdata->result == -ENODATA) { 1325 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 1326 rdata->result = 0; 1327 } else { 1328 size_t trans = rdata->subreq.transferred + rdata->got_bytes; 1329 if (trans < rdata->subreq.len && 1330 rdata->subreq.start + trans == ictx->remote_i_size) { 1331 __set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags); 1332 rdata->result = 0; 1333 } 1334 } 1335 1336 rdata->credits.value = 0; 1337 rdata->subreq.transferred += rdata->got_bytes; 1338 INIT_WORK(&rdata->subreq.work, cifs_readv_worker); 1339 queue_work(cifsiod_wq, &rdata->subreq.work); 1340 release_mid(mid); 1341 add_credits(server, &credits, 0); 1342 } 1343 1344 /* cifs_async_readv - send an async write, and set up mid to handle result */ 1345 int 1346 cifs_async_readv(struct cifs_io_subrequest *rdata) 1347 { 1348 int rc; 1349 READ_REQ *smb = NULL; 1350 int wct; 1351 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink); 1352 struct smb_rqst rqst = { .rq_iov = rdata->iov, 1353 .rq_nvec = 2 }; 1354 1355 cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n", 1356 __func__, rdata->subreq.start, rdata->subreq.len); 1357 1358 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1359 wct = 12; 1360 else { 1361 wct = 10; /* old style read */ 1362 if ((rdata->subreq.start >> 32) > 0) { 1363 /* can not handle this big offset for old */ 1364 return -EIO; 1365 } 1366 } 1367 1368 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb); 1369 if (rc) 1370 return rc; 1371 1372 smb->hdr.Pid = cpu_to_le16((__u16)rdata->req->pid); 1373 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->req->pid >> 16)); 1374 1375 smb->AndXCommand = 0xFF; /* none */ 1376 smb->Fid = rdata->req->cfile->fid.netfid; 1377 smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF); 1378 if (wct == 12) 1379 smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32); 1380 smb->Remaining = 0; 1381 smb->MaxCount = cpu_to_le16(rdata->subreq.len & 0xFFFF); 1382 smb->MaxCountHigh = cpu_to_le32(rdata->subreq.len >> 16); 1383 if (wct == 12) 1384 smb->ByteCount = 0; 1385 else { 1386 /* old style read */ 1387 struct smb_com_readx_req *smbr = 1388 (struct smb_com_readx_req *)smb; 1389 smbr->ByteCount = 0; 1390 } 1391 1392 /* 4 for RFC1001 length + 1 for BCC */ 1393 rdata->iov[0].iov_base = smb; 1394 rdata->iov[0].iov_len = 4; 1395 rdata->iov[1].iov_base = (char *)smb + 4; 1396 rdata->iov[1].iov_len = get_rfc1002_length(smb); 1397 1398 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive, 1399 cifs_readv_callback, NULL, rdata, 0, NULL); 1400 1401 if (rc == 0) 1402 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1403 cifs_small_buf_release(smb); 1404 return rc; 1405 } 1406 1407 int 1408 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms, 1409 unsigned int *nbytes, char **buf, int *pbuf_type) 1410 { 1411 int rc = -EACCES; 1412 READ_REQ *pSMB = NULL; 1413 READ_RSP *pSMBr = NULL; 1414 char *pReadData = NULL; 1415 int wct; 1416 int resp_buf_type = 0; 1417 struct kvec iov[1]; 1418 struct kvec rsp_iov; 1419 __u32 pid = io_parms->pid; 1420 __u16 netfid = io_parms->netfid; 1421 __u64 offset = io_parms->offset; 1422 struct cifs_tcon *tcon = io_parms->tcon; 1423 unsigned int count = io_parms->length; 1424 1425 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid); 1426 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1427 wct = 12; 1428 else { 1429 wct = 10; /* old style read */ 1430 if ((offset >> 32) > 0) { 1431 /* can not handle this big offset for old */ 1432 return -EIO; 1433 } 1434 } 1435 1436 *nbytes = 0; 1437 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB); 1438 if (rc) 1439 return rc; 1440 1441 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1442 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1443 1444 /* tcon and ses pointer are checked in smb_init */ 1445 if (tcon->ses->server == NULL) 1446 return -ECONNABORTED; 1447 1448 pSMB->AndXCommand = 0xFF; /* none */ 1449 pSMB->Fid = netfid; 1450 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1451 if (wct == 12) 1452 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1453 1454 pSMB->Remaining = 0; 1455 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1456 pSMB->MaxCountHigh = cpu_to_le32(count >> 16); 1457 if (wct == 12) 1458 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ 1459 else { 1460 /* old style read */ 1461 struct smb_com_readx_req *pSMBW = 1462 (struct smb_com_readx_req *)pSMB; 1463 pSMBW->ByteCount = 0; 1464 } 1465 1466 iov[0].iov_base = (char *)pSMB; 1467 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 1468 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type, 1469 CIFS_LOG_ERROR, &rsp_iov); 1470 cifs_small_buf_release(pSMB); 1471 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1472 pSMBr = (READ_RSP *)rsp_iov.iov_base; 1473 if (rc) { 1474 cifs_dbg(VFS, "Send error in read = %d\n", rc); 1475 } else { 1476 int data_length = le16_to_cpu(pSMBr->DataLengthHigh); 1477 data_length = data_length << 16; 1478 data_length += le16_to_cpu(pSMBr->DataLength); 1479 *nbytes = data_length; 1480 1481 /*check that DataLength would not go beyond end of SMB */ 1482 if ((data_length > CIFSMaxBufSize) 1483 || (data_length > count)) { 1484 cifs_dbg(FYI, "bad length %d for count %d\n", 1485 data_length, count); 1486 rc = -EIO; 1487 *nbytes = 0; 1488 } else { 1489 pReadData = (char *) (&pSMBr->hdr.Protocol) + 1490 le16_to_cpu(pSMBr->DataOffset); 1491 /* if (rc = copy_to_user(buf, pReadData, data_length)) { 1492 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc); 1493 rc = -EFAULT; 1494 }*/ /* can not use copy_to_user when using page cache*/ 1495 if (*buf) 1496 memcpy(*buf, pReadData, data_length); 1497 } 1498 } 1499 1500 if (*buf) { 1501 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 1502 } else if (resp_buf_type != CIFS_NO_BUFFER) { 1503 /* return buffer to caller to free */ 1504 *buf = rsp_iov.iov_base; 1505 if (resp_buf_type == CIFS_SMALL_BUFFER) 1506 *pbuf_type = CIFS_SMALL_BUFFER; 1507 else if (resp_buf_type == CIFS_LARGE_BUFFER) 1508 *pbuf_type = CIFS_LARGE_BUFFER; 1509 } /* else no valid buffer on return - leave as null */ 1510 1511 /* Note: On -EAGAIN error only caller can retry on handle based calls 1512 since file handle passed in no longer valid */ 1513 return rc; 1514 } 1515 1516 1517 int 1518 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms, 1519 unsigned int *nbytes, const char *buf) 1520 { 1521 int rc = -EACCES; 1522 WRITE_REQ *pSMB = NULL; 1523 WRITE_RSP *pSMBr = NULL; 1524 int bytes_returned, wct; 1525 __u32 bytes_sent; 1526 __u16 byte_count; 1527 __u32 pid = io_parms->pid; 1528 __u16 netfid = io_parms->netfid; 1529 __u64 offset = io_parms->offset; 1530 struct cifs_tcon *tcon = io_parms->tcon; 1531 unsigned int count = io_parms->length; 1532 1533 *nbytes = 0; 1534 1535 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/ 1536 if (tcon->ses == NULL) 1537 return -ECONNABORTED; 1538 1539 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1540 wct = 14; 1541 else { 1542 wct = 12; 1543 if ((offset >> 32) > 0) { 1544 /* can not handle big offset for old srv */ 1545 return -EIO; 1546 } 1547 } 1548 1549 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB, 1550 (void **) &pSMBr); 1551 if (rc) 1552 return rc; 1553 1554 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1555 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1556 1557 /* tcon and ses pointer are checked in smb_init */ 1558 if (tcon->ses->server == NULL) 1559 return -ECONNABORTED; 1560 1561 pSMB->AndXCommand = 0xFF; /* none */ 1562 pSMB->Fid = netfid; 1563 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1564 if (wct == 14) 1565 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1566 1567 pSMB->Reserved = 0xFFFFFFFF; 1568 pSMB->WriteMode = 0; 1569 pSMB->Remaining = 0; 1570 1571 /* Can increase buffer size if buffer is big enough in some cases ie we 1572 can send more if LARGE_WRITE_X capability returned by the server and if 1573 our buffer is big enough or if we convert to iovecs on socket writes 1574 and eliminate the copy to the CIFS buffer */ 1575 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) { 1576 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count); 1577 } else { 1578 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) 1579 & ~0xFF; 1580 } 1581 1582 if (bytes_sent > count) 1583 bytes_sent = count; 1584 pSMB->DataOffset = 1585 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 1586 if (buf) 1587 memcpy(pSMB->Data, buf, bytes_sent); 1588 else if (count != 0) { 1589 /* No buffer */ 1590 cifs_buf_release(pSMB); 1591 return -EINVAL; 1592 } /* else setting file size with write of zero bytes */ 1593 if (wct == 14) 1594 byte_count = bytes_sent + 1; /* pad */ 1595 else /* wct == 12 */ 1596 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ 1597 1598 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); 1599 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1600 inc_rfc1001_len(pSMB, byte_count); 1601 1602 if (wct == 14) 1603 pSMB->ByteCount = cpu_to_le16(byte_count); 1604 else { /* old style write has byte count 4 bytes earlier 1605 so 4 bytes pad */ 1606 struct smb_com_writex_req *pSMBW = 1607 (struct smb_com_writex_req *)pSMB; 1608 pSMBW->ByteCount = cpu_to_le16(byte_count); 1609 } 1610 1611 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1612 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1613 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1614 if (rc) { 1615 cifs_dbg(FYI, "Send error in write = %d\n", rc); 1616 } else { 1617 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1618 *nbytes = (*nbytes) << 16; 1619 *nbytes += le16_to_cpu(pSMBr->Count); 1620 1621 /* 1622 * Mask off high 16 bits when bytes written as returned by the 1623 * server is greater than bytes requested by the client. Some 1624 * OS/2 servers are known to set incorrect CountHigh values. 1625 */ 1626 if (*nbytes > count) 1627 *nbytes &= 0xFFFF; 1628 } 1629 1630 cifs_buf_release(pSMB); 1631 1632 /* Note: On -EAGAIN error only caller can retry on handle based calls 1633 since file handle passed in no longer valid */ 1634 1635 return rc; 1636 } 1637 1638 /* 1639 * Check the mid_state and signature on received buffer (if any), and queue the 1640 * workqueue completion task. 1641 */ 1642 static void 1643 cifs_writev_callback(struct mid_q_entry *mid) 1644 { 1645 struct cifs_io_subrequest *wdata = mid->callback_data; 1646 struct TCP_Server_Info *server = wdata->server; 1647 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink); 1648 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; 1649 struct cifs_credits credits = { 1650 .value = 1, 1651 .instance = 0, 1652 .rreq_debug_id = wdata->rreq->debug_id, 1653 .rreq_debug_index = wdata->subreq.debug_index, 1654 }; 1655 ssize_t result; 1656 size_t written; 1657 1658 switch (mid->mid_state) { 1659 case MID_RESPONSE_RECEIVED: 1660 result = cifs_check_receive(mid, tcon->ses->server, 0); 1661 if (result != 0) 1662 break; 1663 1664 written = le16_to_cpu(smb->CountHigh); 1665 written <<= 16; 1666 written += le16_to_cpu(smb->Count); 1667 /* 1668 * Mask off high 16 bits when bytes written as returned 1669 * by the server is greater than bytes requested by the 1670 * client. OS/2 servers are known to set incorrect 1671 * CountHigh values. 1672 */ 1673 if (written > wdata->subreq.len) 1674 written &= 0xFFFF; 1675 1676 if (written < wdata->subreq.len) 1677 result = -ENOSPC; 1678 else 1679 result = written; 1680 break; 1681 case MID_REQUEST_SUBMITTED: 1682 case MID_RETRY_NEEDED: 1683 result = -EAGAIN; 1684 break; 1685 default: 1686 result = -EIO; 1687 break; 1688 } 1689 1690 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 1691 wdata->credits.value, 1692 server->credits, server->in_flight, 1693 0, cifs_trace_rw_credits_write_response_clear); 1694 wdata->credits.value = 0; 1695 cifs_write_subrequest_terminated(wdata, result, true); 1696 release_mid(mid); 1697 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0, 1698 server->credits, server->in_flight, 1699 credits.value, cifs_trace_rw_credits_write_response_add); 1700 add_credits(tcon->ses->server, &credits, 0); 1701 } 1702 1703 /* cifs_async_writev - send an async write, and set up mid to handle result */ 1704 void 1705 cifs_async_writev(struct cifs_io_subrequest *wdata) 1706 { 1707 int rc = -EACCES; 1708 WRITE_REQ *smb = NULL; 1709 int wct; 1710 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink); 1711 struct kvec iov[2]; 1712 struct smb_rqst rqst = { }; 1713 1714 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 1715 wct = 14; 1716 } else { 1717 wct = 12; 1718 if (wdata->subreq.start >> 32 > 0) { 1719 /* can not handle big offset for old srv */ 1720 rc = -EIO; 1721 goto out; 1722 } 1723 } 1724 1725 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb); 1726 if (rc) 1727 goto async_writev_out; 1728 1729 smb->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid); 1730 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16)); 1731 1732 smb->AndXCommand = 0xFF; /* none */ 1733 smb->Fid = wdata->req->cfile->fid.netfid; 1734 smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF); 1735 if (wct == 14) 1736 smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32); 1737 smb->Reserved = 0xFFFFFFFF; 1738 smb->WriteMode = 0; 1739 smb->Remaining = 0; 1740 1741 smb->DataOffset = 1742 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 1743 1744 /* 4 for RFC1001 length + 1 for BCC */ 1745 iov[0].iov_len = 4; 1746 iov[0].iov_base = smb; 1747 iov[1].iov_len = get_rfc1002_length(smb) + 1; 1748 iov[1].iov_base = (char *)smb + 4; 1749 1750 rqst.rq_iov = iov; 1751 rqst.rq_nvec = 2; 1752 rqst.rq_iter = wdata->subreq.io_iter; 1753 1754 cifs_dbg(FYI, "async write at %llu %zu bytes\n", 1755 wdata->subreq.start, wdata->subreq.len); 1756 1757 smb->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF); 1758 smb->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16); 1759 1760 if (wct == 14) { 1761 inc_rfc1001_len(&smb->hdr, wdata->subreq.len + 1); 1762 put_bcc(wdata->subreq.len + 1, &smb->hdr); 1763 } else { 1764 /* wct == 12 */ 1765 struct smb_com_writex_req *smbw = 1766 (struct smb_com_writex_req *)smb; 1767 inc_rfc1001_len(&smbw->hdr, wdata->subreq.len + 5); 1768 put_bcc(wdata->subreq.len + 5, &smbw->hdr); 1769 iov[1].iov_len += 4; /* pad bigger by four bytes */ 1770 } 1771 1772 rc = cifs_call_async(tcon->ses->server, &rqst, NULL, 1773 cifs_writev_callback, NULL, wdata, 0, NULL); 1774 /* Can't touch wdata if rc == 0 */ 1775 if (rc == 0) 1776 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1777 1778 async_writev_out: 1779 cifs_small_buf_release(smb); 1780 out: 1781 if (rc) { 1782 add_credits_and_wake_if(wdata->server, &wdata->credits, 0); 1783 cifs_write_subrequest_terminated(wdata, rc, false); 1784 } 1785 } 1786 1787 int 1788 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms, 1789 unsigned int *nbytes, struct kvec *iov, int n_vec) 1790 { 1791 int rc; 1792 WRITE_REQ *pSMB = NULL; 1793 int wct; 1794 int smb_hdr_len; 1795 int resp_buf_type = 0; 1796 __u32 pid = io_parms->pid; 1797 __u16 netfid = io_parms->netfid; 1798 __u64 offset = io_parms->offset; 1799 struct cifs_tcon *tcon = io_parms->tcon; 1800 unsigned int count = io_parms->length; 1801 struct kvec rsp_iov; 1802 1803 *nbytes = 0; 1804 1805 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count); 1806 1807 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 1808 wct = 14; 1809 } else { 1810 wct = 12; 1811 if ((offset >> 32) > 0) { 1812 /* can not handle big offset for old srv */ 1813 return -EIO; 1814 } 1815 } 1816 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); 1817 if (rc) 1818 return rc; 1819 1820 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1821 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1822 1823 /* tcon and ses pointer are checked in smb_init */ 1824 if (tcon->ses->server == NULL) 1825 return -ECONNABORTED; 1826 1827 pSMB->AndXCommand = 0xFF; /* none */ 1828 pSMB->Fid = netfid; 1829 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1830 if (wct == 14) 1831 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1832 pSMB->Reserved = 0xFFFFFFFF; 1833 pSMB->WriteMode = 0; 1834 pSMB->Remaining = 0; 1835 1836 pSMB->DataOffset = 1837 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 1838 1839 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); 1840 pSMB->DataLengthHigh = cpu_to_le16(count >> 16); 1841 /* header + 1 byte pad */ 1842 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1; 1843 if (wct == 14) 1844 inc_rfc1001_len(pSMB, count + 1); 1845 else /* wct == 12 */ 1846 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */ 1847 if (wct == 14) 1848 pSMB->ByteCount = cpu_to_le16(count + 1); 1849 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ { 1850 struct smb_com_writex_req *pSMBW = 1851 (struct smb_com_writex_req *)pSMB; 1852 pSMBW->ByteCount = cpu_to_le16(count + 5); 1853 } 1854 iov[0].iov_base = pSMB; 1855 if (wct == 14) 1856 iov[0].iov_len = smb_hdr_len + 4; 1857 else /* wct == 12 pad bigger by four bytes */ 1858 iov[0].iov_len = smb_hdr_len + 8; 1859 1860 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0, 1861 &rsp_iov); 1862 cifs_small_buf_release(pSMB); 1863 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1864 if (rc) { 1865 cifs_dbg(FYI, "Send error Write2 = %d\n", rc); 1866 } else if (resp_buf_type == 0) { 1867 /* presumably this can not happen, but best to be safe */ 1868 rc = -EIO; 1869 } else { 1870 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base; 1871 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1872 *nbytes = (*nbytes) << 16; 1873 *nbytes += le16_to_cpu(pSMBr->Count); 1874 1875 /* 1876 * Mask off high 16 bits when bytes written as returned by the 1877 * server is greater than bytes requested by the client. OS/2 1878 * servers are known to set incorrect CountHigh values. 1879 */ 1880 if (*nbytes > count) 1881 *nbytes &= 0xFFFF; 1882 } 1883 1884 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 1885 1886 /* Note: On -EAGAIN error only caller can retry on handle based calls 1887 since file handle passed in no longer valid */ 1888 1889 return rc; 1890 } 1891 1892 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon, 1893 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock, 1894 const __u32 num_lock, LOCKING_ANDX_RANGE *buf) 1895 { 1896 int rc = 0; 1897 LOCK_REQ *pSMB = NULL; 1898 struct kvec iov[2]; 1899 struct kvec rsp_iov; 1900 int resp_buf_type; 1901 __u16 count; 1902 1903 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n", 1904 num_lock, num_unlock); 1905 1906 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 1907 if (rc) 1908 return rc; 1909 1910 pSMB->Timeout = 0; 1911 pSMB->NumberOfLocks = cpu_to_le16(num_lock); 1912 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock); 1913 pSMB->LockType = lock_type; 1914 pSMB->AndXCommand = 0xFF; /* none */ 1915 pSMB->Fid = netfid; /* netfid stays le */ 1916 1917 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 1918 inc_rfc1001_len(pSMB, count); 1919 pSMB->ByteCount = cpu_to_le16(count); 1920 1921 iov[0].iov_base = (char *)pSMB; 1922 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 - 1923 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 1924 iov[1].iov_base = (char *)buf; 1925 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 1926 1927 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); 1928 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, 1929 CIFS_NO_RSP_BUF, &rsp_iov); 1930 cifs_small_buf_release(pSMB); 1931 if (rc) 1932 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc); 1933 1934 return rc; 1935 } 1936 1937 int 1938 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon, 1939 const __u16 smb_file_id, const __u32 netpid, const __u64 len, 1940 const __u64 offset, const __u32 numUnlock, 1941 const __u32 numLock, const __u8 lockType, 1942 const bool waitFlag, const __u8 oplock_level) 1943 { 1944 int rc = 0; 1945 LOCK_REQ *pSMB = NULL; 1946 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */ 1947 int bytes_returned; 1948 int flags = 0; 1949 __u16 count; 1950 1951 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n", 1952 (int)waitFlag, numLock); 1953 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 1954 1955 if (rc) 1956 return rc; 1957 1958 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 1959 /* no response expected */ 1960 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP; 1961 pSMB->Timeout = 0; 1962 } else if (waitFlag) { 1963 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ 1964 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ 1965 } else { 1966 pSMB->Timeout = 0; 1967 } 1968 1969 pSMB->NumberOfLocks = cpu_to_le16(numLock); 1970 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock); 1971 pSMB->LockType = lockType; 1972 pSMB->OplockLevel = oplock_level; 1973 pSMB->AndXCommand = 0xFF; /* none */ 1974 pSMB->Fid = smb_file_id; /* netfid stays le */ 1975 1976 if ((numLock != 0) || (numUnlock != 0)) { 1977 pSMB->Locks[0].Pid = cpu_to_le16(netpid); 1978 /* BB where to store pid high? */ 1979 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len); 1980 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32)); 1981 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset); 1982 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32)); 1983 count = sizeof(LOCKING_ANDX_RANGE); 1984 } else { 1985 /* oplock break */ 1986 count = 0; 1987 } 1988 inc_rfc1001_len(pSMB, count); 1989 pSMB->ByteCount = cpu_to_le16(count); 1990 1991 if (waitFlag) 1992 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1993 (struct smb_hdr *) pSMB, &bytes_returned); 1994 else 1995 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags); 1996 cifs_small_buf_release(pSMB); 1997 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); 1998 if (rc) 1999 cifs_dbg(FYI, "Send error in Lock = %d\n", rc); 2000 2001 /* Note: On -EAGAIN error only caller can retry on handle based calls 2002 since file handle passed in no longer valid */ 2003 return rc; 2004 } 2005 2006 int 2007 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon, 2008 const __u16 smb_file_id, const __u32 netpid, 2009 const loff_t start_offset, const __u64 len, 2010 struct file_lock *pLockData, const __u16 lock_type, 2011 const bool waitFlag) 2012 { 2013 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2014 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 2015 struct cifs_posix_lock *parm_data; 2016 int rc = 0; 2017 int timeout = 0; 2018 int bytes_returned = 0; 2019 int resp_buf_type = 0; 2020 __u16 params, param_offset, offset, byte_count, count; 2021 struct kvec iov[1]; 2022 struct kvec rsp_iov; 2023 2024 cifs_dbg(FYI, "Posix Lock\n"); 2025 2026 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 2027 2028 if (rc) 2029 return rc; 2030 2031 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; 2032 2033 params = 6; 2034 pSMB->MaxSetupCount = 0; 2035 pSMB->Reserved = 0; 2036 pSMB->Flags = 0; 2037 pSMB->Reserved2 = 0; 2038 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 2039 offset = param_offset + params; 2040 2041 count = sizeof(struct cifs_posix_lock); 2042 pSMB->MaxParameterCount = cpu_to_le16(2); 2043 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ 2044 pSMB->SetupCount = 1; 2045 pSMB->Reserved3 = 0; 2046 if (pLockData) 2047 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 2048 else 2049 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 2050 byte_count = 3 /* pad */ + params + count; 2051 pSMB->DataCount = cpu_to_le16(count); 2052 pSMB->ParameterCount = cpu_to_le16(params); 2053 pSMB->TotalDataCount = pSMB->DataCount; 2054 pSMB->TotalParameterCount = pSMB->ParameterCount; 2055 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2056 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2057 parm_data = (struct cifs_posix_lock *) 2058 (((char *)pSMB) + offset + 4); 2059 2060 parm_data->lock_type = cpu_to_le16(lock_type); 2061 if (waitFlag) { 2062 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ 2063 parm_data->lock_flags = cpu_to_le16(1); 2064 pSMB->Timeout = cpu_to_le32(-1); 2065 } else 2066 pSMB->Timeout = 0; 2067 2068 parm_data->pid = cpu_to_le32(netpid); 2069 parm_data->start = cpu_to_le64(start_offset); 2070 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */ 2071 2072 pSMB->DataOffset = cpu_to_le16(offset); 2073 pSMB->Fid = smb_file_id; 2074 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK); 2075 pSMB->Reserved4 = 0; 2076 inc_rfc1001_len(pSMB, byte_count); 2077 pSMB->ByteCount = cpu_to_le16(byte_count); 2078 if (waitFlag) { 2079 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 2080 (struct smb_hdr *) pSMBr, &bytes_returned); 2081 } else { 2082 iov[0].iov_base = (char *)pSMB; 2083 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 2084 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 2085 &resp_buf_type, timeout, &rsp_iov); 2086 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base; 2087 } 2088 cifs_small_buf_release(pSMB); 2089 2090 if (rc) { 2091 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc); 2092 } else if (pLockData) { 2093 /* lock structure can be returned on get */ 2094 __u16 data_offset; 2095 __u16 data_count; 2096 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2097 2098 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) { 2099 rc = -EIO; /* bad smb */ 2100 goto plk_err_exit; 2101 } 2102 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 2103 data_count = le16_to_cpu(pSMBr->t2.DataCount); 2104 if (data_count < sizeof(struct cifs_posix_lock)) { 2105 rc = -EIO; 2106 goto plk_err_exit; 2107 } 2108 parm_data = (struct cifs_posix_lock *) 2109 ((char *)&pSMBr->hdr.Protocol + data_offset); 2110 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) 2111 pLockData->c.flc_type = F_UNLCK; 2112 else { 2113 if (parm_data->lock_type == 2114 cpu_to_le16(CIFS_RDLCK)) 2115 pLockData->c.flc_type = F_RDLCK; 2116 else if (parm_data->lock_type == 2117 cpu_to_le16(CIFS_WRLCK)) 2118 pLockData->c.flc_type = F_WRLCK; 2119 2120 pLockData->fl_start = le64_to_cpu(parm_data->start); 2121 pLockData->fl_end = pLockData->fl_start + 2122 (le64_to_cpu(parm_data->length) ? 2123 le64_to_cpu(parm_data->length) - 1 : 0); 2124 pLockData->c.flc_pid = -le32_to_cpu(parm_data->pid); 2125 } 2126 } 2127 2128 plk_err_exit: 2129 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 2130 2131 /* Note: On -EAGAIN error only caller can retry on handle based calls 2132 since file handle passed in no longer valid */ 2133 2134 return rc; 2135 } 2136 2137 2138 int 2139 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) 2140 { 2141 int rc = 0; 2142 CLOSE_REQ *pSMB = NULL; 2143 cifs_dbg(FYI, "In CIFSSMBClose\n"); 2144 2145 /* do not retry on dead session on close */ 2146 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB); 2147 if (rc == -EAGAIN) 2148 return 0; 2149 if (rc) 2150 return rc; 2151 2152 pSMB->FileID = (__u16) smb_file_id; 2153 pSMB->LastWriteTime = 0xFFFFFFFF; 2154 pSMB->ByteCount = 0; 2155 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 2156 cifs_small_buf_release(pSMB); 2157 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes); 2158 if (rc) { 2159 if (rc != -EINTR) { 2160 /* EINTR is expected when user ctl-c to kill app */ 2161 cifs_dbg(VFS, "Send error in Close = %d\n", rc); 2162 } 2163 } 2164 2165 /* Since session is dead, file will be closed on server already */ 2166 if (rc == -EAGAIN) 2167 rc = 0; 2168 2169 return rc; 2170 } 2171 2172 int 2173 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) 2174 { 2175 int rc = 0; 2176 FLUSH_REQ *pSMB = NULL; 2177 cifs_dbg(FYI, "In CIFSSMBFlush\n"); 2178 2179 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB); 2180 if (rc) 2181 return rc; 2182 2183 pSMB->FileID = (__u16) smb_file_id; 2184 pSMB->ByteCount = 0; 2185 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 2186 cifs_small_buf_release(pSMB); 2187 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes); 2188 if (rc) 2189 cifs_dbg(VFS, "Send error in Flush = %d\n", rc); 2190 2191 return rc; 2192 } 2193 2194 int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, 2195 struct dentry *source_dentry, 2196 const char *from_name, const char *to_name, 2197 struct cifs_sb_info *cifs_sb) 2198 { 2199 int rc = 0; 2200 RENAME_REQ *pSMB = NULL; 2201 RENAME_RSP *pSMBr = NULL; 2202 int bytes_returned; 2203 int name_len, name_len2; 2204 __u16 count; 2205 int remap = cifs_remap(cifs_sb); 2206 2207 cifs_dbg(FYI, "In CIFSSMBRename\n"); 2208 renameRetry: 2209 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB, 2210 (void **) &pSMBr); 2211 if (rc) 2212 return rc; 2213 2214 pSMB->BufferFormat = 0x04; 2215 pSMB->SearchAttributes = 2216 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 2217 ATTR_DIRECTORY); 2218 2219 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2220 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName, 2221 from_name, PATH_MAX, 2222 cifs_sb->local_nls, remap); 2223 name_len++; /* trailing null */ 2224 name_len *= 2; 2225 pSMB->OldFileName[name_len] = 0x04; /* pad */ 2226 /* protocol requires ASCII signature byte on Unicode string */ 2227 pSMB->OldFileName[name_len + 1] = 0x00; 2228 name_len2 = 2229 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2230 to_name, PATH_MAX, cifs_sb->local_nls, 2231 remap); 2232 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2233 name_len2 *= 2; /* convert to bytes */ 2234 } else { 2235 name_len = copy_path_name(pSMB->OldFileName, from_name); 2236 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name); 2237 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2238 name_len2++; /* signature byte */ 2239 } 2240 2241 count = 1 /* 1st signature byte */ + name_len + name_len2; 2242 inc_rfc1001_len(pSMB, count); 2243 pSMB->ByteCount = cpu_to_le16(count); 2244 2245 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2246 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2247 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames); 2248 if (rc) 2249 cifs_dbg(FYI, "Send error in rename = %d\n", rc); 2250 2251 cifs_buf_release(pSMB); 2252 2253 if (rc == -EAGAIN) 2254 goto renameRetry; 2255 2256 return rc; 2257 } 2258 2259 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon, 2260 int netfid, const char *target_name, 2261 const struct nls_table *nls_codepage, int remap) 2262 { 2263 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2264 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 2265 struct set_file_rename *rename_info; 2266 char *data_offset; 2267 char dummy_string[30]; 2268 int rc = 0; 2269 int bytes_returned = 0; 2270 int len_of_str; 2271 __u16 params, param_offset, offset, count, byte_count; 2272 2273 cifs_dbg(FYI, "Rename to File by handle\n"); 2274 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB, 2275 (void **) &pSMBr); 2276 if (rc) 2277 return rc; 2278 2279 params = 6; 2280 pSMB->MaxSetupCount = 0; 2281 pSMB->Reserved = 0; 2282 pSMB->Flags = 0; 2283 pSMB->Timeout = 0; 2284 pSMB->Reserved2 = 0; 2285 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 2286 offset = param_offset + params; 2287 2288 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2289 data_offset = (char *)(pSMB) + offset + 4; 2290 rename_info = (struct set_file_rename *) data_offset; 2291 pSMB->MaxParameterCount = cpu_to_le16(2); 2292 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ 2293 pSMB->SetupCount = 1; 2294 pSMB->Reserved3 = 0; 2295 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 2296 byte_count = 3 /* pad */ + params; 2297 pSMB->ParameterCount = cpu_to_le16(params); 2298 pSMB->TotalParameterCount = pSMB->ParameterCount; 2299 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2300 pSMB->DataOffset = cpu_to_le16(offset); 2301 /* construct random name ".cifs_tmp<inodenum><mid>" */ 2302 rename_info->overwrite = cpu_to_le32(1); 2303 rename_info->root_fid = 0; 2304 /* unicode only call */ 2305 if (target_name == NULL) { 2306 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid); 2307 len_of_str = 2308 cifsConvertToUTF16((__le16 *)rename_info->target_name, 2309 dummy_string, 24, nls_codepage, remap); 2310 } else { 2311 len_of_str = 2312 cifsConvertToUTF16((__le16 *)rename_info->target_name, 2313 target_name, PATH_MAX, nls_codepage, 2314 remap); 2315 } 2316 rename_info->target_name_len = cpu_to_le32(2 * len_of_str); 2317 count = sizeof(struct set_file_rename) + (2 * len_of_str); 2318 byte_count += count; 2319 pSMB->DataCount = cpu_to_le16(count); 2320 pSMB->TotalDataCount = pSMB->DataCount; 2321 pSMB->Fid = netfid; 2322 pSMB->InformationLevel = 2323 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION); 2324 pSMB->Reserved4 = 0; 2325 inc_rfc1001_len(pSMB, byte_count); 2326 pSMB->ByteCount = cpu_to_le16(byte_count); 2327 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, 2328 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2329 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames); 2330 if (rc) 2331 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n", 2332 rc); 2333 2334 cifs_buf_release(pSMB); 2335 2336 /* Note: On -EAGAIN error only caller can retry on handle based calls 2337 since file handle passed in no longer valid */ 2338 2339 return rc; 2340 } 2341 2342 int 2343 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon, 2344 const char *fromName, const __u16 target_tid, const char *toName, 2345 const int flags, const struct nls_table *nls_codepage, int remap) 2346 { 2347 int rc = 0; 2348 COPY_REQ *pSMB = NULL; 2349 COPY_RSP *pSMBr = NULL; 2350 int bytes_returned; 2351 int name_len, name_len2; 2352 __u16 count; 2353 2354 cifs_dbg(FYI, "In CIFSSMBCopy\n"); 2355 copyRetry: 2356 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB, 2357 (void **) &pSMBr); 2358 if (rc) 2359 return rc; 2360 2361 pSMB->BufferFormat = 0x04; 2362 pSMB->Tid2 = target_tid; 2363 2364 pSMB->Flags = cpu_to_le16(flags & COPY_TREE); 2365 2366 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2367 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName, 2368 fromName, PATH_MAX, nls_codepage, 2369 remap); 2370 name_len++; /* trailing null */ 2371 name_len *= 2; 2372 pSMB->OldFileName[name_len] = 0x04; /* pad */ 2373 /* protocol requires ASCII signature byte on Unicode string */ 2374 pSMB->OldFileName[name_len + 1] = 0x00; 2375 name_len2 = 2376 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2377 toName, PATH_MAX, nls_codepage, remap); 2378 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2379 name_len2 *= 2; /* convert to bytes */ 2380 } else { 2381 name_len = copy_path_name(pSMB->OldFileName, fromName); 2382 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2383 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName); 2384 name_len2++; /* signature byte */ 2385 } 2386 2387 count = 1 /* 1st signature byte */ + name_len + name_len2; 2388 inc_rfc1001_len(pSMB, count); 2389 pSMB->ByteCount = cpu_to_le16(count); 2390 2391 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2392 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2393 if (rc) { 2394 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n", 2395 rc, le16_to_cpu(pSMBr->CopyCount)); 2396 } 2397 cifs_buf_release(pSMB); 2398 2399 if (rc == -EAGAIN) 2400 goto copyRetry; 2401 2402 return rc; 2403 } 2404 2405 int 2406 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon, 2407 const char *fromName, const char *toName, 2408 const struct nls_table *nls_codepage, int remap) 2409 { 2410 TRANSACTION2_SPI_REQ *pSMB = NULL; 2411 TRANSACTION2_SPI_RSP *pSMBr = NULL; 2412 char *data_offset; 2413 int name_len; 2414 int name_len_target; 2415 int rc = 0; 2416 int bytes_returned = 0; 2417 __u16 params, param_offset, offset, byte_count; 2418 2419 cifs_dbg(FYI, "In Symlink Unix style\n"); 2420 createSymLinkRetry: 2421 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2422 (void **) &pSMBr); 2423 if (rc) 2424 return rc; 2425 2426 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2427 name_len = 2428 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName, 2429 /* find define for this maxpathcomponent */ 2430 PATH_MAX, nls_codepage, remap); 2431 name_len++; /* trailing null */ 2432 name_len *= 2; 2433 2434 } else { 2435 name_len = copy_path_name(pSMB->FileName, fromName); 2436 } 2437 params = 6 + name_len; 2438 pSMB->MaxSetupCount = 0; 2439 pSMB->Reserved = 0; 2440 pSMB->Flags = 0; 2441 pSMB->Timeout = 0; 2442 pSMB->Reserved2 = 0; 2443 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2444 InformationLevel) - 4; 2445 offset = param_offset + params; 2446 2447 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2448 data_offset = (char *)pSMB + offset + 4; 2449 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2450 name_len_target = 2451 cifsConvertToUTF16((__le16 *) data_offset, toName, 2452 /* find define for this maxpathcomponent */ 2453 PATH_MAX, nls_codepage, remap); 2454 name_len_target++; /* trailing null */ 2455 name_len_target *= 2; 2456 } else { 2457 name_len_target = copy_path_name(data_offset, toName); 2458 } 2459 2460 pSMB->MaxParameterCount = cpu_to_le16(2); 2461 /* BB find exact max on data count below from sess */ 2462 pSMB->MaxDataCount = cpu_to_le16(1000); 2463 pSMB->SetupCount = 1; 2464 pSMB->Reserved3 = 0; 2465 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 2466 byte_count = 3 /* pad */ + params + name_len_target; 2467 pSMB->DataCount = cpu_to_le16(name_len_target); 2468 pSMB->ParameterCount = cpu_to_le16(params); 2469 pSMB->TotalDataCount = pSMB->DataCount; 2470 pSMB->TotalParameterCount = pSMB->ParameterCount; 2471 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2472 pSMB->DataOffset = cpu_to_le16(offset); 2473 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK); 2474 pSMB->Reserved4 = 0; 2475 inc_rfc1001_len(pSMB, byte_count); 2476 pSMB->ByteCount = cpu_to_le16(byte_count); 2477 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2478 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2479 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks); 2480 if (rc) 2481 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n", 2482 rc); 2483 2484 cifs_buf_release(pSMB); 2485 2486 if (rc == -EAGAIN) 2487 goto createSymLinkRetry; 2488 2489 return rc; 2490 } 2491 2492 int 2493 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, 2494 const char *fromName, const char *toName, 2495 const struct nls_table *nls_codepage, int remap) 2496 { 2497 TRANSACTION2_SPI_REQ *pSMB = NULL; 2498 TRANSACTION2_SPI_RSP *pSMBr = NULL; 2499 char *data_offset; 2500 int name_len; 2501 int name_len_target; 2502 int rc = 0; 2503 int bytes_returned = 0; 2504 __u16 params, param_offset, offset, byte_count; 2505 2506 cifs_dbg(FYI, "In Create Hard link Unix style\n"); 2507 createHardLinkRetry: 2508 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2509 (void **) &pSMBr); 2510 if (rc) 2511 return rc; 2512 2513 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2514 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName, 2515 PATH_MAX, nls_codepage, remap); 2516 name_len++; /* trailing null */ 2517 name_len *= 2; 2518 2519 } else { 2520 name_len = copy_path_name(pSMB->FileName, toName); 2521 } 2522 params = 6 + name_len; 2523 pSMB->MaxSetupCount = 0; 2524 pSMB->Reserved = 0; 2525 pSMB->Flags = 0; 2526 pSMB->Timeout = 0; 2527 pSMB->Reserved2 = 0; 2528 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2529 InformationLevel) - 4; 2530 offset = param_offset + params; 2531 2532 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2533 data_offset = (char *)pSMB + offset + 4; 2534 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2535 name_len_target = 2536 cifsConvertToUTF16((__le16 *) data_offset, fromName, 2537 PATH_MAX, nls_codepage, remap); 2538 name_len_target++; /* trailing null */ 2539 name_len_target *= 2; 2540 } else { 2541 name_len_target = copy_path_name(data_offset, fromName); 2542 } 2543 2544 pSMB->MaxParameterCount = cpu_to_le16(2); 2545 /* BB find exact max on data count below from sess*/ 2546 pSMB->MaxDataCount = cpu_to_le16(1000); 2547 pSMB->SetupCount = 1; 2548 pSMB->Reserved3 = 0; 2549 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 2550 byte_count = 3 /* pad */ + params + name_len_target; 2551 pSMB->ParameterCount = cpu_to_le16(params); 2552 pSMB->TotalParameterCount = pSMB->ParameterCount; 2553 pSMB->DataCount = cpu_to_le16(name_len_target); 2554 pSMB->TotalDataCount = pSMB->DataCount; 2555 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2556 pSMB->DataOffset = cpu_to_le16(offset); 2557 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK); 2558 pSMB->Reserved4 = 0; 2559 inc_rfc1001_len(pSMB, byte_count); 2560 pSMB->ByteCount = cpu_to_le16(byte_count); 2561 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2562 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2563 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); 2564 if (rc) 2565 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n", 2566 rc); 2567 2568 cifs_buf_release(pSMB); 2569 if (rc == -EAGAIN) 2570 goto createHardLinkRetry; 2571 2572 return rc; 2573 } 2574 2575 int CIFSCreateHardLink(const unsigned int xid, 2576 struct cifs_tcon *tcon, 2577 struct dentry *source_dentry, 2578 const char *from_name, const char *to_name, 2579 struct cifs_sb_info *cifs_sb) 2580 { 2581 int rc = 0; 2582 NT_RENAME_REQ *pSMB = NULL; 2583 RENAME_RSP *pSMBr = NULL; 2584 int bytes_returned; 2585 int name_len, name_len2; 2586 __u16 count; 2587 int remap = cifs_remap(cifs_sb); 2588 2589 cifs_dbg(FYI, "In CIFSCreateHardLink\n"); 2590 winCreateHardLinkRetry: 2591 2592 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB, 2593 (void **) &pSMBr); 2594 if (rc) 2595 return rc; 2596 2597 pSMB->SearchAttributes = 2598 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 2599 ATTR_DIRECTORY); 2600 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK); 2601 pSMB->ClusterCount = 0; 2602 2603 pSMB->BufferFormat = 0x04; 2604 2605 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2606 name_len = 2607 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name, 2608 PATH_MAX, cifs_sb->local_nls, remap); 2609 name_len++; /* trailing null */ 2610 name_len *= 2; 2611 2612 /* protocol specifies ASCII buffer format (0x04) for unicode */ 2613 pSMB->OldFileName[name_len] = 0x04; 2614 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */ 2615 name_len2 = 2616 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2617 to_name, PATH_MAX, cifs_sb->local_nls, 2618 remap); 2619 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2620 name_len2 *= 2; /* convert to bytes */ 2621 } else { 2622 name_len = copy_path_name(pSMB->OldFileName, from_name); 2623 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2624 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name); 2625 name_len2++; /* signature byte */ 2626 } 2627 2628 count = 1 /* string type byte */ + name_len + name_len2; 2629 inc_rfc1001_len(pSMB, count); 2630 pSMB->ByteCount = cpu_to_le16(count); 2631 2632 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2633 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2634 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); 2635 if (rc) 2636 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc); 2637 2638 cifs_buf_release(pSMB); 2639 if (rc == -EAGAIN) 2640 goto winCreateHardLinkRetry; 2641 2642 return rc; 2643 } 2644 2645 int 2646 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, 2647 const unsigned char *searchName, char **symlinkinfo, 2648 const struct nls_table *nls_codepage, int remap) 2649 { 2650 /* SMB_QUERY_FILE_UNIX_LINK */ 2651 TRANSACTION2_QPI_REQ *pSMB = NULL; 2652 TRANSACTION2_QPI_RSP *pSMBr = NULL; 2653 int rc = 0; 2654 int bytes_returned; 2655 int name_len; 2656 __u16 params, byte_count; 2657 char *data_start; 2658 2659 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName); 2660 2661 querySymLinkRetry: 2662 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2663 (void **) &pSMBr); 2664 if (rc) 2665 return rc; 2666 2667 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2668 name_len = 2669 cifsConvertToUTF16((__le16 *) pSMB->FileName, 2670 searchName, PATH_MAX, nls_codepage, 2671 remap); 2672 name_len++; /* trailing null */ 2673 name_len *= 2; 2674 } else { 2675 name_len = copy_path_name(pSMB->FileName, searchName); 2676 } 2677 2678 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 2679 pSMB->TotalDataCount = 0; 2680 pSMB->MaxParameterCount = cpu_to_le16(2); 2681 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 2682 pSMB->MaxSetupCount = 0; 2683 pSMB->Reserved = 0; 2684 pSMB->Flags = 0; 2685 pSMB->Timeout = 0; 2686 pSMB->Reserved2 = 0; 2687 pSMB->ParameterOffset = cpu_to_le16(offsetof( 2688 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 2689 pSMB->DataCount = 0; 2690 pSMB->DataOffset = 0; 2691 pSMB->SetupCount = 1; 2692 pSMB->Reserved3 = 0; 2693 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 2694 byte_count = params + 1 /* pad */ ; 2695 pSMB->TotalParameterCount = cpu_to_le16(params); 2696 pSMB->ParameterCount = pSMB->TotalParameterCount; 2697 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK); 2698 pSMB->Reserved4 = 0; 2699 inc_rfc1001_len(pSMB, byte_count); 2700 pSMB->ByteCount = cpu_to_le16(byte_count); 2701 2702 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2703 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2704 if (rc) { 2705 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc); 2706 } else { 2707 /* decode response */ 2708 2709 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2710 /* BB also check enough total bytes returned */ 2711 if (rc || get_bcc(&pSMBr->hdr) < 2) 2712 rc = -EIO; 2713 else { 2714 bool is_unicode; 2715 u16 count = le16_to_cpu(pSMBr->t2.DataCount); 2716 2717 data_start = ((char *) &pSMBr->hdr.Protocol) + 2718 le16_to_cpu(pSMBr->t2.DataOffset); 2719 2720 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 2721 is_unicode = true; 2722 else 2723 is_unicode = false; 2724 2725 /* BB FIXME investigate remapping reserved chars here */ 2726 *symlinkinfo = cifs_strndup_from_utf16(data_start, 2727 count, is_unicode, nls_codepage); 2728 if (!*symlinkinfo) 2729 rc = -ENOMEM; 2730 } 2731 } 2732 cifs_buf_release(pSMB); 2733 if (rc == -EAGAIN) 2734 goto querySymLinkRetry; 2735 return rc; 2736 } 2737 2738 int cifs_query_reparse_point(const unsigned int xid, 2739 struct cifs_tcon *tcon, 2740 struct cifs_sb_info *cifs_sb, 2741 const char *full_path, 2742 u32 *tag, struct kvec *rsp, 2743 int *rsp_buftype) 2744 { 2745 struct reparse_data_buffer *buf; 2746 struct cifs_open_parms oparms; 2747 TRANSACT_IOCTL_REQ *io_req = NULL; 2748 TRANSACT_IOCTL_RSP *io_rsp = NULL; 2749 struct cifs_fid fid; 2750 __u32 data_offset, data_count, len; 2751 __u8 *start, *end; 2752 int io_rsp_len; 2753 int oplock = 0; 2754 int rc; 2755 2756 cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path); 2757 2758 if (cap_unix(tcon->ses)) 2759 return -EOPNOTSUPP; 2760 2761 oparms = (struct cifs_open_parms) { 2762 .tcon = tcon, 2763 .cifs_sb = cifs_sb, 2764 .desired_access = FILE_READ_ATTRIBUTES, 2765 .create_options = cifs_create_options(cifs_sb, 2766 OPEN_REPARSE_POINT), 2767 .disposition = FILE_OPEN, 2768 .path = full_path, 2769 .fid = &fid, 2770 }; 2771 2772 rc = CIFS_open(xid, &oparms, &oplock, NULL); 2773 if (rc) 2774 return rc; 2775 2776 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, 2777 (void **)&io_req, (void **)&io_rsp); 2778 if (rc) 2779 goto error; 2780 2781 io_req->TotalParameterCount = 0; 2782 io_req->TotalDataCount = 0; 2783 io_req->MaxParameterCount = cpu_to_le32(2); 2784 /* BB find exact data count max from sess structure BB */ 2785 io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); 2786 io_req->MaxSetupCount = 4; 2787 io_req->Reserved = 0; 2788 io_req->ParameterOffset = 0; 2789 io_req->DataCount = 0; 2790 io_req->DataOffset = 0; 2791 io_req->SetupCount = 4; 2792 io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 2793 io_req->ParameterCount = io_req->TotalParameterCount; 2794 io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT); 2795 io_req->IsFsctl = 1; 2796 io_req->IsRootFlag = 0; 2797 io_req->Fid = fid.netfid; 2798 io_req->ByteCount = 0; 2799 2800 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req, 2801 (struct smb_hdr *)io_rsp, &io_rsp_len, 0); 2802 if (rc) 2803 goto error; 2804 2805 data_offset = le32_to_cpu(io_rsp->DataOffset); 2806 data_count = le32_to_cpu(io_rsp->DataCount); 2807 if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 || 2808 !data_count || data_count > 2048) { 2809 rc = -EIO; 2810 goto error; 2811 } 2812 2813 end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount; 2814 start = (__u8 *)&io_rsp->hdr.Protocol + data_offset; 2815 if (start >= end) { 2816 rc = -EIO; 2817 goto error; 2818 } 2819 2820 data_count = le16_to_cpu(io_rsp->ByteCount); 2821 buf = (struct reparse_data_buffer *)start; 2822 len = sizeof(*buf); 2823 if (data_count < len || 2824 data_count < le16_to_cpu(buf->ReparseDataLength) + len) { 2825 rc = -EIO; 2826 goto error; 2827 } 2828 2829 *tag = le32_to_cpu(buf->ReparseTag); 2830 rsp->iov_base = io_rsp; 2831 rsp->iov_len = io_rsp_len; 2832 *rsp_buftype = CIFS_LARGE_BUFFER; 2833 CIFSSMBClose(xid, tcon, fid.netfid); 2834 return 0; 2835 2836 error: 2837 cifs_buf_release(io_req); 2838 CIFSSMBClose(xid, tcon, fid.netfid); 2839 return rc; 2840 } 2841 2842 int 2843 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon, 2844 __u16 fid) 2845 { 2846 int rc = 0; 2847 int bytes_returned; 2848 struct smb_com_transaction_compr_ioctl_req *pSMB; 2849 struct smb_com_transaction_ioctl_rsp *pSMBr; 2850 2851 cifs_dbg(FYI, "Set compression for %u\n", fid); 2852 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, 2853 (void **) &pSMBr); 2854 if (rc) 2855 return rc; 2856 2857 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT); 2858 2859 pSMB->TotalParameterCount = 0; 2860 pSMB->TotalDataCount = cpu_to_le32(2); 2861 pSMB->MaxParameterCount = 0; 2862 pSMB->MaxDataCount = 0; 2863 pSMB->MaxSetupCount = 4; 2864 pSMB->Reserved = 0; 2865 pSMB->ParameterOffset = 0; 2866 pSMB->DataCount = cpu_to_le32(2); 2867 pSMB->DataOffset = 2868 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req, 2869 compression_state) - 4); /* 84 */ 2870 pSMB->SetupCount = 4; 2871 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 2872 pSMB->ParameterCount = 0; 2873 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION); 2874 pSMB->IsFsctl = 1; /* FSCTL */ 2875 pSMB->IsRootFlag = 0; 2876 pSMB->Fid = fid; /* file handle always le */ 2877 /* 3 byte pad, followed by 2 byte compress state */ 2878 pSMB->ByteCount = cpu_to_le16(5); 2879 inc_rfc1001_len(pSMB, 5); 2880 2881 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2882 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2883 if (rc) 2884 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc); 2885 2886 cifs_buf_release(pSMB); 2887 2888 /* 2889 * Note: On -EAGAIN error only caller can retry on handle based calls 2890 * since file handle passed in no longer valid. 2891 */ 2892 return rc; 2893 } 2894 2895 2896 #ifdef CONFIG_CIFS_POSIX 2897 2898 #ifdef CONFIG_FS_POSIX_ACL 2899 /** 2900 * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format 2901 * @ace: POSIX ACL entry to store converted ACL into 2902 * @cifs_ace: ACL in cifs format 2903 * 2904 * Convert an Access Control Entry from wire format to local POSIX xattr 2905 * format. 2906 * 2907 * Note that the @cifs_uid member is used to store both {g,u}id_t. 2908 */ 2909 static void cifs_init_posix_acl(struct posix_acl_entry *ace, 2910 struct cifs_posix_ace *cifs_ace) 2911 { 2912 /* u8 cifs fields do not need le conversion */ 2913 ace->e_perm = cifs_ace->cifs_e_perm; 2914 ace->e_tag = cifs_ace->cifs_e_tag; 2915 2916 switch (ace->e_tag) { 2917 case ACL_USER: 2918 ace->e_uid = make_kuid(&init_user_ns, 2919 le64_to_cpu(cifs_ace->cifs_uid)); 2920 break; 2921 case ACL_GROUP: 2922 ace->e_gid = make_kgid(&init_user_ns, 2923 le64_to_cpu(cifs_ace->cifs_uid)); 2924 break; 2925 } 2926 return; 2927 } 2928 2929 /** 2930 * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format 2931 * @acl: ACLs returned in POSIX ACL format 2932 * @src: ACLs in cifs format 2933 * @acl_type: type of POSIX ACL requested 2934 * @size_of_data_area: size of SMB we got 2935 * 2936 * This function converts ACLs from cifs format to POSIX ACL format. 2937 * If @acl is NULL then the size of the buffer required to store POSIX ACLs in 2938 * their uapi format is returned. 2939 */ 2940 static int cifs_to_posix_acl(struct posix_acl **acl, char *src, 2941 const int acl_type, const int size_of_data_area) 2942 { 2943 int size = 0; 2944 __u16 count; 2945 struct cifs_posix_ace *pACE; 2946 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src; 2947 struct posix_acl *kacl = NULL; 2948 struct posix_acl_entry *pa, *pe; 2949 2950 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION) 2951 return -EOPNOTSUPP; 2952 2953 if (acl_type == ACL_TYPE_ACCESS) { 2954 count = le16_to_cpu(cifs_acl->access_entry_count); 2955 pACE = &cifs_acl->ace_array[0]; 2956 size = sizeof(struct cifs_posix_acl); 2957 size += sizeof(struct cifs_posix_ace) * count; 2958 /* check if we would go beyond end of SMB */ 2959 if (size_of_data_area < size) { 2960 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n", 2961 size_of_data_area, size); 2962 return -EINVAL; 2963 } 2964 } else if (acl_type == ACL_TYPE_DEFAULT) { 2965 count = le16_to_cpu(cifs_acl->access_entry_count); 2966 size = sizeof(struct cifs_posix_acl); 2967 size += sizeof(struct cifs_posix_ace) * count; 2968 /* skip past access ACEs to get to default ACEs */ 2969 pACE = &cifs_acl->ace_array[count]; 2970 count = le16_to_cpu(cifs_acl->default_entry_count); 2971 size += sizeof(struct cifs_posix_ace) * count; 2972 /* check if we would go beyond end of SMB */ 2973 if (size_of_data_area < size) 2974 return -EINVAL; 2975 } else { 2976 /* illegal type */ 2977 return -EINVAL; 2978 } 2979 2980 /* Allocate number of POSIX ACLs to store in VFS format. */ 2981 kacl = posix_acl_alloc(count, GFP_NOFS); 2982 if (!kacl) 2983 return -ENOMEM; 2984 2985 FOREACH_ACL_ENTRY(pa, kacl, pe) { 2986 cifs_init_posix_acl(pa, pACE); 2987 pACE++; 2988 } 2989 2990 *acl = kacl; 2991 return 0; 2992 } 2993 2994 /** 2995 * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format 2996 * @cifs_ace: the cifs ACL entry to store into 2997 * @local_ace: the POSIX ACL entry to convert 2998 */ 2999 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace, 3000 const struct posix_acl_entry *local_ace) 3001 { 3002 cifs_ace->cifs_e_perm = local_ace->e_perm; 3003 cifs_ace->cifs_e_tag = local_ace->e_tag; 3004 3005 switch (local_ace->e_tag) { 3006 case ACL_USER: 3007 cifs_ace->cifs_uid = 3008 cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid)); 3009 break; 3010 case ACL_GROUP: 3011 cifs_ace->cifs_uid = 3012 cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid)); 3013 break; 3014 default: 3015 cifs_ace->cifs_uid = cpu_to_le64(-1); 3016 } 3017 } 3018 3019 /** 3020 * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format 3021 * @parm_data: ACLs in cifs format to conver to 3022 * @acl: ACLs in POSIX ACL format to convert from 3023 * @acl_type: the type of POSIX ACLs stored in @acl 3024 * 3025 * Return: the number cifs ACL entries after conversion 3026 */ 3027 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl, 3028 const int acl_type) 3029 { 3030 __u16 rc = 0; 3031 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data; 3032 const struct posix_acl_entry *pa, *pe; 3033 int count; 3034 int i = 0; 3035 3036 if ((acl == NULL) || (cifs_acl == NULL)) 3037 return 0; 3038 3039 count = acl->a_count; 3040 cifs_dbg(FYI, "setting acl with %d entries\n", count); 3041 3042 /* 3043 * Note that the uapi POSIX ACL version is verified by the VFS and is 3044 * independent of the cifs ACL version. Changing the POSIX ACL version 3045 * is a uapi change and if it's changed we will pass down the POSIX ACL 3046 * version in struct posix_acl from the VFS. For now there's really 3047 * only one that all filesystems know how to deal with. 3048 */ 3049 cifs_acl->version = cpu_to_le16(1); 3050 if (acl_type == ACL_TYPE_ACCESS) { 3051 cifs_acl->access_entry_count = cpu_to_le16(count); 3052 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF); 3053 } else if (acl_type == ACL_TYPE_DEFAULT) { 3054 cifs_acl->default_entry_count = cpu_to_le16(count); 3055 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF); 3056 } else { 3057 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type); 3058 return 0; 3059 } 3060 FOREACH_ACL_ENTRY(pa, acl, pe) { 3061 cifs_init_ace(&cifs_acl->ace_array[i++], pa); 3062 } 3063 if (rc == 0) { 3064 rc = (__u16)(count * sizeof(struct cifs_posix_ace)); 3065 rc += sizeof(struct cifs_posix_acl); 3066 /* BB add check to make sure ACL does not overflow SMB */ 3067 } 3068 return rc; 3069 } 3070 3071 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, 3072 const unsigned char *searchName, struct posix_acl **acl, 3073 const int acl_type, const struct nls_table *nls_codepage, 3074 int remap) 3075 { 3076 /* SMB_QUERY_POSIX_ACL */ 3077 TRANSACTION2_QPI_REQ *pSMB = NULL; 3078 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3079 int rc = 0; 3080 int bytes_returned; 3081 int name_len; 3082 __u16 params, byte_count; 3083 3084 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName); 3085 3086 queryAclRetry: 3087 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3088 (void **) &pSMBr); 3089 if (rc) 3090 return rc; 3091 3092 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3093 name_len = 3094 cifsConvertToUTF16((__le16 *) pSMB->FileName, 3095 searchName, PATH_MAX, nls_codepage, 3096 remap); 3097 name_len++; /* trailing null */ 3098 name_len *= 2; 3099 pSMB->FileName[name_len] = 0; 3100 pSMB->FileName[name_len+1] = 0; 3101 } else { 3102 name_len = copy_path_name(pSMB->FileName, searchName); 3103 } 3104 3105 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 3106 pSMB->TotalDataCount = 0; 3107 pSMB->MaxParameterCount = cpu_to_le16(2); 3108 /* BB find exact max data count below from sess structure BB */ 3109 pSMB->MaxDataCount = cpu_to_le16(4000); 3110 pSMB->MaxSetupCount = 0; 3111 pSMB->Reserved = 0; 3112 pSMB->Flags = 0; 3113 pSMB->Timeout = 0; 3114 pSMB->Reserved2 = 0; 3115 pSMB->ParameterOffset = cpu_to_le16( 3116 offsetof(struct smb_com_transaction2_qpi_req, 3117 InformationLevel) - 4); 3118 pSMB->DataCount = 0; 3119 pSMB->DataOffset = 0; 3120 pSMB->SetupCount = 1; 3121 pSMB->Reserved3 = 0; 3122 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3123 byte_count = params + 1 /* pad */ ; 3124 pSMB->TotalParameterCount = cpu_to_le16(params); 3125 pSMB->ParameterCount = pSMB->TotalParameterCount; 3126 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL); 3127 pSMB->Reserved4 = 0; 3128 inc_rfc1001_len(pSMB, byte_count); 3129 pSMB->ByteCount = cpu_to_le16(byte_count); 3130 3131 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3132 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3133 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); 3134 if (rc) { 3135 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc); 3136 } else { 3137 /* decode response */ 3138 3139 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3140 /* BB also check enough total bytes returned */ 3141 if (rc || get_bcc(&pSMBr->hdr) < 2) 3142 rc = -EIO; /* bad smb */ 3143 else { 3144 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3145 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3146 rc = cifs_to_posix_acl(acl, 3147 (char *)&pSMBr->hdr.Protocol+data_offset, 3148 acl_type, count); 3149 } 3150 } 3151 cifs_buf_release(pSMB); 3152 /* 3153 * The else branch after SendReceive() doesn't return EAGAIN so if we 3154 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return 3155 * here and don't leak POSIX ACLs. 3156 */ 3157 if (rc == -EAGAIN) 3158 goto queryAclRetry; 3159 return rc; 3160 } 3161 3162 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon, 3163 const unsigned char *fileName, const struct posix_acl *acl, 3164 const int acl_type, const struct nls_table *nls_codepage, 3165 int remap) 3166 { 3167 struct smb_com_transaction2_spi_req *pSMB = NULL; 3168 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 3169 char *parm_data; 3170 int name_len; 3171 int rc = 0; 3172 int bytes_returned = 0; 3173 __u16 params, byte_count, data_count, param_offset, offset; 3174 3175 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName); 3176 setAclRetry: 3177 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3178 (void **) &pSMBr); 3179 if (rc) 3180 return rc; 3181 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3182 name_len = 3183 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 3184 PATH_MAX, nls_codepage, remap); 3185 name_len++; /* trailing null */ 3186 name_len *= 2; 3187 } else { 3188 name_len = copy_path_name(pSMB->FileName, fileName); 3189 } 3190 params = 6 + name_len; 3191 pSMB->MaxParameterCount = cpu_to_le16(2); 3192 /* BB find max SMB size from sess */ 3193 pSMB->MaxDataCount = cpu_to_le16(1000); 3194 pSMB->MaxSetupCount = 0; 3195 pSMB->Reserved = 0; 3196 pSMB->Flags = 0; 3197 pSMB->Timeout = 0; 3198 pSMB->Reserved2 = 0; 3199 param_offset = offsetof(struct smb_com_transaction2_spi_req, 3200 InformationLevel) - 4; 3201 offset = param_offset + params; 3202 parm_data = ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset; 3203 pSMB->ParameterOffset = cpu_to_le16(param_offset); 3204 3205 /* convert to on the wire format for POSIX ACL */ 3206 data_count = posix_acl_to_cifs(parm_data, acl, acl_type); 3207 3208 if (data_count == 0) { 3209 rc = -EOPNOTSUPP; 3210 goto setACLerrorExit; 3211 } 3212 pSMB->DataOffset = cpu_to_le16(offset); 3213 pSMB->SetupCount = 1; 3214 pSMB->Reserved3 = 0; 3215 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 3216 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL); 3217 byte_count = 3 /* pad */ + params + data_count; 3218 pSMB->DataCount = cpu_to_le16(data_count); 3219 pSMB->TotalDataCount = pSMB->DataCount; 3220 pSMB->ParameterCount = cpu_to_le16(params); 3221 pSMB->TotalParameterCount = pSMB->ParameterCount; 3222 pSMB->Reserved4 = 0; 3223 inc_rfc1001_len(pSMB, byte_count); 3224 pSMB->ByteCount = cpu_to_le16(byte_count); 3225 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3226 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3227 if (rc) 3228 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc); 3229 3230 setACLerrorExit: 3231 cifs_buf_release(pSMB); 3232 if (rc == -EAGAIN) 3233 goto setAclRetry; 3234 return rc; 3235 } 3236 #else 3237 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, 3238 const unsigned char *searchName, struct posix_acl **acl, 3239 const int acl_type, const struct nls_table *nls_codepage, 3240 int remap) 3241 { 3242 return -EOPNOTSUPP; 3243 } 3244 3245 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon, 3246 const unsigned char *fileName, const struct posix_acl *acl, 3247 const int acl_type, const struct nls_table *nls_codepage, 3248 int remap) 3249 { 3250 return -EOPNOTSUPP; 3251 } 3252 #endif /* CONFIG_FS_POSIX_ACL */ 3253 3254 int 3255 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon, 3256 const int netfid, __u64 *pExtAttrBits, __u64 *pMask) 3257 { 3258 int rc = 0; 3259 struct smb_t2_qfi_req *pSMB = NULL; 3260 struct smb_t2_qfi_rsp *pSMBr = NULL; 3261 int bytes_returned; 3262 __u16 params, byte_count; 3263 3264 cifs_dbg(FYI, "In GetExtAttr\n"); 3265 if (tcon == NULL) 3266 return -ENODEV; 3267 3268 GetExtAttrRetry: 3269 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3270 (void **) &pSMBr); 3271 if (rc) 3272 return rc; 3273 3274 params = 2 /* level */ + 2 /* fid */; 3275 pSMB->t2.TotalDataCount = 0; 3276 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3277 /* BB find exact max data count below from sess structure BB */ 3278 pSMB->t2.MaxDataCount = cpu_to_le16(4000); 3279 pSMB->t2.MaxSetupCount = 0; 3280 pSMB->t2.Reserved = 0; 3281 pSMB->t2.Flags = 0; 3282 pSMB->t2.Timeout = 0; 3283 pSMB->t2.Reserved2 = 0; 3284 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3285 Fid) - 4); 3286 pSMB->t2.DataCount = 0; 3287 pSMB->t2.DataOffset = 0; 3288 pSMB->t2.SetupCount = 1; 3289 pSMB->t2.Reserved3 = 0; 3290 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3291 byte_count = params + 1 /* pad */ ; 3292 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3293 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3294 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); 3295 pSMB->Pad = 0; 3296 pSMB->Fid = netfid; 3297 inc_rfc1001_len(pSMB, byte_count); 3298 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3299 3300 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3301 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3302 if (rc) { 3303 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc); 3304 } else { 3305 /* decode response */ 3306 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3307 /* BB also check enough total bytes returned */ 3308 if (rc || get_bcc(&pSMBr->hdr) < 2) 3309 /* If rc should we check for EOPNOSUPP and 3310 disable the srvino flag? or in caller? */ 3311 rc = -EIO; /* bad smb */ 3312 else { 3313 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3314 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3315 struct file_chattr_info *pfinfo; 3316 3317 if (count != 16) { 3318 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n"); 3319 rc = -EIO; 3320 goto GetExtAttrOut; 3321 } 3322 pfinfo = (struct file_chattr_info *) 3323 (data_offset + (char *) &pSMBr->hdr.Protocol); 3324 *pExtAttrBits = le64_to_cpu(pfinfo->mode); 3325 *pMask = le64_to_cpu(pfinfo->mask); 3326 } 3327 } 3328 GetExtAttrOut: 3329 cifs_buf_release(pSMB); 3330 if (rc == -EAGAIN) 3331 goto GetExtAttrRetry; 3332 return rc; 3333 } 3334 3335 #endif /* CONFIG_POSIX */ 3336 3337 /* 3338 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that 3339 * all NT TRANSACTS that we init here have total parm and data under about 400 3340 * bytes (to fit in small cifs buffer size), which is the case so far, it 3341 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of 3342 * returned setup area) and MaxParameterCount (returned parms size) must be set 3343 * by caller 3344 */ 3345 static int 3346 smb_init_nttransact(const __u16 sub_command, const int setup_count, 3347 const int parm_len, struct cifs_tcon *tcon, 3348 void **ret_buf) 3349 { 3350 int rc; 3351 __u32 temp_offset; 3352 struct smb_com_ntransact_req *pSMB; 3353 3354 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, 3355 (void **)&pSMB); 3356 if (rc) 3357 return rc; 3358 *ret_buf = (void *)pSMB; 3359 pSMB->Reserved = 0; 3360 pSMB->TotalParameterCount = cpu_to_le32(parm_len); 3361 pSMB->TotalDataCount = 0; 3362 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); 3363 pSMB->ParameterCount = pSMB->TotalParameterCount; 3364 pSMB->DataCount = pSMB->TotalDataCount; 3365 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + 3366 (setup_count * 2) - 4 /* for rfc1001 length itself */; 3367 pSMB->ParameterOffset = cpu_to_le32(temp_offset); 3368 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); 3369 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ 3370 pSMB->SubCommand = cpu_to_le16(sub_command); 3371 return 0; 3372 } 3373 3374 static int 3375 validate_ntransact(char *buf, char **ppparm, char **ppdata, 3376 __u32 *pparmlen, __u32 *pdatalen) 3377 { 3378 char *end_of_smb; 3379 __u32 data_count, data_offset, parm_count, parm_offset; 3380 struct smb_com_ntransact_rsp *pSMBr; 3381 u16 bcc; 3382 3383 *pdatalen = 0; 3384 *pparmlen = 0; 3385 3386 if (buf == NULL) 3387 return -EINVAL; 3388 3389 pSMBr = (struct smb_com_ntransact_rsp *)buf; 3390 3391 bcc = get_bcc(&pSMBr->hdr); 3392 end_of_smb = 2 /* sizeof byte count */ + bcc + 3393 (char *)&pSMBr->ByteCount; 3394 3395 data_offset = le32_to_cpu(pSMBr->DataOffset); 3396 data_count = le32_to_cpu(pSMBr->DataCount); 3397 parm_offset = le32_to_cpu(pSMBr->ParameterOffset); 3398 parm_count = le32_to_cpu(pSMBr->ParameterCount); 3399 3400 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; 3401 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; 3402 3403 /* should we also check that parm and data areas do not overlap? */ 3404 if (*ppparm > end_of_smb) { 3405 cifs_dbg(FYI, "parms start after end of smb\n"); 3406 return -EINVAL; 3407 } else if (parm_count + *ppparm > end_of_smb) { 3408 cifs_dbg(FYI, "parm end after end of smb\n"); 3409 return -EINVAL; 3410 } else if (*ppdata > end_of_smb) { 3411 cifs_dbg(FYI, "data starts after end of smb\n"); 3412 return -EINVAL; 3413 } else if (data_count + *ppdata > end_of_smb) { 3414 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n", 3415 *ppdata, data_count, (data_count + *ppdata), 3416 end_of_smb, pSMBr); 3417 return -EINVAL; 3418 } else if (parm_count + data_count > bcc) { 3419 cifs_dbg(FYI, "parm count and data count larger than SMB\n"); 3420 return -EINVAL; 3421 } 3422 *pdatalen = data_count; 3423 *pparmlen = parm_count; 3424 return 0; 3425 } 3426 3427 /* Get Security Descriptor (by handle) from remote server for a file or dir */ 3428 int 3429 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, 3430 struct smb_ntsd **acl_inf, __u32 *pbuflen) 3431 { 3432 int rc = 0; 3433 int buf_type = 0; 3434 QUERY_SEC_DESC_REQ *pSMB; 3435 struct kvec iov[1]; 3436 struct kvec rsp_iov; 3437 3438 cifs_dbg(FYI, "GetCifsACL\n"); 3439 3440 *pbuflen = 0; 3441 *acl_inf = NULL; 3442 3443 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 3444 8 /* parm len */, tcon, (void **) &pSMB); 3445 if (rc) 3446 return rc; 3447 3448 pSMB->MaxParameterCount = cpu_to_le32(4); 3449 /* BB TEST with big acls that might need to be e.g. larger than 16K */ 3450 pSMB->MaxSetupCount = 0; 3451 pSMB->Fid = fid; /* file handle always le */ 3452 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP | 3453 CIFS_ACL_DACL); 3454 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ 3455 inc_rfc1001_len(pSMB, 11); 3456 iov[0].iov_base = (char *)pSMB; 3457 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 3458 3459 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 3460 0, &rsp_iov); 3461 cifs_small_buf_release(pSMB); 3462 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); 3463 if (rc) { 3464 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc); 3465 } else { /* decode response */ 3466 __le32 *parm; 3467 __u32 parm_len; 3468 __u32 acl_len; 3469 struct smb_com_ntransact_rsp *pSMBr; 3470 char *pdata; 3471 3472 /* validate_nttransact */ 3473 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm, 3474 &pdata, &parm_len, pbuflen); 3475 if (rc) 3476 goto qsec_out; 3477 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base; 3478 3479 cifs_dbg(FYI, "smb %p parm %p data %p\n", 3480 pSMBr, parm, *acl_inf); 3481 3482 if (le32_to_cpu(pSMBr->ParameterCount) != 4) { 3483 rc = -EIO; /* bad smb */ 3484 *pbuflen = 0; 3485 goto qsec_out; 3486 } 3487 3488 /* BB check that data area is minimum length and as big as acl_len */ 3489 3490 acl_len = le32_to_cpu(*parm); 3491 if (acl_len != *pbuflen) { 3492 cifs_dbg(VFS, "acl length %d does not match %d\n", 3493 acl_len, *pbuflen); 3494 if (*pbuflen > acl_len) 3495 *pbuflen = acl_len; 3496 } 3497 3498 /* check if buffer is big enough for the acl 3499 header followed by the smallest SID */ 3500 if ((*pbuflen < sizeof(struct smb_ntsd) + 8) || 3501 (*pbuflen >= 64 * 1024)) { 3502 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen); 3503 rc = -EINVAL; 3504 *pbuflen = 0; 3505 } else { 3506 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL); 3507 if (*acl_inf == NULL) { 3508 *pbuflen = 0; 3509 rc = -ENOMEM; 3510 } 3511 } 3512 } 3513 qsec_out: 3514 free_rsp_buf(buf_type, rsp_iov.iov_base); 3515 return rc; 3516 } 3517 3518 int 3519 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, 3520 struct smb_ntsd *pntsd, __u32 acllen, int aclflag) 3521 { 3522 __u16 byte_count, param_count, data_count, param_offset, data_offset; 3523 int rc = 0; 3524 int bytes_returned = 0; 3525 SET_SEC_DESC_REQ *pSMB = NULL; 3526 void *pSMBr; 3527 3528 setCifsAclRetry: 3529 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr); 3530 if (rc) 3531 return rc; 3532 3533 pSMB->MaxSetupCount = 0; 3534 pSMB->Reserved = 0; 3535 3536 param_count = 8; 3537 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4; 3538 data_count = acllen; 3539 data_offset = param_offset + param_count; 3540 byte_count = 3 /* pad */ + param_count; 3541 3542 pSMB->DataCount = cpu_to_le32(data_count); 3543 pSMB->TotalDataCount = pSMB->DataCount; 3544 pSMB->MaxParameterCount = cpu_to_le32(4); 3545 pSMB->MaxDataCount = cpu_to_le32(16384); 3546 pSMB->ParameterCount = cpu_to_le32(param_count); 3547 pSMB->ParameterOffset = cpu_to_le32(param_offset); 3548 pSMB->TotalParameterCount = pSMB->ParameterCount; 3549 pSMB->DataOffset = cpu_to_le32(data_offset); 3550 pSMB->SetupCount = 0; 3551 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC); 3552 pSMB->ByteCount = cpu_to_le16(byte_count+data_count); 3553 3554 pSMB->Fid = fid; /* file handle always le */ 3555 pSMB->Reserved2 = 0; 3556 pSMB->AclFlags = cpu_to_le32(aclflag); 3557 3558 if (pntsd && acllen) { 3559 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) + 3560 data_offset, pntsd, acllen); 3561 inc_rfc1001_len(pSMB, byte_count + data_count); 3562 } else 3563 inc_rfc1001_len(pSMB, byte_count); 3564 3565 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3566 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3567 3568 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n", 3569 bytes_returned, rc); 3570 if (rc) 3571 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc); 3572 cifs_buf_release(pSMB); 3573 3574 if (rc == -EAGAIN) 3575 goto setCifsAclRetry; 3576 3577 return (rc); 3578 } 3579 3580 3581 /* Legacy Query Path Information call for lookup to old servers such 3582 as Win9x/WinME */ 3583 int 3584 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, 3585 const char *search_name, FILE_ALL_INFO *data, 3586 const struct nls_table *nls_codepage, int remap) 3587 { 3588 QUERY_INFORMATION_REQ *pSMB; 3589 QUERY_INFORMATION_RSP *pSMBr; 3590 int rc = 0; 3591 int bytes_returned; 3592 int name_len; 3593 3594 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name); 3595 QInfRetry: 3596 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, 3597 (void **) &pSMBr); 3598 if (rc) 3599 return rc; 3600 3601 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3602 name_len = 3603 cifsConvertToUTF16((__le16 *) pSMB->FileName, 3604 search_name, PATH_MAX, nls_codepage, 3605 remap); 3606 name_len++; /* trailing null */ 3607 name_len *= 2; 3608 } else { 3609 name_len = copy_path_name(pSMB->FileName, search_name); 3610 } 3611 pSMB->BufferFormat = 0x04; 3612 name_len++; /* account for buffer type byte */ 3613 inc_rfc1001_len(pSMB, (__u16)name_len); 3614 pSMB->ByteCount = cpu_to_le16(name_len); 3615 3616 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3617 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3618 if (rc) { 3619 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc); 3620 } else if (data) { 3621 struct timespec64 ts; 3622 __u32 time = le32_to_cpu(pSMBr->last_write_time); 3623 3624 /* decode response */ 3625 /* BB FIXME - add time zone adjustment BB */ 3626 memset(data, 0, sizeof(FILE_ALL_INFO)); 3627 ts.tv_nsec = 0; 3628 ts.tv_sec = time; 3629 /* decode time fields */ 3630 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts)); 3631 data->LastWriteTime = data->ChangeTime; 3632 data->LastAccessTime = 0; 3633 data->AllocationSize = 3634 cpu_to_le64(le32_to_cpu(pSMBr->size)); 3635 data->EndOfFile = data->AllocationSize; 3636 data->Attributes = 3637 cpu_to_le32(le16_to_cpu(pSMBr->attr)); 3638 } else 3639 rc = -EIO; /* bad buffer passed in */ 3640 3641 cifs_buf_release(pSMB); 3642 3643 if (rc == -EAGAIN) 3644 goto QInfRetry; 3645 3646 return rc; 3647 } 3648 3649 int 3650 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 3651 u16 netfid, FILE_ALL_INFO *pFindData) 3652 { 3653 struct smb_t2_qfi_req *pSMB = NULL; 3654 struct smb_t2_qfi_rsp *pSMBr = NULL; 3655 int rc = 0; 3656 int bytes_returned; 3657 __u16 params, byte_count; 3658 3659 QFileInfoRetry: 3660 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3661 (void **) &pSMBr); 3662 if (rc) 3663 return rc; 3664 3665 params = 2 /* level */ + 2 /* fid */; 3666 pSMB->t2.TotalDataCount = 0; 3667 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3668 /* BB find exact max data count below from sess structure BB */ 3669 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 3670 pSMB->t2.MaxSetupCount = 0; 3671 pSMB->t2.Reserved = 0; 3672 pSMB->t2.Flags = 0; 3673 pSMB->t2.Timeout = 0; 3674 pSMB->t2.Reserved2 = 0; 3675 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3676 Fid) - 4); 3677 pSMB->t2.DataCount = 0; 3678 pSMB->t2.DataOffset = 0; 3679 pSMB->t2.SetupCount = 1; 3680 pSMB->t2.Reserved3 = 0; 3681 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3682 byte_count = params + 1 /* pad */ ; 3683 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3684 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3685 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3686 pSMB->Pad = 0; 3687 pSMB->Fid = netfid; 3688 inc_rfc1001_len(pSMB, byte_count); 3689 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3690 3691 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3692 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3693 if (rc) { 3694 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc); 3695 } else { /* decode response */ 3696 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3697 3698 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3699 rc = -EIO; 3700 else if (get_bcc(&pSMBr->hdr) < 40) 3701 rc = -EIO; /* bad smb */ 3702 else if (pFindData) { 3703 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3704 memcpy((char *) pFindData, 3705 (char *) &pSMBr->hdr.Protocol + 3706 data_offset, sizeof(FILE_ALL_INFO)); 3707 } else 3708 rc = -ENOMEM; 3709 } 3710 cifs_buf_release(pSMB); 3711 if (rc == -EAGAIN) 3712 goto QFileInfoRetry; 3713 3714 return rc; 3715 } 3716 3717 int 3718 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 3719 const char *search_name, FILE_ALL_INFO *data, 3720 int legacy /* old style infolevel */, 3721 const struct nls_table *nls_codepage, int remap) 3722 { 3723 /* level 263 SMB_QUERY_FILE_ALL_INFO */ 3724 TRANSACTION2_QPI_REQ *pSMB = NULL; 3725 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3726 int rc = 0; 3727 int bytes_returned; 3728 int name_len; 3729 __u16 params, byte_count; 3730 3731 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */ 3732 QPathInfoRetry: 3733 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3734 (void **) &pSMBr); 3735 if (rc) 3736 return rc; 3737 3738 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3739 name_len = 3740 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name, 3741 PATH_MAX, nls_codepage, remap); 3742 name_len++; /* trailing null */ 3743 name_len *= 2; 3744 } else { 3745 name_len = copy_path_name(pSMB->FileName, search_name); 3746 } 3747 3748 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 3749 pSMB->TotalDataCount = 0; 3750 pSMB->MaxParameterCount = cpu_to_le16(2); 3751 /* BB find exact max SMB PDU from sess structure BB */ 3752 pSMB->MaxDataCount = cpu_to_le16(4000); 3753 pSMB->MaxSetupCount = 0; 3754 pSMB->Reserved = 0; 3755 pSMB->Flags = 0; 3756 pSMB->Timeout = 0; 3757 pSMB->Reserved2 = 0; 3758 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3759 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 3760 pSMB->DataCount = 0; 3761 pSMB->DataOffset = 0; 3762 pSMB->SetupCount = 1; 3763 pSMB->Reserved3 = 0; 3764 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3765 byte_count = params + 1 /* pad */ ; 3766 pSMB->TotalParameterCount = cpu_to_le16(params); 3767 pSMB->ParameterCount = pSMB->TotalParameterCount; 3768 if (legacy) 3769 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD); 3770 else 3771 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3772 pSMB->Reserved4 = 0; 3773 inc_rfc1001_len(pSMB, byte_count); 3774 pSMB->ByteCount = cpu_to_le16(byte_count); 3775 3776 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3777 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3778 if (rc) { 3779 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc); 3780 } else { /* decode response */ 3781 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3782 3783 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3784 rc = -EIO; 3785 else if (!legacy && get_bcc(&pSMBr->hdr) < 40) 3786 rc = -EIO; /* bad smb */ 3787 else if (legacy && get_bcc(&pSMBr->hdr) < 24) 3788 rc = -EIO; /* 24 or 26 expected but we do not read 3789 last field */ 3790 else if (data) { 3791 int size; 3792 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3793 3794 /* 3795 * On legacy responses we do not read the last field, 3796 * EAsize, fortunately since it varies by subdialect and 3797 * also note it differs on Set vs Get, ie two bytes or 4 3798 * bytes depending but we don't care here. 3799 */ 3800 if (legacy) 3801 size = sizeof(FILE_INFO_STANDARD); 3802 else 3803 size = sizeof(FILE_ALL_INFO); 3804 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol + 3805 data_offset, size); 3806 } else 3807 rc = -ENOMEM; 3808 } 3809 cifs_buf_release(pSMB); 3810 if (rc == -EAGAIN) 3811 goto QPathInfoRetry; 3812 3813 return rc; 3814 } 3815 3816 int 3817 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 3818 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData) 3819 { 3820 struct smb_t2_qfi_req *pSMB = NULL; 3821 struct smb_t2_qfi_rsp *pSMBr = NULL; 3822 int rc = 0; 3823 int bytes_returned; 3824 __u16 params, byte_count; 3825 3826 UnixQFileInfoRetry: 3827 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3828 (void **) &pSMBr); 3829 if (rc) 3830 return rc; 3831 3832 params = 2 /* level */ + 2 /* fid */; 3833 pSMB->t2.TotalDataCount = 0; 3834 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3835 /* BB find exact max data count below from sess structure BB */ 3836 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 3837 pSMB->t2.MaxSetupCount = 0; 3838 pSMB->t2.Reserved = 0; 3839 pSMB->t2.Flags = 0; 3840 pSMB->t2.Timeout = 0; 3841 pSMB->t2.Reserved2 = 0; 3842 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3843 Fid) - 4); 3844 pSMB->t2.DataCount = 0; 3845 pSMB->t2.DataOffset = 0; 3846 pSMB->t2.SetupCount = 1; 3847 pSMB->t2.Reserved3 = 0; 3848 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3849 byte_count = params + 1 /* pad */ ; 3850 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3851 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3852 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 3853 pSMB->Pad = 0; 3854 pSMB->Fid = netfid; 3855 inc_rfc1001_len(pSMB, byte_count); 3856 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3857 3858 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3859 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3860 if (rc) { 3861 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc); 3862 } else { /* decode response */ 3863 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3864 3865 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { 3866 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n"); 3867 rc = -EIO; /* bad smb */ 3868 } else { 3869 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3870 memcpy((char *) pFindData, 3871 (char *) &pSMBr->hdr.Protocol + 3872 data_offset, 3873 sizeof(FILE_UNIX_BASIC_INFO)); 3874 } 3875 } 3876 3877 cifs_buf_release(pSMB); 3878 if (rc == -EAGAIN) 3879 goto UnixQFileInfoRetry; 3880 3881 return rc; 3882 } 3883 3884 int 3885 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 3886 const unsigned char *searchName, 3887 FILE_UNIX_BASIC_INFO *pFindData, 3888 const struct nls_table *nls_codepage, int remap) 3889 { 3890 /* SMB_QUERY_FILE_UNIX_BASIC */ 3891 TRANSACTION2_QPI_REQ *pSMB = NULL; 3892 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3893 int rc = 0; 3894 int bytes_returned = 0; 3895 int name_len; 3896 __u16 params, byte_count; 3897 3898 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName); 3899 UnixQPathInfoRetry: 3900 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3901 (void **) &pSMBr); 3902 if (rc) 3903 return rc; 3904 3905 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3906 name_len = 3907 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 3908 PATH_MAX, nls_codepage, remap); 3909 name_len++; /* trailing null */ 3910 name_len *= 2; 3911 } else { 3912 name_len = copy_path_name(pSMB->FileName, searchName); 3913 } 3914 3915 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 3916 pSMB->TotalDataCount = 0; 3917 pSMB->MaxParameterCount = cpu_to_le16(2); 3918 /* BB find exact max SMB PDU from sess structure BB */ 3919 pSMB->MaxDataCount = cpu_to_le16(4000); 3920 pSMB->MaxSetupCount = 0; 3921 pSMB->Reserved = 0; 3922 pSMB->Flags = 0; 3923 pSMB->Timeout = 0; 3924 pSMB->Reserved2 = 0; 3925 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3926 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 3927 pSMB->DataCount = 0; 3928 pSMB->DataOffset = 0; 3929 pSMB->SetupCount = 1; 3930 pSMB->Reserved3 = 0; 3931 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3932 byte_count = params + 1 /* pad */ ; 3933 pSMB->TotalParameterCount = cpu_to_le16(params); 3934 pSMB->ParameterCount = pSMB->TotalParameterCount; 3935 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 3936 pSMB->Reserved4 = 0; 3937 inc_rfc1001_len(pSMB, byte_count); 3938 pSMB->ByteCount = cpu_to_le16(byte_count); 3939 3940 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3941 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3942 if (rc) { 3943 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc); 3944 } else { /* decode response */ 3945 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3946 3947 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { 3948 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n"); 3949 rc = -EIO; /* bad smb */ 3950 } else { 3951 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3952 memcpy((char *) pFindData, 3953 (char *) &pSMBr->hdr.Protocol + 3954 data_offset, 3955 sizeof(FILE_UNIX_BASIC_INFO)); 3956 } 3957 } 3958 cifs_buf_release(pSMB); 3959 if (rc == -EAGAIN) 3960 goto UnixQPathInfoRetry; 3961 3962 return rc; 3963 } 3964 3965 /* xid, tcon, searchName and codepage are input parms, rest are returned */ 3966 int 3967 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon, 3968 const char *searchName, struct cifs_sb_info *cifs_sb, 3969 __u16 *pnetfid, __u16 search_flags, 3970 struct cifs_search_info *psrch_inf, bool msearch) 3971 { 3972 /* level 257 SMB_ */ 3973 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 3974 TRANSACTION2_FFIRST_RSP *pSMBr = NULL; 3975 T2_FFIRST_RSP_PARMS *parms; 3976 struct nls_table *nls_codepage; 3977 unsigned int lnoff; 3978 __u16 params, byte_count; 3979 int bytes_returned = 0; 3980 int name_len, remap; 3981 int rc = 0; 3982 3983 cifs_dbg(FYI, "In FindFirst for %s\n", searchName); 3984 3985 findFirstRetry: 3986 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3987 (void **) &pSMBr); 3988 if (rc) 3989 return rc; 3990 3991 nls_codepage = cifs_sb->local_nls; 3992 remap = cifs_remap(cifs_sb); 3993 3994 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3995 name_len = 3996 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 3997 PATH_MAX, nls_codepage, remap); 3998 /* We can not add the asterik earlier in case 3999 it got remapped to 0xF03A as if it were part of the 4000 directory name instead of a wildcard */ 4001 name_len *= 2; 4002 if (msearch) { 4003 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb); 4004 pSMB->FileName[name_len+1] = 0; 4005 pSMB->FileName[name_len+2] = '*'; 4006 pSMB->FileName[name_len+3] = 0; 4007 name_len += 4; /* now the trailing null */ 4008 /* null terminate just in case */ 4009 pSMB->FileName[name_len] = 0; 4010 pSMB->FileName[name_len+1] = 0; 4011 name_len += 2; 4012 } 4013 } else { 4014 name_len = copy_path_name(pSMB->FileName, searchName); 4015 if (msearch) { 4016 if (WARN_ON_ONCE(name_len > PATH_MAX-2)) 4017 name_len = PATH_MAX-2; 4018 /* overwrite nul byte */ 4019 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb); 4020 pSMB->FileName[name_len] = '*'; 4021 pSMB->FileName[name_len+1] = 0; 4022 name_len += 2; 4023 } 4024 } 4025 4026 params = 12 + name_len /* includes null */ ; 4027 pSMB->TotalDataCount = 0; /* no EAs */ 4028 pSMB->MaxParameterCount = cpu_to_le16(10); 4029 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4030 pSMB->MaxSetupCount = 0; 4031 pSMB->Reserved = 0; 4032 pSMB->Flags = 0; 4033 pSMB->Timeout = 0; 4034 pSMB->Reserved2 = 0; 4035 byte_count = params + 1 /* pad */ ; 4036 pSMB->TotalParameterCount = cpu_to_le16(params); 4037 pSMB->ParameterCount = pSMB->TotalParameterCount; 4038 pSMB->ParameterOffset = cpu_to_le16( 4039 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) 4040 - 4); 4041 pSMB->DataCount = 0; 4042 pSMB->DataOffset = 0; 4043 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */ 4044 pSMB->Reserved3 = 0; 4045 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST); 4046 pSMB->SearchAttributes = 4047 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 4048 ATTR_DIRECTORY); 4049 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO)); 4050 pSMB->SearchFlags = cpu_to_le16(search_flags); 4051 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4052 4053 /* BB what should we set StorageType to? Does it matter? BB */ 4054 pSMB->SearchStorageType = 0; 4055 inc_rfc1001_len(pSMB, byte_count); 4056 pSMB->ByteCount = cpu_to_le16(byte_count); 4057 4058 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4059 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4060 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst); 4061 4062 if (rc) { 4063 /* 4064 * BB: add logic to retry regular search if Unix search rejected 4065 * unexpectedly by server. 4066 */ 4067 /* BB: add code to handle unsupported level rc */ 4068 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc); 4069 cifs_buf_release(pSMB); 4070 /* 4071 * BB: eventually could optimize out free and realloc of buf for 4072 * this case. 4073 */ 4074 if (rc == -EAGAIN) 4075 goto findFirstRetry; 4076 return rc; 4077 } 4078 /* decode response */ 4079 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4080 if (rc) { 4081 cifs_buf_release(pSMB); 4082 return rc; 4083 } 4084 4085 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE); 4086 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 4087 psrch_inf->smallBuf = false; 4088 psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol + 4089 le16_to_cpu(pSMBr->t2.DataOffset); 4090 4091 parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol + 4092 le16_to_cpu(pSMBr->t2.ParameterOffset)); 4093 psrch_inf->endOfSearch = !!parms->EndofSearch; 4094 4095 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 4096 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + 4097 psrch_inf->entries_in_buffer; 4098 lnoff = le16_to_cpu(parms->LastNameOffset); 4099 if (CIFSMaxBufSize < lnoff) { 4100 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4101 psrch_inf->last_entry = NULL; 4102 } else { 4103 psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff; 4104 if (pnetfid) 4105 *pnetfid = parms->SearchHandle; 4106 } 4107 return 0; 4108 } 4109 4110 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon, 4111 __u16 searchHandle, __u16 search_flags, 4112 struct cifs_search_info *psrch_inf) 4113 { 4114 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 4115 TRANSACTION2_FNEXT_RSP *pSMBr = NULL; 4116 T2_FNEXT_RSP_PARMS *parms; 4117 unsigned int name_len; 4118 unsigned int lnoff; 4119 __u16 params, byte_count; 4120 char *response_data; 4121 int bytes_returned; 4122 int rc = 0; 4123 4124 cifs_dbg(FYI, "In FindNext\n"); 4125 4126 if (psrch_inf->endOfSearch) 4127 return -ENOENT; 4128 4129 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4130 (void **) &pSMBr); 4131 if (rc) 4132 return rc; 4133 4134 params = 14; /* includes 2 bytes of null string, converted to LE below*/ 4135 byte_count = 0; 4136 pSMB->TotalDataCount = 0; /* no EAs */ 4137 pSMB->MaxParameterCount = cpu_to_le16(8); 4138 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4139 pSMB->MaxSetupCount = 0; 4140 pSMB->Reserved = 0; 4141 pSMB->Flags = 0; 4142 pSMB->Timeout = 0; 4143 pSMB->Reserved2 = 0; 4144 pSMB->ParameterOffset = cpu_to_le16( 4145 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4); 4146 pSMB->DataCount = 0; 4147 pSMB->DataOffset = 0; 4148 pSMB->SetupCount = 1; 4149 pSMB->Reserved3 = 0; 4150 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); 4151 pSMB->SearchHandle = searchHandle; /* always kept as le */ 4152 pSMB->SearchCount = 4153 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); 4154 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4155 pSMB->ResumeKey = psrch_inf->resume_key; 4156 pSMB->SearchFlags = cpu_to_le16(search_flags); 4157 4158 name_len = psrch_inf->resume_name_len; 4159 params += name_len; 4160 if (name_len < PATH_MAX) { 4161 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len); 4162 byte_count += name_len; 4163 /* 14 byte parm len above enough for 2 byte null terminator */ 4164 pSMB->ResumeFileName[name_len] = 0; 4165 pSMB->ResumeFileName[name_len+1] = 0; 4166 } else { 4167 cifs_buf_release(pSMB); 4168 return -EINVAL; 4169 } 4170 byte_count = params + 1 /* pad */ ; 4171 pSMB->TotalParameterCount = cpu_to_le16(params); 4172 pSMB->ParameterCount = pSMB->TotalParameterCount; 4173 inc_rfc1001_len(pSMB, byte_count); 4174 pSMB->ByteCount = cpu_to_le16(byte_count); 4175 4176 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4177 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4178 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext); 4179 4180 if (rc) { 4181 cifs_buf_release(pSMB); 4182 if (rc == -EBADF) { 4183 psrch_inf->endOfSearch = true; 4184 rc = 0; /* search probably was closed at end of search*/ 4185 } else { 4186 cifs_dbg(FYI, "FindNext returned = %d\n", rc); 4187 } 4188 return rc; 4189 } 4190 4191 /* decode response */ 4192 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4193 if (rc) { 4194 cifs_buf_release(pSMB); 4195 return rc; 4196 } 4197 /* BB fixme add lock for file (srch_info) struct here */ 4198 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE); 4199 response_data = (char *)&pSMBr->hdr.Protocol + 4200 le16_to_cpu(pSMBr->t2.ParameterOffset); 4201 parms = (T2_FNEXT_RSP_PARMS *)response_data; 4202 response_data = (char *)&pSMBr->hdr.Protocol + 4203 le16_to_cpu(pSMBr->t2.DataOffset); 4204 4205 if (psrch_inf->smallBuf) 4206 cifs_small_buf_release(psrch_inf->ntwrk_buf_start); 4207 else 4208 cifs_buf_release(psrch_inf->ntwrk_buf_start); 4209 4210 psrch_inf->srch_entries_start = response_data; 4211 psrch_inf->ntwrk_buf_start = (char *)pSMB; 4212 psrch_inf->smallBuf = false; 4213 psrch_inf->endOfSearch = !!parms->EndofSearch; 4214 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 4215 psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer; 4216 lnoff = le16_to_cpu(parms->LastNameOffset); 4217 if (CIFSMaxBufSize < lnoff) { 4218 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4219 psrch_inf->last_entry = NULL; 4220 } else { 4221 psrch_inf->last_entry = 4222 psrch_inf->srch_entries_start + lnoff; 4223 } 4224 /* BB fixme add unlock here */ 4225 4226 /* 4227 * BB: On error, should we leave previous search buf 4228 * (and count and last entry fields) intact or free the previous one? 4229 * 4230 * Note: On -EAGAIN error only caller can retry on handle based calls 4231 * since file handle passed in no longer valid. 4232 */ 4233 return 0; 4234 } 4235 4236 int 4237 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon, 4238 const __u16 searchHandle) 4239 { 4240 int rc = 0; 4241 FINDCLOSE_REQ *pSMB = NULL; 4242 4243 cifs_dbg(FYI, "In CIFSSMBFindClose\n"); 4244 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); 4245 4246 /* no sense returning error if session restarted 4247 as file handle has been closed */ 4248 if (rc == -EAGAIN) 4249 return 0; 4250 if (rc) 4251 return rc; 4252 4253 pSMB->FileID = searchHandle; 4254 pSMB->ByteCount = 0; 4255 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 4256 cifs_small_buf_release(pSMB); 4257 if (rc) 4258 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc); 4259 4260 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose); 4261 4262 /* Since session is dead, search handle closed on server already */ 4263 if (rc == -EAGAIN) 4264 rc = 0; 4265 4266 return rc; 4267 } 4268 4269 int 4270 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon, 4271 const char *search_name, __u64 *inode_number, 4272 const struct nls_table *nls_codepage, int remap) 4273 { 4274 int rc = 0; 4275 TRANSACTION2_QPI_REQ *pSMB = NULL; 4276 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4277 int name_len, bytes_returned; 4278 __u16 params, byte_count; 4279 4280 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name); 4281 if (tcon == NULL) 4282 return -ENODEV; 4283 4284 GetInodeNumberRetry: 4285 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4286 (void **) &pSMBr); 4287 if (rc) 4288 return rc; 4289 4290 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4291 name_len = 4292 cifsConvertToUTF16((__le16 *) pSMB->FileName, 4293 search_name, PATH_MAX, nls_codepage, 4294 remap); 4295 name_len++; /* trailing null */ 4296 name_len *= 2; 4297 } else { 4298 name_len = copy_path_name(pSMB->FileName, search_name); 4299 } 4300 4301 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 4302 pSMB->TotalDataCount = 0; 4303 pSMB->MaxParameterCount = cpu_to_le16(2); 4304 /* BB find exact max data count below from sess structure BB */ 4305 pSMB->MaxDataCount = cpu_to_le16(4000); 4306 pSMB->MaxSetupCount = 0; 4307 pSMB->Reserved = 0; 4308 pSMB->Flags = 0; 4309 pSMB->Timeout = 0; 4310 pSMB->Reserved2 = 0; 4311 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4312 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 4313 pSMB->DataCount = 0; 4314 pSMB->DataOffset = 0; 4315 pSMB->SetupCount = 1; 4316 pSMB->Reserved3 = 0; 4317 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4318 byte_count = params + 1 /* pad */ ; 4319 pSMB->TotalParameterCount = cpu_to_le16(params); 4320 pSMB->ParameterCount = pSMB->TotalParameterCount; 4321 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO); 4322 pSMB->Reserved4 = 0; 4323 inc_rfc1001_len(pSMB, byte_count); 4324 pSMB->ByteCount = cpu_to_le16(byte_count); 4325 4326 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4327 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4328 if (rc) { 4329 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc); 4330 } else { 4331 /* decode response */ 4332 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4333 /* BB also check enough total bytes returned */ 4334 if (rc || get_bcc(&pSMBr->hdr) < 2) 4335 /* If rc should we check for EOPNOSUPP and 4336 disable the srvino flag? or in caller? */ 4337 rc = -EIO; /* bad smb */ 4338 else { 4339 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4340 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 4341 struct file_internal_info *pfinfo; 4342 /* BB Do we need a cast or hash here ? */ 4343 if (count < 8) { 4344 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n"); 4345 rc = -EIO; 4346 goto GetInodeNumOut; 4347 } 4348 pfinfo = (struct file_internal_info *) 4349 (data_offset + (char *) &pSMBr->hdr.Protocol); 4350 *inode_number = le64_to_cpu(pfinfo->UniqueId); 4351 } 4352 } 4353 GetInodeNumOut: 4354 cifs_buf_release(pSMB); 4355 if (rc == -EAGAIN) 4356 goto GetInodeNumberRetry; 4357 return rc; 4358 } 4359 4360 int 4361 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses, 4362 const char *search_name, struct dfs_info3_param **target_nodes, 4363 unsigned int *num_of_nodes, 4364 const struct nls_table *nls_codepage, int remap) 4365 { 4366 /* TRANS2_GET_DFS_REFERRAL */ 4367 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; 4368 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL; 4369 int rc = 0; 4370 int bytes_returned; 4371 int name_len; 4372 __u16 params, byte_count; 4373 *num_of_nodes = 0; 4374 *target_nodes = NULL; 4375 4376 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name); 4377 if (ses == NULL || ses->tcon_ipc == NULL) 4378 return -ENODEV; 4379 4380 getDFSRetry: 4381 /* 4382 * Use smb_init_no_reconnect() instead of smb_init() as 4383 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus 4384 * causing an infinite recursion. 4385 */ 4386 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, 4387 (void **)&pSMB, (void **)&pSMBr); 4388 if (rc) 4389 return rc; 4390 4391 /* server pointer checked in called function, 4392 but should never be null here anyway */ 4393 pSMB->hdr.Mid = get_next_mid(ses->server); 4394 pSMB->hdr.Tid = ses->tcon_ipc->tid; 4395 pSMB->hdr.Uid = ses->Suid; 4396 if (ses->capabilities & CAP_STATUS32) 4397 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; 4398 if (ses->capabilities & CAP_DFS) 4399 pSMB->hdr.Flags2 |= SMBFLG2_DFS; 4400 4401 if (ses->capabilities & CAP_UNICODE) { 4402 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 4403 name_len = 4404 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName, 4405 search_name, PATH_MAX, nls_codepage, 4406 remap); 4407 name_len++; /* trailing null */ 4408 name_len *= 2; 4409 } else { /* BB improve the check for buffer overruns BB */ 4410 name_len = copy_path_name(pSMB->RequestFileName, search_name); 4411 } 4412 4413 if (ses->server->sign) 4414 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 4415 4416 pSMB->hdr.Uid = ses->Suid; 4417 4418 params = 2 /* level */ + name_len /*includes null */ ; 4419 pSMB->TotalDataCount = 0; 4420 pSMB->DataCount = 0; 4421 pSMB->DataOffset = 0; 4422 pSMB->MaxParameterCount = 0; 4423 /* BB find exact max SMB PDU from sess structure BB */ 4424 pSMB->MaxDataCount = cpu_to_le16(4000); 4425 pSMB->MaxSetupCount = 0; 4426 pSMB->Reserved = 0; 4427 pSMB->Flags = 0; 4428 pSMB->Timeout = 0; 4429 pSMB->Reserved2 = 0; 4430 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4431 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4); 4432 pSMB->SetupCount = 1; 4433 pSMB->Reserved3 = 0; 4434 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL); 4435 byte_count = params + 3 /* pad */ ; 4436 pSMB->ParameterCount = cpu_to_le16(params); 4437 pSMB->TotalParameterCount = pSMB->ParameterCount; 4438 pSMB->MaxReferralLevel = cpu_to_le16(3); 4439 inc_rfc1001_len(pSMB, byte_count); 4440 pSMB->ByteCount = cpu_to_le16(byte_count); 4441 4442 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 4443 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4444 if (rc) { 4445 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc); 4446 goto GetDFSRefExit; 4447 } 4448 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4449 4450 /* BB Also check if enough total bytes returned? */ 4451 if (rc || get_bcc(&pSMBr->hdr) < 17) { 4452 rc = -EIO; /* bad smb */ 4453 goto GetDFSRefExit; 4454 } 4455 4456 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n", 4457 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset)); 4458 4459 /* parse returned result into more usable form */ 4460 rc = parse_dfs_referrals(&pSMBr->dfs_data, 4461 le16_to_cpu(pSMBr->t2.DataCount), 4462 num_of_nodes, target_nodes, nls_codepage, 4463 remap, search_name, 4464 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0); 4465 4466 GetDFSRefExit: 4467 cifs_buf_release(pSMB); 4468 4469 if (rc == -EAGAIN) 4470 goto getDFSRetry; 4471 4472 return rc; 4473 } 4474 4475 /* Query File System Info such as free space to old servers such as Win 9x */ 4476 int 4477 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 4478 struct kstatfs *FSData) 4479 { 4480 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */ 4481 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4482 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4483 FILE_SYSTEM_ALLOC_INFO *response_data; 4484 int rc = 0; 4485 int bytes_returned = 0; 4486 __u16 params, byte_count; 4487 4488 cifs_dbg(FYI, "OldQFSInfo\n"); 4489 oldQFSInfoRetry: 4490 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4491 (void **) &pSMBr); 4492 if (rc) 4493 return rc; 4494 4495 params = 2; /* level */ 4496 pSMB->TotalDataCount = 0; 4497 pSMB->MaxParameterCount = cpu_to_le16(2); 4498 pSMB->MaxDataCount = cpu_to_le16(1000); 4499 pSMB->MaxSetupCount = 0; 4500 pSMB->Reserved = 0; 4501 pSMB->Flags = 0; 4502 pSMB->Timeout = 0; 4503 pSMB->Reserved2 = 0; 4504 byte_count = params + 1 /* pad */ ; 4505 pSMB->TotalParameterCount = cpu_to_le16(params); 4506 pSMB->ParameterCount = pSMB->TotalParameterCount; 4507 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4508 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4509 pSMB->DataCount = 0; 4510 pSMB->DataOffset = 0; 4511 pSMB->SetupCount = 1; 4512 pSMB->Reserved3 = 0; 4513 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4514 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION); 4515 inc_rfc1001_len(pSMB, byte_count); 4516 pSMB->ByteCount = cpu_to_le16(byte_count); 4517 4518 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4519 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4520 if (rc) { 4521 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 4522 } else { /* decode response */ 4523 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4524 4525 if (rc || get_bcc(&pSMBr->hdr) < 18) 4526 rc = -EIO; /* bad smb */ 4527 else { 4528 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4529 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n", 4530 get_bcc(&pSMBr->hdr), data_offset); 4531 4532 response_data = (FILE_SYSTEM_ALLOC_INFO *) 4533 (((char *) &pSMBr->hdr.Protocol) + data_offset); 4534 FSData->f_bsize = 4535 le16_to_cpu(response_data->BytesPerSector) * 4536 le32_to_cpu(response_data-> 4537 SectorsPerAllocationUnit); 4538 /* 4539 * much prefer larger but if server doesn't report 4540 * a valid size than 4K is a reasonable minimum 4541 */ 4542 if (FSData->f_bsize < 512) 4543 FSData->f_bsize = 4096; 4544 4545 FSData->f_blocks = 4546 le32_to_cpu(response_data->TotalAllocationUnits); 4547 FSData->f_bfree = FSData->f_bavail = 4548 le32_to_cpu(response_data->FreeAllocationUnits); 4549 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 4550 (unsigned long long)FSData->f_blocks, 4551 (unsigned long long)FSData->f_bfree, 4552 FSData->f_bsize); 4553 } 4554 } 4555 cifs_buf_release(pSMB); 4556 4557 if (rc == -EAGAIN) 4558 goto oldQFSInfoRetry; 4559 4560 return rc; 4561 } 4562 4563 int 4564 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 4565 struct kstatfs *FSData) 4566 { 4567 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ 4568 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4569 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4570 FILE_SYSTEM_INFO *response_data; 4571 int rc = 0; 4572 int bytes_returned = 0; 4573 __u16 params, byte_count; 4574 4575 cifs_dbg(FYI, "In QFSInfo\n"); 4576 QFSInfoRetry: 4577 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4578 (void **) &pSMBr); 4579 if (rc) 4580 return rc; 4581 4582 params = 2; /* level */ 4583 pSMB->TotalDataCount = 0; 4584 pSMB->MaxParameterCount = cpu_to_le16(2); 4585 pSMB->MaxDataCount = cpu_to_le16(1000); 4586 pSMB->MaxSetupCount = 0; 4587 pSMB->Reserved = 0; 4588 pSMB->Flags = 0; 4589 pSMB->Timeout = 0; 4590 pSMB->Reserved2 = 0; 4591 byte_count = params + 1 /* pad */ ; 4592 pSMB->TotalParameterCount = cpu_to_le16(params); 4593 pSMB->ParameterCount = pSMB->TotalParameterCount; 4594 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4595 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4596 pSMB->DataCount = 0; 4597 pSMB->DataOffset = 0; 4598 pSMB->SetupCount = 1; 4599 pSMB->Reserved3 = 0; 4600 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4601 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO); 4602 inc_rfc1001_len(pSMB, byte_count); 4603 pSMB->ByteCount = cpu_to_le16(byte_count); 4604 4605 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4606 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4607 if (rc) { 4608 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 4609 } else { /* decode response */ 4610 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4611 4612 if (rc || get_bcc(&pSMBr->hdr) < 24) 4613 rc = -EIO; /* bad smb */ 4614 else { 4615 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4616 4617 response_data = 4618 (FILE_SYSTEM_INFO 4619 *) (((char *) &pSMBr->hdr.Protocol) + 4620 data_offset); 4621 FSData->f_bsize = 4622 le32_to_cpu(response_data->BytesPerSector) * 4623 le32_to_cpu(response_data-> 4624 SectorsPerAllocationUnit); 4625 /* 4626 * much prefer larger but if server doesn't report 4627 * a valid size than 4K is a reasonable minimum 4628 */ 4629 if (FSData->f_bsize < 512) 4630 FSData->f_bsize = 4096; 4631 4632 FSData->f_blocks = 4633 le64_to_cpu(response_data->TotalAllocationUnits); 4634 FSData->f_bfree = FSData->f_bavail = 4635 le64_to_cpu(response_data->FreeAllocationUnits); 4636 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 4637 (unsigned long long)FSData->f_blocks, 4638 (unsigned long long)FSData->f_bfree, 4639 FSData->f_bsize); 4640 } 4641 } 4642 cifs_buf_release(pSMB); 4643 4644 if (rc == -EAGAIN) 4645 goto QFSInfoRetry; 4646 4647 return rc; 4648 } 4649 4650 int 4651 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon) 4652 { 4653 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ 4654 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4655 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4656 FILE_SYSTEM_ATTRIBUTE_INFO *response_data; 4657 int rc = 0; 4658 int bytes_returned = 0; 4659 __u16 params, byte_count; 4660 4661 cifs_dbg(FYI, "In QFSAttributeInfo\n"); 4662 QFSAttributeRetry: 4663 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4664 (void **) &pSMBr); 4665 if (rc) 4666 return rc; 4667 4668 params = 2; /* level */ 4669 pSMB->TotalDataCount = 0; 4670 pSMB->MaxParameterCount = cpu_to_le16(2); 4671 /* BB find exact max SMB PDU from sess structure BB */ 4672 pSMB->MaxDataCount = cpu_to_le16(1000); 4673 pSMB->MaxSetupCount = 0; 4674 pSMB->Reserved = 0; 4675 pSMB->Flags = 0; 4676 pSMB->Timeout = 0; 4677 pSMB->Reserved2 = 0; 4678 byte_count = params + 1 /* pad */ ; 4679 pSMB->TotalParameterCount = cpu_to_le16(params); 4680 pSMB->ParameterCount = pSMB->TotalParameterCount; 4681 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4682 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4683 pSMB->DataCount = 0; 4684 pSMB->DataOffset = 0; 4685 pSMB->SetupCount = 1; 4686 pSMB->Reserved3 = 0; 4687 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4688 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO); 4689 inc_rfc1001_len(pSMB, byte_count); 4690 pSMB->ByteCount = cpu_to_le16(byte_count); 4691 4692 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4693 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4694 if (rc) { 4695 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc); 4696 } else { /* decode response */ 4697 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4698 4699 if (rc || get_bcc(&pSMBr->hdr) < 13) { 4700 /* BB also check if enough bytes returned */ 4701 rc = -EIO; /* bad smb */ 4702 } else { 4703 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4704 response_data = 4705 (FILE_SYSTEM_ATTRIBUTE_INFO 4706 *) (((char *) &pSMBr->hdr.Protocol) + 4707 data_offset); 4708 memcpy(&tcon->fsAttrInfo, response_data, 4709 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)); 4710 } 4711 } 4712 cifs_buf_release(pSMB); 4713 4714 if (rc == -EAGAIN) 4715 goto QFSAttributeRetry; 4716 4717 return rc; 4718 } 4719 4720 int 4721 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon) 4722 { 4723 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ 4724 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4725 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4726 FILE_SYSTEM_DEVICE_INFO *response_data; 4727 int rc = 0; 4728 int bytes_returned = 0; 4729 __u16 params, byte_count; 4730 4731 cifs_dbg(FYI, "In QFSDeviceInfo\n"); 4732 QFSDeviceRetry: 4733 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4734 (void **) &pSMBr); 4735 if (rc) 4736 return rc; 4737 4738 params = 2; /* level */ 4739 pSMB->TotalDataCount = 0; 4740 pSMB->MaxParameterCount = cpu_to_le16(2); 4741 /* BB find exact max SMB PDU from sess structure BB */ 4742 pSMB->MaxDataCount = cpu_to_le16(1000); 4743 pSMB->MaxSetupCount = 0; 4744 pSMB->Reserved = 0; 4745 pSMB->Flags = 0; 4746 pSMB->Timeout = 0; 4747 pSMB->Reserved2 = 0; 4748 byte_count = params + 1 /* pad */ ; 4749 pSMB->TotalParameterCount = cpu_to_le16(params); 4750 pSMB->ParameterCount = pSMB->TotalParameterCount; 4751 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4752 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4753 4754 pSMB->DataCount = 0; 4755 pSMB->DataOffset = 0; 4756 pSMB->SetupCount = 1; 4757 pSMB->Reserved3 = 0; 4758 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4759 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO); 4760 inc_rfc1001_len(pSMB, byte_count); 4761 pSMB->ByteCount = cpu_to_le16(byte_count); 4762 4763 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4764 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4765 if (rc) { 4766 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc); 4767 } else { /* decode response */ 4768 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4769 4770 if (rc || get_bcc(&pSMBr->hdr) < 4771 sizeof(FILE_SYSTEM_DEVICE_INFO)) 4772 rc = -EIO; /* bad smb */ 4773 else { 4774 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4775 response_data = 4776 (FILE_SYSTEM_DEVICE_INFO *) 4777 (((char *) &pSMBr->hdr.Protocol) + 4778 data_offset); 4779 memcpy(&tcon->fsDevInfo, response_data, 4780 sizeof(FILE_SYSTEM_DEVICE_INFO)); 4781 } 4782 } 4783 cifs_buf_release(pSMB); 4784 4785 if (rc == -EAGAIN) 4786 goto QFSDeviceRetry; 4787 4788 return rc; 4789 } 4790 4791 int 4792 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon) 4793 { 4794 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ 4795 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4796 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4797 FILE_SYSTEM_UNIX_INFO *response_data; 4798 int rc = 0; 4799 int bytes_returned = 0; 4800 __u16 params, byte_count; 4801 4802 cifs_dbg(FYI, "In QFSUnixInfo\n"); 4803 QFSUnixRetry: 4804 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 4805 (void **) &pSMB, (void **) &pSMBr); 4806 if (rc) 4807 return rc; 4808 4809 params = 2; /* level */ 4810 pSMB->TotalDataCount = 0; 4811 pSMB->DataCount = 0; 4812 pSMB->DataOffset = 0; 4813 pSMB->MaxParameterCount = cpu_to_le16(2); 4814 /* BB find exact max SMB PDU from sess structure BB */ 4815 pSMB->MaxDataCount = cpu_to_le16(100); 4816 pSMB->MaxSetupCount = 0; 4817 pSMB->Reserved = 0; 4818 pSMB->Flags = 0; 4819 pSMB->Timeout = 0; 4820 pSMB->Reserved2 = 0; 4821 byte_count = params + 1 /* pad */ ; 4822 pSMB->ParameterCount = cpu_to_le16(params); 4823 pSMB->TotalParameterCount = pSMB->ParameterCount; 4824 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 4825 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4826 pSMB->SetupCount = 1; 4827 pSMB->Reserved3 = 0; 4828 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4829 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO); 4830 inc_rfc1001_len(pSMB, byte_count); 4831 pSMB->ByteCount = cpu_to_le16(byte_count); 4832 4833 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4834 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4835 if (rc) { 4836 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc); 4837 } else { /* decode response */ 4838 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4839 4840 if (rc || get_bcc(&pSMBr->hdr) < 13) { 4841 rc = -EIO; /* bad smb */ 4842 } else { 4843 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4844 response_data = 4845 (FILE_SYSTEM_UNIX_INFO 4846 *) (((char *) &pSMBr->hdr.Protocol) + 4847 data_offset); 4848 memcpy(&tcon->fsUnixInfo, response_data, 4849 sizeof(FILE_SYSTEM_UNIX_INFO)); 4850 } 4851 } 4852 cifs_buf_release(pSMB); 4853 4854 if (rc == -EAGAIN) 4855 goto QFSUnixRetry; 4856 4857 4858 return rc; 4859 } 4860 4861 int 4862 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap) 4863 { 4864 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */ 4865 TRANSACTION2_SETFSI_REQ *pSMB = NULL; 4866 TRANSACTION2_SETFSI_RSP *pSMBr = NULL; 4867 int rc = 0; 4868 int bytes_returned = 0; 4869 __u16 params, param_offset, offset, byte_count; 4870 4871 cifs_dbg(FYI, "In SETFSUnixInfo\n"); 4872 SETFSUnixRetry: 4873 /* BB switch to small buf init to save memory */ 4874 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 4875 (void **) &pSMB, (void **) &pSMBr); 4876 if (rc) 4877 return rc; 4878 4879 params = 4; /* 2 bytes zero followed by info level. */ 4880 pSMB->MaxSetupCount = 0; 4881 pSMB->Reserved = 0; 4882 pSMB->Flags = 0; 4883 pSMB->Timeout = 0; 4884 pSMB->Reserved2 = 0; 4885 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) 4886 - 4; 4887 offset = param_offset + params; 4888 4889 pSMB->MaxParameterCount = cpu_to_le16(4); 4890 /* BB find exact max SMB PDU from sess structure BB */ 4891 pSMB->MaxDataCount = cpu_to_le16(100); 4892 pSMB->SetupCount = 1; 4893 pSMB->Reserved3 = 0; 4894 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION); 4895 byte_count = 1 /* pad */ + params + 12; 4896 4897 pSMB->DataCount = cpu_to_le16(12); 4898 pSMB->ParameterCount = cpu_to_le16(params); 4899 pSMB->TotalDataCount = pSMB->DataCount; 4900 pSMB->TotalParameterCount = pSMB->ParameterCount; 4901 pSMB->ParameterOffset = cpu_to_le16(param_offset); 4902 pSMB->DataOffset = cpu_to_le16(offset); 4903 4904 /* Params. */ 4905 pSMB->FileNum = 0; 4906 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO); 4907 4908 /* Data. */ 4909 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION); 4910 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION); 4911 pSMB->ClientUnixCap = cpu_to_le64(cap); 4912 4913 inc_rfc1001_len(pSMB, byte_count); 4914 pSMB->ByteCount = cpu_to_le16(byte_count); 4915 4916 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4917 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4918 if (rc) { 4919 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc); 4920 } else { /* decode response */ 4921 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4922 if (rc) 4923 rc = -EIO; /* bad smb */ 4924 } 4925 cifs_buf_release(pSMB); 4926 4927 if (rc == -EAGAIN) 4928 goto SETFSUnixRetry; 4929 4930 return rc; 4931 } 4932 4933 4934 4935 int 4936 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon, 4937 struct kstatfs *FSData) 4938 { 4939 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ 4940 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4941 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4942 FILE_SYSTEM_POSIX_INFO *response_data; 4943 int rc = 0; 4944 int bytes_returned = 0; 4945 __u16 params, byte_count; 4946 4947 cifs_dbg(FYI, "In QFSPosixInfo\n"); 4948 QFSPosixRetry: 4949 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4950 (void **) &pSMBr); 4951 if (rc) 4952 return rc; 4953 4954 params = 2; /* level */ 4955 pSMB->TotalDataCount = 0; 4956 pSMB->DataCount = 0; 4957 pSMB->DataOffset = 0; 4958 pSMB->MaxParameterCount = cpu_to_le16(2); 4959 /* BB find exact max SMB PDU from sess structure BB */ 4960 pSMB->MaxDataCount = cpu_to_le16(100); 4961 pSMB->MaxSetupCount = 0; 4962 pSMB->Reserved = 0; 4963 pSMB->Flags = 0; 4964 pSMB->Timeout = 0; 4965 pSMB->Reserved2 = 0; 4966 byte_count = params + 1 /* pad */ ; 4967 pSMB->ParameterCount = cpu_to_le16(params); 4968 pSMB->TotalParameterCount = pSMB->ParameterCount; 4969 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 4970 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4971 pSMB->SetupCount = 1; 4972 pSMB->Reserved3 = 0; 4973 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4974 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO); 4975 inc_rfc1001_len(pSMB, byte_count); 4976 pSMB->ByteCount = cpu_to_le16(byte_count); 4977 4978 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4979 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4980 if (rc) { 4981 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc); 4982 } else { /* decode response */ 4983 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4984 4985 if (rc || get_bcc(&pSMBr->hdr) < 13) { 4986 rc = -EIO; /* bad smb */ 4987 } else { 4988 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4989 response_data = 4990 (FILE_SYSTEM_POSIX_INFO 4991 *) (((char *) &pSMBr->hdr.Protocol) + 4992 data_offset); 4993 FSData->f_bsize = 4994 le32_to_cpu(response_data->BlockSize); 4995 /* 4996 * much prefer larger but if server doesn't report 4997 * a valid size than 4K is a reasonable minimum 4998 */ 4999 if (FSData->f_bsize < 512) 5000 FSData->f_bsize = 4096; 5001 5002 FSData->f_blocks = 5003 le64_to_cpu(response_data->TotalBlocks); 5004 FSData->f_bfree = 5005 le64_to_cpu(response_data->BlocksAvail); 5006 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) { 5007 FSData->f_bavail = FSData->f_bfree; 5008 } else { 5009 FSData->f_bavail = 5010 le64_to_cpu(response_data->UserBlocksAvail); 5011 } 5012 if (response_data->TotalFileNodes != cpu_to_le64(-1)) 5013 FSData->f_files = 5014 le64_to_cpu(response_data->TotalFileNodes); 5015 if (response_data->FreeFileNodes != cpu_to_le64(-1)) 5016 FSData->f_ffree = 5017 le64_to_cpu(response_data->FreeFileNodes); 5018 } 5019 } 5020 cifs_buf_release(pSMB); 5021 5022 if (rc == -EAGAIN) 5023 goto QFSPosixRetry; 5024 5025 return rc; 5026 } 5027 5028 5029 /* 5030 * We can not use write of zero bytes trick to set file size due to need for 5031 * large file support. Also note that this SetPathInfo is preferred to 5032 * SetFileInfo based method in next routine which is only needed to work around 5033 * a sharing violation bugin Samba which this routine can run into. 5034 */ 5035 int 5036 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon, 5037 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb, 5038 bool set_allocation, struct dentry *dentry) 5039 { 5040 struct smb_com_transaction2_spi_req *pSMB = NULL; 5041 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5042 struct file_end_of_file_info *parm_data; 5043 int name_len; 5044 int rc = 0; 5045 int bytes_returned = 0; 5046 int remap = cifs_remap(cifs_sb); 5047 5048 __u16 params, byte_count, data_count, param_offset, offset; 5049 5050 cifs_dbg(FYI, "In SetEOF\n"); 5051 SetEOFRetry: 5052 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5053 (void **) &pSMBr); 5054 if (rc) 5055 return rc; 5056 5057 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5058 name_len = 5059 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 5060 PATH_MAX, cifs_sb->local_nls, remap); 5061 name_len++; /* trailing null */ 5062 name_len *= 2; 5063 } else { 5064 name_len = copy_path_name(pSMB->FileName, file_name); 5065 } 5066 params = 6 + name_len; 5067 data_count = sizeof(struct file_end_of_file_info); 5068 pSMB->MaxParameterCount = cpu_to_le16(2); 5069 pSMB->MaxDataCount = cpu_to_le16(4100); 5070 pSMB->MaxSetupCount = 0; 5071 pSMB->Reserved = 0; 5072 pSMB->Flags = 0; 5073 pSMB->Timeout = 0; 5074 pSMB->Reserved2 = 0; 5075 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5076 InformationLevel) - 4; 5077 offset = param_offset + params; 5078 if (set_allocation) { 5079 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5080 pSMB->InformationLevel = 5081 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5082 else 5083 pSMB->InformationLevel = 5084 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5085 } else /* Set File Size */ { 5086 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5087 pSMB->InformationLevel = 5088 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5089 else 5090 pSMB->InformationLevel = 5091 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5092 } 5093 5094 parm_data = 5095 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) + 5096 offset); 5097 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5098 pSMB->DataOffset = cpu_to_le16(offset); 5099 pSMB->SetupCount = 1; 5100 pSMB->Reserved3 = 0; 5101 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5102 byte_count = 3 /* pad */ + params + data_count; 5103 pSMB->DataCount = cpu_to_le16(data_count); 5104 pSMB->TotalDataCount = pSMB->DataCount; 5105 pSMB->ParameterCount = cpu_to_le16(params); 5106 pSMB->TotalParameterCount = pSMB->ParameterCount; 5107 pSMB->Reserved4 = 0; 5108 inc_rfc1001_len(pSMB, byte_count); 5109 parm_data->FileSize = cpu_to_le64(size); 5110 pSMB->ByteCount = cpu_to_le16(byte_count); 5111 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5112 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5113 if (rc) 5114 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc); 5115 5116 cifs_buf_release(pSMB); 5117 5118 if (rc == -EAGAIN) 5119 goto SetEOFRetry; 5120 5121 return rc; 5122 } 5123 5124 int 5125 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, 5126 struct cifsFileInfo *cfile, __u64 size, bool set_allocation) 5127 { 5128 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5129 struct file_end_of_file_info *parm_data; 5130 int rc = 0; 5131 __u16 params, param_offset, offset, byte_count, count; 5132 5133 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n", 5134 (long long)size); 5135 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5136 5137 if (rc) 5138 return rc; 5139 5140 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid); 5141 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16)); 5142 5143 params = 6; 5144 pSMB->MaxSetupCount = 0; 5145 pSMB->Reserved = 0; 5146 pSMB->Flags = 0; 5147 pSMB->Timeout = 0; 5148 pSMB->Reserved2 = 0; 5149 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5150 offset = param_offset + params; 5151 5152 count = sizeof(struct file_end_of_file_info); 5153 pSMB->MaxParameterCount = cpu_to_le16(2); 5154 /* BB find exact max SMB PDU from sess structure BB */ 5155 pSMB->MaxDataCount = cpu_to_le16(1000); 5156 pSMB->SetupCount = 1; 5157 pSMB->Reserved3 = 0; 5158 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5159 byte_count = 3 /* pad */ + params + count; 5160 pSMB->DataCount = cpu_to_le16(count); 5161 pSMB->ParameterCount = cpu_to_le16(params); 5162 pSMB->TotalDataCount = pSMB->DataCount; 5163 pSMB->TotalParameterCount = pSMB->ParameterCount; 5164 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5165 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5166 parm_data = 5167 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4); 5168 pSMB->DataOffset = cpu_to_le16(offset); 5169 parm_data->FileSize = cpu_to_le64(size); 5170 pSMB->Fid = cfile->fid.netfid; 5171 if (set_allocation) { 5172 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5173 pSMB->InformationLevel = 5174 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5175 else 5176 pSMB->InformationLevel = 5177 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5178 } else /* Set File Size */ { 5179 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5180 pSMB->InformationLevel = 5181 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5182 else 5183 pSMB->InformationLevel = 5184 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5185 } 5186 pSMB->Reserved4 = 0; 5187 inc_rfc1001_len(pSMB, byte_count); 5188 pSMB->ByteCount = cpu_to_le16(byte_count); 5189 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5190 cifs_small_buf_release(pSMB); 5191 if (rc) { 5192 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n", 5193 rc); 5194 } 5195 5196 /* Note: On -EAGAIN error only caller can retry on handle based calls 5197 since file handle passed in no longer valid */ 5198 5199 return rc; 5200 } 5201 5202 /* Some legacy servers such as NT4 require that the file times be set on 5203 an open handle, rather than by pathname - this is awkward due to 5204 potential access conflicts on the open, but it is unavoidable for these 5205 old servers since the only other choice is to go from 100 nanosecond DCE 5206 time and resort to the original setpathinfo level which takes the ancient 5207 DOS time format with 2 second granularity */ 5208 int 5209 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 5210 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener) 5211 { 5212 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5213 char *data_offset; 5214 int rc = 0; 5215 __u16 params, param_offset, offset, byte_count, count; 5216 5217 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n"); 5218 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5219 5220 if (rc) 5221 return rc; 5222 5223 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5224 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5225 5226 params = 6; 5227 pSMB->MaxSetupCount = 0; 5228 pSMB->Reserved = 0; 5229 pSMB->Flags = 0; 5230 pSMB->Timeout = 0; 5231 pSMB->Reserved2 = 0; 5232 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5233 offset = param_offset + params; 5234 5235 data_offset = (char *)pSMB + 5236 offsetof(struct smb_hdr, Protocol) + offset; 5237 5238 count = sizeof(FILE_BASIC_INFO); 5239 pSMB->MaxParameterCount = cpu_to_le16(2); 5240 /* BB find max SMB PDU from sess */ 5241 pSMB->MaxDataCount = cpu_to_le16(1000); 5242 pSMB->SetupCount = 1; 5243 pSMB->Reserved3 = 0; 5244 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5245 byte_count = 3 /* pad */ + params + count; 5246 pSMB->DataCount = cpu_to_le16(count); 5247 pSMB->ParameterCount = cpu_to_le16(params); 5248 pSMB->TotalDataCount = pSMB->DataCount; 5249 pSMB->TotalParameterCount = pSMB->ParameterCount; 5250 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5251 pSMB->DataOffset = cpu_to_le16(offset); 5252 pSMB->Fid = fid; 5253 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5254 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5255 else 5256 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5257 pSMB->Reserved4 = 0; 5258 inc_rfc1001_len(pSMB, byte_count); 5259 pSMB->ByteCount = cpu_to_le16(byte_count); 5260 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5261 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5262 cifs_small_buf_release(pSMB); 5263 if (rc) 5264 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 5265 rc); 5266 5267 /* Note: On -EAGAIN error only caller can retry on handle based calls 5268 since file handle passed in no longer valid */ 5269 5270 return rc; 5271 } 5272 5273 int 5274 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon, 5275 bool delete_file, __u16 fid, __u32 pid_of_opener) 5276 { 5277 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5278 char *data_offset; 5279 int rc = 0; 5280 __u16 params, param_offset, offset, byte_count, count; 5281 5282 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n"); 5283 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5284 5285 if (rc) 5286 return rc; 5287 5288 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5289 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5290 5291 params = 6; 5292 pSMB->MaxSetupCount = 0; 5293 pSMB->Reserved = 0; 5294 pSMB->Flags = 0; 5295 pSMB->Timeout = 0; 5296 pSMB->Reserved2 = 0; 5297 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5298 offset = param_offset + params; 5299 5300 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5301 data_offset = (char *)(pSMB) + offset + 4; 5302 5303 count = 1; 5304 pSMB->MaxParameterCount = cpu_to_le16(2); 5305 /* BB find max SMB PDU from sess */ 5306 pSMB->MaxDataCount = cpu_to_le16(1000); 5307 pSMB->SetupCount = 1; 5308 pSMB->Reserved3 = 0; 5309 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5310 byte_count = 3 /* pad */ + params + count; 5311 pSMB->DataCount = cpu_to_le16(count); 5312 pSMB->ParameterCount = cpu_to_le16(params); 5313 pSMB->TotalDataCount = pSMB->DataCount; 5314 pSMB->TotalParameterCount = pSMB->ParameterCount; 5315 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5316 pSMB->DataOffset = cpu_to_le16(offset); 5317 pSMB->Fid = fid; 5318 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO); 5319 pSMB->Reserved4 = 0; 5320 inc_rfc1001_len(pSMB, byte_count); 5321 pSMB->ByteCount = cpu_to_le16(byte_count); 5322 *data_offset = delete_file ? 1 : 0; 5323 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5324 cifs_small_buf_release(pSMB); 5325 if (rc) 5326 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc); 5327 5328 return rc; 5329 } 5330 5331 static int 5332 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon, 5333 const char *fileName, const FILE_BASIC_INFO *data, 5334 const struct nls_table *nls_codepage, 5335 struct cifs_sb_info *cifs_sb) 5336 { 5337 int oplock = 0; 5338 struct cifs_open_parms oparms; 5339 struct cifs_fid fid; 5340 int rc; 5341 5342 oparms = (struct cifs_open_parms) { 5343 .tcon = tcon, 5344 .cifs_sb = cifs_sb, 5345 .desired_access = GENERIC_WRITE, 5346 .create_options = cifs_create_options(cifs_sb, 0), 5347 .disposition = FILE_OPEN, 5348 .path = fileName, 5349 .fid = &fid, 5350 }; 5351 5352 rc = CIFS_open(xid, &oparms, &oplock, NULL); 5353 if (rc) 5354 goto out; 5355 5356 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid); 5357 CIFSSMBClose(xid, tcon, fid.netfid); 5358 out: 5359 5360 return rc; 5361 } 5362 5363 int 5364 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5365 const char *fileName, const FILE_BASIC_INFO *data, 5366 const struct nls_table *nls_codepage, 5367 struct cifs_sb_info *cifs_sb) 5368 { 5369 TRANSACTION2_SPI_REQ *pSMB = NULL; 5370 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5371 int name_len; 5372 int rc = 0; 5373 int bytes_returned = 0; 5374 char *data_offset; 5375 __u16 params, param_offset, offset, byte_count, count; 5376 int remap = cifs_remap(cifs_sb); 5377 5378 cifs_dbg(FYI, "In SetTimes\n"); 5379 5380 SetTimesRetry: 5381 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5382 (void **) &pSMBr); 5383 if (rc) 5384 return rc; 5385 5386 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5387 name_len = 5388 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 5389 PATH_MAX, nls_codepage, remap); 5390 name_len++; /* trailing null */ 5391 name_len *= 2; 5392 } else { 5393 name_len = copy_path_name(pSMB->FileName, fileName); 5394 } 5395 5396 params = 6 + name_len; 5397 count = sizeof(FILE_BASIC_INFO); 5398 pSMB->MaxParameterCount = cpu_to_le16(2); 5399 /* BB find max SMB PDU from sess structure BB */ 5400 pSMB->MaxDataCount = cpu_to_le16(1000); 5401 pSMB->MaxSetupCount = 0; 5402 pSMB->Reserved = 0; 5403 pSMB->Flags = 0; 5404 pSMB->Timeout = 0; 5405 pSMB->Reserved2 = 0; 5406 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5407 InformationLevel) - 4; 5408 offset = param_offset + params; 5409 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 5410 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5411 pSMB->DataOffset = cpu_to_le16(offset); 5412 pSMB->SetupCount = 1; 5413 pSMB->Reserved3 = 0; 5414 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5415 byte_count = 3 /* pad */ + params + count; 5416 5417 pSMB->DataCount = cpu_to_le16(count); 5418 pSMB->ParameterCount = cpu_to_le16(params); 5419 pSMB->TotalDataCount = pSMB->DataCount; 5420 pSMB->TotalParameterCount = pSMB->ParameterCount; 5421 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5422 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5423 else 5424 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5425 pSMB->Reserved4 = 0; 5426 inc_rfc1001_len(pSMB, byte_count); 5427 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5428 pSMB->ByteCount = cpu_to_le16(byte_count); 5429 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5430 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5431 if (rc) 5432 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc); 5433 5434 cifs_buf_release(pSMB); 5435 5436 if (rc == -EAGAIN) 5437 goto SetTimesRetry; 5438 5439 if (rc == -EOPNOTSUPP) 5440 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data, 5441 nls_codepage, cifs_sb); 5442 5443 return rc; 5444 } 5445 5446 static void 5447 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, 5448 const struct cifs_unix_set_info_args *args) 5449 { 5450 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64; 5451 u64 mode = args->mode; 5452 5453 if (uid_valid(args->uid)) 5454 uid = from_kuid(&init_user_ns, args->uid); 5455 if (gid_valid(args->gid)) 5456 gid = from_kgid(&init_user_ns, args->gid); 5457 5458 /* 5459 * Samba server ignores set of file size to zero due to bugs in some 5460 * older clients, but we should be precise - we use SetFileSize to 5461 * set file size and do not want to truncate file size to zero 5462 * accidentally as happened on one Samba server beta by putting 5463 * zero instead of -1 here 5464 */ 5465 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); 5466 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); 5467 data_offset->LastStatusChange = cpu_to_le64(args->ctime); 5468 data_offset->LastAccessTime = cpu_to_le64(args->atime); 5469 data_offset->LastModificationTime = cpu_to_le64(args->mtime); 5470 data_offset->Uid = cpu_to_le64(uid); 5471 data_offset->Gid = cpu_to_le64(gid); 5472 /* better to leave device as zero when it is */ 5473 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); 5474 data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); 5475 data_offset->Permissions = cpu_to_le64(mode); 5476 5477 if (S_ISREG(mode)) 5478 data_offset->Type = cpu_to_le32(UNIX_FILE); 5479 else if (S_ISDIR(mode)) 5480 data_offset->Type = cpu_to_le32(UNIX_DIR); 5481 else if (S_ISLNK(mode)) 5482 data_offset->Type = cpu_to_le32(UNIX_SYMLINK); 5483 else if (S_ISCHR(mode)) 5484 data_offset->Type = cpu_to_le32(UNIX_CHARDEV); 5485 else if (S_ISBLK(mode)) 5486 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); 5487 else if (S_ISFIFO(mode)) 5488 data_offset->Type = cpu_to_le32(UNIX_FIFO); 5489 else if (S_ISSOCK(mode)) 5490 data_offset->Type = cpu_to_le32(UNIX_SOCKET); 5491 } 5492 5493 int 5494 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 5495 const struct cifs_unix_set_info_args *args, 5496 u16 fid, u32 pid_of_opener) 5497 { 5498 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5499 char *data_offset; 5500 int rc = 0; 5501 u16 params, param_offset, offset, byte_count, count; 5502 5503 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n"); 5504 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5505 5506 if (rc) 5507 return rc; 5508 5509 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5510 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5511 5512 params = 6; 5513 pSMB->MaxSetupCount = 0; 5514 pSMB->Reserved = 0; 5515 pSMB->Flags = 0; 5516 pSMB->Timeout = 0; 5517 pSMB->Reserved2 = 0; 5518 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5519 offset = param_offset + params; 5520 5521 data_offset = (char *)pSMB + 5522 offsetof(struct smb_hdr, Protocol) + offset; 5523 5524 count = sizeof(FILE_UNIX_BASIC_INFO); 5525 5526 pSMB->MaxParameterCount = cpu_to_le16(2); 5527 /* BB find max SMB PDU from sess */ 5528 pSMB->MaxDataCount = cpu_to_le16(1000); 5529 pSMB->SetupCount = 1; 5530 pSMB->Reserved3 = 0; 5531 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5532 byte_count = 3 /* pad */ + params + count; 5533 pSMB->DataCount = cpu_to_le16(count); 5534 pSMB->ParameterCount = cpu_to_le16(params); 5535 pSMB->TotalDataCount = pSMB->DataCount; 5536 pSMB->TotalParameterCount = pSMB->ParameterCount; 5537 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5538 pSMB->DataOffset = cpu_to_le16(offset); 5539 pSMB->Fid = fid; 5540 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5541 pSMB->Reserved4 = 0; 5542 inc_rfc1001_len(pSMB, byte_count); 5543 pSMB->ByteCount = cpu_to_le16(byte_count); 5544 5545 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args); 5546 5547 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5548 cifs_small_buf_release(pSMB); 5549 if (rc) 5550 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 5551 rc); 5552 5553 /* Note: On -EAGAIN error only caller can retry on handle based calls 5554 since file handle passed in no longer valid */ 5555 5556 return rc; 5557 } 5558 5559 int 5560 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5561 const char *file_name, 5562 const struct cifs_unix_set_info_args *args, 5563 const struct nls_table *nls_codepage, int remap) 5564 { 5565 TRANSACTION2_SPI_REQ *pSMB = NULL; 5566 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5567 int name_len; 5568 int rc = 0; 5569 int bytes_returned = 0; 5570 FILE_UNIX_BASIC_INFO *data_offset; 5571 __u16 params, param_offset, offset, count, byte_count; 5572 5573 cifs_dbg(FYI, "In SetUID/GID/Mode\n"); 5574 setPermsRetry: 5575 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5576 (void **) &pSMBr); 5577 if (rc) 5578 return rc; 5579 5580 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5581 name_len = 5582 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 5583 PATH_MAX, nls_codepage, remap); 5584 name_len++; /* trailing null */ 5585 name_len *= 2; 5586 } else { 5587 name_len = copy_path_name(pSMB->FileName, file_name); 5588 } 5589 5590 params = 6 + name_len; 5591 count = sizeof(FILE_UNIX_BASIC_INFO); 5592 pSMB->MaxParameterCount = cpu_to_le16(2); 5593 /* BB find max SMB PDU from sess structure BB */ 5594 pSMB->MaxDataCount = cpu_to_le16(1000); 5595 pSMB->MaxSetupCount = 0; 5596 pSMB->Reserved = 0; 5597 pSMB->Flags = 0; 5598 pSMB->Timeout = 0; 5599 pSMB->Reserved2 = 0; 5600 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5601 InformationLevel) - 4; 5602 offset = param_offset + params; 5603 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5604 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4); 5605 memset(data_offset, 0, count); 5606 pSMB->DataOffset = cpu_to_le16(offset); 5607 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5608 pSMB->SetupCount = 1; 5609 pSMB->Reserved3 = 0; 5610 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5611 byte_count = 3 /* pad */ + params + count; 5612 pSMB->ParameterCount = cpu_to_le16(params); 5613 pSMB->DataCount = cpu_to_le16(count); 5614 pSMB->TotalParameterCount = pSMB->ParameterCount; 5615 pSMB->TotalDataCount = pSMB->DataCount; 5616 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5617 pSMB->Reserved4 = 0; 5618 inc_rfc1001_len(pSMB, byte_count); 5619 5620 cifs_fill_unix_set_info(data_offset, args); 5621 5622 pSMB->ByteCount = cpu_to_le16(byte_count); 5623 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5624 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5625 if (rc) 5626 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc); 5627 5628 cifs_buf_release(pSMB); 5629 if (rc == -EAGAIN) 5630 goto setPermsRetry; 5631 return rc; 5632 } 5633 5634 #ifdef CONFIG_CIFS_XATTR 5635 /* 5636 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common 5637 * function used by listxattr and getxattr type calls. When ea_name is set, 5638 * it looks for that attribute name and stuffs that value into the EAData 5639 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the 5640 * buffer. In both cases, the return value is either the length of the 5641 * resulting data or a negative error code. If EAData is a NULL pointer then 5642 * the data isn't copied to it, but the length is returned. 5643 */ 5644 ssize_t 5645 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon, 5646 const unsigned char *searchName, const unsigned char *ea_name, 5647 char *EAData, size_t buf_size, 5648 struct cifs_sb_info *cifs_sb) 5649 { 5650 /* BB assumes one setup word */ 5651 TRANSACTION2_QPI_REQ *pSMB = NULL; 5652 TRANSACTION2_QPI_RSP *pSMBr = NULL; 5653 int remap = cifs_remap(cifs_sb); 5654 struct nls_table *nls_codepage = cifs_sb->local_nls; 5655 int rc = 0; 5656 int bytes_returned; 5657 int list_len; 5658 struct fealist *ea_response_data; 5659 struct fea *temp_fea; 5660 char *temp_ptr; 5661 char *end_of_smb; 5662 __u16 params, byte_count, data_offset; 5663 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0; 5664 5665 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName); 5666 QAllEAsRetry: 5667 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5668 (void **) &pSMBr); 5669 if (rc) 5670 return rc; 5671 5672 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5673 list_len = 5674 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 5675 PATH_MAX, nls_codepage, remap); 5676 list_len++; /* trailing null */ 5677 list_len *= 2; 5678 } else { 5679 list_len = copy_path_name(pSMB->FileName, searchName); 5680 } 5681 5682 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */; 5683 pSMB->TotalDataCount = 0; 5684 pSMB->MaxParameterCount = cpu_to_le16(2); 5685 /* BB find exact max SMB PDU from sess structure BB */ 5686 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 5687 pSMB->MaxSetupCount = 0; 5688 pSMB->Reserved = 0; 5689 pSMB->Flags = 0; 5690 pSMB->Timeout = 0; 5691 pSMB->Reserved2 = 0; 5692 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5693 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 5694 pSMB->DataCount = 0; 5695 pSMB->DataOffset = 0; 5696 pSMB->SetupCount = 1; 5697 pSMB->Reserved3 = 0; 5698 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 5699 byte_count = params + 1 /* pad */ ; 5700 pSMB->TotalParameterCount = cpu_to_le16(params); 5701 pSMB->ParameterCount = pSMB->TotalParameterCount; 5702 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS); 5703 pSMB->Reserved4 = 0; 5704 inc_rfc1001_len(pSMB, byte_count); 5705 pSMB->ByteCount = cpu_to_le16(byte_count); 5706 5707 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5708 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5709 if (rc) { 5710 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc); 5711 goto QAllEAsOut; 5712 } 5713 5714 5715 /* BB also check enough total bytes returned */ 5716 /* BB we need to improve the validity checking 5717 of these trans2 responses */ 5718 5719 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5720 if (rc || get_bcc(&pSMBr->hdr) < 4) { 5721 rc = -EIO; /* bad smb */ 5722 goto QAllEAsOut; 5723 } 5724 5725 /* check that length of list is not more than bcc */ 5726 /* check that each entry does not go beyond length 5727 of list */ 5728 /* check that each element of each entry does not 5729 go beyond end of list */ 5730 /* validate_trans2_offsets() */ 5731 /* BB check if start of smb + data_offset > &bcc+ bcc */ 5732 5733 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5734 ea_response_data = (struct fealist *) 5735 (((char *) &pSMBr->hdr.Protocol) + data_offset); 5736 5737 list_len = le32_to_cpu(ea_response_data->list_len); 5738 cifs_dbg(FYI, "ea length %d\n", list_len); 5739 if (list_len <= 8) { 5740 cifs_dbg(FYI, "empty EA list returned from server\n"); 5741 /* didn't find the named attribute */ 5742 if (ea_name) 5743 rc = -ENODATA; 5744 goto QAllEAsOut; 5745 } 5746 5747 /* make sure list_len doesn't go past end of SMB */ 5748 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr); 5749 if ((char *)ea_response_data + list_len > end_of_smb) { 5750 cifs_dbg(FYI, "EA list appears to go beyond SMB\n"); 5751 rc = -EIO; 5752 goto QAllEAsOut; 5753 } 5754 5755 /* account for ea list len */ 5756 list_len -= 4; 5757 temp_fea = &ea_response_data->list; 5758 temp_ptr = (char *)temp_fea; 5759 while (list_len > 0) { 5760 unsigned int name_len; 5761 __u16 value_len; 5762 5763 list_len -= 4; 5764 temp_ptr += 4; 5765 /* make sure we can read name_len and value_len */ 5766 if (list_len < 0) { 5767 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 5768 rc = -EIO; 5769 goto QAllEAsOut; 5770 } 5771 5772 name_len = temp_fea->name_len; 5773 value_len = le16_to_cpu(temp_fea->value_len); 5774 list_len -= name_len + 1 + value_len; 5775 if (list_len < 0) { 5776 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 5777 rc = -EIO; 5778 goto QAllEAsOut; 5779 } 5780 5781 if (ea_name) { 5782 if (ea_name_len == name_len && 5783 memcmp(ea_name, temp_ptr, name_len) == 0) { 5784 temp_ptr += name_len + 1; 5785 rc = value_len; 5786 if (buf_size == 0) 5787 goto QAllEAsOut; 5788 if ((size_t)value_len > buf_size) { 5789 rc = -ERANGE; 5790 goto QAllEAsOut; 5791 } 5792 memcpy(EAData, temp_ptr, value_len); 5793 goto QAllEAsOut; 5794 } 5795 } else { 5796 /* account for prefix user. and trailing null */ 5797 rc += (5 + 1 + name_len); 5798 if (rc < (int) buf_size) { 5799 memcpy(EAData, "user.", 5); 5800 EAData += 5; 5801 memcpy(EAData, temp_ptr, name_len); 5802 EAData += name_len; 5803 /* null terminate name */ 5804 *EAData = 0; 5805 ++EAData; 5806 } else if (buf_size == 0) { 5807 /* skip copy - calc size only */ 5808 } else { 5809 /* stop before overrun buffer */ 5810 rc = -ERANGE; 5811 break; 5812 } 5813 } 5814 temp_ptr += name_len + 1 + value_len; 5815 temp_fea = (struct fea *)temp_ptr; 5816 } 5817 5818 /* didn't find the named attribute */ 5819 if (ea_name) 5820 rc = -ENODATA; 5821 5822 QAllEAsOut: 5823 cifs_buf_release(pSMB); 5824 if (rc == -EAGAIN) 5825 goto QAllEAsRetry; 5826 5827 return (ssize_t)rc; 5828 } 5829 5830 int 5831 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, 5832 const char *fileName, const char *ea_name, const void *ea_value, 5833 const __u16 ea_value_len, const struct nls_table *nls_codepage, 5834 struct cifs_sb_info *cifs_sb) 5835 { 5836 struct smb_com_transaction2_spi_req *pSMB = NULL; 5837 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5838 struct fealist *parm_data; 5839 int name_len; 5840 int rc = 0; 5841 int bytes_returned = 0; 5842 __u16 params, param_offset, byte_count, offset, count; 5843 int remap = cifs_remap(cifs_sb); 5844 5845 cifs_dbg(FYI, "In SetEA\n"); 5846 SetEARetry: 5847 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5848 (void **) &pSMBr); 5849 if (rc) 5850 return rc; 5851 5852 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5853 name_len = 5854 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 5855 PATH_MAX, nls_codepage, remap); 5856 name_len++; /* trailing null */ 5857 name_len *= 2; 5858 } else { 5859 name_len = copy_path_name(pSMB->FileName, fileName); 5860 } 5861 5862 params = 6 + name_len; 5863 5864 /* done calculating parms using name_len of file name, 5865 now use name_len to calculate length of ea name 5866 we are going to create in the inode xattrs */ 5867 if (ea_name == NULL) 5868 name_len = 0; 5869 else 5870 name_len = strnlen(ea_name, 255); 5871 5872 count = sizeof(*parm_data) + 1 + ea_value_len + name_len; 5873 pSMB->MaxParameterCount = cpu_to_le16(2); 5874 /* BB find max SMB PDU from sess */ 5875 pSMB->MaxDataCount = cpu_to_le16(1000); 5876 pSMB->MaxSetupCount = 0; 5877 pSMB->Reserved = 0; 5878 pSMB->Flags = 0; 5879 pSMB->Timeout = 0; 5880 pSMB->Reserved2 = 0; 5881 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5882 InformationLevel) - 4; 5883 offset = param_offset + params; 5884 pSMB->InformationLevel = 5885 cpu_to_le16(SMB_SET_FILE_EA); 5886 5887 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset; 5888 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5889 pSMB->DataOffset = cpu_to_le16(offset); 5890 pSMB->SetupCount = 1; 5891 pSMB->Reserved3 = 0; 5892 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5893 byte_count = 3 /* pad */ + params + count; 5894 pSMB->DataCount = cpu_to_le16(count); 5895 parm_data->list_len = cpu_to_le32(count); 5896 parm_data->list.EA_flags = 0; 5897 /* we checked above that name len is less than 255 */ 5898 parm_data->list.name_len = (__u8)name_len; 5899 /* EA names are always ASCII and NUL-terminated */ 5900 strscpy(parm_data->list.name, ea_name ?: "", name_len + 1); 5901 parm_data->list.value_len = cpu_to_le16(ea_value_len); 5902 /* caller ensures that ea_value_len is less than 64K but 5903 we need to ensure that it fits within the smb */ 5904 5905 /*BB add length check to see if it would fit in 5906 negotiated SMB buffer size BB */ 5907 /* if (ea_value_len > buffer_size - 512 (enough for header)) */ 5908 if (ea_value_len) 5909 memcpy(parm_data->list.name + name_len + 1, 5910 ea_value, ea_value_len); 5911 5912 pSMB->TotalDataCount = pSMB->DataCount; 5913 pSMB->ParameterCount = cpu_to_le16(params); 5914 pSMB->TotalParameterCount = pSMB->ParameterCount; 5915 pSMB->Reserved4 = 0; 5916 inc_rfc1001_len(pSMB, byte_count); 5917 pSMB->ByteCount = cpu_to_le16(byte_count); 5918 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5919 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5920 if (rc) 5921 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc); 5922 5923 cifs_buf_release(pSMB); 5924 5925 if (rc == -EAGAIN) 5926 goto SetEARetry; 5927 5928 return rc; 5929 } 5930 #endif 5931