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