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