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