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