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