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