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