Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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