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