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